Exemple #1
0
 def testDelete(self):
     files.File('/foo').write('')
     files.File('/bar').write(LARGE_FILE_CONTENT)
     files.File('/qux').write('')
     blob_key = files.File('/bar').blob.key()
     files.Files(['/foo', '/bar']).delete()
     self.assertEqual(files.Files(['/qux']),
                      files.Files(['/foo', '/bar', '/qux']).load())
     # Verify that the blob is also deleted.
     self.assertIsNone(blobstore.get(blob_key))
Exemple #2
0
    def testCopyTo(self):
        # Populate the in-context cache by reading the file before creation.
        self.assertFalse(files.File('/x/b/foo').exists)

        files.File('/foo').write('')
        files.File('/a/foo').write('')
        files.File('/a/b/foo').write('')
        files.File('/c/foo').write('')

        result_files = files.Files()
        failed_files = files.Files()
        files.Files.list('/').copy_to(dir_path='/x',
                                      result_files=result_files,
                                      failed_files=failed_files)
        expected_paths = [
            '/x/foo',
        ]
        self.assertSameElements(expected_paths, result_files.keys())
        self.assertEqual([], failed_files.keys())
        titan_files = files.Files.list('/a/', recursive=True)
        titan_files.copy_to('/x',
                            strip_prefix='/a/',
                            result_files=result_files)
        expected_paths = [
            '/x/foo',
            '/x/b/foo',
        ]
        self.assertSameElements(expected_paths, result_files.keys())
        # With trailing slashes should be the same.
        result_files.clear()
        titan_files.copy_to('/x/',
                            strip_prefix='/a/',
                            result_files=result_files)
        self.assertSameElements(expected_paths, result_files.keys())

        result_files = files.Files()
        failed_files = files.Files()
        files_paths = ['/foo', '/fake']
        self.assertRaises(files.CopyFilesError,
                          files.Files(files_paths).copy_to,
                          dir_path='/x',
                          result_files=result_files,
                          failed_files=failed_files)
        expected_paths = [
            '/x/foo',
        ]
        failed_paths = [
            '/x/fake',
        ]
        self.assertSameElements(expected_paths, result_files.keys())
        self.assertSameElements(failed_paths, failed_files.keys())

        # Verify that the NDB in-context cache was cleared correctly.
        self.assertTrue(files.File('/x/b/foo').exists)
Exemple #3
0
    def testMoveTo(self):
        # Populate the in-context cache by reading the file before creation.
        self.assertFalse(files.File('/x/b/foo').exists)

        files.File('/foo').write('')
        files.File('/a/foo').write('')
        files.File('/a/b/foo').write('')
        files.File('/c/foo').write('')

        result_files = files.Files()
        titan_files = files.Files.list('/a/', recursive=True)
        titan_files.move_to('/x',
                            strip_prefix='/a/',
                            result_files=result_files)
        expected_paths = [
            '/x/foo',
            '/x/b/foo',
        ]
        self.assertSameElements(expected_paths, result_files.keys())

        # Verify files has been deleted from the old directory.
        self.assertFalse(files.File('/a/foo').exists)
        self.assertFalse(files.File('/a/b/foo').exists)

        result_files = files.Files()
        failed_files = files.Files()
        files_paths = ['/foo', '/fake']
        self.assertRaises(files.CopyFilesError,
                          files.Files(files_paths).move_to,
                          dir_path='/x',
                          result_files=result_files,
                          failed_files=failed_files)
        expected_paths = [
            '/x/foo',
        ]
        failed_paths = [
            '/x/fake',
        ]
        self.assertSameElements(expected_paths, result_files.keys())
        self.assertSameElements(failed_paths, failed_files.keys())

        # Verify files has been deleted from the old directory.
        self.assertFalse(files.File('/foo').exists)

        # Verify that the NDB in-context cache was cleared correctly.
        self.assertTrue(files.File('/x/b/foo').exists)
