mirror of
https://github.com/odoo/runbot.git
synced 2025-03-15 23:45:44 +07:00
[IMP] runbot: refactor tests
A lot of things have to be mocked during runbot tests, as a consequence, a lot of patch decorators accumulate in a big stack uppon some tests methods. Also, a lot of mocks are used multiple times among tests. With this commit, a new RunbotClass is added that comes with patches ready to be started. A start_patcher helper method is available to start a patch and add the appropriate stop in a cleanup. Also, when a build is created in the tests, the _get_params method is always called, resulting in an annoying git warning. With this commit, a create_build method is added on the test class, that way the _get_params is always mocked when a build is created.
This commit is contained in:
parent
7d1283492b
commit
73f720a55c
@ -63,10 +63,14 @@ def now():
|
||||
|
||||
def grep(filename, string):
|
||||
if os.path.isfile(filename):
|
||||
return open(filename).read().find(string) != -1
|
||||
return find(filename, string) != -1
|
||||
return False
|
||||
|
||||
|
||||
def find(filename, string):
|
||||
return open(filename).read().find(string)
|
||||
|
||||
|
||||
def uniq_list(l):
|
||||
return OrderedDict.fromkeys(l).keys()
|
||||
|
||||
|
@ -14,7 +14,7 @@ import datetime
|
||||
import io
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from .common import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import time
|
||||
|
@ -2,14 +2,13 @@
|
||||
import fnmatch
|
||||
import glob
|
||||
import logging
|
||||
import os
|
||||
import pwd
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import time
|
||||
import datetime
|
||||
from ..common import dt2time, fqdn, now, grep, uniq_list, local_pgadmin_cursor, s2human, Commit, dest_reg
|
||||
from ..common import dt2time, fqdn, now, grep, uniq_list, local_pgadmin_cursor, s2human, Commit, dest_reg, os
|
||||
from ..container import docker_build, docker_stop, docker_is_running, Command
|
||||
from odoo.addons.runbot.models.repo import RunbotException
|
||||
from odoo import models, fields, api
|
||||
@ -382,10 +381,7 @@ class runbot_build(models.Model):
|
||||
|
||||
def _get_params(self):
|
||||
message = False
|
||||
try:
|
||||
message = self.repo_id._git(['show', '-s', self.name])
|
||||
except CalledProcessError:
|
||||
pass # todo remove this try catch and make correct patch for _git
|
||||
message = self.repo_id._git(['show', '-s', self.name])
|
||||
params = defaultdict(lambda: defaultdict(str))
|
||||
if message:
|
||||
regex = re.compile(r'^[\t ]*Runbot-dependency: ([A-Za-z0-9\-_]+/[A-Za-z0-9\-_]+):([0-9A-Fa-f\-]*) *(#.*)?$', re.M) # dep:repo:hash #comment
|
||||
|
@ -1,11 +1,10 @@
|
||||
import base64
|
||||
import glob
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import time
|
||||
from ..common import now, grep, time2str, rfind, Commit, s2human
|
||||
from ..common import now, grep, time2str, rfind, Commit, s2human, os
|
||||
from ..container import docker_run, docker_get_gateway_ip, Command
|
||||
from odoo import models, fields, api
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
@ -3,7 +3,6 @@ import datetime
|
||||
import dateutil
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import requests
|
||||
@ -18,7 +17,7 @@ from odoo.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from odoo import models, fields, api, registry
|
||||
from odoo.modules.module import get_module_resource
|
||||
from odoo.tools import config
|
||||
from ..common import fqdn, dt2time, Commit, dest_reg
|
||||
from ..common import fqdn, dt2time, Commit, dest_reg, os
|
||||
from ..container import docker_ps, docker_stop
|
||||
from psycopg2.extensions import TransactionRollbackError
|
||||
_logger = logging.getLogger(__name__)
|
||||
@ -538,6 +537,7 @@ class runbot_repo(models.Model):
|
||||
"""This method have to be called from a dedicated cron on a runbot
|
||||
in charge of orchestration.
|
||||
"""
|
||||
|
||||
if hostname != fqdn():
|
||||
return 'Not for me'
|
||||
|
||||
@ -558,8 +558,10 @@ class runbot_repo(models.Model):
|
||||
""" This method have to be called from a dedicated cron
|
||||
created on each runbot instance.
|
||||
"""
|
||||
|
||||
if hostname != fqdn():
|
||||
return 'Not for me'
|
||||
|
||||
host = self.env['runbot.host']._get_current()
|
||||
host.set_psql_conn_count()
|
||||
host.last_start_loop = fields.Datetime.now()
|
||||
|
@ -1,3 +1,4 @@
|
||||
from . import common
|
||||
from . import test_repo
|
||||
from . import test_build_error
|
||||
from . import test_branch
|
||||
|
55
runbot/tests/common.py
Normal file
55
runbot/tests/common.py
Normal file
@ -0,0 +1,55 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo.tests.common import TransactionCase
|
||||
from unittest.mock import patch
|
||||
|
||||
class Dummy():
|
||||
...
|
||||
|
||||
|
||||
class RunbotCase(TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(RunbotCase, self).setUp()
|
||||
|
||||
self.Build = self.env['runbot.build']
|
||||
self.Repo = self.env['runbot.repo']
|
||||
self.Branch = self.env['runbot.branch']
|
||||
|
||||
self.patchers = {}
|
||||
|
||||
def git_side_effect(cmd):
|
||||
if cmd[:2] == ['show', '-s'] or cmd[:3] == ['show', '--pretty="%H -- %s"', '-s']:
|
||||
return 'commit message for %s' % cmd[-1]
|
||||
if cmd[:2] == ['cat-file', '-e']:
|
||||
return True
|
||||
else:
|
||||
print('Unsupported mock command %s' % cmd)
|
||||
|
||||
self.start_patcher('git_patcher', 'odoo.addons.runbot.models.repo.runbot_repo._git', side_effect=git_side_effect)
|
||||
self.start_patcher('fqdn_patcher', 'odoo.addons.runbot.common.socket.getfqdn', 'host.runbot.com')
|
||||
self.start_patcher('find_patcher', 'odoo.addons.runbot.common.find', 0)
|
||||
self.start_patcher('github_patcher', 'odoo.addons.runbot.models.repo.runbot_repo._github', {})
|
||||
self.start_patcher('is_on_remote_patcher', 'odoo.addons.runbot.models.branch.runbot_branch._is_on_remote', True)
|
||||
self.start_patcher('repo_root_patcher', 'odoo.addons.runbot.models.repo.runbot_repo._root', '/tmp/runbot_test/static')
|
||||
self.start_patcher('makedirs', 'odoo.addons.runbot.common.os.makedirs', True)
|
||||
self.start_patcher('mkdir', 'odoo.addons.runbot.common.os.mkdir', True)
|
||||
self.start_patcher('local_pgadmin_cursor', 'odoo.addons.runbot.common.local_pgadmin_cursor', False) # avoid to create databases
|
||||
self.start_patcher('isdir', 'odoo.addons.runbot.common.os.path.isdir', True)
|
||||
self.start_patcher('isfile', 'odoo.addons.runbot.common.os.path.isfile', True)
|
||||
self.start_patcher('docker_run', 'odoo.addons.runbot.models.build_config.docker_run')
|
||||
self.start_patcher('docker_ps', 'odoo.addons.runbot.models.repo.docker_ps', [])
|
||||
self.start_patcher('docker_stop', 'odoo.addons.runbot.models.repo.docker_stop')
|
||||
|
||||
def start_patcher(self, patcher_name, patcher_path, return_value=Dummy, side_effect=Dummy):
|
||||
patcher = patch(patcher_path)
|
||||
if not hasattr(patcher, 'is_local'):
|
||||
res = patcher.start()
|
||||
self.addCleanup(patcher.stop)
|
||||
self.patchers[patcher_name] = res
|
||||
if side_effect != Dummy:
|
||||
res.side_effect = side_effect
|
||||
elif return_value != Dummy:
|
||||
res.return_value = return_value
|
||||
|
||||
def create_build(self, vals):
|
||||
return self.Build.create(vals)
|
@ -1,8 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from unittest.mock import patch
|
||||
from odoo.tests import common
|
||||
from .common import RunbotCase
|
||||
|
||||
class Test_Branch(common.TransactionCase):
|
||||
class Test_Branch(RunbotCase):
|
||||
|
||||
def setUp(self):
|
||||
super(Test_Branch, self).setUp()
|
||||
@ -24,8 +25,8 @@ class Test_Branch(common.TransactionCase):
|
||||
self.assertEqual(branch.branch_url, 'https://example.com/foo/bar/tree/master')
|
||||
self.assertEqual(branch.config_id, self.env.ref('runbot.runbot_build_config_default'))
|
||||
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._github')
|
||||
def test_pull_request(self, mock_github):
|
||||
def test_pull_request(self):
|
||||
mock_github = self.patchers['github_patcher']
|
||||
mock_github.return_value = {
|
||||
'head' : {'label': 'foo-dev:bar_branch'},
|
||||
'base' : {'ref': 'master'},
|
||||
|
@ -1,7 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from collections import defaultdict
|
||||
from unittest.mock import patch
|
||||
from odoo.tests import common
|
||||
|
||||
from .common import RunbotCase
|
||||
|
||||
def rev_parse(repo, branch_name):
|
||||
"""
|
||||
@ -12,13 +14,11 @@ def rev_parse(repo, branch_name):
|
||||
head_hash = 'rp_%s_%s_head' % (repo.name.split(':')[1], branch_name.split('/')[-1])
|
||||
return head_hash
|
||||
|
||||
class Test_Build(common.TransactionCase):
|
||||
class Test_Build(RunbotCase):
|
||||
|
||||
def setUp(self):
|
||||
super(Test_Build, self).setUp()
|
||||
self.Repo = self.env['runbot.repo']
|
||||
self.repo = self.Repo.create({'name': 'bla@example.com:foo/bar', 'server_files': 'server.py', 'addons_paths': 'addons,core/addons'})
|
||||
self.Branch = self.env['runbot.branch']
|
||||
self.branch = self.Branch.create({
|
||||
'repo_id': self.repo.id,
|
||||
'name': 'refs/heads/master'
|
||||
@ -31,11 +31,9 @@ class Test_Build(common.TransactionCase):
|
||||
'repo_id': self.repo.id,
|
||||
'name': 'refs/heads/11.0'
|
||||
})
|
||||
self.Build = self.env['runbot.build']
|
||||
|
||||
@patch('odoo.addons.runbot.models.build.fqdn')
|
||||
def test_base_fields(self, mock_fqdn):
|
||||
build = self.Build.create({
|
||||
def test_base_fields(self):
|
||||
build = self.create_build({
|
||||
'branch_id': self.branch.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'port': '1234',
|
||||
@ -47,14 +45,14 @@ class Test_Build(common.TransactionCase):
|
||||
self.assertEqual(build.dest, '%05d-master-deadbe' % build.id)
|
||||
|
||||
# Test domain compute with fqdn and ir.config_parameter
|
||||
mock_fqdn.return_value = 'runbot98.nowhere.org'
|
||||
self.patchers['fqdn_patcher'].return_value = 'runbot98.nowhere.org'
|
||||
self.env['ir.config_parameter'].sudo().set_param('runbot.runbot_domain', False)
|
||||
self.assertEqual(build.domain, 'runbot98.nowhere.org:1234')
|
||||
self.env['ir.config_parameter'].set_param('runbot.runbot_domain', 'runbot99.example.org')
|
||||
build._compute_domain()
|
||||
self.assertEqual(build.domain, 'runbot99.example.org:1234')
|
||||
|
||||
other = self.Build.create({
|
||||
other = self.create_build({
|
||||
'branch_id': self.branch.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'port': '5678',
|
||||
@ -71,11 +69,9 @@ class Test_Build(common.TransactionCase):
|
||||
builds.write({'local_state': 'duplicate'})
|
||||
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._get_repo_available_modules')
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._get_params')
|
||||
@patch('odoo.addons.runbot.models.build.fqdn')
|
||||
def test_filter_modules(self, mock_fqdn, mock_get_params, mock_get_repo_mods):
|
||||
def test_filter_modules(self, mock_get_repo_mods):
|
||||
""" test module filtering """
|
||||
build = self.Build.create({
|
||||
build = self.create_build({
|
||||
'branch_id': self.branch.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'port': '1234',
|
||||
@ -99,15 +95,11 @@ class Test_Build(common.TransactionCase):
|
||||
modules_to_test = build._get_modules_to_test(self, modules_patterns='*, -hw_*, hw_explicit')
|
||||
self.assertEqual(modules_to_test, sorted(['good_module', 'bad_module', 'other_good', 'l10n_be', 'hwgood', 'hw_explicit', 'other_mod_1', 'other_mod_2']))
|
||||
|
||||
@patch('odoo.addons.runbot.models.build.os.path.isfile')
|
||||
@patch('odoo.addons.runbot.models.build.os.mkdir')
|
||||
@patch('odoo.addons.runbot.models.build.grep')
|
||||
def test_build_cmd_log_db(self, mock_grep, mock_mkdir, mock_is_file):
|
||||
def test_build_cmd_log_db(self, ):
|
||||
""" test that the logdb connection URI is taken from the .odoorc file """
|
||||
mock_is_file.return_value = True
|
||||
uri = 'postgres://someone:pass@somewhere.com/db'
|
||||
self.env['ir.config_parameter'].sudo().set_param("runbot.runbot_logdb_uri", uri)
|
||||
build = self.Build.create({
|
||||
build = self.create_build({
|
||||
'branch_id': self.branch.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'port': '1234',
|
||||
@ -115,15 +107,9 @@ class Test_Build(common.TransactionCase):
|
||||
cmd = build._cmd(py_version=3)
|
||||
self.assertIn('log-db = %s' % uri, cmd.get_config())
|
||||
|
||||
@patch('odoo.addons.runbot.models.build.os.path.isdir')
|
||||
@patch('odoo.addons.runbot.models.build.os.path.isfile')
|
||||
@patch('odoo.addons.runbot.models.build.os.mkdir')
|
||||
@patch('odoo.addons.runbot.models.build.grep')
|
||||
def test_build_cmd_server_path_no_dep(self, mock_grep, mock_mkdir, mock_is_file, mock_is_dir):
|
||||
def test_build_cmd_server_path_no_dep(self):
|
||||
""" test that the server path and addons path """
|
||||
mock_is_file.return_value = True
|
||||
mock_is_dir.return_value = True
|
||||
build = self.Build.create({
|
||||
build = self.create_build({
|
||||
'branch_id': self.branch.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'port': '1234',
|
||||
@ -135,19 +121,15 @@ class Test_Build(common.TransactionCase):
|
||||
addons_path_pos = cmd.index('--addons-path') + 1
|
||||
self.assertEqual(cmd[addons_path_pos], 'bar/addons,bar/core/addons')
|
||||
|
||||
@patch('odoo.addons.runbot.models.branch.runbot_branch._is_on_remote')
|
||||
@patch('odoo.addons.runbot.models.build.os.path.isdir')
|
||||
@patch('odoo.addons.runbot.models.build.os.path.isfile')
|
||||
@patch('odoo.addons.runbot.models.build.os.mkdir')
|
||||
@patch('odoo.addons.runbot.models.build.grep')
|
||||
def test_build_cmd_server_path_with_dep(self, mock_grep, mock_mkdir, mock_is_file, mock_is_dir, mock_is_on_remote):
|
||||
def test_build_cmd_server_path_with_dep(self):
|
||||
""" test that the server path and addons path """
|
||||
|
||||
def is_file(file):
|
||||
self.assertIn(file, [
|
||||
'/tmp/runbot_test/static/sources/bar-ent/d0d0caca0000ffffffffffffffffffffffffffff/requirements.txt',
|
||||
'/tmp/runbot_test/static/sources/bar/dfdfcfcf0000ffffffffffffffffffffffffffff/requirements.txt',
|
||||
'/tmp/runbot_test/static/sources/bar/dfdfcfcf0000ffffffffffffffffffffffffffff/server.py'
|
||||
'/tmp/runbot_test/static/sources/bar/dfdfcfcf0000ffffffffffffffffffffffffffff/server.py',
|
||||
'/tmp/runbot_test/static/sources/bar/dfdfcfcf0000ffffffffffffffffffffffffffff/openerp/tools/config.py'
|
||||
])
|
||||
if file == '/tmp/runbot_test/static/sources/bar-ent/d0d0caca0000ffffffffffffffffffffffffffff/requirements.txt':
|
||||
return False
|
||||
@ -162,9 +144,9 @@ class Test_Build(common.TransactionCase):
|
||||
self.assertTrue(any([path in file for path in paths])) # checking that addons path existence check looks ok
|
||||
return True
|
||||
|
||||
mock_is_file.side_effect = is_file
|
||||
mock_is_dir.side_effect = is_dir
|
||||
mock_is_on_remote.return_value = True
|
||||
self.patchers['isfile'].side_effect = is_file
|
||||
self.patchers['isdir'].side_effect = is_dir
|
||||
|
||||
repo_ent = self.env['runbot.repo'].create({
|
||||
'name': 'bla@example.com:foo/bar-ent',
|
||||
'server_files': '',
|
||||
@ -181,7 +163,7 @@ class Test_Build(common.TransactionCase):
|
||||
return 'dfdfcfcf0000ffffffffffffffffffffffffffff'
|
||||
|
||||
with patch('odoo.addons.runbot.models.repo.runbot_repo._git_rev_parse', new=rev_parse):
|
||||
build = self.Build.create({
|
||||
build = self.create_build({
|
||||
'branch_id': enterprise_branch.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'port': '1234',
|
||||
@ -193,26 +175,21 @@ class Test_Build(common.TransactionCase):
|
||||
self.assertEqual('bar/server.py', cmd[1])
|
||||
self.assertEqual('python3', cmd[0])
|
||||
|
||||
@patch('odoo.addons.runbot.models.branch.runbot_branch._is_on_remote')
|
||||
@patch('odoo.addons.runbot.models.build.os.path.isdir')
|
||||
@patch('odoo.addons.runbot.models.build.os.path.isfile')
|
||||
@patch('odoo.addons.runbot.models.build.os.mkdir')
|
||||
@patch('odoo.addons.runbot.models.build.grep')
|
||||
def test_build_cmd_server_path_with_dep_collision(self, mock_grep, mock_mkdir, mock_is_file, mock_is_dir, mock_is_on_remote):
|
||||
def test_build_cmd_server_path_with_dep_collision(self):
|
||||
""" test that the server path and addons path """
|
||||
|
||||
def is_file(file):
|
||||
self.assertIn(file, [
|
||||
'/tmp/runbot_test/static/sources/bar/dfdfcfcf0000ffffffffffffffffffffffffffff/requirements.txt',
|
||||
'/tmp/runbot_test/static/sources/bar/d0d0caca0000ffffffffffffffffffffffffffff/requirements.txt',
|
||||
'/tmp/runbot_test/static/sources/bar/dfdfcfcf0000ffffffffffffffffffffffffffff/server.py'])
|
||||
'/tmp/runbot_test/static/sources/bar/dfdfcfcf0000ffffffffffffffffffffffffffff/server.py',
|
||||
'/tmp/runbot_test/static/sources/bar/dfdfcfcf0000ffffffffffffffffffffffffffff/openerp/tools/config.py'
|
||||
])
|
||||
if file == '/tmp/runbot_test/static/sources/bar/dfdfcfcf0000ffffffffffffffffffffffffffff/requirements.txt':
|
||||
return False
|
||||
return True
|
||||
|
||||
mock_is_file.side_effect = is_file
|
||||
mock_is_dir.return_value = True
|
||||
mock_is_on_remote.return_value = True
|
||||
self.patchers['isfile'].side_effect = is_file
|
||||
repo_ent = self.env['runbot.repo'].create({
|
||||
'name': 'bla@example.com:foo-ent/bar',
|
||||
'server_files': '',
|
||||
@ -229,7 +206,7 @@ class Test_Build(common.TransactionCase):
|
||||
return 'dfdfcfcf0000ffffffffffffffffffffffffffff'
|
||||
|
||||
with patch('odoo.addons.runbot.models.repo.runbot_repo._git_rev_parse', new=rev_parse):
|
||||
build = self.Build.create({
|
||||
build = self.create_build({
|
||||
'branch_id': enterprise_branch.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'port': '1234',
|
||||
@ -243,7 +220,7 @@ class Test_Build(common.TransactionCase):
|
||||
|
||||
def test_build_config_from_branch_default(self):
|
||||
"""test build config_id is computed from branch default config_id"""
|
||||
build = self.Build.create({
|
||||
build = self.create_build({
|
||||
'branch_id': self.branch.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
})
|
||||
@ -252,7 +229,7 @@ class Test_Build(common.TransactionCase):
|
||||
def test_build_config_from_branch_testing(self):
|
||||
"""test build config_id is computed from branch"""
|
||||
self.branch.config_id = self.env.ref('runbot.runbot_build_config_default_no_run')
|
||||
build = self.Build.create({
|
||||
build = self.create_build({
|
||||
'branch_id': self.branch.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
})
|
||||
@ -261,7 +238,7 @@ class Test_Build(common.TransactionCase):
|
||||
def test_build_from_branch_no_build(self):
|
||||
"""test build is not even created when branch no_build is True"""
|
||||
self.branch.no_build = True
|
||||
build = self.Build.create({
|
||||
build = self.create_build({
|
||||
'branch_id': self.branch.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
})
|
||||
@ -270,7 +247,7 @@ class Test_Build(common.TransactionCase):
|
||||
def test_build_config_can_be_set(self):
|
||||
"""test build config_id can be set to something different than the one on the branch"""
|
||||
self.branch.config_id = self.env.ref('runbot.runbot_build_config_default')
|
||||
build = self.Build.create({
|
||||
build = self.create_build({
|
||||
'branch_id': self.branch.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'config_id': self.env.ref('runbot.runbot_build_config_default_no_run').id
|
||||
@ -280,7 +257,7 @@ class Test_Build(common.TransactionCase):
|
||||
@patch('odoo.addons.runbot.models.build._logger')
|
||||
def test_build_skip(self, mock_logger):
|
||||
"""test build is skipped"""
|
||||
build = self.Build.create({
|
||||
build = self.create_build({
|
||||
'branch_id': self.branch.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'port': '1234',
|
||||
@ -289,7 +266,7 @@ class Test_Build(common.TransactionCase):
|
||||
self.assertEqual(build.local_state, 'done')
|
||||
self.assertEqual(build.local_result, 'skipped')
|
||||
|
||||
other_build = self.Build.create({
|
||||
other_build = self.create_build({
|
||||
'branch_id': self.branch.id,
|
||||
'name': 'deadbeef0000ffffffffffffffffffffffffffff',
|
||||
'port': '1234',
|
||||
@ -302,13 +279,12 @@ class Test_Build(common.TransactionCase):
|
||||
|
||||
def test_ask_kill_duplicate(self):
|
||||
""" Test that the _ask_kill method works on duplicate"""
|
||||
#mock_is_on_remote.return_value = True
|
||||
|
||||
build1 = self.Build.create({
|
||||
build1 = self.create_build({
|
||||
'branch_id': self.branch_10.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
})
|
||||
build2 = self.Build.create({
|
||||
build2 = self.create_build({
|
||||
'branch_id': self.branch_10.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
})
|
||||
@ -320,30 +296,30 @@ class Test_Build(common.TransactionCase):
|
||||
self.assertEqual(build1.local_result, 'skipped', 'A killed pending duplicate build should mark the real build as skipped')
|
||||
|
||||
def test_children(self):
|
||||
build1 = self.Build.create({
|
||||
build1 = self.create_build({
|
||||
'branch_id': self.branch_10.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
})
|
||||
build1_1 = self.Build.create({
|
||||
build1_1 = self.create_build({
|
||||
'branch_id': self.branch_10.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'parent_id': build1.id,
|
||||
'hidden': True,
|
||||
'extra_params': '2', # avoid duplicate
|
||||
})
|
||||
build1_2 = self.Build.create({
|
||||
build1_2 = self.create_build({
|
||||
'branch_id': self.branch_10.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'parent_id': build1.id,
|
||||
'extra_params': '3',
|
||||
})
|
||||
build1_1_1 = self.Build.create({
|
||||
build1_1_1 = self.create_build({
|
||||
'branch_id': self.branch_10.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'parent_id': build1_1.id,
|
||||
'extra_params': '4',
|
||||
})
|
||||
build1_1_2 = self.Build.create({
|
||||
build1_1_2 = self.create_build({
|
||||
'branch_id': self.branch_10.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'parent_id': build1_1.id,
|
||||
@ -408,17 +384,17 @@ class Test_Build(common.TransactionCase):
|
||||
assert_state(0, 0, 0, 'done', build1_1_2)
|
||||
|
||||
def test_duplicate_childrens(self):
|
||||
build_old = self.Build.create({
|
||||
build_old = self.create_build({
|
||||
'branch_id': self.branch_10.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'extra_params': '0',
|
||||
})
|
||||
build_parent = self.Build.create({
|
||||
build_parent = self.create_build({
|
||||
'branch_id': self.branch_10.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'extra_params': '1',
|
||||
})
|
||||
build_child = self.Build.create({
|
||||
build_child = self.create_build({
|
||||
'branch_id': self.branch_10.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'parent_id': build_parent.id,
|
||||
@ -431,7 +407,8 @@ class Test_Build(common.TransactionCase):
|
||||
self.assertEqual(build_parent.nb_testing, 0)
|
||||
self.assertEqual(build_parent.global_state, 'done')
|
||||
|
||||
class TestClosestBranch(common.TransactionCase):
|
||||
|
||||
class TestClosestBranch(RunbotCase):
|
||||
|
||||
def branch_description(self, branch):
|
||||
branch_type = 'pull' if 'pull' in branch.name else 'branch'
|
||||
@ -453,7 +430,7 @@ class TestClosestBranch(common.TransactionCase):
|
||||
}
|
||||
for b1, b2 in [(branch1, branch2), (branch2, branch1)]:
|
||||
hash = '%s%s' % (b1.name, b2.name)
|
||||
build1 = self.Build.create({
|
||||
build1 = self.create_build({
|
||||
'branch_id': b1.id,
|
||||
'name': hash,
|
||||
})
|
||||
@ -461,7 +438,7 @@ class TestClosestBranch(common.TransactionCase):
|
||||
if b1_closest:
|
||||
self.assertClosest(b1, closest[b1])
|
||||
|
||||
build2 = self.Build.create({
|
||||
build2 = self.create_build({
|
||||
'branch_id': b2.id,
|
||||
'name': hash,
|
||||
})
|
||||
@ -533,10 +510,10 @@ class TestClosestBranch(common.TransactionCase):
|
||||
|
||||
self.Build = self.env['runbot.build']
|
||||
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._github')
|
||||
def test_pr_is_duplicate(self, mock_github):
|
||||
def test_pr_is_duplicate(self):
|
||||
""" test PR is a duplicate of a dev branch build """
|
||||
|
||||
mock_github = self.patchers['github_patcher']
|
||||
mock_github.return_value = {
|
||||
'head': {'label': 'odoo-dev:10.0-fix-thing-moc'},
|
||||
'base': {'ref': '10.0'},
|
||||
@ -553,10 +530,8 @@ class TestClosestBranch(common.TransactionCase):
|
||||
})
|
||||
self.assertDuplicate(dev_branch, pr)
|
||||
|
||||
@patch('odoo.addons.runbot.models.branch.runbot_branch._is_on_remote')
|
||||
def test_closest_branch_01(self, mock_is_on_remote):
|
||||
def test_closest_branch_01(self):
|
||||
""" test find a matching branch in a target repo based on branch name """
|
||||
mock_is_on_remote.return_value = True
|
||||
|
||||
self.Branch.create({
|
||||
'repo_id': self.community_dev_repo.id,
|
||||
@ -569,10 +544,10 @@ class TestClosestBranch(common.TransactionCase):
|
||||
|
||||
self.assertEqual((addons_branch, 'exact'), addons_branch._get_closest_branch(self.enterprise_dev_repo.id))
|
||||
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._github')
|
||||
def test_closest_branch_02(self, mock_github):
|
||||
|
||||
def test_closest_branch_02(self):
|
||||
""" test find two matching PR having the same head name """
|
||||
|
||||
mock_github = self.patchers['github_patcher']
|
||||
mock_github.return_value = {
|
||||
# "head label" is the repo:branch where the PR comes from
|
||||
# "base ref" is the target of the PR
|
||||
@ -601,13 +576,11 @@ class TestClosestBranch(common.TransactionCase):
|
||||
})
|
||||
self.assertEqual((community_branch, 'exact PR'), enterprise_pr._get_closest_branch(self.community_repo.id))
|
||||
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._github')
|
||||
@patch('odoo.addons.runbot.models.branch.runbot_branch._is_on_remote')
|
||||
def test_closest_branch_02_improved(self, mock_is_on_remote, mock_github):
|
||||
def test_closest_branch_02_improved(self):
|
||||
""" test that a PR in enterprise with a matching PR in Community
|
||||
uses the matching one"""
|
||||
|
||||
mock_is_on_remote.return_value = True
|
||||
mock_github = self.patchers['github_patcher']
|
||||
|
||||
com_dev_branch = self.Branch.create({
|
||||
'repo_id': self.community_dev_repo.id,
|
||||
@ -656,22 +629,18 @@ class TestClosestBranch(common.TransactionCase):
|
||||
(com_dev_branch, 'exact PR')
|
||||
)
|
||||
|
||||
@patch('odoo.addons.runbot.models.branch.runbot_branch._is_on_remote')
|
||||
def test_closest_branch_03(self, mock_is_on_remote):
|
||||
def test_closest_branch_03(self):
|
||||
""" test find a branch based on dashed prefix"""
|
||||
mock_is_on_remote.return_value = True
|
||||
addons_branch = self.Branch.create({
|
||||
'repo_id': self.enterprise_dev_repo.id,
|
||||
'name': 'refs/heads/10.0-fix-blah-blah-moc'
|
||||
})
|
||||
self.assertEqual((self.branch_odoo_10, 'prefix'), addons_branch._get_closest_branch(self.community_repo.id))
|
||||
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._github')
|
||||
@patch('odoo.addons.runbot.models.branch.runbot_branch._is_on_remote')
|
||||
def test_closest_branch_03_05(self, mock_is_on_remote, mock_github):
|
||||
def test_closest_branch_03_05(self):
|
||||
""" test that a PR in enterprise without a matching PR in Community
|
||||
and no branch in community"""
|
||||
mock_is_on_remote.return_value = True
|
||||
mock_github = self.patchers['github_patcher']
|
||||
# comm_repo = self.repo
|
||||
# self.repo.write({'token': 1})
|
||||
|
||||
@ -715,12 +684,10 @@ class TestClosestBranch(common.TransactionCase):
|
||||
(com_branch, 'prefix'),
|
||||
)
|
||||
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._github')
|
||||
@patch('odoo.addons.runbot.models.branch.runbot_branch._is_on_remote')
|
||||
def test_closest_branch_04(self, mock_is_on_remote, mock_github):
|
||||
def test_closest_branch_04(self):
|
||||
""" test that a PR in enterprise without a matching PR in Community
|
||||
uses the corresponding exact branch in community"""
|
||||
mock_is_on_remote.return_value = True
|
||||
mock_github = self.patchers['github_patcher']
|
||||
|
||||
com_dev_branch = self.Branch.create({
|
||||
'repo_id': self.community_dev_repo.id,
|
||||
@ -753,9 +720,9 @@ class TestClosestBranch(common.TransactionCase):
|
||||
(com_dev_branch, 'no PR')
|
||||
)
|
||||
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._github')
|
||||
def test_closest_branch_05(self, mock_github):
|
||||
def test_closest_branch_05(self):
|
||||
""" test last resort value """
|
||||
mock_github = self.patchers['github_patcher']
|
||||
mock_github.return_value = {
|
||||
'head': {'label': 'foo-dev:bar_branch'},
|
||||
'base': {'ref': '10.0'},
|
||||
@ -786,10 +753,8 @@ class TestClosestBranch(common.TransactionCase):
|
||||
})
|
||||
self.assertEqual((self.branch_odoo_master, 'default'), addons_branch._get_closest_branch(self.community_repo.id))
|
||||
|
||||
@patch('odoo.addons.runbot.models.branch.runbot_branch._is_on_remote')
|
||||
def test_no_duplicate_update(self, mock_is_on_remote):
|
||||
def test_no_duplicate_update(self):
|
||||
"""push a dev branch in enterprise with same head as sticky, but with a matching branch in community"""
|
||||
mock_is_on_remote.return_value = True
|
||||
community_sticky_branch = self.Branch.create({
|
||||
'repo_id': self.community_repo.id,
|
||||
'name': 'refs/heads/saas-12.2',
|
||||
@ -811,7 +776,7 @@ class TestClosestBranch(common.TransactionCase):
|
||||
# we shouldn't have duplicate since community_dev_branch exists
|
||||
with patch('odoo.addons.runbot.models.repo.runbot_repo._git_rev_parse', new=rev_parse):
|
||||
# lets create an old enterprise build
|
||||
self.Build.create({
|
||||
self.create_build({
|
||||
'branch_id': enterprise_sticky_branch.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
})
|
||||
@ -822,9 +787,9 @@ class TestClosestBranch(common.TransactionCase):
|
||||
(community_dev_branch, 'exact'),
|
||||
)
|
||||
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._github')
|
||||
def test_external_pr_closest_branch(self, mock_github):
|
||||
def test_external_pr_closest_branch(self):
|
||||
""" test last resort value target_name"""
|
||||
mock_github = self.patchers['github_patcher']
|
||||
mock_github.return_value = {
|
||||
'head': {'label': 'external_repo:11.0-fix'},
|
||||
'base': {'ref': '11.0'},
|
||||
@ -838,9 +803,9 @@ class TestClosestBranch(common.TransactionCase):
|
||||
closest_branch = enterprise_pr._get_closest_branch(dependency_repo.id)
|
||||
self.assertEqual(enterprise_pr._get_closest_branch(dependency_repo.id), (self.branch_odoo_11, 'pr_target'))
|
||||
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._github')
|
||||
def test_external_pr_with_comunity_pr_closest_branch(self, mock_github):
|
||||
def test_external_pr_with_comunity_pr_closest_branch(self):
|
||||
""" test matching external pr """
|
||||
mock_github = self.patchers['github_patcher']
|
||||
mock_github.return_value = {
|
||||
'head': {'label': 'external_dev_repo:11.0-fix'},
|
||||
'base': {'ref': '11.0'},
|
||||
@ -860,7 +825,7 @@ class TestClosestBranch(common.TransactionCase):
|
||||
'name': 'refs/pull/123'
|
||||
})
|
||||
with patch('odoo.addons.runbot.models.repo.runbot_repo._git_rev_parse', new=rev_parse):
|
||||
build = self.Build.create({
|
||||
build = self.create_build({
|
||||
'branch_id': enterprise_pr.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
})
|
||||
|
@ -1,15 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from unittest.mock import patch
|
||||
from odoo.tests import common
|
||||
from .common import RunbotCase
|
||||
|
||||
|
||||
class TestBuildConfigStep(common.TransactionCase):
|
||||
class TestBuildConfigStep(RunbotCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestBuildConfigStep, 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.repo = self.Repo.create({'name': 'bla@example.com:foo/bar', 'server_files': 'server.py'})
|
||||
self.branch = self.Branch.create({
|
||||
'repo_id': self.repo.id,
|
||||
'name': 'refs/heads/master'
|
||||
@ -31,6 +29,9 @@ class TestBuildConfigStep(common.TransactionCase):
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'port': '1234',
|
||||
})
|
||||
self.start_patcher('_local_pg_createdb', 'odoo.addons.runbot.models.build.runbot_build._local_pg_createdb', True)
|
||||
self.start_patcher('_get_py_version', 'odoo.addons.runbot.models.build.runbot_build._get_py_version', 3)
|
||||
|
||||
|
||||
def test_config_step_create_results(self):
|
||||
""" Test child builds are taken into account"""
|
||||
@ -81,50 +82,48 @@ class TestBuildConfigStep(common.TransactionCase):
|
||||
|
||||
self.assertFalse(self.parent_build.global_result)
|
||||
|
||||
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._local_pg_createdb')
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._get_server_info')
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._get_addons_path')
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._get_py_version')
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._server')
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._checkout')
|
||||
@patch('odoo.addons.runbot.models.build_config.docker_run')
|
||||
def test_coverage(self, mock_docker_run, mock_checkout, mock_server, mock_get_py_version, mock_get_addons_path, mock_get_server_info, mock_local_pg_createdb):
|
||||
def test_coverage(self, mock_checkout):
|
||||
config_step = self.ConfigStep.create({
|
||||
'name': 'coverage',
|
||||
'job_type': 'install_odoo',
|
||||
'coverage': True
|
||||
})
|
||||
|
||||
mock_checkout.return_value = {}
|
||||
mock_server.return_value = 'bar'
|
||||
mock_get_py_version.return_value = '3'
|
||||
mock_get_addons_path.return_value = ['bar/addons']
|
||||
mock_get_server_info.return_value = (self.parent_build._get_all_commit()[0], 'server.py')
|
||||
mock_local_pg_createdb.return_value = True
|
||||
|
||||
def docker_run(cmd, log_path, build_dir, *args, **kwargs):
|
||||
cmds = cmd.split(' && ')
|
||||
self.assertEqual(cmds[0], 'sudo pip3 install -r bar/requirements.txt')
|
||||
self.assertEqual(cmds[1].split(' bar/server.py')[0], 'python3 -m coverage run --branch --source /data/build --omit *__manifest__.py')
|
||||
self.assertEqual(cmds[2].split(' ; ')[0], 'python3 -m coverage html -d /data/build/coverage --ignore-errors')
|
||||
self.assertEqual(cmds[2].split(' ; ')[1], 'pg_dump %s-coverage > /data/build/logs/%s-coverage//dump.sql' % (self.parent_build.dest, self.parent_build.dest))
|
||||
def docker_run(cmd, log_path, *args, **kwargs):
|
||||
cmds = cmd.build().split(' && ')
|
||||
dest = self.parent_build.dest
|
||||
self.assertEqual(cmd.pres, [['sudo', 'pip3', 'install', '-r', 'bar/requirements.txt']])
|
||||
self.assertEqual(cmd.cmd[:10], ['python3', '-m', 'coverage', 'run', '--branch', '--source', '/data/build', '--omit', '*__manifest__.py', 'bar/server.py'])
|
||||
#['bar/server.py', '--addons-path', 'bar', '--no-xmlrpcs', '--no-netrpc', '-d', '08732-master-d0d0ca-coverage', '--test-enable', '--stop-after-init', '--log-level=test', '--max-cron-threads=0']
|
||||
self.assertEqual(cmd.posts, [['python3', '-m', 'coverage', 'html', '-d', '/data/build/coverage', '--ignore-errors']])
|
||||
self.assertEqual(log_path, 'dev/null/logpath')
|
||||
|
||||
mock_docker_run.side_effect = docker_run
|
||||
|
||||
self.patchers['docker_run'].side_effect = docker_run
|
||||
|
||||
config_step._run_odoo_install(self.parent_build, 'dev/null/logpath')
|
||||
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._checkout')
|
||||
def test_dump(self, mock_checkout):
|
||||
config_step = self.ConfigStep.create({
|
||||
'name': 'all',
|
||||
'job_type': 'install_odoo',
|
||||
})
|
||||
def docker_run(cmd, log_path, *args, **kwargs):
|
||||
dest = self.parent_build.dest
|
||||
self.assertEqual(cmd.cmd[:2], ['python3', 'bar/server.py'])
|
||||
self.assertEqual(cmd.finals[0], ['pg_dump', '%s-all' % dest, '>', '/data/build/logs/%s-all//dump.sql' % dest])
|
||||
self.assertEqual(cmd.finals[1], ['cp', '-r', '/data/build/datadir/filestore/%s-all' % dest, '/data/build/logs/%s-all//filestore/' % dest])
|
||||
self.assertEqual(cmd.finals[2], ['cd', '/data/build/logs/%s-all/' % dest, '&&', 'zip', '-rmq9', '/data/build/logs/%s-all.zip' % dest, '*'])
|
||||
self.assertEqual(log_path, 'dev/null/logpath')
|
||||
|
||||
self.patchers['docker_run'].side_effect = docker_run
|
||||
|
||||
config_step._run_odoo_install(self.parent_build, 'dev/null/logpath')
|
||||
|
||||
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._local_pg_createdb')
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._get_server_info')
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._get_addons_path')
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._get_py_version')
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._server')
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._checkout')
|
||||
@patch('odoo.addons.runbot.models.build_config.docker_run')
|
||||
@patch('odoo.addons.runbot.models.build_config.grep')
|
||||
def test_install_tags(self, mock_grep, mock_docker_run, mock_checkout, mock_server, mock_get_py_version, mock_get_addons_path, mock_get_server_info, mock_local_pg_createdb):
|
||||
def test_install_tags(self, mock_checkout):
|
||||
config_step = self.ConfigStep.create({
|
||||
'name': 'all',
|
||||
'job_type': 'install_odoo',
|
||||
@ -137,29 +136,22 @@ class TestBuildConfigStep(common.TransactionCase):
|
||||
'test_tags': ':otherclass.othertest'
|
||||
})
|
||||
|
||||
mock_checkout.return_value = {}
|
||||
mock_server.return_value = 'bar'
|
||||
mock_get_py_version.return_value = '3'
|
||||
mock_get_addons_path.return_value = ['bar/addons']
|
||||
mock_get_server_info.return_value = (self.parent_build._get_all_commit()[0], 'server.py')
|
||||
mock_local_pg_createdb.return_value = True
|
||||
mock_grep.return_value = True
|
||||
|
||||
def docker_run(cmd, log_path, build_dir, *args, **kwargs):
|
||||
cmds = cmd.split(' && ')
|
||||
def docker_run(cmd, *args, **kwargs):
|
||||
cmds = cmd.build().split(' && ')
|
||||
self.assertEqual(cmds[1].split(' bar/server.py')[0], 'python3')
|
||||
tags = cmds[1].split('--test-tags ')[1].split(' ')[0]
|
||||
self.assertEqual(tags, '/module,:class.method')
|
||||
|
||||
mock_docker_run.side_effect = docker_run
|
||||
self.patchers['docker_run'].side_effect = docker_run
|
||||
config_step._run_odoo_install(self.parent_build, 'dev/null/logpath')
|
||||
|
||||
config_step.enable_auto_tags =True
|
||||
def docker_run(cmd, log_path, build_dir, *args, **kwargs):
|
||||
cmds = cmd.split(' && ')
|
||||
config_step.enable_auto_tags = True
|
||||
|
||||
def docker_run2(cmd, *args, **kwargs):
|
||||
cmds = cmd.build().split(' && ')
|
||||
self.assertEqual(cmds[1].split(' bar/server.py')[0], 'python3')
|
||||
tags = cmds[1].split('--test-tags ')[1].split(' ')[0]
|
||||
self.assertEqual(tags, '/module,:class.method,-:otherclass.othertest')
|
||||
|
||||
mock_docker_run.side_effect = docker_run
|
||||
self.patchers['docker_run'].side_effect = docker_run2
|
||||
config_step._run_odoo_install(self.parent_build, 'dev/null/logpath')
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from unittest.mock import patch
|
||||
from odoo.tests import common
|
||||
from .common import RunbotCase
|
||||
|
||||
RTE_ERROR = """FAIL: TestUiTranslate.test_admin_tour_rte_translator
|
||||
Traceback (most recent call last):
|
||||
@ -14,9 +15,10 @@ AssertionError: The test code "odoo.startTour('rte_translator')" failed
|
||||
Tour rte_translator failed at step click language dropdown (trigger: .js_language_selector .dropdown-toggle)
|
||||
"""
|
||||
|
||||
class TestBuildError(common.TransactionCase):
|
||||
|
||||
def create_build(self, vals):
|
||||
class TestBuildError(RunbotCase):
|
||||
|
||||
def create_test_build(self, vals):
|
||||
create_vals = {
|
||||
'branch_id': self.branch.id,
|
||||
'name': 'deadbeaf0000ffffffffffffffffffffffffffff',
|
||||
@ -24,11 +26,10 @@ class TestBuildError(common.TransactionCase):
|
||||
'local_result': 'ok'
|
||||
}
|
||||
create_vals.update(vals)
|
||||
return self.Build.create(create_vals)
|
||||
|
||||
return self.create_build(create_vals)
|
||||
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._get_params')
|
||||
def setUp(self, mock_get_params):
|
||||
|
||||
def setUp(self):
|
||||
super(TestBuildError, self).setUp()
|
||||
repo = self.env['runbot.repo'].create({'name': 'bla@example.com:foo/bar'})
|
||||
self.branch = self.env['runbot.branch'].create({
|
||||
@ -36,14 +37,12 @@ class TestBuildError(common.TransactionCase):
|
||||
'name': 'refs/heads/master'
|
||||
})
|
||||
|
||||
self.Build = self.env['runbot.build']
|
||||
self.BuildError = self.env['runbot.build.error']
|
||||
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._get_params')
|
||||
def test_build_scan(self, mock_get_params):
|
||||
def test_build_scan(self):
|
||||
IrLog = self.env['ir.logging']
|
||||
ko_build = self.create_build({'local_result': 'ko'})
|
||||
ok_build = self.create_build({'local_result': 'ok'})
|
||||
ko_build = self.create_test_build({'local_result': 'ko'})
|
||||
ok_build = self.create_test_build({'local_result': 'ok'})
|
||||
|
||||
log = {'message': RTE_ERROR,
|
||||
'build_id': ko_build.id,
|
||||
@ -66,24 +65,24 @@ class TestBuildError(common.TransactionCase):
|
||||
self.assertFalse(self.BuildError.search([('build_ids','in', [ok_build.id])]), 'A successful build should not associated to a runbot.build.error')
|
||||
|
||||
# Test that build with same error is added to the errors
|
||||
ko_build_same_error = self.create_build({'local_result': 'ko'})
|
||||
ko_build_same_error = self.create_test_build({'local_result': 'ko'})
|
||||
log.update({'build_id': ko_build_same_error.id})
|
||||
IrLog.create(log)
|
||||
ko_build_same_error._parse_logs()
|
||||
self.assertIn(ko_build_same_error, build_error.build_ids, 'The parsed build should be added to the existing runbot.build.error')
|
||||
|
||||
|
||||
# Test that line numbers does not interfere with error recognition
|
||||
ko_build_diff_number = self.create_build({'local_result': 'ko'})
|
||||
ko_build_diff_number = self.create_test_build({'local_result': 'ko'})
|
||||
rte_diff_numbers = RTE_ERROR.replace('89','100').replace('1062','1000').replace('1046', '4610')
|
||||
log.update({'build_id': ko_build_diff_number.id, 'message': rte_diff_numbers})
|
||||
IrLog.create(log)
|
||||
ko_build_diff_number._parse_logs()
|
||||
self.assertIn(ko_build_diff_number, build_error.build_ids, 'The parsed build with different line numbers in error should be added to the runbot.build.error')
|
||||
|
||||
|
||||
# Test that when an error re-appears after the bug has been fixed,
|
||||
# a new build error is created, with the old one linked
|
||||
build_error.active = False
|
||||
ko_build_new = self.create_build({'local_result': 'ko'})
|
||||
ko_build_new = self.create_test_build({'local_result': 'ko'})
|
||||
log.update({'build_id': ko_build_new.id})
|
||||
IrLog.create(log)
|
||||
ko_build_new._parse_logs()
|
||||
@ -92,10 +91,9 @@ class TestBuildError(common.TransactionCase):
|
||||
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')
|
||||
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._get_params')
|
||||
def test_build_error_links(self, mock_get_params):
|
||||
build_a = self.create_build({'local_result': 'ko'})
|
||||
build_b = self.create_build({'local_result': 'ko'})
|
||||
def test_build_error_links(self):
|
||||
build_a = self.create_test_build({'local_result': 'ko'})
|
||||
build_b = self.create_test_build({'local_result': 'ko'})
|
||||
|
||||
error_a = self.env['runbot.build.error'].create({
|
||||
'content': 'foo',
|
||||
|
@ -1,13 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from unittest.mock import patch
|
||||
from odoo.tests import common
|
||||
from .common import RunbotCase
|
||||
|
||||
|
||||
class Test_Cron(common.TransactionCase):
|
||||
class Test_Cron(RunbotCase):
|
||||
|
||||
def setUp(self):
|
||||
super(Test_Cron, self).setUp()
|
||||
self.Repo = self.env['runbot.repo']
|
||||
self.start_patcher('_get_cron_period', 'odoo.addons.runbot.models.repo.runbot_repo._get_cron_period', 2)
|
||||
|
||||
@patch('odoo.addons.runbot.models.repo.config.get')
|
||||
def test_cron_period(self, mock_config_get):
|
||||
@ -19,53 +20,43 @@ class Test_Cron(common.TransactionCase):
|
||||
for i in range(200):
|
||||
self.assertLess(period, 400)
|
||||
|
||||
@patch('odoo.addons.runbot.models.repo.fqdn')
|
||||
def test_crons_returns(self, mock_fqdn):
|
||||
def test_crons_returns(self):
|
||||
""" test that cron_fetch_and_schedule and _cron_fetch_and_build
|
||||
return directly when called on wrong host
|
||||
"""
|
||||
mock_fqdn.return_value = 'runboty.foo.com'
|
||||
|
||||
ret = self.Repo._cron_fetch_and_schedule('runbotx.foo.com')
|
||||
self.assertEqual(ret, 'Not for me')
|
||||
|
||||
ret = self.Repo._cron_fetch_and_build('runbotx.foo.com')
|
||||
self.assertEqual(ret, 'Not for me')
|
||||
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._get_cron_period')
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._create_pending_builds')
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._update')
|
||||
@patch('odoo.addons.runbot.models.repo.fqdn')
|
||||
def test_cron_schedule(self, mock_fqdn, mock_update, mock_create, mock_cron_period):
|
||||
def test_cron_schedule(self, mock_update, mock_create):
|
||||
""" test that cron_fetch_and_schedule do its work """
|
||||
mock_fqdn.return_value = 'runbotx.foo.com'
|
||||
mock_cron_period.return_value = 2
|
||||
self.env['ir.config_parameter'].sudo().set_param('runbot.runbot_update_frequency', 1)
|
||||
self.Repo.create({'name': '/path/somewhere/disabled.git', 'mode': 'disabled'}) # create a disabled
|
||||
self.Repo.search([]).write({'mode': 'disabled'}) # disable all depo, in case we have existing ones
|
||||
local_repo = self.Repo.create({'name': '/path/somewhere/rep.git'}) # create active repo
|
||||
ret = self.Repo._cron_fetch_and_schedule('runbotx.foo.com')
|
||||
ret = self.Repo._cron_fetch_and_schedule('host.runbot.com')
|
||||
self.assertEqual(None, ret)
|
||||
mock_update.assert_called_with(force=False)
|
||||
mock_create.assert_called_with()
|
||||
|
||||
@patch('odoo.addons.runbot.models.host.fqdn')
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._get_cron_period')
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._reload_nginx')
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._scheduler')
|
||||
@patch('odoo.addons.runbot.models.repo.fqdn')
|
||||
def test_cron_build(self, mock_fqdn, mock_scheduler, mock_reload, mock_cron_period, mock_host_fqdn):
|
||||
def test_cron_build(self, mock_scheduler, mock_reload):
|
||||
""" test that cron_fetch_and_build do its work """
|
||||
hostname = 'runbotx.foo.com'
|
||||
mock_fqdn.return_value = mock_host_fqdn.return_value = hostname
|
||||
mock_cron_period.return_value = 2
|
||||
hostname = 'host.runbot.com'
|
||||
self.env['ir.config_parameter'].sudo().set_param('runbot.runbot_update_frequency', 1)
|
||||
self.Repo.create({'name': '/path/somewhere/disabled.git', 'mode': 'disabled'}) # create a disabled
|
||||
self.Repo.search([]).write({'mode': 'disabled'}) # disable all depo, in case we have existing ones
|
||||
local_repo = self.Repo.create({'name': '/path/somewhere/rep.git'}) # create active repo
|
||||
ret = self.Repo._cron_fetch_and_build('runbotx.foo.com')
|
||||
ret = self.Repo._cron_fetch_and_build(hostname)
|
||||
self.assertEqual(None, ret)
|
||||
mock_scheduler.assert_called()
|
||||
self.assertTrue(mock_reload.called)
|
||||
host = self.env['runbot.host'].search([('name', '=', 'runbotx.foo.com')])
|
||||
host = self.env['runbot.host'].search([('name', '=', hostname)])
|
||||
self.assertEqual(host.name, hostname, 'A new host should have been created')
|
||||
self.assertGreater(host.psql_conn_count, 0, 'A least one connection should exist on the current psql instance')
|
||||
|
@ -1,15 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from unittest.mock import patch
|
||||
from odoo.tests import common
|
||||
from .common import RunbotCase
|
||||
|
||||
|
||||
class TestIrLogging(common.TransactionCase):
|
||||
class TestIrLogging(RunbotCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestIrLogging, self).setUp()
|
||||
self.Repo = self.env['runbot.repo']
|
||||
self.repo = self.Repo.create({'name': 'bla@example.com:foo/bar', 'server_files': 'server.py', 'addons_paths': 'addons,core/addons'})
|
||||
self.Branch = self.env['runbot.branch']
|
||||
self.branch = self.Branch.create({
|
||||
'repo_id': self.repo.id,
|
||||
'name': 'refs/heads/master'
|
||||
@ -26,10 +25,8 @@ class TestIrLogging(common.TransactionCase):
|
||||
VALUES (NOW() at time zone 'UTC', %s, %s, %s, %s, %s, %s, %s, %s)
|
||||
""", val)
|
||||
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._get_params')
|
||||
@patch('odoo.addons.runbot.models.build.fqdn')
|
||||
def test_ir_logging(self, mock_fqdn, mock_get_params):
|
||||
build = self.Build.create({
|
||||
def test_ir_logging(self):
|
||||
build = self.create_build({
|
||||
'branch_id': self.branch.id,
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'port': '1234',
|
||||
|
@ -1,12 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from collections import defaultdict
|
||||
from itertools import cycle
|
||||
from unittest.mock import patch
|
||||
from werkzeug.wrappers import Response
|
||||
from odoo.tests import common
|
||||
from odoo.addons.runbot.controllers import frontend
|
||||
from .common import RunbotCase
|
||||
|
||||
|
||||
class Test_Frontend(common.HttpCase):
|
||||
class Test_Frontend(RunbotCase):
|
||||
|
||||
def setUp(self):
|
||||
super(Test_Frontend, self).setUp()
|
||||
|
@ -2,22 +2,22 @@
|
||||
import datetime
|
||||
from unittest import skip
|
||||
from unittest.mock import patch, Mock
|
||||
from odoo.tests import common
|
||||
from odoo.tests import common, TransactionCase
|
||||
import logging
|
||||
import odoo
|
||||
import time
|
||||
|
||||
import datetime
|
||||
from .common import RunbotCase
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Test_Repo(common.TransactionCase):
|
||||
class Test_Repo(RunbotCase):
|
||||
|
||||
def setUp(self):
|
||||
super(Test_Repo, self).setUp()
|
||||
self.Repo = self.env['runbot.repo']
|
||||
self.commit_list = []
|
||||
self.mock_root = self.patchers['repo_root_patcher']
|
||||
|
||||
def mock_git_helper(self):
|
||||
"""Helper that returns a mock for repo._git()"""
|
||||
@ -26,9 +26,8 @@ class Test_Repo(common.TransactionCase):
|
||||
return '\n'.join(['\0'.join(commit_fields) for commit_fields in self.commit_list])
|
||||
return mock_git
|
||||
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._root')
|
||||
def test_base_fields(self, mock_root):
|
||||
mock_root.return_value = '/tmp/static'
|
||||
def test_base_fields(self):
|
||||
self.mock_root.return_value = '/tmp/static'
|
||||
repo = self.Repo.create({'name': 'bla@example.com:foo/bar'})
|
||||
self.assertEqual(repo.path, '/tmp/static/repo/bla_example.com_foo_bar')
|
||||
|
||||
@ -41,13 +40,12 @@ class Test_Repo(common.TransactionCase):
|
||||
local_repo = self.Repo.create({'name': '/path/somewhere/rep.git'})
|
||||
self.assertEqual(local_repo.short_name, 'somewhere/rep')
|
||||
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._root')
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._get_fetch_head_time')
|
||||
def test_repo_create_pending_builds(self, mock_fetch_head_time, mock_root):
|
||||
def test_repo_create_pending_builds(self, mock_fetch_head_time):
|
||||
""" Test that when finding new refs in a repo, the missing branches
|
||||
are created and new builds are created in pending state
|
||||
"""
|
||||
mock_root.return_value = '/tmp/static'
|
||||
self.mock_root.return_value = '/tmp/static'
|
||||
repo = self.Repo.create({'name': 'bla@example.com:foo/bar'})
|
||||
|
||||
# create another repo and branch to ensure there is no mismatch
|
||||
@ -152,8 +150,7 @@ class Test_Repo(common.TransactionCase):
|
||||
|
||||
|
||||
@skip('This test is for performances. It needs a lot of real branches in DB to mean something')
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._root')
|
||||
def test_repo_perf_find_new_commits(self, mock_root):
|
||||
def test_repo_perf_find_new_commits(self):
|
||||
mock_root.return_value = '/tmp/static'
|
||||
repo = self.env['runbot.repo'].search([('name', '=', 'blabla')])
|
||||
|
||||
@ -179,9 +176,11 @@ class Test_Repo(common.TransactionCase):
|
||||
|
||||
_logger.info('Create pending builds took: %ssec', (time.time() - inserted_time))
|
||||
|
||||
|
||||
class Test_Github(TransactionCase):
|
||||
def test_github(self):
|
||||
""" Test different github responses or failures"""
|
||||
repo = self.Repo.create({'name': 'bla@example.com:foo/foo'})
|
||||
repo = self.env['runbot.repo'].create({'name': 'bla@example.com:foo/foo'})
|
||||
self.assertEqual(repo._github('/repos/:owner/:repo/statuses/abcdef', dict(), ignore_errors=True), None, 'A repo without token should return None')
|
||||
repo.token = 'abc'
|
||||
with patch('odoo.addons.runbot.models.repo.requests.Session') as mock_session:
|
||||
@ -204,22 +203,23 @@ class Test_Repo(common.TransactionCase):
|
||||
|
||||
self.assertEqual(2, mock_session.return_value.post.call_count, "_github method should try two times by default")
|
||||
|
||||
class Test_Repo_Scheduler(common.TransactionCase):
|
||||
|
||||
@patch('odoo.addons.runbot.models.repo.runbot_repo._root')
|
||||
def setUp(self, mock_root):
|
||||
class Test_Repo_Scheduler(RunbotCase):
|
||||
|
||||
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')
|
||||
mock_root = self.patchers['repo_root_patcher']
|
||||
mock_root.return_value = '/tmp/static'
|
||||
self.Repo_model = self.env['runbot.repo']
|
||||
self.Branch_model = self.env['runbot.branch']
|
||||
self.foo_repo = self.Repo_model.create({'name': 'bla@example.com:foo/bar'})
|
||||
|
||||
self.foo_branch = self.Branch_model.create({
|
||||
self.foo_repo = self.Repo.create({'name': 'bla@example.com:foo/bar'})
|
||||
|
||||
self.foo_branch = self.Branch.create({
|
||||
'repo_id': self.foo_repo.id,
|
||||
'name': 'refs/head/foo'
|
||||
})
|
||||
@ -227,26 +227,23 @@ class Test_Repo_Scheduler(common.TransactionCase):
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._reap')
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._kill')
|
||||
@patch('odoo.addons.runbot.models.build.runbot_build._schedule')
|
||||
@patch('odoo.addons.runbot.models.host.fqdn')
|
||||
def test_repo_scheduler(self, mock_fqdn, mock_schedule, mock_kill, mock_reap):
|
||||
mock_fqdn.return_value = 'test_host'
|
||||
def test_repo_scheduler(self, mock_schedule, mock_kill, mock_reap):
|
||||
self.env['ir.config_parameter'].set_param('runbot.runbot_workers', 6)
|
||||
Build_model = self.env['runbot.build']
|
||||
builds = []
|
||||
# create 6 builds that are testing on the host to verify that
|
||||
# workers are not overfilled
|
||||
for build_name in ['a', 'b', 'c', 'd', 'e', 'f']:
|
||||
build = Build_model.create({
|
||||
build = self.create_build({
|
||||
'branch_id': self.foo_branch.id,
|
||||
'name': build_name,
|
||||
'port': '1234',
|
||||
'build_type': 'normal',
|
||||
'local_state': 'testing',
|
||||
'host': 'test_host'
|
||||
'host': 'host.runbot.com'
|
||||
})
|
||||
builds.append(build)
|
||||
# now the pending build that should stay unasigned
|
||||
scheduled_build = Build_model.create({
|
||||
scheduled_build = self.create_build({
|
||||
'branch_id': self.foo_branch.id,
|
||||
'name': 'sched_build',
|
||||
'port': '1234',
|
||||
@ -255,7 +252,7 @@ class Test_Repo_Scheduler(common.TransactionCase):
|
||||
})
|
||||
builds.append(scheduled_build)
|
||||
# create the build that should be assigned once a slot is available
|
||||
build = Build_model.create({
|
||||
build = self.create_build({
|
||||
'branch_id': self.foo_branch.id,
|
||||
'name': 'foobuild',
|
||||
'port': '1234',
|
||||
@ -272,10 +269,10 @@ class Test_Repo_Scheduler(common.TransactionCase):
|
||||
self.assertFalse(scheduled_build.host)
|
||||
|
||||
# give some room for the pending build
|
||||
Build_model.search([('name', '=', 'a')]).write({'local_state': 'done'})
|
||||
self.Build.search([('name', '=', 'a')]).write({'local_state': 'done'})
|
||||
|
||||
self.foo_repo._scheduler()
|
||||
build.invalidate_cache()
|
||||
scheduled_build.invalidate_cache()
|
||||
self.assertEqual(build.host, 'test_host')
|
||||
self.assertEqual(build.host, 'host.runbot.com')
|
||||
self.assertFalse(scheduled_build.host)
|
||||
|
@ -3,9 +3,10 @@ import datetime
|
||||
from unittest.mock import patch
|
||||
from odoo.tests import common
|
||||
import odoo
|
||||
from .common import RunbotCase
|
||||
|
||||
|
||||
class TestSchedule(common.TransactionCase):
|
||||
class TestSchedule(RunbotCase):
|
||||
|
||||
def setUp(self):
|
||||
# entering test mode to avoid that the _schedule method commits records
|
||||
@ -13,19 +14,16 @@ class TestSchedule(common.TransactionCase):
|
||||
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.os.makedirs')
|
||||
@patch('odoo.addons.runbot.models.build.os.path.getmtime')
|
||||
@patch('odoo.addons.runbot.models.build.docker_is_running')
|
||||
def test_schedule_mark_done(self, mock_running, mock_getmtime, mock_makedirs):
|
||||
def test_schedule_mark_done(self, mock_running, mock_getmtime):
|
||||
""" 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()
|
||||
|
Loading…
Reference in New Issue
Block a user