def test_in_progress(self, get_implementation, queue_delay): # Simulate test which doesn't interact with artifacts store. responses.add(responses.GET, SyncJobStepTest.ARTIFACTSTORE_REQUEST_RE, body='', status=404) implementation = mock.Mock() get_implementation.return_value = implementation def mark_in_progress(step): step.status = Status.in_progress project = self.create_project() build = self.create_build(project=project) job = self.create_job(build=build) plan = self.create_plan(project) self.create_step(plan, implementation='test', order=0) self.create_job_plan(job, plan) phase = self.create_jobphase(job) step = self.create_jobstep(phase) task = self.create_task( parent_id=job.id, task_id=step.id, task_name='sync_job_step', ) db.session.add(ItemStat(item_id=job.id, name='tests_missing', value=1)) db.session.commit() implementation.update_step.side_effect = mark_in_progress sync_job_step( step_id=step.id.hex, task_id=step.id.hex, parent_task_id=job.id.hex, ) implementation.update_step.assert_called_once_with(step=step) db.session.expire(step) db.session.expire(task) step = JobStep.query.get(step.id) assert step.status == Status.in_progress task = Task.query.get(task.id) assert task.status == Status.in_progress queue_delay.assert_any_call('sync_job_step', kwargs={ 'step_id': step.id.hex, 'task_id': step.id.hex, 'parent_task_id': job.id.hex, }, countdown=5)
def test_simple(self): project = self.create_project() previous_build = self.create_build(project, date_created=datetime( 2013, 9, 19, 22, 15, 23), status=Status.finished) build = self.create_build(project, date_created=datetime( 2013, 9, 19, 22, 15, 24)) job1 = self.create_job(build) job2 = self.create_job(build) phase = self.create_jobphase(job1) step = self.create_jobstep(phase) db.session.add( Event( item_id=build.id, type='green_build_notification', )) db.session.add( ItemStat( item_id=build.id, name='test_failures', value=2, )) db.session.add( FailureReason(project_id=project.id, build_id=build.id, job_id=job1.id, step_id=step.id, reason='test_failures')) db.session.commit() path = '/api/0/builds/{0}/'.format(build.id.hex) resp = self.client.get(path) assert resp.status_code == 200 data = self.unserialize(resp) assert data['id'] == build.id.hex assert len(data['jobs']) == 2 assert data['jobs'][0]['id'] == job1.id.hex assert data['jobs'][1]['id'] == job2.id.hex assert data['seenBy'] == [] assert data['testFailures']['total'] == 0 assert data['testFailures']['tests'] == [] assert data['testChanges'] == [] assert len(data['events']) == 1 assert len(data['failures']) == 1 assert data['failures'][0] == { 'id': 'test_failures', 'reason': 'There were <a href="http://example.com/projects/{0}/builds/{1}/tests/?result=failed">2 failing tests</a>.' .format( project.slug, build.id.hex, ), 'count': 1, }
def test_in_progress(self, get_implementation, queue_delay): implementation = mock.Mock() get_implementation.return_value = implementation def mark_in_progress(step): step.status = Status.in_progress project = self.create_project() build = self.create_build(project=project) job = self.create_job(build=build) plan = self.create_plan() self.create_step(plan, implementation='test', order=0) self.create_job_plan(job, plan) phase = self.create_jobphase(job) step = self.create_jobstep(phase) task = self.create_task( parent_id=job.id, task_id=step.id, task_name='sync_job_step', ) db.session.add(ItemStat(item_id=job.id, name='tests_missing', value=1)) db.session.commit() implementation.update_step.side_effect = mark_in_progress sync_job_step( step_id=step.id.hex, task_id=step.id.hex, parent_task_id=job.id.hex, ) get_implementation.assert_called_once_with() implementation.update_step.assert_called_once_with(step=step) db.session.expire(step) db.session.expire(task) step = JobStep.query.get(step.id) assert step.status == Status.in_progress task = Task.query.get(task.id) assert task.status == Status.in_progress queue_delay.assert_any_call('sync_job_step', kwargs={ 'step_id': step.id.hex, 'task_id': step.id.hex, 'parent_task_id': job.id.hex, }, countdown=5)
def test_simple(self, execute_build): build = self.create_build(project=self.project, status=Status.in_progress) job = self.create_job(build=build) phase = self.create_jobphase(job=job) step = self.create_jobstep(phase=phase) db.session.add(ItemStat(item_id=build.id.hex, name='test', value=1)) db.session.add(ItemStat(item_id=job.id.hex, name='test', value=1)) db.session.add(ItemStat(item_id=step.id.hex, name='test', value=1)) db.session.commit() path = '/api/0/builds/{0}/restart/'.format(build.id.hex) # build isnt finished resp = self.client.post(path, follow_redirects=True) assert resp.status_code == 400 build.status = Status.finished db.session.add(build) resp = self.client.post(path, follow_redirects=True) assert resp.status_code == 200 data = self.unserialize(resp) assert data['id'] == build.id.hex execute_build.assert_called_once_with(build=build) build = Build.query.get(build.id) assert build.status == Status.queued assert build.result == Result.unknown assert build.date_finished is None assert build.duration is None assert not Job.query.filter(Job.id == job.id).first() assert not JobStep.query.filter(JobStep.id == step.id).first() assert not ItemStat.query.filter( ItemStat.item_id.in_([build.id, job.id, step.id])).first()
def test_finished(self, publish_job_update, get_implementation, queue_delay): implementation = mock.Mock() get_implementation.return_value = implementation assert self.jobplan build, job, task = self.build, self.job, self.task step = job.phases[0].steps[0] self.create_task( task_name='sync_job_step', task_id=step.id, parent_id=job.id, status=Status.finished, ) self.create_test(job) self.create_test(job) db.session.add(ItemStat(item_id=step.id, name='tests_missing', value=1)) db.session.commit() sync_job( job_id=job.id.hex, task_id=job.id.hex, parent_task_id=build.id.hex, ) job = Job.query.get(job.id) assert job.status == Status.finished publish_job_update.assert_called_once_with(job) queue_delay.assert_any_call('update_project_plan_stats', kwargs={ 'project_id': self.project.id.hex, 'plan_id': self.plan.id.hex, }, countdown=1) queue_delay.assert_any_call('notify_job_finished', kwargs={ 'job_id': job.id.hex, }) task = Task.query.get(task.id) assert task.status == Status.finished stat = ItemStat.query.filter( ItemStat.item_id == job.id, ItemStat.name == 'tests_missing', ).first() assert stat.value == 1
def create_itemstat(self, item_id, name, value, **kwargs): """ Args: item_id (UUID): The ID of the item. name (str): Name of the stat. value (int): Value of the stat. **kwargs: Other fields. Returns: ItemStat: The newly created/committed ItemStat. """ stat = ItemStat(item_id=item_id, name=name, value=value, **kwargs) db.session.add(stat) db.session.commit() return stat
def test_simple(self, queue_delay): build = self.create_build( project=self.project, status=Status.unknown, result=Result.unknown, ) job_a = self.create_job( build=build, status=Status.finished, result=Result.failed, duration=5000, date_started=datetime(2013, 9, 19, 22, 15, 22), date_finished=datetime(2013, 9, 19, 22, 15, 25), ) job_b = self.create_job( build=build, status=Status.in_progress, result=Result.passed, duration=5000, date_started=datetime(2013, 9, 19, 22, 15, 23), date_finished=datetime(2013, 9, 19, 22, 15, 26), ) self.create_task( task_name='sync_job', parent_id=build.id, task_id=job_a.id, status=Status.finished, ) task_b = self.create_task( task_name='sync_job', parent_id=build.id, task_id=job_b.id, status=Status.in_progress, ) db.session.add( ItemStat(item_id=job_a.id, name='tests_missing', value=1)) db.session.add( ItemStat(item_id=job_b.id, name='tests_missing', value=0)) db.session.commit() sync_build(build_id=build.id.hex, task_id=build.id.hex) build = Build.query.get(build.id) assert build.status == Status.in_progress assert build.result == Result.failed task_b.status = Status.finished db.session.add(task_b) job_b.status = Status.finished db.session.add(job_b) sync_build(build_id=build.id.hex, task_id=build.id.hex) build = Build.query.get(build.id) assert build.status == Status.finished assert build.result == Result.failed assert build.duration == 4000 assert build.date_started == datetime(2013, 9, 19, 22, 15, 22) assert build.date_finished == datetime(2013, 9, 19, 22, 15, 26) queue_delay.assert_any_call('update_project_stats', kwargs={ 'project_id': self.project.id.hex, }, countdown=1) stat = ItemStat.query.filter( ItemStat.item_id == build.id, ItemStat.name == 'tests_missing', ).first() assert stat.value == 1
def test_finished(self, get_implementation, queue_delay, mock_fire_signal): implementation = mock.Mock() get_implementation.return_value = implementation assert self.jobplan build, job, task = self.build, self.job, self.task step = job.phases[0].steps[0] self.create_task( task_name='sync_job_step', task_id=step.id, parent_id=job.id, status=Status.finished, ) self.create_test(job) self.create_test(job) step2 = self.create_jobstep(self.jobphase, status=Status.finished, replacement_id=step.id) self.jobstep.status = Status.finished db.session.add(self.jobstep) db.session.add(ItemStat(item_id=step.id, name='tests_missing', value=1)) db.session.add(ItemStat(item_id=step.id, name='lines_covered', value=10)) db.session.add(ItemStat(item_id=step.id, name='lines_uncovered', value=25)) # this shouldn't affect aggregated stats since this jobstep is replaced db.session.add(ItemStat(item_id=step2.id, name='lines_uncovered', value=10)) db.session.commit() sync_job( job_id=job.id.hex, task_id=job.id.hex, parent_task_id=build.id.hex, ) implementation.validate_phase.assert_called_once_with(phase=self.job.phases[0]) implementation.validate.assert_called_once_with(job=self.job) job = Job.query.get(job.id) assert job.status == Status.finished queue_delay.assert_any_call('update_project_plan_stats', kwargs={ 'project_id': self.project.id.hex, 'plan_id': self.plan.id.hex, }, countdown=1) mock_fire_signal.delay.assert_any_call( signal='job.finished', kwargs={'job_id': job.id.hex}, ) task = Task.query.get(task.id) assert task.status == Status.finished stat = ItemStat.query.filter( ItemStat.item_id == job.id, ItemStat.name == 'tests_missing', ).first() assert stat.value == 1 stat = ItemStat.query.filter( ItemStat.item_id == job.id, ItemStat.name == 'lines_covered', ).first() assert stat.value == 10 stat = ItemStat.query.filter( ItemStat.item_id == job.id, ItemStat.name == 'lines_uncovered', ).first() assert stat.value == 25
def test_simple(self): now = datetime(2014, 4, 21, 22, 15, 22) project = self.create_project() path = '/api/0/projects/{0}/stats/'.format(project.id.hex) build1 = self.create_build( project=project, date_created=now, ) build2 = self.create_build( project=project, date_created=now - timedelta(hours=1), ) build3 = self.create_build( project=project, date_created=now - timedelta(days=1), ) build4 = self.create_build( project=project, date_created=now.replace(day=1) - timedelta(days=32), ) build5 = self.create_build( project=project, date_created=now.replace(day=1) - timedelta(days=370), ) db.session.add(ItemStat(name='test_count', value=1, item_id=build1.id)) db.session.add(ItemStat(name='test_count', value=3, item_id=build2.id)) db.session.add(ItemStat(name='test_count', value=6, item_id=build3.id)) db.session.add(ItemStat(name='test_count', value=20, item_id=build4.id)) db.session.add( ItemStat(name='test_count', value=100, item_id=build5.id)) db.session.commit() base_path = path + '?from=' + now.strftime('%s') + '&' # test hourly resp = self.client.get(base_path + 'stat=test_count&resolution=1h') assert resp.status_code == 200 data = self.unserialize(resp) assert len(data) == 24 assert data[0]['time'] == to_timestamp(datetime(2014, 4, 20, 22, 0)) assert data[0]['value'] == 6 for point in data[1:-1]: assert point['value'] == 0 assert data[-1]['time'] == to_timestamp(datetime(2014, 4, 21, 21, 0)) assert data[-1]['value'] == 3 # test weekly resp = self.client.get(base_path + 'stat=test_count&resolution=1w') assert resp.status_code == 200 data = self.unserialize(resp) assert len(data) == 26 for point in itertools.chain(data[:-8], data[-7:-1]): assert point['value'] == 0 assert data[-8]['time'] == to_timestamp(datetime(2014, 2, 24, 0, 0)) assert data[-8]['value'] == 20 assert data[-1]['time'] == to_timestamp(datetime(2014, 4, 14, 0, 0)) assert data[-1]['value'] == 6 # test daily resp = self.client.get(base_path + 'stat=test_count&resolution=1d') assert resp.status_code == 200 data = self.unserialize(resp) assert len(data) == 30 for point in data[:-1]: assert point['value'] == 0 assert data[-1]['time'] == to_timestamp(datetime(2014, 4, 20, 0, 0)) assert data[-1]['value'] == 6 # test monthly resp = self.client.get(base_path + 'stat=test_count&resolution=1m') assert resp.status_code == 200 data = self.unserialize(resp) assert len(data) == 12 for point in itertools.chain(data[:-2], data[-1:]): assert point['value'] == 0 assert data[-2]['time'] == to_timestamp(datetime(2014, 2, 1, 0, 0)) assert data[-2]['value'] == 20
def create_new_build(change, source, patch, project): date_started = datetime.utcnow() build = mock.build( author=change.author, project=project, source=source, message=change.message, result=Result.failed if random.randint(0, 3) == 1 else Result.unknown, status=Status.in_progress, date_started=date_started, ) build_task = fixtures.create_task( task_id=build.id, task_name='sync_build', data={'kwargs': { 'build_id': build.id.hex }}, ) db.session.add(ItemStat(item_id=build.id, name='lines_covered', value='5')) db.session.add( ItemStat(item_id=build.id, name='lines_uncovered', value='5')) db.session.add( ItemStat(item_id=build.id, name='diff_lines_covered', value='5')) db.session.add( ItemStat(item_id=build.id, name='diff_lines_uncovered', value='5')) db.session.commit() for x in xrange(0, random.randint(1, 3)): job = mock.job( build=build, change=change, status=Status.in_progress, result=build.result, ) fixtures.create_task( task_id=job.id.hex, parent_id=build_task.task_id, task_name='sync_job', data={'kwargs': { 'job_id': job.id.hex }}, ) db.session.commit() if patch: mock.file_coverage(project, job, patch) for step in JobStep.query.filter(JobStep.job == job): logsource = LogSource( job=job, project=job.project, step=step, name=step.label, ) db.session.add(logsource) db.session.commit() fixtures.create_artifact( step=step, name='junit.xml', ) fixtures.create_artifact( step=step, name='coverage.xml', ) offset = 0 for x in xrange(30): lc = mock.logchunk(source=logsource, offset=offset) db.session.commit() offset += lc.size return build