示例#1
0
def make_running_import(code_import=None,
                        machine=None,
                        date_started=None,
                        factory=None,
                        logtail=None):
    """Return a code import with a running job.

    :param code_import: The code import to create the job for.  If None, an
        anonymous CodeImport is created.
    :param machine: The `CodeImportMachine` to associate with the running
        job.  If None, an anonymous CodeImportMachine is created.
    :param date_started: If specified this overrides the UTC_NOW timestamp
        of the newly started job.
    :param factory: The LaunchpadObjectFactory to use for the creation of
        the objects.  If None, one is created.
    :param logtail: An optional string to put in the logtail field of the job.
    """
    if factory is None:
        factory = LaunchpadObjectFactory()
    if code_import is None:
        code_import = factory.makeCodeImport()
    if machine is None:
        machine = factory.makeCodeImportMachine(set_online=True)
    # The code import must be in a reviewed state.
    if code_import.review_status != CodeImportReviewStatus.REVIEWED:
        code_import.updateFromData(
            {'review_status': CodeImportReviewStatus.REVIEWED},
            code_import.registrant)

    CodeImportJobWorkflow().startJob(code_import.import_job, machine)
    if logtail:
        CodeImportJobWorkflow().updateHeartbeat(code_import.import_job,
                                                logtail)

    assert code_import.import_job.state == CodeImportJobState.RUNNING

    if date_started is not None:
        # Override the job date_started.
        naked_job = removeSecurityProxy(code_import.import_job)
        naked_job.date_started = date_started

    return code_import
示例#2
0
def make_finished_import(code_import=None,
                         status=None,
                         date_finished=None,
                         factory=None):
    """Return a code import with a new finished job.

    :param code_import: The code import to create the job for.  If None, an
        anonymous CodeImport is created.
    :param status: The result status.  If not specified it is set to
        SUCCESSFUL.
    :param date_finished: If specified this overrides the date_last_successful
        attribute of the code_import if the state is SUCCESSFUL.
    :param factory: The LaunchpadObjectFactory to use for the creation of
        the objects.  If None, one is created.
    """
    if factory is None:
        factory = LaunchpadObjectFactory()
    if code_import is None:
        code_import = factory.makeCodeImport()
    if status is None:
        status = CodeImportResultStatus.SUCCESS
    # The code import must be in a reviewed state.
    if code_import.review_status != CodeImportReviewStatus.REVIEWED:
        code_import.updateFromData(
            {'review_status': CodeImportReviewStatus.REVIEWED},
            code_import.registrant)

    # If the job isn't running, make it run.
    if code_import.import_job.state != CodeImportJobState.RUNNING:
        machine = factory.makeCodeImportMachine(set_online=True)
        CodeImportJobWorkflow().startJob(code_import.import_job, machine)

    CodeImportJobWorkflow().finishJob(code_import.import_job, status, None)

    if date_finished is not None and status == CodeImportResultStatus.SUCCESS:
        # Override the code import date last successful.
        naked_import = removeSecurityProxy(code_import)
        naked_import.date_last_successful = date_finished

    return code_import
def make_running_import(code_import=None, machine=None, date_started=None,
                        factory=None, logtail=None):
    """Return a code import with a running job.

    :param code_import: The code import to create the job for.  If None, an
        anonymous CodeImport is created.
    :param machine: The `CodeImportMachine` to associate with the running
        job.  If None, an anonymous CodeImportMachine is created.
    :param date_started: If specified this overrides the UTC_NOW timestamp
        of the newly started job.
    :param factory: The LaunchpadObjectFactory to use for the creation of
        the objects.  If None, one is created.
    :param logtail: An optional string to put in the logtail field of the job.
    """
    if factory is None:
        factory = LaunchpadObjectFactory()
    if code_import is None:
        code_import = factory.makeCodeImport()
    if machine is None:
        machine = factory.makeCodeImportMachine(set_online=True)
    # The code import must be in a reviewed state.
    if code_import.review_status != CodeImportReviewStatus.REVIEWED:
        code_import.updateFromData(
            {'review_status': CodeImportReviewStatus.REVIEWED},
            code_import.registrant)

    CodeImportJobWorkflow().startJob(code_import.import_job, machine)
    if logtail:
        CodeImportJobWorkflow().updateHeartbeat(
            code_import.import_job, logtail)

    assert code_import.import_job.state == CodeImportJobState.RUNNING

    if date_started is not None:
        # Override the job date_started.
        naked_job = removeSecurityProxy(code_import.import_job)
        naked_job.date_started = date_started

    return code_import
