Example #1
0
def execute_build(build):
    # TODO(dcramer): most of this should be abstracted into sync_build as if it
    # were a "im on step 0, create step 1"
    project = build.project

    jobs = []
    for plan in project.plans:
        cur_no_query = db.session.query(
            coalesce(func.max(Job.number), 0)
        ).filter(
            Job.build_id == build.id,
        ).scalar()

        job = Job(
            build=build,
            build_id=build.id,
            number=cur_no_query + 1,
            project=project,
            project_id=project.id,
            source=build.source,
            source_id=build.source_id,
            status=build.status,
            label=plan.label,
        )

        db.session.add(job)

        jobplan = JobPlan(
            project=project,
            job=job,
            build=build,
            plan=plan,
        )

        db.session.add(jobplan)

        jobs.append(job)

    db.session.commit()

    publish_build_update(build)

    for job in jobs:
        publish_job_update(job)
        create_job.delay(
            job_id=job.id.hex,
            task_id=job.id.hex,
            parent_task_id=job.build_id.hex,
        )

    db.session.commit()

    sync_build.delay(
        build_id=job.build_id.hex,
        task_id=job.build_id.hex,
    )

    return build
Example #2
0
def execute_build(build, snapshot_id, no_snapshot):
    if no_snapshot:
        assert snapshot_id is None, 'Cannot specify snapshot with no_snapshot option'
    # TODO(dcramer): most of this should be abstracted into sync_build as if it
    # were a "im on step 0, create step 1"
    project = build.project

    # We choose a snapshot before creating jobplans. This is so that different
    # jobplans won't end up using different snapshots in a build.
    if snapshot_id is None and not no_snapshot:
        snapshot = Snapshot.get_current(project.id)
        if snapshot:
            snapshot_id = snapshot.id

    jobs = []
    for plan in get_build_plans(project):
        job = Job(
            build=build,
            build_id=build.id,
            project=project,
            project_id=project.id,
            source=build.source,
            source_id=build.source_id,
            status=build.status,
            label=plan.label,
        )

        db.session.add(job)

        jobplan = JobPlan.build_jobplan(plan, job, snapshot_id=snapshot_id)

        db.session.add(jobplan)

        jobs.append(job)

    db.session.commit()

    for job in jobs:
        create_job.delay(
            job_id=job.id.hex,
            task_id=job.id.hex,
            parent_task_id=job.build_id.hex,
        )

    db.session.commit()

    sync_build.delay(
        build_id=build.id.hex,
        task_id=build.id.hex,
    )

    return build
Example #3
0
def execute_build(build, snapshot_id, no_snapshot):
    if no_snapshot:
        assert snapshot_id is None, 'Cannot specify snapshot with no_snapshot option'
    # TODO(dcramer): most of this should be abstracted into sync_build as if it
    # were a "im on step 0, create step 1"
    project = build.project

    # We choose a snapshot before creating jobplans. This is so that different
    # jobplans won't end up using different snapshots in a build.
    if snapshot_id is None and not no_snapshot:
        snapshot = Snapshot.get_current(project.id)
        if snapshot:
            snapshot_id = snapshot.id

    jobs = []
    for plan in get_build_plans(project):
        job = Job(
            build=build,
            build_id=build.id,
            project=project,
            project_id=project.id,
            source=build.source,
            source_id=build.source_id,
            status=build.status,
            label=plan.label,
        )

        db.session.add(job)

        jobplan = JobPlan.build_jobplan(plan, job, snapshot_id=snapshot_id)

        db.session.add(jobplan)

        jobs.append(job)

    db.session.commit()

    for job in jobs:
        create_job.delay(
            job_id=job.id.hex,
            task_id=job.id.hex,
            parent_task_id=job.build_id.hex,
        )

    db.session.commit()

    sync_build.delay(
        build_id=build.id.hex,
        task_id=build.id.hex,
    )

    return build
Example #4
0
def execute_build(build):
    # TODO(dcramer): most of this should be abstracted into sync_build as if it
    # were a "im on step 0, create step 1"
    project = build.project

    jobs = []
    for plan in project.plans:
        job = Job(
            build=build,
            build_id=build.id,
            project=project,
            project_id=project.id,
            source=build.source,
            source_id=build.source_id,
            status=build.status,
            label=plan.label,
        )

        db.session.add(job)

        jobplan = JobPlan(
            project=project,
            job=job,
            build=build,
            plan=plan,
        )

        db.session.add(jobplan)

        jobs.append(job)

    db.session.commit()

    publish_build_update(build)

    for job in jobs:
        publish_job_update(job)
        create_job.delay(
            job_id=job.id.hex,
            task_id=job.id.hex,
            parent_task_id=job.build_id.hex,
        )

    db.session.commit()

    sync_build.delay(
        build_id=job.build_id.hex,
        task_id=job.build_id.hex,
    )

    return build
Example #5
0
def execute_build(build):
    # TODO(dcramer): most of this should be abstracted into sync_build as if it
    # were a "im on step 0, create step 1"
    project = build.project

    jobs = []
    for plan in project.plans:
        job = Job(
            build=build,
            build_id=build.id,
            project=project,
            project_id=project.id,
            source=build.source,
            source_id=build.source_id,
            status=build.status,
            label=plan.label,
        )

        db.session.add(job)

        jobplan = JobPlan(
            project=project,
            job=job,
            build=build,
            plan=plan,
        )

        db.session.add(jobplan)

        jobs.append(job)

    db.session.commit()

    for job in jobs:
        create_job.delay(
            job_id=job.id.hex,
            task_id=job.id.hex,
            parent_task_id=job.build_id.hex,
        )

    db.session.commit()

    sync_build.delay(
        build_id=job.build_id.hex,
        task_id=job.build_id.hex,
    )

    return build
