def _TestWithPaths(searchPaths): self.assertEqual( resolver.CreateContextFromString(os.pathsep.join(searchPaths)), Ar.ResolverContext(Ar.DefaultResolverContext(searchPaths))) self.assertEqual( resolver.CreateContextFromStrings( [("", os.pathsep.join(searchPaths))]), Ar.ResolverContext(Ar.DefaultResolverContext(searchPaths)))
def test_FindOrOpenDefaultResolverSearchPaths(self): # Set up test directory structure by exporting layers. We # don't use Sdf.Layer.CreateNew here to avoid populating the # layer registry. layerA_Orig = Sdf.Layer.CreateAnonymous() Sdf.CreatePrimInLayer(layerA_Orig, "/LayerA") layerA_Orig.Export("dir1/sub/searchPath.sdf") layerB_Orig = Sdf.Layer.CreateAnonymous() Sdf.CreatePrimInLayer(layerB_Orig, "/LayerB") layerB_Orig.Export("dir2/sub/searchPath.sdf") # This should fail since there is no searchPath.sdf layer in the # current directory and no context is bound. self.assertFalse(Sdf.Layer.FindOrOpen("sub/searchPath.sdf")) # Bind an Ar.DefaultResolverContext with dir1 as a search path. # Now sub/searchPath.sdf should be discovered in dir1/. ctx1 = Ar.DefaultResolverContext([os.path.abspath("dir1/")]) with Ar.ResolverContextBinder(ctx1): layerA = Sdf.Layer.FindOrOpen("sub/searchPath.sdf") self.assertTrue(layerA) self.assertTrue(layerA.GetPrimAtPath("/LayerA")) self.assertEqual(layerA.identifier, "sub/searchPath.sdf") # Do the same as above, but with dir2 as the search path. # Now sub/searchPath.sdf should be discovered in dir2/. ctx2 = Ar.DefaultResolverContext([os.path.abspath("dir2/")]) with Ar.ResolverContextBinder(ctx2): layerB = Sdf.Layer.FindOrOpen("sub/searchPath.sdf") self.assertTrue(layerB) self.assertTrue(layerB.GetPrimAtPath("/LayerB")) self.assertEqual(layerB.identifier, "sub/searchPath.sdf") # Note that layerB has the same identifier as layerA, but # different resolved paths. self.assertEqual(layerA.identifier, layerB.identifier) self.assertNotEqual(layerA.realPath, layerB.realPath) # Sdf.Layer.Find should fail since no context is bound. self.assertFalse(Sdf.Layer.Find("sub/searchPath.sdf")) # Binding the contexts from above will allow Sdf.Layer.Find # to find the right layers. with Ar.ResolverContextBinder(ctx1): self.assertEqual(Sdf.Layer.Find("sub/searchPath.sdf"), layerA) with Ar.ResolverContextBinder(ctx2): self.assertEqual(Sdf.Layer.Find("sub/searchPath.sdf"), layerB) # Anonymous layers should be discoverable regardless of context. anonLayerA = Sdf.Layer.CreateAnonymous() with Ar.ResolverContextBinder(ctx1): self.assertEqual(Sdf.Layer.Find(anonLayerA.identifier), anonLayerA) with Ar.ResolverContextBinder(ctx2): anonLayerB = Sdf.Layer.CreateAnonymous() self.assertEqual(Sdf.Layer.Find(anonLayerB.identifier), anonLayerB)
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 >> ofp, 'Garbage' 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'))
def test_ResolverContext(self): emptyContext = Ar.DefaultResolverContext() self.assertEqual(emptyContext.GetSearchPath(), []) self.assertEqual(emptyContext, Ar.DefaultResolverContext()) self.assertEqual(eval(repr(emptyContext)), emptyContext) context = Ar.DefaultResolverContext(["/test/path/1", "/test/path/2"]) self.assertEqual(context.GetSearchPath(), [os.path.abspath("/test/path/1"), os.path.abspath("/test/path/2")]) self.assertEqual(context, Ar.DefaultResolverContext(["/test/path/1", "/test/path/2"])) self.assertEqual(eval(repr(context)), context) self.assertNotEqual(emptyContext, context);
def test_ExplicitConstruction(self): # Passing in None or an empty tuple or list to Ar.ResolverContext # should all result in creating an empty Ar.ResolverContext. self.assertEqual(Ar.ResolverContext(None), Ar.ResolverContext()) self.assertEqual(Ar.ResolverContext(()), Ar.ResolverContext()) self.assertEqual(Ar.ResolverContext([]), Ar.ResolverContext()) # Passing in a Python-wrapped context object or tuple or list # containing such objects should create an Ar.ResolverContext holding # these objects. ctxObj = Ar.DefaultResolverContext(["/test"]) ctx = Ar.ResolverContext(ctxObj) self.assertEqual(Ar.ResolverContext(ctxObj), ctx) self.assertEqual(Ar.ResolverContext((ctxObj, )), ctx) self.assertEqual(Ar.ResolverContext([ ctxObj, ]), ctx) # Passing in an object that hasn't been registered as a context object # should result in an error. with self.assertRaises(TypeError): ctx = Ar.ResolverContext(1) with self.assertRaises(TypeError): ctx = Ar.ResolverContext((1, )) with self.assertRaises(TypeError): ctx = Ar.ResolverContext([ 1, ]) with self.assertRaises(TypeError): ctx = Ar.ResolverContext((1, ctxObj)) with self.assertRaises(TypeError): ctx = Ar.ResolverContext([1, ctxObj])
def test_Repr(self): ctxObj = Ar.DefaultResolverContext(["/test"]) ctx = Ar.ResolverContext(ctxObj) expectedRepr = "Ar.ResolverContext({})".format(repr(ctxObj)) self.assertEqual(str(ctx), expectedRepr) self.assertEqual(repr(ctx), expectedRepr)
def test_ResolveWithCache(self): testDir = os.path.abspath('testResolveWithCache/sub') if os.path.isdir(testDir): shutil.rmtree(testDir) os.makedirs(testDir) with open('testResolveWithCache/test.txt', 'w') as ofp: print('Test 1', file=ofp) with open('testResolveWithCache/sub/test.txt', 'w') as ofp: print('Test 2', file=ofp) resolver = Ar.GetResolver() # 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')]) 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')) os.remove('testResolveWithCache/test.txt') # 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')) # 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'))
def test_ImplicitConversion(self): """Test implicit conversion of a Python-wrapped context object when passed to a C++ function that takes an ArResolverContext.""" # Passing in None or an empty tuple or list should implicitly # convert to an empty Ar.ResolverContext() self.assertEqual(Ar._TestImplicitConversion(None), Ar.ResolverContext()) self.assertEqual(Ar._TestImplicitConversion(()), Ar.ResolverContext()) self.assertEqual(Ar._TestImplicitConversion([]), Ar.ResolverContext()) # Passing in a Python-wrapped context object or tuple or list # containing such objects should implicitly convert to an # Ar.ResolverContext holding these objects. ctxObj = Ar.DefaultResolverContext(["/test"]) ctx = Ar.ResolverContext(ctxObj) self.assertEqual(Ar._TestImplicitConversion(ctxObj), ctx) self.assertEqual(Ar._TestImplicitConversion((ctxObj, )), ctx) self.assertEqual(Ar._TestImplicitConversion([ ctxObj, ]), ctx) # Passing in an object that hasn't been registered as a context object # should result in an error. with self.assertRaises(TypeError): ctx = Ar._TestImplicitConversion(1) with self.assertRaises(TypeError): ctx = Ar._TestImplicitConversion((1, )) with self.assertRaises(TypeError): ctx = Ar._TestImplicitConversion([ 1, ]) with self.assertRaises(TypeError): ctx = Ar._TestImplicitConversion((1, ctxObj)) with self.assertRaises(TypeError): ctx = Ar._TestImplicitConversion([1, ctxObj])
def test_Get(self): ctxObj = Ar.DefaultResolverContext(["/test"]) ctx = Ar.ResolverContext(ctxObj) self.assertEqual(ctx.Get(), [ctxObj])
def test_ReferencingLayerWithAbsoluteSublayerPaths(self): '''Tests behavior when the resolved path of a layer changes and that layer contains references to other layers and absolute sublayer paths.''' # Create test directory structure and assets. CreateLayer( 'absRef.sdf', '''\ #sdf 1.4.32 def "Ref" { } ''') CreateLayer('absSublayer.sdf', '''\ #sdf 1.4.32 ''') CreateLayer( 'v1/root.sdf', '''\ #sdf 1.4.32 ( subLayers = [ @{sublayerPath}@ ] ) def "AbsoluteReference" ( references = @{absRefPath}@</Ref> ) {{ }} def "RelativeReference" ( references = @./ref.sdf@</Ref> ) {{ }} '''.format(sublayerPath=os.path.abspath('absSublayer.sdf'), absRefPath=os.path.abspath('absRef.sdf'))) CreateLayer( 'v1/ref.sdf', '''\ #sdf 1.4.32 def "Ref" { } ''') # Create PcpCache using a resolver context that searches # v2/ first, then v1/. Note that we use a search path for root.sdf. # Since v2/root.sdf doesn't exist yet, we should find v1/root.sdf # as our root layer. pcpCache = CreatePcpCache( "root.sdf", Ar.DefaultResolverContext( searchPaths=[os.path.abspath('v2'), os.path.abspath('v1')])) # All relative asset paths in references/sublayers/etc. should be # anchored to v1/root.sdf initially. pi, err = pcpCache.ComputePrimIndex('/AbsoluteReference') self.assertFalse(err) self.assertReferenceNode(pi.rootNode.children[0], ['absRef.sdf']) pi, err = pcpCache.ComputePrimIndex('/RelativeReference') self.assertFalse(err) self.assertReferenceNode(pi.rootNode.children[0], ['v1/ref.sdf']) self.assertEqual( pcpCache.layerStack.layers, [Sdf.Layer.Find('v1/root.sdf'), Sdf.Layer.Find('absSublayer.sdf')]) # Copy v1/ to v2/ and reload. This should cause the resolved path of # root.sdf to change to v2/root.sdf. Any prims with references that were # relative to root.sdf need to be resynced since those references now # target a different layer. shutil.copytree('v1', 'v2') with Pcp._TestChangeProcessor(pcpCache) as changes: pcpCache.Reload() self.assertEqual(changes.GetSignificantChanges(), ['/RelativeReference']) self.assertTrue(pcpCache.FindPrimIndex('/AbsoluteReference')) self.assertFalse(pcpCache.FindPrimIndex('/RelativeReference')) pi, err = pcpCache.ComputePrimIndex('/RelativeReference') self.assertFalse(err) self.assertReferenceNode(pi.rootNode.children[0], ['v2/ref.sdf']) self.assertLayerStack(pcpCache.layerStack, ['v2/root.sdf', 'absSublayer.sdf'])
def test_ReferencedWithAbsoluteSublayerPaths(self): '''Tests behavior when the resolved path of a referenced layer changes and that layer contains absolute sublayer paths.''' # Create test directory structure and assets. CreateLayer( 'root.sdf', '''\ #sdf 1.4.32 def "SearchPathRef" ( references = @ref.sdf@</Ref> ) { } def "InnocentBystander" { } ''') CreateLayer( 'absSublayer.sdf', '''\ #sdf 1.4.32 def "Ref" {} ''') CreateLayer( 'v1/ref.sdf', '''\ #sdf 1.4.32 ( subLayers = [ @{absSublayerPath}@ ] ) '''.format(absSublayerPath=os.path.abspath('absSublayer.sdf'))) # Create PcpCache using a resolver context that searches # v2/ first, then v1/. The search path reference to ref.sdf should # resolve to v1/ref.sdf since v2/ doesn't exist yet. pcpCache = CreatePcpCache( "root.sdf", Ar.DefaultResolverContext( searchPaths=[os.path.abspath('v2'), os.path.abspath('v1')])) pi, err = pcpCache.ComputePrimIndex('/InnocentBystander') self.assertFalse(err) pi, err = pcpCache.ComputePrimIndex('/SearchPathRef') self.assertFalse(err) self.assertReferenceNode(pi.rootNode.children[0], ['v1/ref.sdf', 'absSublayer.sdf']) # Copy v1/ to v2/ and reload. This should cause the resolved path of # ref.sdf to change to v2/ref.sdf, but no other scene description is # changed because v1/ and v2/ are exactly the same. # # Even though the root layer of the referenced layer stack has changed # resolved paths, there's no actual change to the layer stack itself # because the sublayer asset path was an absolute path -- it contains # exactly the same layers that it did prior to the reload. So no prims # actually needs to be resynced in this case. shutil.copytree('v1', 'v2') with Pcp._TestChangeProcessor(pcpCache) as changes: pcpCache.Reload() self.assertEqual(changes.GetSignificantChanges(), [])
def test_ReferencedWithRelativeSublayerPaths(self): '''Tests behavior when the resolved path of a referenced layer changes and that layer contains relative sublayer paths.''' # Create test directory structure and assets. CreateLayer( 'root.sdf', '''\ #sdf 1.4.32 def "SearchPathRef" ( references = @ref.sdf@</Ref> ) { } def "InnocentBystander" { } ''') CreateLayer( 'v1/ref.sdf', '''\ #sdf 1.4.32 ( subLayers = [ @./sublayer.sdf@ ] ) ''') CreateLayer( 'v1/sublayer.sdf', '''\ #sdf 1.4.32 def "Ref" { } ''') # Create PcpCache using a resolver context that searches # v2/ first, then v1/. The search path reference to ref.sdf should # resolve to v1/ref.sdf since v2/ doesn't exist yet. pcpCache = CreatePcpCache( "root.sdf", Ar.DefaultResolverContext( searchPaths=[os.path.abspath('v2'), os.path.abspath('v1')])) pi, err = pcpCache.ComputePrimIndex('/InnocentBystander') self.assertFalse(err) pi, err = pcpCache.ComputePrimIndex('/SearchPathRef') self.assertFalse(err) self.assertReferenceNode(pi.rootNode.children[0], ['v1/ref.sdf', 'v1/sublayer.sdf']) # Copy v1/ to v2/ and reload. This should cause the resolved path of # ref.sdf to change to v2/ref.sdf, but no other scene description # is changed because v1/ and v2/ are exactly the same. # # Because we had a sublayer with a relative path, we need to recompute # the layer stack since its anchor has changed. This means that any prim # index that uses that layer stack must be resynced. shutil.copytree('v1', 'v2') with Pcp._TestChangeProcessor(pcpCache) as changes: pcpCache.Reload() self.assertEqual(changes.GetSignificantChanges(), ['/SearchPathRef']) self.assertTrue(pcpCache.FindPrimIndex('/InnocentBystander')) self.assertFalse(pcpCache.FindPrimIndex('/SearchPathRef')) pi, err = pcpCache.ComputePrimIndex('/SearchPathRef') self.assertFalse(err) self.assertReferenceNode(pi.rootNode.children[0], ['v2/ref.sdf', 'v2/sublayer.sdf'])