def make_finished_import(code_import=None, status=None, date_finished=None,
                         factory=None):
    """Return a code import with a new finished job.

    :param code_import: The code import to create the job for.  If None, an
        anonymous CodeImport is created.
    :param status: The result status.  If not specified it is set to
        SUCCESSFUL.
    :param date_finished: If specified this overrides the date_last_successful
        attribute of the code_import if the state is SUCCESSFUL.
    :param factory: The LaunchpadObjectFactory to use for the creation of
        the objects.  If None, one is created.
    """
    if factory is None:
        factory = LaunchpadObjectFactory()
    if code_import is None:
        code_import = factory.makeCodeImport()
    if status is None:
        status = CodeImportResultStatus.SUCCESS
    # The code import must be in a reviewed state.
    if code_import.review_status != CodeImportReviewStatus.REVIEWED:
        code_import.updateFromData(
            {'review_status': CodeImportReviewStatus.REVIEWED},
            code_import.registrant)

    # If the job isn't running, make it run.
    if code_import.import_job.state != CodeImportJobState.RUNNING:
        machine = factory.makeCodeImportMachine(set_online=True)
        CodeImportJobWorkflow().startJob(code_import.import_job, machine)

    CodeImportJobWorkflow().finishJob(code_import.import_job, status, None)

    if date_finished is not None and status == CodeImportResultStatus.SUCCESS:
        # Override the code import date last successful.
        naked_import = removeSecurityProxy(code_import)
        naked_import.date_last_successful = date_finished

    return code_import
