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_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_streaming_upload(self):
        remote_client = self.remote_document_client_1

        # Create a document by streaming a text file
        file_path = remote_client.make_tmp_file("Some content.")
        doc_ref = remote_client.stream_file(self.workspace,
                                  'Streamed text file', file_path,
                                  filename='My streamed file.txt')
        self.assertEquals(remote_client.get_info(doc_ref).name,
                          'Streamed text file')
        self.assertEquals(remote_client.get_content(doc_ref), "Some content.")

        # Update a document by streaming a new text file
        file_path = remote_client.make_tmp_file("Other content.")
        remote_client.stream_update(doc_ref, file_path,
                                    filename='My updated file.txt')
        self.assertEquals(remote_client.get_content(doc_ref), "Other content.")

        # Create a document by streaming a binary file
        file_path = os.path.join(self.upload_tmp_dir, 'testFile.pdf')
        copyfile('nxdrive/tests/resources/testFile.pdf', file_path)
        doc_ref = remote_client.stream_file(self.workspace,
                                  'Streamed binary file', file_path)
        local_client = LocalClient(self.upload_tmp_dir)
        doc_info = remote_client.get_info(doc_ref)
        self.assertEquals(doc_info.name, 'Streamed binary file')
        self.assertEquals(doc_info.digest,
                          local_client.get_info('/testFile.pdf').get_digest())
Exemple #4
0
    def test_streaming_upload(self):
        remote_client = self.remote_document_client_1

        # Create a document by streaming a text file
        file_path = remote_client.make_tmp_file("Some content.")
        try:
            doc_ref = remote_client.stream_file(self.workspace, 'Streamed text file', file_path,
                                                filename='My streamed file.txt')
        finally:
            os.remove(file_path)
        self.assertEqual(remote_client.get_info(doc_ref).name,
                         'Streamed text file')
        self.assertEqual(remote_client.get_content(doc_ref), "Some content.")

        # Update a document by streaming a new text file
        file_path = remote_client.make_tmp_file("Other content.")
        try:
            remote_client.stream_update(doc_ref, file_path, filename='My updated file.txt')
        finally:
            os.remove(file_path)
        self.assertEqual(remote_client.get_content(doc_ref), "Other content.")

        # Create a document by streaming a binary file
        file_path = os.path.join(self.upload_tmp_dir, 'testFile.pdf')
        copyfile(self.location + '/resources/testFile.pdf', file_path)
        doc_ref = remote_client.stream_file(self.workspace,
                                  'Streamed binary file', file_path)
        local_client = LocalClient(self.upload_tmp_dir)
        doc_info = remote_client.get_info(doc_ref)
        self.assertEqual(doc_info.name, 'Streamed binary file')
        self.assertEqual(doc_info.digest_algorithm, 'md5')
        self.assertEqual(doc_info.digest,
                         local_client.get_info('/testFile.pdf').get_digest())
    def test_streaming_upload(self):
        remote_client = self.remote_file_system_client_1

        # Create a document by streaming a text file
        file_path = remote_client.make_tmp_file("Some content.")
        try:
            fs_item_info = remote_client.stream_file(self.workspace_id, file_path, filename='My streamed file.txt')
        finally:
            os.remove(file_path)
        fs_item_id = fs_item_info.uid
        self.assertEquals(fs_item_info.name,
                        'My streamed file.txt')
        self.assertEquals(remote_client.get_content(fs_item_id),
                          "Some content.")

        # Update a document by streaming a new text file
        file_path = remote_client.make_tmp_file("Other content.")
        try:
            fs_item_info = remote_client.stream_update(fs_item_id, file_path, filename='My updated file.txt')
        finally:
            os.remove(file_path)
        self.assertEqual(fs_item_info.uid, fs_item_id)
        self.assertEquals(fs_item_info.name,
                        'My updated file.txt')
        self.assertEquals(remote_client.get_content(fs_item_id),
                          "Other content.")

        # Create a document by streaming a binary file
        file_path = os.path.join(self.upload_tmp_dir, 'testFile.pdf')
        copyfile('nxdrive/tests/resources/testFile.pdf', file_path)
        fs_item_info = remote_client.stream_file(self.workspace_id, file_path)
        local_client = LocalClient(self.upload_tmp_dir)
        self.assertEquals(fs_item_info.name, 'testFile.pdf')
        self.assertEquals(fs_item_info.digest,
                          local_client.get_info('/testFile.pdf').get_digest())
    def test_streaming_upload(self):
        remote_client = self.remote_document_client_1

        # Create a document by streaming a text file
        file_path = remote_client.make_tmp_file("Some content.")
        doc_ref = remote_client.stream_file(
            self.workspace, "Streamed text file", file_path, filename="My streamed file.txt"
        )
        self.assertEquals(remote_client.get_info(doc_ref).name, "Streamed text file")
        self.assertEquals(remote_client.get_content(doc_ref), "Some content.")

        # Update a document by streaming a new text file
        file_path = remote_client.make_tmp_file("Other content.")
        remote_client.stream_update(doc_ref, file_path, filename="My updated file.txt")
        # As a workaround for https://jira.nuxeo.com/browse/NXP-10964,
        # wait for a while to ensure transaction is committed before
        # Blob response is serialized and sent to the client
        sleep(1.0)
        self.assertEquals(remote_client.get_content(doc_ref), "Other content.")

        # Create a document by streaming a binary file
        file_path = os.path.join(self.upload_tmp_dir, "testFile.pdf")
        copyfile("nxdrive/tests/resources/testFile.pdf", file_path)
        doc_ref = remote_client.stream_file(self.workspace, "Streamed binary file", file_path)
        local_client = LocalClient(self.upload_tmp_dir)
        doc_info = remote_client.get_info(doc_ref)
        self.assertEquals(doc_info.name, "Streamed binary file")
        self.assertEquals(doc_info.digest, local_client.get_info("/testFile.pdf").get_digest())
