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