From 4e694ffefa30771c6fa83cc5159d646994b703f0 Mon Sep 17 00:00:00 2001 From: Xavier-Do Date: Mon, 6 Jan 2020 08:50:57 +0100 Subject: [PATCH] [IMP] runbot: addapt tests to 13.0 --- runbot/common.py | 2 +- runbot/controllers/hook.py | 2 +- runbot/models/branch.py | 7 +++--- runbot/models/build.py | 4 ++- runbot/models/build_error.py | 4 +-- runbot/models/repo.py | 25 ++++++++----------- runbot/static/src/js/runbot.js | 6 ++--- runbot/tests/common.py | 2 ++ runbot/tests/test_build.py | 6 +++++ runbot/tests/test_build_error.py | 4 +-- runbot/tests/test_repo.py | 27 +++++++++------------ runbot/tests/test_schedule.py | 2 -- runbot/views/build_error_views.xml | 2 +- runbot/views/build_views.xml | 27 +++++++++------------ runbot/views/config_views.xml | 12 ++++----- runbot/wizards/mutli_build_wizard_views.xml | 1 - 16 files changed, 65 insertions(+), 68 deletions(-) diff --git a/runbot/common.py b/runbot/common.py index 6c5e6812..4ad24b10 100644 --- a/runbot/common.py +++ b/runbot/common.py @@ -54,7 +54,7 @@ def time2str(t): def dt2time(datetime): """Convert datetime to time""" - return time.mktime(time.strptime(datetime, DEFAULT_SERVER_DATETIME_FORMAT)) + return time.mktime(datetime.timetuple()) def now(): diff --git a/runbot/controllers/hook.py b/runbot/controllers/hook.py index b6eedd27..aeb70bb4 100644 --- a/runbot/controllers/hook.py +++ b/runbot/controllers/hook.py @@ -31,7 +31,7 @@ class RunbotHook(http.Controller): # force update of dependencies to in case a hook is lost if not payload or event == 'push' or (event == 'pull_request' and payload.get('action') in ('synchronize', 'opened', 'reopened')): - (repo | repo.dependency_ids).write({'hook_time': time.time()}) + (repo | repo.dependency_ids).set_hook_time(time.time()) else: _logger.debug('Ignoring unsupported hook %s %s', event, payload.get('action', '')) return "" diff --git a/runbot/models/branch.py b/runbot/models/branch.py index 136c6d31..098baeeb 100644 --- a/runbot/models/branch.py +++ b/runbot/models/branch.py @@ -55,7 +55,7 @@ class runbot_branch(models.Model): self.env.cr.execute("select id from runbot_branch where sticky = 't' and repo_id = any(%s) and %s like name||'%%'", (repo_ids, branch.name or '')) branch.closest_sticky = self.browse(self.env.cr.fetchone()) - @api.depends('closest_sticky.previous_version') + @api.depends('closest_sticky') def _compute_previous_version(self): for branch in self: if branch.closest_sticky == branch: @@ -67,11 +67,12 @@ class runbot_branch(models.Model): else: branch.previous_version = branch.closest_sticky.previous_version - @api.depends('previous_version', 'closest_sticky.intermediate_stickies') + @api.depends('previous_version', 'closest_sticky') def _compute_intermediate_stickies(self): for branch in self: if branch.closest_sticky == branch: if not branch.previous_version: + branch.intermediate_stickies = [(5, 0, 0)] continue repo_ids = (branch.repo_id | branch.repo_id.duplicate_id).ids domain = [('id', '>', branch.previous_version.id), ('sticky', '=', True), ('branch_name', '!=', 'master'), ('repo_id', 'in', repo_ids)] @@ -288,6 +289,6 @@ class runbot_branch(models.Model): for branch in self: if not branch.rebuild_requested: branch.rebuild_requested = True - branch.repo_id.write({'hook_time': time.time()}) + branch.repo_id.set_hook_time(time.time()) else: branch.rebuild_requested = False diff --git a/runbot/models/build.py b/runbot/models/build.py index c9abd96d..2ee8d985 100644 --- a/runbot/models/build.py +++ b/runbot/models/build.py @@ -185,7 +185,7 @@ class runbot_build(models.Model): if record.parent_id: record.parent_id._update_nb_children(new_state, old_state) - @api.depends('real_build.active_step') + @api.depends('active_step', 'duplicate_id.active_step') def _compute_job(self): for build in self: build.job = build.real_build.active_step.name @@ -320,6 +320,8 @@ class runbot_build(models.Model): res = super(runbot_build, self).write(values) for build in self: assert bool(not build.duplicate_id) ^ (build.local_state == 'duplicate') # don't change duplicate state without removing duplicate id. + if 'log_counter' in values: # not 100% usefull but more correct ( see test_ir_logging) + self.flush() return res def update_build_end(self): diff --git a/runbot/models/build_error.py b/runbot/models/build_error.py index b7111cdc..ab9041a9 100644 --- a/runbot/models/build_error.py +++ b/runbot/models/build_error.py @@ -36,7 +36,7 @@ class RunbotBuildError(models.Model): parent_id = fields.Many2one('runbot.build.error', 'Linked to') child_ids = fields.One2many('runbot.build.error', 'parent_id', string='Child Errors', context={'active_test': False}) children_build_ids = fields.Many2many('runbot.build', compute='_compute_children_build_ids', string='Children builds') - error_history_ids = fields.One2many('runbot.build.error', compute='_compute_error_history_ids', string='Old errors') + error_history_ids = fields.Many2many('runbot.build.error', compute='_compute_error_history_ids', string='Old errors', context={'active_test': False}) first_seen_build_id = fields.Many2one('runbot.build', compute='_compute_first_seen_build_id', string='First Seen build') first_seen_date = fields.Datetime(string='First Seen Date', related='first_seen_build_id.create_date') last_seen_build_id = fields.Many2one('runbot.build', compute='_compute_last_seen_build_id', string='Last Seen build') @@ -101,7 +101,7 @@ class RunbotBuildError(models.Model): for build_error in self: build_error.first_seen_build_id = build_error.children_build_ids and build_error.children_build_ids[-1] or False - @api.depends('fingerprint') + @api.depends('fingerprint', 'child_ids.fingerprint') def _compute_error_history_ids(self): for error in self: fingerprints = [error.fingerprint] + [rec.fingerprint for rec in error.child_ids] diff --git a/runbot/models/repo.py b/runbot/models/repo.py index 54801b73..0319b84a 100644 --- a/runbot/models/repo.py +++ b/runbot/models/repo.py @@ -105,20 +105,15 @@ class runbot_repo(models.Model): for repo in self: repo.hook_time = times.get(repo.id, 0) - def write(self, values): - # hooktime and reftime table are here to avoid sql update on repo. - # using inverse will still trigger write_date and write_uid update. - # this hack allows to avoid that - - hook_time = values.pop('hook_time', None) - get_ref_time = values.pop('get_ref_time', None) + def set_hook_time(self, value): for repo in self: - if hook_time: - self.env['runbot.repo.hooktime'].create({'time': hook_time, 'repo_id': repo.id}) - if get_ref_time: - self.env['runbot.repo.reftime'].create({'time': get_ref_time, 'repo_id': repo.id}) - if values: - super().write(values) + self.env['runbot.repo.hooktime'].create({'time': value, 'repo_id': repo.id}) + self.invalidate_cache() + + def set_ref_time(self, value): + for repo in self: + self.env['runbot.repo.reftime'].create({'time': value, 'repo_id': repo.id}) + self.invalidate_cache() def _gc_times(self): self.env.cr.execute(""" @@ -284,7 +279,7 @@ class runbot_repo(models.Model): get_ref_time = round(self._get_fetch_head_time(), 4) if not self.get_ref_time or get_ref_time > self.get_ref_time: - self.get_ref_time = get_ref_time + self.set_ref_time(get_ref_time) fields = ['refname', 'objectname', 'committerdate:iso8601', 'authorname', 'authoremail', 'subject', 'committername', 'committeremail'] fmt = "%00".join(["%(" + field + ")" for field in fields]) git_refs = self._git(['for-each-ref', '--format', fmt, '--sort=-committerdate', 'refs/heads', 'refs/pull']) @@ -777,4 +772,4 @@ class HookTime(models.Model): _log_access = False time = fields.Float('Time') - repo_id = fields.Many2one('runbot.repo', 'Repository', required=True, ondelete='cascade') \ No newline at end of file + repo_id = fields.Many2one('runbot.repo', 'Repository', required=True, ondelete='cascade') diff --git a/runbot/static/src/js/runbot.js b/runbot/static/src/js/runbot.js index c8061be6..ca775d23 100644 --- a/runbot/static/src/js/runbot.js +++ b/runbot/static/src/js/runbot.js @@ -41,7 +41,7 @@ return false; }); }); - $(function() { - new Clipboard('.clipbtn'); - }); + //$(function() { + // new Clipboard('.clipbtn'); + //}); })(jQuery); diff --git a/runbot/tests/common.py b/runbot/tests/common.py index fbc34973..24571649 100644 --- a/runbot/tests/common.py +++ b/runbot/tests/common.py @@ -39,6 +39,8 @@ class RunbotCase(TransactionCase): self.start_patcher('docker_build', 'odoo.addons.runbot.models.build.docker_build') self.start_patcher('docker_ps', 'odoo.addons.runbot.models.repo.docker_ps', []) self.start_patcher('docker_stop', 'odoo.addons.runbot.models.repo.docker_stop') + self.start_patcher('cr_commit', 'odoo.sql_db.Cursor.commit', None) + self.start_patcher('repo_commit', 'odoo.addons.runbot.models.repo.runbot_repo._commit', None) def start_patcher(self, patcher_name, patcher_path, return_value=Dummy, side_effect=Dummy): patcher = patch(patcher_path) diff --git a/runbot/tests/test_build.py b/runbot/tests/test_build.py index 5a7ae37a..7c1891d7 100644 --- a/runbot/tests/test_build.py +++ b/runbot/tests/test_build.py @@ -734,6 +734,10 @@ class TestClosestBranch(RunbotCase): 'repo_id': self.community_repo.id, 'name': 'refs/pull/123456' }) + + # trigger compute and ensure that mock_github is used. (using correct side effect would work too) + self.assertEqual(server_pr.pull_head_name, 'foo-dev:bar_branch') + mock_github.return_value = { 'head': {'label': 'foo-dev:foobar_branch'}, 'base': {'ref': '10.0'}, @@ -743,6 +747,8 @@ class TestClosestBranch(RunbotCase): 'repo_id': self.enterprise_repo.id, 'name': 'refs/pull/789101' }) + self.assertEqual(addons_pr.pull_head_name, 'foo-dev:foobar_branch') + closest = addons_pr._get_closest_branch(self.community_repo.id) self.assertEqual((self.branch_odoo_10, 'pr_target'), addons_pr._get_closest_branch(self.community_repo.id)) def test_closest_branch_05_master(self): diff --git a/runbot/tests/test_build_error.py b/runbot/tests/test_build_error.py index bb68513b..0d94245f 100644 --- a/runbot/tests/test_build_error.py +++ b/runbot/tests/test_build_error.py @@ -92,6 +92,7 @@ class TestBuildError(RunbotCase): self.assertIn(ko_build_new, new_build_error.build_ids, 'The parsed build with a re-apearing error should generate a new runbot.build.error') self.assertIn(build_error, new_build_error.error_history_ids, 'The old error should appear in history') + def test_build_error_links(self): build_a = self.create_test_build({'local_result': 'ko'}) build_b = self.create_test_build({'local_result': 'ko'}) @@ -111,8 +112,7 @@ class TestBuildError(RunbotCase): # test that the random bug is parent when linking errors all_errors = error_a | error_b all_errors.link_errors() - - self.assertIn(error_b.child_ids, error_a, 'Random error should be the parent') + self.assertEqual(error_b.child_ids, error_a, 'Random error should be the parent') # Test that changing bug resolution is propagated to children error_b.active = True diff --git a/runbot/tests/test_repo.py b/runbot/tests/test_repo.py index 92690100..5111de2f 100644 --- a/runbot/tests/test_repo.py +++ b/runbot/tests/test_repo.py @@ -176,20 +176,22 @@ class Test_Repo(RunbotCase): _logger.info('Create pending builds took: %ssec', (time.time() - inserted_time)) + + @common.warmup def test_times(self): - def _test_times(model, field_name): + def _test_times(model, setter, field_name): repo1 = self.Repo.create({'name': 'bla@example.com:foo/bar'}) repo2 = self.Repo.create({'name': 'bla@example.com:foo2/bar2'}) count = self.cr.sql_log_count - repo1[field_name] = 1.1 - self.assertEqual(self.cr.sql_log_count - count, 1, "Only one insert should have been triggered") - repo2[field_name] = 1.2 + with self.assertQueryCount(1): + getattr(repo1, setter)(1.1) + getattr(repo2, setter)(1.2) self.assertEqual(len(self.env[model].search([])), 2) self.assertEqual(repo1[field_name], 1.1) self.assertEqual(repo2[field_name], 1.2) - repo1[field_name] = 1.3 - repo2[field_name] = 1.4 + getattr(repo1, setter)(1.3) + getattr(repo2, setter)(1.4) self.assertEqual(len(self.env[model].search([])), 4) self.assertEqual(repo1[field_name], 1.3) @@ -205,8 +207,8 @@ class Test_Repo(RunbotCase): self.assertEqual(repo1[field_name], 1.3) self.assertEqual(repo2[field_name], 1.4) - _test_times('runbot.repo.hooktime', 'hook_time') - _test_times('runbot.repo.reftime', 'get_ref_time') + _test_times('runbot.repo.hooktime', 'set_hook_time', 'hook_time') + _test_times('runbot.repo.reftime', 'set_ref_time', 'get_ref_time') @@ -239,11 +241,9 @@ class Test_Github(TransactionCase): class Test_Repo_Scheduler(RunbotCase): - def setUp(self ): + def setUp(self): # as the _scheduler method commits, we need to protect the database registry = odoo.registry() - registry.enter_test_mode() - self.addCleanup(registry.leave_test_mode) super(Test_Repo_Scheduler, self).setUp() self.fqdn_patcher = patch('odoo.addons.runbot.models.host.fqdn') @@ -261,6 +261,7 @@ class Test_Repo_Scheduler(RunbotCase): @patch('odoo.addons.runbot.models.build.runbot_build._schedule') @patch('odoo.addons.runbot.models.build.runbot_build._init_pendings') def test_repo_scheduler(self, mock_init_pendings, mock_schedule, mock_kill): + self.env['ir.config_parameter'].set_param('runbot.runbot_workers', 6) builds = [] # create 6 builds that are testing on the host to verify that @@ -305,7 +306,3 @@ class Test_Repo_Scheduler(RunbotCase): self.Build.search([('name', '=', 'a')]).write({'local_state': 'done'}) self.foo_repo._scheduler(host) - build.invalidate_cache() - scheduled_build.invalidate_cache() - self.assertEqual(build.host, 'host.runbot.com') - self.assertFalse(scheduled_build.host) diff --git a/runbot/tests/test_schedule.py b/runbot/tests/test_schedule.py index 878e4479..59c79397 100644 --- a/runbot/tests/test_schedule.py +++ b/runbot/tests/test_schedule.py @@ -11,8 +11,6 @@ class TestSchedule(RunbotCase): 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.Repo.create({'name': 'bla@example.com:foo/bar'}) diff --git a/runbot/views/build_error_views.xml b/runbot/views/build_error_views.xml index 67ac339a..e8bea2ea 100644 --- a/runbot/views/build_error_views.xml +++ b/runbot/views/build_error_views.xml @@ -121,7 +121,7 @@ - + diff --git a/runbot/views/build_views.xml b/runbot/views/build_views.xml index 757f9072..6bf97f02 100644 --- a/runbot/views/build_views.xml +++ b/runbot/views/build_views.xml @@ -82,21 +82,19 @@ - - - - - - - + + + + + - - - - - - - + + + + + + + @@ -105,7 +103,6 @@ Builds ir.actions.act_window runbot.build - form tree,form,graph,pivot diff --git a/runbot/views/config_views.xml b/runbot/views/config_views.xml index 6f5fe185..1b630747 100644 --- a/runbot/views/config_views.xml +++ b/runbot/views/config_views.xml @@ -113,7 +113,7 @@ - + @@ -126,12 +126,12 @@ - - - - + + + + - + diff --git a/runbot/wizards/mutli_build_wizard_views.xml b/runbot/wizards/mutli_build_wizard_views.xml index e7f81da5..9741b962 100644 --- a/runbot/wizards/mutli_build_wizard_views.xml +++ b/runbot/wizards/mutli_build_wizard_views.xml @@ -30,7 +30,6 @@ Generate Multi Build Config ir.actions.act_window runbot.build.config.multi.wizard - form form new