class TestWorkerMonitorIntegration(BzrTestCase):

    layer = ZopelessAppServerLayer
    run_tests_with = AsynchronousDeferredRunTest.make_factory(timeout=60)

    def setUp(self):
        BzrTestCase.setUp(self)
        login('*****@*****.**')
        self.factory = LaunchpadObjectFactory()
        nuke_codeimport_sample_data()
        self.repo_path = tempfile.mkdtemp()
        self.disable_directory_isolation()
        self.addCleanup(shutil.rmtree, self.repo_path)
        self.foreign_commit_count = 0

    def tearDown(self):
        BzrTestCase.tearDown(self)
        logout()

    def makeCVSCodeImport(self):
        """Make a `CodeImport` that points to a real CVS repository."""
        cvs_server = CVSServer(self.repo_path)
        cvs_server.start_server()
        self.addCleanup(cvs_server.stop_server)

        cvs_server.makeModule('trunk', [('README', 'original\n')])
        self.foreign_commit_count = 2

        return self.factory.makeCodeImport(
            cvs_root=cvs_server.getRoot(), cvs_module='trunk')

    def makeSVNCodeImport(self):
        """Make a `CodeImport` that points to a real Subversion repository."""
        self.subversion_server = SubversionServer(self.repo_path)
        self.subversion_server.start_server()
        self.addCleanup(self.subversion_server.stop_server)
        url = self.subversion_server.makeBranch(
            'trunk', [('README', 'contents')])
        self.foreign_commit_count = 2

        return self.factory.makeCodeImport(svn_branch_url=url)

    def makeBzrSvnCodeImport(self):
        """Make a `CodeImport` that points to a real Subversion repository."""
        self.subversion_server = SubversionServer(
            self.repo_path, use_svn_serve=True)
        self.subversion_server.start_server()
        self.addCleanup(self.subversion_server.stop_server)
        url = self.subversion_server.makeBranch(
            'trunk', [('README', 'contents')])
        self.foreign_commit_count = 2

        return self.factory.makeCodeImport(
            svn_branch_url=url, rcs_type=RevisionControlSystems.BZR_SVN)

    def makeGitCodeImport(self):
        """Make a `CodeImport` that points to a real Git repository."""
        self.git_server = GitServer(self.repo_path, use_server=False)
        self.git_server.start_server()
        self.addCleanup(self.git_server.stop_server)

        self.git_server.makeRepo([('README', 'contents')])
        self.foreign_commit_count = 1

        return self.factory.makeCodeImport(
            git_repo_url=self.git_server.get_url())

    def makeBzrCodeImport(self):
        """Make a `CodeImport` that points to a real Bazaar branch."""
        self.bzr_server = BzrServer(self.repo_path)
        self.bzr_server.start_server()
        self.addCleanup(self.bzr_server.stop_server)

        self.bzr_server.makeRepo([('README', 'contents')])
        self.foreign_commit_count = 1
        return self.factory.makeCodeImport(
            bzr_branch_url=self.bzr_server.get_url())

    def getStartedJobForImport(self, code_import):
        """Get a started `CodeImportJob` for `code_import`.

        This method approves the import, creates a job, marks it started and
        returns the job.  It also makes sure there are no branches or foreign
        trees in the default stores to interfere with processing this job.
        """
        source_details = CodeImportSourceDetails.fromCodeImport(code_import)
        clean_up_default_stores_for_import(source_details)
        self.addCleanup(clean_up_default_stores_for_import, source_details)
        if code_import.review_status != CodeImportReviewStatus.REVIEWED:
            code_import.updateFromData(
                {'review_status': CodeImportReviewStatus.REVIEWED},
                self.factory.makePerson())
        job = getUtility(ICodeImportJobSet).getJobForMachine('machine', 10)
        self.assertEqual(code_import, job.code_import)
        return job

    def assertCodeImportResultCreated(self, code_import):
        """Assert that a `CodeImportResult` was created for `code_import`."""
        self.assertEqual(len(list(code_import.results)), 1)
        result = list(code_import.results)[0]
        self.assertEqual(result.status, CodeImportResultStatus.SUCCESS)

    def assertBranchImportedOKForCodeImport(self, code_import):
        """Assert that a branch was pushed into the default branch store."""
        url = get_default_bazaar_branch_store()._getMirrorURL(
            code_import.branch.id)
        branch = Branch.open(url)
        self.assertEqual(self.foreign_commit_count, branch.revno())

    def assertImported(self, ignored, code_import_id):
        """Assert that the `CodeImport` of the given id was imported."""
        # In the in-memory tests, check that resetTimeout on the
        # CodeImportWorkerMonitorProtocol was called at least once.
        if self._protocol is not None:
            self.assertPositive(self._protocol.reset_calls)
        code_import = getUtility(ICodeImportSet).get(code_import_id)
        self.assertCodeImportResultCreated(code_import)
        self.assertBranchImportedOKForCodeImport(code_import)

    def performImport(self, job_id):
        """Perform the import job with ID job_id.

        Return a Deferred that fires when it the job is done.

        This implementation does it in-process.
        """
        logger = BufferLogger()
        monitor = CIWorkerMonitorForTesting(
            job_id, logger,
            xmlrpc.Proxy(config.codeimportdispatcher.codeimportscheduler_url),
            "anything")
        deferred = monitor.run()

        def save_protocol_object(result):
            """Save the process protocol object.

            We do this in an addBoth so that it's called after the process
            protocol is actually constructed but before we drop the last
            reference to the monitor object.
            """
            self._protocol = monitor._protocol
            return result

        return deferred.addBoth(save_protocol_object)

    def test_import_cvs(self):
        # Create a CVS CodeImport and import it.
        job = self.getStartedJobForImport(self.makeCVSCodeImport())
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        result = self.performImport(job_id)
        return result.addCallback(self.assertImported, code_import_id)

    def test_import_subversion(self):
        # Create a Subversion CodeImport and import it.
        job = self.getStartedJobForImport(self.makeSVNCodeImport())
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        result = self.performImport(job_id)
        return result.addCallback(self.assertImported, code_import_id)

    def test_import_git(self):
        # Create a Git CodeImport and import it.
        job = self.getStartedJobForImport(self.makeGitCodeImport())
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        result = self.performImport(job_id)
        return result.addCallback(self.assertImported, code_import_id)

    def test_import_bzr(self):
        # Create a Bazaar CodeImport and import it.
        job = self.getStartedJobForImport(self.makeBzrCodeImport())
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        result = self.performImport(job_id)
        return result.addCallback(self.assertImported, code_import_id)

    def test_import_bzrsvn(self):
        # Create a Subversion-via-bzr-svn CodeImport and import it.
        job = self.getStartedJobForImport(self.makeBzrSvnCodeImport())
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        result = self.performImport(job_id)
        return result.addCallback(self.assertImported, code_import_id)