Example #6
0
    def test_full(self):
        from changes.jobs.create_job import create_job

        # TODO: move this out of this file and integrate w/ buildstep
        responses.add(responses.POST,
                      'http://jenkins.example.com/job/server/build/api/json/',
                      body='',
                      status=201)
        responses.add(
            responses.GET,
            'http://jenkins.example.com/queue/api/xml/?wrapper=x&xpath=%2Fqueue%2Fitem%5Baction%2Fparameter%2Fname%3D%22CHANGES_BID%22+and+action%2Fparameter%2Fvalue%3D%2281d1596fd4d642f4a6bdf86c45e014e8%22%5D%2Fid',
            body=self.load_fixture('fixtures/GET/queue_item_by_job_id.xml'),
            match_querystring=True)
        responses.add(
            responses.GET,
            'http://jenkins.example.com/queue/item/13/api/json/',
            body=self.load_fixture('fixtures/GET/queue_details_building.json'))
        responses.add(
            responses.GET,
            'http://jenkins.example.com/job/server/2/api/json/',
            body=self.load_fixture('fixtures/GET/job_details_success.json'))
        responses.add(
            responses.GET,
            'http://jenkins.example.com/job/server/2/logText/progressiveText/?start=0',
            match_querystring=True,
            adding_headers={'X-Text-Size': '7'},
            body='Foo bar')
        responses.add(
            responses.GET,
            'http://jenkins.example.com/computer/server-ubuntu-10.04%20(ami-746cf244)%20(i-836023b7)/config.xml',
            body=self.load_fixture('fixtures/GET/node_config.xml'))

        build = self.create_build(self.project)
        job = self.create_job(build=build,
                              id=UUID('81d1596fd4d642f4a6bdf86c45e014e8'))

        plan = self.create_plan()
        plan.projects.append(self.project)
        self.create_step(
            plan,
            order=0,
            implementation=
            'changes.backends.jenkins.buildstep.JenkinsBuildStep',
            data={
                'job_name': 'server',
            },
        )
        self.create_job_plan(job, plan)

        job_id = job.id.hex
        build_id = build.id.hex

        create_job.delay(
            job_id=job_id,
            task_id=job_id,
            parent_task_id=build_id,
        )

        job = Job.query.get(job_id)

        assert job.status == Status.finished
        assert job.result == Result.passed
        assert job.date_created
        assert job.date_started
        assert job.date_finished

        phase_list = job.phases

        assert len(phase_list) == 1

        assert phase_list[0].status == Status.finished
        assert phase_list[0].result == Result.passed
        assert phase_list[0].date_created
        assert phase_list[0].date_started
        assert phase_list[0].date_finished

        step_list = phase_list[0].steps

        assert len(step_list) == 1

        assert step_list[0].status == Status.finished
        assert step_list[0].result == Result.passed
        assert step_list[0].date_created
        assert step_list[0].date_started
        assert step_list[0].date_finished
        assert step_list[0].data == {
            'item_id': '13',
            'queued': False,
            'log_offset': 7,
            'job_name': 'server',
            'build_no': 2,
            'uri': 'https://jenkins.build.itc.dropbox.com/job/server/2/',
        }

        node = step_list[0].node
        assert node.label == 'server-ubuntu-10.04 (ami-746cf244) (i-836023b7)'
        assert [n.label for n in node.clusters] == ['server-runner']

        source = LogSource.query.filter_by(job=job).first()
        assert source.name == step_list[0].label
        assert source.step == step_list[0]
        assert source.project == self.project
        assert source.date_created == job.date_started

        chunks = list(
            LogChunk.query.filter_by(source=source, ).order_by(
                LogChunk.date_created.asc()))
        assert len(chunks) == 1
        assert chunks[0].job_id == job.id
        assert chunks[0].project_id == self.project.id
        assert chunks[0].offset == 0
        assert chunks[0].size == 7
        assert chunks[0].text == 'Foo bar'
    def post(self, project_id):
        """Initiates a new snapshot for this project."""
        project = Project.get(project_id)
        if not project:
            return '', 404

        args = self.post_parser.parse_args()

        repository = project.repository

        try:
            revision = identify_revision(repository, args.sha)
        except MissingRevision:
            # if the default fails, we absolutely can't continue and the
            # client should send a valid revision
            return '{"error": "Unable to find a matching revision."}', 400

        if revision:
            sha = revision.sha
        else:
            sha = args.sha

        plan_list = get_snapshottable_plans(project)

        if not plan_list:
            return '{"error": "No snapshottable plans associated with project."}', 400

        source, _ = get_or_create(Source, where={
            'repository': repository,
            'revision_sha': sha,
        })

        build = Build(
            source_id=source.id,
            source=source,
            project_id=project.id,
            project=project,
            label='Create Snapshot',
            status=Status.queued,
            cause=Cause.snapshot,
            target=sha[:12],
        )
        db.session.add(build)

        # TODO(dcramer): this needs to update with the build result
        snapshot = Snapshot(
            project_id=project.id,
            source_id=source.id,
            build_id=build.id,
            status=SnapshotStatus.pending,
        )
        db.session.add(snapshot)

        jobs = []
        for plan in plan_list:
            job = Job(
                build=build,
                build_id=build.id,
                project=project,
                project_id=project.id,
                source=build.source,
                source_id=build.source_id,
                status=build.status,
                label='Create Snapshot: %s' % (plan.label,),
            )
            db.session.add(job)

            jobplan = JobPlan.build_jobplan(plan, job)
            db.session.add(jobplan)

            image = SnapshotImage(
                job=job,
                snapshot=snapshot,
                plan=plan,
            )
            db.session.add(image)

            jobs.append(job)

        db.session.commit()

        for job in jobs:
            create_job.delay(
                job_id=job.id.hex,
                task_id=job.id.hex,
                parent_task_id=job.build_id.hex,
            )

        db.session.commit()

        sync_build.delay(
            build_id=build.id.hex,
            task_id=build.id.hex,
        )

        return self.respond(snapshot)
