From d7c7e547d40f4a3b153a1078cf5c44479ba14b29 Mon Sep 17 00:00:00 2001 From: Christophe Monniez Date: Tue, 22 Jan 2019 15:59:03 +0100 Subject: [PATCH] [FIX] runbot: write build results in a separate job When a build reach the job30_run method, results from a previous testing methods are computed. With the previous commit 8c73e6a90133c8915ced619a31e48b10fb01b70d this job can now be skipped. In that case, the results are not set. With this commit, the results are computed in a separate method. --- runbot/models/build.py | 13 +++++++--- runbot/tests/__init__.py | 1 + runbot/tests/test_jobs.py | 4 +-- runbot/tests/test_schedule.py | 49 +++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 runbot/tests/test_schedule.py diff --git a/runbot/models/build.py b/runbot/models/build.py index 5ae5aae7..576b955b 100644 --- a/runbot/models/build.py +++ b/runbot/models/build.py @@ -839,10 +839,9 @@ class runbot_build(models.Model): build._log('coverage_result', 'Coverage file not found') return -2 # nothing to wait for - @runbot_job('running') - def _job_30_run(self, build, log_path): - # adjust job_end to record an accurate job_20 job_time - build._log('run', 'Start running build %s' % build.dest) + @runbot_job('testing', 'running') + def _job_29_results(self, build, log_path): + build._log('run', 'Getting results for build %s' % build.dest) log_all = build._path('logs', 'job_20_test_all.txt') log_time = time.localtime(os.path.getmtime(log_all)) v = { @@ -859,6 +858,12 @@ class runbot_build(models.Model): v['result'] = "ko" build.write(v) build._github_status() + return -2 + + @runbot_job('running') + def _job_30_run(self, build, log_path): + # adjust job_end to record an accurate job_20 job_time + build._log('run', 'Start running build %s' % build.dest) # run server cmd, mods = build._cmd() if os.path.exists(build._server('addons/im_livechat')): diff --git a/runbot/tests/__init__.py b/runbot/tests/__init__.py index 79c8d97b..7a4df54d 100644 --- a/runbot/tests/__init__.py +++ b/runbot/tests/__init__.py @@ -4,3 +4,4 @@ from . import test_build from . import test_jobs from . import test_frontend from . import test_job_types +from . import test_schedule diff --git a/runbot/tests/test_jobs.py b/runbot/tests/test_jobs.py index 669680de..493ec266 100644 --- a/runbot/tests/test_jobs.py +++ b/runbot/tests/test_jobs.py @@ -27,7 +27,7 @@ class Test_Jobs(common.TransactionCase): @patch('odoo.addons.runbot.models.build.time.localtime') @patch('odoo.addons.runbot.models.build.docker_run') @patch('odoo.addons.runbot.models.build.grep') - def test_job_30_failed(self, mock_grep, mock_docker_run, mock_localtime, mock_getmtime, mock_cmd, mock_github, mock_domain, mock_docker_get_gateway): + def test_job_29_failed(self, mock_grep, mock_docker_run, mock_localtime, mock_getmtime, mock_cmd, mock_github, mock_domain, mock_docker_get_gateway): """ Test that a failed build sets the failure state on github """ a_time = datetime.datetime.now().strftime(DEFAULT_SERVER_DATETIME_FORMAT) mock_grep.return_value = False @@ -46,7 +46,7 @@ class Test_Jobs(common.TransactionCase): 'job_end': a_time }) self.assertFalse(build.result) - self.Build._job_30_run(build, '/tmp/x.log') + self.Build._job_29_results(build, '/tmp/x.log') self.assertEqual(build.result, 'ko') expected_status = { 'state': 'failure', diff --git a/runbot/tests/test_schedule.py b/runbot/tests/test_schedule.py new file mode 100644 index 00000000..fb8136f1 --- /dev/null +++ b/runbot/tests/test_schedule.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +import datetime +from unittest.mock import patch +from odoo.tests import common +import odoo + + +class TestSchedule(common.TransactionCase): + + def setUp(self): + # entering test mode to avoid that the _schedule method commits records + registry = odoo.registry() + registry.enter_test_mode() + self.addCleanup(registry.leave_test_mode) + super(TestSchedule, self).setUp() + self.Repo = self.env['runbot.repo'] + self.repo = self.Repo.create({'name': 'bla@example.com:foo/bar'}) + self.Branch = self.env['runbot.branch'] + self.branch = self.Branch.create({ + 'repo_id': self.repo.id, + 'name': 'refs/heads/master' + }) + self.Build = self.env['runbot.build'] + + @patch('odoo.addons.runbot.models.build.runbot_build._local_cleanup') + @patch('odoo.addons.runbot.models.build.os.makedirs') + @patch('odoo.addons.runbot.models.build.os.path.getmtime') + @patch('odoo.addons.runbot.models.build.docker_is_running') + def test_schedule_skip_running(self, mock_running, mock_getmtime, mock_makedirs, mock_localcleanup): + """ Test that results are set even when job_30_run is skipped """ + job_end_time = datetime.datetime.now() + mock_getmtime.return_value = job_end_time.timestamp() + + build = self.Build.create({ + 'state': 'testing', + 'branch_id': self.branch.id, + 'name': 'd0d0caca0000ffffffffffffffffffffffffffff', + 'port': '1234', + 'host': 'runbotxx', + 'job_type': 'testing', + 'job': 'job_20_test_all' + }) + domain = [('repo_id', 'in', (self.repo.id, )), ('branch_id.job_type', '!=', 'none')] + domain_host = domain + [('host', '=', 'runbotxx')] + build_ids = self.Build.search(domain_host + [('state', 'in', ['testing', 'running', 'deathrow'])]) + mock_running.return_value = False + build_ids._schedule() + self.assertEqual(build.state, 'done') + self.assertEqual(build.result, 'ko')