def test_shot(self): """Tests paths used in making a shot are as expected.""" expected_paths = [] shot_path = os.path.join(self.project_root, "%s_%s" % (self.shot["code"], self.seq["code"])) expected_paths.extend( [self.project_root, shot_path] ) folder.process_filesystem_structure(self.tk, self.shot["type"], self.shot["id"], preview=False, engine=None) assert_paths_to_create(expected_paths) # now check the path cache! # there shouldbe two entries, one for the shot and one for the seq pc = path_cache.PathCache(self.pipeline_configuration) shot_paths = pc.get_paths("Shot", self.shot["id"], primary_only=False) seq_paths = pc.get_paths("Sequence", self.seq["id"], primary_only=False) self.assertEquals( len(shot_paths), 1 ) self.assertEquals( len(seq_paths), 1) pc.close() # it's the same folder for seq and shot self.assertEquals(shot_paths, seq_paths)
def test_list_field_token(self): """ Test that we can reference list field tokens in the symlink definition """ self.assertFalse(os.path.exists(self.bbb)) self.assertFalse(os.path.exists(self.bbb_work)) self.assertFalse(os.path.exists(self.bbb_link)) folder.process_filesystem_structure( self.tk, self.asset_bbb["type"], self.asset_bbb["id"], preview=False, engine=None ) self.assertTrue(os.path.exists(self.bbb)) self.assertTrue(os.path.exists(self.bbb_work)) if sys.platform != "win32": self.assertTrue(os.path.lexists(self.bbb_link)) self.assertTrue(os.path.islink(self.bbb_link)) self.assertEqual(os.readlink(self.bbb_link), "../Stuff/project_code/vehicle/bbb") else: # no support on windows self.assertFalse(os.path.exists(self.bbb_link))
def test_no_new_folders_created(self): """ Test the case when folder creation is running for an already existing path """ # we should have one Toolkit_Folders_Create record in the path cache, # coming from the project setup folder_events = self.tk.shotgun.find("EventLogEntry", [["event_type", "is", "Toolkit_Folders_Create"]]) self.assertEqual(len(folder_events), 1) folder.process_filesystem_structure(self.tk, self.seq["type"], self.seq["id"], preview=False, engine=None) # a seq should have been added to the path cache and we should have two events folder_events = self.tk.shotgun.find("EventLogEntry", [["event_type", "is", "Toolkit_Folders_Create"]]) self.assertEqual(len(folder_events), 2) # running this again, no folders should be created and no events should be generated folder.process_filesystem_structure(self.tk, self.seq["type"], self.seq["id"], preview=False, engine=None) folder_events = self.tk.shotgun.find("EventLogEntry", [["event_type", "is", "Toolkit_Folders_Create"]]) self.assertEqual(len(folder_events), 2)
def test_concurrent_full_sync(self): """ test multiple processes doing a full sync of the path cache at the same time """ # skip this test on windows or py2.5 where multiprocessing isn't available if sys.platform == "win32" or sys.version_info < (2,6): return import multiprocessing folder.process_filesystem_structure(self.tk, self.task["type"], self.task["id"], preview=False, engine=None) self.tk.synchronize_filesystem_structure(True) self._multiprocess_fail = False processes = [] for x in range(50): p = multiprocessing.Process(target=self.concurrent_full_sync) p.start() processes.append(p) all_processes_finished = False while not all_processes_finished: time.sleep(0.1) sys.stderr.write(".") all_processes_finished = all([not(p.is_alive()) for p in processes]) self.assertFalse(self._multiprocess_fail)
def test_made_string(self, get_current_user): self.assertFalse(os.path.exists(self.user_path)) get_current_user.return_value = self.humanuser folder.process_filesystem_structure(self.tk, self.shot["type"], self.shot["id"], preview=False, engine="tk-maya") self.assertTrue(os.path.exists(self.user_path)) get_current_user.return_value = self.humanuser2 folder.process_filesystem_structure(self.tk, self.shot["type"], self.shot["id"], preview=False, engine="tk-maya") self.assertTrue(os.path.exists(self.user_path2)) # test user context ctx_foo = self.tk.context_from_path(self.user_path) ctx_bar = self.tk.context_from_path(self.user_path2) self.assertEquals(ctx_foo.filesystem_locations, [self.user_path]) self.assertEquals(ctx_bar.filesystem_locations, [self.user_path2])
def test_context_from_path(self): """Testing task based context resolution from path.""" task_path = os.path.join( self.project_root, "sequences", self.seq["code"], self.shot["code"], self.task["content"] ) # before folders exist for the task, we expect # only the project to be extracted from the path ctx = self.tk.context_from_path(task_path) self.assertEqual(ctx.project, {'type': 'Project', 'id': 1, 'name': 'project_name'}) self.assertEqual(ctx.entity, None) self.assertEqual(ctx.step, None) self.assertEqual(ctx.task, None) # create folders folder.process_filesystem_structure(self.tk, self.task["type"], self.task ["id"], preview=False, engine=None) # now we should get a full context, including step ctx = self.tk.context_from_path(task_path) self.assertEqual(ctx.project, {'type': 'Project', 'id': 1, 'name': 'project_name'}) self.assertEqual(ctx.entity, {'type': 'Shot', 'id': 1, 'name': 'shot_code'}) self.assertEqual(ctx.step, {'type': 'Step', 'id': 3, 'name': 'step_code'}) self.assertEqual(ctx.task, {'type': 'Task', 'id': 23, 'name': 'task1'})
def test_asset(self): """Tests paths used in making a asset are as expected.""" # expected paths here are based on sg_standard start-config # define paths we expect for entities expected_paths = [] expected_paths.append(self.alt_root_1) expected_paths.append(os.path.join(self.alt_root_1, "assets")) expected_paths.append(os.path.join(self.alt_root_1, "alternate_reference")) asset_folder_name = "%s_%s" % (self.asset["sg_asset_type"], self.asset["code"]) asset_path = os.path.join(self.alt_root_1, "assets", asset_folder_name) step_path = os.path.join(asset_path, self.step["short_name"]) expected_paths.append(asset_path) expected_paths.append(step_path) # add non-entity paths expected_paths.append(os.path.join(step_path, "publish")) expected_paths.append(os.path.join(step_path, "images")) expected_paths.append(os.path.join(step_path, "review")) expected_paths.append(os.path.join(step_path, "work")) expected_paths.append(os.path.join(step_path, "work", "snapshots")) expected_paths.append(os.path.join(step_path, "out")) folder.process_filesystem_structure(self.tk, self.asset["type"], self.asset["id"], preview=False, engine=None) assert_paths_to_create(expected_paths)
def test_step_a(self, get_current_user): """Tests paths used in making a shot are as expected.""" get_current_user.return_value = self.humanuser folder.process_filesystem_structure(self.tk, self.task["type"], self.task ["id"], preview=False, engine="foo-bar") expected_paths = [] sequence_path = os.path.join(self.project_root, "sequences", self.seq["code"]) sequences_path = os.path.join(self.project_root, "sequences") shot_path = os.path.join(sequence_path, self.shot["code"]) sandbox_path = os.path.join(shot_path, self.humanuser["login"]) step_path = os.path.join(sandbox_path, self.step["short_name"]) expected_paths.extend( [self.project_root, sequences_path, sequence_path, shot_path, sandbox_path, step_path] ) # add non-entity paths expected_paths.append(os.path.join(step_path, "publish")) expected_paths.append(os.path.join(step_path, "images")) expected_paths.append(os.path.join(step_path, "review")) expected_paths.append(os.path.join(step_path, "work")) expected_paths.append(os.path.join(step_path, "work", "snapshots")) expected_paths.append(os.path.join(step_path, "work", "workspace.mel")) expected_paths.append(os.path.join(step_path, "out")) assert_paths_to_create(expected_paths)
def test_shot(self): """Tests paths used in making a shot are as expected.""" sequence_path = os.path.join(self.project_root, "sequences", self.seq["code"]) sequences_path = os.path.join(self.project_root, "sequences") shot_path = os.path.join(sequence_path, self.shot["code"]) ws_path = os.path.join(shot_path, self.workspace["code"]) expected_paths = [self.project_root, os.path.join(self.project_root, "assets"), ] expected_paths.extend( [sequences_path, sequence_path, shot_path, ws_path] ) folder.process_filesystem_structure(self.tk, self.workspace["type"], self.workspace["id"], preview=False, engine=None) assert_paths_to_create(expected_paths)
def test_step_b(self): """Tests paths used in making a shot are as expected.""" folder.process_filesystem_structure(self.tk, self.task2["type"], self.task2["id"], preview=False, engine=None) expected_paths = [] sequence_path = os.path.join(self.project_root, "sequences", self.seq["code"]) sequences_path = os.path.join(self.project_root, "sequences") shot_path = os.path.join(sequence_path, self.shot["code"]) step_path = os.path.join(shot_path, self.step2["short_name"]) expected_paths.extend( [self.project_root, sequences_path, sequence_path, shot_path, step_path] ) # add non-entity paths expected_paths.append(os.path.join(step_path, "publish")) expected_paths.append(os.path.join(step_path, "images")) expected_paths.append(os.path.join(step_path, "review")) expected_paths.append(os.path.join(step_path, "work")) expected_paths.append(os.path.join(step_path, "work", "snapshots")) expected_paths.append(os.path.join(step_path, "work", "workspace.mel")) expected_paths.append(os.path.join(step_path, "out")) assert_paths_to_create(expected_paths)
def test_create_symlink(self): """ Test folder creation for a shot which matches the static folder trigger condition """ self.assertFalse(os.path.exists(self.aaa)) self.assertFalse(os.path.exists(self.aaa_work)) self.assertFalse(os.path.exists(self.aaa_link)) folder.process_filesystem_structure( self.tk, self.shot_aaa["type"], self.shot_aaa["id"], preview=False, engine=None ) self.assertTrue(os.path.exists(self.aaa)) self.assertTrue(os.path.exists(self.aaa_work)) if sys.platform != "win32": self.assertTrue(os.path.lexists(self.aaa_link)) self.assertTrue(os.path.islink(self.aaa_link)) self.assertEqual(os.readlink(self.aaa_link), "../Stuff/project_code/aaa") else: # no support on windows self.assertFalse(os.path.exists(self.aaa_link))
def test_create_sequence(self): expected = os.path.join(self.project_root, "sequences", self.seq["code"]) self.assertFalse(os.path.exists(expected)) folder.process_filesystem_structure(self.tk, self.seq["type"], self.seq["id"], preview=False, engine=None) self.assertTrue(os.path.exists(expected))
def test_step_b(self): """Tests paths used in making a shot are as expected.""" folder.process_filesystem_structure(self.tk, self.task2["type"], self.task2["id"], preview=False, engine=None) assert_paths_to_create(self.make_path_list())
def test_not_made_default(self, get_current_user): self.assertFalse(os.path.exists(self.user_path)) get_current_user.return_value = self.humanuser folder.process_filesystem_structure(self.tk, self.shot["type"], self.shot["id"], preview=False, engine=None) self.assertFalse(os.path.exists(self.user_path))
def test_shot(self): """Tests paths used in making a shot are as expected.""" expected_paths = self._construct_shot_paths() folder.process_filesystem_structure(self.tk, self.shot["type"], self.shot["id"], preview=False, engine=None) assert_paths_to_create(expected_paths)
def test_create_task(self): # Task should create folders for it's entity expected = os.path.join(self.project_root, "sequences", self.seq["code"], self.shot["code"]) self.assertFalse(os.path.exists(expected)) folder.process_filesystem_structure(self.tk, self.task["type"], self.task["id"], preview=False, engine=None) self.assertTrue(os.path.exists(expected))
def test_create_project(self): # Check static folders without entity children are created expected = os.path.join(self.project_root, "reference", "artwork") self.assertFalse(os.path.exists(expected)) folder.process_filesystem_structure(self.tk, self.project["type"], self.project["id"], preview=False, engine=None) self.assertTrue(os.path.exists(expected))
def test_project(self): """Tests paths used in making a project are as expected.""" # paths based on sg_standard starter config expected_paths = [] expected_paths.append(self.project_root) expected_paths.append(os.path.join(self.project_root, "sequences")) expected_paths.append(os.path.join(self.project_root, "scenes")) expected_paths.append(os.path.join(self.project_root, "assets")) expected_paths.append(os.path.join(self.project_root, "reference")) expected_paths.append( os.path.join(self.project_root, "reference", "artwork")) expected_paths.append( os.path.join(self.project_root, "reference", "footage")) folder.process_filesystem_structure(self.tk, self.project["type"], self.project["id"], preview=False, engine=None) assert_paths_to_create(expected_paths)
def test_shot(self, get_current_user): """Tests paths used in making a shot are as expected.""" get_current_user.return_value = self.humanuser expected_paths = [] sequence_path = os.path.join(self.project_root, "sequences", self.seq["code"]) sequences_path = os.path.join(self.project_root, "sequences") shot_path = os.path.join(sequence_path, self.shot["code"]) expected_paths.extend( [self.project_root, sequences_path, sequence_path, shot_path]) folder.process_filesystem_structure(self.tk, self.shot["type"], self.shot["id"], preview=False, engine=None) assert_paths_to_create(expected_paths)
def test_asset(self): """Tests paths used in making a shot are as expected.""" assets_path = os.path.join(self.project_root, "assets") at_path = os.path.join(assets_path, "assettype") asset_path = os.path.join(at_path, self.asset["code"]) ws_path = os.path.join(asset_path, self.workspace2["code"]) expected_paths = [] expected_paths.extend([ self.project_root, os.path.join(self.project_root, "sequences"), assets_path, at_path, asset_path, ws_path ]) folder.process_filesystem_structure(self.tk, self.workspace2["type"], self.workspace2["id"], preview=False, engine=None) assert_paths_to_create(expected_paths)
def test_rename_shot_but_keep_on_disk(self): # 1. create fodlers for shot ABC # 2. rename shot to XYZ # 3. create folders --> ERROR folder.process_filesystem_structure(self.tk, self.task["type"], self.task["id"], preview=False, engine=None) # rename the shot self.shot["code"] = "XYZ" self.assertRaises(TankError, folder.process_filesystem_structure, self.tk, self.task["type"], self.task["id"], preview=False, engine=None) # but if I delete the old folder on disk, the folder creation should proceed shot_path = os.path.join(self.project_root, "sequences", "seq_code", "shot_code") renamed_shot_path = os.path.join(self.project_root, "sequences", "seq_code", "shot_code_renamed") shutil.move(shot_path, renamed_shot_path) folder.process_filesystem_structure(self.tk, self.task["type"], self.task["id"], preview=False, engine=None) new_shot_path = os.path.join(self.project_root, "sequences", "seq_code", "XYZ") self.assertTrue(os.path.exists(new_shot_path))
def test_delete_shot_then_recreate(self): # 1. create fodlers for shot ABC # 2. delete shot ABC from SG # 3. create a new shot ABC in SG # 4. when creating folders, it should delete the previous records and replace with new self.assertEquals(self.path_cache.get_paths("Shot", self.shot["id"], False), []) folder.process_filesystem_structure(self.tk, self.task["type"], self.task["id"], preview=False, engine=None) # check that it is in the db shot_path = os.path.join(self.project_root, "sequences", "seq_code", "shot_code") paths_in_db = self.path_cache.get_paths("Shot", self.shot["id"], False) self.assertEquals(paths_in_db, [shot_path]) # change the id of the shot - effectively deleting and creating a shot! old_id = self.shot["id"] self.shot["id"] = 12345 # make sure to null the link going from the task too - this is how shotgun # would have done a retirement. self.task["entity"] = self.shot self.assertEquals( self.path_cache.get_paths("Shot", self.shot["id"], False), []) self.assertRaisesRegexp(TankError, "Folder creation aborted.*unregister_folders", folder.process_filesystem_structure, self.tk, self.task["type"], self.task["id"], preview=False, engine=None)
def test_asset(self): """Tests paths used in making a asset are as expected.""" # expected paths here are based on sg_standard start-config # define paths we expect for entities static_assets = os.path.join(self.project_root, "assets") asset_type_path = os.path.join(static_assets, self.asset["sg_asset_type"]) asset_path = os.path.join(asset_type_path, self.asset["code"]) step_path = os.path.join(asset_path, self.step["short_name"]) expected_paths = [ self.project_root, os.path.join(self.project_root, "reference"), os.path.join(self.project_root, "scenes"), os.path.join(self.project_root, "sequences"), os.path.join(self.project_root, "reference", "artwork"), os.path.join(self.project_root, "reference", "footage"), static_assets, asset_type_path, asset_path, step_path ] # add non-entity paths expected_paths.append(os.path.join(step_path, "publish")) expected_paths.append(os.path.join(step_path, "images")) expected_paths.append(os.path.join(step_path, "review")) expected_paths.append(os.path.join(step_path, "work")) expected_paths.append(os.path.join(step_path, "work", "snapshots")) expected_paths.append(os.path.join(step_path, "out")) self.tk = tank.Tank(self.project_root) folder.process_filesystem_structure(self.tk, self.asset["type"], self.asset["id"], preview=False, engine=None) assert_paths_to_create(expected_paths)
def test_made_string(self, get_current_user): self.assertFalse(os.path.exists(self.user_path)) get_current_user.return_value = self.humanuser folder.process_filesystem_structure( self.tk, self.shot["type"], self.shot["id"], preview=False, engine="tk-maya" ) self.assertTrue(os.path.exists(self.user_path)) get_current_user.return_value = self.humanuser2 folder.process_filesystem_structure( self.tk, self.shot["type"], self.shot["id"], preview=False, engine="tk-maya" ) self.assertTrue(os.path.exists(self.user_path2)) # test user context ctx_foo = self.tk.context_from_path(self.user_path) ctx_bar = self.tk.context_from_path(self.user_path2) self.assertEqual(ctx_foo.filesystem_locations, [self.user_path]) self.assertEqual(ctx_bar.filesystem_locations, [self.user_path2])
def test_asset(self): self.assertFalse(os.path.exists(self.deferred_absent)) self.assertFalse(os.path.exists(self.deferred_false)) self.assertFalse(os.path.exists(self.deferred_specified)) self.assertFalse(os.path.exists(self.deferred_specified_2)) self.assertFalse(os.path.exists(self.deferred_true)) self.assertFalse(os.path.exists(self.deferred_asset_type)) self.assertFalse(os.path.exists(self.deferred_asset)) folder.process_filesystem_structure(self.tk, self.asset["type"], self.asset["id"], preview=False, engine="asset") self.assertFalse(os.path.exists(self.deferred_absent)) self.assertFalse(os.path.exists(self.deferred_false)) self.assertFalse(os.path.exists(self.deferred_specified)) self.assertFalse(os.path.exists(self.deferred_specified_2)) self.assertFalse(os.path.exists(self.deferred_true)) self.assertTrue(os.path.exists(self.deferred_asset_type)) self.assertTrue(os.path.exists(self.deferred_asset))
def test_project(self): """ Tests paths used in making a project are as expected when single project directory with no yaml file exits. """ # paths based on sg_standard starter config modified to be multi-project expected_paths = [] expected_paths.append(self.project_root) expected_paths.append(os.path.join(self.project_root, "sequences")) expected_paths.append(os.path.join(self.project_root, "reference")) expected_paths.append(os.path.join(self.project_root, "reference", "artwork")) expected_paths.append(os.path.join(self.project_root, "reference", "footage")) expected_paths.append(self.alt_root_1) expected_paths.append(os.path.join(self.alt_root_1, "assets")) expected_paths.append(os.path.join(self.alt_root_1, "alternate_reference")) folder.process_filesystem_structure(self.tk, self.project["type"], self.project["id"], preview=False, engine=None) assert_paths_to_create(expected_paths)
def test_create_symlink(self): """ Test folder creation for a shot which matches the static folder trigger condition """ self.assertFalse(os.path.exists(self.aaa)) self.assertFalse(os.path.exists(self.aaa_work)) self.assertFalse(os.path.exists(self.aaa_link)) folder.process_filesystem_structure(self.tk, self.shot_aaa["type"], self.shot_aaa["id"], preview=False, engine=None) self.assertTrue(os.path.exists(self.aaa)) self.assertTrue(os.path.exists(self.aaa_work)) if sys.platform != "win32": self.assertTrue(os.path.lexists(self.aaa_link)) self.assertTrue(os.path.islink(self.aaa_link)) self.assertEqual(os.readlink(self.aaa_link), "../Stuff/project_code/aaa") else: # no support on windows self.assertFalse(os.path.exists(self.aaa_link))
def test_list_field_token(self): """ Test that we can reference list field tokens in the symlink definition """ self.assertFalse(os.path.exists(self.bbb)) self.assertFalse(os.path.exists(self.bbb_work)) self.assertFalse(os.path.exists(self.bbb_link)) folder.process_filesystem_structure(self.tk, self.asset_bbb["type"], self.asset_bbb["id"], preview=False, engine=None) self.assertTrue(os.path.exists(self.bbb)) self.assertTrue(os.path.exists(self.bbb_work)) if sys.platform != "win32": self.assertTrue(os.path.lexists(self.bbb_link)) self.assertTrue(os.path.islink(self.bbb_link)) self.assertEqual(os.readlink(self.bbb_link), "../Stuff/project_code/vehicle/bbb") else: # no support on windows self.assertFalse(os.path.exists(self.bbb_link))
def test_concurrent(self): """ Test multi process incremental sync as records are being inserted. """ # skip this test on windows or py2.5 where multiprocessing isn't available if sys.platform == "win32" or sys.version_info < (2, 6): return import multiprocessing folder.process_filesystem_structure(self.tk, self.task["type"], self.task["id"], preview=False, engine=None) self.tk.synchronize_filesystem_structure(True) processes = [] queues = [] self._multiprocess_fail = False for x in range(20): queue = multiprocessing.Queue() proc = multiprocessing.Process(target=self.concurrent_payload, args=(queue, )) processes.append(proc) queues.append(queue) proc.start() shot_id = 5000 filesystem_location_id = 6000 event_log_id = 7000 while True: time.sleep(0.1) sys.stderr.write(".") shot_id += 1 filesystem_location_id += 1 event_log_id += 1 # create a new shot in shotgun sg_shot = { "type": "Shot", "id": shot_id, "code": "shot_code_%s" % shot_id, "sg_sequence": self.seq, "project": self.project } sg_folder = { 'id': filesystem_location_id, 'type': 'FilesystemLocation', 'project': self.project, 'code': sg_shot["code"], 'linked_entity_type': 'Shot', 'linked_entity_id': shot_id, 'path': None, 'configuration_metadata': '', 'is_primary': True, 'pipeline_configuration': { 'type': 'PipelineConfiguration', 'id': 123 }, 'created_by': None, 'entity': sg_shot } sg_event_log_entry = { 'id': event_log_id, 'type': 'EventLogEntry', 'project': self.project, 'event_type': "Toolkit_Folders_Create", 'meta': { 'core_api_version': 'HEAD', 'sg_folder_ids': [filesystem_location_id] } } self.add_to_sg_mock_db([sg_shot, sg_folder, sg_event_log_entry]) if all(not (p.is_alive()) for p in processes): # all procs finished break # now update the mockgun in all other processes for queue in queues: try: queue.put(self.tk.shotgun._db, block=False) except IOError: pass self.assertFalse(self._multiprocess_fail)
def test_shot(self): """Test full and incremental path cache sync.""" path_cache = tank.path_cache.PathCache(self.tk) pcl = path_cache._get_path_cache_location() path_cache.close() self.assertEqual( len(self.tk.shotgun.find(tank.path_cache.SHOTGUN_ENTITY, [])), 1) self.assertEqual(len(self._get_path_cache()), 1) folder.process_filesystem_structure(self.tk, self.seq["type"], self.seq["id"], preview=False, engine=None) # now have project / seq self.assertEqual( len(self.tk.shotgun.find(tank.path_cache.SHOTGUN_ENTITY, [])), 2) self.assertEqual(len(self._get_path_cache()), 2) # nothing should happen sync_path_cache(self.tk) self.assertEqual( len(self.tk.shotgun.find(tank.path_cache.SHOTGUN_ENTITY, [])), 2) self.assertEqual(len(self._get_path_cache()), 2) # make a copy of the path cache at this point shutil.copy(pcl, "%s.snap1" % pcl) # now insert a new path in Shotgun folder.process_filesystem_structure(self.tk, self.task["type"], self.task["id"], preview=False, engine=None) # now have project / seq / shot / step self.assertEqual( len(self.tk.shotgun.find(tank.path_cache.SHOTGUN_ENTITY, [])), 4) self.assertEqual(len(self._get_path_cache()), 4) path_cache_contents_1 = self._get_path_cache() # now replace our path cache with snap1 shutil.copy(pcl, "%s.snap2" % pcl) shutil.copy("%s.snap1" % pcl, pcl) # now path cache has not been synchronized but shotgun has an entry self.assertEqual( len(self.tk.shotgun.find(tank.path_cache.SHOTGUN_ENTITY, [])), 4) self.assertEqual(len(self._get_path_cache()), 2) sync_path_cache(self.tk) # check that the sync happend self.assertEqual( len(self.tk.shotgun.find(tank.path_cache.SHOTGUN_ENTITY, [])), 4) self.assertEqual(len(self._get_path_cache()), 4) # and that the content is the same path_cache_contents_2 = self._get_path_cache() self.assertEqual(path_cache_contents_2, path_cache_contents_1) # now clear the path cache completely. This should trigger a full flush os.remove(pcl) log = sync_path_cache(self.tk) self.assertTrue("Performing a complete Shotgun folder sync" in log) # check that the sync happend self.assertEqual( len(self.tk.shotgun.find(tank.path_cache.SHOTGUN_ENTITY, [])), 4) self.assertEqual(len(self._get_path_cache()), 4) # and that the content is the same path_cache_contents_3 = self._get_path_cache() self.assertEqual(path_cache_contents_3, path_cache_contents_1)