3 from twisted.trial import unittest
4 from twisted.application import service
6 from foolscap import Tub, eventual
7 from foolscap.logging import log
9 from allmydata import upload, offloaded
10 from allmydata.util import hashutil, fileutil, idlib
11 from pycryptopp.cipher.aes import AES
15 class CHKUploadHelper_fake(offloaded.CHKUploadHelper):
16 def start_encrypted(self, eu):
19 d2 = eu.get_all_encoding_parameters()
20 def _got_parms(parms):
21 needed_shares, happy, total_shares, segsize = parms
22 return (hashutil.uri_extension_hash(""),
23 needed_shares, total_shares, size)
24 d2.addCallback(_got_parms)
26 d.addCallback(_got_size)
29 class CHKUploadHelper_already_uploaded(offloaded.CHKUploadHelper):
31 res = {'uri_extension_hash': hashutil.uri_extension_hash("")}
34 class FakeClient(service.MultiService):
35 DEFAULT_ENCODING_PARAMETERS = {"k":25,
38 "max_segment_size": 1*MiB,
40 def log(self, *args, **kwargs):
41 return log.msg(*args, **kwargs)
42 def get_push_to_ourselves(self):
44 def get_encoding_parameters(self):
45 return self.DEFAULT_ENCODING_PARAMETERS
46 def get_permuted_peers(self, storage_index):
49 def flush_but_dont_ignore(res):
50 d = eventual.flushEventualQueue()
56 def upload_data(uploader, data):
58 return uploader.upload(u)
60 class AssistedUpload(unittest.TestCase):
66 t.setServiceParent(self.s)
68 # we never actually use this for network traffic, so it can use a
70 t.setLocation("bogus:1234")
72 def setUpHelper(self, basedir):
73 fileutil.make_dirs(basedir)
74 self.helper = h = offloaded.Helper(basedir)
75 h.chk_upload_helper_class = CHKUploadHelper_fake
76 h.setServiceParent(self.s)
77 self.helper_furl = self.tub.registerReference(h)
80 d = self.s.stopService()
81 d.addCallback(eventual.fireEventually)
82 d.addBoth(flush_but_dont_ignore)
87 self.basedir = "helper/AssistedUpload/test_one"
88 self.setUpHelper(self.basedir)
89 u = upload.Uploader(self.helper_furl)
90 u.setServiceParent(self.s)
93 d = eventual.fireEventually()
94 d.addCallback(eventual.fireEventually)
95 d.addCallback(eventual.fireEventually)
100 DATA = "I need help\n" * 1000
101 return upload_data(u, DATA)
102 d.addCallback(_ready)
105 d.addCallback(_uploaded)
107 def _check_empty(res):
108 files = os.listdir(os.path.join(self.basedir, "CHK_encoding"))
109 self.failUnlessEqual(files, [])
110 files = os.listdir(os.path.join(self.basedir, "CHK_incoming"))
111 self.failUnlessEqual(files, [])
112 d.addCallback(_check_empty)
116 def test_previous_upload_failed(self):
117 self.basedir = "helper/AssistedUpload/test_previous_upload_failed"
118 self.setUpHelper(self.basedir)
119 DATA = "I need help\n" * 1000
121 # we want to make sure that an upload which fails (leaving the
122 # ciphertext in the CHK_encoding/ directory) does not prevent a later
123 # attempt to upload that file from working. We simulate this by
124 # populating the directory manually.
125 key = hashutil.key_hash(DATA)[:16]
127 SI = hashutil.storage_index_hash(key)
129 encfile = os.path.join(self.basedir, "CHK_encoding", SI_s)
130 f = open(encfile, "wb")
131 f.write(encryptor.process(DATA))
134 u = upload.Uploader(self.helper_furl)
135 u.setServiceParent(self.s)
138 d = eventual.fireEventually()
139 d.addCallback(eventual.fireEventually)
140 d.addCallback(eventual.fireEventually)
144 return upload_data(u, DATA)
145 d.addCallback(_ready)
148 d.addCallback(_uploaded)
150 def _check_empty(res):
151 files = os.listdir(os.path.join(self.basedir, "CHK_encoding"))
152 self.failUnlessEqual(files, [])
153 files = os.listdir(os.path.join(self.basedir, "CHK_incoming"))
154 self.failUnlessEqual(files, [])
155 d.addCallback(_check_empty)
159 def test_already_uploaded(self):
160 self.basedir = "helper/AssistedUpload/test_already_uploaded"
161 self.setUpHelper(self.basedir)
162 self.helper.chk_upload_helper_class = CHKUploadHelper_already_uploaded
163 u = upload.Uploader(self.helper_furl)
164 u.setServiceParent(self.s)
167 d = eventual.fireEventually()
168 d.addCallback(eventual.fireEventually)
169 d.addCallback(eventual.fireEventually)
174 DATA = "I need help\n" * 1000
175 return upload_data(u, DATA)
176 d.addCallback(_ready)
179 d.addCallback(_uploaded)
181 def _check_empty(res):
182 files = os.listdir(os.path.join(self.basedir, "CHK_encoding"))
183 self.failUnlessEqual(files, [])
184 files = os.listdir(os.path.join(self.basedir, "CHK_incoming"))
185 self.failUnlessEqual(files, [])
186 d.addCallback(_check_empty)