1 | # -*- coding: utf-8 -*- |
---|
2 | # Tahoe-LAFS -- secure, distributed storage grid |
---|
3 | # |
---|
4 | # Copyright © 2020 The Tahoe-LAFS Software Foundation |
---|
5 | # |
---|
6 | # This file is part of Tahoe-LAFS. |
---|
7 | # |
---|
8 | # See the docs/about.rst file for licensing information. |
---|
9 | |
---|
10 | """ |
---|
11 | Tests for the allmydata.testing helpers |
---|
12 | """ |
---|
13 | |
---|
14 | from twisted.internet.defer import ( |
---|
15 | inlineCallbacks, |
---|
16 | ) |
---|
17 | |
---|
18 | from allmydata.uri import ( |
---|
19 | from_string, |
---|
20 | CHKFileURI, |
---|
21 | ) |
---|
22 | from allmydata.testing.web import ( |
---|
23 | create_tahoe_treq_client, |
---|
24 | capability_generator, |
---|
25 | ) |
---|
26 | |
---|
27 | from hyperlink import ( |
---|
28 | DecodedURL, |
---|
29 | ) |
---|
30 | |
---|
31 | from hypothesis import ( |
---|
32 | given, |
---|
33 | ) |
---|
34 | from hypothesis.strategies import ( |
---|
35 | binary, |
---|
36 | ) |
---|
37 | |
---|
38 | from .common import ( |
---|
39 | SyncTestCase, |
---|
40 | ) |
---|
41 | |
---|
42 | from testtools.matchers import ( |
---|
43 | Always, |
---|
44 | Equals, |
---|
45 | IsInstance, |
---|
46 | MatchesStructure, |
---|
47 | AfterPreprocessing, |
---|
48 | Contains, |
---|
49 | ) |
---|
50 | from testtools.twistedsupport import ( |
---|
51 | succeeded, |
---|
52 | ) |
---|
53 | from twisted.web.http import GONE |
---|
54 | |
---|
55 | |
---|
56 | class FakeWebTest(SyncTestCase): |
---|
57 | """ |
---|
58 | Test the WebUI verified-fakes infrastucture |
---|
59 | """ |
---|
60 | |
---|
61 | # Note: do NOT use setUp() because Hypothesis doesn't work |
---|
62 | # properly with it. You must instead do all fixture-type work |
---|
63 | # yourself in each test. |
---|
64 | |
---|
65 | @given( |
---|
66 | content=binary(), |
---|
67 | ) |
---|
68 | def test_create_and_download(self, content): |
---|
69 | """ |
---|
70 | Upload some content (via 'PUT /uri') and then download it (via |
---|
71 | 'GET /uri?uri=...') |
---|
72 | """ |
---|
73 | http_client = create_tahoe_treq_client() |
---|
74 | |
---|
75 | @inlineCallbacks |
---|
76 | def do_test(): |
---|
77 | resp = yield http_client.put("http://example.com/uri", content) |
---|
78 | self.assertThat(resp.code, Equals(201)) |
---|
79 | |
---|
80 | cap_raw = yield resp.content() |
---|
81 | cap = from_string(cap_raw) |
---|
82 | self.assertThat(cap, IsInstance(CHKFileURI)) |
---|
83 | |
---|
84 | resp = yield http_client.get( |
---|
85 | b"http://example.com/uri?uri=" + cap.to_string() |
---|
86 | ) |
---|
87 | self.assertThat(resp.code, Equals(200)) |
---|
88 | |
---|
89 | round_trip_content = yield resp.content() |
---|
90 | |
---|
91 | # using the form "/uri/<cap>" is also valid |
---|
92 | |
---|
93 | resp = yield http_client.get( |
---|
94 | b"http://example.com/uri?uri=" + cap.to_string() |
---|
95 | ) |
---|
96 | self.assertEqual(resp.code, 200) |
---|
97 | |
---|
98 | round_trip_content = yield resp.content() |
---|
99 | self.assertEqual(content, round_trip_content) |
---|
100 | self.assertThat( |
---|
101 | do_test(), |
---|
102 | succeeded(Always()), |
---|
103 | ) |
---|
104 | |
---|
105 | @given( |
---|
106 | content=binary(), |
---|
107 | ) |
---|
108 | def test_duplicate_upload(self, content): |
---|
109 | """ |
---|
110 | Upload the same content (via 'PUT /uri') twice |
---|
111 | """ |
---|
112 | |
---|
113 | http_client = create_tahoe_treq_client() |
---|
114 | |
---|
115 | @inlineCallbacks |
---|
116 | def do_test(): |
---|
117 | resp = yield http_client.put("http://example.com/uri", content) |
---|
118 | self.assertEqual(resp.code, 201) |
---|
119 | |
---|
120 | cap_raw = yield resp.content() |
---|
121 | self.assertThat( |
---|
122 | cap_raw, |
---|
123 | AfterPreprocessing( |
---|
124 | from_string, |
---|
125 | IsInstance(CHKFileURI) |
---|
126 | ) |
---|
127 | ) |
---|
128 | |
---|
129 | resp = yield http_client.put("http://example.com/uri", content) |
---|
130 | self.assertThat(resp.code, Equals(200)) |
---|
131 | self.assertThat( |
---|
132 | do_test(), |
---|
133 | succeeded(Always()), |
---|
134 | ) |
---|
135 | |
---|
136 | def test_download_missing(self): |
---|
137 | """ |
---|
138 | The response to a request to download a capability that doesn't exist |
---|
139 | is 410 (GONE). |
---|
140 | """ |
---|
141 | |
---|
142 | http_client = create_tahoe_treq_client() |
---|
143 | cap_gen = capability_generator(b"URI:CHK:") |
---|
144 | cap = next(cap_gen).decode('ascii') |
---|
145 | uri = DecodedURL.from_text(u"http://example.com/uri?uri={}".format(cap)) |
---|
146 | resp = http_client.get(uri.to_uri().to_text()) |
---|
147 | |
---|
148 | self.assertThat( |
---|
149 | resp, |
---|
150 | succeeded( |
---|
151 | MatchesStructure( |
---|
152 | code=Equals(GONE), |
---|
153 | content=AfterPreprocessing( |
---|
154 | lambda m: m(), |
---|
155 | succeeded(Contains(b"No data for")), |
---|
156 | ), |
---|
157 | ) |
---|
158 | ) |
---|
159 | ) |
---|
160 | |
---|
161 | def test_download_no_arg(self): |
---|
162 | """ |
---|
163 | Error if we GET from "/uri" with no ?uri= query-arg |
---|
164 | """ |
---|
165 | |
---|
166 | http_client = create_tahoe_treq_client() |
---|
167 | |
---|
168 | uri = DecodedURL.from_text(u"http://example.com/uri/") |
---|
169 | resp = http_client.get(uri.to_uri().to_text()) |
---|
170 | |
---|
171 | self.assertThat( |
---|
172 | resp, |
---|
173 | succeeded( |
---|
174 | MatchesStructure( |
---|
175 | code=Equals(400) |
---|
176 | ) |
---|
177 | ) |
---|
178 | ) |
---|