示例#6
0
class TestWorkerMonitorIntegration(BzrTestCase):

    layer = ZopelessAppServerLayer
    run_tests_with = AsynchronousDeferredRunTest.make_factory(timeout=60)

    def setUp(self):
        BzrTestCase.setUp(self)
        login('*****@*****.**')
        self.factory = LaunchpadObjectFactory()
        nuke_codeimport_sample_data()
        self.repo_path = tempfile.mkdtemp()
        self.disable_directory_isolation()
        self.addCleanup(shutil.rmtree, self.repo_path)
        self.foreign_commit_count = 0

    def tearDown(self):
        BzrTestCase.tearDown(self)
        logout()

    def makeCVSCodeImport(self):
        """Make a `CodeImport` that points to a real CVS repository."""
        cvs_server = CVSServer(self.repo_path)
        cvs_server.start_server()
        self.addCleanup(cvs_server.stop_server)

        cvs_server.makeModule('trunk', [('README', 'original\n')])
        self.foreign_commit_count = 2

        return self.factory.makeCodeImport(cvs_root=cvs_server.getRoot(),
                                           cvs_module='trunk')

    def makeSVNCodeImport(self):
        """Make a `CodeImport` that points to a real Subversion repository."""
        self.subversion_server = SubversionServer(self.repo_path)
        self.subversion_server.start_server()
        self.addCleanup(self.subversion_server.stop_server)
        url = self.subversion_server.makeBranch('trunk',
                                                [('README', 'contents')])
        self.foreign_commit_count = 2

        return self.factory.makeCodeImport(svn_branch_url=url)

    def makeBzrSvnCodeImport(self):
        """Make a `CodeImport` that points to a real Subversion repository."""
        self.subversion_server = SubversionServer(self.repo_path,
                                                  use_svn_serve=True)
        self.subversion_server.start_server()
        self.addCleanup(self.subversion_server.stop_server)
        url = self.subversion_server.makeBranch('trunk',
                                                [('README', 'contents')])
        self.foreign_commit_count = 2

        return self.factory.makeCodeImport(
            svn_branch_url=url, rcs_type=RevisionControlSystems.BZR_SVN)

    def makeGitCodeImport(self):
        """Make a `CodeImport` that points to a real Git repository."""
        self.git_server = GitServer(self.repo_path, use_server=False)
        self.git_server.start_server()
        self.addCleanup(self.git_server.stop_server)

        self.git_server.makeRepo([('README', 'contents')])
        self.foreign_commit_count = 1

        return self.factory.makeCodeImport(
            git_repo_url=self.git_server.get_url())

    def makeBzrCodeImport(self):
        """Make a `CodeImport` that points to a real Bazaar branch."""
        self.bzr_server = BzrServer(self.repo_path)
        self.bzr_server.start_server()
        self.addCleanup(self.bzr_server.stop_server)

        self.bzr_server.makeRepo([('README', 'contents')])
        self.foreign_commit_count = 1
        return self.factory.makeCodeImport(
            bzr_branch_url=self.bzr_server.get_url())

    def getStartedJobForImport(self, code_import):
        """Get a started `CodeImportJob` for `code_import`.

        This method approves the import, creates a job, marks it started and
        returns the job.  It also makes sure there are no branches or foreign
        trees in the default stores to interfere with processing this job.
        """
        source_details = CodeImportSourceDetails.fromCodeImport(code_import)
        clean_up_default_stores_for_import(source_details)
        self.addCleanup(clean_up_default_stores_for_import, source_details)
        if code_import.review_status != CodeImportReviewStatus.REVIEWED:
            code_import.updateFromData(
                {'review_status': CodeImportReviewStatus.REVIEWED},
                self.factory.makePerson())
        job = getUtility(ICodeImportJobSet).getJobForMachine('machine', 10)
        self.assertEqual(code_import, job.code_import)
        return job

    def assertCodeImportResultCreated(self, code_import):
        """Assert that a `CodeImportResult` was created for `code_import`."""
        self.assertEqual(len(list(code_import.results)), 1)
        result = list(code_import.results)[0]
        self.assertEqual(result.status, CodeImportResultStatus.SUCCESS)

    def assertBranchImportedOKForCodeImport(self, code_import):
        """Assert that a branch was pushed into the default branch store."""
        url = get_default_bazaar_branch_store()._getMirrorURL(
            code_import.branch.id)
        branch = Branch.open(url)
        self.assertEqual(self.foreign_commit_count, branch.revno())

    def assertImported(self, ignored, code_import_id):
        """Assert that the `CodeImport` of the given id was imported."""
        # In the in-memory tests, check that resetTimeout on the
        # CodeImportWorkerMonitorProtocol was called at least once.
        if self._protocol is not None:
            self.assertPositive(self._protocol.reset_calls)
        code_import = getUtility(ICodeImportSet).get(code_import_id)
        self.assertCodeImportResultCreated(code_import)
        self.assertBranchImportedOKForCodeImport(code_import)

    def performImport(self, job_id):
        """Perform the import job with ID job_id.

        Return a Deferred that fires when it the job is done.

        This implementation does it in-process.
        """
        logger = BufferLogger()
        monitor = CIWorkerMonitorForTesting(
            job_id, logger,
            xmlrpc.Proxy(config.codeimportdispatcher.codeimportscheduler_url),
            "anything")
        deferred = monitor.run()

        def save_protocol_object(result):
            """Save the process protocol object.

            We do this in an addBoth so that it's called after the process
            protocol is actually constructed but before we drop the last
            reference to the monitor object.
            """
            self._protocol = monitor._protocol
            return result

        return deferred.addBoth(save_protocol_object)

    def test_import_cvs(self):
        # Create a CVS CodeImport and import it.
        job = self.getStartedJobForImport(self.makeCVSCodeImport())
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        result = self.performImport(job_id)
        return result.addCallback(self.assertImported, code_import_id)

    def test_import_subversion(self):
        # Create a Subversion CodeImport and import it.
        job = self.getStartedJobForImport(self.makeSVNCodeImport())
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        result = self.performImport(job_id)
        return result.addCallback(self.assertImported, code_import_id)

    def test_import_git(self):
        # Create a Git CodeImport and import it.
        job = self.getStartedJobForImport(self.makeGitCodeImport())
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        result = self.performImport(job_id)
        return result.addCallback(self.assertImported, code_import_id)

    def test_import_bzr(self):
        # Create a Bazaar CodeImport and import it.
        job = self.getStartedJobForImport(self.makeBzrCodeImport())
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        result = self.performImport(job_id)
        return result.addCallback(self.assertImported, code_import_id)

    def test_import_bzrsvn(self):
        # Create a Subversion-via-bzr-svn CodeImport and import it.
        job = self.getStartedJobForImport(self.makeBzrSvnCodeImport())
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        result = self.performImport(job_id)
        return result.addCallback(self.assertImported, code_import_id)