Exemple #4
0
    def testFilesCount(self):
        # Create files for testing.
        root_level = files.Files(['/index.html', '/qux'])
        first_level = files.Files(['/foo/bar'])
        second_level = files.Files([
            '/foo/bar/baz',
            '/foo/bar/baz.html',
            '/foo/bar/baz.txt',
        ])
        root_and_first_levels = files.Files.merge(root_level, first_level)
        all_files = files.Files(root_level.keys() + first_level.keys() +
                                second_level.keys())

        for titan_file in all_files.itervalues():
            titan_file.write('')

        # Empty.
        self.assertEqual(0, files.Files.count('/fake/path'))

        # From root.
        self.assertEqual(len(root_level), files.Files.count('/'))
        self.assertEqual(len(all_files), files.Files.count('/',
                                                           recursive=True))

        # Limit recursion depth.
        self.assertEqual(len(root_and_first_levels),
                         files.Files.count('/', recursive=True, depth=1))

        # Custom filters:
        files.File('/a/foo').write('', meta={'color': 'red', 'item_id': 1})
        files.File('/a/bar/qux').write('', meta={'color': 'red', 'item_id': 2})
        files.File('/a/baz').write('', meta={'color': 'blue', 'item_id': 3})
        # Single filter:
        filters = [files.FileProperty('color') == 'blue']
        self.assertEqual(
            1, files.Files.count('/', recursive=True, filters=filters))
        # Multiple filters:
        filters = [
            files.FileProperty('color') == 'red',
            files.FileProperty('item_id') == 2,
        ]
        self.assertEqual(
            1, files.Files.count('/', recursive=True, filters=filters))
Exemple #5
0
    def testLoad(self):
        files.File('/foo').write('')
        files.File('/bar').write('')
        titan_files = files.Files(paths=['/foo', '/bar', '/fake'])
        titan_files.load()

        self.assertIn('/foo', titan_files)
        self.assertIn('/bar', titan_files)
        self.assertTrue(titan_files['/foo'].is_loaded)
        self.assertTrue(titan_files['/bar'].is_loaded)
        self.assertNotIn('/fake', titan_files)
Exemple #6
0
  def testMixin(self):
    # NOTE: Look here first. If this test fails, other tests are likely broken.
    changeset = self.vcs.new_staging_changeset()
    meta = {'color': 'blue', 'flag': False}
    files.File('/foo', changeset=changeset).write('foo-versioned')
    files.File('/bar', changeset=changeset).write('bar-versioned', meta=meta)

    # exists().
    self.assertFalse(files.File('/foo').exists)
    self.assertTrue(files.File('/foo', changeset=changeset).exists)
    self.assertFalse(files.File('/fake', changeset=changeset).exists)

    # Init with an uncommitted file path:
    self.assertFalse(files.File('/foo').exists)
    # Init with an uncommitted file within a changeset:
    titan_file = files.File('/foo', changeset=changeset)
    self.assertEqual('/foo', titan_file.path)
    self.assertEqual('/_titan/ver/1/foo', titan_file.versioned_path)
    expected_foo = files.File('/foo', changeset=changeset)
    expected_bar = files.File('/bar', changeset=changeset)
    actual_titan_files = files.Files(files=[
        expected_foo,
        expected_bar,
        files.File('/fake', changeset=changeset),
    ])
    actual_titan_files.load()
    expected_titan_files = files.Files(files=[
        expected_foo,
        expected_bar,
    ])
    self.assertEqual(expected_titan_files, actual_titan_files)

    # write().
    titan_file = files.File('/foo', changeset=changeset)
    titan_file.write('foo', meta={'color': 'blue'})
    self.assertEqual('/_titan/ver/1/foo', titan_file.versioned_path)

    # Delete (really "mark for deletion").
    titan_file = files.File('/foo', changeset=changeset).delete()
    self.assertEqual('/_titan/ver/1/foo', titan_file.versioned_path)
    # Just for testing, set make sure the status is correct.
    titan_file._allow_deleted_files = True
    self.assertEqual(FILE_DELETED, titan_file.meta.status)
    # Files marked for delete technically exist at the versioned path,
    # but through the file interface they should pretend to not exist:
    self.assertFalse(files.File('/foo', changeset=changeset).exists)
    self.assertRaises(files.BadFileError,
                      lambda: files.File('/foo', changeset=changeset).content)

    # Revert a file marked for deletion.
    changeset.revert_file(files.File('/foo', changeset=changeset))
    self.assertFalse(files.File('/foo').exists)
    self.assertFalse(files.File('/foo', changeset=changeset).exists)

    # Commit the changeset (/bar is the only remaining file).
    changeset.finalize_associated_files()
    self.vcs.commit(changeset)

    # Check exists() with a committed file path.
    self.assertFalse(files.File('/foo').exists)
    self.assertTrue(files.File('/bar').exists)

    # Writing an already-existing file in a new changeset should
    # copy the existing file's content and attributes.
    changeset = self.vcs.new_staging_changeset()
    titan_file = files.File('/bar', changeset=changeset)
    # Should copy from last-committed file:
    titan_file.write(meta={'color': 'red'})

    # Test original object:
    self.assertEqual('bar-versioned', titan_file.content)
    self.assertEqual('red', titan_file.meta.color)
    self.assertEqual(False, titan_file.meta.flag)  # untouched meta property.
    # Test re-inited object:
    titan_file = files.File('/bar', changeset=changeset)
    self.assertEqual('bar-versioned', titan_file.content)
    self.assertEqual('red', titan_file.meta.color)
    self.assertEqual(False, titan_file.meta.flag)  # untouched meta property.