Exemple #7
0
    def _local_bind_root(self, server_binding, remote_info, nxclient, session):
        # Check that this workspace does not already exist locally
        # TODO: shall we handle deduplication for root names too?
        local_root = os.path.join(server_binding.local_folder,
                                  safe_filename(remote_info.name))
        repository = nxclient.repository
        if not os.path.exists(local_root):
            os.makedirs(local_root)
        lcclient = LocalClient(local_root)
        local_info = lcclient.get_info('/')

        try:
            existing_binding = session.query(RootBinding).filter_by(
                local_root=local_root,
            ).one()
            if (existing_binding.remote_repo != repository
                or existing_binding.remote_root != remote_info.uid):
                raise RuntimeError(
                    "%r is already bound to %r on repo %r of %r" % (
                        local_root,
                        existing_binding.remote_root,
                        existing_binding.remote_repo,
                        existing_binding.server_binding.server_url))
        except NoResultFound:
            # Register the new binding itself
            log.info("Binding local root '%s' to '%s' (id=%s) on server '%s'",
                 local_root, remote_info.name, remote_info.uid,
                     server_binding.server_url)
            session.add(RootBinding(local_root, repository, remote_info.uid))

            # Initialize the metadata info by recursive walk on the remote
            # folder structure
            self._recursive_init(lcclient, local_info, nxclient, remote_info)
        session.commit()
Exemple #8
0
    def test_streaming_upload(self):
        remote_client = self.remote_file_system_client_1

        # Create a document by streaming a text file
        file_path = remote_client.make_tmp_file("Some content.")
        try:
            fs_item_info = remote_client.stream_file(
                self.workspace_id, file_path, filename='My streamed file.txt')
        finally:
            os.remove(file_path)
        fs_item_id = fs_item_info.uid
        self.assertEquals(fs_item_info.name, 'My streamed file.txt')
        self.assertEquals(remote_client.get_content(fs_item_id),
                          "Some content.")

        # Update a document by streaming a new text file
        file_path = remote_client.make_tmp_file("Other content.")
        try:
            fs_item_info = remote_client.stream_update(
                fs_item_id, file_path, filename='My updated file.txt')
        finally:
            os.remove(file_path)
        self.assertEqual(fs_item_info.uid, fs_item_id)
        self.assertEquals(fs_item_info.name, 'My updated file.txt')
        self.assertEquals(remote_client.get_content(fs_item_id),
                          "Other content.")

        # Create a document by streaming a binary file
        file_path = os.path.join(self.upload_tmp_dir, 'testFile.pdf')
        copyfile('nxdrive/tests/resources/testFile.pdf', file_path)
        fs_item_info = remote_client.stream_file(self.workspace_id, file_path)
        local_client = LocalClient(self.upload_tmp_dir)
        self.assertEquals(fs_item_info.name, 'testFile.pdf')
        self.assertEquals(fs_item_info.digest,
                          local_client.get_info('/testFile.pdf').get_digest())
    def test_bad_mime_type(self):
        remote_client = self.remote_file_system_client_1

        # Create a document by streaming a binary file
        file_path = os.path.join(self.upload_tmp_dir, "testFile.pdf")
        copyfile("nxdrive/tests/resources/testFile.pdf", file_path)
        fs_item_id = remote_client.stream_file(self.workspace_id, file_path, mime_type="pdf")
        local_client = LocalClient(self.upload_tmp_dir)
        fs_item_info = remote_client.get_info(fs_item_id)
        self.assertEquals(fs_item_info.name, "testFile.pdf")
        self.assertEquals(fs_item_info.digest, local_client.get_info("/testFile.pdf").get_digest())
Exemple #10
0
    def test_bad_mime_type(self):
        remote_client = self.remote_file_system_client_1

        # Create a document by streaming a binary file
        file_path = os.path.join(self.upload_tmp_dir, 'testFile.pdf')
        copyfile(self.location + '/resources/testFile.pdf', file_path)
        fs_item_info = remote_client.stream_file(self.workspace_id, file_path,
                                               mime_type='pdf')
        local_client = LocalClient(self.upload_tmp_dir)
        self.assertEqual(fs_item_info.name, 'testFile.pdf')
        self.assertEqual(fs_item_info.digest,
                         local_client.get_info('/testFile.pdf').get_digest())
Exemple #11
0
    def _add_top_level_state(self, server_binding, session):
        local_client = LocalClient(server_binding.local_folder)
        local_info = local_client.get_info(u'/')

        remote_client = self.get_remote_fs_client(server_binding)
        remote_info = remote_client.get_filesystem_root_info()

        state = LastKnownState(server_binding.local_folder,
                               local_info=local_info,
                               local_state='synchronized',
                               remote_info=remote_info,
                               remote_state='synchronized')
        session.add(state)
Exemple #12
0
    def _add_top_level_state(self, server_binding, session):
        local_client = LocalClient(server_binding.local_folder)
        local_info = local_client.get_info(u'/')

        remote_client = self.get_remote_fs_client(server_binding)
        remote_info = remote_client.get_filesystem_root_info()

        state = LastKnownState(server_binding.local_folder,
                               local_info=local_info,
                               local_state='synchronized',
                               remote_info=remote_info,
                               remote_state='synchronized')
        session.add(state)
