56
58
BROKEN_PICKLE = '\axb80\x02}q\x01(U\x01aU\x04testq\x02U\x01bU\x06brokenq\x03u.'
61
@defer.inlineCallbacks
62
def _create_share(share_id, share_name, fsm, shares_dir, access_level='Modify'):
64
share_path = os.path.join(shares_dir, share_name)
65
os.makedirs(share_path)
66
share = Share(path=share_path, volume_id=share_id,
67
access_level=access_level)
68
yield fsm.vm.add_share(share)
69
defer.returnValue(share)
59
72
class FSMTestCase(unittest.TestCase):
60
73
""" Base test case for FSM """
75
@defer.inlineCallbacks
63
77
""" Setup the test """
64
78
unittest.TestCase.setUp(self)
80
94
FakeVolumeManager(self.root_dir), self.db)
81
95
self.eq = EventQueue(self.fsm)
82
96
self.fsm.register_eq(self.eq)
83
self.share = self.create_share('share', 'share_name',
84
self.fsm, self.shares_dir)
97
self.share = yield self.create_share('share', 'share_name')
85
98
self.share_path = self.share.path
87
100
# add a in-memory logger handler
109
122
os.chmod(os.path.join(dirpath, dir), 0777)
110
123
shutil.rmtree(path)
113
def create_share(share_id, share_name, fsm, shares_dir,
125
@defer.inlineCallbacks
126
def create_share(self, share_id, share_name, fsm=None, shares_dir=None,
114
127
access_level='Modify'):
115
""" creates a share """
116
share_path = os.path.join(shares_dir, share_name)
117
os.makedirs(share_path)
118
share = Share(path=share_path, volume_id=share_id,
119
access_level=access_level)
120
fsm.vm.add_share(share)
128
"""Create a share."""
131
if shares_dir is None:
132
shares_dir = self.shares_dir
133
share = yield _create_share(share_id, share_name, fsm, shares_dir,
135
defer.returnValue(share)
123
137
def create_node(self, name, is_dir=False, share=None):
124
138
"""Create a node."""
172
187
db = Tritcask(fsmdir)
173
188
fsm = FileSystemManager(fsmdir, partials_dir,
174
189
FakeVolumeManager(fsmdir), db)
175
share = FSMTestCase.create_share('share', 'share_name',
190
share = yield _create_share('share', 'share_name',
191
fsm=fsm, shares_dir=fsmdir)
177
192
self.assertEqual(fsm._idx_path, {})
178
193
self.assertEqual(fsm._idx_node_id, {})
299
314
md_version = open(os.path.join(self.fsmdir, "metadata_version")).read()
300
315
self.assertEqual(md_version, METADATA_VERSION)
317
@defer.inlineCallbacks
302
318
def test_old_metadata_None(self):
303
319
"""Test old metadata situation, in None."""
304
320
# create some stuff
307
323
mdid = self.fsm.create(path, "share")
308
324
self.fsm.set_node_id(path, "uuid")
309
325
# create a path with the old layout
310
other_share = self.create_share('share1', 'share1_name',
311
self.fsm, self.shares_dir)
326
other_share = yield self.create_share('share1', 'share1_name')
312
327
share_mdid = self.fsm.create(other_share.path, "share1")
313
328
self.fsm.set_node_id(other_share.path, "uuid1")
314
329
os.makedirs(os.path.join(self.root_dir, 'Ubuntu One'))
369
385
self.fsm.set_node_id(path2, "uuid2")
371
387
# create a path with the old layout
372
other_share = self.create_share('share1', 'share1_name',
373
self.fsm, self.shares_dir)
388
other_share = yield self.create_share('share1', 'share1_name')
374
389
share_mdid = self.fsm.create(other_share.path, "share1")
375
390
self.fsm.set_node_id(other_share.path, "uuid1")
376
391
os.makedirs(os.path.join(self.root_dir, 'Ubuntu One'))
430
446
mdid = self.fsm.create(path, "share")
431
447
self.fsm.set_node_id(path, "uuid")
432
448
# create a path with the old layout
433
other_share = self.create_share('share1', 'share1_name',
434
self.fsm, self.shares_dir)
449
other_share = yield self.create_share('share1', 'share1_name')
435
450
share_mdid = self.fsm.create(other_share.path, "share1")
436
451
self.fsm.set_node_id(other_share.path, "uuid1")
437
452
os.makedirs(os.path.join(self.root_dir, 'Ubuntu One'))
480
495
self.assertFalse(old_path in newfsm._idx_path)
498
@defer.inlineCallbacks
483
499
def test_old_metadata_3(self):
484
500
"""Test old metadata situation, in v3."""
485
501
# create a path with the old layout and metadata
487
503
root_mdid = self.fsm.create(self.root_dir, "")
488
504
self.fsm.set_node_id(self.root_dir, "uuid")
490
other_share = self.create_share('share1', 'share1_name',
491
self.fsm, self.shares_dir)
506
other_share = yield self.create_share('share1', 'share1_name')
492
507
share_mdid = self.fsm.create(other_share.path, "share1")
493
508
self.fsm.set_node_id(other_share.path, "uuid1")
494
509
os.makedirs(os.path.join(self.root_dir, 'Ubuntu One'))
1263
1278
mdobj = self.fsm.get_by_node_id("share", "uuid")
1264
1279
self.assertEquals(self.share_path, mdobj.path)
1281
@defer.inlineCallbacks
1266
1282
def test_get_all_by_share(self):
1267
1283
""" Test that it returns all the mdids in a share. """
1268
1284
# create the shares
1269
share1 = self.create_share('share_id1', 'share_name1', self.fsm,
1270
self.shares_dir, access_level='View')
1271
share2 = self.create_share('share_id2', 'share_name2', self.fsm,
1272
self.shares_dir, access_level='View')
1285
share1 = yield self.create_share('share_id1', 'share_name1',
1286
access_level='View')
1287
share2 = yield self.create_share('share_id2', 'share_name2',
1288
access_level='View')
1273
1289
self.fsm.create(share1.path, "share_id1", is_dir=True)
1274
1290
self.fsm.set_node_id(share1.path, "uuid1")
1275
1291
self.fsm.create(share2.path, "share_id2", is_dir=True)
1330
1346
self.assertTrue(mdid7 not in all)
1331
1347
self.assertTrue(mdid8 not in all)
1349
@defer.inlineCallbacks
1333
1350
def test_get_all_by_share_mixed(self):
1334
1351
"""Test that it returns all the mdids in a share with mixed nodes."""
1335
1352
# create the shares
1336
share = self.create_share('share_id', 'sharetest', self.fsm,
1337
self.shares_dir, access_level='View')
1353
share = yield self.create_share('share_id', 'sharetest',
1354
access_level='View')
1338
1355
self.fsm.create(share.path, "share_id", is_dir=True)
1339
1356
self.fsm.set_node_id(share.path, "uuid")
1441
1458
os.path.join(self.share.path, 'a', 'b'))])
1442
1459
self.assertEqual(expected, actual)
1461
@defer.inlineCallbacks
1444
1462
def test_with_two_shares(self):
1445
1463
"""Test having 2 shares."""
1446
second_share = self.create_share('second_share', 'the_second',
1447
self.fsm, self.shares_dir)
1464
second_share = yield self.create_share('second_share', 'the_second')
1448
1465
self.create_some_contents(second_share)
1450
1467
expected = ['a']
1452
1469
self.fsm.get_mdobjs_in_dir(second_share.path)])
1453
1470
self.assertEqual(expected, actual)
1472
@defer.inlineCallbacks
1455
1473
def test_both_shares(self):
1456
1474
"""Test having 2 shares and asking for mdobjs in shares_dir."""
1457
second_share = self.create_share('second_share', 'the_second',
1458
self.fsm, self.shares_dir)
1475
second_share = yield self.create_share('second_share', 'the_second')
1459
1476
self.create_some_contents(second_share)
1750
1767
# it has no partial!
1751
1768
self.fsm.remove_partial("uuid", "share")
1770
@defer.inlineCallbacks
1753
1771
def test_ro_share(self):
1754
1772
"""Test creating a partial of a RO share.
1756
1774
It should leave the partials dir permissions intact.
1758
share = self.create_share('ro_share', 'ro_share_name',
1759
self.fsm, self.shares_dir,
1760
access_level='View')
1776
share = yield self.create_share('ro_share', 'ro_share_name',
1777
access_level='View')
1761
1778
testdir = os.path.join(share.path, "path")
1762
1779
mdid = self.fsm.create(testdir, share.volume_id, is_dir=False)
1763
1780
self.fsm.set_node_id(testdir, "uuid")
1965
1982
new_name = testfile + self.fsm.CONFLICT_SUFFIX
1966
1983
kwargs = dict(old_name=testfile, new_name=new_name)
1968
self.assertTrue(("FSM_FILE_CONFLICT", (), kwargs) in listener.events)
1985
self.assertTrue(("FSM_FILE_CONFLICT", kwargs) in listener.events)
1970
1987
def test_conflict_dir_pushes_event(self):
1971
1988
"""A conflict with a dir pushes FSM_DIR_CONFLICT."""
1982
1999
new_name = testdir + self.fsm.CONFLICT_SUFFIX
1983
2000
kwargs = dict(old_name=testdir, new_name=new_name)
1985
self.assertTrue(("FSM_DIR_CONFLICT", (), kwargs) in listener.events)
2002
self.assertTrue(("FSM_DIR_CONFLICT", kwargs) in listener.events)
1987
2004
def test_upload_finished(self):
1988
2005
"""Test upload finished."""
2638
2655
self.fsm.make_dir(mdid)
2639
2656
self.assertTrue(os.path.exists(local_dir))
2658
@defer.inlineCallbacks
2641
2659
def test_make_dir_in_ro_share(self):
2642
2660
"""Also works in a read only share."""
2643
share = self.create_share('ro_share_id', 'ro', self.fsm,
2644
self.shares_dir, access_level='View')
2661
share = yield self.create_share('ro_share_id', 'ro',
2662
access_level='View')
2645
2663
testdir = os.path.join(share.path, "foo")
2646
2664
mdid = self.fsm.create(testdir, 'ro_share_id', is_dir=True)
2647
2665
self.fsm.make_dir(mdid)
2648
2666
self.assertTrue(os.path.exists(testdir))
2668
@defer.inlineCallbacks
2650
2669
def test_make_dir_ro_watch(self):
2651
2670
"""Don't add the watch nor the mute on a RO share."""
2653
2672
self.eq.add_watch = lambda p: called.append(p)
2654
2673
self.eq.add_to_mute_filter = lambda *a: called.append(a)
2655
share = self.create_share('ro_share_id', 'ro', self.fsm,
2656
self.shares_dir, access_level='View')
2674
share = yield self.create_share('ro_share_id', 'ro',
2675
access_level='View')
2657
2676
testdir = os.path.join(share.path, "foo")
2658
2677
mdid = self.fsm.create(testdir, 'ro_share_id', is_dir=True)
2862
2881
os.chmod(os.path.join(dirpath, file), 0666)
2863
2882
FSMTestCase.tearDown(self)
2884
@defer.inlineCallbacks
2865
2885
def test_file_ro_share_fail(self):
2866
2886
""" Test that manual creation of a file, fails on a ro-share. """
2867
share = self.create_share('ro_share', 'ro_share_name', self.fsm,
2868
self.shares_dir, access_level='View')
2887
share = yield self.create_share('ro_share', 'ro_share_name',
2888
access_level='View')
2869
2889
testfile = os.path.join(share.path, "a_file")
2870
2890
self.assertRaises(IOError, open, testfile, 'w')
2892
@defer.inlineCallbacks
2872
2893
def test_dir_ro_share(self):
2873
2894
""" Test that the creation of a file using fsm, works on a ro-share."""
2874
share = self.create_share('ro_share', 'ro_share_name', self.fsm,
2875
self.shares_dir, access_level='View')
2895
share = yield self.create_share('ro_share', 'ro_share_name',
2896
access_level='View')
2876
2897
testdir = os.path.join(share.path, "path2")
2877
2898
self.fsm.create(testdir, share.volume_id, is_dir=True)
2878
2899
self.fsm.set_node_id(testdir, "uuid2")
2883
2904
self.assertTrue(os.path.exists(testdir))
2906
@defer.inlineCallbacks
2885
2907
def test_file_ro_share(self):
2886
2908
""" Test that the creation of a file using fsm, works on a ro-share."""
2887
self.share = self.create_share('ro_share', 'ro_share_name', self.fsm,
2888
self.shares_dir, access_level='View')
2909
self.share = yield self.create_share('ro_share', 'ro_share_name',
2910
access_level='View')
2889
2911
testfile = os.path.join(self.share.path, "a_file")
2890
2912
self.fsm.create(testfile, self.share.volume_id, is_dir=False)
2891
2913
self.fsm.set_node_id(testfile, "uuid3")
2896
2918
self.fsm.commit_partial('uuid3', self.share.volume_id, None)
2897
2919
self.assertTrue(os.path.exists(testfile))
2921
@defer.inlineCallbacks
2899
2922
def test_delete_dir_ro_share(self):
2900
2923
""" Test that fsm is able to delete a dir in a ro.share. """
2901
share = self.create_share('ro_share', 'ro_share_name', self.fsm,
2902
self.shares_dir, access_level='View')
2924
share = yield self.create_share('ro_share', 'ro_share_name',
2925
access_level='View')
2903
2926
testdir = os.path.join(share.path, "path2")
2904
2927
self.fsm.create(testdir, share.volume_id, is_dir=True)
2905
2928
self.fsm.set_node_id(testdir, "uuid2")
2912
2935
self.fsm.delete_file(testdir)
2913
2936
self.assertFalse(os.path.exists(testdir))
2938
@defer.inlineCallbacks
2915
2939
def test_delete_non_empty_dir_ro_share(self):
2916
2940
"""Test that fsm is able to delete a non-empty dir in a ro.share."""
2917
share = self.create_share('ro_share', 'ro_share_name', self.fsm,
2918
self.shares_dir, access_level='View')
2941
share = yield self.create_share('ro_share', 'ro_share_name',
2942
access_level='View')
2919
2943
testdir = os.path.join(share.path, "path2")
2920
2944
mdid = self.fsm.create(testdir, share.volume_id, is_dir=True)
2921
2945
self.fsm.set_node_id(testdir, "uuid2")
2941
2965
self.assertFalse(os.path.exists(testdir))
2942
2966
self.assertFalse(os.path.exists(testfile))
2968
@defer.inlineCallbacks
2944
2969
def test_delete_non_empty_dir_rw_share(self):
2945
2970
"""Test that fsm is able to delete a non-empty dir in a rw.share."""
2946
share = self.create_share('rw_share', 'rw_share_name', self.fsm,
2947
self.shares_dir, access_level='Modify')
2971
share = yield self.create_share('rw_share', 'rw_share_name',
2972
access_level='Modify')
2948
2973
testdir = os.path.join(share.path, "path2")
2949
2974
mdid = self.fsm.create(testdir, share.volume_id, is_dir=True)
2950
2975
self.fsm.set_node_id(testdir, "uuid2")
2970
2995
self.assertFalse(os.path.exists(testdir))
2971
2996
self.assertFalse(os.path.exists(testfile))
2998
@defer.inlineCallbacks
2973
2999
def test_delete_non_empty_dir_bad_perms_rw_share(self):
2974
3000
"""Test that fsm is able to delete a non-empty dir in a rw.share."""
2975
share = self.create_share('rw_share', 'rw_share_name', self.fsm,
2976
self.shares_dir, access_level='Modify')
3001
share = yield self.create_share('rw_share', 'rw_share_name',
3002
access_level='Modify')
2977
3003
testdir = os.path.join(share.path, "path2")
2978
3004
mdid = self.fsm.create(testdir, share.volume_id, is_dir=True)
2979
3005
self.fsm.set_node_id(testdir, "uuid2")
3001
3027
self.assertTrue(os.path.exists(testdir))
3002
3028
self.assertTrue(os.path.exists(testfile))
3030
@defer.inlineCallbacks
3004
3031
def test_delete_file_ro_share(self):
3005
3032
""" Test that fsm is able to delete a file in a ro-share. """
3006
self.share = self.create_share('ro_share', 'ro_share_name', self.fsm,
3007
self.shares_dir, access_level='View')
3033
self.share = yield self.create_share('ro_share', 'ro_share_name',
3034
access_level='View')
3008
3035
testfile = os.path.join(self.share.path, "a_file")
3009
3036
self.fsm.create(testfile, self.share.volume_id, is_dir=False)
3010
3037
self.fsm.set_node_id(testfile, "uuid3")
3017
3044
self.fsm.delete_file(testfile)
3018
3045
self.assertFalse(os.path.exists(testfile))
3047
@defer.inlineCallbacks
3020
3048
def test_move_to_conflict_ro_share(self):
3021
3049
""" Test that fsm is able to handle move_to_conflict in a ro-share. """
3022
self.share = self.create_share('ro_share', 'ro_share_name', self.fsm,
3023
self.shares_dir, access_level='View')
3050
self.share = yield self.create_share('ro_share', 'ro_share_name',
3051
access_level='View')
3024
3052
testfile = os.path.join(self.share.path, "a_file")
3025
3053
file_mdid = self.fsm.create(testfile, self.share.volume_id,
3034
3062
self.fsm.move_to_conflict(file_mdid)
3035
3063
self.assertTrue(os.path.exists(testfile + self.fsm.CONFLICT_SUFFIX))
3065
@defer.inlineCallbacks
3037
3066
def test_file_rw_share_no_fail(self):
3038
3067
""" Test that manual creation of a file, ona rw-share. """
3039
share = self.create_share('ro_share', 'ro_share_name', self.fsm,
3068
share = yield self.create_share('ro_share', 'ro_share_name')
3041
3069
testfile = os.path.join(share.path, "a_file")
3042
3070
open(testfile, 'w').close()
3043
3071
self.assertTrue(os.path.exists(testfile))
3073
@defer.inlineCallbacks
3045
3074
def test_dir_rw_share(self):
3046
3075
""" Test that the creation of a file using fsm, works on a rw-share."""
3047
share = self.create_share('ro_share', 'ro_share_name', self.fsm,
3076
share = yield self.create_share('ro_share', 'ro_share_name')
3049
3077
testdir = os.path.join(share.path, "path2")
3050
3078
self.fsm.create(testdir, share.volume_id, is_dir=True)
3051
3079
self.fsm.set_node_id(testdir, "uuid2")
3056
3084
self.assertTrue(os.path.exists(testdir))
3086
@defer.inlineCallbacks
3058
3087
def test_file_rw_share(self):
3059
3088
""" Test that the creation of a file using fsm, works on a rw-share."""
3060
self.share = self.create_share('ro_share', 'ro_share_name', self.fsm,
3089
self.share = yield self.create_share('ro_share', 'ro_share_name')
3062
3090
testfile = os.path.join(self.share.path, "a_file")
3063
3091
self.fsm.create(testfile, self.share.volume_id, is_dir=False)
3064
3092
self.fsm.set_node_id(testfile, "uuid3")
3094
3122
class TestEnableShareWrite(FSMTestCase):
3095
3123
"""Tests for EnableShareWrite context manager"""
3125
@defer.inlineCallbacks
3097
3126
def setUp(self):
3098
3127
"""Test setup"""
3099
3128
FSMTestCase.setUp(self)
3100
3129
# create a ro share
3101
self.share_ro = self.create_share('share_ro', 'share_ro_name',
3102
self.fsm, self.shares_dir,
3103
access_level='View')
3130
self.share_ro = yield self.create_share('share_ro', 'share_ro_name',
3131
access_level='View')
3104
3132
self.share_ro_path = self.share_ro.path
3106
3134
def test_write_in_ro_share(self):
3158
3187
self.main = FakeMain(self.root_dir, self.shares_dir,
3159
3188
self.data_dir, self.partials_dir)
3160
3189
self.fsm = self.main.fs
3161
self.share = self.create_share('share', 'share_name',
3162
self.fsm, self.shares_dir)
3190
self.share = yield self.create_share('share', 'share_name')
3163
3191
self.share_path = self.share.path
3165
3193
def tearDown(self):
3167
3195
self.main.shutdown()
3168
3196
self.rmtree(TESTS_DIR)
3172
def create_share(share_id, share_name, fsm, shares_dir,
3198
@defer.inlineCallbacks
3199
def create_share(self, share_id, share_name,
3173
3200
access_level='Modify'):
3174
with allow_writes(shares_dir):
3175
return FSMTestCase.create_share(share_id, share_name, fsm,
3176
shares_dir, access_level)
3201
with allow_writes(self.shares_dir):
3202
share = yield _create_share(share_id, share_name, self.fsm,
3203
self.shares_dir, access_level)
3205
defer.returnValue(share)
3207
@defer.inlineCallbacks
3178
3208
def test_old_metadata_None_missing_share(self):
3179
3209
"""test loading metadata v0. that points to a share that
3185
3215
mdid = self.fsm.create(path, "share")
3186
3216
self.fsm.set_node_id(path, "uuid")
3187
3217
# create a path with the old layout
3188
other_share = self.create_share('share1', 'share1_name',
3189
self.fsm, self.shares_dir)
3218
other_share = yield self.create_share('share1', 'share1_name')
3190
3219
share_mdid = self.fsm.create(other_share.path, "share1")
3191
3220
self.fsm.set_node_id(other_share.path, "uuid1")
3192
3221
os.makedirs(os.path.join(self.root_dir, 'Ubuntu One'))
3251
3281
self.fsm.set_node_id(path2, "uuid2")
3253
3283
# create a path with the old layout
3254
other_share = self.create_share('share1', 'share1_name',
3255
self.fsm, self.shares_dir)
3284
other_share = yield self.create_share('share1', 'share1_name')
3256
3285
share_mdid = self.fsm.create(other_share.path, "share1")
3257
3286
self.fsm.set_node_id(other_share.path, "uuid3")
3258
3287
os.makedirs(os.path.join(self.root_dir, 'Ubuntu One'))
3312
3342
mdid = self.fsm.create(path, "share")
3313
3343
self.fsm.set_node_id(path, "uuid")
3314
3344
# create a path with the old layout
3315
other_share = self.create_share('share1', 'share1_name',
3316
self.fsm, self.shares_dir)
3345
other_share = yield self.create_share('share1', 'share1_name')
3317
3346
share_mdid = self.fsm.create(other_share.path, "share1")
3318
3347
self.fsm.set_node_id(other_share.path, "uuid3")
3319
3348
os.makedirs(os.path.join(self.root_dir, 'Ubuntu One'))
3369
3399
root_mdid = self.fsm.get_by_path(self.root_dir).mdid
3370
3400
self.fsm.set_node_id(self.root_dir, "uuid")
3372
other_share = self.create_share('share1', 'share1_name',
3373
self.fsm, self.shares_dir)
3402
other_share = yield self.create_share('share1', 'share1_name')
3374
3403
share_mdid = self.fsm.create(other_share.path, "share1")
3375
3404
self.fsm.set_node_id(other_share.path, "uuid1")
3376
3405
os.makedirs(os.path.join(self.root_dir, 'Ubuntu One'))
3425
3455
self.assertEqual(md_version, METADATA_VERSION)
3426
3456
path = os.path.join(self.share.path, 'path')
3427
3457
path1 = os.path.join(self.share.path, 'path1')
3428
other_share = self.create_share('share1', 'share1_name',
3429
self.fsm, self.shares_dir)
3458
other_share = yield self.create_share('share1', 'share1_name')
3431
3460
path2 = os.path.join(other_share.path, 'broken_path2')
3432
3461
for p in [path, path1, path2]: