160
160
now = time.time()
161
161
self.assertTrue(now-3 <= when <= now) # 3 seconds test range
163
def test_with_node_id(self):
164
'''Test creation with node_id'''
165
# create, but not twice
166
path = os.path.join(self.share.path, 'path')
167
self.fsm.create(path, "share", node_id='a_node_id')
168
self.assertRaises(ValueError, self.fsm.create, path, "share")
169
self.assertRaises(ValueError, self.fsm.create, path, "other")
170
mdobj = self.fsm.get_by_path(path)
171
self.assertEqual(mdobj.path, "path")
172
self.assertEqual(mdobj.share_id, "share")
173
self.assertEqual(mdobj.node_id, "a_node_id")
174
when = mdobj.info.created
176
self.assertTrue(now-3 <= when <= now) # 3 seconds test range
178
# set uuid using valid path, but not twice
179
self.assertRaises(ValueError, self.fsm.set_node_id, path, "whatever")
180
mdobj = self.fsm.get_by_path(path)
181
when = mdobj.info.node_id_assigned
183
self.assertTrue(now-3 <= when <= now) # 3 seconds test range
163
185
def test_invalid_args(self):
164
186
'''Test using invalid args in set_node_id.'''
165
187
path = os.path.join(self.share.path, 'path')
171
193
# set uuid using an invalid node_id
172
194
self.assertRaises(ValueError, self.fsm.set_node_id, path, None)
174
def test_no_twice(self):
196
def test_twice_sameid_ok(self):
197
'''Test that uuid can be set twice, if the uuid is same.'''
198
# using the first FSM
199
path = os.path.join(self.share.path, 'path')
200
self.fsm.create(path, "share")
201
self.fsm.set_node_id(path, "uuid")
202
self.fsm.set_node_id(path, "uuid")
204
# opening another FSM
205
FileSystemManager(self.fsmdir, self.fsm.vm)
206
self.fsm.set_node_id(path, "uuid")
208
def test_twice_different_bad(self):
175
209
'''Test that assignments must be done once, even in different FSMs.'''
176
210
# using the first FSM
177
211
path = os.path.join(self.share.path, 'path')
178
212
self.fsm.create(path, "share")
179
213
self.fsm.set_node_id(path, "uuid")
214
self.assertRaises(ValueError, self.fsm.set_node_id, path, "other_uuid")
181
216
# opening another FSM
182
217
fsm = FileSystemManager(self.fsmdir, self.fsm.vm)
183
218
self.assertRaises(ValueError, fsm.create, path, "share")
184
self.assertRaises(ValueError, fsm.set_node_id, path, "whatever")
219
self.assertRaises(ValueError, fsm.set_node_id, path, "other_uuid")
186
221
def test_fresh_metadata(self):
187
222
'''Initing with nothing in the metadata, it should leave it in v1.'''
188
223
md_version = open(os.path.join(self.fsmdir, "metadata_version")).read()
189
self.assertEqual(md_version, "2")
224
self.assertEqual(md_version, "3")
191
226
def test_old_metadata_None(self):
192
227
'''Faking an old metadata situation, in None.'''
209
246
# start up again, and check
210
247
newfsm = FileSystemManager(self.fsmdir, self.fsm.vm)
211
248
md_version = open(version_file).read()
212
self.assertEqual(md_version, "2")
249
self.assertEqual(md_version, "3")
213
250
newmdobj = newfsm.get_by_path(path)
214
251
self.assertEqual(newmdobj.mdid, mdid)
215
252
self.assertEqual(newmdobj.stat, os.stat(path))
253
self.assertEqual(newmdobj.local_hash, "")
254
self.assertEqual(newmdobj.server_hash, "")
216
255
self.assertTrue(isinstance(newmdobj.path, str))
218
257
def test_old_metadata_1(self):
241
282
# start up again, and check
242
283
newfsm = FileSystemManager(self.fsmdir, self.fsm.vm)
243
284
md_version = open(version_file).read()
244
self.assertEqual(md_version, "2")
285
self.assertEqual(md_version, "3")
245
286
newmdobj = newfsm.get_by_path(path1)
246
287
self.assertEqual(newmdobj.mdid, mdid1)
288
self.assertEqual(newmdobj.local_hash, "")
289
self.assertEqual(newmdobj.server_hash, "")
290
self.assertTrue(isinstance(newmdobj.path, str))
291
# pylint: disable-msg=W0212
292
self.assertEqual(1, len(newfsm._idx_node_id))
294
def test_old_metadata_2(self):
295
'''Faking an old metadata situation, in v2.'''
297
path = os.path.join(self.share.path, 'path')
298
mdid = self.fsm.create(path, "share")
299
self.fsm.set_node_id(path, "uuid")
301
# break the node on purpose, with hashes in None
302
real_mdobj = self.fsm.fs[mdid]
303
real_mdobj["local_hash"] = None
304
real_mdobj["server_hash"] = None
305
self.fsm.fs[mdid] = real_mdobj
307
# put the version file in 1
308
version_file = os.path.join(self.fsmdir, "metadata_version")
309
with open(version_file, "w") as fh:
312
# start up again, and check
313
newfsm = FileSystemManager(self.fsmdir, self.fsm.vm)
314
md_version = open(version_file).read()
315
self.assertEqual(md_version, "3")
316
newmdobj = newfsm.get_by_path(path)
317
self.assertEqual(newmdobj.mdid, mdid)
318
self.assertEqual(newmdobj.local_hash, "")
319
self.assertEqual(newmdobj.server_hash, "")
247
320
self.assertTrue(isinstance(newmdobj.path, str))
248
321
# pylint: disable-msg=W0212
249
322
self.assertEqual(1, len(newfsm._idx_node_id))
272
345
self.assertEqual(mdobj.node_id, "uuid1")
273
346
self.assertEqual(mdobj.path, "path1")
274
347
self.assertEqual(mdobj.share_id, "share")
275
self.assertEqual(mdobj.local_hash, None)
276
self.assertEqual(mdobj.server_hash, None)
348
self.assertEqual(mdobj.local_hash, "")
349
self.assertEqual(mdobj.server_hash, "")
277
350
self.assertEqual(mdobj.info.is_partial, False)
278
351
self.assertEqual(mdobj.is_dir, False)
279
352
self.assertEqual(mdobj.mdid, mdid1)
468
541
self.assertRaises(ValueError, self.fsm.set_by_mdid, mdid, info="-")
469
542
self.assertRaises(ValueError, self.fsm.set_by_path, path, info="-")
471
# test with forbidden stat
472
self.assertRaises(ValueError, self.fsm.set_by_node_id, "uuid", "share",
474
self.assertRaises(ValueError, self.fsm.set_by_mdid, mdid, stat="-")
475
self.assertRaises(ValueError, self.fsm.set_by_path, path, stat="-")
477
544
# test with forbidden share
478
545
self.assertRaises(ValueError, self.fsm.set_by_mdid, mdid, share_id="-")
479
546
self.assertRaises(ValueError, self.fsm.set_by_path, path, share_id="-")
577
644
self.assertTrue(mdid7 in all)
578
645
self.assertTrue(mdid8 in all)
648
for mdobj in self.fsm.get_mdobjs_by_share_id("share_id1", os.
649
path.join(share1.path, 'a')):
651
self.assertTrue(mdid3 in all)
652
self.assertTrue(mdid4 in all)
653
self.assertTrue(mdid5 not in all)
654
self.assertTrue(mdid6 not in all)
655
self.assertTrue(mdid7 not in all)
656
self.assertTrue(mdid8 not in all)
580
658
def test_get_all_by_share_mixed(self):
581
659
"""Test that it returns all the mdids in a share with mixed nodes."""
582
660
# create the shares
604
682
self.assertTrue(mdid2 in all)
605
683
self.assertTrue(mdid3 in all)
685
def test_internal_set_node_id(self):
686
"""Test _set_node_id"""
687
path = os.path.join(self.share.path, 'path')
688
mdid = self.fsm.create(path, "share")
689
mdobj = self.fsm.fs[mdid]
690
# yes, it's a unit test, I access protected members.
691
# pylint: disable-msg=W0212
692
self.fsm._set_node_id(mdobj, "uuid", path)
694
self.assertEquals('uuid', mdobj['node_id'])
695
self.fsm.set_node_id(path, "uuid")
696
new_mdobj = self.fsm.get_by_node_id('share', 'uuid')
697
for k, v in mdobj.items():
699
for k1, v1 in v.items():
700
self.assertEquals(v1, getattr(new_mdobj.info, k1))
702
self.assertEquals(v, getattr(new_mdobj, k))
704
# test using bad uuid
705
mdobj = self.fsm.fs[mdid]
706
self.assertEquals('uuid', mdobj['node_id'])
707
self.assertRaises(ValueError,
708
self.fsm._set_node_id, mdobj, 'bad-uuid', path)
608
711
class StatTests(FSMTestCase):
609
712
'''Test all the behaviour regarding the stats.'''
736
839
def test_create_file(self):
737
840
'''Test create .partial for a file.'''
738
841
testfile = os.path.join(self.share_path, "path")
842
partial_path = os.path.join(self.share_path, ".u1partial.path")
739
843
mdid = self.fsm.create(testfile, "share")
740
844
self.fsm.set_node_id(testfile, "uuid")
742
846
# create partial ok
743
847
self.fsm.create_partial("uuid", "share")
744
848
self.assertTrue(self.fsm.get_by_mdid(mdid).info.is_partial)
745
self.assertTrue(os.path.exists(testfile + ".partial"))
849
self.assertTrue(os.path.exists(partial_path))
746
850
mdobj = self.fsm.get_by_mdid(mdid)
747
851
when = mdobj.info.last_partial_created
748
852
now = time.time()
758
862
def test_commit_file(self):
759
863
'''Test commit the .partial for a file, after a successful download.'''
760
864
testfile = os.path.join(self.share_path, "path")
865
partial_path = os.path.join(self.share_path, ".u1partial.path")
761
866
mdid = self.fsm.create(testfile, "share")
762
867
self.fsm.set_node_id(testfile, "uuid")
765
870
self.fsm.create_partial("uuid", "share")
766
871
self.assertTrue(self.fsm.get_by_mdid(mdid).info.is_partial)
767
with open(testfile + ".partial", "w") as fh:
872
with open(partial_path, "w") as fh:
768
873
fh.write("test info!")
770
875
# commit partial, and check that the file is moved, and metadata is ok
771
876
self.fsm.commit_partial("uuid", "share", local_hash=9876)
772
self.assertFalse(os.path.exists(testfile + ".partial"))
877
self.assertFalse(os.path.exists(partial_path))
773
878
with open(testfile) as fh:
774
879
in_file = fh.read()
775
880
self.assertEqual(in_file, "test info!")
792
897
def test_remove_file(self):
793
898
'''Test removing the .partial for a file, because a bad download.'''
794
899
testfile = os.path.join(self.share_path, "path")
900
partial_path = os.path.join(self.share_path, ".u1partial.path")
795
901
mdid = self.fsm.create(testfile, "share")
796
902
self.fsm.set_node_id(testfile, "uuid")
799
905
self.fsm.create_partial("uuid", "share")
800
906
self.assertTrue(self.fsm.get_by_mdid(mdid).info.is_partial)
801
with open(testfile + ".partial", "w") as fh:
907
with open(partial_path, "w") as fh:
802
908
fh.write("test info!")
803
909
with open(testfile, "w") as fh:
804
910
fh.write("previous stuff!")
806
912
# remove partial, and check that the file is gone, and metadata is ok
807
913
self.fsm.remove_partial("uuid", "share")
808
self.assertFalse(os.path.exists(testfile + ".partial"))
914
self.assertFalse(os.path.exists(partial_path))
809
915
with open(testfile) as fh:
810
916
in_file = fh.read()
811
917
self.assertEqual(in_file, "previous stuff!")
855
961
self.fsm.create_partial("uuid", "share")
856
962
self.assertTrue(self.fsm.get_by_mdid(mdid).info.is_partial)
857
963
self.assertTrue(os.path.exists(testdir))
858
self.assertTrue(os.path.exists(os.path.join(testdir, ".partial")))
964
self.assertTrue(os.path.exists(os.path.join(testdir, ".u1partial")))
859
965
mdobj = self.fsm.get_by_mdid(mdid)
860
966
when = mdobj.info.last_partial_created
861
967
now = time.time()
894
1000
# remove partial, and check that the file is gone, and metadata is ok
895
1001
self.fsm.remove_partial("uuid", "share")
896
self.assertFalse(os.path.exists(os.path.join(testdir, ".partial")))
1002
self.assertFalse(os.path.exists(os.path.join(testdir, ".u1partial")))
897
1003
mdobj = self.fsm.get_by_mdid(mdid)
898
1004
self.assertFalse(mdobj.info.is_partial)
899
1005
when = mdobj.info.last_partial_removed
934
1040
fh.write("test 1!")
935
1041
self.fsm.move_to_conflict(mdid)
936
1042
self.assertFalse(os.path.exists(testfile))
937
with open(testfile + ".conflict.1") as fh:
1043
with open(testfile + ".u1conflict.1") as fh:
938
1044
in_file = fh.read()
939
1045
self.assertEqual(in_file, "test 1!")
941
1047
# create a few more, test a higher one
942
open(testfile + ".conflict.2", "w").close()
943
open(testfile + ".conflict.3", "w").close()
944
open(testfile + ".conflict.4", "w").close()
945
open(testfile + ".conflict.5", "w").close()
1048
open(testfile + ".u1conflict.2", "w").close()
1049
open(testfile + ".u1conflict.3", "w").close()
1050
open(testfile + ".u1conflict.4", "w").close()
1051
open(testfile + ".u1conflict.5", "w").close()
946
1052
with open(testfile, "w") as fh:
947
1053
fh.write("test 6!")
948
1054
self.fsm.move_to_conflict(mdid)
949
1055
self.assertFalse(os.path.exists(testfile))
950
with open(testfile + ".conflict.6") as fh:
1056
with open(testfile + ".u1conflict.6") as fh:
951
1057
in_file = fh.read()
952
1058
self.assertEqual(in_file, "test 6!")
1157
1263
self.assertRaises(KeyError, self.fsm.get_by_path, testdir)
1158
1264
self.assertRaises(KeyError, self.fsm.get_by_node_id, "share", "uuid")
1266
def test_move_dir_to_conflict(self):
1267
'''Test that the conflict to a dir removes children metadata.'''
1268
tdir = os.path.join(self.share_path, "adir")
1269
mdid1 = self.fsm.create(tdir, "share")
1270
self.fsm.set_node_id(tdir, "uuid1")
1273
testfile = os.path.join(tdir, "path")
1274
mdid2 = self.fsm.create(testfile, "share")
1275
self.fsm.set_node_id(testfile, "uuid2")
1276
with open(testfile, "w") as fh:
1279
# move the dir to conflict, the file is still there, but with no MD
1280
self.fsm.move_to_conflict(mdid1)
1281
self.assertFalse(os.path.exists(tdir))
1282
self.assertTrue(os.path.exists(tdir + ".u1conflict"))
1283
testfile = os.path.join(self.share_path, tdir + ".u1conflict", "path")
1284
self.assertTrue(os.path.exists(testfile))
1285
self.assertTrue(self.fsm.get_by_mdid(mdid1))
1286
self.assertRaises(KeyError, self.fsm.get_by_mdid, mdid2)
1288
def test_move_dir_to_conflict_similar_path(self):
1289
'''Test that the conflict to a dir removes children metadata.'''
1290
tdir1 = os.path.join(self.share_path, "adirectory")
1291
mdid1 = self.fsm.create(tdir1, "share")
1292
self.fsm.set_node_id(tdir1, "uuid1")
1295
tdir2 = os.path.join(self.share_path, "adir")
1296
mdid2 = self.fsm.create(tdir2, "share")
1297
self.fsm.set_node_id(tdir2, "uuid2")
1300
testfile = os.path.join(tdir2, "path")
1301
mdid3 = self.fsm.create(testfile, "share")
1302
self.fsm.set_node_id(testfile, "uuid3")
1303
with open(testfile, "w") as fh:
1306
# move the dir2 to conflict, see dir2 and file inside it went ok
1307
self.fsm.move_to_conflict(mdid2)
1308
self.assertFalse(os.path.exists(tdir2))
1309
self.assertTrue(os.path.exists(tdir2 + ".u1conflict"))
1310
testfile = os.path.join(self.share_path, tdir2 + ".u1conflict", "path")
1311
self.assertTrue(os.path.exists(testfile))
1312
self.assertTrue(self.fsm.get_by_mdid(mdid2))
1313
self.assertRaises(KeyError, self.fsm.get_by_mdid, mdid3)
1315
# and check that the one with similar path is untouched
1316
self.assertTrue(os.path.exists(tdir1))
1317
self.assertTrue(self.fsm.get_by_mdid(mdid1))
1161
1320
class SyntheticInfoTests(FSMTestCase):
1162
1321
'''Test the methods that generates attributes.'''
1220
1380
self.assertTrue(self.fsm.changed(path=testfile), "SERVER")
1222
1382
# put a .partial by hand, to see it crash
1223
open(testfile + ".partial", "w").close()
1383
open(partial_path, "w").close()
1224
1384
# pylint: disable-msg=W0212
1225
1385
self.assertRaises(InconsistencyError,
1226
1386
self.fsm._check_partial, mdid=mdid)
1240
1401
self.assertTrue(self.fsm.changed(path=testfile), "NONE")
1242
1403
# put a .partial by hand, to see it crash
1243
open(testfile + ".partial", "w").close()
1404
open(partial_path, "w").close()
1244
1405
# pylint: disable-msg=W0212
1245
1406
self.assertRaises(InconsistencyError,
1246
1407
self.fsm._check_partial, mdid=mdid)