Exemple #13
0
    def test_bad_mime_type(self):
        remote_client = self.remote_document_client_1

        # Create a document by streaming a binary file
        file_path = os.path.join(self.upload_tmp_dir, 'testFile.pdf')
        copyfile(self.location + '/resources/testFile.pdf', file_path)
        doc_ref = remote_client.stream_file(self.workspace,
                                  'Streamed binary file',
                                  file_path, mime_type='pdf')
        local_client = LocalClient(self.upload_tmp_dir)
        doc_info = remote_client.get_info(doc_ref)
        self.assertEqual(doc_info.name, 'Streamed binary file')
        self.assertEqual(doc_info.digest,
                         local_client.get_info('/testFile.pdf').get_digest(digest_func=doc_info.digest_algorithm))
    def test_bad_mime_type(self):
        remote_client = self.remote_document_client_1

        # Create a document by streaming a binary file
        file_path = os.path.join(self.upload_tmp_dir, 'testFile.pdf')
        copyfile('nxdrive/tests/resources/testFile.pdf', file_path)
        doc_ref = remote_client.stream_file(self.workspace,
                                  'Streamed binary file',
                                  file_path, mime_type='pdf')
        local_client = LocalClient(self.upload_tmp_dir)
        doc_info = remote_client.get_info(doc_ref)
        self.assertEquals(doc_info.name, 'Streamed binary file')
        self.assertEquals(doc_info.digest,
                          local_client.get_info('/testFile.pdf').get_digest())
    def test_bad_mime_type(self):
        remote_client = self.remote_document_client_1

        # Create a document by streaming a binary file
        file_path = os.path.join(self.upload_tmp_dir, 'testFile.pdf')
        copyfile('nxdrive/tests/resources/testFile.pdf', file_path)
        doc_ref = remote_client.stream_file(self.workspace,
                                  'Streamed binary file',
                                  file_path, mime_type='pdf')
        # Wait to make sure transaction is commited
        # TODO: remove when https://jira.nuxeo.com/browse/NXP-10964 is
        # fixed
        sleep(1.0)
        local_client = LocalClient(self.upload_tmp_dir)
        doc_info = remote_client.get_info(doc_ref)
        self.assertEquals(doc_info.name, 'Streamed binary file')
        self.assertEquals(doc_info.digest,
                          local_client.get_info('/testFile.pdf').get_digest())
    def test_bad_mime_type(self):
        remote_client = self.remote_document_client_1

        # Create a document by streaming a binary file
        file_path = os.path.join(self.upload_tmp_dir, 'testFile.pdf')
        copyfile('nxdrive/tests/resources/testFile.pdf', file_path)
        doc_ref = remote_client.stream_file(self.workspace,
                                            'Streamed binary file',
                                            file_path,
                                            mime_type='pdf')
        # Wait to make sure transaction is commited
        # TODO: remove when https://jira.nuxeo.com/browse/NXP-10964 is
        # fixed
        sleep(1.0)
        local_client = LocalClient(self.upload_tmp_dir)
        doc_info = remote_client.get_info(doc_ref)
        self.assertEquals(doc_info.name, 'Streamed binary file')
        self.assertEquals(doc_info.digest,
                          local_client.get_info('/testFile.pdf').get_digest())
    def test_streaming_upload(self):
        remote_client = self.remote_document_client_1

        # Create a document by streaming a text file
        file_path = remote_client.make_tmp_file("Some content.")
        doc_ref = remote_client.stream_file(self.workspace,
                                            'Streamed text file',
                                            file_path,
                                            filename='My streamed file.txt')
        # Wait to make sure transaction is commited
        # TODO: remove when https://jira.nuxeo.com/browse/NXP-10964 is
        # fixed
        sleep(1.0)
        self.assertEquals(
            remote_client.get_info(doc_ref).name, 'Streamed text file')
        self.assertEquals(remote_client.get_content(doc_ref), "Some content.")

        # Update a document by streaming a new text file
        file_path = remote_client.make_tmp_file("Other content.")
        remote_client.stream_update(doc_ref,
                                    file_path,
                                    filename='My updated file.txt')
        # As a workaround for https://jira.nuxeo.com/browse/NXP-10964,
        # wait for a while to ensure transaction is committed before
        # Blob response is serialized and sent to the client
        sleep(1.0)
        self.assertEquals(remote_client.get_content(doc_ref), "Other content.")

        # Create a document by streaming a binary file
        file_path = os.path.join(self.upload_tmp_dir, 'testFile.pdf')
        copyfile('nxdrive/tests/resources/testFile.pdf', file_path)
        doc_ref = remote_client.stream_file(self.workspace,
                                            'Streamed binary file', file_path)
        # Wait to make sure transaction is commited
        # TODO: remove when https://jira.nuxeo.com/browse/NXP-10964 is
        # fixed
        sleep(1.0)
        local_client = LocalClient(self.upload_tmp_dir)
        doc_info = remote_client.get_info(doc_ref)
        self.assertEquals(doc_info.name, 'Streamed binary file')
        self.assertEquals(doc_info.digest,
                          local_client.get_info('/testFile.pdf').get_digest())
    def test_streaming_upload(self):
        remote_client = self.remote_file_system_client_1

        # Create a document by streaming a text file
        file_path = remote_client.make_tmp_file("Some content.")
        fs_item_id = remote_client.stream_file(self.workspace_id, file_path, filename="My streamed file.txt")
        self.assertEquals(remote_client.get_info(fs_item_id).name, "My streamed file.txt")
        self.assertEquals(remote_client.get_content(fs_item_id), "Some content.")

        # Update a document by streaming a new text file
        file_path = remote_client.make_tmp_file("Other content.")
        remote_client.stream_update(fs_item_id, file_path, filename="My updated file.txt")
        self.assertEquals(remote_client.get_info(fs_item_id).name, "My updated file.txt")
        self.assertEquals(remote_client.get_content(fs_item_id), "Other content.")

        # Create a document by streaming a binary file
        file_path = os.path.join(self.upload_tmp_dir, "testFile.pdf")
        copyfile("nxdrive/tests/resources/testFile.pdf", file_path)
        fs_item_id = remote_client.stream_file(self.workspace_id, file_path)
        local_client = LocalClient(self.upload_tmp_dir)
        fs_item_info = remote_client.get_info(fs_item_id)
        self.assertEquals(fs_item_info.name, "testFile.pdf")
        self.assertEquals(fs_item_info.digest, local_client.get_info("/testFile.pdf").get_digest())
    def test_concurrent_file_access(self):
        """Test update/deletion of a locally locked file.

        This is to simulate downstream synchronization of a file opened (thus
        locked) by any program under Windows, typically MS Word.
        The file should be blacklisted and not prevent synchronization of other
        pending items.
        Once the file is unlocked and the cooldown period is over it should be
        synchronized.
        """
        # 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 file in the remote root workspace
        remote.make_file('/', 'test_update.docx', 'Some content to update.')
        remote.make_file('/', 'test_delete.docx', 'Some content to delete.')

        # Launch first synchronization
        syn = ctl.synchronizer
        self._synchronize(syn)
        self.assertTrue(local.exists('/test_update.docx'))
        self.assertTrue(local.exists('/test_delete.docx'))

        # Open locally synchronized files to lock them and generate a
        # WindowsError when trying to update / delete them
        file1_path = local.get_info('/test_update.docx').filepath
        file1_desc = open(file1_path, 'rb')
        file2_path = local.get_info('/test_delete.docx').filepath
        file2_desc = open(file2_path, 'rb')

        # Update /delete existing remote files and create a new remote file
        remote.update_content('/test_update.docx', 'Updated content.')
        remote.delete('/test_delete.docx')
        remote.make_file('/', 'other.docx', 'Other content.')

        # Synchronize
        self._synchronize(syn)
        if sys.platform == 'win32':
            # As local file are locked, a WindowsError should occur during the
            # local update process, therefore:
            # - Temporary download file (.part) should be created locally but
            #   not renamed
            # - Opened local files should still exist and not have been
            #   modified
            # - Synchronization should not fail: doc pairs should be
            #   blacklisted, there should be 2 pending items and other remote
            #   modifications should be locally synchronized
            self.assertTrue(local.exists('/.test_update.docx.part'))
            self.assertTrue(local.exists('/test_update.docx'))
            self.assertEquals(local.get_content('/test_update.docx'),
                              'Some content to update.')
            self.assertTrue(local.exists('/test_delete.docx'))
            self.assertEquals(local.get_content('/test_delete.docx'),
                              'Some content to delete.')
            self.assertEquals(len(ctl.list_pending()), 2)
            self.assertTrue(local.exists('/other.docx'))
            self.assertEquals(local.get_content('/other.docx'),
                              'Other content.')

            # Synchronize again
            syn.loop(delay=0.1, max_loops=1)
            # Blacklisted files should be ignored as delay (300 seconds by
            # default) is not expired, nothing should have changed
            self.assertTrue(local.exists('/.test_update.docx.part'))
            self.assertTrue(local.exists('/test_update.docx'))
            self.assertEquals(local.get_content('/test_update.docx'),
                              'Some content to update.')
            self.assertTrue(local.exists('/test_delete.docx'))
            self.assertEquals(local.get_content('/test_delete.docx'),
                              'Some content to delete.')
            self.assertEquals(len(ctl.list_pending()), 2)

            # Release file locks by closing them
            file1_desc.close()
            file2_desc.close()
            # Reduce error skip delay to retry synchronization of pairs in
            # error
            syn.error_skip_period = 1.0
            time.sleep(syn.error_skip_period)
            syn.loop(delay=0.1, max_loops=1)
            # Previously blacklisted files should be updated / deleted locally,
            # temporary download file should not be there anymore and there
            # should be no pending items left
            self.assertTrue(local.exists('/test_update.docx'))
            self.assertEquals(local.get_content('/test_update.docx'),
                              'Updated content.')
            self.assertFalse(local.exists('/.test_update.docx.part'))
            self.assertFalse(local.exists('/test_delete.docx'))
            self.assertEquals(len(ctl.list_pending()), 0)
        else:
            self.assertTrue(local.exists('/test_update.docx'))
            self.assertEquals(local.get_content('/test_update.docx'),
                              'Updated content.')
            self.assertFalse(local.exists('/.test_update.docx.part'))
            self.assertFalse(local.exists('/test_delete.docx'))
            self.assertEquals(len(ctl.list_pending()), 0)
