1
# Copyright 2008-2015 Canonical
3
# This program is free software: you can redistribute it and/or modify
4
# it under the terms of the GNU Affero General Public License as
5
# published by the Free Software Foundation, either version 3 of the
6
# License, or (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU Affero General Public License for more details.
13
# You should have received a copy of the GNU Affero General Public License
14
# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
# For further info, check http://launchpad.net/filesync-server
18
"""Test cancellation of the action queue's commands."""
22
from cStringIO import StringIO
24
from twisted.internet import defer, error
26
from ubuntuone.storageprotocol import request
27
from ubuntuone.storage.server.testing.aq_helpers import (
35
from ubuntuone.storageprotocol.content_hash import content_hash_factory, crc32
36
from ubuntuone.syncdaemon.marker import MDMarker as Marker
39
class AQCancelTestBase(TestContentBase):
40
"""Things common to TestCancel and TestCancelMarker."""
44
self.connlost_deferred = defer.Deferred()
45
return super(AQCancelTestBase, self).setUp()
48
"""Tear thins down."""
49
self.eq.push('SYS_NET_DISCONNECTED')
50
self.eq.push('SYS_USER_DISCONNECT')
51
return super(AQCancelTestBase, self).tearDown()
54
"""Hiccup the network."""
55
self.eq.push('SYS_NET_DISCONNECTED')
56
self.eq.push('SYS_USER_DISCONNECT')
57
self.connlost_deferred.errback(error.ConnectionLost())
58
self.eq.push('SYS_CONNECTION_LOST')
59
self.eq.push('SYS_USER_CONNECT',
60
access_token=self.access_tokens['jack'])
61
self.eq.push('SYS_NET_CONNECTED')
62
return self.wait_for_nirvana(.1)
65
class TestCancel(AQCancelTestBase):
66
"""Cancellation of non-marker-related things."""
68
def test_list_shares(self):
69
"""Hiccup the network in the middle of a list_shares."""
74
d = self.nuke_client_method('query', worker,
75
lambda: self.connlost_deferred)
76
self.assertInQ(d, ('AQ_SHARES_LIST', {'shares_list':
80
def test_create_share(self):
81
"""Hiccup the network in the middle of a create_share."""
84
self.aq.create_share(self.root, 'jack', '', 'View', 'marker:x', '')
86
d = self.nuke_client_method('create_share', worker,
87
lambda: self.connlost_deferred)
88
self.assertInQ(d, ('AQ_CREATE_SHARE_OK',
89
{'marker': 'marker:x',
90
'share_id': aShareUUID}))
93
def test_answer_share(self):
94
"""Hiccup the network in the middle of an answer_share."""
97
share_id = self.listener.get_id_for_marker('marker:x')
98
self.aq.answer_share(share_id, 'Yes')
100
d = self.wait_for_nirvana()
101
d.addCallback(lambda _: self.nuke_client_method(
102
'accept_share', worker, lambda: self.connlost_deferred))
104
self.aq.create_share(self.root, 'jack', '', 'View', 'marker:x', '')
105
self.assertInQ(d, ('AQ_ANSWER_SHARE_OK',
106
{'answer': 'Yes', 'share_id': anUUID}))
109
def test_unlink(self):
110
"""Hiccup the network in the middle of an unlink."""
113
new_id = self.listener.get_id_for_marker('marker:x')
114
self.aq.unlink('', self.root, new_id, '', False)
116
d = self.wait_for_nirvana()
117
d.addCallback(lambda _: self.nuke_client_method(
118
'unlink', worker, lambda: self.connlost_deferred))
120
parent_path = self.main.fs.get_by_node_id('', self.root).path
121
mdid = self.main.fs.create(os.path.join(parent_path, u"test"), '')
122
self.aq.make_file('', self.root, 'hola', 'marker:x', mdid)
123
self.assertInQ(d, ('AQ_UNLINK_OK', {'share_id': '',
125
'parent_id': self.root,
128
'new_generation': 2L}))
132
"""Hiccup the network in the middle of a move."""
135
new_id = self.listener.get_id_for_marker('marker:x')
136
self.aq.move('', new_id, self.root, self.root,
137
'chau', 'from', 'to')
139
d = self.wait_for_nirvana()
140
d.addCallback(lambda _: self.nuke_client_method(
141
'move', worker, lambda: self.connlost_deferred))
142
parent_path = self.main.fs.get_by_node_id('', self.root).path
143
mdid = self.main.fs.create(os.path.join(parent_path, u"test"), '')
144
self.aq.make_file('', self.root, 'hola', 'marker:x', mdid)
146
self.assertInQ(d, ('AQ_MOVE_OK', {'share_id': '',
148
'new_generation': 2L}))
151
def test_make_file(self):
152
"""Hiccup the network in the middle of a make_file."""
155
parent_path = self.main.fs.get_by_node_id('', self.root).path
156
mdid = self.main.fs.create(os.path.join(parent_path, u"test"), '')
157
self.aq.make_file('', self.root, 'hola', 'marker:x', mdid)
159
d = self.nuke_client_method('make_file', worker,
160
lambda: self.connlost_deferred)
161
self.assertInQ(d, ('AQ_FILE_NEW_OK', {'new_id': anUUID,
162
'marker': 'marker:x',
163
'new_generation': 1L,
164
'volume_id': request.ROOT}))
167
@defer.inlineCallbacks
168
def test_download(self):
169
"""Hiccup the network in the middle of a download."""
170
self.patch(self.main.fs, 'get_partial_for_writing',
171
lambda s, n: StringIO())
172
hash_value, _, _, d = self._mk_file_w_content()
173
mdid, node_id = yield d
177
self.aq.download('', node_id, hash_value, mdid)
179
fake_gc = FakeGetContent(self.connlost_deferred, '',
180
self.root, hash_value)
181
d = self.nuke_client_method('get_content_request', worker,
183
self.assertInQ(d, ('AQ_DOWNLOAD_COMMIT',
186
'server_hash': hash_value}))
189
@defer.inlineCallbacks
190
def test_upload(self):
191
"""Hiccup the network in the middle of an upload."""
192
data = os.urandom(1000)
193
hash_object = content_hash_factory()
194
hash_object.update(data)
195
hash_value = hash_object.content_hash()
196
crc32_value = crc32(data)
198
self.patch(self.main.fs, 'open_file', lambda mdid: StringIO(data))
199
mdid, node_id = yield self._mkfile('hola')
203
self.aq.upload('', node_id, NO_CONTENT_HASH, hash_value,
204
crc32_value, size, mdid)
206
d = self.wait_for_nirvana()
207
d.addCallback(lambda _: self.nuke_client_method(
208
'put_content_request', worker, lambda: self.connlost_deferred))
210
self.assertInQ(d, lambda: ('AQ_UPLOAD_FINISHED',
214
'new_generation': 2L}))
218
class TestCancelMarker(AQCancelTestBase):
219
"""Cancellation of marker-related things."""
221
@defer.inlineCallbacks
224
yield super(TestCancelMarker, self).setUp()
225
self.marker = Marker('marker')
227
def test_create_share(self):
228
"""Hiccup the network in the middle of a create_share."""
231
dir_path = os.path.join(self.main.root_dir, 'testdir')
232
mdid = self.main.fs.create(dir_path, request.ROOT)
233
marker = Marker(mdid)
234
self.aq.make_dir('', self.root, 'hola', marker, mdid)
235
self.aq.create_share(marker, 'jack', '', 'View', 'marker:x', '')
237
d = self.nuke_client_method('make_dir', worker)
238
self.assertInQ(d, ('AQ_CREATE_SHARE_OK',
239
{'marker': 'marker:x',
240
'share_id': aShareUUID}))
243
def test_unlink(self):
244
"""Hiccup the network in the middle of an unlink."""
247
dir_path = os.path.join(self.main.root_dir, 'testdir')
248
mdid = self.main.fs.create(dir_path, request.ROOT)
249
marker = Marker(mdid)
250
self.aq.make_dir('', self.root, 'hola', marker, mdid)
251
self.aq.unlink('', self.root, marker, 'dir', False)
253
d = self.nuke_client_method('make_dir', worker)
255
self.assertInQ(d, ('AQ_UNLINK_OK', {'share_id': '',
257
'parent_id': self.root,
260
'new_generation': 2L}))
264
"""Hiccup the network in the middle of a move."""
267
dir_path = os.path.join(self.main.root_dir, 'testdir')
268
mdid = self.main.fs.create(dir_path, request.ROOT)
269
marker = Marker(mdid)
270
self.aq.make_dir('', self.root, 'hola', marker, mdid)
271
self.aq.move('', marker, self.root, self.root, 'chau', 'dir', 'to')
273
d = self.nuke_client_method('make_dir', worker)
274
self.assertInQ(d, ('AQ_MOVE_OK', {'share_id': '',
276
'new_generation': 2L}))
279
def test_make_file(self):
280
"""Hiccup the network in the middle of a make_file."""
283
dir_path = os.path.join(self.main.root_dir, 'testdir')
284
mdid = self.main.fs.create(dir_path, request.ROOT)
285
marker = Marker(mdid)
286
self.aq.make_dir('', self.root, 'chau', marker, mdid)
287
file_path = os.path.join(dir_path, 'testfile')
288
mdid = self.main.fs.create(file_path, request.ROOT)
289
self.aq.make_file('', marker, 'hola', 'marker:x', mdid)
292
d = self.nuke_client_method('make_dir', worker)
293
self.assertInQ(d, ('AQ_FILE_NEW_OK', {'new_id': anUUID,
294
'marker': 'marker:x',
295
'new_generation': 2L,
296
'volume_id': request.ROOT}))