Exemple #7
0
    def testOrderedFiles(self):
        # Create files for testing.
        root_level = files.OrderedFiles([
            # These need to be alphabetically ordered here because they will be
            # usually returned that way from queries inside files.Files.list(),
            # except for when other filters are applied.
            '/bar',
            '/baz',
            '/foo',
        ])
        for titan_file in root_level.itervalues():
            titan_file.write('')

        # Verify that equality handles order checking. Do this first to make sure
        # that following assertEqual() calls are also checking for order.
        root_level_same_order = files.OrderedFiles([
            # Intentionally not the same order, to test Sort() right below.
            '/baz',
            '/foo',
            '/bar',
        ])
        root_level_same_order.sort()
        root_level_different_order = files.OrderedFiles([
            '/foo',
            '/baz',
            '/bar',
        ])
        self.assertEqual(root_level, root_level_same_order)
        self.assertNotEqual(root_level, root_level_different_order)
        self.assertNotEqual(files.OrderedFiles([]), root_level)

        # Test updating and removing items.
        new_root_level = files.OrderedFiles([
            '/bar',
            '/baz',
            '/foo',
        ])
        new_root_level.update(files.Files(['/qux']))
        self.assertNotEqual(root_level, new_root_level)
        del new_root_level['/qux']
        self.assertEqual(root_level, new_root_level)

        # Test files.OrderedFiles.list().
        self.assertEqual(root_level, files.OrderedFiles.list('/'))
        self.assertNotEqual(root_level_different_order,
                            files.OrderedFiles.list('/'))

        # Test files.OrderedFiles.list() with order= kwarg.
        self.Login('*****@*****.**')
        files.File('/a/middle').write('')
        self.Login('*****@*****.**')
        files.File('/a/last').write('')
        self.Login('*****@*****.**')
        files.File('/a/first').write('')
        order = [files.FileProperty('created_by')]
        results = files.OrderedFiles.list('/a', order=order)
        expected = files.OrderedFiles([
            '/a/first',
            '/a/middle',
            '/a/last',
        ])
        self.assertEqual(expected, results)

        # Test reverse order.
        order = [-files.FileProperty('created_by')]
        results = files.OrderedFiles.list('/a', order=order)
        expected = files.OrderedFiles([
            '/a/last',
            '/a/middle',
            '/a/first',
        ])
        self.assertEqual(expected, results)

        # Error handling.
        self.assertRaises(AttributeError, new_root_level.__setitem__, '/qux',
                          files.File('/qux'))