Exemple #20
0
    def test_remote_rename_sync_root_folder(self):
        remote_client = self.remote_client_1
        local_client = LocalClient(self.local_nxdrive_folder_1)

        # Rename a sync root folder
        remote_client.rename(self.workspace_id,
                             u'Renamed Nuxeo Drive Test Workspace')
        self.assertEquals(
            remote_client.get_info(self.workspace_id).name,
            u'Renamed Nuxeo Drive Test Workspace')

        # Synchronize: only the sync root folder renaming is detected: all
        # the descendants are automatically realigned
        self.wait_sync(wait_for_async=True)

        # The client folder has been renamed
        self.assertFalse(local_client.exists(u'/Nuxeo Drive Test Workspace'))
        self.assertTrue(
            local_client.exists(u'/Renamed Nuxeo Drive Test Workspace'))

        renamed_workspace_path = os.path.join(
            self.local_nxdrive_folder_1, u'Renamed Nuxeo Drive Test Workspace')
        # The content of the renamed folder is left unchanged
        # Check child name
        self.assertTrue(
            local_client.exists(
                u'/Renamed Nuxeo Drive Test Workspace/Original File 1.txt'))
        file_1_local_info = local_client.get_info(
            u'/Renamed Nuxeo Drive Test Workspace/Original File 1.txt')
        file_1_parent_path = os.path.dirname(file_1_local_info.filepath)
        self.assertEquals(file_1_parent_path, renamed_workspace_path)
        # Check child state
        file_1_state = self._get_state(self.file_1_id)
        self.assertEquals(
            file_1_state.local_path,
            u'/Renamed Nuxeo Drive Test Workspace/Original File 1.txt')
        self.assertEquals(file_1_state.local_name, u'Original File 1.txt')

        # Check child name
        self.assertTrue(
            local_client.exists(
                u'/Renamed Nuxeo Drive Test Workspace/Original Folder 1'))
        folder_1_local_info = local_client.get_info(
            u'/Renamed Nuxeo Drive Test Workspace/Original Folder 1')
        folder_1_parent_path = os.path.dirname(folder_1_local_info.filepath)
        self.assertEquals(folder_1_parent_path, renamed_workspace_path)
        # Check child state
        folder_1_state = self._get_state(self.folder_1_id)
        self.assertEquals(
            folder_1_state.local_path,
            u'/Renamed Nuxeo Drive Test Workspace/Original Folder 1')
        self.assertEquals(folder_1_state.local_name, u'Original Folder 1')

        # Check child name
        self.assertTrue(
            local_client.exists(u'/Renamed Nuxeo Drive Test Workspace/'
                                u'Original Folder 1/Sub-Folder 1.1'))
        folder_1_1_local_info = local_client.get_info(
            u'/Renamed Nuxeo Drive Test Workspace/'
            u'Original Folder 1/Sub-Folder 1.1')
        folder_1_1_parent_path = os.path.dirname(
            folder_1_1_local_info.filepath)
        self.assertEquals(
            folder_1_1_parent_path,
            os.path.join(renamed_workspace_path, u'Original Folder 1'))
        # Check child state
        folder_1_1_state = self._get_state(self.folder_1_1_id)
        self.assertEquals(
            folder_1_1_state.local_path, u'/Renamed Nuxeo Drive Test Workspace'
            '/Original Folder 1/Sub-Folder 1.1')
        self.assertEquals(folder_1_1_state.local_name, u'Sub-Folder 1.1')

        # Check child name
        self.assertTrue(
            local_client.exists(u'/Renamed Nuxeo Drive Test Workspace/'
                                u'Original Folder 1/Original File 1.1.txt'))
        file_1_1_local_info = local_client.get_info(
            u'/Renamed Nuxeo Drive Test Workspace/'
            'Original Folder 1/Original File 1.1.txt')
        file_1_1_parent_path = os.path.dirname(file_1_1_local_info.filepath)
        self.assertEquals(
            file_1_1_parent_path,
            os.path.join(renamed_workspace_path, u'Original Folder 1'))
        # Check child state
        file_1_1_state = self._get_state(self.file_1_1_id)
        self.assertEquals(
            file_1_1_state.local_path, u'/Renamed Nuxeo Drive Test Workspace'
            '/Original Folder 1/Original File 1.1.txt')
        self.assertEquals(file_1_1_state.local_name, u'Original File 1.1.txt')
    def test_remote_rename_sync_root_folder(self):
        remote_client = self.remote_client_1
        local_client = LocalClient(self.local_nxdrive_folder_1)

        # Rename a sync root folder
        remote_client.rename(self.workspace_id,
            u'Renamed Nuxeo Drive Test Workspace')
        self.assertEquals(remote_client.get_info(self.workspace_id).name,
            u'Renamed Nuxeo Drive Test Workspace')

        # Synchronize: only the sync root folder renaming is detected: all
        # the descendants are automatically realigned
        self.wait_sync(wait_for_async=True)

        # The client folder has been renamed
        self.assertFalse(local_client.exists(u'/Nuxeo Drive Test Workspace'))
        self.assertTrue(local_client.exists(
            u'/Renamed Nuxeo Drive Test Workspace'))

        renamed_workspace_path = os.path.join(self.local_nxdrive_folder_1,
            u'Renamed Nuxeo Drive Test Workspace')
        # The content of the renamed folder is left unchanged
        # Check child name
        self.assertTrue(local_client.exists(
            u'/Renamed Nuxeo Drive Test Workspace/Original File 1.txt'))
        file_1_local_info = local_client.get_info(
            u'/Renamed Nuxeo Drive Test Workspace/Original File 1.txt')
        file_1_parent_path = os.path.dirname(file_1_local_info.filepath)
        self.assertEquals(file_1_parent_path, renamed_workspace_path)
        # Check child state
        file_1_state = self._get_state(self.file_1_id)
        self.assertEquals(file_1_state.local_path,
            u'/Renamed Nuxeo Drive Test Workspace/Original File 1.txt')
        self.assertEquals(file_1_state.local_name, u'Original File 1.txt')

        # Check child name
        self.assertTrue(local_client.exists(
            u'/Renamed Nuxeo Drive Test Workspace/Original Folder 1'))
        folder_1_local_info = local_client.get_info(
            u'/Renamed Nuxeo Drive Test Workspace/Original Folder 1')
        folder_1_parent_path = os.path.dirname(folder_1_local_info.filepath)
        self.assertEquals(folder_1_parent_path, renamed_workspace_path)
        # Check child state
        folder_1_state = self._get_state(self.folder_1_id)
        self.assertEquals(folder_1_state.local_path,
            u'/Renamed Nuxeo Drive Test Workspace/Original Folder 1')
        self.assertEquals(folder_1_state.local_name, u'Original Folder 1')

        # Check child name
        self.assertTrue(local_client.exists(
            u'/Renamed Nuxeo Drive Test Workspace/'
            u'Original Folder 1/Sub-Folder 1.1'))
        folder_1_1_local_info = local_client.get_info(
            u'/Renamed Nuxeo Drive Test Workspace/'
            u'Original Folder 1/Sub-Folder 1.1')
        folder_1_1_parent_path = os.path.dirname(
            folder_1_1_local_info.filepath)
        self.assertEquals(folder_1_1_parent_path,
            os.path.join(renamed_workspace_path, u'Original Folder 1'))
        # Check child state
        folder_1_1_state = self._get_state(self.folder_1_1_id)
        self.assertEquals(folder_1_1_state.local_path,
            u'/Renamed Nuxeo Drive Test Workspace'
            '/Original Folder 1/Sub-Folder 1.1')
        self.assertEquals(folder_1_1_state.local_name, u'Sub-Folder 1.1')

        # Check child name
        self.assertTrue(local_client.exists(
            u'/Renamed Nuxeo Drive Test Workspace/'
            u'Original Folder 1/Original File 1.1.txt'))
        file_1_1_local_info = local_client.get_info(
            u'/Renamed Nuxeo Drive Test Workspace/'
            'Original Folder 1/Original File 1.1.txt')
        file_1_1_parent_path = os.path.dirname(file_1_1_local_info.filepath)
        self.assertEquals(file_1_1_parent_path,
            os.path.join(renamed_workspace_path, u'Original Folder 1'))
        # Check child state
        file_1_1_state = self._get_state(self.file_1_1_id)
        self.assertEquals(file_1_1_state.local_path,
                          u'/Renamed Nuxeo Drive Test Workspace'
                          '/Original Folder 1/Original File 1.1.txt')
        self.assertEquals(file_1_1_state.local_name, u'Original File 1.1.txt')
    def test_remote_rename_sync_root_folder(self):
        sb, ctl = self.sb_1, self.controller_1
        remote_client = self.remote_client_1
        local_client = LocalClient(self.local_nxdrive_folder_1)
        session = ctl.get_session()

        # Rename a sync root folder
        remote_client.rename(self.workspace_id,
            u'Renamed Nuxeo Drive Test Workspace')
        self.assertEquals(remote_client.get_info(self.workspace_id).name,
            u'Renamed Nuxeo Drive Test Workspace')

        # Synchronize: only the sync root folder renaming is detected: all
        # the descendants are automatically realigned
        time.sleep(self.AUDIT_CHANGE_FINDER_TIME_RESOLUTION)
        self.wait()
        self.assertEquals(ctl.synchronizer.update_synchronize_server(sb), 1)

        # The client folder has been renamed
        self.assertFalse(local_client.exists(u'/Nuxeo Drive Test Workspace'))
        self.assertTrue(local_client.exists(
            u'/Renamed Nuxeo Drive Test Workspace'))

        renamed_workspace_path = os.path.join(self.local_nxdrive_folder_1,
            u'Renamed Nuxeo Drive Test Workspace')
        # The content of the renamed folder is left unchanged
        # Check child name
        self.assertTrue(local_client.exists(
            u'/Renamed Nuxeo Drive Test Workspace/Original File 1.txt'))
        file_1_local_info = local_client.get_info(
            u'/Renamed Nuxeo Drive Test Workspace/Original File 1.txt')
        file_1_parent_path = os.path.dirname(file_1_local_info.filepath)
        self.assertEquals(file_1_parent_path, renamed_workspace_path)
        # Check child state
        file_1_state = session.query(LastKnownState).filter_by(
            remote_name=u'Original File 1.txt').one()
        self.assertEquals(file_1_state.local_path,
            u'/Renamed Nuxeo Drive Test Workspace/Original File 1.txt')
        self.assertEquals(file_1_state.local_name, u'Original File 1.txt')

        # Check child name
        self.assertTrue(local_client.exists(
            u'/Renamed Nuxeo Drive Test Workspace/Original Folder 1'))
        folder_1_local_info = local_client.get_info(
            u'/Renamed Nuxeo Drive Test Workspace/Original Folder 1')
        folder_1_parent_path = os.path.dirname(folder_1_local_info.filepath)
        self.assertEquals(folder_1_parent_path, renamed_workspace_path)
        # Check child state
        folder_1_state = session.query(LastKnownState).filter_by(
            remote_name=u'Original Folder 1').one()
        self.assertEquals(folder_1_state.local_path,
            u'/Renamed Nuxeo Drive Test Workspace/Original Folder 1')
        self.assertEquals(folder_1_state.local_name, u'Original Folder 1')

        # Check child name
        self.assertTrue(local_client.exists(
            u'/Renamed Nuxeo Drive Test Workspace/'
            u'Original Folder 1/Sub-Folder 1.1'))
        folder_1_1_local_info = local_client.get_info(
            u'/Renamed Nuxeo Drive Test Workspace/'
            u'Original Folder 1/Sub-Folder 1.1')
        folder_1_1_parent_path = os.path.dirname(
            folder_1_1_local_info.filepath)
        self.assertEquals(folder_1_1_parent_path,
            os.path.join(renamed_workspace_path, u'Original Folder 1'))
        # Check child state
        folder_1_1_state = session.query(LastKnownState).filter_by(
            remote_name=u'Sub-Folder 1.1').one()
        self.assertEquals(folder_1_1_state.local_path,
            u'/Renamed Nuxeo Drive Test Workspace'
            '/Original Folder 1/Sub-Folder 1.1')
        self.assertEquals(folder_1_1_state.local_name, u'Sub-Folder 1.1')

        # Check child name
        self.assertTrue(local_client.exists(
            u'/Renamed Nuxeo Drive Test Workspace/'
            u'Original Folder 1/Original File 1.1.txt'))
        file_1_1_local_info = local_client.get_info(
            u'/Renamed Nuxeo Drive Test Workspace/'
            'Original Folder 1/Original File 1.1.txt')
        file_1_1_parent_path = os.path.dirname(file_1_1_local_info.filepath)
        self.assertEquals(file_1_1_parent_path,
            os.path.join(renamed_workspace_path, u'Original Folder 1'))
        # Check child state
        file_1_1_state = session.query(LastKnownState).filter_by(
            remote_name=u'Original File 1.1.txt').one()
        self.assertEquals(file_1_1_state.local_path,
                          u'/Renamed Nuxeo Drive Test Workspace'
                          '/Original Folder 1/Original File 1.1.txt')
        self.assertEquals(file_1_1_state.local_name, u'Original File 1.1.txt')

        # The more things change, the more they remain the same.
        time.sleep(self.AUDIT_CHANGE_FINDER_TIME_RESOLUTION)
        self.wait()
        self.assertEquals(ctl.synchronizer.update_synchronize_server(sb), 0)