Example #8
0
def execute_build(build, snapshot_id, no_snapshot):
    if no_snapshot:
        assert snapshot_id is None, 'Cannot specify snapshot with no_snapshot option'
    # TODO(dcramer): most of this should be abstracted into sync_build as if it
    # were a "im on step 0, create step 1"
    project = build.project

    # We choose a snapshot before creating jobplans. This is so that different
    # jobplans won't end up using different snapshots in a build.
    if snapshot_id is None and not no_snapshot:
        snapshot = Snapshot.get_current(project.id)
        if snapshot:
            snapshot_id = snapshot.id

    plans = get_build_plans(project)

    options = ItemOptionsHelper.get_options([p.id for p in plans], ['snapshot.require'])

    jobs = []
    for plan in get_build_plans(project):
        if (options[plan.id].get('snapshot.require', '0') == '1' and
                not no_snapshot and
                SnapshotImage.get(plan, snapshot_id) is None):
            logging.warning('Skipping plan %r (%r) because no snapshot exists yet', plan.label, project.slug)
            continue

        job = Job(
            build=build,
            build_id=build.id,
            project=project,
            project_id=project.id,
            source=build.source,
            source_id=build.source_id,
            status=build.status,
            label=plan.label,
        )

        db.session.add(job)

        jobplan = JobPlan.build_jobplan(plan, job, snapshot_id=snapshot_id)

        db.session.add(jobplan)

        jobs.append(job)

    db.session.commit()

    for job in jobs:
        create_job.delay(
            job_id=job.id.hex,
            task_id=job.id.hex,
            parent_task_id=job.build_id.hex,
        )

    db.session.commit()

    sync_build.delay(
        build_id=build.id.hex,
        task_id=build.id.hex,
    )

    return build
Example #9
0
    def test_full(self):
        from changes.jobs.create_job import create_job

        # TODO: move this out of this file and integrate w/ buildstep
        responses.add(
            responses.POST, 'http://jenkins.example.com/job/server/build/api/json/',
            body='',
            status=201)
        responses.add(
            responses.GET, 'http://jenkins.example.com/queue/api/xml/?wrapper=x&xpath=%2Fqueue%2Fitem%5Baction%2Fparameter%2Fname%3D%22CHANGES_BID%22+and+action%2Fparameter%2Fvalue%3D%2281d1596fd4d642f4a6bdf86c45e014e8%22%5D%2Fid',
            body=self.load_fixture('fixtures/GET/queue_item_by_job_id.xml'),
            match_querystring=True)
        responses.add(
            responses.GET, 'http://jenkins.example.com/queue/item/13/api/json/',
            body=self.load_fixture('fixtures/GET/queue_details_building.json'))
        responses.add(
            responses.GET, 'http://jenkins.example.com/job/server/2/api/json/',
            body=self.load_fixture('fixtures/GET/job_details_success.json'))
        responses.add(
            responses.GET, 'http://jenkins.example.com/job/server/2/logText/progressiveText/?start=0',
            match_querystring=True,
            adding_headers={'X-Text-Size': '7'},
            body='Foo bar')
        responses.add(
            responses.GET, 'http://jenkins.example.com/computer/server-ubuntu-10.04%20(ami-746cf244)%20(i-836023b7)/config.xml',
            body=self.load_fixture('fixtures/GET/node_config.xml'))

        build = self.create_build(self.project)
        job = self.create_job(
            build=build,
            id=UUID('81d1596fd4d642f4a6bdf86c45e014e8'))

        plan = self.create_plan(self.project)
        self.create_step(
            plan, order=0, implementation='changes.backends.jenkins.buildstep.JenkinsBuildStep', data={
                'job_name': 'server',
                'jenkins_url': 'http://jenkins.example.com',
            },
        )
        self.create_job_plan(job, plan)

        job_id = job.id.hex
        build_id = build.id.hex

        create_job.delay(
            job_id=job_id,
            task_id=job_id,
            parent_task_id=build_id,
        )

        job = Job.query.get(job_id)

        assert job.status == Status.finished
        assert job.result == Result.passed
        assert job.date_created
        assert job.date_started
        assert job.date_finished

        phase_list = job.phases

        assert len(phase_list) == 1

        assert phase_list[0].status == Status.finished
        assert phase_list[0].result == Result.passed
        assert phase_list[0].date_created
        assert phase_list[0].date_started
        assert phase_list[0].date_finished

        step_list = phase_list[0].steps

        assert len(step_list) == 1

        assert step_list[0].status == Status.finished
        assert step_list[0].result == Result.passed
        assert step_list[0].date_created
        assert step_list[0].date_started
        assert step_list[0].date_finished
        assert step_list[0].data == {
            'item_id': '13',
            'queued': False,
            'log_offset': 7,
            'job_name': 'server',
            'build_no': 2,
            'uri': 'https://jenkins.build.itc.dropbox.com/job/server/2/',
            'master': 'http://jenkins.example.com',
        }

        node = step_list[0].node
        assert node.label == 'server-ubuntu-10.04 (ami-746cf244) (i-836023b7)'
        assert [n.label for n in node.clusters] == ['server-runner']

        source = LogSource.query.filter_by(job=job).first()
        assert source.name == step_list[0].label
        assert source.step == step_list[0]
        assert source.project == self.project
        assert source.date_created == job.date_started

        chunks = list(LogChunk.query.filter_by(
            source=source,
        ).order_by(LogChunk.date_created.asc()))
        assert len(chunks) == 1
        assert chunks[0].job_id == job.id
        assert chunks[0].project_id == self.project.id
        assert chunks[0].offset == 0
        assert chunks[0].size == 7
        assert chunks[0].text == 'Foo bar'
