1 | """ |
---|
2 | Integration tests for getting and putting files, including reading from stdin |
---|
3 | and stdout. |
---|
4 | """ |
---|
5 | |
---|
6 | from subprocess import Popen, PIPE, check_output, check_call |
---|
7 | |
---|
8 | import pytest |
---|
9 | from twisted.internet import reactor |
---|
10 | from twisted.internet.threads import blockingCallFromThread |
---|
11 | |
---|
12 | from .util import run_in_thread, cli |
---|
13 | |
---|
14 | DATA = b"abc123 this is not utf-8 decodable \xff\x00\x33 \x11" |
---|
15 | try: |
---|
16 | DATA.decode("utf-8") |
---|
17 | except UnicodeDecodeError: |
---|
18 | pass # great, what we want |
---|
19 | else: |
---|
20 | raise ValueError("BUG, the DATA string was decoded from UTF-8") |
---|
21 | |
---|
22 | |
---|
23 | @pytest.fixture(scope="session") |
---|
24 | def get_put_alias(alice): |
---|
25 | cli(alice.process, "create-alias", "getput") |
---|
26 | |
---|
27 | |
---|
28 | def read_bytes(path): |
---|
29 | with open(path, "rb") as f: |
---|
30 | return f.read() |
---|
31 | |
---|
32 | |
---|
33 | @run_in_thread |
---|
34 | def test_put_from_stdin(alice, get_put_alias, tmpdir): |
---|
35 | """ |
---|
36 | It's possible to upload a file via `tahoe put`'s STDIN, and then download |
---|
37 | it to a file. |
---|
38 | """ |
---|
39 | tempfile = str(tmpdir.join("file")) |
---|
40 | p = Popen( |
---|
41 | ["tahoe", "--node-directory", alice.process.node_dir, "put", "-", "getput:fromstdin"], |
---|
42 | stdin=PIPE |
---|
43 | ) |
---|
44 | p.stdin.write(DATA) |
---|
45 | p.stdin.close() |
---|
46 | assert p.wait() == 0 |
---|
47 | |
---|
48 | cli(alice.process, "get", "getput:fromstdin", tempfile) |
---|
49 | assert read_bytes(tempfile) == DATA |
---|
50 | |
---|
51 | |
---|
52 | @run_in_thread |
---|
53 | def test_get_to_stdout(alice, get_put_alias, tmpdir): |
---|
54 | """ |
---|
55 | It's possible to upload a file, and then download it to stdout. |
---|
56 | """ |
---|
57 | tempfile = tmpdir.join("file") |
---|
58 | with tempfile.open("wb") as f: |
---|
59 | f.write(DATA) |
---|
60 | cli(alice.process, "put", str(tempfile), "getput:tostdout") |
---|
61 | |
---|
62 | p = Popen( |
---|
63 | ["tahoe", "--node-directory", alice.process.node_dir, "get", "getput:tostdout", "-"], |
---|
64 | stdout=PIPE |
---|
65 | ) |
---|
66 | assert p.stdout.read() == DATA |
---|
67 | assert p.wait() == 0 |
---|
68 | |
---|
69 | |
---|
70 | @run_in_thread |
---|
71 | def test_large_file(alice, get_put_alias, tmp_path): |
---|
72 | """ |
---|
73 | It's possible to upload and download a larger file. |
---|
74 | |
---|
75 | We avoid stdin/stdout since that's flaky on Windows. |
---|
76 | """ |
---|
77 | tempfile = tmp_path / "file" |
---|
78 | with tempfile.open("wb") as f: |
---|
79 | f.write(DATA * 1_000_000) |
---|
80 | cli(alice.process, "put", str(tempfile), "getput:largefile") |
---|
81 | |
---|
82 | outfile = tmp_path / "out" |
---|
83 | check_call( |
---|
84 | ["tahoe", "--node-directory", alice.process.node_dir, "get", "getput:largefile", str(outfile)], |
---|
85 | ) |
---|
86 | assert outfile.read_bytes() == tempfile.read_bytes() |
---|
87 | |
---|
88 | |
---|
89 | @run_in_thread |
---|
90 | def test_upload_download_immutable_different_default_max_segment_size(alice, get_put_alias, tmpdir, request): |
---|
91 | """ |
---|
92 | Tahoe-LAFS used to have a default max segment size of 128KB, and is now |
---|
93 | 1MB. Test that an upload created when 128KB was the default can be |
---|
94 | downloaded with 1MB as the default (i.e. old uploader, new downloader), and |
---|
95 | vice versa, (new uploader, old downloader). |
---|
96 | """ |
---|
97 | tempfile = tmpdir.join("file") |
---|
98 | large_data = DATA * 100_000 |
---|
99 | assert len(large_data) > 2 * 1024 * 1024 |
---|
100 | with tempfile.open("wb") as f: |
---|
101 | f.write(large_data) |
---|
102 | |
---|
103 | def set_segment_size(segment_size): |
---|
104 | return blockingCallFromThread( |
---|
105 | reactor, |
---|
106 | lambda: alice.reconfigure_zfec( |
---|
107 | reactor, |
---|
108 | (1, 1, 1), |
---|
109 | None, |
---|
110 | max_segment_size=segment_size |
---|
111 | ) |
---|
112 | ) |
---|
113 | |
---|
114 | # 1. Upload file 1 with default segment size set to 1MB |
---|
115 | set_segment_size(1024 * 1024) |
---|
116 | cli(alice.process, "put", str(tempfile), "getput:seg1024kb") |
---|
117 | |
---|
118 | # 2. Download file 1 with default segment size set to 128KB |
---|
119 | set_segment_size(128 * 1024) |
---|
120 | assert large_data == check_output( |
---|
121 | ["tahoe", "--node-directory", alice.process.node_dir, "get", "getput:seg1024kb", "-"] |
---|
122 | ) |
---|
123 | |
---|
124 | # 3. Upload file 2 with default segment size set to 128KB |
---|
125 | cli(alice.process, "put", str(tempfile), "getput:seg128kb") |
---|
126 | |
---|
127 | # 4. Download file 2 with default segment size set to 1MB |
---|
128 | set_segment_size(1024 * 1024) |
---|
129 | assert large_data == check_output( |
---|
130 | ["tahoe", "--node-directory", alice.process.node_dir, "get", "getput:seg128kb", "-"] |
---|
131 | ) |
---|