Exemple #23
0
    def test_remote_rename_sync_root_folder(self):
        sb, ctl = self.sb_1, self.controller_1
        remote_client = self.remote_client_1
        local_client = LocalClient(self.local_nxdrive_folder_1)
        session = ctl.get_session()

        # Rename a sync root folder
        remote_client.rename(self.workspace_id,
                             u'Renamed Nuxeo Drive Test Workspace')
        self.assertEquals(
            remote_client.get_info(self.workspace_id).name,
            u'Renamed Nuxeo Drive Test Workspace')

        # Synchronize: only the sync root folder renaming is detected: all
        # the descendants are automatically realigned
        self.wait_audit_change_finder_if_needed()
        self.wait()
        self.assertEquals(ctl.synchronizer.update_synchronize_server(sb), 1)

        # The client folder has been renamed
        self.assertFalse(local_client.exists(u'/Nuxeo Drive Test Workspace'))
        self.assertTrue(
            local_client.exists(u'/Renamed Nuxeo Drive Test Workspace'))

        renamed_workspace_path = os.path.join(
            self.local_nxdrive_folder_1, u'Renamed Nuxeo Drive Test Workspace')
        # The content of the renamed folder is left unchanged
        # Check child name
        self.assertTrue(
            local_client.exists(
                u'/Renamed Nuxeo Drive Test Workspace/Original File 1.txt'))
        file_1_local_info = local_client.get_info(
            u'/Renamed Nuxeo Drive Test Workspace/Original File 1.txt')
        file_1_parent_path = os.path.dirname(file_1_local_info.filepath)
        self.assertEquals(file_1_parent_path, renamed_workspace_path)
        # Check child state
        file_1_state = session.query(LastKnownState).filter_by(
            remote_name=u'Original File 1.txt').one()
        self.assertEquals(
            file_1_state.local_path,
            u'/Renamed Nuxeo Drive Test Workspace/Original File 1.txt')
        self.assertEquals(file_1_state.local_name, u'Original File 1.txt')

        # Check child name
        self.assertTrue(
            local_client.exists(
                u'/Renamed Nuxeo Drive Test Workspace/Original Folder 1'))
        folder_1_local_info = local_client.get_info(
            u'/Renamed Nuxeo Drive Test Workspace/Original Folder 1')
        folder_1_parent_path = os.path.dirname(folder_1_local_info.filepath)
        self.assertEquals(folder_1_parent_path, renamed_workspace_path)
        # Check child state
        folder_1_state = session.query(LastKnownState).filter_by(
            remote_name=u'Original Folder 1').one()
        self.assertEquals(
            folder_1_state.local_path,
            u'/Renamed Nuxeo Drive Test Workspace/Original Folder 1')
        self.assertEquals(folder_1_state.local_name, u'Original Folder 1')

        # Check child name
        self.assertTrue(
            local_client.exists(u'/Renamed Nuxeo Drive Test Workspace/'
                                u'Original Folder 1/Sub-Folder 1.1'))
        folder_1_1_local_info = local_client.get_info(
            u'/Renamed Nuxeo Drive Test Workspace/'
            u'Original Folder 1/Sub-Folder 1.1')
        folder_1_1_parent_path = os.path.dirname(
            folder_1_1_local_info.filepath)
        self.assertEquals(
            folder_1_1_parent_path,
            os.path.join(renamed_workspace_path, u'Original Folder 1'))
        # Check child state
        folder_1_1_state = session.query(LastKnownState).filter_by(
            remote_name=u'Sub-Folder 1.1').one()
        self.assertEquals(
            folder_1_1_state.local_path, u'/Renamed Nuxeo Drive Test Workspace'
            '/Original Folder 1/Sub-Folder 1.1')
        self.assertEquals(folder_1_1_state.local_name, u'Sub-Folder 1.1')

        # Check child name
        self.assertTrue(
            local_client.exists(u'/Renamed Nuxeo Drive Test Workspace/'
                                u'Original Folder 1/Original File 1.1.txt'))
        file_1_1_local_info = local_client.get_info(
            u'/Renamed Nuxeo Drive Test Workspace/'
            'Original Folder 1/Original File 1.1.txt')
        file_1_1_parent_path = os.path.dirname(file_1_1_local_info.filepath)
        self.assertEquals(
            file_1_1_parent_path,
            os.path.join(renamed_workspace_path, u'Original Folder 1'))
        # Check child state
        file_1_1_state = session.query(LastKnownState).filter_by(
            remote_name=u'Original File 1.1.txt').one()
        self.assertEquals(
            file_1_1_state.local_path, u'/Renamed Nuxeo Drive Test Workspace'
            '/Original Folder 1/Original File 1.1.txt')
        self.assertEquals(file_1_1_state.local_name, u'Original File 1.1.txt')

        # The more things change, the more they remain the same.
        self.wait_audit_change_finder_if_needed()
        self.wait()
        self.assertEquals(ctl.synchronizer.update_synchronize_server(sb), 0)
    def test_concurrent_file_access(self):
        """Test update/deletion of a locally locked file.

        This is to simulate downstream synchronization of a file opened (thus
        locked) by any program under Windows, typically MS Word.
        The file should be blacklisted and not prevent synchronization of other
        pending items.
        Once the file is unlocked and the cooldown period is over it should be
        synchronized.
        """
        # 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 file in the remote root workspace
        remote.make_file('/', 'test_update.docx', 'Some content to update.')
        remote.make_file('/', 'test_delete.docx', 'Some content to delete.')

        # Launch first synchronization
        syn = ctl.synchronizer
        self._synchronize(syn)
        self.assertTrue(local.exists('/test_update.docx'))
        self.assertTrue(local.exists('/test_delete.docx'))

        # Open locally synchronized files to lock them and generate a
        # WindowsError when trying to update / delete them
        file1_path = local.get_info('/test_update.docx').filepath
        file1_desc = open(file1_path, 'rb')
        file2_path = local.get_info('/test_delete.docx').filepath
        file2_desc = open(file2_path, 'rb')

        # Update /delete existing remote files and create a new remote file
        remote.update_content('/test_update.docx', 'Updated content.')
        remote.delete('/test_delete.docx')
        remote.make_file('/', 'other.docx', 'Other content.')

        # Synchronize
        self._synchronize(syn)
        if sys.platform == 'win32':
            # As local file are locked, a WindowsError should occur during the
            # local update process, therefore:
            # - Temporary download file (.part) should be created locally but
            #   not renamed
            # - Opened local files should still exist and not have been
            #   modified
            # - Synchronization should not fail: doc pairs should be
            #   blacklisted, there should be 2 pending items and other remote
            #   modifications should be locally synchronized
            self.assertTrue(local.exists('/.test_update.docx.part'))
            self.assertTrue(local.exists('/test_update.docx'))
            self.assertEquals(local.get_content('/test_update.docx'),
                              'Some content to update.')
            self.assertTrue(local.exists('/test_delete.docx'))
            self.assertEquals(local.get_content('/test_delete.docx'),
                              'Some content to delete.')
            self.assertEquals(len(ctl.list_pending()), 2)
            self.assertTrue(local.exists('/other.docx'))
            self.assertEquals(local.get_content('/other.docx'),
                              'Other content.')

            # Synchronize again
            syn.loop(delay=0.1, max_loops=1)
            # Blacklisted files should be ignored as delay (300 seconds by
            # default) is not expired, nothing should have changed
            self.assertTrue(local.exists('/.test_update.docx.part'))
            self.assertTrue(local.exists('/test_update.docx'))
            self.assertEquals(local.get_content('/test_update.docx'),
                              'Some content to update.')
            self.assertTrue(local.exists('/test_delete.docx'))
            self.assertEquals(local.get_content('/test_delete.docx'),
                              'Some content to delete.')
            self.assertEquals(len(ctl.list_pending()), 2)

            # Release file locks by closing them
            file1_desc.close()
            file2_desc.close()
            # Reduce error skip delay to retry synchronization of pairs in
            # error
            syn.error_skip_period = 1.0
            time.sleep(syn.error_skip_period)
            syn.loop(delay=0.1, max_loops=1)
            # Previously blacklisted files should be updated / deleted locally,
            # temporary download file should not be there anymore and there
            # should be no pending items left
            self.assertTrue(local.exists('/test_update.docx'))
            self.assertEquals(local.get_content('/test_update.docx'),
                              'Updated content.')
            self.assertFalse(local.exists('/.test_update.docx.part'))
            self.assertFalse(local.exists('/test_delete.docx'))
            self.assertEquals(len(ctl.list_pending()), 0)
        else:
            self.assertTrue(local.exists('/test_update.docx'))
            self.assertEquals(local.get_content('/test_update.docx'),
                              'Updated content.')
            self.assertFalse(local.exists('/.test_update.docx.part'))
            self.assertFalse(local.exists('/test_delete.docx'))
            self.assertEquals(len(ctl.list_pending()), 0)