Example #10
0
    def test_full(self):
        from changes.jobs.create_job import create_job

        # TODO: move this out of this file and integrate w/ buildstep
        responses.add(
            responses.POST, 'http://jenkins.example.com/job/server/build/api/json/',
            body='',
            status=201)
        responses.add(
            responses.GET, 'http://jenkins.example.com/queue/api/xml/?xpath=%2Fqueue%2Fitem%5Baction%2Fparameter%2Fname%3D%22CHANGES_BID%22+and+action%2Fparameter%2Fvalue%3D%2281d1596fd4d642f4a6bdf86c45e014e8%22%5D%2Fid',
            body=self.load_fixture('fixtures/GET/queue_item_by_job_id.xml'),
            match_querystring=True)
        responses.add(
            responses.GET, 'http://jenkins.example.com/queue/item/13/api/json/',
            body=self.load_fixture('fixtures/GET/queue_details_building.json'))
        responses.add(
            responses.GET, 'http://jenkins.example.com/job/server/2/api/json/',
            body=self.load_fixture('fixtures/GET/job_details_with_test_report.json'))
        responses.add(
            responses.GET, 'http://jenkins.example.com/job/server/2/testReport/api/json/',
            body=self.load_fixture('fixtures/GET/job_test_report.json'))
        responses.add(
            responses.GET, 'http://jenkins.example.com/job/server/2/logText/progressiveHtml/?start=0',
            match_querystring=True,
            adding_headers={'X-Text-Size': '7'},
            body='Foo bar')

        build = self.create_build(self.project)
        job = self.create_job(
            build=build,
            id=UUID('81d1596fd4d642f4a6bdf86c45e014e8'))

        plan = self.create_plan()
        plan.projects.append(self.project)
        self.create_step(
            plan, order=0, implementation='changes.backends.jenkins.buildstep.JenkinsBuildStep', data={
                'job_name': 'server',
            },
        )
        self.create_job_plan(job, plan)

        job_id = job.id.hex
        build_id = build.id.hex

        create_job.delay(
            job_id=job_id,
            task_id=job_id,
            parent_task_id=build_id,
        )

        job = Job.query.get(job_id)

        assert job.status == Status.finished
        assert job.result == Result.passed
        assert job.date_created
        assert job.date_started
        assert job.date_finished

        phase_list = job.phases

        assert len(phase_list) == 1

        assert phase_list[0].status == Status.finished
        assert phase_list[0].result == Result.passed
        assert phase_list[0].date_created
        assert phase_list[0].date_started
        assert phase_list[0].date_finished

        step_list = phase_list[0].steps

        assert len(step_list) == 1

        assert step_list[0].status == Status.finished
        assert step_list[0].result == Result.passed
        assert step_list[0].date_created
        assert step_list[0].date_started
        assert step_list[0].date_finished
        assert step_list[0].data == {
            'item_id': '13',
            'queued': False,
            'log_offset': 7,
            'job_name': 'server',
            'build_no': 2,
        }

        test_list = sorted(TestCase.query.filter_by(job=job), key=lambda x: x.duration)

        assert len(test_list) == 2
        assert test_list[0].name == 'Test'
        assert test_list[0].package == 'tests.changes.handlers.test_xunit'
        assert test_list[0].result == Result.skipped
        assert test_list[0].message == 'collection skipped'
        assert test_list[0].duration == 0

        assert test_list[1].name == 'test_simple'
        assert test_list[1].package == 'tests.changes.api.test_build_details.BuildDetailsTest'
        assert test_list[1].result == Result.passed
        assert test_list[1].message == ''
        assert test_list[1].duration == 155

        source = LogSource.query.filter_by(job=job).first()
        assert source.name == 'server #2'
        assert source.step == step_list[0]
        assert source.project == self.project
        assert source.date_created == job.date_started

        chunks = list(LogChunk.query.filter_by(
            source=source,
        ).order_by(LogChunk.date_created.asc()))
        assert len(chunks) == 1
        assert chunks[0].job_id == job.id
        assert chunks[0].project_id == self.project.id
        assert chunks[0].offset == 0
        assert chunks[0].size == 7
        assert chunks[0].text == 'Foo bar'
