121
123
event_q.subscribe(listener)
124
def _create_udf(self, id, node_id, suggested_path, subscribed=True,
125
generation=None, free_bytes=100):
126
def _create_udf(self, volume_id=None, node_id=None,
127
suggested_path='~/Documents',
128
subscribed=True, generation=None, free_bytes=100):
126
129
"""Create an UDF and returns it and the volume"""
127
130
with environ('HOME', self.home_dir):
128
131
path = get_udf_path(suggested_path)
129
132
# make sure suggested_path is unicode
130
133
if isinstance(suggested_path, str):
131
134
suggested_path = suggested_path.decode('utf-8')
132
volume = volumes.UDFVolume(id, node_id, generation,
136
if volume_id is None:
137
volume_id = str(uuid.uuid4())
139
node_id = str(uuid.uuid4())
141
volume = volumes.UDFVolume(volume_id, node_id, generation,
133
142
free_bytes, suggested_path)
134
143
udf = UDF.from_udf_volume(volume, path)
135
144
udf.subscribed = subscribed
136
145
udf.generation = generation
148
def _create_share_volume(self, volume_id=None, node_id=None,
149
name='fake_share', generation=None, free_bytes=10,
150
access_level='View', accepted=True,
151
other_visible_name='visible_username'):
152
"""Return a new ShareVolume."""
153
if volume_id is None:
154
volume_id = str(uuid.uuid4())
156
node_id = str(uuid.uuid4())
158
share_volume = volumes.ShareVolume(volume_id=volume_id,
159
node_id=node_id, generation=generation,
160
free_bytes=free_bytes, direction='to_me',
161
share_name=name, other_username='username',
162
other_visible_name=other_visible_name,
163
accepted=accepted, access_level=access_level)
166
def _create_share(self, volume_id=None, node_id=None, name='fake_share',
167
generation=None, free_bytes=1024,
168
access_level='View', accepted=True, subscribed=False,
169
other_visible_name='visible_username'):
170
"""Return a new Share."""
171
share_volume = self._create_share_volume(volume_id=volume_id,
172
node_id=node_id, name=name, generation=generation,
173
free_bytes=free_bytes, access_level=access_level,
174
accepted=accepted, other_visible_name=other_visible_name)
175
dir_name = get_share_path(share_volume)
176
share_path = os.path.join(self.shares_dir, dir_name)
177
share = Share.from_share_volume(share_volume, share_path)
178
share.subscribed = subscribed
179
share.accepted = accepted
140
183
class VolumeManagerTests(BaseVolumeManagerTests):
175
218
self.vm._got_root('other_root_uuid')
178
def test_add_share(self):
179
""" test the add_share method. """
180
# initialize the the root
181
self.vm._got_root('root_uuid')
182
share_path = os.path.join(self.shares_dir, 'fake_share')
183
share = Share(path=share_path, volume_id='share_id')
184
self.vm.add_share(share)
185
self.assertIn(share.volume_id, self.vm.shares)
222
class VolumeManagerSharesTests(BaseVolumeManagerTests):
223
"""Tests for Volume Manager Shares management."""
225
def test_share_is_equal(self):
226
"""Test for share comparison."""
227
share1 = self._create_share(volume_id='volume_id', node_id='node_id',
229
share2 = self._create_share(volume_id='volume_id', node_id='node_id',
232
self.assertEqual(share1, share2)
234
def test_share_is_not_equal(self):
235
"""Test for share comparison."""
236
share1 = self._create_share(volume_id='volume_id', node_id='node_id',
238
share2 = self._create_share(volume_id='volume_id', node_id='node_id',
241
self.assertNotEqual(share1, share2)
243
@defer.inlineCallbacks
244
def test_add_share_access_level_view(self):
245
"""Test for add_share for a View share."""
246
share = self._create_share(access_level='View', subscribed=False)
247
yield self.vm.add_share(share)
249
dir_name = get_share_path(share)
250
share_path = os.path.join(self.shares_dir, dir_name)
251
self.assertEqual(share_path, share.path)
252
self.assertEqual(2, len(self.vm.shares)) # root and share
253
self.assertIn(share.volume_id, self.vm.shares)
255
# check that the share is in the fsm metadata
256
mdobj = self.main.fs.get_by_path(share.path)
257
self.assertEqual(mdobj.node_id, share.node_id)
258
self.assertEqual(mdobj.share_id, share.volume_id)
260
# check that there isn't a watch in the share (subscribed is False)
261
self.assertFalse(self.main.event_q.has_watch(share.path))
264
self.vm.share_deleted(share.volume_id)
266
# add it again, but this time with subscribed = True
267
share.subscribed = True
268
yield self.vm.add_share(share)
270
self.assertEqual(share_path, share.path)
271
self.assertEqual(2, len(self.vm.shares))
272
self.assertIn(share.volume_id, self.vm.shares)
274
# check that the share is in the fsm metadata
275
mdobj = self.main.fs.get_by_path(share.path)
276
self.assertEqual(mdobj.node_id, share.node_id)
277
self.assertEqual(mdobj.share_id, share.volume_id)
279
# check that there isn't a watch in the share (subscribed is False)
280
self.assertFalse(self.main.event_q.has_watch(share.path))
282
@defer.inlineCallbacks
283
def test_add_share_access_level_modify(self):
284
"""Test for add_share for a Modify share."""
285
share = self._create_share(access_level='Modify', subscribed=False)
286
yield self.vm.add_share(share)
288
dir_name = get_share_path(share)
289
share_path = os.path.join(self.shares_dir, dir_name)
290
self.assertEqual(share_path, share.path)
291
self.assertEqual(2, len(self.vm.shares)) # root and share
292
self.assertIn(share.volume_id, self.vm.shares)
294
# check that the share is in the fsm metadata
295
mdobj = self.main.fs.get_by_path(share.path)
296
self.assertEqual(mdobj.node_id, share.node_id)
297
self.assertEqual(mdobj.share_id, share.volume_id)
299
# check that there isn't a watch in the share (subscribed is False)
300
self.assertFalse(self.main.event_q.has_watch(share.path))
303
self.vm.share_deleted(share.volume_id)
305
# add it again, but this time with subscribed = True
306
share.subscribed = True
307
yield self.vm.add_share(share)
309
self.assertEqual(share_path, share.path)
310
self.assertEqual(2, len(self.vm.shares))
311
self.assertIn(share.volume_id, self.vm.shares)
313
# check that the share is in the fsm metadata
314
mdobj = self.main.fs.get_by_path(share.path)
315
self.assertEqual(mdobj.node_id, share.node_id)
316
self.assertEqual(mdobj.share_id, share.volume_id)
318
# check that there is a watch in the share
319
self.assertTrue(self.main.event_q.has_watch(share.path))
321
@defer.inlineCallbacks
322
def test_add_share_view_does_not_local_scan_share(self):
323
"""Test that add_share does not scan the View share."""
324
share = self._create_share(access_level='View', subscribed=True)
326
self.patch(self.main.lr, 'scan_dir', lambda *a, **kw: self.fail(a))
327
server_rescan_d = defer.Deferred()
328
self.main.action_q.rescan_from_scratch = server_rescan_d.callback
330
yield self.vm.add_share(share)
332
yield server_rescan_d
334
self.assertEqual(2, len(self.vm.shares))
335
mdobj = self.main.fs.get_by_path(share.path)
336
# check that the share is in the fsm metadata
337
self.assertEqual(mdobj.node_id, share.node_id)
338
self.assertEqual(mdobj.share_id, share.volume_id)
339
self.assertTrue(share.subscribed)
340
self.assertFalse(self.main.event_q.has_watch(share.path))
342
@defer.inlineCallbacks
343
def test_add_share_modify_scans_share(self):
344
"""Test that add_share scans the share."""
345
share = self._create_share(access_level='Modify', subscribed=True)
347
scan_d = defer.Deferred()
349
def fake_scan_dir(mdid, path, udfmode):
350
"""A fake scan share that check the arguments."""
351
mdobj = self.main.fs.get_by_path(share.path)
352
# check that the share is in the fsm metadata
353
self.assertEqual(mdobj.node_id, share.node_id)
354
self.assertEqual(mdobj.share_id, share.volume_id)
355
self.assertEqual(mdid, mdobj.mdid)
356
self.assertEqual(path, share.path)
357
self.assertTrue(udfmode)
358
scan_d.callback(None)
361
self.patch(self.main.lr, 'scan_dir', fake_scan_dir)
363
scratch_d = defer.Deferred()
364
def fake_rescan_from_scratch(volume_id):
365
"""A fake scan share that check the arguments."""
366
self.assertEqual(share.volume_id, volume_id)
367
scratch_d.callback(None)
369
self.main.action_q.rescan_from_scratch = fake_rescan_from_scratch
371
yield self.vm.add_share(share)
375
self.assertEqual(2, len(self.vm.shares))
376
self.assertTrue(share.subscribed)
377
self.assertTrue(self.main.event_q.has_watch(share.path))
379
@defer.inlineCallbacks
187
380
def test_share_deleted(self):
188
""" Check that a share is deleted from the share mapping. """
189
# initialize the the root
190
self.vm._got_root('root_uuid')
191
share_path = os.path.join(self.shares_dir, 'fake_share')
192
share = Share(path=share_path, volume_id='share_id')
193
self.vm.add_share(share)
381
"""Test for share_deleted when empty."""
382
share = self._create_share()
383
yield self.vm.add_share(share)
385
self.assertEqual(2, len(self.vm.shares)) # root and share
194
386
self.assertIn(share.volume_id, self.vm.shares)
195
388
self.vm.share_deleted(share.volume_id)
390
self.assertEqual(1, len(self.vm.shares))
196
391
self.assertNotIn(share.volume_id, self.vm.shares)
393
# check that the share isn't in the fsm metadata
394
self.assertRaises(KeyError, self.main.fs.get_by_path, share.path)
395
# check that there isn't a watch in the share
396
self.assertFalse(self.main.event_q.has_watch(share.path))
398
@defer.inlineCallbacks
198
399
def test_share_deleted_with_content(self):
199
""" Check that a share is deleted from the share mapping. """
200
# initialize the the root
201
self.vm._got_root('root_uuid')
202
share_path = os.path.join(self.shares_dir, 'fake_share')
203
share = Share(path=share_path, volume_id='share_id',
204
node_id='share_node_id', access_level='Modify',
206
self.vm.add_share(share)
400
"""Test for share_deleted when non empty."""
401
share = self._create_share(access_level='Modify',
402
accepted=True, subscribed=True)
403
yield self.vm.add_share(share)
404
self.assertEqual(2, len(self.vm.shares))
207
406
# create a few files and directories
208
407
dirs = ['dir', 'dir/subdir', 'dir/empty_dir']
209
408
for i, dir in enumerate(dirs):
794
1000
self.assertEqual(set(defined_args[1:]), set(evtargs))
1003
class ViewSharesSubscriptionTests(BaseVolumeManagerTests):
1004
"""Test Shares subscription operations when access_level is View."""
1006
access_level = 'View'
1008
@defer.inlineCallbacks
1009
def test_subscribe_share(self):
1010
"""Test subscribe_share method."""
1011
share = self._create_share(access_level=self.access_level,
1013
yield self.vm.add_share(share)
1014
self.assertFalse(self.vm.shares[share.volume_id].subscribed)
1016
yield self.vm.subscribe_share(share.volume_id)
1017
self.assertTrue(self.vm.shares[share.volume_id].subscribed)
1019
@defer.inlineCallbacks
1020
def test_subscribe_share_missing_path(self):
1021
"""Test subscribe_share with a missing path """
1022
share = self._create_share(access_level=self.access_level,
1024
yield self.vm.add_share(share)
1025
self.assertFalse(os.path.exists(share.path))
1026
self.assertFalse(self.vm.shares[share.id].subscribed)
1028
yield self.vm.subscribe_share(share.id)
1029
self.assertTrue(self.vm.shares[share.id].subscribed)
1030
self.assertTrue(os.path.exists(share.path))
1032
@defer.inlineCallbacks
1033
def test_subscribe_share_missing_volume(self):
1034
"""Test subscribe_share with a invalid volume_id."""
1036
yield self.vm.subscribe_share('invalid_share_id')
1037
except VolumeDoesNotExist, e:
1038
self.assertEquals('DOES_NOT_EXIST', e.args[0])
1039
self.assertEquals('invalid_share_id', e.args[1])
1041
self.fail('Must get a VolumeDoesNotExist!')
1043
@defer.inlineCallbacks
1044
def test_unsubscribe_share(self):
1045
"""Test unsubscribe_share method."""
1046
share = self._create_share(access_level=self.access_level,
1048
yield self.vm.add_share(share)
1049
self.assertTrue(self.vm.shares[share.volume_id].subscribed)
1050
# unsubscribe from it
1051
self.vm.unsubscribe_share(share.volume_id)
1052
self.assertFalse(self.vm.shares[share.volume_id].subscribed)
1054
@defer.inlineCallbacks
1055
def test_unsubscribe_share_with_content(self):
1056
"""Test unsubscribe_share method in a share with content."""
1057
share = self._create_share(access_level=self.access_level,
1059
yield self.vm.add_share(share)
1061
self.assertTrue(self.vm.shares[share.volume_id].subscribed)
1062
# create a few files and directories
1063
dirs = ['dir', 'dir/subdir', 'dir/empty_dir']
1064
for i, dir in enumerate(dirs):
1065
path = os.path.join(share.path, dir)
1066
with allow_writes(os.path.split(share.path)[0]):
1067
with allow_writes(share.path):
1068
if not os.path.exists(path):
1070
self.main.fs.create(path, share.volume_id, is_dir=True)
1071
self.main.fs.set_node_id(path, 'dir_node_id'+str(i))
1072
# add a inotify watch to the dir
1073
self.main.event_q.add_watch(path)
1074
files = ['a_file', 'dir/file', 'dir/subdir/file']
1075
for i, file in enumerate(files):
1076
path = os.path.join(share.path, file)
1077
with allow_writes(os.path.split(share.path)[0]):
1078
with allow_writes(share.path):
1079
open(path, 'w').close()
1080
self.main.fs.create(path, share.volume_id)
1081
self.main.fs.set_node_id(path, 'file_node_id'+str(i))
1082
paths = self.main.fs.get_paths_starting_with(share.path)
1083
self.assertEquals(len(paths), len(dirs+files)+1)
1085
# unsubscribe from it
1086
self.vm.unsubscribe_share(share.volume_id)
1088
self.assertEquals(2, len(self.vm.shares)) # share and root
1089
self.assertFalse(self.vm.shares[share.volume_id].subscribed)
1090
# check that the share is in the fsm metadata
1091
self.assertTrue(self.main.fs.get_by_path(share.path))
1092
# get the childs (should be an empty list)
1093
paths = list(self.main.fs.get_paths_starting_with(share.path))
1094
self.assertEquals(len(dirs+files)+1, len(paths))
1095
# check that there isn't a watch in the share
1096
self.assertFalse(self.main.event_q.has_watch(share.path))
1097
# check that the childs don't have a watch
1098
for path, is_dir in paths:
1100
self.assertFalse(self.main.event_q.has_watch(path))
1103
class ModifySharesSubscriptionTests(ViewSharesSubscriptionTests):
1104
"""Test Shares subscription operations when access_level is Modify."""
1106
access_level = 'Modify'
1108
@defer.inlineCallbacks
1109
def test_subscribe_share_missing_fsm_md(self):
1110
"""Test subscribe_share with a missing node in fsm."""
1111
share = self._create_share(access_level=self.access_level,
1113
yield self.vm.add_share(share)
1114
self.assertFalse(os.path.exists(share.path))
1115
self.assertFalse(self.vm.shares[share.id].subscribed)
1116
yield self.vm.subscribe_share(share.id)
1117
yield self.vm.unsubscribe_share(share.id)
1118
# delete the fsm metadata
1119
self.main.fs.delete_metadata(share.path)
1120
# subscribe to it and fail!
1122
yield self.vm.subscribe_share(share.id)
1124
self.assertIn(share.path, e.args[0])
1126
self.fail('Must get a KeyError!')
1128
@defer.inlineCallbacks
1129
def _test_subscribe_share_generations(self, share):
1130
"""Test subscribe_share with a generation."""
1131
scratch_d = defer.Deferred()
1132
def fake_rescan_from_scratch(volume_id):
1133
"""A fake rescan_from_scratch that check the arguments."""
1134
self.assertEquals(share.volume_id, volume_id)
1135
scratch_d.callback(None)
1136
self.main.action_q.rescan_from_scratch = fake_rescan_from_scratch
1138
yield self.vm.subscribe_share(share.volume_id)
1140
self.assertTrue(self.vm.shares[share.volume_id].subscribed)
1142
@defer.inlineCallbacks
1143
def test_subscribe_share_valid_generation(self):
1144
"""Test subscribe_share with a valid generation."""
1145
share = self._create_share(access_level=self.access_level,
1147
yield self.vm.add_share(share)
1148
self.assertFalse(self.vm.shares[share.volume_id].subscribed)
1149
# update share generation
1150
self.vm.update_generation(share.volume_id, 0)
1151
yield self._test_subscribe_share_generations(share)
1153
@defer.inlineCallbacks
1154
def test_subscribe_share_without_generation(self):
1155
"""Test subscribe_share without a valid generation."""
1156
share = self._create_share(access_level=self.access_level,
1158
yield self.vm.add_share(share)
1159
self.assertFalse(self.vm.shares[share.volume_id].subscribed)
1160
# update share generation
1161
self.vm.update_generation(share.volume_id, None)
1162
yield self._test_subscribe_share_generations(share)
1164
@defer.inlineCallbacks
1165
def test_unsubscribe_subscribe_share_with_content(self):
1166
"""Test for re-subscribing to a share."""
1167
share = self._create_share(access_level=self.access_level,
1169
yield self.vm.add_share(share)
1170
self.main.event_q.rm_watch(share.path)
1171
self.assertTrue(self.vm.shares[share.volume_id].subscribed)
1172
# create a few files and directories
1173
dirs = ['dir', 'dir/subdir', 'dir/empty_dir']
1174
for i, dir in enumerate(dirs):
1175
path = os.path.join(share.path, dir)
1176
with allow_writes(os.path.split(share.path)[0]):
1177
with allow_writes(share.path):
1178
if not os.path.exists(path):
1180
self.main.fs.create(path, share.volume_id, is_dir=True)
1181
self.main.fs.set_node_id(path, 'dir_node_id'+str(i))
1182
files = ['a_file', 'dir/file', 'dir/subdir/file']
1183
for i, path in enumerate(files):
1184
path = os.path.join(share.path, path)
1185
with allow_writes(os.path.split(share.path)[0]):
1186
with allow_writes(share.path):
1187
open(path, 'w').close()
1188
self.main.fs.create(path, share.volume_id)
1189
self.main.fs.set_node_id(path, 'file_node_id'+str(i))
1190
paths = list(self.main.fs.get_paths_starting_with(share.path))
1191
# add a inotify watch to the dirs
1192
for path, is_dir in paths:
1194
self.main.event_q.add_watch(path)
1195
self.assertEquals(len(paths), len(dirs+files)+1, paths)
1197
# unsubscribe from it
1198
self.vm.unsubscribe_share(share.volume_id)
1200
self.assertEquals(2, len(self.vm.shares)) # share and root
1201
self.assertFalse(self.vm.shares[share.volume_id].subscribed)
1202
# check that the share is in the fsm metadata
1203
self.assertTrue(self.main.fs.get_by_path(share.path))
1204
# check that there isn't a watch in the share
1205
self.assertFalse(self.main.event_q.has_watch(share.path))
1206
# check that the childs don't have a watch
1207
for path, is_dir in paths:
1209
self.assertFalse(self.main.event_q.has_watch(path))
1211
paths = self.main.fs.get_paths_starting_with(share.path)
1212
self.assertEquals(len(dirs+files)+1, len(paths))
1214
yield self.vm.subscribe_share(share.volume_id)
1215
paths = list(self.main.fs.get_paths_starting_with(share.path))
1216
# we should only have the dirs, as the files metadata is
1217
# delete by local rescan (both hashes are '')
1218
self.assertEquals(len(dirs)+1, len(paths))
1219
# check that there is a watch in the share
1220
self.assertTrue(self.main.event_q.has_watch(share.path))
1221
# check that the child dirs have a watch
1222
for path, is_dir in paths:
1224
self.assertTrue(self.main.event_q.has_watch(path),
1225
'%s has a watch' % path)
1226
self.vm._remove_watch(path)
797
1229
class VolumeManagerUnicodeTests(BaseVolumeManagerTests):
798
1230
"""Tests for Volume Manager unicode capabilities."""
1156
1567
def _test_handle_AQ_LIST_VOLUMES_accepted_share(self, auto_subscribe):
1157
1568
"""Test handle_AQ_LIST_VOLUMES event with an accepted share."""
1158
1569
user_conf = config.get_user_config()
1159
user_conf.set_udf_autosubscribe(auto_subscribe)
1162
share_id = uuid.uuid4()
1163
share_response = ShareResponse.from_params(share_id, 'to_me',
1164
'fake_share_uuid_to_me',
1167
'visible_username_1', False,
1169
shared_id = uuid.uuid4()
1170
shared_response = ShareResponse.from_params(shared_id, 'from_me',
1172
'fake_share', 'username',
1173
'visible_username', True,
1175
shares_response = ListShares(None)
1176
shares_response.shares = [shared_response, share_response]
1177
self.vm.handle_AQ_SHARES_LIST(shares_response)
1180
self.assertIn(str(share_id), self.vm.shares)
1181
self.assertFalse(self.vm.shares[str(share_id)].active)
1182
self.assertIn(str(shared_id), self.vm.shared)
1570
user_conf.set_share_autosubscribe(auto_subscribe)
1572
# handle_AQ_SHARES_LIST is tested on test_handle_AQ_SHARES_LIST
1184
1574
# create a volume list
1185
udf_id = uuid.uuid4()
1186
udf_volume = volumes.UDFVolume(udf_id, 'udf_uuid', None, 100, u'~/UDF')
1187
1575
root_volume = volumes.RootVolume(uuid.uuid4(), 17, 10)
1188
share_volume = volumes.ShareVolume(share_id, 'fake_share_uuid', 10,
1189
10, 'to_me', 'fake_share',
1190
'username', 'visible_username',
1192
response = [share_volume, udf_volume, root_volume]
1193
d1 = defer.Deferred()
1194
d2 = defer.Deferred()
1576
share_id = uuid.uuid4()
1577
share_volume = self._create_share_volume(volume_id=share_id,
1578
node_id='fake_share_uuid', generation=10, accepted=True)
1579
response = [share_volume, root_volume]
1195
1581
share_created_d = defer.Deferred()
1196
self.vm.refresh_volumes = lambda: d1.errback('refresh_volumes called!')
1197
self._listen_for('VM_UDF_CREATED', d1.callback)
1198
self._listen_for('SV_VOLUME_NEW_GENERATION', d2.callback, 2, collect=True)
1582
vol_new_gen_d = defer.Deferred()
1584
self.vm.refresh_volumes = lambda: self.fail('refresh_volumes called!')
1199
1585
# listen for VM_SHARE_CREATED event for the new share
1200
1586
self._listen_for('VM_SHARE_CREATED', share_created_d.callback)
1588
expected_events = [{'generation': 10, 'volume_id': str(share_id)},
1589
{'generation': 17, 'volume_id': ''}]
1590
self.patch(self.vm, '_scan_share',
1591
lambda *a, **kw: defer.succeed(None))
1592
self._listen_for('SV_VOLUME_NEW_GENERATION',
1593
vol_new_gen_d.callback, 2, collect=True)
1595
expected_events = {'generation': 17, 'volume_id': ''}
1596
self.patch(self.vm, '_scan_share', lambda *a, **kw: self.fail(a))
1597
self._listen_for('SV_VOLUME_NEW_GENERATION',
1598
vol_new_gen_d.callback)
1600
# use a custom home, and trigger the operation
1202
1601
with environ('HOME', self.home_dir):
1203
1602
self.vm.handle_AQ_LIST_VOLUMES(response)
1207
1604
yield share_created_d
1605
events = yield vol_new_gen_d
1209
expected_events = [{'generation': 10, 'volume_id': str(share_id)},
1210
{'generation': 17, 'volume_id': ''}]
1211
1607
self.assertEqual(events, expected_events)
1610
"""The test itself."""
1611
self.assertEqual(2, len(self.vm.shares)) # the share and the root
1612
# check that the share is in the shares dict
1613
self.assertIn(str(share_id), self.vm.shares)
1614
share = self.vm.shares[str(share_id)]
1615
self.assertEqual('fake_share', share.name)
1616
self.assertEqual('fake_share_uuid', share.node_id)
1617
self.assertTrue(share.accepted, "The share is accepted")
1620
self.assertEqual(2, len(list(self.vm.get_volumes())))
1621
self.assertTrue(share.active)
1622
else: # share was added to VM, but isn't active
1623
self.assertEqual(1, len(list(self.vm.get_volumes())))
1624
self.assertFalse(share.active)
1628
# root was already checked on test_handle_AQ_LIST_VOLUMES_root
1630
# now send the same list again and check using a custom home
1631
with environ('HOME', self.home_dir):
1632
self.vm.handle_AQ_LIST_VOLUMES(response)
1636
@defer.inlineCallbacks
1637
def test_handle_AQ_LIST_VOLUMES_accepted_share_with_autosubscribe(self):
1638
"""Test handle_AQ_LIST_VOLUMES event with an active share."""
1639
yield self._test_handle_AQ_LIST_VOLUMES_accepted_share(True)
1641
@defer.inlineCallbacks
1642
def test_handle_AQ_LIST_VOLUMES_accepted_share_without_autosubscribe(self):
1643
"""Test handle_AQ_LIST_VOLUMES event with an inactive share."""
1644
yield self._test_handle_AQ_LIST_VOLUMES_accepted_share(False)
1646
@defer.inlineCallbacks
1647
def _test_handle_AQ_LIST_VOLUMES_udf(self, auto_subscribe):
1648
"""Test handle_AQ_LIST_VOLUMES event with an udf."""
1649
user_conf = config.get_user_config()
1650
user_conf.set_udf_autosubscribe(auto_subscribe)
1652
# create a volume list
1653
udf_id = uuid.uuid4()
1654
udf_volume = volumes.UDFVolume(udf_id, 'udf_uuid', 23, 100, u'~/UDF')
1655
root_volume = volumes.RootVolume(uuid.uuid4(), 17, 10)
1656
response = [udf_volume, root_volume]
1658
self.vm.refresh_volumes = lambda: self.fail('refresh_volumes called!')
1660
udf_created_d = defer.Deferred()
1661
vol_new_gen_d = defer.Deferred()
1663
# listen for VM_UDF_CREATED event for the new UDF
1664
self._listen_for('VM_UDF_CREATED', udf_created_d.callback)
1213
1665
if auto_subscribe:
1214
# root, share and udf
1215
self.assertEqual(3, len(list(self.vm.get_volumes())))
1666
expected_events = [{'generation': 23, 'volume_id': str(udf_id)},
1667
{'generation': 17, 'volume_id': ''}]
1668
self.patch(self.vm, '_scan_udf', defer.succeed)
1669
self._listen_for('SV_VOLUME_NEW_GENERATION',
1670
vol_new_gen_d.callback, 2, collect=True)
1672
expected_events = {'generation': 17, 'volume_id': ''}
1673
self.patch(self.vm, '_scan_udf', self.fail)
1674
self._listen_for('SV_VOLUME_NEW_GENERATION',
1675
vol_new_gen_d.callback)
1677
# use a custom home, and trigger the operation
1678
with environ('HOME', self.home_dir):
1679
self.vm.handle_AQ_LIST_VOLUMES(response)
1682
events = yield vol_new_gen_d
1684
self.assertEqual(events, expected_events)
1687
"""The test itself."""
1216
1688
self.assertEqual(1, len(self.vm.udfs)) # the new udf
1689
# check that the UDF is in the udfs dict
1217
1690
self.assertIn(str(udf_id), self.vm.udfs)
1218
1691
udf = self.vm.udfs[str(udf_id)]
1219
1692
self.assertEqual('udf_uuid', udf.node_id)
1220
1693
self.assertEqual(os.path.join(self.home_dir, 'UDF'), udf.path)
1221
else: # udf was not added to VM
1222
self.assertEqual(2, len(list(self.vm.get_volumes())))
1223
self.assertEqual(1, len(self.vm.udfs)) # the new udf
1224
self.assertFalse(self.vm.udfs.values()[0].active)
1226
self.assertEqual(2, len(self.vm.shares)) # the share and the root
1227
# check that the share is in the shares dict
1228
self.assertIn(str(share_id), self.vm.shares)
1229
share = self.vm.shares[str(share_id)]
1230
self.assertEqual('fake_share_to_me', share.name)
1231
self.assertEqual('fake_share_uuid_to_me', share.node_id)
1232
self.assertTrue(share.accepted, "The share isn't accepted")
1233
# check that the root it's there, have right node_id and generation
1234
self.assertIn(request.ROOT, self.vm.shares)
1235
root = self.vm.shares[request.ROOT]
1236
self.assertEqual(root.node_id, str(root_volume.node_id))
1238
# now send the same list again and check
1696
self.assertEqual(2, len(list(self.vm.get_volumes())))
1697
self.assertTrue(udf.active)
1698
else: # udf was added to VM, but isn't active
1699
self.assertEqual(1, len(list(self.vm.get_volumes())))
1700
self.assertFalse(udf.active)
1704
# root was already checked on test_handle_AQ_LIST_VOLUMES_root
1706
# now send the same list again and check using a custom home
1240
1707
with environ('HOME', self.home_dir):
1241
1708
self.vm.handle_AQ_LIST_VOLUMES(response)
1243
self.assertEqual(2, len(self.vm.shares)) # the share and root
1245
# root, share and udf
1246
self.assertEqual(1, len(self.vm.udfs)) # one udf
1247
self.assertEqual(3, len(list(self.vm.get_volumes())))
1248
else: # udf was added to VM, but isn't active
1249
self.assertEqual(2, len(list(self.vm.get_volumes())))
1250
self.assertEqual(1, len(self.vm.udfs)) # the new udf
1251
self.assertFalse(self.vm.udfs.values()[0].active)
1253
@defer.inlineCallbacks
1254
def test_handle_AQ_LIST_VOLUMES_accepted_share_with_autosubscribe(self):
1255
"""Test handle_AQ_LIST_VOLUMES event with an accepted share.
1257
The setting udf_autosubscribe will be set.
1260
yield self._test_handle_AQ_LIST_VOLUMES_accepted_share(True)
1262
@defer.inlineCallbacks
1263
def test_handle_AQ_LIST_VOLUMES_accepted_share_without_autosubscribe(self):
1264
"""Test handle_AQ_LIST_VOLUMES event with an accepted share.
1266
The setting udf_autosubscribe will not be set.
1269
yield self._test_handle_AQ_LIST_VOLUMES_accepted_share(False)
1712
@defer.inlineCallbacks
1713
def test_handle_AQ_LIST_VOLUMES_udf_with_autosubscribe(self):
1714
"""Test handle_AQ_LIST_VOLUMES event with an active udf."""
1715
yield self._test_handle_AQ_LIST_VOLUMES_udf(True)
1717
@defer.inlineCallbacks
1718
def test_handle_AQ_LIST_VOLUMES_udf_without_autosubscribe(self):
1719
"""Test handle_AQ_LIST_VOLUMES event with an inactive udf."""
1720
yield self._test_handle_AQ_LIST_VOLUMES_udf(False)
1272
1723
class VolumeManagerOperationsTests(BaseVolumeManagerTests):
1273
1724
"""Test UDF/Volumes operations."""
1277
1726
def setUp(self):
1278
1727
"""Setup the test."""
1279
1728
BaseVolumeManagerTests.setUp(self)
1681
2098
self.assertNotIn(share.volume_id, self.vm.shares)
1682
2099
self.assertNotIn(udf.volume_id, self.vm.udfs)
2101
@defer.inlineCallbacks
1684
2102
def test_cleanup_shared(self):
1685
2103
"""Test for VolumeManager._cleanup_shared"""
1686
2104
shared_path = os.path.join(self.root_dir, 'fake_shared')
1687
2105
shared = Share(path=shared_path, volume_id='shared_id')
1688
self.vm.add_shared(shared)
2106
yield self.vm.add_shared(shared)
1689
2107
self.assertIn(shared.volume_id, self.vm.shared)
1690
2108
self.vm._cleanup_shared([shared.volume_id])
1691
2109
self.assertIn(shared.volume_id, self.vm.shared)
1692
2110
self.vm._cleanup_shared([])
1693
2111
self.assertNotIn(shared.volume_id, self.vm.shared)
2113
@defer.inlineCallbacks
1695
2114
def test_cleanup_shares(self):
1696
2115
"""Test for VolumeManager._cleanup_shares"""
1697
2116
share_path = os.path.join(self.shares_dir, 'fake_share')
1698
2117
share = Share(path=share_path, volume_id='share_id')
1699
2118
share_2_path = os.path.join(self.root_dir, 'fake_share_2')
1700
2119
share_2 = Share(path=share_2_path, volume_id='share_2_id')
1701
self.vm.add_share(share)
1702
self.vm.add_share(share_2)
2120
yield self.vm.add_share(share)
2121
yield self.vm.add_share(share_2)
1703
2122
self.assertIn(share.volume_id, self.vm.shares)
1704
2123
self.assertIn(share_2.volume_id, self.vm.shares)
1705
2124
self.vm._cleanup_shares([])
1706
2125
self.assertNotIn(share.volume_id, self.vm.shares)
1707
2126
self.assertNotIn(share_2.volume_id, self.vm.shares)
1708
self.vm.add_share(share)
1709
self.vm.add_share(share_2)
2127
yield self.vm.add_share(share)
2128
yield self.vm.add_share(share_2)
1710
2129
self.vm._cleanup_shares([share.volume_id])
1711
2130
self.assertIn(share.volume_id, self.vm.shares)
1712
2131
self.assertNotIn(share_2.volume_id, self.vm.shares)
1713
self.vm.add_share(share)
1714
self.vm.add_share(share_2)
2132
yield self.vm.add_share(share)
2133
yield self.vm.add_share(share_2)
1715
2134
self.vm._cleanup_shares([share.volume_id, share_2.volume_id])
1716
2135
self.assertIn(share.volume_id, self.vm.shares)
1717
2136
self.assertIn(share_2.volume_id, self.vm.shares)
1829
2244
self.assertTrue(self.handler.check_warning("missing volume id"))
1831
2246
@defer.inlineCallbacks
1832
def test_handle_SV_VOLUME_CREATED_share(self):
2247
def _test_handle_SV_VOLUME_CREATED_share(self, auto_subscribe):
1833
2248
"""Test for handle_SV_VOLUME_CREATED with shares."""
2249
user_conf = config.get_user_config()
2250
user_conf.set_share_autosubscribe(auto_subscribe)
1834
2252
# start the test
1835
share_id = uuid.uuid4()
1836
share_volume = volumes.ShareVolume(
1837
share_id, 'fake_share_uuid', None, 10, 'to_me', u'ñoño',
1838
'username', u'visible_username',
1839
False, # this is how the protocol send it
2253
share_volume = self._create_share_volume(accepted=False, access_level='Modify')
1841
2254
# initialize the the root
1842
2255
self.vm._got_root('root_uuid')
1843
d = defer.Deferred()
1844
self._listen_for('VM_SHARE_CREATED', d.callback)
1845
rescan_cb = defer.Deferred()
1846
self.patch(self.main.action_q, 'rescan_from_scratch', rescan_cb.callback)
2257
share_created_d = defer.Deferred()
2258
self._listen_for('VM_SHARE_CREATED', share_created_d.callback)
2260
local_scan_d = defer.Deferred()
2261
server_rescan_d = defer.Deferred()
2264
self.patch(self.main.lr, 'scan_dir',
2265
lambda *a, **kw: local_scan_d.callback(a))
2266
self.patch(self.main.action_q, 'rescan_from_scratch',
2267
server_rescan_d.callback)
2269
self.patch(self.main.lr, 'scan_dir', lambda *a: self.fail(a))
2270
self.patch(self.main.action_q, 'rescan_from_scratch', self.fail)
1847
2272
# fire SV_VOLUME_CREATED with a share
1848
2273
with environ('HOME', self.home_dir):
1849
2274
self.vm.handle_SV_VOLUME_CREATED(share_volume)
2276
info = yield share_created_d
1851
2277
share_id = info['share_id']
1852
2278
share = self.vm.get_volume(share_id)
1853
2279
self.assertEquals(share.volume_id, str(share_id))
1854
2280
self.assertIn(str(share_id), self.vm.shares)
1855
# check that rescan_from_scratch is called
1856
vol_id = yield rescan_cb
1857
self.assertEqual(vol_id, share.volume_id)
2283
self.assertTrue(share.subscribed)
2284
self.assertTrue(os.path.exists(share.path))
2285
# check that scan_dir and rescan_from_scratch is called
2287
vol_id = yield server_rescan_d
2288
self.assertEqual(vol_id, share.volume_id)
2290
self.assertFalse(share.subscribed)
2291
self.assertFalse(os.path.exists(share.path))
2293
def test_handle_SV_VOLUME_CREATED_share_subscribe(self):
2294
"""Test SV_VOLUME_CREATED with share auto_subscribe """
2295
return self._test_handle_SV_VOLUME_CREATED_share(True)
2297
def test_handle_SV_VOLUME_CREATED_share_no_subscribe(self):
2298
"""Test SV_VOLUME_CREATED without share auto_subscribe """
2299
return self._test_handle_SV_VOLUME_CREATED_share(False)
1859
2301
@defer.inlineCallbacks
1860
2302
def _test_handle_SV_VOLUME_CREATED_udf(self, auto_subscribe):
1929
2368
self._listen_for('VM_VOLUME_DELETED', share_deferred.callback)
1930
2369
# fire SV_VOLUME_DELETED with a share
1931
2370
with environ('HOME', self.home_dir):
1932
self.vm.handle_SV_VOLUME_DELETED(share_volume.volume_id)
2371
self.vm.handle_SV_VOLUME_DELETED(share.volume_id)
1933
2372
share_info = yield share_deferred
1934
share = share_info['volume']
1935
self.assertEquals(share.volume_id, str(share_id))
2373
new_share = share_info['volume']
2374
self.assertEquals(new_share.volume_id, share.volume_id)
1936
2375
self.assertNotIn(str(share.volume_id), self.vm.shares)
1938
2377
@defer.inlineCallbacks
1939
2378
def test_get_volumes(self):
1940
"""Tests for VolumeManager.get_volumes."""
2379
"""Tests for VolumeManager.get_volumes.
2381
This is a legacy test where all the volume types are mixed. Dedicated
2382
tests in a per volume basis follow below.
1941
2385
share_path = os.path.join(self.shares_dir, 'fake_share')
1942
2386
share_modify = Share(path=share_path, volume_id='share_id',
1943
2387
node_id=str(uuid.uuid4()),
1944
access_level='Modify', accepted=True)
2388
access_level='Modify', accepted=True,
1945
2390
share_no_accepted_path = os.path.join(self.shares_dir, 'fake_share')
1946
2391
share_no_accepted = Share(path=share_no_accepted_path,
1947
2392
node_id=str(uuid.uuid4()),
1948
2393
volume_id='accepted_share_id',
1949
access_level='Modify', accepted=False)
2394
access_level='Modify', accepted=False,
1950
2396
share_view = Share(path=share_path, volume_id='share_id_view',
1951
access_level='View', accepted=True)
1952
self.vm.add_share(share_modify)
1953
self.vm.add_share(share_view)
1954
self.vm.add_share(share_no_accepted)
2397
access_level='View', accepted=True,
2399
yield self.vm.add_share(share_modify)
2400
yield self.vm.add_share(share_view)
2401
yield self.vm.add_share(share_no_accepted)
1955
2402
shared_path = os.path.join(self.root_dir, 'fake_shared')
1956
shared = Share(path=shared_path, volume_id='shared_id')
1957
self.vm.add_shared(shared)
1958
suggested_path = "suggested_path"
1959
udf_subscribed, _ = self._create_udf(uuid.uuid4(), 'udf_node_id',
1960
'~/' + suggested_path, subscribed=True)
1961
udf_unsubscribed, _ = self._create_udf(uuid.uuid4(), 'udf_node_id',
1962
'~/' + suggested_path, subscribed=False)
2403
shared = Shared(path=shared_path, volume_id='shared_id')
2404
yield self.vm.add_shared(shared)
2405
udf_subscribed = self._create_udf(subscribed=True)
2406
udf_unsubscribed = self._create_udf(subscribed=False)
1963
2407
yield self.vm.add_udf(udf_subscribed)
1964
2408
yield self.vm.add_udf(udf_unsubscribed)
1965
2409
volumes = list(self.vm.get_volumes())
1979
2423
self.assertIn(udf_subscribed.id, all_volumes_ids)
1980
2424
self.assertIn(udf_unsubscribed.id, all_volumes_ids)
2426
@defer.inlineCallbacks
2427
def test_get_volumes_shared(self):
2428
"""Tests for VolumeManager.get_volumes."""
2429
shared_path = os.path.join(self.root_dir, 'fake_shared')
2430
shared = Shared(path=shared_path, volume_id='shared_id')
2431
yield self.vm.add_shared(shared)
2433
volumes = list(self.vm.get_volumes())
2434
volumes_ids = [v.id for v in volumes]
2435
self.assertNotIn(shared.id, volumes_ids)
2437
all_volumes = list(self.vm.get_volumes(all_volumes=True))
2438
all_volumes_ids = [v.id for v in all_volumes]
2439
self.assertNotIn(shared.id, all_volumes_ids)
2441
@defer.inlineCallbacks
2442
def test_get_volumes_share_active_modify(self):
2443
"""Tests for VolumeManager.get_volumes."""
2444
share = self._create_share(access_level='Modify',
2445
accepted=True, subscribed=True)
2446
yield self.vm.add_share(share)
2448
volumes = list(self.vm.get_volumes())
2449
volumes_ids = [v.id for v in volumes]
2450
self.assertIn(share.id, volumes_ids)
2452
all_volumes = list(self.vm.get_volumes(all_volumes=True))
2453
all_volumes_ids = [v.id for v in all_volumes]
2454
self.assertIn(share.id, all_volumes_ids)
2456
@defer.inlineCallbacks
2457
def test_get_volumes_share_active_view(self):
2458
"""Tests for VolumeManager.get_volumes."""
2459
share = self._create_share(access_level='View',
2460
accepted=True, subscribed=True)
2461
yield self.vm.add_share(share)
2463
volumes = list(self.vm.get_volumes())
2464
volumes_ids = [v.id for v in volumes]
2465
self.assertIn(share.id, volumes_ids)
2467
all_volumes = list(self.vm.get_volumes(all_volumes=True))
2468
all_volumes_ids = [v.id for v in all_volumes]
2469
self.assertIn(share.id, all_volumes_ids)
2471
@defer.inlineCallbacks
2472
def test_get_volumes_share_inactive(self):
2473
"""Tests for VolumeManager.get_volumes."""
2474
share_no_accepted = self._create_share(accepted=False,
2476
yield self.vm.add_share(share_no_accepted)
2477
share_no_subscribed = self._create_share(accepted=True,
2479
yield self.vm.add_share(share_no_subscribed)
2481
volumes = list(self.vm.get_volumes())
2482
volumes_ids = [v.id for v in volumes]
2483
self.assertNotIn(share_no_accepted.id, volumes_ids)
2484
self.assertNotIn(share_no_subscribed.id, volumes_ids)
2486
all_volumes = list(self.vm.get_volumes(all_volumes=True))
2487
all_volumes_ids = [v.id for v in all_volumes]
2488
self.assertIn(share_no_accepted.id, all_volumes_ids)
2489
self.assertIn(share_no_subscribed.id, all_volumes_ids)
2491
@defer.inlineCallbacks
2492
def test_get_volumes_udf_inactive(self):
2493
"""Tests for VolumeManager.get_volumes."""
2494
udf = self._create_udf(subscribed=False)
2495
yield self.vm.add_udf(udf)
2497
volumes = list(self.vm.get_volumes())
2498
volumes_ids = [v.id for v in volumes]
2499
self.assertNotIn(udf.id, volumes_ids)
2501
all_volumes = list(self.vm.get_volumes(all_volumes=True))
2502
all_volumes_ids = [v.id for v in all_volumes]
2503
self.assertIn(udf.id, all_volumes_ids)
2505
@defer.inlineCallbacks
2506
def test_get_volumes_udf_active(self):
2507
"""Tests for VolumeManager.get_volumes."""
2508
udf = self._create_udf(subscribed=True)
2509
yield self.vm.add_udf(udf)
2511
volumes = list(self.vm.get_volumes())
2512
volumes_ids = [v.id for v in volumes]
2513
self.assertIn(udf.id, volumes_ids)
2515
all_volumes = list(self.vm.get_volumes(all_volumes=True))
2516
all_volumes_ids = [v.id for v in all_volumes]
2517
self.assertIn(udf.id, all_volumes_ids)
1982
2519
def test_udf_can_write(self):
1983
2520
"""Test that UDF class match Share.can_write() API."""
1984
suggested_path = "suggested_path"
1985
udf, volume = self._create_udf(uuid.uuid4(), 'udf_node_id',
1986
'~/' + suggested_path, subscribed=False)
2521
udf = self._create_udf(subscribed=False)
1987
2522
self.assertTrue(udf.can_write())
1989
2524
def test_udf_from_udf_volume(self):
2285
2789
self.main.action_q.query_volumes = lambda: defer.succeed(response)
2286
2790
vol_rescan_d = defer.Deferred()
2287
2791
self._listen_for('SV_VOLUME_NEW_GENERATION',
2288
vol_rescan_d.callback, 2, True)
2289
server_rescan_d = defer.Deferred()
2290
self._listen_for('SYS_SERVER_RESCAN_DONE', server_rescan_d.callback)
2291
with environ('HOME', self.home_dir):
2292
yield self.vm.server_rescan()
2293
yield server_rescan_d
2294
events = yield vol_rescan_d
2295
events_dict = dict((event['volume_id'], event['generation'])
2296
for event in events)
2297
self.assertIn(str(share_id), events_dict)
2298
# new udfs server rescan is triggered after local rescan.
2299
self.assertNotIn(str(udf_id), events_dict)
2300
self.assertIn(request.ROOT, events_dict)
2301
self.assertEquals(1, events_dict[str(share_id)])
2302
self.assertEquals(1, events_dict[request.ROOT])
2792
vol_rescan_d.callback) # autosubscribe is False
2793
server_rescan_d = defer.Deferred()
2794
self._listen_for('SYS_SERVER_RESCAN_DONE', server_rescan_d.callback)
2795
with environ('HOME', self.home_dir):
2796
yield self.vm.server_rescan()
2797
yield server_rescan_d
2798
events = yield vol_rescan_d
2800
self.assertEqual({'generation': 1, 'volume_id': ''}, events)
2802
@defer.inlineCallbacks
2803
def test_server_rescan_with_share_autosubscribe(self):
2804
"""Test the server_rescan method."""
2805
user_conf = config.get_user_config()
2806
user_conf.set_share_autosubscribe(True)
2808
share_id = uuid.uuid4()
2809
share_volume = self._create_share_volume(volume_id=share_id,
2811
udf_id = uuid.uuid4()
2812
udf_volume = volumes.UDFVolume(udf_id, 'udf_node_id', 13, 200, u'~/UDF')
2813
root_id = uuid.uuid4()
2814
root_volume = volumes.RootVolume(root_id, 1, 500)
2815
response = [share_volume, udf_volume, root_volume]
2817
# patch the fake action queue
2818
self.main.action_q.query_volumes = lambda: defer.succeed(response)
2819
self.patch(self.vm, '_scan_volume', lambda *a, **kw: defer.succeed(a))
2821
vol_rescan_d = defer.Deferred()
2822
self._listen_for('SV_VOLUME_NEW_GENERATION',
2823
vol_rescan_d.callback, 2, collect=True)
2824
server_rescan_d = defer.Deferred()
2825
self._listen_for('SYS_SERVER_RESCAN_DONE', server_rescan_d.callback)
2826
with environ('HOME', self.home_dir):
2827
yield self.vm.server_rescan()
2829
yield server_rescan_d
2830
events = yield vol_rescan_d
2832
expected_events = [{'generation': 17, 'volume_id': str(share_id)},
2833
{'generation': 1, 'volume_id': ''}]
2834
self.assertEqual(expected_events, events)
2836
@defer.inlineCallbacks
2837
def test_server_rescan_with_udf_autosubscribe(self):
2838
"""Test the server_rescan method."""
2839
user_conf = config.get_user_config()
2840
user_conf.set_udf_autosubscribe(True)
2842
share_volume = self._create_share_volume()
2843
udf_id = uuid.uuid4()
2844
udf_volume = volumes.UDFVolume(udf_id, 'udf_node_id', 13, 200, u'~/UDF')
2845
root_id = uuid.uuid4()
2846
root_volume = volumes.RootVolume(root_id, 1, 500)
2847
response = [share_volume, udf_volume, root_volume]
2849
# patch the fake action queue
2850
self.main.action_q.query_volumes = lambda: defer.succeed(response)
2852
self.patch(self.vm, '_scan_volume', defer.succeed)
2854
vol_rescan_d = defer.Deferred()
2855
self._listen_for('SV_VOLUME_NEW_GENERATION',
2856
vol_rescan_d.callback, 2, collect=True)
2857
server_rescan_d = defer.Deferred()
2858
self._listen_for('SYS_SERVER_RESCAN_DONE', server_rescan_d.callback)
2859
with environ('HOME', self.home_dir):
2860
yield self.vm.server_rescan()
2862
yield server_rescan_d
2863
events = yield vol_rescan_d
2865
expected_events = [{'generation': 13, 'volume_id': str(udf_id)},
2866
{'generation': 1, 'volume_id': ''}]
2867
self.assertEqual(expected_events, events)
2869
@defer.inlineCallbacks
2870
def test_server_rescan_with_autosubscribe(self):
2871
"""Test the server_rescan method."""
2872
user_conf = config.get_user_config()
2873
user_conf.set_udf_autosubscribe(True)
2874
user_conf.set_share_autosubscribe(True)
2876
share_id = uuid.uuid4()
2877
share_volume = self._create_share_volume(volume_id=share_id,
2879
udf_id = uuid.uuid4()
2880
udf_volume = volumes.UDFVolume(udf_id, 'udf_node_id', 13, 200, u'~/UDF')
2881
root_id = uuid.uuid4()
2882
root_volume = volumes.RootVolume(root_id, 1, 500)
2883
response = [share_volume, udf_volume, root_volume]
2885
# patch the fake action queue
2886
self.main.action_q.query_volumes = lambda: defer.succeed(response)
2887
self.patch(self.vm, '_scan_volume', lambda *a, **kw: defer.succeed(a))
2889
vol_rescan_d = defer.Deferred()
2890
self._listen_for('SV_VOLUME_NEW_GENERATION',
2891
vol_rescan_d.callback, 3, collect=True)
2892
server_rescan_d = defer.Deferred()
2893
self._listen_for('SYS_SERVER_RESCAN_DONE', server_rescan_d.callback)
2894
with environ('HOME', self.home_dir):
2895
yield self.vm.server_rescan()
2897
yield server_rescan_d
2898
events = yield vol_rescan_d
2900
expected_events = [{'generation': 17, 'volume_id': str(share_id)},
2901
{'generation': 13, 'volume_id': str(udf_id)},
2902
{'generation': 1, 'volume_id': ''}]
2903
self.assertEqual(expected_events, events)
2304
2905
@defer.inlineCallbacks
2305
2906
def test_server_rescan_error(self):