Exemple #25
0
    def bind_server(self, local_folder, server_url, username, password):
        """Bind a local folder to a remote nuxeo server"""
        session = self.get_session()
        local_folder = normalized_path(local_folder)
        if not os.path.exists(local_folder):
            os.makedirs(local_folder)

        self.register_folder_link(local_folder)

        # check the connection to the server by issuing an authentication
        # request
        server_url = self._normalize_url(server_url)
        nxclient = self.remote_doc_client_factory(
            server_url, username, self.device_id, password)
        token = nxclient.request_token()
        if token is not None:
            # The server supports token based identification: do not store the
            # password in the DB
            password = None
        try:
            server_binding = session.query(ServerBinding).filter(
                ServerBinding.local_folder == local_folder).one()
            if (server_binding.remote_user != username
                or server_binding.server_url != server_url):
                raise RuntimeError(
                    "%s is already bound to '%s' with user '%s'" % (
                        local_folder, server_binding.server_url,
                        server_binding.remote_user))

            if token is None and server_binding.remote_password != password:
                # Update password info if required
                server_binding.remote_password = password
                log.info("Updating password for user '%s' on server '%s'",
                        username, server_url)

            if token is not None and server_binding.remote_token != token:
                log.info("Updating token for user '%s' on server '%s'",
                        username, server_url)
                # Update the token info if required
                server_binding.remote_token = token

                # Ensure that the password is not stored in the DB
                if server_binding.remote_password is not None:
                    server_binding.remote_password = None

        except NoResultFound:
            log.info("Binding '%s' to '%s' with account '%s'",
                     local_folder, server_url, username)
            server_binding = ServerBinding(local_folder, server_url, username,
                                           remote_password=password,
                                           remote_token=token)
            session.add(server_binding)

            # Creating the toplevel state for the server binding
            local_client = LocalClient(server_binding.local_folder)
            local_info = local_client.get_info(u'/')

            remote_client = self.get_remote_fs_client(server_binding)
            remote_info = remote_client.get_filesystem_root_info()

            state = LastKnownState(server_binding.local_folder,
                                   local_info=local_info,
                                   local_state='synchronized',
                                   remote_info=remote_info,
                                   remote_state='synchronized')
            session.add(state)

        session.commit()
        return server_binding