def test_local_rename_sync_root_folder(self): # Use the Administrator to be able to introspect the container of the # test workspace. remote_client = RemoteDocumentClient( self.nuxeo_url, self.admin_user, 'nxdrive-test-administrator-device', self.version, password=self.password, base_folder=self.workspace) folder_1_uid = remote_client.get_info(u'/Original Folder 1').uid # Create new clients to be able to introspect the test sync root toplevel_local_client = LocalClient(self.local_nxdrive_folder_1) toplevel_local_client.rename('/' + self.workspace_title, 'Renamed Nuxeo Drive Test Workspace') self.wait_sync() workspace_info = remote_client.get_info(self.workspace) self.assertEquals(workspace_info.name, u"Renamed Nuxeo Drive Test Workspace") folder_1_info = remote_client.get_info(folder_1_uid) self.assertEquals(folder_1_info.name, u"Original Folder 1") self.assertEquals(folder_1_info.parent_uid, self.workspace) self.assertEqual(len(remote_client.get_children_info(self.workspace_1)), 4)
def test_local_rename_sync_root_folder(self): sb, ctl = self.sb_1, self.controller_1 # Use the Administrator to be able to introspect the container of the # test workspace. remote_client = RemoteDocumentClient( self.nuxeo_url, self.admin_user, 'nxdrive-test-administrator-device', self.version, password=self.password, base_folder=self.workspace) folder_1_uid = remote_client.get_info(u'/Original Folder 1').uid # Create new clients to be able to introspect the test sync root toplevel_local_client = LocalClient(self.local_nxdrive_folder_1) toplevel_local_client.rename('/' + self.workspace_title, 'Renamed Nuxeo Drive Test Workspace') self.assertEquals(ctl.synchronizer.update_synchronize_server(sb), 1) workspace_info = remote_client.get_info(self.workspace) self.assertEquals(workspace_info.name, u"Renamed Nuxeo Drive Test Workspace") folder_1_info = remote_client.get_info(folder_1_uid) self.assertEquals(folder_1_info.name, u"Original Folder 1") self.assertEquals(folder_1_info.parent_uid, self.workspace)
def test_local_rename_top_level_folder(self): sb, ctl = self.sb_1, self.controller_1 local_client = LocalClient(self.local_test_folder_1) session = ctl.get_session() # Check top level folder self.assertTrue(local_client.exists(u'/Nuxeo Drive')) top_level_folder_info = local_client.get_info(u'/Nuxeo Drive') self.assertEquals(top_level_folder_info.name, u'Nuxeo Drive') self.assertEquals( top_level_folder_info.filepath, os.path.join(self.local_test_folder_1, u'Nuxeo Drive')) # Check top level folder state top_level_folder_state = session.query(LastKnownState).filter_by( local_name=u'Nuxeo Drive').one() self.assertEquals(top_level_folder_state.local_path, '/') self.assertEquals(top_level_folder_state.local_name, u'Nuxeo Drive') # Rename top level folder local_client.rename(u'/Nuxeo Drive', u'Nuxeo Drive renamed') top_level_folder_info = local_client.get_info(u'/Nuxeo Drive renamed') self.assertEquals(top_level_folder_info.name, u'Nuxeo Drive renamed') self.assertEquals( top_level_folder_info.filepath, os.path.join(self.local_test_folder_1, u'Nuxeo Drive renamed')) self.assertEquals(ctl.synchronizer.update_synchronize_server(sb), 1) # Check deleted server binding self.assertRaises(RuntimeError, ctl.get_server_binding, self.local_nxdrive_folder_1, raise_if_missing=True) # Check deleted pair state self.assertEquals(len(session.query(LastKnownState).all()), 0)
def test_local_rename_sync_root_folder(self): if sys.platform.startswith('linux'): raise SkipTest("WIP in https://jira.nuxeo.com/browse/NXDRIVE-170") # Use the Administrator to be able to introspect the container of the # test workspace. remote_client = RemoteDocumentClient( self.nuxeo_url, self.admin_user, 'nxdrive-test-administrator-device', self.version, password=self.password, base_folder=self.workspace) folder_1_uid = remote_client.get_info(u'/Original Folder 1').uid # Create new clients to be able to introspect the test sync root toplevel_local_client = LocalClient(self.local_nxdrive_folder_1) toplevel_local_client.rename('/' + self.workspace_title, 'Renamed Nuxeo Drive Test Workspace') self.wait_sync() workspace_info = remote_client.get_info(self.workspace) self.assertEquals(workspace_info.name, u"Renamed Nuxeo Drive Test Workspace") folder_1_info = remote_client.get_info(folder_1_uid) self.assertEquals(folder_1_info.name, u"Original Folder 1") self.assertEquals(folder_1_info.parent_uid, self.workspace)
def test_local_rename_top_level_folder(self): sb, ctl = self.sb_1, self.controller_1 local_client = LocalClient(self.local_test_folder_1) session = ctl.get_session() # Check top level folder self.assertTrue(local_client.exists(u'/Nuxeo Drive')) top_level_folder_info = local_client.get_info(u'/Nuxeo Drive') self.assertEquals(top_level_folder_info.name, u'Nuxeo Drive') self.assertEquals(top_level_folder_info.filepath, os.path.join(self.local_test_folder_1, u'Nuxeo Drive')) # Check top level folder state top_level_folder_state = session.query(LastKnownState).filter_by( local_name=u'Nuxeo Drive').one() self.assertEquals(top_level_folder_state.local_path, '/') self.assertEquals(top_level_folder_state.local_name, u'Nuxeo Drive') # Rename top level folder local_client.rename(u'/Nuxeo Drive', u'Nuxeo Drive renamed') top_level_folder_info = local_client.get_info(u'/Nuxeo Drive renamed') self.assertEquals(top_level_folder_info.name, u'Nuxeo Drive renamed') self.assertEquals(top_level_folder_info.filepath, os.path.join(self.local_test_folder_1, u'Nuxeo Drive renamed')) self.assertEquals(ctl.synchronizer.update_synchronize_server(sb), 1) # Check deleted server binding self.assertRaises(RuntimeError, ctl.get_server_binding, self.local_nxdrive_folder_1, raise_if_missing=True) # Check deleted pair state self.assertEquals(len(session.query(LastKnownState).all()), 0)
def test_local_rename_sync_root_folder(self): sb, ctl = self.sb_1, self.controller_1 # Use the Administrator to be able to introspect the container of the # test workspace. remote_client = RemoteDocumentClient( self.nuxeo_url, self.admin_user, 'nxdrive-test-administrator-device', self.password, base_folder=self.workspace) folder_1_uid = remote_client.get_info(u'/Original Folder 1').uid # Create new clients to be able to introspect the test sync root toplevel_local_client = LocalClient(self.local_nxdrive_folder_1) toplevel_local_client.rename('/' + self.workspace_title, 'Renamed Nuxeo Drive Test Workspace') self.assertEquals(ctl.synchronizer.update_synchronize_server(sb), 1) workspace_info = remote_client.get_info(self.workspace) self.assertEquals(workspace_info.name, u"Renamed Nuxeo Drive Test Workspace") folder_1_info = remote_client.get_info(folder_1_uid) self.assertEquals(folder_1_info.name, u"Original Folder 1") self.assertEquals(folder_1_info.parent_uid, self.workspace) # TODO: implement me once canDelete is checked in the synchronizer # def test_local_move_sync_root_folder(self): # pass
def test_local_rename_sync_root_folder(self): # Use the Administrator to be able to introspect the container of the # test workspace. remote_client = RemoteDocumentClientForTests( self.nuxeo_url, self.admin_user, 'nxdrive-test-administrator-device', self.version, password=self.password, base_folder=self.workspace) folder_1_uid = remote_client.get_info(u'/Original Folder 1').uid # Create new clients to be able to introspect the test sync root toplevel_local_client = LocalClient(self.local_nxdrive_folder_1) toplevel_local_client.rename('/' + self.workspace_title, 'Renamed Nuxeo Drive Test Workspace') self.wait_sync() workspace_info = remote_client.get_info(self.workspace) self.assertEqual(workspace_info.name, u"Renamed Nuxeo Drive Test Workspace") folder_1_info = remote_client.get_info(folder_1_uid) self.assertEqual(folder_1_info.name, u"Original Folder 1") self.assertEqual(folder_1_info.parent_uid, self.workspace) self.assertEqual( len(remote_client.get_children_info(self.workspace_1)), 4)
def test_synchronize_local_folder_rename_remote_deletion(self): """Test local folder rename followed by remote deletion""" raise SkipTest("Skipped waiting for" " https://jira.nuxeo.com/browse/NXDRIVE-80 to be fixed") # Bind the server and root workspace ctl = self.controller_1 ctl.bind_server(self.local_nxdrive_folder_1, self.nuxeo_url, self.user_1, self.password_1) ctl.bind_root(self.local_nxdrive_folder_1, self.workspace) # Get local and remote clients local = LocalClient(os.path.join(self.local_nxdrive_folder_1, self.workspace_title)) remote = self.remote_document_client_1 # Create a folder with a child file in the remote root workspace # then synchronize test_folder_uid = remote.make_folder('/', 'Test folder') remote.make_file(test_folder_uid, 'joe.odt', 'Some content') syn = ctl.synchronizer self._synchronize(syn) self.assertTrue(local.exists('/Test folder')) self.assertTrue(local.exists('/Test folder/joe.odt')) # Locally rename the folder then synchronize time.sleep(self.OS_STAT_MTIME_RESOLUTION) local.rename('/Test folder', 'Test folder renamed') self._synchronize(syn) self.assertFalse(local.exists('/Test folder')) self.assertTrue(local.exists('/Test folder renamed')) self.assertEquals(remote.get_info(test_folder_uid).name, 'Test folder renamed') # Delete remote folder then synchronize remote.delete('/Test folder') self._synchronize(syn) self.assertFalse(remote.exists('/Test folder renamed')) self.assertFalse(local.exists('/Test folder renamed'))
def test_synchronize_remote_deletion_local_modification(self): """Test remote deletion with concurrent local modification Use cases: - Remotely delete a regular folder and make some local changes concurrently. => Only locally modified content should be kept and should be marked as 'unsynchronized', other content should be deleted. - Remotely restore folder from the trash. => Remote documents should be merged with locally modified content which should be unmarked as 'unsynchronized'. - Remotely delete a file and locally update its content concurrently. => File should be kept locally and be marked as 'unsynchronized'. - Remotely restore file from the trash. => Remote file should be merged with locally modified file with a conflict detection and both files should be marked as 'synchronized'. - Remotely delete a file and locally rename it concurrently. => File should be kept locally and be marked as 'synchronized'. - Remotely restore file from the trash. => Remote file should be merged with locally renamed file and both files should be marked as 'synchronized'. See TestIntegrationSecurityUpdates .test_synchronize_denying_read_access_local_modification as the same uses cases are tested. Note that we use the .odt extension for test files to make sure that they are created as File and not Note documents on the server when synchronized upstream, as the current implementation of RemoteDocumentClient is File oriented. """ # Bind the server and root workspace ctl = self.controller_1 ctl.bind_server(self.local_nxdrive_folder_1, self.nuxeo_url, self.user_1, self.password_1) ctl.bind_root(self.local_nxdrive_folder_1, self.workspace) # Get local and remote clients local = LocalClient(os.path.join(self.local_nxdrive_folder_1, self.workspace_title)) remote = self.remote_document_client_1 # Create documents in the remote root workspace # then synchronize remote.make_folder('/', 'Test folder') remote.make_file('/Test folder', 'joe.odt', 'Some content') remote.make_file('/Test folder', 'jack.odt', 'Some content') remote.make_folder('/Test folder', 'Sub folder 1') remote.make_file('/Test folder/Sub folder 1', 'sub file 1.txt', 'Content') syn = ctl.synchronizer self._synchronize(syn) self.assertTrue(local.exists('/Test folder')) self.assertTrue(local.exists('/Test folder/joe.odt')) self.assertTrue(local.exists('/Test folder/jack.odt')) self.assertTrue(local.exists('/Test folder/Sub folder 1')) self.assertTrue(local.exists( '/Test folder/Sub folder 1/sub file 1.txt')) # Delete remote folder and make some local changes # concurrently then synchronize remote.delete('/Test folder') time.sleep(self.OS_STAT_MTIME_RESOLUTION) # Create new file local.make_file('/Test folder', 'new.odt', "New content") # Create new folder with files local.make_folder('/Test folder', 'Sub folder 2') local.make_file('/Test folder/Sub folder 2', 'sub file 2.txt', 'Other content') # Update file local.update_content('/Test folder/joe.odt', 'Some updated content') self._synchronize(syn) # Only locally modified content should exist # and should be marked as 'unsynchronized', other content should # have been deleted # Local check self.assertTrue(local.exists('/Test folder')) self.assertTrue(local.exists('/Test folder/joe.odt')) self.assertEquals(local.get_content('/Test folder/joe.odt'), 'Some updated content') self.assertTrue(local.exists('/Test folder/new.odt')) self.assertTrue(local.exists('/Test folder/Sub folder 2')) self.assertTrue(local.exists( '/Test folder/Sub folder 2/sub file 2.txt')) self.assertFalse(local.exists('/Test folder/jack.odt')) self.assertFalse(local.exists('/Test folder/Sub folder 1')) self.assertFalse(local.exists( '/Test folder/Sub folder 1/sub file 1.txt')) # State check session = ctl.get_session() self._check_pair_state(session, '/Test folder', 'unsynchronized') self._check_pair_state(session, '/Test folder/joe.odt', 'unsynchronized') self._check_pair_state(session, '/Test folder/new.odt', 'unsynchronized') self._check_pair_state(session, '/Test folder/Sub folder 2', 'unsynchronized') self._check_pair_state(session, '/Test folder/Sub folder 2/sub file 2.txt', 'unsynchronized') # Remote check self.assertFalse(remote.exists('/Test folder')) # Restore remote folder and its children from trash then synchronize remote.undelete('/Test folder') remote.undelete('/Test folder/joe.odt') remote.undelete('/Test folder/jack.odt') remote.undelete('/Test folder/Sub folder 1') remote.undelete('/Test folder/Sub folder 1/sub file 1.txt') self._synchronize(syn) # Remotely restored documents should be merged with # locally modified content which should be unmarked # as 'unsynchronized' and therefore synchronized upstream # Local check self.assertTrue(local.exists('/Test folder')) children_info = local.get_children_info('/Test folder') self.assertEquals(len(children_info), 6) for info in children_info: if info.name == 'joe.odt': remote_version = info elif info.name.startswith('joe (') and info.name.endswith(').odt'): local_version = info self.assertTrue(remote_version is not None) self.assertTrue(local_version is not None) self.assertTrue(local.exists(remote_version.path)) self.assertEquals(local.get_content(remote_version.path), 'Some content') self.assertTrue(local.exists(local_version.path)) self.assertEquals(local.get_content(local_version.path), 'Some updated content') self.assertTrue(local.exists('/Test folder/jack.odt')) self.assertTrue(local.exists('/Test folder/new.odt')) self.assertTrue(local.exists('/Test folder/Sub folder 1')) self.assertTrue(local.exists( '/Test folder/Sub folder 1/sub file 1.txt')) self.assertTrue(local.exists('/Test folder/Sub folder 2')) self.assertTrue(local.exists( '/Test folder/Sub folder 2/sub file 2.txt')) # State check self._check_pair_state(session, '/Test folder', 'synchronized') self._check_pair_state(session, '/Test folder/joe.odt', 'synchronized') self._check_pair_state(session, '/Test folder/new.odt', 'synchronized') self._check_pair_state(session, '/Test folder/Sub folder 2', 'synchronized') self._check_pair_state(session, '/Test folder/Sub folder 2/sub file 2.txt', 'synchronized') # Remote check self.assertTrue(remote.exists('/Test folder')) test_folder_uid = remote.get_info('/Test folder').uid children_info = remote.get_children_info(test_folder_uid) self.assertEquals(len(children_info), 6) for info in children_info: if info.name == 'joe.odt': remote_version = info elif info.name.startswith('joe (') and info.name.endswith(').odt'): local_version = info self.assertTrue(remote_version is not None) self.assertTrue(local_version is not None) remote_version_ref_length = (len(remote_version.path) - len(self.TEST_WORKSPACE_PATH)) remote_version_ref = remote_version.path[-remote_version_ref_length:] self.assertTrue(remote.exists(remote_version_ref)) self.assertEquals(remote.get_content(remote_version_ref), 'Some content') local_version_ref_length = (len(local_version.path) - len(self.TEST_WORKSPACE_PATH)) local_version_ref = local_version.path[-local_version_ref_length:] self.assertTrue(remote.exists(local_version_ref)) self.assertEquals(remote.get_content(local_version_ref), 'Some updated content') self.assertTrue(remote.exists('/Test folder/jack.odt')) self.assertTrue(remote.exists('/Test folder/new.odt')) self.assertTrue(remote.exists('/Test folder/Sub folder 1')) self.assertTrue(remote.exists( '/Test folder/Sub folder 1/sub file 1.txt')) self.assertTrue(remote.exists('/Test folder/Sub folder 2')) self.assertTrue(remote.exists( '/Test folder/Sub folder 2/sub file 2.txt')) # Delete remote file and update its local content # concurrently then synchronize remote.delete('/Test folder/jack.odt') time.sleep(self.OS_STAT_MTIME_RESOLUTION) local.update_content('/Test folder/jack.odt', 'Some updated content') self._synchronize(syn) # File should be kept locally and be marked as 'unsynchronized'. # Local check self.assertTrue(local.exists('/Test folder/jack.odt')) self.assertEquals(local.get_content('/Test folder/jack.odt'), 'Some updated content') # Remote check self.assertFalse(remote.exists('/Test folder/jack.odt')) # State check session = ctl.get_session() self._check_pair_state(session, '/Test folder', 'synchronized') self._check_pair_state(session, '/Test folder/jack.odt', 'unsynchronized') # Remotely restore file from the trash then synchronize remote.undelete('/Test folder/jack.odt') self._synchronize(syn) # Remotely restored file should be merged with locally modified file # with a conflict detection and both files should be marked # as 'synchronized' # Local check children_info = local.get_children_info('/Test folder') for info in children_info: if info.name == 'jack.odt': remote_version = info elif (info.name.startswith('jack (') and info.name.endswith(').odt')): local_version = info self.assertTrue(remote_version is not None) self.assertTrue(local_version is not None) self.assertTrue(local.exists(remote_version.path)) self.assertEquals(local.get_content(remote_version.path), 'Some content') self.assertTrue(local.exists(local_version.path)) self.assertEquals(local.get_content(local_version.path), 'Some updated content') # Remote check self.assertTrue(remote.exists(remote_version.path)) self.assertEquals(remote.get_content(remote_version.path), 'Some content') local_version_path = self._truncate_remote_path(local_version.path) self.assertTrue(remote.exists(local_version_path)) self.assertEquals(remote.get_content(local_version_path), 'Some updated content') # State check self._check_pair_state(session, remote_version.path, 'synchronized') self._check_pair_state(session, local_version.path, 'synchronized') # Delete remote file and rename it locally # concurrently then synchronize remote.delete('/Test folder/jack.odt') time.sleep(self.OS_STAT_MTIME_RESOLUTION) local.rename('/Test folder/jack.odt', 'jack renamed.odt') self._synchronize(syn) # File should be kept locally and be marked as 'synchronized' # Local check self.assertFalse(local.exists('/Test folder/jack.odt')) self.assertTrue(local.exists('/Test folder/jack renamed.odt')) self.assertEquals(local.get_content('/Test folder/jack renamed.odt'), 'Some content') # Remote check self.assertFalse(remote.exists('/Test folder/jack.odt')) # State check session = ctl.get_session() self._check_pair_state(session, '/Test folder', 'synchronized') self._check_pair_state(session, '/Test folder/jack renamed.odt', 'synchronized') # Remotely restore file from the trash then synchronize remote.undelete('/Test folder/jack.odt') self._synchronize(syn) # Remotely restored file should be merged with locally renamed file # and both files should be marked as 'synchronized' # Local check self.assertTrue(local.exists('/Test folder/jack.odt')) self.assertEquals(local.get_content('/Test folder/jack.odt'), 'Some content') self.assertTrue(local.exists('/Test folder/jack renamed.odt')) self.assertEquals(local.get_content('/Test folder/jack renamed.odt'), 'Some content') # Remote check self.assertTrue(remote.exists('/Test folder/jack.odt')) self.assertEquals(remote.get_content('/Test folder/jack.odt'), 'Some content') self.assertTrue(remote.exists('/Test folder/jack renamed.odt')) self.assertEquals(remote.get_content('/Test folder/jack renamed.odt'), 'Some content') # State check self._check_pair_state(session, '/Test folder/jack.odt', 'synchronized') self._check_pair_state(session, '/Test folder/jack renamed.odt', 'synchronized')