Example #11
0
def execute_build(build, snapshot_id, no_snapshot):
    if no_snapshot:
        assert snapshot_id is None, 'Cannot specify snapshot with no_snapshot option'
    # TODO(dcramer): most of this should be abstracted into sync_build as if it
    # were a "im on step 0, create step 1"
    project = build.project

    # We choose a snapshot before creating jobplans. This is so that different
    # jobplans won't end up using different snapshots in a build.
    if snapshot_id is None and not no_snapshot:
        snapshot = Snapshot.get_current(project.id)
        if snapshot:
            snapshot_id = snapshot.id

    plans = get_build_plans(project)

    options = ItemOptionsHelper.get_options([p.id for p in plans],
                                            ['snapshot.require'])

    jobs = []
    for plan in get_build_plans(project):
        if (options[plan.id].get('snapshot.require', '0') == '1'
                and not no_snapshot
                and SnapshotImage.get(plan, snapshot_id) is None):
            logging.warning(
                'Skipping plan %r (%r) because no snapshot exists yet',
                plan.label, project.slug)
            continue

        job = Job(
            build=build,
            build_id=build.id,
            project=project,
            project_id=project.id,
            source=build.source,
            source_id=build.source_id,
            status=build.status,
            label=plan.label,
        )

        db.session.add(job)

        jobplan = JobPlan.build_jobplan(plan, job, snapshot_id=snapshot_id)

        db.session.add(jobplan)

        jobs.append(job)

    db.session.commit()

    for job in jobs:
        create_job.delay(
            job_id=job.id.hex,
            task_id=job.id.hex,
            parent_task_id=job.build_id.hex,
        )

    db.session.commit()

    sync_build.delay(
        build_id=build.id.hex,
        task_id=build.id.hex,
    )

    return build
Example #12
0
    def test_full(self):
        from changes.jobs.create_job import create_job

        job_id = "81d1596fd4d642f4a6bdf86c45e014e8"

        # TODO: move this out of this file and integrate w/ buildstep
        responses.add(responses.POST, "http://jenkins.example.com/job/server/build", body="", status=201)
        responses.add(
            responses.GET,
            re.compile(
                "http://jenkins\\.example\\.com/queue/api/xml/\\?xpath=%2Fqueue%2Fitem%5Baction%2Fparameter%2Fname%3D%22CHANGES_BID%22\\+and\\+action%2Fparameter%2Fvalue%3D%22.*?%22%5D%2Fid&wrapper=x"
            ),
            body=self.load_fixture("fixtures/GET/queue_item_by_job_id.xml"),
        )
        responses.add(
            responses.GET,
            "http://jenkins.example.com/queue/item/13/api/json/",
            body=self.load_fixture("fixtures/GET/queue_details_building.json"),
        )
        responses.add(
            responses.GET,
            "http://jenkins.example.com/job/server/2/api/json/",
            body=self.load_fixture("fixtures/GET/job_details_success.json"),
        )
        responses.add(
            responses.GET,
            "http://jenkins.example.com/job/server/2/logText/progressiveText/?start=0",
            match_querystring=True,
            adding_headers={"X-Text-Size": "7"},
            body="Foo bar",
        )
        responses.add(
            responses.GET,
            "http://jenkins.example.com/computer/server-ubuntu-10.04%20(ami-746cf244)%20(i-836023b7)/config.xml",
            body=self.load_fixture("fixtures/GET/node_config.xml"),
        )

        artifacts_store_requests_re = re.compile(r"http://localhost:1234/buckets/.+/artifacts")
        # Simulate test type which doesn't interact with artifacts store.
        responses.add(responses.GET, artifacts_store_requests_re, body="", status=404)

        build = self.create_build(self.project)
        job = self.create_job(build=build, id=UUID(job_id))

        plan = self.create_plan(self.project)
        self.create_step(
            plan,
            order=0,
            implementation="changes.backends.jenkins.buildstep.JenkinsBuildStep",
            data={"job_name": "server", "jenkins_url": "http://jenkins.example.com"},
        )
        self.create_job_plan(job, plan)

        job_id = job.id.hex
        build_id = build.id.hex

        create_job.delay(job_id=job_id, task_id=job_id, parent_task_id=build_id)

        job = Job.query.get(job_id)

        assert job.status == Status.finished
        assert job.result == Result.passed
        assert job.date_created
        assert job.date_started
        assert job.date_finished

        phase_list = job.phases

        assert len(phase_list) == 1

        assert phase_list[0].status == Status.finished
        assert phase_list[0].result == Result.passed
        assert phase_list[0].date_created
        assert phase_list[0].date_started
        assert phase_list[0].date_finished

        step_list = phase_list[0].steps

        assert len(step_list) == 1

        assert step_list[0].status == Status.finished
        assert step_list[0].result == Result.passed
        assert step_list[0].date_created
        assert step_list[0].date_started
        assert step_list[0].date_finished
        assert step_list[0].data == {
            "item_id": "13",
            "queued": False,
            "log_offset": 7,
            "job_name": "server",
            "build_no": 2,
            "uri": "https://jenkins.build.itc.dropbox.com/job/server/2/",
            "master": "http://jenkins.example.com",
        }

        node = step_list[0].node
        assert node.label == "server-ubuntu-10.04 (ami-746cf244) (i-836023b7)"
        assert [n.label for n in node.clusters] == ["server-runner"]

        source = LogSource.query.filter_by(job=job).first()
        assert source.name == step_list[0].label
        assert source.step == step_list[0]
        assert source.project == self.project
        assert source.date_created == job.date_started

        chunks = list(LogChunk.query.filter_by(source=source).order_by(LogChunk.date_created.asc()))
        assert len(chunks) == 1
        assert chunks[0].job_id == job.id
        assert chunks[0].project_id == self.project.id
        assert chunks[0].offset == 0
        assert chunks[0].size == 7
        assert chunks[0].text == "Foo bar"
    def post(self, project_id):
        """Initiates a new snapshot for this project."""
        project = Project.get(project_id)
        if not project:
            return '', 404

        args = self.post_parser.parse_args()

        repository = project.repository

        try:
            revision = identify_revision(repository, args.sha)
        except MissingRevision:
            # if the default fails, we absolutely can't continue and the
            # client should send a valid revision
            return '{"error": "Unable to find a matching revision."}', 400

        if revision:
            sha = revision.sha
        else:
            sha = args.sha

        plan_list = get_snapshottable_plans(project)

        if not plan_list:
            return '{"error": "No snapshottable plans associated with project."}', 400

        source, _ = get_or_create(Source,
                                  where={
                                      'repository': repository,
                                      'revision_sha': sha,
                                      'patch_id': None,
                                  })

        build = Build(
            source_id=source.id,
            source=source,
            project_id=project.id,
            project=project,
            label='Create Snapshot',
            status=Status.queued,
            cause=Cause.snapshot,
            target=sha[:12],
        )
        db.session.add(build)

        # TODO(dcramer): this needs to update with the build result
        snapshot = Snapshot(
            project_id=project.id,
            source_id=source.id,
            build_id=build.id,
            status=SnapshotStatus.pending,
        )
        db.session.add(snapshot)

        jobs = []
        for plan in plan_list:
            job = Job(
                build=build,
                build_id=build.id,
                project=project,
                project_id=project.id,
                source=build.source,
                source_id=build.source_id,
                status=build.status,
                label='Create Snapshot: %s' % (plan.label, ),
            )
            db.session.add(job)

            jobplan = JobPlan.build_jobplan(plan, job)
            db.session.add(jobplan)

            image = SnapshotImage(
                job=job,
                snapshot=snapshot,
                plan=plan,
            )
            db.session.add(image)

            jobs.append(job)

        db.session.commit()

        for job in jobs:
            create_job.delay(
                job_id=job.id.hex,
                task_id=job.id.hex,
                parent_task_id=job.build_id.hex,
            )

        db.session.commit()

        sync_build.delay(
            build_id=build.id.hex,
            task_id=build.id.hex,
        )

        return self.respond(snapshot)
