source: trunk/src/allmydata/test/mutable/test_checker.py

Last change on this file was 1cfe843d, checked in by Alexandre Detiste <alexandre.detiste@…>, at 2024-02-22T23:40:25Z

more python2 removal

  • Property mode set to 100644
File size: 10.0 KB
Line 
1"""
2Ported to Python 3.
3"""
4
5from ..common import AsyncTestCase
6from foolscap.api import flushEventualQueue
7from allmydata.monitor import Monitor
8from allmydata.mutable.common import CorruptShareError
9from .util import PublishMixin, corrupt, CheckerMixin
10
11class Checker(AsyncTestCase, CheckerMixin, PublishMixin):
12    def setUp(self):
13        super(Checker, self).setUp()
14        return self.publish_one()
15
16
17    def test_check_good(self):
18        d = self._fn.check(Monitor())
19        d.addCallback(self.check_good, "test_check_good")
20        return d
21
22    def test_check_mdmf_good(self):
23        d = self.publish_mdmf()
24        d.addCallback(lambda ignored:
25            self._fn.check(Monitor()))
26        d.addCallback(self.check_good, "test_check_mdmf_good")
27        return d
28
29    def test_check_no_shares(self):
30        for shares in list(self._storage._peers.values()):
31            shares.clear()
32        d = self._fn.check(Monitor())
33        d.addCallback(self.check_bad, "test_check_no_shares")
34        return d
35
36    def test_check_mdmf_no_shares(self):
37        d = self.publish_mdmf()
38        def _then(ignored):
39            for share in list(self._storage._peers.values()):
40                share.clear()
41        d.addCallback(_then)
42        d.addCallback(lambda ignored:
43            self._fn.check(Monitor()))
44        d.addCallback(self.check_bad, "test_check_mdmf_no_shares")
45        return d
46
47    def test_check_not_enough_shares(self):
48        for shares in list(self._storage._peers.values()):
49            for shnum in list(shares.keys()):
50                if shnum > 0:
51                    del shares[shnum]
52        d = self._fn.check(Monitor())
53        d.addCallback(self.check_bad, "test_check_not_enough_shares")
54        return d
55
56    def test_check_mdmf_not_enough_shares(self):
57        d = self.publish_mdmf()
58        def _then(ignored):
59            for shares in list(self._storage._peers.values()):
60                for shnum in list(shares.keys()):
61                    if shnum > 0:
62                        del shares[shnum]
63        d.addCallback(_then)
64        d.addCallback(lambda ignored:
65            self._fn.check(Monitor()))
66        d.addCallback(self.check_bad, "test_check_mdmf_not_enougH_shares")
67        return d
68
69
70    def test_check_all_bad_sig(self):
71        d = corrupt(None, self._storage, 1) # bad sig
72        d.addCallback(lambda ignored:
73            self._fn.check(Monitor()))
74        d.addCallback(self.check_bad, "test_check_all_bad_sig")
75        return d
76
77    def test_check_mdmf_all_bad_sig(self):
78        d = self.publish_mdmf()
79        d.addCallback(lambda ignored:
80            corrupt(None, self._storage, 1))
81        d.addCallback(lambda ignored:
82            self._fn.check(Monitor()))
83        d.addCallback(self.check_bad, "test_check_mdmf_all_bad_sig")
84        return d
85
86    def test_verify_mdmf_all_bad_sharedata(self):
87        d = self.publish_mdmf()
88        # On 8 of the shares, corrupt the beginning of the share data.
89        # The signature check during the servermap update won't catch this.
90        d.addCallback(lambda ignored:
91            corrupt(None, self._storage, "share_data", list(range(8))))
92        # On 2 of the shares, corrupt the end of the share data.
93        # The signature check during the servermap update won't catch
94        # this either, and the retrieval process will have to process
95        # all of the segments before it notices.
96        d.addCallback(lambda ignored:
97            # the block hash tree comes right after the share data, so if we
98            # corrupt a little before the block hash tree, we'll corrupt in the
99            # last block of each share.
100            corrupt(None, self._storage, "block_hash_tree", [8, 9], -5))
101        d.addCallback(lambda ignored:
102            self._fn.check(Monitor(), verify=True))
103        # The verifier should flag the file as unhealthy, and should
104        # list all 10 shares as bad.
105        d.addCallback(self.check_bad, "test_verify_mdmf_all_bad_sharedata")
106        def _check_num_bad(r):
107            self.failIf(r.is_recoverable())
108            smap = r.get_servermap()
109            self.failUnlessEqual(len(smap.get_bad_shares()), 10)
110        d.addCallback(_check_num_bad)
111        return d
112
113    def test_check_all_bad_blocks(self):
114        d = corrupt(None, self._storage, "share_data", [9]) # bad blocks
115        # the Checker won't notice this.. it doesn't look at actual data
116        d.addCallback(lambda ignored:
117            self._fn.check(Monitor()))
118        d.addCallback(self.check_good, "test_check_all_bad_blocks")
119        return d
120
121
122    def test_check_mdmf_all_bad_blocks(self):
123        d = self.publish_mdmf()
124        d.addCallback(lambda ignored:
125            corrupt(None, self._storage, "share_data"))
126        d.addCallback(lambda ignored:
127            self._fn.check(Monitor()))
128        d.addCallback(self.check_good, "test_check_mdmf_all_bad_blocks")
129        return d
130
131    def test_verify_good(self):
132        d = self._fn.check(Monitor(), verify=True)
133        d.addCallback(self.check_good, "test_verify_good")
134        return d
135
136    def test_verify_all_bad_sig(self):
137        d = corrupt(None, self._storage, 1) # bad sig
138        d.addCallback(lambda ignored:
139            self._fn.check(Monitor(), verify=True))
140        d.addCallback(self.check_bad, "test_verify_all_bad_sig")
141        return d
142
143    def test_verify_one_bad_sig(self):
144        d = corrupt(None, self._storage, 1, [9]) # bad sig
145        d.addCallback(lambda ignored:
146            self._fn.check(Monitor(), verify=True))
147        d.addCallback(self.check_bad, "test_verify_one_bad_sig")
148        return d
149
150    def test_verify_one_bad_block(self):
151        d = corrupt(None, self._storage, "share_data", [9]) # bad blocks
152        # the Verifier *will* notice this, since it examines every byte
153        d.addCallback(lambda ignored:
154            self._fn.check(Monitor(), verify=True))
155        d.addCallback(self.check_bad, "test_verify_one_bad_block")
156        d.addCallback(self.check_expected_failure,
157                      CorruptShareError, "block hash tree failure",
158                      "test_verify_one_bad_block")
159        return d
160
161    def test_verify_one_bad_sharehash(self):
162        d = corrupt(None, self._storage, "share_hash_chain", [9], 5)
163        d.addCallback(lambda ignored:
164            self._fn.check(Monitor(), verify=True))
165        d.addCallback(self.check_bad, "test_verify_one_bad_sharehash")
166        d.addCallback(self.check_expected_failure,
167                      CorruptShareError, "corrupt hashes",
168                      "test_verify_one_bad_sharehash")
169        return d
170
171    def test_verify_one_bad_encprivkey(self):
172        d = corrupt(None, self._storage, "enc_privkey", [9]) # bad privkey
173        d.addCallback(lambda ignored:
174            self._fn.check(Monitor(), verify=True))
175        d.addCallback(self.check_bad, "test_verify_one_bad_encprivkey")
176        d.addCallback(self.check_expected_failure,
177                      CorruptShareError, "invalid privkey",
178                      "test_verify_one_bad_encprivkey")
179        return d
180
181    def test_verify_one_bad_encprivkey_uncheckable(self):
182        d = corrupt(None, self._storage, "enc_privkey", [9]) # bad privkey
183        readonly_fn = self._fn.get_readonly()
184        # a read-only node has no way to validate the privkey
185        d.addCallback(lambda ignored:
186            readonly_fn.check(Monitor(), verify=True))
187        d.addCallback(self.check_good,
188                      "test_verify_one_bad_encprivkey_uncheckable")
189        return d
190
191
192    def test_verify_mdmf_good(self):
193        d = self.publish_mdmf()
194        d.addCallback(lambda ignored:
195            self._fn.check(Monitor(), verify=True))
196        d.addCallback(self.check_good, "test_verify_mdmf_good")
197        return d
198
199
200    def test_verify_mdmf_one_bad_block(self):
201        d = self.publish_mdmf()
202        d.addCallback(lambda ignored:
203            corrupt(None, self._storage, "share_data", [1]))
204        d.addCallback(lambda ignored:
205            self._fn.check(Monitor(), verify=True))
206        # We should find one bad block here
207        d.addCallback(self.check_bad, "test_verify_mdmf_one_bad_block")
208        d.addCallback(self.check_expected_failure,
209                      CorruptShareError, "block hash tree failure",
210                      "test_verify_mdmf_one_bad_block")
211        return d
212
213
214    def test_verify_mdmf_bad_encprivkey(self):
215        d = self.publish_mdmf()
216        d.addCallback(lambda ignored:
217            corrupt(None, self._storage, "enc_privkey", [0]))
218        d.addCallback(lambda ignored:
219            self._fn.check(Monitor(), verify=True))
220        d.addCallback(self.check_bad, "test_verify_mdmf_bad_encprivkey")
221        d.addCallback(self.check_expected_failure,
222                      CorruptShareError, "privkey",
223                      "test_verify_mdmf_bad_encprivkey")
224        return d
225
226
227    def test_verify_mdmf_bad_sig(self):
228        d = self.publish_mdmf()
229        d.addCallback(lambda ignored:
230            corrupt(None, self._storage, 1, [1]))
231        d.addCallback(lambda ignored:
232            self._fn.check(Monitor(), verify=True))
233        d.addCallback(self.check_bad, "test_verify_mdmf_bad_sig")
234        return d
235
236
237    def test_verify_mdmf_bad_encprivkey_uncheckable(self):
238        d = self.publish_mdmf()
239        d.addCallback(lambda ignored:
240            corrupt(None, self._storage, "enc_privkey", [1]))
241        d.addCallback(lambda ignored:
242            self._fn.get_readonly())
243        d.addCallback(lambda fn:
244            fn.check(Monitor(), verify=True))
245        d.addCallback(self.check_good,
246                      "test_verify_mdmf_bad_encprivkey_uncheckable")
247        return d
248
249    def test_verify_sdmf_empty(self):
250        d = self.publish_sdmf(b"")
251        d.addCallback(lambda ignored: self._fn.check(Monitor(), verify=True))
252        d.addCallback(self.check_good, "test_verify_sdmf")
253        d.addCallback(flushEventualQueue)
254        return d
255
256    def test_verify_mdmf_empty(self):
257        d = self.publish_mdmf(b"")
258        d.addCallback(lambda ignored: self._fn.check(Monitor(), verify=True))
259        d.addCallback(self.check_good, "test_verify_mdmf")
260        d.addCallback(flushEventualQueue)
261        return d
Note: See TracBrowser for help on using the repository browser.