def _reinit_database(self): # Close database self.ctl.dispose() # Destroy configuration folder shutil.rmtree(self.nxdrive_conf_folder_1) os.mkdir(self.nxdrive_conf_folder_1) # Recreate a controller self.ctl = Controller(self.nxdrive_conf_folder_1) self.ctl.bind_server(self.local_nxdrive_folder_1, self.nuxeo_url, self.user_1, self.password_1) self.ctl.bind_root(self.local_nxdrive_folder_1, self.workspace) self.syn = self.ctl.synchronizer
def handle(self, args): # use the CLI parser to check that the first args is a valid command options = self.parser.parse_args(args) if options.debug: # Install Post-Mortem debugger hook def info(type, value, tb): traceback.print_exception(type, value, tb) print debugger.pm() sys.excepthook = info filename = options.log_filename if filename is None: filename = os.path.join( options.nxdrive_home, 'logs', 'nxdrive.log') configure( filename, file_level=options.log_level_file, console_level=options.log_level_console, process_name=options.command, ) self.controller = Controller(options.nxdrive_home) handler = getattr(self, options.command, None) if handler is None: raise NotImplementedError( 'No handler implemented for command ' + options.command) return handler(options)
def get_controller(self, options): nb_tries = 1 while (nb_tries <= GET_CTL_MAX_NB_TRIES): try: return Controller(options.nxdrive_home, handshake_timeout=options.handshake_timeout, timeout=options.timeout, max_errors=options.max_errors, update_url=options.update_site_url) except OperationalError as e: self.log.error("OperationalError during try #%d to get" " controller, waiting for %d seconds and" " retrying at most %d times" % (nb_tries, GET_CTL_SLEEP_DURATION, GET_CTL_MAX_NB_TRIES - nb_tries), exc_info=True) time.sleep(GET_CTL_SLEEP_DURATION) nb_tries += 1 if nb_tries > 1: raise e
def test_synchronize_paged_delete_detection(self): # Initialize a controller with page size = 1 for deleted items # detection query ctl = Controller(self.nxdrive_conf_folder_1, page_size=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) # Launch first synchronization time.sleep(self.AUDIT_CHANGE_FINDER_TIME_RESOLUTION) self.wait() syn = ctl.synchronizer syn.loop(delay=0.1, max_loops=1) # 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 remote folder with 2 children then synchronize remote.make_folder('/', 'Remote folder',) remote.make_file('/Remote folder', 'Remote file 1.odt', 'Some content.') remote.make_file('/Remote folder', 'Remote file 2.odt', 'Other content.') time.sleep(self.AUDIT_CHANGE_FINDER_TIME_RESOLUTION) self.wait() syn.loop(delay=0.1, max_loops=1) self.assertTrue(local.exists('/Remote folder')) self.assertTrue(local.exists('/Remote folder/Remote file 1.odt')) self.assertTrue(local.exists('/Remote folder/Remote file 2.odt')) # Delete remote folder then synchronize remote.delete('/Remote folder') time.sleep(self.AUDIT_CHANGE_FINDER_TIME_RESOLUTION) self.wait() syn.loop(delay=0.1, max_loops=1) self.assertFalse(local.exists('/Remote folder')) self.assertFalse(local.exists('/Remote folder/Remote file 1.odt')) self.assertFalse(local.exists('/Remote folder/Remote file 2.odt')) # Create a local folder with 2 children then synchronize local.make_folder('/', 'Local folder') local.make_file('/Local folder', 'Local file 1.odt', 'Some content.') local.make_file('/Local folder', 'Local file 2.odt', 'Other content.') syn.loop(delay=0.1, max_loops=1) self.assertTrue(remote.exists('/Local folder')) self.assertTrue(remote.exists('/Local folder/Local file 1.odt')) self.assertTrue(remote.exists('/Local folder/Local file 2.odt')) # Delete local folder then synchronize time.sleep(self.OS_STAT_MTIME_RESOLUTION) local.delete('/Local folder') syn.loop(delay=0.1, max_loops=1) self.assertFalse(remote.exists('/Local folder')) self.assertFalse(remote.exists('/Local folder/Local file 1.odt')) self.assertFalse(remote.exists('/Local folder/Local file 2.odt')) # Dispose dedicated Controller instantiated for this test ctl.dispose()
class TestIntegrationReinitDatabase(IntegrationTestCase): def setUp(self): super(TestIntegrationReinitDatabase, self).setUp() self.syn, self.local, self.remote = self.init_default_drive() self.ctl = self.controller_1 # Make a folder and a file self.remote.make_folder('/', 'Test folder') self.remote.make_file('/Test folder', 'Test.txt', 'This is some content') self.test_remote_folder_id = self.remote.get_info('/Test folder').uid # Wait for synchro self._synchronize() # Verify that all is synchronize self.assertTrue(self.local.exists('/Test folder'), 'Local folder should exist') self.assertTrue(self.local.exists('/Test folder/Test.txt'), 'Local file should exist') # Destroy database self._reinit_database() def tearDown(self): # Dispose dedicated Controller instantiated for this test # in _reinit_database() self.ctl.dispose() super(TestIntegrationReinitDatabase, self).tearDown() def _check_states(self): rows = self.controller_1.get_session().query(LastKnownState).all() for row in rows: self.assertEquals(row.pair_state, 'synchronized') def _reinit_database(self): # Close database self.ctl.dispose() # Destroy configuration folder shutil.rmtree(self.nxdrive_conf_folder_1) os.mkdir(self.nxdrive_conf_folder_1) # Recreate a controller self.ctl = Controller(self.nxdrive_conf_folder_1) self.ctl.bind_server(self.local_nxdrive_folder_1, self.nuxeo_url, self.user_1, self.password_1) self.ctl.bind_root(self.local_nxdrive_folder_1, self.workspace) self.syn = self.ctl.synchronizer def _synchronize(self, loops=1): super(TestIntegrationReinitDatabase, self)._synchronize(self.syn, loops) def _check_conflict_locally_handled(self): # As a conflict has been raised 2 files should be present locally self.assertEqual(len(self.local.get_children_info("/Test folder")), 2) self.assertEqual(len(self.remote.get_children_info( self.test_remote_folder_id)), 1) def _check_conflict_locally_and_remotely_handled(self): # End the conflict handling by uploading the second local file to # the server self.assertEqual(len(self.local.get_children_info("/Test folder")), 2) self.assertEqual(len(self.remote.get_children_info( self.test_remote_folder_id, types=('File', 'Note'))), 2) def test_synchronize_folderish_and_same_digest(self): # Reload sync self._synchronize() # Check everything is synchronized self._check_states() def test_synchronize_remote_change(self): # Modify the remote file self.remote.update_content('/Test folder/Test.txt', 'Content has changed') # Sync self._synchronize() # Check a conflict is detected and handled locally self._check_conflict_locally_handled() # Assert content of the original file has changed self.assertEquals(self.local.get_content('/Test folder/Test.txt'), 'Content has changed', 'Local content should be the same as the remote one') # Sync again self._synchronize(3) # Check a conflict is handled locally and remotely self._check_conflict_locally_and_remotely_handled() # Check everything is synchronized self._check_states() def test_synchronize_local_change(self): # Modify the local file time.sleep(self.OS_STAT_MTIME_RESOLUTION) self.local.update_content('/Test folder/Test.txt', 'Content has changed') # Sync self._synchronize() # Check a conflict is detected and handled locally self._check_conflict_locally_handled() # Assert content of the original file has not changed self.assertEquals(self.local.get_content('/Test folder/Test.txt'), 'This is some content', 'Local content should be the same as the remote one') # Sync again self._synchronize(3) # Check a conflict is handled locally and remotely self._check_conflict_locally_and_remotely_handled() # Assert content has changed self.assertEquals(self.remote.get_content('/Test folder/Test.txt'), 'This is some content', 'Remote content should not have changed') # Check everything is synchronized self._check_states() def test_synchronize_remote_and_local_change(self): # Modify the remote file self.remote.update_content('/Test folder/Test.txt', 'Content has remote changed') # Modify the local file time.sleep(self.OS_STAT_MTIME_RESOLUTION) self.local.update_content('/Test folder/Test.txt', 'Content has local changed') # Sync self._synchronize() # Check a conflict is detected and handled locally self._check_conflict_locally_handled() # Assert content of the original file has not changed self.assertEquals(self.local.get_content('/Test folder/Test.txt'), 'Content has remote changed', 'Local content should be the same as remote one') # Sync again self._synchronize(3) # Check a conflict is handled locally and remotely self._check_conflict_locally_and_remotely_handled() # Assert content has changed self.assertEquals(self.local.get_content('/Test folder/Test.txt'), 'Content has remote changed', 'Remote changed content should not have changed again') # Check everything is synchronized self._check_states()
class IntegrationTestCase(unittest.TestCase): TEST_WORKSPACE_PATH = ( u'/default-domain/workspaces/nuxeo-drive-test-workspace') FS_ITEM_ID_PREFIX = u'defaultFileSystemItemFactory#default#' EMPTY_DIGEST = hashlib.md5().hexdigest() SOME_TEXT_CONTENT = b"Some text content." SOME_TEXT_DIGEST = hashlib.md5(SOME_TEXT_CONTENT).hexdigest() # 1s time resolution as we truncate remote last modification time to the # seconds in RemoteFileSystemClient.file_to_info() because of the datetime # resolution of some databases (MySQL...) REMOTE_MODIFICATION_TIME_RESOLUTION = 1.0 # 1s time resolution because of the datetime resolution of MYSQL AUDIT_CHANGE_FINDER_TIME_RESOLUTION = 1.0 # 1s resolution on HFS+ on OSX # 2s resolution on FAT but can be ignored as no Jenkins is running the test # suite under windows on FAT partitions # ~0.01s resolution for NTFS # 0.001s for EXT4FS OS_STAT_MTIME_RESOLUTION = 1.0 # Nuxeo max length for document name DOC_NAME_MAX_LENGTH = 24 def _synchronize(self, syn, delay=0.1, loops=1): self.wait_audit_change_finder_if_needed() self.wait() syn.loop(delay=delay, max_loops=loops) def setUp(self): # Check the Nuxeo server test environment self.nuxeo_url = os.environ.get('NXDRIVE_TEST_NUXEO_URL') self.admin_user = os.environ.get('NXDRIVE_TEST_USER') self.password = os.environ.get('NXDRIVE_TEST_PASSWORD') # Take default parameter if none has been set if self.nuxeo_url is None: self.nuxeo_url = "http://localhost:8080/nuxeo" if self.admin_user is None: self.admin_user = "******" if self.password is None: self.password = "******" if None in (self.nuxeo_url, self.admin_user, self.password): raise unittest.SkipTest( "No integration server configuration found in environment.") # Check the local filesystem test environment self.local_test_folder_1 = tempfile.mkdtemp(u'-nxdrive-tests-user-1') self.local_test_folder_2 = tempfile.mkdtemp(u'-nxdrive-tests-user-2') self.local_nxdrive_folder_1 = os.path.join( self.local_test_folder_1, u'Nuxeo Drive') os.mkdir(self.local_nxdrive_folder_1) self.local_nxdrive_folder_2 = os.path.join( self.local_test_folder_2, u'Nuxeo Drive') os.mkdir(self.local_nxdrive_folder_2) self.nxdrive_conf_folder_1 = os.path.join( self.local_test_folder_1, u'nuxeo-drive-conf') os.mkdir(self.nxdrive_conf_folder_1) self.nxdrive_conf_folder_2 = os.path.join( self.local_test_folder_2, u'nuxeo-drive-conf') os.mkdir(self.nxdrive_conf_folder_2) # Set echo to True to enable SQL statements and transactions logging # and echo_pool to True to enable connection pool logging self.controller_1 = Controller(self.nxdrive_conf_folder_1, echo=False, echo_pool=False) self.controller_2 = Controller(self.nxdrive_conf_folder_2, echo=False, echo_pool=False) self.controller_1.synchronizer.test_delay = 3 self.controller_2.synchronizer.test_delay = 3 self.version = self.controller_1.get_version() # Long timeout for the root client that is responsible for the test # environment set: this client is doing the first query on the Nuxeo # server and might need to wait for a long time without failing for # Nuxeo to finish initialize the repo on the first request after # startup root_remote_client = RemoteDocumentClient( self.nuxeo_url, self.admin_user, u'nxdrive-test-administrator-device', self.version, password=self.password, base_folder=u'/', timeout=60) # Call the Nuxeo operation to setup the integration test environment credentials = root_remote_client.execute( "NuxeoDrive.SetupIntegrationTests", userNames="user_1, user_2", permission='ReadWrite') credentials = [c.strip().split(u":") for c in credentials.split(u",")] self.user_1, self.password_1 = credentials[0] self.user_2, self.password_2 = credentials[1] ws_info = root_remote_client.fetch(self.TEST_WORKSPACE_PATH) self.workspace = ws_info[u'uid'] self.workspace_title = ws_info[u'title'] # Document client to be used to create remote test documents # and folders self.upload_tmp_dir = tempfile.mkdtemp(u'-nxdrive-uploads') remote_document_client_1 = RemoteDocumentClient( self.nuxeo_url, self.user_1, u'nxdrive-test-device-1', self.version, password=self.password_1, base_folder=self.workspace, upload_tmp_dir=self.upload_tmp_dir) remote_document_client_2 = RemoteDocumentClient( self.nuxeo_url, self.user_2, u'nxdrive-test-device-2', self.version, password=self.password_2, base_folder=self.workspace, upload_tmp_dir=self.upload_tmp_dir) # File system client to be used to create remote test documents # and folders remote_file_system_client_1 = RemoteFileSystemClient( self.nuxeo_url, self.user_1, u'nxdrive-test-device-1', self.version, password=self.password_1, upload_tmp_dir=self.upload_tmp_dir) remote_file_system_client_2 = RemoteFileSystemClient( self.nuxeo_url, self.user_2, u'nxdrive-test-device-2', self.version, password=self.password_2, upload_tmp_dir=self.upload_tmp_dir) self.root_remote_client = root_remote_client self.remote_document_client_1 = remote_document_client_1 self.remote_document_client_2 = remote_document_client_2 self.remote_file_system_client_1 = remote_file_system_client_1 self.remote_file_system_client_2 = remote_file_system_client_2 def tearDown(self): # Force to clean all observers self.controller_1.synchronizer.stop_observers(raise_on_error=False) self.controller_2.synchronizer.stop_observers(raise_on_error=False) # Note that unbinding a server revokes the related token if needed, # see Controller.unbind_server() self.controller_1.unbind_all() self.controller_2.unbind_all() # Don't need to revoke tokens for the file system remote clients # since they use the same users as the remote document clients self.root_remote_client.execute("NuxeoDrive.TearDownIntegrationTests") if os.path.exists(self.upload_tmp_dir): shutil.rmtree(safe_long_path(self.upload_tmp_dir)) if os.path.exists(self.local_test_folder_1): self.controller_1.dispose() try: shutil.rmtree(safe_long_path(self.local_test_folder_1)) except: pass if os.path.exists(self.local_test_folder_2): self.controller_2.dispose() try: shutil.rmtree(safe_long_path(self.local_test_folder_2)) except: pass def get_all_states(self, session=None, get_pair_state=False): """Utility to quickly introspect the current known states""" if session is None: session = self.controller_1.get_session() pairs = session.query(LastKnownState).order_by( LastKnownState.local_path, LastKnownState.remote_parent_path, LastKnownState.remote_name).all() if not get_pair_state: return [(p.local_path, p.local_state, p.remote_state) for p in pairs] else: return [(p.local_path, p.local_state, p.remote_state, p.pair_state) for p in pairs] def make_server_tree(self): remote_client = self.remote_document_client_1 # create some folders on the server folder_1 = remote_client.make_folder(self.workspace, u'Folder 1') folder_1_1 = remote_client.make_folder(folder_1, u'Folder 1.1') folder_1_2 = remote_client.make_folder(folder_1, u'Folder 1.2') folder_2 = remote_client.make_folder(self.workspace, u'Folder 2') # create some files on the server remote_client.make_file(folder_2, u'Duplicated File.txt', content=b"Some content.") remote_client.make_file(folder_2, u'Duplicated File.txt', content=b"Other content.") remote_client.make_file(folder_1, u'File 1.txt', content=b"aaa") remote_client.make_file(folder_1_1, u'File 2.txt', content=b"bbb") remote_client.make_file(folder_1_2, u'File 3.txt', content=b"ccc") remote_client.make_file(folder_2, u'File 4.txt', content=b"ddd") remote_client.make_file(self.workspace, u'File 5.txt', content=b"eee") def init_default_drive(self): # 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) # Launch first synchronization self.wait_audit_change_finder_if_needed() self.wait() syn = ctl.synchronizer syn.loop(delay=0.1, max_loops=1) # Get local and remote clients local = LocalClient(os.path.join(self.local_nxdrive_folder_1, self.workspace_title)) remote = self.remote_document_client_1 return syn, local, remote def wait(self): self.root_remote_client.wait() def wait_audit_change_finder_if_needed(self): if not self.root_remote_client.is_event_log_id_available(): time.sleep(self.AUDIT_CHANGE_FINDER_TIME_RESOLUTION)
dialog.show_message(msg, tab_index=tab_index) return False if app is None: log.debug("Launching Qt prompt to manage settings.") QtGui.QApplication([]) dialog = Dialog(sb_field_spec, proxy_field_spec, version, title="Nuxeo Drive - Settings", callback=validate) is_dialog_open = True try: dialog.exec_() except: dialog.reject() raise finally: is_dialog_open = False return dialog.accepted if __name__ == '__main__': from nxdrive.controller import Controller from nxdrive.controller import default_nuxeo_drive_folder ctl = Controller('/tmp') sb_settings = ServerBindingSettings( server_url='http://localhost:8080/nuxeo', username='******', local_folder=default_nuxeo_drive_folder()) proxy_settings = ProxySettings() version = ctl.get_version() print prompt_settings(ctl, sb_settings, proxy_settings, version)
def setUp(self): # Check the Nuxeo server test environment self.nuxeo_url = os.environ.get('NXDRIVE_TEST_NUXEO_URL') self.admin_user = os.environ.get('NXDRIVE_TEST_USER') self.password = os.environ.get('NXDRIVE_TEST_PASSWORD') # Take default parameter if none has been set if self.nuxeo_url is None: self.nuxeo_url = "http://localhost:8080/nuxeo" if self.admin_user is None: self.admin_user = "******" if self.password is None: self.password = "******" if None in (self.nuxeo_url, self.admin_user, self.password): raise unittest.SkipTest( "No integration server configuration found in environment.") # Check the local filesystem test environment self.local_test_folder_1 = tempfile.mkdtemp(u'-nxdrive-tests-user-1') self.local_test_folder_2 = tempfile.mkdtemp(u'-nxdrive-tests-user-2') self.local_nxdrive_folder_1 = os.path.join(self.local_test_folder_1, u'Nuxeo Drive') os.mkdir(self.local_nxdrive_folder_1) self.local_nxdrive_folder_2 = os.path.join(self.local_test_folder_2, u'Nuxeo Drive') os.mkdir(self.local_nxdrive_folder_2) self.nxdrive_conf_folder_1 = os.path.join(self.local_test_folder_1, u'nuxeo-drive-conf') os.mkdir(self.nxdrive_conf_folder_1) self.nxdrive_conf_folder_2 = os.path.join(self.local_test_folder_2, u'nuxeo-drive-conf') os.mkdir(self.nxdrive_conf_folder_2) # Set echo to True to enable SQL statements and transactions logging # and echo_pool to True to enable connection pool logging self.controller_1 = Controller(self.nxdrive_conf_folder_1, echo=False, echo_pool=False) self.controller_2 = Controller(self.nxdrive_conf_folder_2, echo=False, echo_pool=False) self.controller_1.synchronizer.test_delay = 3 self.controller_2.synchronizer.test_delay = 3 self.version = self.controller_1.get_version() # Long timeout for the root client that is responsible for the test # environment set: this client is doing the first query on the Nuxeo # server and might need to wait for a long time without failing for # Nuxeo to finish initialize the repo on the first request after # startup root_remote_client = RemoteDocumentClient( self.nuxeo_url, self.admin_user, u'nxdrive-test-administrator-device', self.version, password=self.password, base_folder=u'/', timeout=60) # Call the Nuxeo operation to setup the integration test environment credentials = root_remote_client.execute( "NuxeoDrive.SetupIntegrationTests", userNames="user_1, user_2", permission='ReadWrite') credentials = [c.strip().split(u":") for c in credentials.split(u",")] self.user_1, self.password_1 = credentials[0] self.user_2, self.password_2 = credentials[1] ws_info = root_remote_client.fetch(self.TEST_WORKSPACE_PATH) self.workspace = ws_info[u'uid'] self.workspace_title = ws_info[u'title'] # Document client to be used to create remote test documents # and folders self.upload_tmp_dir = tempfile.mkdtemp(u'-nxdrive-uploads') remote_document_client_1 = RemoteDocumentClient( self.nuxeo_url, self.user_1, u'nxdrive-test-device-1', self.version, password=self.password_1, base_folder=self.workspace, upload_tmp_dir=self.upload_tmp_dir) remote_document_client_2 = RemoteDocumentClient( self.nuxeo_url, self.user_2, u'nxdrive-test-device-2', self.version, password=self.password_2, base_folder=self.workspace, upload_tmp_dir=self.upload_tmp_dir) # File system client to be used to create remote test documents # and folders remote_file_system_client_1 = RemoteFileSystemClient( self.nuxeo_url, self.user_1, u'nxdrive-test-device-1', self.version, password=self.password_1, upload_tmp_dir=self.upload_tmp_dir) remote_file_system_client_2 = RemoteFileSystemClient( self.nuxeo_url, self.user_2, u'nxdrive-test-device-2', self.version, password=self.password_2, upload_tmp_dir=self.upload_tmp_dir) self.root_remote_client = root_remote_client self.remote_document_client_1 = remote_document_client_1 self.remote_document_client_2 = remote_document_client_2 self.remote_file_system_client_1 = remote_file_system_client_1 self.remote_file_system_client_2 = remote_file_system_client_2
def get_controller(self, options): return Controller(options.nxdrive_home, handshake_timeout=options.handshake_timeout, timeout=options.timeout, max_errors=options.max_errors)
# Useful to launch an interactive debugging session in ipython with %ed or %run from nxdrive.controller import Controller from nxdrive.model import ServerBinding c = Controller('~/.nuxeo-drive') s = c.get_session() sb = s.query(ServerBinding).one()
class CliHandler(object): """Command Line Interface handler: parse options and execute operation""" def __init__(self): self.parser = make_cli_parser() def handle(self, args): # use the CLI parser to check that the first args is a valid command options = self.parser.parse_args(args) if options.debug: # Install Post-Mortem debugger hook def info(type, value, tb): traceback.print_exception(type, value, tb) print debugger.pm() sys.excepthook = info filename = options.log_filename if filename is None: filename = os.path.join( options.nxdrive_home, 'logs', 'nxdrive.log') configure( filename, file_level=options.log_level_file, console_level=options.log_level_console, process_name=options.command, ) self.controller = Controller(options.nxdrive_home) handler = getattr(self, options.command, None) if handler is None: raise NotImplementedError( 'No handler implemented for command ' + options.command) return handler(options) def start(self, options=None): self.controller.start() return 0 def stop(self, options=None): self.controller.stop() return 0 def console(self, options): fault_tolerant = not options.stop_on_error self.controller.loop(fault_tolerant=fault_tolerant, delay=options.delay) return 0 def status(self, options): states = self.controller.status(options.files) for filename, status in states: print status + '\t' + filename return 0 def bind_server(self, options): if options.password is None: password = getpass() else: password = options.password self.controller.bind_server(options.local_folder, options.nuxeo_url, options.username, password) for root in options.remote_roots: self.controller.bind_root(options.local_folder, root, repository=options.remote_repo) return 0 def unbind_server(self, options): self.controller.unbind_server(options.local_folder) return 0 def bind_root(self, options): self.controller.bind_root(options.local_folder, options.remote_root, repository=options.remote_repo) return 0 def unbind_root(self, options): self.controller.unbind_root(options.local_root) return 0 def test(self, options): import nose # Monkeypatch nose usage message as it's complicated to include # the missing text resource in the frozen binary package nose.core.TestProgram.usage = lambda cls: "" argv = [''] if options.with_coverage: argv += [ '--with-coverage', '--cover-package=nxdrive', '--cover-html', '--cover-html-dir=coverage', ] if options.with_profile: argv += [ '--with-profile', '--profile-restrict=nxdrive', ] # List the test modules explicitly as recursive discovery is broken # when the app is frozen. argv += [ "nxdrive.tests.test_controller", "nxdrive.tests.test_filesystem_client", "nxdrive.tests.test_integration_nuxeo_client", "nxdrive.tests.test_integration_synchronization", ] return 0 if nose.run(argv=argv) else 1
class IntegrationTestCase(unittest.TestCase): TEST_WORKSPACE_PATH = ( u'/default-domain/workspaces/nuxeo-drive-test-workspace') FS_ITEM_ID_PREFIX = u'defaultFileSystemItemFactory#default#' EMPTY_DIGEST = hashlib.md5().hexdigest() SOME_TEXT_CONTENT = b"Some text content." SOME_TEXT_DIGEST = hashlib.md5(SOME_TEXT_CONTENT).hexdigest() # 1s time resolution because of the datetime resolution of MYSQL AUDIT_CHANGE_FINDER_TIME_RESOLUTION = 1.0 # 1s resolution on HFS+ on OSX # 2s resolution on FAT but can be ignored as no Jenkins is running the test # suite under windows on FAT partitions # ~0.01s resolution for NTFS # 0.001s for EXT4FS OS_STAT_MTIME_RESOLUTION = 1.0 def setUp(self): # Check the Nuxeo server test environment self.nuxeo_url = os.environ.get('NXDRIVE_TEST_NUXEO_URL') self.admin_user = os.environ.get('NXDRIVE_TEST_USER') self.password = os.environ.get('NXDRIVE_TEST_PASSWORD') if None in (self.nuxeo_url, self.admin_user, self.password): raise unittest.SkipTest( "No integration server configuration found in environment.") # Long timeout for the root client that is responsible for the test # environment set: this client is doing the first query on the Nuxeo # server and might need to wait for a long time without failing for # Nuxeo to finish initialize the repo on the first request after # startup root_remote_client = RemoteDocumentClient( self.nuxeo_url, self.admin_user, u'nxdrive-test-administrator-device', password=self.password, base_folder=u'/', timeout=60) # Call the Nuxeo operation to setup the integration test environment credentials = root_remote_client.execute( "NuxeoDrive.SetupIntegrationTests", userNames="user_1, user_2") credentials = [c.strip().split(u":") for c in credentials.split(u",")] self.user_1, self.password_1 = credentials[0] self.user_2, self.password_2 = credentials[1] ws_info = root_remote_client.fetch(self.TEST_WORKSPACE_PATH) self.workspace = ws_info[u'uid'] self.workspace_title = ws_info[u'title'] # Document client to be used to create remote test documents # and folders self.upload_tmp_dir = tempfile.mkdtemp(u'-nxdrive-uploads') remote_document_client_1 = RemoteDocumentClient( self.nuxeo_url, self.user_1, u'nxdrive-test-device-1', password=self.password_1, base_folder=self.workspace, upload_tmp_dir=self.upload_tmp_dir) remote_document_client_2 = RemoteDocumentClient( self.nuxeo_url, self.user_2, u'nxdrive-test-device-2', password=self.password_2, base_folder=self.workspace, upload_tmp_dir=self.upload_tmp_dir) # File system client to be used to create remote test documents # and folders remote_file_system_client_1 = RemoteFileSystemClient( self.nuxeo_url, self.user_1, u'nxdrive-test-device-1', password=self.password_1, upload_tmp_dir=self.upload_tmp_dir) remote_file_system_client_2 = RemoteFileSystemClient( self.nuxeo_url, self.user_2, u'nxdrive-test-device-2', password=self.password_2, upload_tmp_dir=self.upload_tmp_dir) # Check the local filesystem test environment self.local_test_folder_1 = tempfile.mkdtemp(u'-nxdrive-tests-user-1') self.local_test_folder_2 = tempfile.mkdtemp(u'-nxdrive-tests-user-2') self.local_nxdrive_folder_1 = os.path.join( self.local_test_folder_1, u'Nuxeo Drive') os.mkdir(self.local_nxdrive_folder_1) self.local_nxdrive_folder_2 = os.path.join( self.local_test_folder_2, u'Nuxeo Drive') os.mkdir(self.local_nxdrive_folder_2) self.nxdrive_conf_folder_1 = os.path.join( self.local_test_folder_1, u'nuxeo-drive-conf') os.mkdir(self.nxdrive_conf_folder_1) self.nxdrive_conf_folder_2 = os.path.join( self.local_test_folder_2, u'nuxeo-drive-conf') os.mkdir(self.nxdrive_conf_folder_2) # Set echo to True to enable SQL statements logging self.controller_1 = Controller(self.nxdrive_conf_folder_1, echo=False) self.controller_2 = Controller(self.nxdrive_conf_folder_2, echo=False) self.root_remote_client = root_remote_client self.remote_document_client_1 = remote_document_client_1 self.remote_document_client_2 = remote_document_client_2 self.remote_file_system_client_1 = remote_file_system_client_1 self.remote_file_system_client_2 = remote_file_system_client_2 def tearDown(self): self.controller_1.unbind_all() self.controller_2.unbind_all() self.remote_document_client_1.revoke_token() self.remote_document_client_2.revoke_token() # Don't need to revoke tokens for the file system remote clients # since they use the same users as the remote document clients self.root_remote_client.execute(u"NuxeoDrive.TearDownIntegrationTests") self.root_remote_client.revoke_token() if os.path.exists(self.upload_tmp_dir): shutil.rmtree(safe_long_path(self.upload_tmp_dir)) if os.path.exists(self.local_test_folder_1): self.controller_1.dispose() shutil.rmtree(safe_long_path(self.local_test_folder_1)) if os.path.exists(self.local_test_folder_2): self.controller_2.dispose() shutil.rmtree(safe_long_path(self.local_test_folder_2)) def get_all_states(self, session=None): """Utility to quickly introspect the current known states""" if session is None: session = self.controller_1.get_session() pairs = session.query(LastKnownState).order_by( LastKnownState.local_path, LastKnownState.remote_parent_path, LastKnownState.remote_name).all() return [(p.local_path, p.local_state, p.remote_state) for p in pairs] def make_server_tree(self): remote_client = self.remote_document_client_1 # create some folders on the server folder_1 = remote_client.make_folder(self.workspace, u'Folder 1') folder_1_1 = remote_client.make_folder(folder_1, u'Folder 1.1') folder_1_2 = remote_client.make_folder(folder_1, u'Folder 1.2') folder_2 = remote_client.make_folder(self.workspace, u'Folder 2') # create some files on the server remote_client.make_file(folder_2, u'Duplicated File.txt', content=b"Some content.") remote_client.make_file(folder_2, u'Duplicated File.txt', content=b"Other content.") remote_client.make_file(folder_1, u'File 1.txt', content=b"aaa") remote_client.make_file(folder_1_1, u'File 2.txt', content=b"bbb") remote_client.make_file(folder_1_2, u'File 3.txt', content=b"ccc") remote_client.make_file(folder_2, u'File 4.txt', content=b"ddd") remote_client.make_file(self.workspace, u'File 5.txt', content=b"eee") def wait(self): self.root_remote_client.wait()
def setUp(self): # Check the Nuxeo server test environment self.nuxeo_url = os.environ.get('NXDRIVE_TEST_NUXEO_URL') self.admin_user = os.environ.get('NXDRIVE_TEST_USER') self.password = os.environ.get('NXDRIVE_TEST_PASSWORD') if None in (self.nuxeo_url, self.admin_user, self.password): raise unittest.SkipTest( "No integration server configuration found in environment.") # Long timeout for the root client that is responsible for the test # environment set: this client is doing the first query on the Nuxeo # server and might need to wait for a long time without failing for # Nuxeo to finish initialize the repo on the first request after # startup root_remote_client = RemoteDocumentClient( self.nuxeo_url, self.admin_user, u'nxdrive-test-administrator-device', password=self.password, base_folder=u'/', timeout=60) # Call the Nuxeo operation to setup the integration test environment credentials = root_remote_client.execute( "NuxeoDrive.SetupIntegrationTests", userNames="user_1, user_2") credentials = [c.strip().split(u":") for c in credentials.split(u",")] self.user_1, self.password_1 = credentials[0] self.user_2, self.password_2 = credentials[1] ws_info = root_remote_client.fetch(self.TEST_WORKSPACE_PATH) self.workspace = ws_info[u'uid'] self.workspace_title = ws_info[u'title'] # Document client to be used to create remote test documents # and folders self.upload_tmp_dir = tempfile.mkdtemp(u'-nxdrive-uploads') remote_document_client_1 = RemoteDocumentClient( self.nuxeo_url, self.user_1, u'nxdrive-test-device-1', password=self.password_1, base_folder=self.workspace, upload_tmp_dir=self.upload_tmp_dir) remote_document_client_2 = RemoteDocumentClient( self.nuxeo_url, self.user_2, u'nxdrive-test-device-2', password=self.password_2, base_folder=self.workspace, upload_tmp_dir=self.upload_tmp_dir) # File system client to be used to create remote test documents # and folders remote_file_system_client_1 = RemoteFileSystemClient( self.nuxeo_url, self.user_1, u'nxdrive-test-device-1', password=self.password_1, upload_tmp_dir=self.upload_tmp_dir) remote_file_system_client_2 = RemoteFileSystemClient( self.nuxeo_url, self.user_2, u'nxdrive-test-device-2', password=self.password_2, upload_tmp_dir=self.upload_tmp_dir) # Check the local filesystem test environment self.local_test_folder_1 = tempfile.mkdtemp(u'-nxdrive-tests-user-1') self.local_test_folder_2 = tempfile.mkdtemp(u'-nxdrive-tests-user-2') self.local_nxdrive_folder_1 = os.path.join( self.local_test_folder_1, u'Nuxeo Drive') os.mkdir(self.local_nxdrive_folder_1) self.local_nxdrive_folder_2 = os.path.join( self.local_test_folder_2, u'Nuxeo Drive') os.mkdir(self.local_nxdrive_folder_2) self.nxdrive_conf_folder_1 = os.path.join( self.local_test_folder_1, u'nuxeo-drive-conf') os.mkdir(self.nxdrive_conf_folder_1) self.nxdrive_conf_folder_2 = os.path.join( self.local_test_folder_2, u'nuxeo-drive-conf') os.mkdir(self.nxdrive_conf_folder_2) # Set echo to True to enable SQL statements logging self.controller_1 = Controller(self.nxdrive_conf_folder_1, echo=False) self.controller_2 = Controller(self.nxdrive_conf_folder_2, echo=False) self.root_remote_client = root_remote_client self.remote_document_client_1 = remote_document_client_1 self.remote_document_client_2 = remote_document_client_2 self.remote_file_system_client_1 = remote_file_system_client_1 self.remote_file_system_client_2 = remote_file_system_client_2
class IntegrationTestCase(unittest.TestCase): TEST_WORKSPACE_PATH = ( u'/default-domain/workspaces/nuxeo-drive-test-workspace') FS_ITEM_ID_PREFIX = u'defaultFileSystemItemFactory#default#' EMPTY_DIGEST = hashlib.md5().hexdigest() SOME_TEXT_CONTENT = b"Some text content." SOME_TEXT_DIGEST = hashlib.md5(SOME_TEXT_CONTENT).hexdigest() # 1s time resolution because of the datetime resolution of MYSQL AUDIT_CHANGE_FINDER_TIME_RESOLUTION = 1.0 # 1s resolution on HFS+ on OSX # 2s resolution on FAT but can be ignored as no Jenkins is running the test # suite under windows on FAT partitions # ~0.01s resolution for NTFS # 0.001s for EXT4FS OS_STAT_MTIME_RESOLUTION = 1.0 # Nuxeo max length for document name DOC_NAME_MAX_LENGTH = 24 def _synchronize(self, syn, delay=0.1, loops=1): time.sleep(self.AUDIT_CHANGE_FINDER_TIME_RESOLUTION) self.wait() syn.loop(delay=delay, max_loops=loops) def setUp(self): # Check the Nuxeo server test environment self.nuxeo_url = os.environ.get('NXDRIVE_TEST_NUXEO_URL') self.admin_user = os.environ.get('NXDRIVE_TEST_USER') self.password = os.environ.get('NXDRIVE_TEST_PASSWORD') # Take default parameter if none has been set if self.nuxeo_url is None: self.nuxeo_url = "http://localhost:8080/nuxeo" if self.admin_user is None: self.admin_user = "******" if self.password is None: self.password = "******" if None in (self.nuxeo_url, self.admin_user, self.password): raise unittest.SkipTest( "No integration server configuration found in environment.") # Check the local filesystem test environment self.local_test_folder_1 = tempfile.mkdtemp(u'-nxdrive-tests-user-1') self.local_test_folder_2 = tempfile.mkdtemp(u'-nxdrive-tests-user-2') self.local_nxdrive_folder_1 = os.path.join(self.local_test_folder_1, u'Nuxeo Drive') os.mkdir(self.local_nxdrive_folder_1) self.local_nxdrive_folder_2 = os.path.join(self.local_test_folder_2, u'Nuxeo Drive') os.mkdir(self.local_nxdrive_folder_2) self.nxdrive_conf_folder_1 = os.path.join(self.local_test_folder_1, u'nuxeo-drive-conf') os.mkdir(self.nxdrive_conf_folder_1) self.nxdrive_conf_folder_2 = os.path.join(self.local_test_folder_2, u'nuxeo-drive-conf') os.mkdir(self.nxdrive_conf_folder_2) # Set echo to True to enable SQL statements and transactions logging # and echo_pool to True to enable connection pool logging self.controller_1 = Controller(self.nxdrive_conf_folder_1, echo=False, echo_pool=False) self.controller_2 = Controller(self.nxdrive_conf_folder_2, echo=False, echo_pool=False) self.controller_1.synchronizer.test_delay = 3 self.controller_2.synchronizer.test_delay = 3 self.version = self.controller_1.get_version() # Long timeout for the root client that is responsible for the test # environment set: this client is doing the first query on the Nuxeo # server and might need to wait for a long time without failing for # Nuxeo to finish initialize the repo on the first request after # startup root_remote_client = RemoteDocumentClient( self.nuxeo_url, self.admin_user, u'nxdrive-test-administrator-device', self.version, password=self.password, base_folder=u'/', timeout=60) # Call the Nuxeo operation to setup the integration test environment credentials = root_remote_client.execute( "NuxeoDrive.SetupIntegrationTests", userNames="user_1, user_2", permission='ReadWrite') credentials = [c.strip().split(u":") for c in credentials.split(u",")] self.user_1, self.password_1 = credentials[0] self.user_2, self.password_2 = credentials[1] ws_info = root_remote_client.fetch(self.TEST_WORKSPACE_PATH) self.workspace = ws_info[u'uid'] self.workspace_title = ws_info[u'title'] # Document client to be used to create remote test documents # and folders self.upload_tmp_dir = tempfile.mkdtemp(u'-nxdrive-uploads') remote_document_client_1 = RemoteDocumentClient( self.nuxeo_url, self.user_1, u'nxdrive-test-device-1', self.version, password=self.password_1, base_folder=self.workspace, upload_tmp_dir=self.upload_tmp_dir) remote_document_client_2 = RemoteDocumentClient( self.nuxeo_url, self.user_2, u'nxdrive-test-device-2', self.version, password=self.password_2, base_folder=self.workspace, upload_tmp_dir=self.upload_tmp_dir) # File system client to be used to create remote test documents # and folders remote_file_system_client_1 = RemoteFileSystemClient( self.nuxeo_url, self.user_1, u'nxdrive-test-device-1', self.version, password=self.password_1, upload_tmp_dir=self.upload_tmp_dir) remote_file_system_client_2 = RemoteFileSystemClient( self.nuxeo_url, self.user_2, u'nxdrive-test-device-2', self.version, password=self.password_2, upload_tmp_dir=self.upload_tmp_dir) self.root_remote_client = root_remote_client self.remote_document_client_1 = remote_document_client_1 self.remote_document_client_2 = remote_document_client_2 self.remote_file_system_client_1 = remote_file_system_client_1 self.remote_file_system_client_2 = remote_file_system_client_2 def tearDown(self): # Force to clean all observers for observer in self.controller_1.synchronizer.observers: observer.stop() observer.join() del observer self.controller_1.synchronizer.observers = [] for observer in self.controller_2.synchronizer.observers: observer.stop() observer.join() del observer self.controller_2.synchronizer.observers = [] # Note that unbinding a server revokes the related token if needed, # see Controller.unbind_server() self.controller_1.unbind_all() self.controller_2.unbind_all() # Don't need to revoke tokens for the file system remote clients # since they use the same users as the remote document clients self.root_remote_client.execute("NuxeoDrive.TearDownIntegrationTests") if os.path.exists(self.upload_tmp_dir): shutil.rmtree(safe_long_path(self.upload_tmp_dir)) if os.path.exists(self.local_test_folder_1): self.controller_1.dispose() try: shutil.rmtree(safe_long_path(self.local_test_folder_1)) except: pass if os.path.exists(self.local_test_folder_2): self.controller_2.dispose() try: shutil.rmtree(safe_long_path(self.local_test_folder_2)) except: pass def get_all_states(self, session=None): """Utility to quickly introspect the current known states""" if session is None: session = self.controller_1.get_session() pairs = session.query(LastKnownState).order_by( LastKnownState.local_path, LastKnownState.remote_parent_path, LastKnownState.remote_name).all() return [(p.local_path, p.local_state, p.remote_state) for p in pairs] def make_server_tree(self): remote_client = self.remote_document_client_1 # create some folders on the server folder_1 = remote_client.make_folder(self.workspace, u'Folder 1') folder_1_1 = remote_client.make_folder(folder_1, u'Folder 1.1') folder_1_2 = remote_client.make_folder(folder_1, u'Folder 1.2') folder_2 = remote_client.make_folder(self.workspace, u'Folder 2') # create some files on the server remote_client.make_file(folder_2, u'Duplicated File.txt', content=b"Some content.") remote_client.make_file(folder_2, u'Duplicated File.txt', content=b"Other content.") remote_client.make_file(folder_1, u'File 1.txt', content=b"aaa") remote_client.make_file(folder_1_1, u'File 2.txt', content=b"bbb") remote_client.make_file(folder_1_2, u'File 3.txt', content=b"ccc") remote_client.make_file(folder_2, u'File 4.txt', content=b"ddd") remote_client.make_file(self.workspace, u'File 5.txt', content=b"eee") def init_default_drive(self): # 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) # Launch first synchronization time.sleep(self.AUDIT_CHANGE_FINDER_TIME_RESOLUTION) self.wait() syn = ctl.synchronizer syn.loop(delay=0.1, max_loops=1) # Get local and remote clients local = LocalClient( os.path.join(self.local_nxdrive_folder_1, self.workspace_title)) remote = self.remote_document_client_1 return syn, local, remote def wait(self): self.root_remote_client.wait()