Example #14
0
    def test_full(self):
        from changes.jobs.create_job import create_job
        job_id = '81d1596fd4d642f4a6bdf86c45e014e8'

        # TODO: move this out of this file and integrate w/ buildstep
        responses.add(
            responses.POST, 'http://jenkins.example.com/job/server/build',
            body='',
            status=201)
        responses.add(
            responses.GET,
            re.compile('http://jenkins\\.example\\.com/queue/api/xml/\\?xpath=%2Fqueue%2Fitem%5Baction%2Fparameter%2Fname%3D%22CHANGES_BID%22\\+and\\+action%2Fparameter%2Fvalue%3D%22.*?%22%5D%2Fid&wrapper=x'),
            body=self.load_fixture('fixtures/GET/queue_item_by_job_id.xml'))
        responses.add(
            responses.GET, 'http://jenkins.example.com/queue/item/13/api/json/',
            body=self.load_fixture('fixtures/GET/queue_details_building.json'))
        responses.add(
            responses.GET, 'http://jenkins.example.com/job/server/2/api/json/',
            body=self.load_fixture('fixtures/GET/job_details_success.json'))
        responses.add(
            responses.GET, 'http://jenkins.example.com/job/server/2/logText/progressiveText/?start=0',
            match_querystring=True,
            adding_headers={'X-Text-Size': '7'},
            body='Foo bar')
        responses.add(
            responses.GET, 'http://jenkins.example.com/computer/server-ubuntu-10.04%20(ami-746cf244)%20(i-836023b7)/config.xml',
            body=self.load_fixture('fixtures/GET/node_config.xml'))

        artifacts_store_requests_re = re.compile(r'http://localhost:1234/buckets/.+/artifacts')
        # Simulate test type which doesn't interact with artifacts store.
        responses.add(
            responses.GET, artifacts_store_requests_re,
            body='',
            status=404)

        build = self.create_build(self.project)
        job = self.create_job(
            build=build,
            id=UUID(job_id))

        plan = self.create_plan(self.project)
        self.create_step(
            plan, order=0, implementation='changes.backends.jenkins.buildstep.JenkinsBuildStep', data={
                'job_name': 'server',
                'jenkins_url': 'http://jenkins.example.com',
            },
        )
        self.create_job_plan(job, plan)

        job_id = job.id.hex
        build_id = build.id.hex

        create_job.delay(
            job_id=job_id,
            task_id=job_id,
            parent_task_id=build_id,
        )

        job = Job.query.get(job_id)

        assert job.status == Status.finished
        assert job.result == Result.passed
        assert job.date_created
        assert job.date_started
        assert job.date_finished

        phase_list = job.phases

        assert len(phase_list) == 1

        assert phase_list[0].status == Status.finished
        assert phase_list[0].result == Result.passed
        assert phase_list[0].date_created
        assert phase_list[0].date_started
        assert phase_list[0].date_finished

        step_list = phase_list[0].steps

        assert len(step_list) == 1

        assert step_list[0].status == Status.finished
        assert step_list[0].result == Result.passed
        assert step_list[0].date_created
        assert step_list[0].date_started
        assert step_list[0].date_finished
        assert step_list[0].data == {
            'item_id': '13',
            'queued': False,
            'log_offset': 7,
            'log_artifact_name': JENKINS_LOG_NAME,
            'jenkins_bucket_name': step_list[0].id.hex + '-jenkins',
            'job_name': 'server',
            'build_no': 2,
            'uri': 'https://jenkins.build.itc.dropbox.com/job/server/2/',
            'master': 'http://jenkins.example.com',
        }

        node = step_list[0].node
        assert node.label == 'server-ubuntu-10.04 (ami-746cf244) (i-836023b7)'
        assert [n.label for n in node.clusters] == ['server-runner']

        source = LogSource.query.filter_by(job=job).first()
        assert source.name == JENKINS_LOG_NAME
        assert source.step == step_list[0]
        assert source.project == self.project
        assert source.date_created == job.date_started

        bucket_name = step_list[0].id.hex + '-jenkins'
        artifact_name = step_list[0].data['log_artifact_name']
        artifact = ArtifactStoreMock('').get_artifact(bucket_name, artifact_name)
        assert artifact.name == artifact_name
        assert artifact.path == JENKINS_LOG_NAME
        assert artifact.size == 7
        assert artifact.state == ArtifactState.UPLOADED
        assert ArtifactStoreMock('').get_artifact_content(bucket_name, artifact_name).getvalue() == 'Foo bar'
    def test_full(self):
        from changes.jobs.create_job import create_job
        job_id = '81d1596fd4d642f4a6bdf86c45e014e8'

        # TODO: move this out of this file and integrate w/ buildstep
        responses.add(responses.POST,
                      'http://jenkins.example.com/job/server/build',
                      body='',
                      status=201)
        responses.add(
            responses.GET,
            re.compile(
                'http://jenkins\\.example\\.com/queue/api/xml/\\?xpath=%2Fqueue%2Fitem%5Baction%2Fparameter%2Fname%3D%22CHANGES_BID%22\\+and\\+action%2Fparameter%2Fvalue%3D%22.*?%22%5D%2Fid&wrapper=x'
            ),
            body=self.load_fixture('fixtures/GET/queue_item_by_job_id.xml'))
        responses.add(
            responses.GET,
            'http://jenkins.example.com/queue/item/13/api/json/',
            body=self.load_fixture('fixtures/GET/queue_details_building.json'))
        responses.add(
            responses.GET,
            'http://jenkins.example.com/job/server/2/api/json/',
            body=self.load_fixture('fixtures/GET/job_details_success.json'))
        responses.add(
            responses.GET,
            'http://jenkins.example.com/job/server/2/logText/progressiveText/?start=0',
            match_querystring=True,
            adding_headers={'X-Text-Size': '7'},
            body='Foo bar')
        responses.add(
            responses.GET,
            'http://jenkins.example.com/computer/server-ubuntu-10.04%20(ami-746cf244)%20(i-836023b7)/config.xml',
            body=self.load_fixture('fixtures/GET/node_config.xml'))

        artifacts_store_requests_re = re.compile(
            r'http://localhost:1234/buckets/.+/artifacts')
        # Simulate test type which doesn't interact with artifacts store.
        responses.add(responses.GET,
                      artifacts_store_requests_re,
                      body='',
                      status=404)

        build = self.create_build(self.project)
        job = self.create_job(build=build, id=UUID(job_id))

        plan = self.create_plan(self.project)
        self.create_step(
            plan,
            order=0,
            implementation=
            'changes.backends.jenkins.buildstep.JenkinsBuildStep',
            data={
                'job_name': 'server',
                'jenkins_url': 'http://jenkins.example.com',
            },
        )
        self.create_job_plan(job, plan)

        job_id = job.id.hex
        build_id = build.id.hex

        create_job.delay(
            job_id=job_id,
            task_id=job_id,
            parent_task_id=build_id,
        )

        job = Job.query.get(job_id)

        assert job.status == Status.finished
        assert job.result == Result.passed
        assert job.date_created
        assert job.date_started
        assert job.date_finished

        phase_list = job.phases

        assert len(phase_list) == 1

        assert phase_list[0].status == Status.finished
        assert phase_list[0].result == Result.passed
        assert phase_list[0].date_created
        assert phase_list[0].date_started
        assert phase_list[0].date_finished

        step_list = phase_list[0].steps

        assert len(step_list) == 1

        assert step_list[0].status == Status.finished
        assert step_list[0].result == Result.passed
        assert step_list[0].date_created
        assert step_list[0].date_started
        assert step_list[0].date_finished
        assert step_list[0].data == {
            'item_id': '13',
            'queued': False,
            'log_offset': 7,
            'log_artifact_name': JENKINS_LOG_NAME,
            'jenkins_bucket_name': step_list[0].id.hex + '-jenkins',
            'job_name': 'server',
            'build_no': 2,
            'uri': 'https://jenkins.build.itc.dropbox.com/job/server/2/',
            'master': 'http://jenkins.example.com',
        }

        node = step_list[0].node
        assert node.label == 'server-ubuntu-10.04 (ami-746cf244) (i-836023b7)'
        assert [n.label for n in node.clusters] == ['server-runner']

        source = LogSource.query.filter_by(job=job).first()
        assert source.name == JENKINS_LOG_NAME
        assert source.step == step_list[0]
        assert source.project == self.project
        assert source.date_created == job.date_started

        bucket_name = step_list[0].id.hex + '-jenkins'
        artifact_name = step_list[0].data['log_artifact_name']
        artifact = ArtifactStoreMock('').get_artifact(bucket_name,
                                                      artifact_name)
        assert artifact.name == artifact_name
        assert artifact.path == JENKINS_LOG_NAME
        assert artifact.size == 7
        assert artifact.state == ArtifactState.UPLOADED
        assert ArtifactStoreMock('').get_artifact_content(
            bucket_name, artifact_name).getvalue() == 'Foo bar'
