1 | Tue May 18 23:51:46 MDT 2010 zooko@zooko.com |
---|
2 | * tests: refactor test_web.py to have less duplication of literal caps-from-the-future |
---|
3 | This is a prelude to a patch which will add tests of caps from the future which have non-ascii chars in them. |
---|
4 | |
---|
5 | Wed May 19 00:06:23 MDT 2010 zooko@zooko.com |
---|
6 | * add tests of caps from the future that have non-ASCII characters in them |
---|
7 | Current trunk fails these tests. The changes to test_uri.py, test_client.py, and test_dirnode.py add tests of non-ascii-future-caps (in Python unicode objects) in addition to the current tests of all-ascii-future-caps (in Python str objects). The changes to test_web.py just replace the tests of all-ascii-future-caps with tests of non-ascii-future-caps. |
---|
8 | |
---|
9 | New patches: |
---|
10 | |
---|
11 | [tests: refactor test_web.py to have less duplication of literal caps-from-the-future |
---|
12 | zooko@zooko.com**20100519055146 |
---|
13 | Ignore-this: 49e5412e6cc4566ca67f069ffd850af6 |
---|
14 | This is a prelude to a patch which will add tests of caps from the future which have non-ascii chars in them. |
---|
15 | ] { |
---|
16 | hunk ./src/allmydata/test/test_web.py 38 |
---|
17 | |
---|
18 | timeout = 480 # Most of these take longer than 240 seconds on Francois's arm box. |
---|
19 | |
---|
20 | +unknown_rwcap = "lafs://from_the_future" |
---|
21 | +unknown_rocap = "ro.lafs://readonly_from_the_future" |
---|
22 | +unknown_immcap = "imm.lafs://immutable_from_the_future" |
---|
23 | + |
---|
24 | class FakeStatsProvider: |
---|
25 | def get_stats(self): |
---|
26 | stats = {'stats': {}, 'counters': {}} |
---|
27 | hunk ./src/allmydata/test/test_web.py 2180 |
---|
28 | filecap2 = make_mutable_file_uri() |
---|
29 | node3 = self.s.create_node_from_uri(make_mutable_file_uri()) |
---|
30 | filecap3 = node3.get_readonly_uri() |
---|
31 | - unknown_rwcap = "lafs://from_the_future" |
---|
32 | - unknown_rocap = "ro.lafs://readonly_from_the_future" |
---|
33 | - unknown_immcap = "imm.lafs://immutable_from_the_future" |
---|
34 | node4 = self.s.create_node_from_uri(make_mutable_file_uri()) |
---|
35 | dircap = DirectoryNode(node4, None, None).get_uri() |
---|
36 | litdircap = "URI:DIR2-LIT:ge3dumj2mewdcotyfqydulbshj5x2lbm" |
---|
37 | hunk ./src/allmydata/test/test_web.py 2215 |
---|
38 | tnode = create_chk_filenode("immutable directory contents\n"*10) |
---|
39 | dnode = DirectoryNode(tnode, None, None) |
---|
40 | assert not dnode.is_mutable() |
---|
41 | - unknown_immcap = "imm.lafs://immutable_from_the_future" |
---|
42 | immdircap = dnode.get_uri() |
---|
43 | litdircap = "URI:DIR2-LIT:ge3dumj2mewdcotyfqydulbshj5x2lbm" |
---|
44 | emptydircap = "URI:DIR2-LIT:" |
---|
45 | hunk ./src/allmydata/test/test_web.py 2456 |
---|
46 | return d |
---|
47 | |
---|
48 | def test_POST_link_uri_unknown_bad(self): |
---|
49 | - newuri = "lafs://from_the_future" |
---|
50 | - d = self.POST(self.public_url + "/foo", t="uri", name="future.txt", uri=newuri) |
---|
51 | + d = self.POST(self.public_url + "/foo", t="uri", name="future.txt", uri=unknown_rwcap) |
---|
52 | d.addBoth(self.shouldFail, error.Error, |
---|
53 | "POST_link_uri_unknown_bad", |
---|
54 | "400 Bad Request", |
---|
55 | hunk ./src/allmydata/test/test_web.py 2464 |
---|
56 | return d |
---|
57 | |
---|
58 | def test_POST_link_uri_unknown_ro_good(self): |
---|
59 | - newuri = "ro.lafs://readonly_from_the_future" |
---|
60 | - d = self.POST(self.public_url + "/foo", t="uri", name="future-ro.txt", uri=newuri) |
---|
61 | + d = self.POST(self.public_url + "/foo", t="uri", name="future-ro.txt", uri=unknown_rocap) |
---|
62 | d.addCallback(self.failUnlessURIMatchesROChild, self._foo_node, u"future-ro.txt") |
---|
63 | return d |
---|
64 | |
---|
65 | hunk ./src/allmydata/test/test_web.py 2469 |
---|
66 | def test_POST_link_uri_unknown_imm_good(self): |
---|
67 | - newuri = "imm.lafs://immutable_from_the_future" |
---|
68 | - d = self.POST(self.public_url + "/foo", t="uri", name="future-imm.txt", uri=newuri) |
---|
69 | + d = self.POST(self.public_url + "/foo", t="uri", name="future-imm.txt", uri=unknown_immcap) |
---|
70 | d.addCallback(self.failUnlessURIMatchesROChild, self._foo_node, u"future-imm.txt") |
---|
71 | return d |
---|
72 | |
---|
73 | hunk ./src/allmydata/test/test_web.py 2760 |
---|
74 | return d |
---|
75 | |
---|
76 | def test_PUT_NEWFILEURL_uri_unknown_bad(self): |
---|
77 | - new_uri = "lafs://from_the_future" |
---|
78 | - d = self.PUT(self.public_url + "/foo/put-future.txt?t=uri", new_uri) |
---|
79 | + d = self.PUT(self.public_url + "/foo/put-future.txt?t=uri", unknown_rwcap) |
---|
80 | d.addBoth(self.shouldFail, error.Error, |
---|
81 | "POST_put_uri_unknown_bad", |
---|
82 | "400 Bad Request", |
---|
83 | hunk ./src/allmydata/test/test_web.py 2768 |
---|
84 | return d |
---|
85 | |
---|
86 | def test_PUT_NEWFILEURL_uri_unknown_ro_good(self): |
---|
87 | - new_uri = "ro.lafs://readonly_from_the_future" |
---|
88 | - d = self.PUT(self.public_url + "/foo/put-future-ro.txt?t=uri", new_uri) |
---|
89 | + d = self.PUT(self.public_url + "/foo/put-future-ro.txt?t=uri", unknown_rocap) |
---|
90 | d.addCallback(self.failUnlessURIMatchesROChild, self._foo_node, |
---|
91 | u"put-future-ro.txt") |
---|
92 | return d |
---|
93 | hunk ./src/allmydata/test/test_web.py 2774 |
---|
94 | |
---|
95 | def test_PUT_NEWFILEURL_uri_unknown_imm_good(self): |
---|
96 | - new_uri = "imm.lafs://immutable_from_the_future" |
---|
97 | - d = self.PUT(self.public_url + "/foo/put-future-imm.txt?t=uri", new_uri) |
---|
98 | + d = self.PUT(self.public_url + "/foo/put-future-imm.txt?t=uri", unknown_immcap) |
---|
99 | d.addCallback(self.failUnlessURIMatchesROChild, self._foo_node, |
---|
100 | u"put-future-imm.txt") |
---|
101 | return d |
---|
102 | hunk ./src/allmydata/test/test_web.py 3367 |
---|
103 | self.uris = {} |
---|
104 | self.fileurls = {} |
---|
105 | |
---|
106 | - future_write_uri = "x-tahoe-crazy://I_am_from_the_future." |
---|
107 | - future_read_uri = "x-tahoe-crazy-readonly://I_am_from_the_future." |
---|
108 | # the future cap format may contain slashes, which must be tolerated |
---|
109 | hunk ./src/allmydata/test/test_web.py 3368 |
---|
110 | - expected_info_url = "uri/%s?t=info" % urllib.quote(future_write_uri, |
---|
111 | + expected_info_url = "uri/%s?t=info" % urllib.quote(unknown_rwcap, |
---|
112 | safe="") |
---|
113 | |
---|
114 | if immutable: |
---|
115 | hunk ./src/allmydata/test/test_web.py 3373 |
---|
116 | name = u"future-imm" |
---|
117 | - future_node = UnknownNode(None, future_read_uri, deep_immutable=True) |
---|
118 | + future_node = UnknownNode(None, unknown_immcap, deep_immutable=True) |
---|
119 | d = c0.create_immutable_dirnode({name: (future_node, {})}) |
---|
120 | else: |
---|
121 | name = u"future" |
---|
122 | hunk ./src/allmydata/test/test_web.py 3377 |
---|
123 | - future_node = UnknownNode(future_write_uri, future_read_uri) |
---|
124 | + future_node = UnknownNode(unknown_rwcap, unknown_rocap) |
---|
125 | d = c0.create_dirnode() |
---|
126 | |
---|
127 | def _stash_root_and_create_file(n): |
---|
128 | hunk ./src/allmydata/test/test_web.py 3411 |
---|
129 | f = data[1]["children"][name] |
---|
130 | self.failUnlessEqual(f[0], "unknown") |
---|
131 | if expect_rw_uri: |
---|
132 | - self.failUnlessEqual(f[1]["rw_uri"], future_write_uri) |
---|
133 | + self.failUnlessEqual(f[1]["rw_uri"], unknown_rwcap) |
---|
134 | else: |
---|
135 | self.failIfIn("rw_uri", f[1]) |
---|
136 | if immutable: |
---|
137 | hunk ./src/allmydata/test/test_web.py 3415 |
---|
138 | - self.failUnlessEqual(f[1]["ro_uri"], "imm." + future_read_uri) |
---|
139 | + self.failUnlessEqual(f[1]["ro_uri"], unknown_immcap, data) |
---|
140 | else: |
---|
141 | hunk ./src/allmydata/test/test_web.py 3417 |
---|
142 | - self.failUnlessEqual(f[1]["ro_uri"], "ro." + future_read_uri) |
---|
143 | + self.failUnlessEqual(f[1]["ro_uri"], unknown_rocap) |
---|
144 | self.failUnless("metadata" in f[1]) |
---|
145 | d.addCallback(_check_directory_json, expect_rw_uri=not immutable) |
---|
146 | |
---|
147 | hunk ./src/allmydata/test/test_web.py 3424 |
---|
148 | def _check_info(res, expect_rw_uri, expect_ro_uri): |
---|
149 | self.failUnlessIn("Object Type: <span>unknown</span>", res) |
---|
150 | if expect_rw_uri: |
---|
151 | - self.failUnlessIn(future_write_uri, res) |
---|
152 | + self.failUnlessIn(unknown_rwcap, res) |
---|
153 | if expect_ro_uri: |
---|
154 | hunk ./src/allmydata/test/test_web.py 3426 |
---|
155 | - self.failUnlessIn(future_read_uri, res) |
---|
156 | + if immutable: |
---|
157 | + self.failUnlessIn(unknown_immcap, res) |
---|
158 | + else: |
---|
159 | + self.failUnlessIn(unknown_rocap, res) |
---|
160 | else: |
---|
161 | hunk ./src/allmydata/test/test_web.py 3431 |
---|
162 | - self.failIfIn(future_read_uri, res) |
---|
163 | + self.failIfIn(unknown_rocap, res) |
---|
164 | self.failIfIn("Raw data as", res) |
---|
165 | self.failIfIn("Directory writecap", res) |
---|
166 | self.failIfIn("Checker Operations", res) |
---|
167 | hunk ./src/allmydata/test/test_web.py 3450 |
---|
168 | data = simplejson.loads(res) |
---|
169 | self.failUnlessEqual(data[0], "unknown") |
---|
170 | if expect_rw_uri: |
---|
171 | - self.failUnlessEqual(data[1]["rw_uri"], future_write_uri) |
---|
172 | + self.failUnlessEqual(data[1]["rw_uri"], unknown_rwcap) |
---|
173 | else: |
---|
174 | self.failIfIn("rw_uri", data[1]) |
---|
175 | |
---|
176 | hunk ./src/allmydata/test/test_web.py 3455 |
---|
177 | if immutable: |
---|
178 | - self.failUnlessEqual(data[1]["ro_uri"], "imm." + future_read_uri) |
---|
179 | + self.failUnlessEqual(data[1]["ro_uri"], unknown_immcap) |
---|
180 | self.failUnlessEqual(data[1]["mutable"], False) |
---|
181 | elif expect_rw_uri: |
---|
182 | hunk ./src/allmydata/test/test_web.py 3458 |
---|
183 | - self.failUnlessEqual(data[1]["ro_uri"], "ro." + future_read_uri) |
---|
184 | + self.failUnlessEqual(data[1]["ro_uri"], unknown_rocap) |
---|
185 | self.failUnlessEqual(data[1]["mutable"], True) |
---|
186 | else: |
---|
187 | hunk ./src/allmydata/test/test_web.py 3461 |
---|
188 | - self.failUnlessEqual(data[1]["ro_uri"], "ro." + future_read_uri) |
---|
189 | + self.failUnlessEqual(data[1]["ro_uri"], unknown_rocap) |
---|
190 | self.failIf("mutable" in data[1], data[1]) |
---|
191 | |
---|
192 | # TODO: check metadata contents |
---|
193 | hunk ./src/allmydata/test/test_web.py 3471 |
---|
194 | d.addCallback(_check_json, expect_rw_uri=not immutable) |
---|
195 | |
---|
196 | # and make sure that a read-only version of the directory can be |
---|
197 | - # rendered too. This version will not have future_write_uri, whether |
---|
198 | + # rendered too. This version will not have unknown_rwcap, whether |
---|
199 | # or not future_node was immutable. |
---|
200 | d.addCallback(lambda ign: self.GET(self.rourl)) |
---|
201 | if immutable: |
---|
202 | hunk ./src/allmydata/test/test_web.py 3650 |
---|
203 | |
---|
204 | # this tests that deep-check and stream-manifest will ignore |
---|
205 | # UnknownNode instances. Hopefully this will also cover deep-stats. |
---|
206 | - future_write_uri = "x-tahoe-crazy://I_am_from_the_future." |
---|
207 | - future_read_uri = "x-tahoe-crazy-readonly://I_am_from_the_future." |
---|
208 | - future_node = UnknownNode(future_write_uri, future_read_uri) |
---|
209 | + future_node = UnknownNode(unknown_rwcap, unknown_rocap) |
---|
210 | d.addCallback(lambda ign: self.rootnode.set_node(u"future", future_node)) |
---|
211 | |
---|
212 | def _clobber_shares(ignored): |
---|
213 | } |
---|
214 | [add tests of caps from the future that have non-ASCII characters in them |
---|
215 | zooko@zooko.com**20100519060623 |
---|
216 | Ignore-this: 754e6f060da9d96b13feab58e9b60cb9 |
---|
217 | Current trunk fails these tests. The changes to test_uri.py, test_client.py, and test_dirnode.py add tests of non-ascii-future-caps (in Python unicode objects) in addition to the current tests of all-ascii-future-caps (in Python str objects). The changes to test_web.py just replace the tests of all-ascii-future-caps with tests of non-ascii-future-caps. |
---|
218 | ] { |
---|
219 | hunk ./src/allmydata/test/test_client.py 1 |
---|
220 | +# -*- coding: utf-8 -*- |
---|
221 | |
---|
222 | import os |
---|
223 | from twisted.trial import unittest |
---|
224 | hunk ./src/allmydata/test/test_client.py 304 |
---|
225 | self.failUnlessEqual(n.get_uri(), unknown_rw) |
---|
226 | self.failUnlessEqual(n.get_write_uri(), unknown_rw) |
---|
227 | self.failUnlessEqual(n.get_readonly_uri(), "ro." + unknown_ro) |
---|
228 | + |
---|
229 | + unknown_rw = u"lafs://from_the_future_fw-蜔쳨欝遃䝦舜琇襇邤䍏㵦☚✸킾궑蒴犏띎냔㳆㼿졨浴䒉ΐ屝稜퍙鉧迴" |
---|
230 | + unknown_ro = u"lafs://readonly_from_the_future_fo-ą쳨欝遃䝦舜琇襇邤䍏㵦☚✸킾궑蒴犏띎냔㳆㼿졨浴䒉ΐ屝稜퍙鉧迴" |
---|
231 | + n = c.create_node_from_uri(unknown_rw, unknown_ro) |
---|
232 | + self.failUnless(IFilesystemNode.providedBy(n)) |
---|
233 | + self.failIf(IFileNode.providedBy(n)) |
---|
234 | + self.failIf(IImmutableFileNode.providedBy(n)) |
---|
235 | + self.failIf(IMutableFileNode.providedBy(n)) |
---|
236 | + self.failIf(IDirectoryNode.providedBy(n)) |
---|
237 | + self.failUnless(n.is_unknown()) |
---|
238 | + self.failUnlessEqual(n.get_uri(), unknown_rw) |
---|
239 | + self.failUnlessEqual(n.get_write_uri(), unknown_rw) |
---|
240 | + self.failUnlessEqual(n.get_readonly_uri(), "ro." + unknown_ro) |
---|
241 | hunk ./src/allmydata/test/test_dirnode.py 1 |
---|
242 | +# -*- coding: utf-8 -*- |
---|
243 | |
---|
244 | import time |
---|
245 | from zope.interface import implements |
---|
246 | hunk ./src/allmydata/test/test_dirnode.py 49 |
---|
247 | mut_read_uri = "URI:SSK-RO:jf6wkflosyvntwxqcdo7a54jvm:euw4iw7bbnkrrwpzuburbhppuxhc3gwxv26f6imekhz7zyw2ojnq" |
---|
248 | future_write_uri = "x-tahoe-crazy://I_am_from_the_future." |
---|
249 | future_read_uri = "x-tahoe-crazy-readonly://I_am_from_the_future." |
---|
250 | +future_nonascii_write_uri = u"x-tahoe-even-more-crazy://I_am_from_the_fw-蜔쳨欝遃䝦舜琇襇邤䍏㵦☚✸킾궑蒴犏띎냔㳆㼿졨浴䒉ΐ屝稜퍙鉧迴." |
---|
251 | +future_nonascii_read_uri = u"x-tahoe-even-more-crazy-readonly://I_am_from_the_fo-ą쳨欝遃䝦舜琇襇邤䍏㵦☚✸킾궑蒴犏띎냔㳆㼿졨浴䒉ΐ屝稜퍙鉧迴." |
---|
252 | |
---|
253 | class Dirnode(GridTestMixin, unittest.TestCase, |
---|
254 | testutil.ShouldFailMixin, testutil.StallMixin, ErrorMixin): |
---|
255 | hunk ./src/allmydata/test/test_dirnode.py 85 |
---|
256 | u"mut": (nm.create_from_cap(mut_write_uri, mut_read_uri), {}), |
---|
257 | u"fut": (nm.create_from_cap(future_write_uri, future_read_uri), {}), |
---|
258 | u"fro": (nm.create_from_cap(None, future_read_uri), {}), |
---|
259 | + u"fut-unic": (nm.create_from_cap(future_nonascii_read_uri, future_nonascii_read_uri), {}), |
---|
260 | + u"fro-unic": (nm.create_from_cap(None, future_nonascii_read_uri), {}), |
---|
261 | u"empty_litdir": (nm.create_from_cap(empty_litdir_uri), {}), |
---|
262 | u"tiny_litdir": (nm.create_from_cap(tiny_litdir_uri), {}), |
---|
263 | } |
---|
264 | hunk ./src/allmydata/test/test_dirnode.py 106 |
---|
265 | |
---|
266 | def _check_kids(children): |
---|
267 | self.failUnlessEqual(set(children.keys()), |
---|
268 | - set([u"one", u"two", u"mut", u"fut", u"fro", u"empty_litdir", u"tiny_litdir"])) |
---|
269 | + set([u"one", u"two", u"mut", u"fut", u"fro", u"fut-unic", u"fro-unic", u"empty_litdir", u"tiny_litdir"])) |
---|
270 | one_node, one_metadata = children[u"one"] |
---|
271 | two_node, two_metadata = children[u"two"] |
---|
272 | mut_node, mut_metadata = children[u"mut"] |
---|
273 | hunk ./src/allmydata/test/test_dirnode.py 112 |
---|
274 | fut_node, fut_metadata = children[u"fut"] |
---|
275 | fro_node, fro_metadata = children[u"fro"] |
---|
276 | + futna_node, futna_metadata = children[u"fut-unic"] |
---|
277 | + frona_node, frona_metadata = children[u"fro-unic"] |
---|
278 | emptylit_node, emptylit_metadata = children[u"empty_litdir"] |
---|
279 | tinylit_node, tinylit_metadata = children[u"tiny_litdir"] |
---|
280 | |
---|
281 | hunk ./src/allmydata/test/test_dirnode.py 135 |
---|
282 | self.failUnlessEqual(fut_node.get_uri(), future_write_uri) |
---|
283 | self.failUnlessEqual(fut_node.get_readonly_uri(), "ro." + future_read_uri) |
---|
284 | self.failUnless(isinstance(fut_metadata, dict), fut_metadata) |
---|
285 | - |
---|
286 | + |
---|
287 | + self.failUnless(futna_node.is_unknown()) |
---|
288 | + self.failUnlessEqual(futna_node.get_uri(), future_nonascii_write_uri) |
---|
289 | + self.failUnlessEqual(futna_node.get_readonly_uri(), "ro." + future_nonascii_read_uri) |
---|
290 | + self.failUnless(isinstance(futna_metadata, dict), futna_metadata) |
---|
291 | + |
---|
292 | self.failUnless(fro_node.is_unknown()) |
---|
293 | self.failUnlessEqual(fro_node.get_uri(), "ro." + future_read_uri) |
---|
294 | self.failUnlessEqual(fut_node.get_readonly_uri(), "ro." + future_read_uri) |
---|
295 | hunk ./src/allmydata/test/test_dirnode.py 146 |
---|
296 | self.failUnless(isinstance(fro_metadata, dict), fro_metadata) |
---|
297 | |
---|
298 | + self.failUnless(frona_node.is_unknown()) |
---|
299 | + self.failUnlessEqual(frona_node.get_uri(), "ro." + future_nonascii_read_uri) |
---|
300 | + self.failUnlessEqual(futna_node.get_readonly_uri(), "ro." + future_nonascii_read_uri) |
---|
301 | + self.failUnless(isinstance(frona_metadata, dict), frona_metadata) |
---|
302 | + |
---|
303 | self.failIf(emptylit_node.is_unknown()) |
---|
304 | self.failUnlessEqual(emptylit_node.get_storage_index(), None) |
---|
305 | self.failIf(tinylit_node.is_unknown()) |
---|
306 | hunk ./src/allmydata/test/test_dirnode.py 200 |
---|
307 | u"two": (nm.create_from_cap(setup_py_uri), |
---|
308 | {"metakey": "metavalue"}), |
---|
309 | u"fut": (nm.create_from_cap(None, future_read_uri), {}), |
---|
310 | + u"futna": (nm.create_from_cap(None, future_nonascii_read_uri), {}), |
---|
311 | u"empty_litdir": (nm.create_from_cap(empty_litdir_uri), {}), |
---|
312 | u"tiny_litdir": (nm.create_from_cap(tiny_litdir_uri), {}), |
---|
313 | } |
---|
314 | hunk ./src/allmydata/test/test_dirnode.py 223 |
---|
315 | |
---|
316 | def _check_kids(children): |
---|
317 | self.failUnlessEqual(set(children.keys()), |
---|
318 | - set([u"one", u"two", u"fut", u"empty_litdir", u"tiny_litdir"])) |
---|
319 | + set([u"one", u"two", u"fut", u"futna", u"empty_litdir", u"tiny_litdir"])) |
---|
320 | one_node, one_metadata = children[u"one"] |
---|
321 | two_node, two_metadata = children[u"two"] |
---|
322 | fut_node, fut_metadata = children[u"fut"] |
---|
323 | hunk ./src/allmydata/test/test_dirnode.py 227 |
---|
324 | + futna_node, futna_metadata = children[u"futna"] |
---|
325 | emptylit_node, emptylit_metadata = children[u"empty_litdir"] |
---|
326 | tinylit_node, tinylit_metadata = children[u"tiny_litdir"] |
---|
327 | |
---|
328 | hunk ./src/allmydata/test/test_dirnode.py 246 |
---|
329 | self.failUnlessEqual(fut_node.get_readonly_uri(), "imm." + future_read_uri) |
---|
330 | self.failUnless(isinstance(fut_metadata, dict), fut_metadata) |
---|
331 | |
---|
332 | + self.failUnless(futna_node.is_unknown()) |
---|
333 | + self.failUnlessEqual(futna_node.get_uri(), "imm." + future_nonascii_read_uri) |
---|
334 | + self.failUnlessEqual(futna_node.get_readonly_uri(), "imm." + future_nonascii_read_uri) |
---|
335 | + self.failUnless(isinstance(futna_metadata, dict), futna_metadata) |
---|
336 | + |
---|
337 | self.failIf(emptylit_node.is_unknown()) |
---|
338 | self.failUnlessEqual(emptylit_node.get_storage_index(), None) |
---|
339 | self.failIf(tinylit_node.is_unknown()) |
---|
340 | hunk ./src/allmydata/test/test_dirnode.py 1304 |
---|
341 | # Create a mutable directory that contains unknown URI types, and make sure |
---|
342 | # we tolerate them properly. |
---|
343 | d = self.nodemaker.create_new_mutable_directory() |
---|
344 | - future_write_uri = "x-tahoe-crazy://I_am_from_the_future." |
---|
345 | - future_read_uri = "x-tahoe-crazy-readonly://I_am_from_the_future." |
---|
346 | - future_imm_uri = "x-tahoe-crazy-immutable://I_am_from_the_future." |
---|
347 | + future_write_uri = u"x-tahoe-crazy://I_am_from_the_future_fw-蜔쳨欝遃䝦舜琇襇邤䍏㵦☚✸킾궑蒴犏띎냔㳆㼿졨浴䒉ΐ屝稜퍙鉧迴" |
---|
348 | + future_read_uri = u"x-tahoe-crazy-readonly://I_am_from_the_future_fo-ą쳨欝遃䝦舜琇襇邤䍏㵦☚✸킾궑蒴犏띎냔㳆㼿졨浴䒉ΐ屝稜퍙鉧迴" |
---|
349 | + future_imm_uri = u"x-tahoe-crazy-immutable://I_am_from_the_future_fi-Ā쳨欝遃䝦舜琇襇邤䍏㵦☚✸킾궑蒴犏띎냔㳆㼿졨浴䒉ΐ屝稜퍙鉧迴" |
---|
350 | future_node = UnknownNode(future_write_uri, future_read_uri) |
---|
351 | def _then(n): |
---|
352 | self._node = n |
---|
353 | hunk ./src/allmydata/test/test_uri.py 1 |
---|
354 | +# -*- coding: utf-8 -*- |
---|
355 | |
---|
356 | from twisted.trial import unittest |
---|
357 | from allmydata import uri |
---|
358 | hunk ./src/allmydata/test/test_uri.py 233 |
---|
359 | self.failUnless(u2.get_readonly() is None) |
---|
360 | self.failUnless(isinstance(u2.get_error(), CapConstraintError)) |
---|
361 | |
---|
362 | + # Future caps might have non-ASCII chars in them. (Or maybe not, who can tell about the future?) |
---|
363 | + future_uri = u"I am a cap from the †‣‡ future. Whatever you " |
---|
364 | + u = uri.from_string(future_uri) |
---|
365 | + self.failUnless(isinstance(u, uri.UnknownURI)) |
---|
366 | + self.failUnlessEqual(u.to_string(), future_uri) |
---|
367 | + self.failUnless(u.get_readonly() is None) |
---|
368 | + self.failUnless(u.get_error() is None) |
---|
369 | + |
---|
370 | + u2 = uri.UnknownURI(future_uri, error=CapConstraintError("...")) |
---|
371 | + self.failUnlessEqual(u.to_string(), future_uri) |
---|
372 | + self.failUnless(u2.get_readonly() is None) |
---|
373 | + self.failUnless(isinstance(u2.get_error(), CapConstraintError)) |
---|
374 | + |
---|
375 | class Constraint(unittest.TestCase): |
---|
376 | def test_constraint(self): |
---|
377 | good="http://127.0.0.1:3456/uri/URI%3ADIR2%3Agh3l5rbvnv2333mrfvalmjfr4i%3Alz6l7u3z3b7g37s4zkdmfpx5ly4ib4m6thrpbusi6ys62qtc6mma/" |
---|
378 | hunk ./src/allmydata/test/test_web.py 1 |
---|
379 | +# -*- coding: utf-8 -*- |
---|
380 | + |
---|
381 | import os.path, re, urllib |
---|
382 | import simplejson |
---|
383 | from StringIO import StringIO |
---|
384 | hunk ./src/allmydata/test/test_web.py 40 |
---|
385 | |
---|
386 | timeout = 480 # Most of these take longer than 240 seconds on Francois's arm box. |
---|
387 | |
---|
388 | -unknown_rwcap = "lafs://from_the_future" |
---|
389 | -unknown_rocap = "ro.lafs://readonly_from_the_future" |
---|
390 | -unknown_immcap = "imm.lafs://immutable_from_the_future" |
---|
391 | +unknown_rwcap = u"lafs://from_the_future_fw-蜔쳨欝遃䝦舜琇襇邤䍏㵦☚✸킾궑蒴犏띎냔㳆㼿졨浴䒉ΐ屝稜퍙鉧迴" |
---|
392 | +unknown_rocap = u"ro.lafs://readonly_from_the_future_fo-ą쳨欝遃䝦舜琇襇邤䍏㵦☚✸킾궑蒴犏띎냔㳆㼿졨浴䒉ΐ屝稜퍙鉧迴" |
---|
393 | +unknown_immcap = u"imm.lafs://immutable_from_the_future_fi-‡쳨欝遃䝦舜琇襇邤䍏㵦☚✸킾궑蒴犏띎냔㳆㼿졨浴䒉ΐ屝稜퍙鉧迴" |
---|
394 | |
---|
395 | class FakeStatsProvider: |
---|
396 | def get_stats(self): |
---|
397 | } |
---|
398 | |
---|
399 | Context: |
---|
400 | |
---|
401 | [docs: line-wrap README.txt |
---|
402 | zooko@zooko.com**20100518174240 |
---|
403 | Ignore-this: 670a02d360df7de51ebdcf4fae752577 |
---|
404 | ] |
---|
405 | [Hush pyflakes warnings |
---|
406 | Kevan Carstensen <kevan@isnotajoke.com>**20100515184344 |
---|
407 | Ignore-this: fd602c3bba115057770715c36a87b400 |
---|
408 | ] |
---|
409 | [setup: new improved misc/show-tool-versions.py |
---|
410 | zooko@zooko.com**20100516050122 |
---|
411 | Ignore-this: ce9b1de1b35b07d733e6cf823b66335a |
---|
412 | ] |
---|
413 | [Improve code coverage of the Tahoe2PeerSelector tests. |
---|
414 | Kevan Carstensen <kevan@isnotajoke.com>**20100515032913 |
---|
415 | Ignore-this: 793151b63ffa65fdae6915db22d9924a |
---|
416 | ] |
---|
417 | [Remove a comment that no longer makes sense. |
---|
418 | Kevan Carstensen <kevan@isnotajoke.com>**20100514203516 |
---|
419 | Ignore-this: 956983c7e7c7e4477215494dfce8f058 |
---|
420 | ] |
---|
421 | [docs: update docs/architecture.txt to more fully and correctly explain the upload procedure |
---|
422 | zooko@zooko.com**20100514043458 |
---|
423 | Ignore-this: 538b6ea256a49fed837500342092efa3 |
---|
424 | ] |
---|
425 | [Fix up the behavior of #778, per reviewers' comments |
---|
426 | Kevan Carstensen <kevan@isnotajoke.com>**20100514004917 |
---|
427 | Ignore-this: 9c20b60716125278b5456e8feb396bff |
---|
428 | |
---|
429 | - Make some important utility functions clearer and more thoroughly |
---|
430 | documented. |
---|
431 | - Assert in upload.servers_of_happiness that the buckets attributes |
---|
432 | of PeerTrackers passed to it are mutually disjoint. |
---|
433 | - Get rid of some silly non-Pythonisms that I didn't see when I first |
---|
434 | wrote these patches. |
---|
435 | - Make sure that should_add_server returns true when queried about a |
---|
436 | shnum that it doesn't know about yet. |
---|
437 | - Change Tahoe2PeerSelector.preexisting_shares to map a shareid to a set |
---|
438 | of peerids, alter dependencies to deal with that. |
---|
439 | - Remove upload.should_add_servers, because it is no longer necessary |
---|
440 | - Move upload.shares_of_happiness and upload.shares_by_server to a utility |
---|
441 | file. |
---|
442 | - Change some points in Tahoe2PeerSelector. |
---|
443 | - Compute servers_of_happiness using a bipartite matching algorithm that |
---|
444 | we know is optimal instead of an ad-hoc greedy algorithm that isn't. |
---|
445 | - Change servers_of_happiness to just take a sharemap as an argument, |
---|
446 | change its callers to merge existing_shares and used_peers before |
---|
447 | calling it. |
---|
448 | - Change an error message in the encoder to be more appropriate for |
---|
449 | servers of happiness. |
---|
450 | - Clarify the wording of an error message in immutable/upload.py |
---|
451 | - Refactor a happiness failure message to happinessutil.py, and make |
---|
452 | immutable/upload.py and immutable/encode.py use it. |
---|
453 | - Move the word "only" as far to the right as possible in failure |
---|
454 | messages. |
---|
455 | - Use a better definition of progress during peer selection. |
---|
456 | - Do read-only peer share detection queries in parallel, not sequentially. |
---|
457 | - Clean up logging semantics; print the query statistics whenever an |
---|
458 | upload is unsuccessful, not just in one case. |
---|
459 | |
---|
460 | ] |
---|
461 | [Alter the error message when an upload fails, per some comments in #778. |
---|
462 | Kevan Carstensen <kevan@isnotajoke.com>**20091230210344 |
---|
463 | Ignore-this: ba97422b2f9737c46abeb828727beb1 |
---|
464 | |
---|
465 | When I first implemented #778, I just altered the error messages to refer to |
---|
466 | servers where they referred to shares. The resulting error messages weren't |
---|
467 | very good. These are a bit better. |
---|
468 | ] |
---|
469 | [Change "UploadHappinessError" to "UploadUnhappinessError" |
---|
470 | Kevan Carstensen <kevan@isnotajoke.com>**20091205043037 |
---|
471 | Ignore-this: 236b64ab19836854af4993bb5c1b221a |
---|
472 | ] |
---|
473 | [Alter the error message returned when peer selection fails |
---|
474 | Kevan Carstensen <kevan@isnotajoke.com>**20091123002405 |
---|
475 | Ignore-this: b2a7dc163edcab8d9613bfd6907e5166 |
---|
476 | |
---|
477 | The Tahoe2PeerSelector returned either NoSharesError or NotEnoughSharesError |
---|
478 | for a variety of error conditions that weren't informatively described by them. |
---|
479 | This patch creates a new error, UploadHappinessError, replaces uses of |
---|
480 | NoSharesError and NotEnoughSharesError with it, and alters the error message |
---|
481 | raised with the errors to be more in line with the new servers_of_happiness |
---|
482 | behavior. See ticket #834 for more information. |
---|
483 | ] |
---|
484 | [Eliminate overcounting iof servers_of_happiness in Tahoe2PeerSelector; also reorganize some things. |
---|
485 | Kevan Carstensen <kevan@isnotajoke.com>**20091118014542 |
---|
486 | Ignore-this: a6cb032cbff74f4f9d4238faebd99868 |
---|
487 | ] |
---|
488 | [Change stray "shares_of_happiness" to "servers_of_happiness" |
---|
489 | Kevan Carstensen <kevan@isnotajoke.com>**20091116212459 |
---|
490 | Ignore-this: 1c971ba8c3c4d2e7ba9f020577b28b73 |
---|
491 | ] |
---|
492 | [Alter Tahoe2PeerSelector to make sure that it recognizes existing shares on readonly servers, fixing an issue in #778 |
---|
493 | Kevan Carstensen <kevan@isnotajoke.com>**20091116192805 |
---|
494 | Ignore-this: 15289f4d709e03851ed0587b286fd955 |
---|
495 | ] |
---|
496 | [Alter 'immutable/encode.py' and 'immutable/upload.py' to use servers_of_happiness instead of shares_of_happiness. |
---|
497 | Kevan Carstensen <kevan@isnotajoke.com>**20091104111222 |
---|
498 | Ignore-this: abb3283314820a8bbf9b5d0cbfbb57c8 |
---|
499 | ] |
---|
500 | [Alter the signature of set_shareholders in IEncoder to add a 'servermap' parameter, which gives IEncoders enough information to perform a sane check for servers_of_happiness. |
---|
501 | Kevan Carstensen <kevan@isnotajoke.com>**20091104033241 |
---|
502 | Ignore-this: b3a6649a8ac66431beca1026a31fed94 |
---|
503 | ] |
---|
504 | [Alter CiphertextDownloader to work with servers_of_happiness |
---|
505 | Kevan Carstensen <kevan@isnotajoke.com>**20090924041932 |
---|
506 | Ignore-this: e81edccf0308c2d3bedbc4cf217da197 |
---|
507 | ] |
---|
508 | [Revisions of the #778 tests, per reviewers' comments |
---|
509 | Kevan Carstensen <kevan@isnotajoke.com>**20100514012542 |
---|
510 | Ignore-this: 735bbc7f663dce633caeb3b66a53cf6e |
---|
511 | |
---|
512 | - Fix comments and confusing naming. |
---|
513 | - Add tests for the new error messages suggested by David-Sarah |
---|
514 | and Zooko. |
---|
515 | - Alter existing tests for new error messages. |
---|
516 | - Make sure that the tests continue to work with the trunk. |
---|
517 | - Add a test for a mutual disjointedness assertion that I added to |
---|
518 | upload.servers_of_happiness. |
---|
519 | - Fix the comments to correctly reflect read-onlyness |
---|
520 | - Add a test for an edge case in should_add_server |
---|
521 | - Add an assertion to make sure that share redistribution works as it |
---|
522 | should |
---|
523 | - Alter tests to work with revised servers_of_happiness semantics |
---|
524 | - Remove tests for should_add_server, since that function no longer exists. |
---|
525 | - Alter tests to know about merge_peers, and to use it before calling |
---|
526 | servers_of_happiness. |
---|
527 | - Add tests for merge_peers. |
---|
528 | - Add Zooko's puzzles to the tests. |
---|
529 | - Edit encoding tests to expect the new kind of failure message. |
---|
530 | - Edit tests to expect error messages with the word "only" moved as far |
---|
531 | to the right as possible. |
---|
532 | - Extended and cleaned up some helper functions. |
---|
533 | - Changed some tests to call more appropriate helper functions. |
---|
534 | - Added a test for the failing redistribution algorithm |
---|
535 | - Added a test for the progress message |
---|
536 | - Added a test for the upper bound on readonly peer share discovery. |
---|
537 | |
---|
538 | ] |
---|
539 | [Alter various unit tests to work with the new happy behavior |
---|
540 | Kevan Carstensen <kevan@isnotajoke.com>**20100107181325 |
---|
541 | Ignore-this: 132032bbf865e63a079f869b663be34a |
---|
542 | ] |
---|
543 | [Replace "UploadHappinessError" with "UploadUnhappinessError" in tests. |
---|
544 | Kevan Carstensen <kevan@isnotajoke.com>**20091205043453 |
---|
545 | Ignore-this: 83f4bc50c697d21b5f4e2a4cd91862ca |
---|
546 | ] |
---|
547 | [Add tests for the behavior described in #834. |
---|
548 | Kevan Carstensen <kevan@isnotajoke.com>**20091123012008 |
---|
549 | Ignore-this: d8e0aa0f3f7965ce9b5cea843c6d6f9f |
---|
550 | ] |
---|
551 | [Re-work 'test_upload.py' to be more readable; add more tests for #778 |
---|
552 | Kevan Carstensen <kevan@isnotajoke.com>**20091116192334 |
---|
553 | Ignore-this: 7e8565f92fe51dece5ae28daf442d659 |
---|
554 | ] |
---|
555 | [Test Tahoe2PeerSelector to make sure that it recognizeses existing shares on readonly servers |
---|
556 | Kevan Carstensen <kevan@isnotajoke.com>**20091109003735 |
---|
557 | Ignore-this: 12f9b4cff5752fca7ed32a6ebcff6446 |
---|
558 | ] |
---|
559 | [Add more tests for comment:53 in ticket #778 |
---|
560 | Kevan Carstensen <kevan@isnotajoke.com>**20091104112849 |
---|
561 | Ignore-this: 3bb2edd299a944cc9586e14d5d83ec8c |
---|
562 | ] |
---|
563 | [Add a test for upload.shares_by_server |
---|
564 | Kevan Carstensen <kevan@isnotajoke.com>**20091104111324 |
---|
565 | Ignore-this: f9802e82d6982a93e00f92e0b276f018 |
---|
566 | ] |
---|
567 | [Minor tweak to an existing test -- make the first server read-write, instead of read-only |
---|
568 | Kevan Carstensen <kevan@isnotajoke.com>**20091104034232 |
---|
569 | Ignore-this: a951a46c93f7f58dd44d93d8623b2aee |
---|
570 | ] |
---|
571 | [Alter tests to use the new form of set_shareholders |
---|
572 | Kevan Carstensen <kevan@isnotajoke.com>**20091104033602 |
---|
573 | Ignore-this: 3deac11fc831618d11441317463ef830 |
---|
574 | ] |
---|
575 | [Refactor some behavior into a mixin, and add tests for the behavior described in #778 |
---|
576 | "Kevan Carstensen" <kevan@isnotajoke.com>**20091030091908 |
---|
577 | Ignore-this: a6f9797057ca135579b249af3b2b66ac |
---|
578 | ] |
---|
579 | [Alter NoNetworkGrid to allow the creation of readonly servers for testing purposes. |
---|
580 | Kevan Carstensen <kevan@isnotajoke.com>**20091018013013 |
---|
581 | Ignore-this: e12cd7c4ddeb65305c5a7e08df57c754 |
---|
582 | ] |
---|
583 | [Update 'docs/architecture.txt' to reflect readonly share discovery |
---|
584 | kevan@isnotajoke.com**20100514003852 |
---|
585 | Ignore-this: 7ead71b34df3b1ecfdcfd3cb2882e4f9 |
---|
586 | ] |
---|
587 | [Alter the wording in docs/architecture.txt to more accurately describe the servers_of_happiness behavior. |
---|
588 | Kevan Carstensen <kevan@isnotajoke.com>**20100428002455 |
---|
589 | Ignore-this: 6eff7fa756858a1c6f73728d989544cc |
---|
590 | ] |
---|
591 | [Alter wording in 'interfaces.py' to be correct wrt #778 |
---|
592 | "Kevan Carstensen" <kevan@isnotajoke.com>**20091205034005 |
---|
593 | Ignore-this: c9913c700ac14e7a63569458b06980e0 |
---|
594 | ] |
---|
595 | [Update 'docs/configuration.txt' to reflect the servers_of_happiness behavior. |
---|
596 | Kevan Carstensen <kevan@isnotajoke.com>**20091205033813 |
---|
597 | Ignore-this: 5e1cb171f8239bfb5b565d73c75ac2b8 |
---|
598 | ] |
---|
599 | [Clarify quickstart instructions for installing pywin32 |
---|
600 | david-sarah@jacaranda.org**20100511180300 |
---|
601 | Ignore-this: d4668359673600d2acbc7cd8dd44b93c |
---|
602 | ] |
---|
603 | [web: add a simple test that you can load directory.xhtml |
---|
604 | zooko@zooko.com**20100510063729 |
---|
605 | Ignore-this: e49b25fa3c67b3c7a56c8b1ae01bb463 |
---|
606 | ] |
---|
607 | [setup: fix typos in misc/show-tool-versions.py |
---|
608 | zooko@zooko.com**20100510063615 |
---|
609 | Ignore-this: 2181b1303a0e288e7a9ebd4c4855628 |
---|
610 | ] |
---|
611 | [setup: show code-coverage tool versions in show-tools-versions.py |
---|
612 | zooko@zooko.com**20100510062955 |
---|
613 | Ignore-this: 4b4c68eb3780b762c8dbbd22b39df7cf |
---|
614 | ] |
---|
615 | [Dependency on Windmill test framework is not needed yet. |
---|
616 | david-sarah@jacaranda.org**20100504161043 |
---|
617 | Ignore-this: be088712bec650d4ef24766c0026ebc8 |
---|
618 | ] |
---|
619 | [docs: update README, mv it to README.txt, update setup.py |
---|
620 | zooko@zooko.com**20100504094340 |
---|
621 | Ignore-this: 40e28ca36c299ea1fd12d3b91e5b421c |
---|
622 | ] |
---|
623 | [tests: pass z to tar so that BSD tar will know to ungzip |
---|
624 | zooko@zooko.com**20100504090628 |
---|
625 | Ignore-this: 1339e493f255e8fc0b01b70478f23a09 |
---|
626 | ] |
---|
627 | [setup: update comments and URLs in setup.cfg |
---|
628 | zooko@zooko.com**20100504061653 |
---|
629 | Ignore-this: f97692807c74bcab56d33100c899f829 |
---|
630 | ] |
---|
631 | [CLI: Support for https url in option --node-url |
---|
632 | Francois Deppierraz <francois@ctrlaltdel.ch>**20100430185609 |
---|
633 | Ignore-this: 1717176b4d27c877e6bc67a944d9bf34 |
---|
634 | |
---|
635 | This patch modifies the regular expression used for verifying of '--node-url' |
---|
636 | parameter. Support for accessing a Tahoe gateway over HTTPS was already |
---|
637 | present, thanks to Python's urllib. |
---|
638 | |
---|
639 | ] |
---|
640 | [backupdb.did_create_directory: use REPLACE INTO, not INSERT INTO + ignore error |
---|
641 | Brian Warner <warner@lothar.com>**20100428050803 |
---|
642 | Ignore-this: 1fca7b8f364a21ae413be8767161e32f |
---|
643 | |
---|
644 | This handles the case where we upload a new tahoe directory for a |
---|
645 | previously-processed local directory, possibly creating a new dircap (if the |
---|
646 | metadata had changed). Now we replace the old dirhash->dircap record. The |
---|
647 | previous behavior left the old record in place (with the old dircap and |
---|
648 | timestamps), so we'd never stop creating new directories and never converge |
---|
649 | on a null backup. |
---|
650 | ] |
---|
651 | ["tahoe webopen": add --info flag, to get ?t=info |
---|
652 | Brian Warner <warner@lothar.com>**20100424233003 |
---|
653 | Ignore-this: 126b0bb6db340fabacb623d295eb45fa |
---|
654 | |
---|
655 | Also fix some trailing whitespace. |
---|
656 | ] |
---|
657 | [setup: reorder and extend the show-tool-versions script, the better to glean information about our new buildslaves |
---|
658 | zooko@zooko.com**20100504045643 |
---|
659 | Ignore-this: 836084b56b8d4ee8f1de1f4efb706d36 |
---|
660 | ] |
---|
661 | [docs: install.html http-equiv refresh to quickstart.html |
---|
662 | zooko@zooko.com**20100421165708 |
---|
663 | Ignore-this: 52b4b619f9dde5886ae2cd7f1f3b734b |
---|
664 | ] |
---|
665 | [docs: install.html -> quickstart.html |
---|
666 | zooko@zooko.com**20100421155757 |
---|
667 | Ignore-this: 6084e203909306bed93efb09d0e6181d |
---|
668 | It is not called "installing" because that implies that it is going to change the configuration of your operating system. It is not called "building" because that implies that you need developer tools like a compiler. Also I added a stern warning against looking at the "InstallDetails" wiki page, which I have renamed to "AdvancedInstall". |
---|
669 | ] |
---|
670 | [Fix another typo in tahoe_storagespace munin plugin |
---|
671 | david-sarah@jacaranda.org**20100416220935 |
---|
672 | Ignore-this: ad1f7aa66b554174f91dfb2b7a3ea5f3 |
---|
673 | ] |
---|
674 | [Add dependency on windmill >= 1.3 |
---|
675 | david-sarah@jacaranda.org**20100416190404 |
---|
676 | Ignore-this: 4437a7a464e92d6c9012926b18676211 |
---|
677 | ] |
---|
678 | [licensing: phrase the OpenSSL-exemption in the vocabulary of copyright instead of computer technology, and replicate the exemption from the GPL to the TGPPL |
---|
679 | zooko@zooko.com**20100414232521 |
---|
680 | Ignore-this: a5494b2f582a295544c6cad3f245e91 |
---|
681 | ] |
---|
682 | [munin-tahoe_storagespace |
---|
683 | freestorm77@gmail.com**20100221203626 |
---|
684 | Ignore-this: 14d6d6a587afe1f8883152bf2e46b4aa |
---|
685 | |
---|
686 | Plugin configuration rename |
---|
687 | |
---|
688 | ] |
---|
689 | [setup: add licensing declaration for setuptools (noticed by the FSF compliance folks) |
---|
690 | zooko@zooko.com**20100309184415 |
---|
691 | Ignore-this: 2dfa7d812d65fec7c72ddbf0de609ccb |
---|
692 | ] |
---|
693 | [setup: fix error in licensing declaration from Shawn Willden, as noted by the FSF compliance division |
---|
694 | zooko@zooko.com**20100309163736 |
---|
695 | Ignore-this: c0623d27e469799d86cabf67921a13f8 |
---|
696 | ] |
---|
697 | [CREDITS to Jacob Appelbaum |
---|
698 | zooko@zooko.com**20100304015616 |
---|
699 | Ignore-this: 70db493abbc23968fcc8db93f386ea54 |
---|
700 | ] |
---|
701 | [desert-island-build-with-proper-versions |
---|
702 | jacob@appelbaum.net**20100304013858] |
---|
703 | [docs: a few small edits to try to guide newcomers through the docs |
---|
704 | zooko@zooko.com**20100303231902 |
---|
705 | Ignore-this: a6aab44f5bf5ad97ea73e6976bc4042d |
---|
706 | These edits were suggested by my watching over Jake Appelbaum's shoulder as he completely ignored/skipped/missed install.html and also as he decided that debian.txt wouldn't help him with basic installation. Then I threw in a few docs edits that have been sitting around in my sandbox asking to be committed for months. |
---|
707 | ] |
---|
708 | [TAG allmydata-tahoe-1.6.1 |
---|
709 | david-sarah@jacaranda.org**20100228062314 |
---|
710 | Ignore-this: eb5f03ada8ea953ee7780e7fe068539 |
---|
711 | ] |
---|
712 | Patch bundle hash: |
---|
713 | 8d679b706a82f068012361b83fdf2ba6c860595f |
---|