Exemple #8
0
    def testFilesList(self):
        # Create files for testing.
        root_level = files.Files(['/index.html', '/qux'])
        first_level = files.Files(['/foo/bar'])
        second_level = files.Files([
            '/foo/bar/baz',
            '/foo/bar/baz.html',
            '/foo/bar/baz.txt',
        ])
        root_and_first_levels = files.Files.merge(root_level, first_level)
        first_and_second_levels = files.Files.merge(first_level, second_level)

        # files.Files.update().
        all_files = files.Files([])
        all_files.update(root_level)
        all_files.update(first_level)
        all_files.update(second_level)
        self.assertEqual(6, len(all_files))

        # Test __eq__ (don't use assertEqual).
        self.assertTrue(files.Files(['/a', '/b']) == files.Files(['/a', '/b']))
        self.assertFalse(files.Files(['/a', '/b']) == files.Files(['/a']))

        for titan_file in all_files.itervalues():
            titan_file.write('')

        # Empty.
        self.assertSameObjects(files.Files(), files.Files.list('/fake/path'))
        self.assertSameObjects(files.Files([]), files.Files.list('/fake/path'))

        # From root.
        self.assertSameObjects(root_level, files.Files.list('/'))
        titan_files = files.Files.list('/', recursive=True)
        self.assertSameObjects(all_files, titan_files)

        # From first level dir.
        self.assertSameObjects(first_level, files.Files.list('/foo'))
        self.assertSameObjects(first_level, files.Files.list('/foo/'))
        titan_files = files.Files.list('/foo', recursive=True)
        self.assertSameObjects(first_and_second_levels, titan_files)

        # From second level dir.
        self.assertSameObjects(second_level, files.Files.list('/foo/bar'))
        titan_files = files.Files.list('/foo/bar', recursive=True)
        self.assertSameObjects(second_level, titan_files)

        # Limit recursion depth.
        titan_files = files.Files.list('/', recursive=True, depth=1)
        self.assertSameObjects(root_and_first_levels, titan_files)
        titan_files = files.Files.list('/', recursive=True, depth=2)
        self.assertSameObjects(all_files, titan_files)
        titan_files = files.Files.list('/foo/', recursive=True, depth=1)
        self.assertSameObjects(first_and_second_levels, titan_files)

        # Limit the number of files returned.
        titan_files = files.Files.list('/foo', recursive=True, limit=1)
        self.assertEqual(1, len(titan_files))

        # Support trailing slashes.
        self.assertSameObjects(second_level, files.Files.list('/foo/bar/'))
        titan_files = files.Files.list('/foo/bar/', recursive=True)
        self.assertSameObjects(second_level, titan_files)

        # Custom filters:
        files.File('/a/foo').write('', meta={'color': 'red', 'count': 1})
        files.File('/a/bar/qux').write('', meta={'color': 'red', 'count': 2})
        files.File('/a/baz').write('', meta={'color': 'blue', 'count': 3})
        # Single filter:
        filters = [files.FileProperty('color') == 'red']
        titan_files = files.Files.list('/a', filters=filters)
        self.assertSameObjects(['/a/foo'], titan_files)
        # Multiple filters:
        filters = [
            files.FileProperty('color') == 'blue',
            files.FileProperty('count') == 3,
        ]
        titan_files = files.Files.list('/', recursive=True, filters=filters)
        self.assertEqual(files.Files(['/a/baz']), titan_files)
        # Recursive:
        filters = [files.FileProperty('color') == 'red']
        titan_files = files.Files.list('/', recursive=True, filters=filters)
        self.assertEqual(files.Files(['/a/foo', '/a/bar/qux']), titan_files)
        # Non-meta property:
        user = users.TitanUser('*****@*****.**')
        filters = [
            files.FileProperty('created_by') == str(user),
            files.FileProperty('count') == 2,
        ]
        titan_files = files.Files.list('/a/', recursive=True, filters=filters)
        self.assertEqual(files.Files(['/a/bar/qux']), titan_files)

        # Error handling.
        self.assertRaises(ValueError, files.Files.list, '')
        self.assertRaises(ValueError, files.Files.list, '//')
        self.assertRaises(ValueError, files.Files.list, '/..')
        self.assertRaises(ValueError,
                          files.Files.list,
                          '/',
                          recursive=True,
                          depth=0)
        self.assertRaises(ValueError,
                          files.Files.list,
                          '/',
                          recursive=False,
                          depth=1)