Example #16
0
    def test_full(self):
        from changes.jobs.create_job import create_job

        # TODO: move this out of this file and integrate w/ buildstep
        responses.add(
            responses.POST, 'http://jenkins.example.com/job/server/build/api/json/',
            body='',
            status=201)
        responses.add(
            responses.GET, 'http://jenkins.example.com/queue/api/xml/?xpath=%2Fqueue%2Fitem%5Baction%2Fparameter%2Fname%3D%22CHANGES_BID%22+and+action%2Fparameter%2Fvalue%3D%2281d1596fd4d642f4a6bdf86c45e014e8%22%5D%2Fid',
            body=self.load_fixture('fixtures/GET/queue_item_by_job_id.xml'),
            match_querystring=True)
        responses.add(
            responses.GET, 'http://jenkins.example.com/queue/item/13/api/json/',
            body=self.load_fixture('fixtures/GET/queue_details_building.json'))
        responses.add(
            responses.GET, 'http://jenkins.example.com/job/server/2/api/json/',
            body=self.load_fixture('fixtures/GET/job_details_with_test_report.json'))
        responses.add(
            responses.GET, 'http://jenkins.example.com/job/server/2/testReport/api/json/',
            body=self.load_fixture('fixtures/GET/job_test_report.json'))
        responses.add(
            responses.GET, 'http://jenkins.example.com/job/server/2/logText/progressiveHtml/?start=0',
            match_querystring=True,
            adding_headers={'X-Text-Size': '7'},
            body='Foo bar')

        build = self.create_build(self.project)
        job = self.create_job(
            build=build,
            id=UUID('81d1596fd4d642f4a6bdf86c45e014e8'))

        plan = self.create_plan()
        plan.projects.append(self.project)
        self.create_step(
            plan, order=0, implementation='changes.backends.jenkins.buildstep.JenkinsBuildStep', data={
                'job_name': 'server',
            },
        )
        self.create_job_plan(job, plan)

        job_id = job.id.hex
        build_id = build.id.hex

        create_job.delay(
            job_id=job_id,
            task_id=job_id,
            parent_task_id=build_id,
        )

        job = Job.query.get(job_id)

        assert job.status == Status.finished
        assert job.result == Result.passed
        assert job.date_created
        assert job.date_started
        assert job.date_finished

        phase_list = job.phases

        assert len(phase_list) == 1

        assert phase_list[0].status == Status.finished
        assert phase_list[0].result == Result.passed
        assert phase_list[0].date_created
        assert phase_list[0].date_started
        assert phase_list[0].date_finished

        step_list = phase_list[0].steps

        assert len(step_list) == 1

        assert step_list[0].status == Status.finished
        assert step_list[0].result == Result.passed
        assert step_list[0].date_created
        assert step_list[0].date_started
        assert step_list[0].date_finished
        assert step_list[0].data == {
            'item_id': '13',
            'queued': False,
            'log_offset': 7,
            'job_name': 'server',
            'build_no': 2,
        }

        test_list = sorted(TestCase.query.filter_by(job=job), key=lambda x: x.duration)

        assert len(test_list) == 2
        assert test_list[0].name == 'tests.changes.handlers.test_xunit.Test'
        assert test_list[0].result == Result.skipped
        assert test_list[0].message == 'collection skipped'
        assert test_list[0].duration == 0

        assert test_list[1].name == 'tests.changes.api.test_build_details.BuildDetailsTest.test_simple'
        assert test_list[1].result == Result.passed
        assert test_list[1].message == ''
        assert test_list[1].duration == 155

        source = LogSource.query.filter_by(job=job).first()
        assert source.name == 'server #2'
        assert source.step == step_list[0]
        assert source.project == self.project
        assert source.date_created == job.date_started

        chunks = list(LogChunk.query.filter_by(
            source=source,
        ).order_by(LogChunk.date_created.asc()))
        assert len(chunks) == 1
        assert chunks[0].job_id == job.id
        assert chunks[0].project_id == self.project.id
        assert chunks[0].offset == 0
        assert chunks[0].size == 7
        assert chunks[0].text == 'Foo bar'