3 import arvados_fuse as fuse
16 import multiprocessing
17 import run_test_server
20 from mount_test_base import MountTestBase
22 logger = logging.getLogger('arvados.arv-mount')
25 class FuseMountTest(MountTestBase):
27 super(FuseMountTest, self).setUp()
29 cw = arvados.CollectionWriter()
31 cw.start_new_file('thing1.txt')
33 cw.start_new_file('thing2.txt')
35 cw.start_new_stream('dir1')
37 cw.start_new_file('thing3.txt')
39 cw.start_new_file('thing4.txt')
42 cw.start_new_stream('dir2')
43 cw.start_new_file('thing5.txt')
45 cw.start_new_file('thing6.txt')
48 cw.start_new_stream('dir2/dir3')
49 cw.start_new_file('thing7.txt')
52 cw.start_new_file('thing8.txt')
55 cw.start_new_stream('edgecases')
56 for f in ":/./../.../-/*/\x01\\/ ".split("/"):
60 for f in ":/../.../-/*/\x01\\/ ".split("/"):
61 cw.start_new_stream('edgecases/dirs/' + f)
62 cw.start_new_file('x/x')
65 self.testcollection = cw.finish()
66 self.api.collections().create(body={"manifest_text":cw.manifest_text()}).execute()
69 self.make_mount(fuse.CollectionDirectory, collection_record=self.testcollection)
71 self.assertDirContents(None, ['thing1.txt', 'thing2.txt',
72 'edgecases', 'dir1', 'dir2'])
73 self.assertDirContents('dir1', ['thing3.txt', 'thing4.txt'])
74 self.assertDirContents('dir2', ['thing5.txt', 'thing6.txt', 'dir3'])
75 self.assertDirContents('dir2/dir3', ['thing7.txt', 'thing8.txt'])
76 self.assertDirContents('edgecases',
77 "dirs/:/_/__/.../-/*/\x01\\/ ".split("/"))
78 self.assertDirContents('edgecases/dirs',
79 ":/__/.../-/*/\x01\\/ ".split("/"))
81 files = {'thing1.txt': 'data 1',
82 'thing2.txt': 'data 2',
83 'dir1/thing3.txt': 'data 3',
84 'dir1/thing4.txt': 'data 4',
85 'dir2/thing5.txt': 'data 5',
86 'dir2/thing6.txt': 'data 6',
87 'dir2/dir3/thing7.txt': 'data 7',
88 'dir2/dir3/thing8.txt': 'data 8'}
90 for k, v in files.items():
91 with open(os.path.join(self.mounttmp, k)) as f:
92 self.assertEqual(v, f.read())
95 class FuseNoAPITest(MountTestBase):
97 super(FuseNoAPITest, self).setUp()
98 keep = arvados.keep.KeepClient(local_store=self.keeptmp)
99 self.file_data = "API-free text\n"
100 self.file_loc = keep.put(self.file_data)
101 self.coll_loc = keep.put(". {} 0:{}:api-free.txt\n".format(
102 self.file_loc, len(self.file_data)))
105 self.make_mount(fuse.MagicDirectory)
106 self.assertDirContents(self.coll_loc, ['api-free.txt'])
107 with open(os.path.join(
108 self.mounttmp, self.coll_loc, 'api-free.txt')) as keep_file:
109 actual = keep_file.read(-1)
110 self.assertEqual(self.file_data, actual)
113 class FuseMagicTest(MountTestBase):
114 def setUp(self, api=None):
115 super(FuseMagicTest, self).setUp(api=api)
117 cw = arvados.CollectionWriter()
119 cw.start_new_file('thing1.txt')
122 self.testcollection = cw.finish()
123 self.test_manifest = cw.manifest_text()
124 self.api.collections().create(body={"manifest_text":self.test_manifest}).execute()
127 self.make_mount(fuse.MagicDirectory)
129 mount_ls = llfuse.listdir(self.mounttmp)
130 self.assertIn('README', mount_ls)
131 self.assertFalse(any(arvados.util.keep_locator_pattern.match(fn) or
132 arvados.util.uuid_pattern.match(fn)
134 "new FUSE MagicDirectory lists Collection")
135 self.assertDirContents(self.testcollection, ['thing1.txt'])
136 self.assertDirContents(os.path.join('by_id', self.testcollection),
138 mount_ls = llfuse.listdir(self.mounttmp)
139 self.assertIn('README', mount_ls)
140 self.assertIn(self.testcollection, mount_ls)
141 self.assertIn(self.testcollection,
142 llfuse.listdir(os.path.join(self.mounttmp, 'by_id')))
145 files[os.path.join(self.mounttmp, self.testcollection, 'thing1.txt')] = 'data 1'
147 for k, v in files.items():
148 with open(os.path.join(self.mounttmp, k)) as f:
149 self.assertEqual(v, f.read())
152 class FuseTagsTest(MountTestBase):
154 self.make_mount(fuse.TagsDirectory)
156 d1 = llfuse.listdir(self.mounttmp)
158 self.assertEqual(['foo_tag'], d1)
160 d2 = llfuse.listdir(os.path.join(self.mounttmp, 'foo_tag'))
162 self.assertEqual(['zzzzz-4zz18-fy296fx3hot09f7'], d2)
164 d3 = llfuse.listdir(os.path.join(self.mounttmp, 'foo_tag', 'zzzzz-4zz18-fy296fx3hot09f7'))
166 self.assertEqual(['foo'], d3)
169 class FuseTagsUpdateTest(MountTestBase):
170 def tag_collection(self, coll_uuid, tag_name):
171 return self.api.links().create(
172 body={'link': {'head_uuid': coll_uuid,
178 self.make_mount(fuse.TagsDirectory, poll_time=1)
180 self.assertIn('foo_tag', llfuse.listdir(self.mounttmp))
182 bar_uuid = run_test_server.fixture('collections')['bar_file']['uuid']
183 self.tag_collection(bar_uuid, 'fuse_test_tag')
185 self.assertIn('fuse_test_tag', llfuse.listdir(self.mounttmp))
186 self.assertDirContents('fuse_test_tag', [bar_uuid])
188 baz_uuid = run_test_server.fixture('collections')['baz_file']['uuid']
189 l = self.tag_collection(baz_uuid, 'fuse_test_tag')
191 self.assertDirContents('fuse_test_tag', [bar_uuid, baz_uuid])
193 self.api.links().delete(uuid=l['uuid']).execute()
195 self.assertDirContents('fuse_test_tag', [bar_uuid])
198 class FuseSharedTest(MountTestBase):
200 self.make_mount(fuse.SharedDirectory,
201 exclude=self.api.users().current().execute()['uuid'])
203 # shared_dirs is a list of the directories exposed
204 # by fuse.SharedDirectory (i.e. any object visible
205 # to the current user)
206 shared_dirs = llfuse.listdir(self.mounttmp)
208 self.assertIn('FUSE User', shared_dirs)
210 # fuse_user_objs is a list of the objects owned by the FUSE
211 # test user (which present as files in the 'FUSE User'
213 fuse_user_objs = llfuse.listdir(os.path.join(self.mounttmp, 'FUSE User'))
214 fuse_user_objs.sort()
215 self.assertEqual(['FUSE Test Project', # project owned by user
216 'collection #1 owned by FUSE', # collection owned by user
217 'collection #2 owned by FUSE', # collection owned by user
218 'pipeline instance owned by FUSE.pipelineInstance', # pipeline instance owned by user
221 # test_proj_files is a list of the files in the FUSE Test Project.
222 test_proj_files = llfuse.listdir(os.path.join(self.mounttmp, 'FUSE User', 'FUSE Test Project'))
223 test_proj_files.sort()
224 self.assertEqual(['collection in FUSE project',
225 'pipeline instance in FUSE project.pipelineInstance',
226 'pipeline template in FUSE project.pipelineTemplate'
229 # Double check that we can open and read objects in this folder as a file,
230 # and that its contents are what we expect.
231 pipeline_template_path = os.path.join(
235 'pipeline template in FUSE project.pipelineTemplate')
236 with open(pipeline_template_path) as f:
238 self.assertEqual("pipeline template in FUSE project", j['name'])
240 # check mtime on template
241 st = os.stat(pipeline_template_path)
242 self.assertEqual(st.st_mtime, 1397493304)
244 # check mtime on collection
245 st = os.stat(os.path.join(
248 'collection #1 owned by FUSE'))
249 self.assertEqual(st.st_mtime, 1391448174)
252 class FuseHomeTest(MountTestBase):
254 self.make_mount(fuse.ProjectDirectory,
255 project_object=self.api.users().current().execute())
257 d1 = llfuse.listdir(self.mounttmp)
258 self.assertIn('Unrestricted public data', d1)
260 d2 = llfuse.listdir(os.path.join(self.mounttmp, 'Unrestricted public data'))
261 public_project = run_test_server.fixture('groups')[
262 'anonymously_accessible_project']
265 for name, item in run_test_server.fixture('collections').iteritems():
266 if 'name' not in item:
268 elif item['owner_uuid'] == public_project['uuid']:
269 self.assertIn(item['name'], d2)
272 # Artificial assumption here: there is no public
273 # collection fixture with the same name as a
274 # non-public collection.
275 self.assertNotIn(item['name'], d2)
277 self.assertNotEqual(0, found_in)
278 self.assertNotEqual(0, found_not_in)
280 d3 = llfuse.listdir(os.path.join(self.mounttmp, 'Unrestricted public data', 'GNU General Public License, version 3'))
281 self.assertEqual(["GNU_General_Public_License,_version_3.pdf"], d3)
284 def fuseModifyFileTestHelperReadStartContents(mounttmp):
285 class Test(unittest.TestCase):
287 d1 = llfuse.listdir(mounttmp)
288 self.assertEqual(["file1.txt"], d1)
289 with open(os.path.join(mounttmp, "file1.txt")) as f:
290 self.assertEqual("blub", f.read())
293 def fuseModifyFileTestHelperReadEndContents(mounttmp):
294 class Test(unittest.TestCase):
296 d1 = llfuse.listdir(mounttmp)
297 self.assertEqual(["file1.txt"], d1)
298 with open(os.path.join(mounttmp, "file1.txt")) as f:
299 self.assertEqual("plnp", f.read())
302 class FuseModifyFileTest(MountTestBase):
304 collection = arvados.collection.Collection(api_client=self.api)
305 with collection.open("file1.txt", "w") as f:
308 collection.save_new()
310 m = self.make_mount(fuse.CollectionDirectory)
312 m.new_collection(collection.api_response(), collection)
314 self.pool.apply(fuseModifyFileTestHelperReadStartContents, (self.mounttmp,))
316 with collection.open("file1.txt", "w") as f:
319 self.pool.apply(fuseModifyFileTestHelperReadEndContents, (self.mounttmp,))
322 class FuseAddFileToCollectionTest(MountTestBase):
324 collection = arvados.collection.Collection(api_client=self.api)
325 with collection.open("file1.txt", "w") as f:
328 collection.save_new()
330 m = self.make_mount(fuse.CollectionDirectory)
332 m.new_collection(collection.api_response(), collection)
334 d1 = llfuse.listdir(self.mounttmp)
335 self.assertEqual(["file1.txt"], d1)
337 with collection.open("file2.txt", "w") as f:
340 d1 = llfuse.listdir(self.mounttmp)
341 self.assertEqual(["file1.txt", "file2.txt"], sorted(d1))
344 class FuseRemoveFileFromCollectionTest(MountTestBase):
346 collection = arvados.collection.Collection(api_client=self.api)
347 with collection.open("file1.txt", "w") as f:
350 with collection.open("file2.txt", "w") as f:
353 collection.save_new()
355 m = self.make_mount(fuse.CollectionDirectory)
357 m.new_collection(collection.api_response(), collection)
359 d1 = llfuse.listdir(self.mounttmp)
360 self.assertEqual(["file1.txt", "file2.txt"], sorted(d1))
362 collection.remove("file2.txt")
364 d1 = llfuse.listdir(self.mounttmp)
365 self.assertEqual(["file1.txt"], d1)
368 def fuseCreateFileTestHelper(mounttmp):
369 class Test(unittest.TestCase):
371 with open(os.path.join(mounttmp, "file1.txt"), "w") as f:
375 class FuseCreateFileTest(MountTestBase):
377 collection = arvados.collection.Collection(api_client=self.api)
378 collection.save_new()
380 collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute()
381 self.assertEqual(collection2["manifest_text"], "")
383 collection.save_new()
385 m = self.make_mount(fuse.CollectionDirectory)
387 m.new_collection(collection.api_response(), collection)
388 self.assertTrue(m.writable())
390 self.assertNotIn("file1.txt", collection)
392 self.pool.apply(fuseCreateFileTestHelper, (self.mounttmp,))
394 self.assertIn("file1.txt", collection)
396 d1 = llfuse.listdir(self.mounttmp)
397 self.assertEqual(["file1.txt"], d1)
399 collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute()
400 self.assertRegexpMatches(collection2["manifest_text"],
401 r'\. d41d8cd98f00b204e9800998ecf8427e\+0\+A\S+ 0:0:file1\.txt$')
404 def fuseWriteFileTestHelperWriteFile(mounttmp):
405 class Test(unittest.TestCase):
407 with open(os.path.join(mounttmp, "file1.txt"), "w") as f:
408 f.write("Hello world!")
411 def fuseWriteFileTestHelperReadFile(mounttmp):
412 class Test(unittest.TestCase):
414 with open(os.path.join(mounttmp, "file1.txt"), "r") as f:
415 self.assertEqual(f.read(), "Hello world!")
418 class FuseWriteFileTest(MountTestBase):
420 collection = arvados.collection.Collection(api_client=self.api)
421 collection.save_new()
423 m = self.make_mount(fuse.CollectionDirectory)
425 m.new_collection(collection.api_response(), collection)
426 self.assertTrue(m.writable())
428 self.assertNotIn("file1.txt", collection)
430 self.pool.apply(fuseWriteFileTestHelperWriteFile, (self.mounttmp,))
432 with collection.open("file1.txt") as f:
433 self.assertEqual(f.read(), "Hello world!")
435 self.pool.apply(fuseWriteFileTestHelperReadFile, (self.mounttmp,))
437 collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute()
438 self.assertRegexpMatches(collection2["manifest_text"],
439 r'\. 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$')
442 def fuseUpdateFileTestHelper(mounttmp):
443 class Test(unittest.TestCase):
445 with open(os.path.join(mounttmp, "file1.txt"), "w") as f:
446 f.write("Hello world!")
448 with open(os.path.join(mounttmp, "file1.txt"), "r+") as f:
450 self.assertEqual(fr, "Hello world!")
452 f.write("Hola mundo!")
455 self.assertEqual(fr, "Hola mundo!!")
457 with open(os.path.join(mounttmp, "file1.txt"), "r") as f:
458 self.assertEqual(f.read(), "Hola mundo!!")
462 class FuseUpdateFileTest(MountTestBase):
464 collection = arvados.collection.Collection(api_client=self.api)
465 collection.save_new()
467 m = self.make_mount(fuse.CollectionDirectory)
469 m.new_collection(collection.api_response(), collection)
470 self.assertTrue(m.writable())
472 # See note in MountTestBase.setUp
473 self.pool.apply(fuseUpdateFileTestHelper, (self.mounttmp,))
475 collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute()
476 self.assertRegexpMatches(collection2["manifest_text"],
477 r'\. daaef200ebb921e011e3ae922dd3266b\+11\+A\S+ 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:11:file1\.txt 22:1:file1\.txt$')
480 def fuseMkdirTestHelper(mounttmp):
481 class Test(unittest.TestCase):
483 with self.assertRaises(IOError):
484 with open(os.path.join(mounttmp, "testdir", "file1.txt"), "w") as f:
485 f.write("Hello world!")
487 os.mkdir(os.path.join(mounttmp, "testdir"))
489 with self.assertRaises(OSError):
490 os.mkdir(os.path.join(mounttmp, "testdir"))
492 d1 = llfuse.listdir(mounttmp)
493 self.assertEqual(["testdir"], d1)
495 with open(os.path.join(mounttmp, "testdir", "file1.txt"), "w") as f:
496 f.write("Hello world!")
498 d1 = llfuse.listdir(os.path.join(mounttmp, "testdir"))
499 self.assertEqual(["file1.txt"], d1)
503 class FuseMkdirTest(MountTestBase):
505 collection = arvados.collection.Collection(api_client=self.api)
506 collection.save_new()
508 m = self.make_mount(fuse.CollectionDirectory)
510 m.new_collection(collection.api_response(), collection)
511 self.assertTrue(m.writable())
513 self.pool.apply(fuseMkdirTestHelper, (self.mounttmp,))
515 collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute()
516 self.assertRegexpMatches(collection2["manifest_text"],
517 r'\./testdir 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$')
520 def fuseRmTestHelperWriteFile(mounttmp):
521 class Test(unittest.TestCase):
523 os.mkdir(os.path.join(mounttmp, "testdir"))
525 with open(os.path.join(mounttmp, "testdir", "file1.txt"), "w") as f:
526 f.write("Hello world!")
530 def fuseRmTestHelperDeleteFile(mounttmp):
531 class Test(unittest.TestCase):
533 # Can't delete because it's not empty
534 with self.assertRaises(OSError):
535 os.rmdir(os.path.join(mounttmp, "testdir"))
537 d1 = llfuse.listdir(os.path.join(mounttmp, "testdir"))
538 self.assertEqual(["file1.txt"], d1)
541 os.remove(os.path.join(mounttmp, "testdir", "file1.txt"))
543 # Make sure it's empty
544 d1 = llfuse.listdir(os.path.join(mounttmp, "testdir"))
545 self.assertEqual([], d1)
547 # Try to delete it again
548 with self.assertRaises(OSError):
549 os.remove(os.path.join(mounttmp, "testdir", "file1.txt"))
553 def fuseRmTestHelperRmdir(mounttmp):
554 class Test(unittest.TestCase):
556 # Should be able to delete now that it is empty
557 os.rmdir(os.path.join(mounttmp, "testdir"))
559 # Make sure it's empty
560 d1 = llfuse.listdir(os.path.join(mounttmp))
561 self.assertEqual([], d1)
563 # Try to delete it again
564 with self.assertRaises(OSError):
565 os.rmdir(os.path.join(mounttmp, "testdir"))
569 class FuseRmTest(MountTestBase):
571 collection = arvados.collection.Collection(api_client=self.api)
572 collection.save_new()
574 m = self.make_mount(fuse.CollectionDirectory)
576 m.new_collection(collection.api_response(), collection)
577 self.assertTrue(m.writable())
579 self.pool.apply(fuseRmTestHelperWriteFile, (self.mounttmp,))
582 collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute()
583 self.assertRegexpMatches(collection2["manifest_text"],
584 r'\./testdir 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$')
585 self.pool.apply(fuseRmTestHelperDeleteFile, (self.mounttmp,))
587 # Can't have empty directories :-( so manifest will be empty.
588 collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute()
589 self.assertEqual(collection2["manifest_text"], "")
591 self.pool.apply(fuseRmTestHelperRmdir, (self.mounttmp,))
593 # manifest should be empty now.
594 collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute()
595 self.assertEqual(collection2["manifest_text"], "")
598 def fuseMvFileTestHelperWriteFile(mounttmp):
599 class Test(unittest.TestCase):
601 os.mkdir(os.path.join(mounttmp, "testdir"))
603 with open(os.path.join(mounttmp, "testdir", "file1.txt"), "w") as f:
604 f.write("Hello world!")
608 def fuseMvFileTestHelperMoveFile(mounttmp):
609 class Test(unittest.TestCase):
611 d1 = llfuse.listdir(os.path.join(mounttmp))
612 self.assertEqual(["testdir"], d1)
613 d1 = llfuse.listdir(os.path.join(mounttmp, "testdir"))
614 self.assertEqual(["file1.txt"], d1)
616 os.rename(os.path.join(mounttmp, "testdir", "file1.txt"), os.path.join(mounttmp, "file1.txt"))
618 d1 = llfuse.listdir(os.path.join(mounttmp))
619 self.assertEqual(["file1.txt", "testdir"], sorted(d1))
620 d1 = llfuse.listdir(os.path.join(mounttmp, "testdir"))
621 self.assertEqual([], d1)
625 class FuseMvFileTest(MountTestBase):
627 collection = arvados.collection.Collection(api_client=self.api)
628 collection.save_new()
630 m = self.make_mount(fuse.CollectionDirectory)
632 m.new_collection(collection.api_response(), collection)
633 self.assertTrue(m.writable())
635 self.pool.apply(fuseMvFileTestHelperWriteFile, (self.mounttmp,))
638 collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute()
639 self.assertRegexpMatches(collection2["manifest_text"],
640 r'\./testdir 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$')
642 self.pool.apply(fuseMvFileTestHelperMoveFile, (self.mounttmp,))
644 collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute()
645 self.assertRegexpMatches(collection2["manifest_text"],
646 r'\. 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$')
649 def fuseRenameTestHelper(mounttmp):
650 class Test(unittest.TestCase):
652 os.mkdir(os.path.join(mounttmp, "testdir"))
654 with open(os.path.join(mounttmp, "testdir", "file1.txt"), "w") as f:
655 f.write("Hello world!")
659 class FuseRenameTest(MountTestBase):
661 collection = arvados.collection.Collection(api_client=self.api)
662 collection.save_new()
664 m = self.make_mount(fuse.CollectionDirectory)
666 m.new_collection(collection.api_response(), collection)
667 self.assertTrue(m.writable())
669 self.pool.apply(fuseRenameTestHelper, (self.mounttmp,))
672 collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute()
673 self.assertRegexpMatches(collection2["manifest_text"],
674 r'\./testdir 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$')
676 d1 = llfuse.listdir(os.path.join(self.mounttmp))
677 self.assertEqual(["testdir"], d1)
678 d1 = llfuse.listdir(os.path.join(self.mounttmp, "testdir"))
679 self.assertEqual(["file1.txt"], d1)
681 os.rename(os.path.join(self.mounttmp, "testdir"), os.path.join(self.mounttmp, "testdir2"))
683 d1 = llfuse.listdir(os.path.join(self.mounttmp))
684 self.assertEqual(["testdir2"], sorted(d1))
685 d1 = llfuse.listdir(os.path.join(self.mounttmp, "testdir2"))
686 self.assertEqual(["file1.txt"], d1)
688 collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute()
689 self.assertRegexpMatches(collection2["manifest_text"],
690 r'\./testdir2 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$')
693 class FuseUpdateFromEventTest(MountTestBase):
695 collection = arvados.collection.Collection(api_client=self.api)
696 collection.save_new()
698 m = self.make_mount(fuse.CollectionDirectory)
700 m.new_collection(collection.api_response(), collection)
702 self.operations.listen_for_events(self.api)
704 d1 = llfuse.listdir(os.path.join(self.mounttmp))
705 self.assertEqual([], sorted(d1))
707 with arvados.collection.Collection(collection.manifest_locator(), api_client=self.api) as collection2:
708 with collection2.open("file1.txt", "w") as f:
713 # should show up via event bus notify
715 d1 = llfuse.listdir(os.path.join(self.mounttmp))
716 self.assertEqual(["file1.txt"], sorted(d1))
719 def fuseFileConflictTestHelper(mounttmp):
720 class Test(unittest.TestCase):
722 with open(os.path.join(mounttmp, "file1.txt"), "w") as f:
725 d1 = sorted(llfuse.listdir(os.path.join(mounttmp)))
726 self.assertEqual(len(d1), 2)
728 with open(os.path.join(mounttmp, "file1.txt"), "r") as f:
729 self.assertEqual(f.read(), "bar")
731 self.assertRegexpMatches(d1[1],
732 r'file1\.txt~\d\d\d\d\d\d\d\d-\d\d\d\d\d\d~conflict~')
734 with open(os.path.join(mounttmp, d1[1]), "r") as f:
735 self.assertEqual(f.read(), "foo")
739 class FuseFileConflictTest(MountTestBase):
741 collection = arvados.collection.Collection(api_client=self.api)
742 collection.save_new()
744 m = self.make_mount(fuse.CollectionDirectory)
746 m.new_collection(collection.api_response(), collection)
748 d1 = llfuse.listdir(os.path.join(self.mounttmp))
749 self.assertEqual([], sorted(d1))
751 with arvados.collection.Collection(collection.manifest_locator(), api_client=self.api) as collection2:
752 with collection2.open("file1.txt", "w") as f:
755 # See note in MountTestBase.setUp
756 self.pool.apply(fuseFileConflictTestHelper, (self.mounttmp,))
759 def fuseUnlinkOpenFileTest(mounttmp):
760 class Test(unittest.TestCase):
762 with open(os.path.join(mounttmp, "file1.txt"), "w+") as f:
765 d1 = llfuse.listdir(os.path.join(mounttmp))
766 self.assertEqual(["file1.txt"], sorted(d1))
768 os.remove(os.path.join(mounttmp, "file1.txt"))
770 d1 = llfuse.listdir(os.path.join(mounttmp))
771 self.assertEqual([], sorted(d1))
774 self.assertEqual(f.read(), "foo")
778 self.assertEqual(f.read(), "foobar")
782 class FuseUnlinkOpenFileTest(MountTestBase):
784 collection = arvados.collection.Collection(api_client=self.api)
785 collection.save_new()
787 m = self.make_mount(fuse.CollectionDirectory)
789 m.new_collection(collection.api_response(), collection)
791 # See note in MountTestBase.setUp
792 self.pool.apply(fuseUnlinkOpenFileTest, (self.mounttmp,))
794 self.assertEqual(collection.manifest_text(), "")
797 def fuseMvFileBetweenCollectionsTest1(mounttmp, uuid1, uuid2):
798 class Test(unittest.TestCase):
800 with open(os.path.join(mounttmp, uuid1, "file1.txt"), "w") as f:
801 f.write("Hello world!")
803 d1 = os.listdir(os.path.join(mounttmp, uuid1))
804 self.assertEqual(["file1.txt"], sorted(d1))
805 d1 = os.listdir(os.path.join(mounttmp, uuid2))
806 self.assertEqual([], sorted(d1))
810 def fuseMvFileBetweenCollectionsTest2(mounttmp, uuid1, uuid2):
811 class Test(unittest.TestCase):
813 os.rename(os.path.join(mounttmp, uuid1, "file1.txt"), os.path.join(mounttmp, uuid2, "file2.txt"))
815 d1 = os.listdir(os.path.join(mounttmp, uuid1))
816 self.assertEqual([], sorted(d1))
817 d1 = os.listdir(os.path.join(mounttmp, uuid2))
818 self.assertEqual(["file2.txt"], sorted(d1))
822 class FuseMvFileBetweenCollectionsTest(MountTestBase):
824 collection1 = arvados.collection.Collection(api_client=self.api)
825 collection1.save_new()
827 collection2 = arvados.collection.Collection(api_client=self.api)
828 collection2.save_new()
830 m = self.make_mount(fuse.MagicDirectory)
832 # See note in MountTestBase.setUp
833 self.pool.apply(fuseMvFileBetweenCollectionsTest1, (self.mounttmp,
834 collection1.manifest_locator(),
835 collection2.manifest_locator()))
840 self.assertRegexpMatches(collection1.manifest_text(), r"\. 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$")
841 self.assertEqual(collection2.manifest_text(), "")
843 self.pool.apply(fuseMvFileBetweenCollectionsTest2, (self.mounttmp,
844 collection1.manifest_locator(),
845 collection2.manifest_locator()))
850 self.assertEqual(collection1.manifest_text(), "")
851 self.assertRegexpMatches(collection2.manifest_text(), r"\. 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file2\.txt$")
853 collection1.stop_threads()
854 collection2.stop_threads()
857 def fuseMvDirBetweenCollectionsTest1(mounttmp, uuid1, uuid2):
858 class Test(unittest.TestCase):
860 os.mkdir(os.path.join(mounttmp, uuid1, "testdir"))
861 with open(os.path.join(mounttmp, uuid1, "testdir", "file1.txt"), "w") as f:
862 f.write("Hello world!")
864 d1 = os.listdir(os.path.join(mounttmp, uuid1))
865 self.assertEqual(["testdir"], sorted(d1))
866 d1 = os.listdir(os.path.join(mounttmp, uuid1, "testdir"))
867 self.assertEqual(["file1.txt"], sorted(d1))
869 d1 = os.listdir(os.path.join(mounttmp, uuid2))
870 self.assertEqual([], sorted(d1))
875 def fuseMvDirBetweenCollectionsTest2(mounttmp, uuid1, uuid2):
876 class Test(unittest.TestCase):
878 os.rename(os.path.join(mounttmp, uuid1, "testdir"), os.path.join(mounttmp, uuid2, "testdir2"))
880 d1 = os.listdir(os.path.join(mounttmp, uuid1))
881 self.assertEqual([], sorted(d1))
883 d1 = os.listdir(os.path.join(mounttmp, uuid2))
884 self.assertEqual(["testdir2"], sorted(d1))
885 d1 = os.listdir(os.path.join(mounttmp, uuid2, "testdir2"))
886 self.assertEqual(["file1.txt"], sorted(d1))
888 with open(os.path.join(mounttmp, uuid2, "testdir2", "file1.txt"), "r") as f:
889 self.assertEqual(f.read(), "Hello world!")
893 class FuseMvDirBetweenCollectionsTest(MountTestBase):
895 collection1 = arvados.collection.Collection(api_client=self.api)
896 collection1.save_new()
898 collection2 = arvados.collection.Collection(api_client=self.api)
899 collection2.save_new()
901 m = self.make_mount(fuse.MagicDirectory)
903 # See note in MountTestBase.setUp
904 self.pool.apply(fuseMvDirBetweenCollectionsTest1, (self.mounttmp,
905 collection1.manifest_locator(),
906 collection2.manifest_locator()))
911 self.assertRegexpMatches(collection1.manifest_text(), r"\./testdir 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$")
912 self.assertEqual(collection2.manifest_text(), "")
914 self.pool.apply(fuseMvDirBetweenCollectionsTest2, (self.mounttmp,
915 collection1.manifest_locator(),
916 collection2.manifest_locator()))
921 self.assertEqual(collection1.manifest_text(), "")
922 self.assertRegexpMatches(collection2.manifest_text(), r"\./testdir2 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$")
924 collection1.stop_threads()
925 collection2.stop_threads()
927 def fuseProjectMkdirTestHelper1(mounttmp):
928 class Test(unittest.TestCase):
930 os.mkdir(os.path.join(mounttmp, "testcollection"))
931 with self.assertRaises(OSError):
932 os.mkdir(os.path.join(mounttmp, "testcollection"))
935 def fuseProjectMkdirTestHelper2(mounttmp):
936 class Test(unittest.TestCase):
938 with open(os.path.join(mounttmp, "testcollection", "file1.txt"), "w") as f:
939 f.write("Hello world!")
940 with self.assertRaises(OSError):
941 os.rmdir(os.path.join(mounttmp, "testcollection"))
942 os.remove(os.path.join(mounttmp, "testcollection", "file1.txt"))
943 with self.assertRaises(OSError):
944 os.remove(os.path.join(mounttmp, "testcollection"))
945 os.rmdir(os.path.join(mounttmp, "testcollection"))
948 class FuseProjectMkdirRmdirTest(MountTestBase):
950 self.make_mount(fuse.ProjectDirectory,
951 project_object=self.api.users().current().execute())
953 d1 = llfuse.listdir(self.mounttmp)
954 self.assertNotIn('testcollection', d1)
956 self.pool.apply(fuseProjectMkdirTestHelper1, (self.mounttmp,))
958 d1 = llfuse.listdir(self.mounttmp)
959 self.assertIn('testcollection', d1)
961 self.pool.apply(fuseProjectMkdirTestHelper2, (self.mounttmp,))
963 d1 = llfuse.listdir(self.mounttmp)
964 self.assertNotIn('testcollection', d1)
967 def fuseProjectMvTestHelper1(mounttmp):
968 class Test(unittest.TestCase):
970 d1 = llfuse.listdir(mounttmp)
971 self.assertNotIn('testcollection', d1)
973 os.mkdir(os.path.join(mounttmp, "testcollection"))
975 d1 = llfuse.listdir(mounttmp)
976 self.assertIn('testcollection', d1)
978 with self.assertRaises(OSError):
979 os.rename(os.path.join(mounttmp, "testcollection"), os.path.join(mounttmp, 'Unrestricted public data'))
981 os.rename(os.path.join(mounttmp, "testcollection"), os.path.join(mounttmp, 'Unrestricted public data', 'testcollection'))
983 d1 = llfuse.listdir(mounttmp)
984 self.assertNotIn('testcollection', d1)
986 d1 = llfuse.listdir(os.path.join(mounttmp, 'Unrestricted public data'))
987 self.assertIn('testcollection', d1)
991 class FuseProjectMvTest(MountTestBase):
993 self.make_mount(fuse.ProjectDirectory,
994 project_object=self.api.users().current().execute())
996 self.pool.apply(fuseProjectMvTestHelper1, (self.mounttmp,))
999 def fuseFsyncTestHelper(mounttmp, k):
1000 class Test(unittest.TestCase):
1002 fd = os.open(os.path.join(mounttmp, k), os.O_RDONLY)
1008 class FuseFsyncTest(FuseMagicTest):
1010 self.make_mount(fuse.MagicDirectory)
1011 self.pool.apply(fuseFsyncTestHelper, (self.mounttmp, self.testcollection))
1014 class MagicDirApiError(FuseMagicTest):
1016 api = mock.MagicMock()
1017 super(MagicDirApiError, self).setUp(api=api)
1018 api.collections().get().execute.side_effect = iter([Exception('API fail'), {"manifest_text": self.test_manifest}])
1019 api.keep.get.side_effect = Exception('Keep fail')
1022 self.make_mount(fuse.MagicDirectory)
1024 self.operations.inodes.inode_cache.cap = 1
1025 self.operations.inodes.inode_cache.min_entries = 2
1027 with self.assertRaises(OSError):
1028 llfuse.listdir(os.path.join(self.mounttmp, self.testcollection))
1030 llfuse.listdir(os.path.join(self.mounttmp, self.testcollection))
1033 class FuseUnitTest(unittest.TestCase):
1034 def test_sanitize_filename(self):
1053 for f in acceptable:
1054 self.assertEqual(f, fuse.sanitize_filename(f))
1055 for f in unacceptable:
1056 self.assertNotEqual(f, fuse.sanitize_filename(f))
1057 # The sanitized filename should be the same length, though.
1058 self.assertEqual(len(f), len(fuse.sanitize_filename(f)))
1060 self.assertEqual("_", fuse.sanitize_filename(""))
1061 self.assertEqual("_", fuse.sanitize_filename("."))
1062 self.assertEqual("__", fuse.sanitize_filename(".."))