Exemple #9
0
    def testNamespaces(self):
        self.write_namespace_testdata()

        # Verify the state of the filesystem in the default namespace.
        self.assertEqual('foo', files.File('/foo').content)
        self.assertEqual('bar', files.File('/b/bar').content)
        self.assertFalse(files.File('/b/qux').exists)

        titan_files = files.Files.list('/', recursive=True)
        self.assertEqual({'/foo', '/b/bar'}, set(titan_files))

        titan_files = files.Files(paths=['/foo', '/b/bar', '/b/qux']).load()
        self.assertEqual({'/foo', '/b/bar'}, set(titan_files))

        # Verify the state of the filesystem in the 'aaa' namespace.
        self.assertEqual('aaa-foo',
                         files.File('/foo', namespace='aaa').content)
        self.assertEqual('aaa-bar',
                         files.File('/b/bar', namespace='aaa').content)
        self.assertFalse(files.File('/b/qux', namespace='aaa').exists)

        titan_files = files.Files.list('/', recursive=True, namespace='aaa')
        self.assertEqual({'/foo', '/b/bar'}, set(titan_files))
        self.assertEqual('aaa-foo', titan_files['/foo'].content)
        self.assertEqual('aaa-bar', titan_files['/b/bar'].content)

        titan_files = files.Files(paths=['/foo', '/b/bar', '/b/qux'],
                                  namespace='aaa').load()
        self.assertEqual({'/foo', '/b/bar'}, set(titan_files))
        self.assertEqual('aaa-foo', titan_files['/foo'].content)
        self.assertEqual('aaa-bar', titan_files['/b/bar'].content)

        # Verify the state of the filesystem in the 'bbb' namespace.
        self.assertEqual('bbb-qux',
                         files.File('/b/qux', namespace='bbb').content)
        self.assertFalse(files.File('/foo', namespace='bbb').exists)
        self.assertFalse(files.File('/b/bar', namespace='bbb').exists)

        titan_files = files.Files.list('/', recursive=True, namespace='bbb')
        self.assertEqual({'/b/qux'}, set(titan_files))
        self.assertEqual('bbb-qux', titan_files['/b/qux'].content)

        titan_files = files.Files(paths=['/foo', '/b/bar', '/b/qux'],
                                  namespace='bbb').load()
        self.assertEqual({'/b/qux'}, set(titan_files))
        self.assertEqual('bbb-qux', titan_files['/b/qux'].content)

        # Namespace is not affected by file existence.
        self.assertIsNone(files.File('/foo').namespace)
        self.assertIsNone(files.File('/fake').namespace)
        self.assertEqual('aaa', files.File('/foo', namespace='aaa').namespace)
        self.assertEqual('zzz', files.File('/fake', namespace='zzz').namespace)

        # Cannot mix namespaces in files.Files.
        titan_files = files.Files()
        with self.assertRaises(files.NamespaceMismatchError):
            other_files = files.Files(paths=['/foo'], namespace='aaa')
            titan_files.update(other_files)

        # Files are not the same if their namespace is different.
        self.assertNotEqual(files.File('/foo'),
                            files.File('/foo', namespace='aaa'))
        self.assertNotEqual(files.File('/foo', namespace='aaa'),
                            files.File('/foo', namespace='zzz'))

        # Error handling (more extensive namespace validate tests in utils_test.py).
        self.assertRaises(ValueError, files.File, '/a', namespace='/')
        self.assertRaises(ValueError, files.File, '/a', namespace=u'∆')