1 | Sat Feb 20 17:04:55 PST 2010 Kevan Carstensen <kevan@isnotajoke.com> |
---|
2 | * Add tests for the ophandle expiration behavior in #577 |
---|
3 | |
---|
4 | New patches: |
---|
5 | |
---|
6 | [Add tests for the ophandle expiration behavior in #577 |
---|
7 | Kevan Carstensen <kevan@isnotajoke.com>**20100221010455 |
---|
8 | Ignore-this: 87a435108999c24920354b58fd78353f |
---|
9 | ] { |
---|
10 | hunk ./src/allmydata/test/test_web.py 370 |
---|
11 | self.fail("%s was supposed to Error(404), not get '%s'" % |
---|
12 | (which, res)) |
---|
13 | |
---|
14 | + def should302(self, res, which): |
---|
15 | + if isinstance(res, failure.Failure): |
---|
16 | + res.trap(error.Error) |
---|
17 | + self.failUnlessEqual(res.value.status, "302") |
---|
18 | + else: |
---|
19 | + self.fail("%s was supposed to Error(302), not get '%s'" % |
---|
20 | + (which, res)) |
---|
21 | + |
---|
22 | |
---|
23 | class Web(WebMixin, WebErrorMixin, testutil.StallMixin, unittest.TestCase): |
---|
24 | def test_create(self): |
---|
25 | hunk ./src/allmydata/test/test_web.py 2900 |
---|
26 | "/operations/130?t=status&output=JSON")) |
---|
27 | return d |
---|
28 | |
---|
29 | + def test_uncollected_ophandle_expiration(self): |
---|
30 | + # uncollected ophandles should expire after 4 days |
---|
31 | + def _make_uncollected_ophandle(ophandle): |
---|
32 | + d = self.POST(self.public_url + |
---|
33 | + "/foo/?t=start-manifest&ophandle=%d" % ophandle, |
---|
34 | + followRedirect=False) |
---|
35 | + # When we start the operation, the webapi server will want |
---|
36 | + # to redirect us to the page for the ophandle, so we get |
---|
37 | + # confirmation that the operation has started. If the |
---|
38 | + # manifest operation has finished by the time we get there, |
---|
39 | + # following that redirect (by setting followRedirect=True |
---|
40 | + # above) has the side effect of collecting the ophandle that |
---|
41 | + # we've just created, which means that we can't use the |
---|
42 | + # ophandle to test the uncollected timeout anymore. So, |
---|
43 | + # instead, catch the 302 here and don't follow it. |
---|
44 | + d.addBoth(self.should302, "uncollected_ophandle_creation") |
---|
45 | + return d |
---|
46 | + # Create an ophandle, don't collect it, then advance the clock by |
---|
47 | + # 4 days - 1 second and make sure that the ophandle is still there. |
---|
48 | + d = _make_uncollected_ophandle(131) |
---|
49 | + d.addCallback(lambda ign: |
---|
50 | + self.clock.advance((96*60*60) - 1)) # 96 hours = 4 days |
---|
51 | + d.addCallback(lambda ign: |
---|
52 | + self.GET("/operations/131?t=status&output=JSON")) |
---|
53 | + def _check1(res): |
---|
54 | + data = simplejson.loads(res) |
---|
55 | + self.failUnless("finished" in data, res) |
---|
56 | + d.addCallback(_check1) |
---|
57 | + # Create an ophandle, don't collect it, then try to collect it |
---|
58 | + # after 4 days. It should be gone. |
---|
59 | + d.addCallback(lambda ign: |
---|
60 | + _make_uncollected_ophandle(132)) |
---|
61 | + d.addCallback(lambda ign: |
---|
62 | + self.clock.advance(96*60*60)) |
---|
63 | + d.addCallback(lambda ign: |
---|
64 | + self.shouldHTTPError("test_uncollected_ophandle_expired_after_100_hours", |
---|
65 | + 404, "404 Not Found", |
---|
66 | + "unknown/expired handle '132'", |
---|
67 | + self.GET, |
---|
68 | + "/operations/132?t=status&output=JSON")) |
---|
69 | + return d |
---|
70 | + |
---|
71 | + def test_collected_ophandle_expiration(self): |
---|
72 | + # collected ophandles should expire after 1 day |
---|
73 | + def _make_collected_ophandle(ophandle): |
---|
74 | + d = self.POST(self.public_url + |
---|
75 | + "/foo/?t=start-manifest&ophandle=%d" % ophandle, |
---|
76 | + followRedirect=True) |
---|
77 | + # By following the initial redirect, we collect the ophandle |
---|
78 | + # we've just created. |
---|
79 | + return d |
---|
80 | + # Create a collected ophandle, then collect it after 23 hours |
---|
81 | + # and 59 seconds to make sure that it is still there. |
---|
82 | + d = _make_collected_ophandle(133) |
---|
83 | + d.addCallback(lambda ign: |
---|
84 | + self.clock.advance((24*60*60) - 1)) |
---|
85 | + d.addCallback(lambda ign: |
---|
86 | + self.GET("/operations/133?t=status&output=JSON")) |
---|
87 | + def _check1(res): |
---|
88 | + data = simplejson.loads(res) |
---|
89 | + self.failUnless("finished" in data, res) |
---|
90 | + d.addCallback(_check1) |
---|
91 | + # Create another uncollected ophandle, then try to collect it |
---|
92 | + # after 24 hours to make sure that it is gone. |
---|
93 | + d.addCallback(lambda ign: |
---|
94 | + _make_collected_ophandle(134)) |
---|
95 | + d.addCallback(lambda ign: |
---|
96 | + self.clock.advance(24*60*60)) |
---|
97 | + d.addCallback(lambda ign: |
---|
98 | + self.shouldHTTPError("test_collected_ophandle_expired_after_1000_minutes", |
---|
99 | + 404, "404 Not Found", |
---|
100 | + "unknown/expired handle '134'", |
---|
101 | + self.GET, |
---|
102 | + "/operations/134?t=status&output=JSON")) |
---|
103 | + return d |
---|
104 | + |
---|
105 | def test_incident(self): |
---|
106 | d = self.POST("/report_incident", details="eek") |
---|
107 | def _done(res): |
---|
108 | } |
---|
109 | |
---|
110 | Context: |
---|
111 | |
---|
112 | [setup: comment-out the dependency on pycrypto, see #953 |
---|
113 | zooko@zooko.com**20100215050844 |
---|
114 | Ignore-this: 2751120921ff35b8189d8fcd896da149 |
---|
115 | ] |
---|
116 | [web/storage.py: display total-seen on the last-complete-cycle line. For #940. |
---|
117 | Brian Warner <warner@lothar.com>**20100208002010 |
---|
118 | Ignore-this: c0ed860f3e9628d3171d2b055d96c5aa |
---|
119 | ] |
---|
120 | [Add tests for #939 |
---|
121 | Kevan Carstensen <kevan@isnotajoke.com>**20100212062137 |
---|
122 | Ignore-this: 5459e8c64ba76cca70aa720e68549637 |
---|
123 | ] |
---|
124 | [Alter CLI utilities to handle nonexistent aliases better |
---|
125 | Kevan Carstensen <kevan@isnotajoke.com>**20100211024318 |
---|
126 | Ignore-this: e698ea4a57f5fe27c24336581ca0cf65 |
---|
127 | ] |
---|
128 | [adding pycrypto to the auto dependencies |
---|
129 | secorp@allmydata.com**20100206054314 |
---|
130 | Ignore-this: b873fc00a6a5b001d30d479e6053cf2f |
---|
131 | ] |
---|
132 | [docs running.html - "tahoe run ." does not work with the current installation, replaced with "tahoe start ." |
---|
133 | secorp@allmydata.com**20100206165320 |
---|
134 | Ignore-this: fdb2dcb0e417d303cd43b1951a4f8c03 |
---|
135 | ] |
---|
136 | [code coverage: replace figleaf with coverage.py, should work on py2.6 now. |
---|
137 | Brian Warner <warner@lothar.com>**20100203165421 |
---|
138 | Ignore-this: 46ab590360be6a385cb4fc4e68b6b42c |
---|
139 | |
---|
140 | It still lacks the right HTML report (the builtin report is very pretty, but |
---|
141 | lacks the "lines uncovered" numbers that I want), and the half-finished |
---|
142 | delta-from-last-run measurements. |
---|
143 | ] |
---|
144 | [More comprehensive changes and ticket references for NEWS |
---|
145 | david-sarah@jacaranda.org**20100202061256 |
---|
146 | Ignore-this: 696cf0106e8a7fd388afc5b55fba8a1b |
---|
147 | ] |
---|
148 | [docs: install.html: link into Python 2.5.5 download page |
---|
149 | zooko@zooko.com**20100202065852 |
---|
150 | Ignore-this: 1a9471b8175b7de5741d8445a7ede29d |
---|
151 | ] |
---|
152 | [TAG allmydata-tahoe-1.6.0 |
---|
153 | zooko@zooko.com**20100202061125 |
---|
154 | Ignore-this: dee6ade7ac1452cf5d1d9c69a8146d84 |
---|
155 | ] |
---|
156 | Patch bundle hash: |
---|
157 | 2052e1f5d647eee0e79d7123b2e8cbfc6b0efb6b |
---|