From 19af3567b0f970607ae939cb1dd9e57dea18f54a Mon Sep 17 00:00:00 2001 From: Luca Scheller Date: Thu, 26 Oct 2023 16:14:53 +0200 Subject: [PATCH] Finish unit tests for FileResolver --- src/FileResolver/testenv/testFileResolver.py | 392 +++++-------------- 1 file changed, 104 insertions(+), 288 deletions(-) diff --git a/src/FileResolver/testenv/testFileResolver.py b/src/FileResolver/testenv/testFileResolver.py index 3e8d93a..066ce27 100644 --- a/src/FileResolver/testenv/testFileResolver.py +++ b/src/FileResolver/testenv/testFileResolver.py @@ -17,308 +17,124 @@ def setUpClass(cls): # Verify that the underlying resolver is the FileResolver assert(isinstance(Ar.GetUnderlyingResolver(), FileResolver.Resolver)) - def _test_CreateIdentifier(self): - r = Ar.GetResolver() - - stage = Usd.Stage.CreateInMemory() - context_collection = stage.GetPathResolverContext() - context = context_collection.Get()[0] - - raise Exception(context.GetSearchPaths()) - - ctx.GetMappingRegexExpression() # Get the regex expression - ctx.SetMappingRegexExpression(regex_str) # Set the regex expression - ctx.GetMappingRegexFormat() # Get the regex expression substitution formatting - ctx.SetMappingRegexFormat() # Set the regex expression substitution formatting - - # To print a full list of exposed methods: - for attr in dir(FileResolver.ResolverContext): - print(attr) - - - ctx.GetSearchPaths() - ctx.RefreshSearchPaths() - ctx.GetEnvSearchPaths() - ctx.GetCustomSearchPaths() - ctx.SetCustomSearchPaths(searchPaths) - - def _RP(path = None): - return Ar.ResolvedPath(os.path.abspath(path or "")) - - self.assertEqual('', r.CreateIdentifier('')) - self.assertEqual('', r.CreateIdentifier('', _RP())) - self.assertEqual('', r.CreateIdentifier('', _RP('AnchorAsset.txt'))) - - # The identifier for an absolute path will always be that absolute - # path normalized. - self.assertPathsEqual( - '/dir/AbsolutePath.txt', - r.CreateIdentifier('/dir/AbsolutePath.txt')) - - self.assertPathsEqual( - '/dir/AbsolutePath.txt', - r.CreateIdentifier('/dir/AbsolutePath.txt', _RP('subdir/A.txt'))) - - self.assertPathsEqual( - '/dir/AbsolutePath.txt', - r.CreateIdentifier('/dir/.//AbsolutePath.txt', _RP('subdir/A.txt'))) - - # The identifier for a file-relative path (i.e. a relative path - # starting with "./" or "../" is obtained by anchoring that path - # to the given anchor, or the normalized file-relative path if no - # anchor is given. - self.assertPathsEqual( - 'subdir/FileRelative.txt', - r.CreateIdentifier('./subdir/FileRelative.txt')) - - self.assertPathsEqual( - os.path.abspath('dir/subdir/FileRelative.txt'), - r.CreateIdentifier('./subdir/FileRelative.txt', _RP('dir/A.txt'))) - - # Test look-here-first behavior for search-relative paths (i.e., - # relative paths that do not start with "./" or "../") - # - # If an asset exists at the location obtained by anchoring the - # relative path to the given anchor, the anchored path is used as - # the identifier. - if not os.path.isdir('dir/subdir'): - os.makedirs('dir/subdir') - with open('dir/subdir/Exists.txt', 'w') as f: - pass - - self.assertPathsEqual( - os.path.abspath('dir/subdir/Exists.txt'), - r.CreateIdentifier('subdir/Exists.txt', _RP('dir/Anchor.txt'))) - - # Otherwise, the search path is used as the identifier. - self.assertPathsEqual( - 'subdir/Bogus.txt', - r.CreateIdentifier('subdir/Bogus.txt', _RP('dir/Anchor.txt'))) - - def _test_CreateIdentifierForNewAsset(self): - r = Ar.GetResolver() - - def _RP(path = None): - return Ar.ResolvedPath(os.path.abspath(path or "")) - - self.assertEqual( - '', r.CreateIdentifierForNewAsset('')) - self.assertEqual( - '', r.CreateIdentifierForNewAsset('', _RP())) - self.assertEqual( - '', r.CreateIdentifierForNewAsset('', _RP('AnchorAsset.txt'))) - - # The identifier for an absolute path will always be that absolute - # path normalized. - self.assertPathsEqual( - '/dir/AbsolutePath.txt', - r.CreateIdentifierForNewAsset('/dir/AbsolutePath.txt')) - - self.assertPathsEqual( - '/dir/AbsolutePath.txt', - r.CreateIdentifierForNewAsset( - '/dir/AbsolutePath.txt', _RP('subdir/A.txt'))) - - self.assertPathsEqual( - '/dir/AbsolutePath.txt', - r.CreateIdentifierForNewAsset( - '/dir/.//AbsolutePath.txt', _RP('subdir/A.txt'))) - - # The identifier for a relative path (file-relative or search-relative) - # will always be the anchored abolute path. - self.assertPathsEqual( - os.path.abspath('subdir/FileRelative.txt'), - r.CreateIdentifierForNewAsset( - './subdir/FileRelative.txt')) - - self.assertPathsEqual( - os.path.abspath('dir/subdir/FileRelative.txt'), - r.CreateIdentifierForNewAsset( - './subdir/FileRelative.txt', _RP('dir/Anchor.txt'))) - - self.assertPathsEqual( - os.path.abspath('subdir/SearchRel.txt'), - r.CreateIdentifierForNewAsset( - 'subdir/SearchRel.txt')) - - self.assertPathsEqual( - os.path.abspath('dir/subdir/SearchRel.txt'), - r.CreateIdentifierForNewAsset( - 'subdir/SearchRel.txt', _RP('dir/Anchor.txt'))) - - def _test_Resolve(self): - testFileName = 'test_Resolve.txt' - testFilePath = os.path.abspath(testFileName) - with open(testFilePath, 'w') as ofp: - print('Garbage', file=ofp) - - # XXX: Explicit conversion to str to accommodate change in - # return type to Ar.ResolvedPath in Ar 2.0. - resolvedPath = str(Ar.GetResolver().Resolve(testFileName)) - - # The resolved path should be absolute. - self.assertTrue(os.path.isabs(resolvedPath)) - self.assertPathsEqual(testFilePath, resolvedPath) - - def _test_ResolveSearchPaths(self): - testDir = os.path.abspath('test1/test2') - if os.path.isdir(testDir): - shutil.rmtree(testDir) - os.makedirs(testDir) - - testFileName = 'test_ResolveWithContext.txt' - testFilePath = os.path.join(testDir, testFileName) - with open(testFilePath, 'w') as ofp: - print('Garbage', file=ofp) - - resolver = Ar.GetResolver() - - self.assertPathsEqual( - os.path.abspath('test1/test2/test_ResolveWithContext.txt'), - resolver.Resolve('test2/test_ResolveWithContext.txt')) + def test_CreateIdentifier(self): + resolver = Ar.GetResolver() - self.assertPathsEqual( - os.path.abspath('test1/test2/test_ResolveWithContext.txt'), - resolver.Resolve('test_ResolveWithContext.txt')) + # Test for invalid paths + self.assertEqual("", resolver.CreateIdentifier("")) + self.assertEqual("", resolver.CreateIdentifier("", Ar.ResolvedPath("some/relative/path.usd"))) + self.assertEqual("", resolver.CreateIdentifier("", Ar.ResolvedPath("/some/absolute/path.usd"))) - def _test_ResolveWithCache(self): - testDir = os.path.abspath('testResolveWithCache/sub') - if os.path.isdir(testDir): - shutil.rmtree(testDir) - os.makedirs(testDir) + # Test for valid paths + self.assertEqual("/some/absolute/path.usd", resolver.CreateIdentifier("/some/absolute/path.usd", Ar.ResolvedPath("some/relative/path.usd"))) + self.assertEqual("/some/absolute/path.usd", resolver.CreateIdentifier("/some/absolute/path.usd", Ar.ResolvedPath("/some/absolute/path.usd"))) - with open('testResolveWithCache/test.txt', 'w') as ofp: - print('Test 1', file=ofp) + self.assertEqual("/some/absolute/some/relative/path.usd", resolver.CreateIdentifier("./some/relative/path.usd", Ar.ResolvedPath("/some/absolute/"))) + self.assertEqual("/some/absolute/some/relative/path.usd", resolver.CreateIdentifier("./some/relative/path.usd", Ar.ResolvedPath("/some/absolute/path.usd"))) + self.assertEqual("/some/some/relative/path.usd", resolver.CreateIdentifier("../some/relative/path.usd", Ar.ResolvedPath("/some/absolute/"))) + self.assertEqual("/some/some/relative/path.usd", resolver.CreateIdentifier("../some/relative/path.usd", Ar.ResolvedPath("/some/absolute/path.usd"))) - with open('testResolveWithCache/sub/test.txt', 'w') as ofp: - print('Test 2', file=ofp) - - resolver = Ar.GetResolver() + self.assertEqual("/other/relative/path.usd", resolver.CreateIdentifier("/some/../other/relative/path.usd", Ar.ResolvedPath("/some/absolute/path.usd"))) - # Set up a context that will search in the test root directory - # first, then the subdirectory. - context = Ar.DefaultResolverContext([ - os.path.abspath('testResolveWithCache'), - os.path.abspath('testResolveWithCache/sub')]) + def test_CreateIdentifierForNewAsset(self): + resolver = Ar.GetResolver() - with Ar.ResolverContextBinder(context): - with Ar.ResolverScopedCache(): - # Resolve should initially find the file in the test root - # directory. - self.assertPathsEqual( - os.path.abspath('testResolveWithCache/test.txt'), - resolver.Resolve('test.txt')) + # Test for invalid paths + self.assertEqual("", resolver.CreateIdentifierForNewAsset("")) + self.assertEqual("", resolver.CreateIdentifierForNewAsset("", Ar.ResolvedPath("some/relative/path.usd"))) + self.assertEqual("", resolver.CreateIdentifierForNewAsset("", Ar.ResolvedPath("/some/absolute/path.usd"))) - os.remove('testResolveWithCache/test.txt') + # Test for valid paths + self.assertEqual("/some/absolute/path.usd", resolver.CreateIdentifierForNewAsset("/some/absolute/path.usd", Ar.ResolvedPath("some/relative/path.usd"))) + self.assertEqual("/some/absolute/path.usd", resolver.CreateIdentifierForNewAsset("/some/absolute/path.usd", Ar.ResolvedPath("/some/absolute/path.usd"))) - # After removing the file from the test root directory, - # Calling Resolve again will still return the same result - # as before since a scoped cache is active. - self.assertPathsEqual( - os.path.abspath('testResolveWithCache/test.txt'), - resolver.Resolve('test.txt')) + self.assertEqual("/some/absolute/some/relative/path.usd", resolver.CreateIdentifierForNewAsset("./some/relative/path.usd", Ar.ResolvedPath("/some/absolute/"))) + self.assertEqual("/some/absolute/some/relative/path.usd", resolver.CreateIdentifierForNewAsset("./some/relative/path.usd", Ar.ResolvedPath("/some/absolute/path.usd"))) + self.assertEqual("/some/some/relative/path.usd", resolver.CreateIdentifierForNewAsset("../some/relative/path.usd", Ar.ResolvedPath("/some/absolute/"))) + self.assertEqual("/some/some/relative/path.usd", resolver.CreateIdentifierForNewAsset("../some/relative/path.usd", Ar.ResolvedPath("/some/absolute/path.usd"))) - # Once the caching scope is closed, Resolve should now return - # the file from the subdirectory. - self.assertPathsEqual( - os.path.abspath('testResolveWithCache/sub/test.txt'), - resolver.Resolve('test.txt')) + self.assertEqual("/other/relative/path.usd", resolver.CreateIdentifierForNewAsset("/some/../other/relative/path.usd", Ar.ResolvedPath("/some/absolute/path.usd"))) - def _test_ResolveWithContext(self): - testDir = os.path.abspath('test3/test4') - if os.path.isdir(testDir): - shutil.rmtree(testDir) - os.makedirs(testDir) - - testFileName = 'test_ResolveWithContext.txt' - testFilePath = os.path.join(testDir, testFileName) - with open(testFilePath, 'w') as ofp: - print('Garbage', file=ofp) - + def test_Resolve(self): + with tempfile.TemporaryDirectory() as temp_dir_path: + # Create context + ctx = FileResolver.ResolverContext() + ctx.SetCustomSearchPaths([temp_dir_path]) + ctx.RefreshSearchPaths() + # Create files + layer_identifier = "layer.usd" + layer_file_path = os.path.join(temp_dir_path, layer_identifier) + Sdf.Layer.CreateAnonymous().Export(layer_file_path) + # Get resolver + resolver = Ar.GetResolver() + with Ar.ResolverContextBinder(ctx): + resolved_path = resolver.Resolve(layer_identifier) + self.assertEqual(resolved_path.GetPathString(), layer_file_path) + self.assertTrue(os.path.isabs(resolved_path.GetPathString())) + resolved_path = resolver.Resolve("example.usd") + self.assertEqual(resolved_path.GetPathString(), "") + resolved_path = resolver.Resolve("/some/invalid/path.usd") + self.assertEqual(resolved_path.GetPathString(), "") + resolved_path = resolver.Resolve(layer_file_path) + self.assertEqual(resolved_path.GetPathString(), layer_file_path) + + def test_ResolveForNewAsset(self): resolver = Ar.GetResolver() - context = Ar.DefaultResolverContext([ - os.path.abspath('test3'), - os.path.abspath('test3/test4') - ]) - - self.assertPathsEqual( - '', - resolver.Resolve('test4/test_ResolveWithContext.txt')) - - with Ar.ResolverContextBinder(context): - self.assertPathsEqual( - os.path.abspath('test3/test4/test_ResolveWithContext.txt'), - resolver.Resolve('test4/test_ResolveWithContext.txt')) - self.assertPathsEqual( - os.path.abspath('test3/test4/test_ResolveWithContext.txt'), - resolver.Resolve('test_ResolveWithContext.txt')) - self.assertPathsEqual( - '', - resolver.Resolve('test4/test_ResolveWithContext.txt')) + layer_identifier = "layer.usd" + layer_file_path = os.path.join(os.getcwd(), layer_identifier) + resolved_path = resolver.ResolveForNewAsset(layer_identifier) + self.assertEqual(resolved_path.GetPathString(), layer_file_path) - def _test_ResolveWithDefaultAssetContext(self): - assetFileName = 'test_Asset.txt' - assetFilePath = os.path.abspath(assetFileName) - with open(assetFilePath, 'w') as ofp: - print('Garbage', file=ofp) + layer_identifier = "../layer.usd" + layer_file_path = os.path.abspath(os.path.join(os.getcwd(), layer_identifier)) + resolved_path = resolver.ResolveForNewAsset(layer_identifier) + self.assertEqual(resolved_path.GetPathString(), layer_file_path) - testFileName = 'test_SiblingOfAsset.txt' - testFilePath = os.path.abspath(testFileName) - with open(testFilePath, 'w') as ofp: - print('Garbage', file=ofp) - - # We use the non-absolute assetFileName to test the - # cwd-anchoring behavior of CreateDefaultContextForAsset() - context = Ar.GetResolver().CreateDefaultContextForAsset(assetFileName) - with Ar.ResolverContextBinder(context): - resolvedPath = Ar.GetResolver().Resolve(testFileName) - - self.assertPathsEqual(resolvedPath, testFilePath) - - # Make sure we get the same behavior using ConfigureResolverForAsset() - if hasattr(Ar.Resolver, "ConfigureResolverForAsset"): - Ar.GetResolver().ConfigureResolverForAsset(assetFileName) - with Ar.ResolverContextBinder(Ar.GetResolver().CreateDefaultContext()): - defaultResolvedPath = Ar.GetResolver().Resolve(testFileName) - - self.assertPathsEqual(defaultResolvedPath, testFilePath) - - def _test_ResolveForNewAsset(self): - resolver = Ar.GetResolver() - - # ResolveForNewAsset returns the path a new asset would be written - # to for a given asset path. ArDefaultResolver assumes all asset paths - # are filesystem paths, so this is just the absolute path of the - # input. - self.assertPathsEqual( - resolver.ResolveForNewAsset('/test/path/1/newfile'), - os.path.abspath('/test/path/1/newfile')) - - self.assertPathsEqual( - resolver.ResolveForNewAsset('test/path/1/newfile'), - os.path.abspath('test/path/1/newfile')) - - # This should work even if a file happens to already exist at the - # computed path. - testDir = os.path.abspath('ResolveForNewAsset') - if os.path.isdir(testDir): - shutil.rmtree(testDir) - os.makedirs(testDir) - - testFileName = 'test_ResolveForNewAsset.txt' - testFileAbsPath = os.path.join(testDir, testFileName) - with open(testFileAbsPath, 'w') as ofp: - print('Garbage', file=ofp) - - self.assertPathsEqual( - resolver.ResolveForNewAsset(testFileAbsPath), - testFileAbsPath) - - self.assertPathsEqual( - resolver.ResolveForNewAsset( - 'ResolveForNewAsset/test_ResolveForNewAsset.txt'), - testFileAbsPath) + def test_ResolveWithCache(self): + with tempfile.TemporaryDirectory() as temp_dir_path: + # Create context + ctx = FileResolver.ResolverContext() + ctx.SetCustomSearchPaths([temp_dir_path]) + ctx.RefreshSearchPaths() + # Create files + layer_identifier = "layer.usd" + layer_file_path = os.path.join(temp_dir_path, layer_identifier) + Sdf.Layer.CreateAnonymous().Export(layer_file_path) + # Get resolver + resolver = Ar.GetResolver() + with Ar.ResolverContextBinder(ctx): + with Ar.ResolverScopedCache(): + # Resolve + self.assertEqual(os.path.abspath(layer_file_path), resolver.Resolve(layer_identifier)) + # Remove file + os.remove(layer_file_path) + # Query cached result + self.assertEqual(os.path.abspath(layer_file_path), resolver.Resolve(layer_identifier)) + # Uncached result should now return empty result + self.assertEqual("", resolver.Resolve(layer_identifier)) + + def test_ResolveWithContext(self): + with tempfile.TemporaryDirectory() as temp_dir_path: + # Create context + ctx = FileResolver.ResolverContext() + ctx.SetCustomSearchPaths([temp_dir_path]) + ctx.RefreshSearchPaths() + ctx.SetMappingRegexExpression("(v\d\d\d)") + ctx.SetMappingRegexFormat("v000") + ctx.AddMappingPair("layer_v000.usd", "layer_v002.usd") + # Create files + layer_v001_identifier = "layer_v001.usd" + layer_v001_file_path = os.path.join(temp_dir_path, layer_v001_identifier) + Sdf.Layer.CreateAnonymous().Export(layer_v001_file_path) + layer_v002_identifier = "layer_v002.usd" + layer_v002_file_path = os.path.join(temp_dir_path, layer_v002_identifier) + Sdf.Layer.CreateAnonymous().Export(layer_v002_file_path) + # Get resolver + resolver = Ar.GetResolver() + with Ar.ResolverContextBinder(ctx): + resolved_path = resolver.Resolve(layer_v001_identifier) + self.assertEqual(resolved_path.GetPathString(), layer_v002_file_path) def test_ResolverContextSearchPaths(self): ctx = FileResolver.ResolverContext()