示例#7
0
class TestWorkerMonitorIntegration(TestCaseInTempDir, TestCase):

    layer = ZopelessAppServerLayer
    run_tests_with = AsynchronousDeferredRunTest.make_factory(timeout=60)

    def setUp(self):
        super(TestWorkerMonitorIntegration, self).setUp()
        login('*****@*****.**')
        self.factory = LaunchpadObjectFactory()
        nuke_codeimport_sample_data()
        self.repo_path = tempfile.mkdtemp()
        self.disable_directory_isolation()
        self.addCleanup(shutil.rmtree, self.repo_path)
        self.foreign_commit_count = 0

    def tearDown(self):
        super(TestWorkerMonitorIntegration, self).tearDown()
        logout()

    def makeCVSCodeImport(self):
        """Make a `CodeImport` that points to a real CVS repository."""
        cvs_server = CVSServer(self.repo_path)
        cvs_server.start_server()
        self.addCleanup(cvs_server.stop_server)

        cvs_server.makeModule('trunk', [('README', 'original\n')])
        self.foreign_commit_count = 2

        return self.factory.makeCodeImport(cvs_root=cvs_server.getRoot(),
                                           cvs_module='trunk')

    def makeSVNCodeImport(self):
        """Make a `CodeImport` that points to a real Subversion repository."""
        self.subversion_server = SubversionServer(self.repo_path)
        self.subversion_server.start_server()
        self.addCleanup(self.subversion_server.stop_server)
        url = self.subversion_server.makeBranch('trunk',
                                                [('README', 'contents')])
        self.foreign_commit_count = 2

        return self.factory.makeCodeImport(svn_branch_url=url)

    def makeBzrSvnCodeImport(self):
        """Make a `CodeImport` that points to a real Subversion repository."""
        self.subversion_server = SubversionServer(self.repo_path,
                                                  use_svn_serve=True)
        self.subversion_server.start_server()
        self.addCleanup(self.subversion_server.stop_server)
        url = self.subversion_server.makeBranch('trunk',
                                                [('README', 'contents')])
        self.foreign_commit_count = 2

        return self.factory.makeCodeImport(
            svn_branch_url=url, rcs_type=RevisionControlSystems.BZR_SVN)

    def makeGitCodeImport(self, target_rcs_type=None):
        """Make a `CodeImport` that points to a real Git repository."""
        self.git_server = GitServer(self.repo_path, use_server=False)
        self.git_server.start_server()
        self.addCleanup(self.git_server.stop_server)

        self.git_server.makeRepo('source', [('README', 'contents')])
        self.foreign_commit_count = 1

        return self.factory.makeCodeImport(
            git_repo_url=self.git_server.get_url('source'),
            target_rcs_type=target_rcs_type)

    def makeBzrCodeImport(self):
        """Make a `CodeImport` that points to a real Bazaar branch."""
        self.bzr_server = BzrServer(self.repo_path)
        self.bzr_server.start_server()
        self.addCleanup(self.bzr_server.stop_server)

        self.bzr_server.makeRepo([('README', 'contents')])
        self.foreign_commit_count = 1
        return self.factory.makeCodeImport(
            bzr_branch_url=self.bzr_server.get_url())

    def getStartedJobForImport(self, code_import):
        """Get a started `CodeImportJob` for `code_import`.

        This method approves the import, creates a job, marks it started and
        returns the job.  It also makes sure there are no branches or foreign
        trees in the default stores to interfere with processing this job.
        """
        if code_import.review_status != CodeImportReviewStatus.REVIEWED:
            code_import.updateFromData(
                {'review_status': CodeImportReviewStatus.REVIEWED},
                self.factory.makePerson())
        job = getUtility(ICodeImportJobSet).getJobForMachine('machine', 10)
        self.assertEqual(code_import, job.code_import)
        source_details = CodeImportSourceDetails.fromArguments(
            removeSecurityProxy(job.makeWorkerArguments()))
        if IBranch.providedBy(code_import.target):
            clean_up_default_stores_for_import(source_details)
            self.addCleanup(clean_up_default_stores_for_import, source_details)
        return job

    def makeTargetGitServer(self):
        """Set up a target Git server that can receive imports."""
        self.target_store = tempfile.mkdtemp()
        self.addCleanup(shutil.rmtree, self.target_store)
        self.target_git_server = GitServer(self.target_store, use_server=True)
        self.target_git_server.start_server()
        self.addCleanup(self.target_git_server.stop_server)
        config_name = self.getUniqueString()
        config_fixture = self.useFixture(
            ConfigFixture(config_name,
                          self.layer.config_fixture.instance_name))
        setting_lines = [
            "[codehosting]",
            "git_browse_root: %s" % self.target_git_server.get_url(""),
            "",
            "[launchpad]",
            "internal_macaroon_secret_key: some-secret",
        ]
        config_fixture.add_section("\n" + "\n".join(setting_lines))
        self.useFixture(ConfigUseFixture(config_name))
        self.useFixture(GitHostingFixture())

    def assertCodeImportResultCreated(self, code_import):
        """Assert that a `CodeImportResult` was created for `code_import`."""
        self.assertEqual(len(list(code_import.results)), 1)
        result = list(code_import.results)[0]
        self.assertEqual(result.status, CodeImportResultStatus.SUCCESS)

    def assertBranchImportedOKForCodeImport(self, code_import):
        """Assert that a branch was pushed into the default branch store."""
        if IBranch.providedBy(code_import.target):
            url = get_default_bazaar_branch_store()._getMirrorURL(
                code_import.branch.id)
            branch = Branch.open(url)
            commit_count = branch.revno()
        else:
            repo_path = os.path.join(self.target_store,
                                     code_import.target.unique_name)
            commit_count = int(
                subprocess.check_output(["git", "rev-list", "--count", "HEAD"],
                                        cwd=repo_path,
                                        universal_newlines=True))
        self.assertEqual(self.foreign_commit_count, commit_count)

    def assertImported(self, code_import_id):
        """Assert that the `CodeImport` of the given id was imported."""
        # In the in-memory tests, check that resetTimeout on the
        # CodeImportWorkerMonitorProtocol was called at least once.
        if self._protocol is not None:
            self.assertPositive(self._protocol.reset_calls)
        code_import = getUtility(ICodeImportSet).get(code_import_id)
        self.assertCodeImportResultCreated(code_import)
        self.assertBranchImportedOKForCodeImport(code_import)

    def performImport(self, job_id):
        """Perform the import job with ID job_id.

        Return a Deferred that fires when it the job is done.

        This implementation does it in-process.
        """
        logger = BufferLogger()
        monitor = CIWorkerMonitorForTesting(
            job_id, logger,
            xmlrpc.Proxy(config.codeimportdispatcher.codeimportscheduler_url),
            "anything")
        deferred = monitor.run()

        def save_protocol_object(result):
            """Save the process protocol object.

            We do this in an addBoth so that it's called after the process
            protocol is actually constructed but before we drop the last
            reference to the monitor object.
            """
            self._protocol = monitor._protocol
            return result

        return deferred.addBoth(save_protocol_object)

    @defer.inlineCallbacks
    def test_import_cvs(self):
        # Create a CVS CodeImport and import it.
        job = self.getStartedJobForImport(self.makeCVSCodeImport())
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        yield self.performImport(job_id)
        self.assertImported(code_import_id)

    @defer.inlineCallbacks
    def test_import_subversion(self):
        # Create a Subversion CodeImport and import it.
        job = self.getStartedJobForImport(self.makeSVNCodeImport())
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        yield self.performImport(job_id)
        self.assertImported(code_import_id)

    @defer.inlineCallbacks
    def test_import_git(self):
        # Create a Git CodeImport and import it.
        job = self.getStartedJobForImport(self.makeGitCodeImport())
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        yield self.performImport(job_id)
        self.assertImported(code_import_id)

    @defer.inlineCallbacks
    def test_import_git_to_git(self):
        # Create a Git-to-Git CodeImport and import it.
        self.makeTargetGitServer()
        job = self.getStartedJobForImport(
            self.makeGitCodeImport(
                target_rcs_type=TargetRevisionControlSystems.GIT))
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        target_repo_path = os.path.join(self.target_store,
                                        job.code_import.target.unique_name)
        os.makedirs(target_repo_path)
        self.target_git_server.createRepository(target_repo_path, bare=True)
        yield self.performImport(job_id)
        self.assertImported(code_import_id)
        target_repo = GitRepo(target_repo_path)
        self.assertContentEqual(["heads/master"],
                                target_repo.refs.keys(base="refs"))
        self.assertEqual("ref: refs/heads/master",
                         target_repo.refs.read_ref("HEAD"))

    @defer.inlineCallbacks
    def test_import_git_to_git_refs_changed(self):
        # Create a Git-to-Git CodeImport and import it incrementally with
        # ref and HEAD changes.
        self.makeTargetGitServer()
        job = self.getStartedJobForImport(
            self.makeGitCodeImport(
                target_rcs_type=TargetRevisionControlSystems.GIT))
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        source_repo = GitRepo(os.path.join(self.repo_path, "source"))
        commit = source_repo.refs["refs/heads/master"]
        source_repo.refs["refs/heads/one"] = commit
        source_repo.refs["refs/heads/two"] = commit
        source_repo.refs.set_symbolic_ref("HEAD", "refs/heads/one")
        del source_repo.refs["refs/heads/master"]
        target_repo_path = os.path.join(self.target_store,
                                        job.code_import.target.unique_name)
        self.target_git_server.makeRepo(job.code_import.target.unique_name,
                                        [("NEWS", "contents")])
        yield self.performImport(job_id)
        self.assertImported(code_import_id)
        target_repo = GitRepo(target_repo_path)
        self.assertContentEqual(["heads/one", "heads/two"],
                                target_repo.refs.keys(base="refs"))
        self.assertEqual("ref: refs/heads/one",
                         GitRepo(target_repo_path).refs.read_ref("HEAD"))

    @defer.inlineCallbacks
    def test_import_bzr(self):
        # Create a Bazaar CodeImport and import it.
        job = self.getStartedJobForImport(self.makeBzrCodeImport())
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        yield self.performImport(job_id)
        self.assertImported(code_import_id)

    @defer.inlineCallbacks
    def test_import_bzrsvn(self):
        # Create a Subversion-via-bzr-svn CodeImport and import it.
        job = self.getStartedJobForImport(self.makeBzrSvnCodeImport())
        code_import_id = job.code_import.id
        job_id = job.id
        self.layer.txn.commit()
        yield self.performImport(job_id)
        self.assertImported(code_import_id)