mirror of
https://github.com/odoo/runbot.git
synced 2025-03-15 15:35:46 +07:00
[FIX] runbot: fix coverage since shared sources
The requirements path and python version where defined from server in cmd. Since in coverage we add a 'python' before server, it is difficult to define which element of the cmd is the server. A solution here is simply to define requirements install and python version when building cmd since we have access to all build/source informations. We also add python part in every cases, and coverage params are now a _cmd python_params. The _cmd method now returns a Command object instead of a list, which behave has a list for the cmd part but also contains a pres and posts list. pres are requirement install, preparation, ... cmd is the original cmd list, element can be append or added, this will allow to keep existing python job without to much changes. posts are post cmd commands, like coverage result making. This commit also fix issue with create_job dependencies.
This commit is contained in:
parent
785001acac
commit
81fefee137
@ -99,13 +99,3 @@ def local_pgadmin_cursor():
|
||||
finally:
|
||||
if cnx:
|
||||
cnx.close()
|
||||
|
||||
def get_py_version(build):
|
||||
"""return the python name to use from build instance"""
|
||||
executables = [ 'odoo-bin', 'openerp-server' ]
|
||||
for server_path in map(build._path, executables):
|
||||
if os.path.exists(server_path):
|
||||
with open(server_path, 'r') as f:
|
||||
if f.readline().strip().endswith('python3'):
|
||||
return 'python3'
|
||||
return 'python'
|
||||
|
@ -31,19 +31,27 @@ ENV COVERAGE_FILE /data/build/.coverage
|
||||
""" % {'group_id': os.getgid(), 'user_id': os.getuid()}
|
||||
|
||||
|
||||
def build_odoo_cmd(odoo_cmd):
|
||||
""" returns the chain of commands necessary to run odoo inside the container
|
||||
: param odoo_cmd: odoo command as a list
|
||||
: returns: a string with the command chain to execute in the docker container
|
||||
"""
|
||||
# build cmd
|
||||
cmd_chain = []
|
||||
cmd_chain.append('cd /data/build')
|
||||
server_path = odoo_cmd[0]
|
||||
requirement_path = os.path.join(os.path.dirname(server_path), 'requirements.txt')
|
||||
cmd_chain.append('head -1 %s | grep -q python3 && sudo pip3 install -r %s || sudo pip install -r %s' % (server_path, requirement_path, requirement_path))
|
||||
cmd_chain.append(' '.join(odoo_cmd))
|
||||
return ' && '.join(cmd_chain)
|
||||
class Command():
|
||||
def __init__(self, pres, cmd, posts):
|
||||
self.pres = pres or []
|
||||
self.cmd = cmd
|
||||
self.posts = posts or []
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.cmd, name)
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.cmd[key]
|
||||
|
||||
def __add__(self, l):
|
||||
return Command(self.pres, self.cmd + l, self.posts)
|
||||
|
||||
def build(self):
|
||||
cmd_chain = []
|
||||
cmd_chain += [' '.join(pre) for pre in self.pres if pre]
|
||||
cmd_chain.append(' '.join(self))
|
||||
cmd_chain += [' '.join(post) for post in self.posts if post]
|
||||
return ' && '.join(cmd_chain)
|
||||
|
||||
|
||||
def docker_build(log_path, build_dir):
|
||||
@ -62,6 +70,7 @@ def docker_build(log_path, build_dir):
|
||||
dbuild = subprocess.Popen(['docker', 'build', '--tag', 'odoo:runbot_tests', '.'], stdout=logs, stderr=logs, cwd=docker_dir)
|
||||
dbuild.wait()
|
||||
|
||||
|
||||
def docker_run(run_cmd, log_path, build_dir, container_name, exposed_ports=None, cpu_limit=None, preexec_fn=None, ro_volumes=None):
|
||||
"""Run tests in a docker container
|
||||
:param run_cmd: command string to run in container
|
||||
@ -74,7 +83,8 @@ def docker_run(run_cmd, log_path, build_dir, container_name, exposed_ports=None,
|
||||
"""
|
||||
_logger.debug('Docker run command: %s', run_cmd)
|
||||
logs = open(log_path, 'w')
|
||||
logs.write("Docker command:\n%s\n=================================================\n" % run_cmd.replace('&& ', '&&\n').replace('|| ','||\n\t'))
|
||||
run_cmd = 'cd /data/build && %s' % run_cmd
|
||||
logs.write("Docker command:\n%s\n=================================================\n" % run_cmd.replace('&& ', '&&\n').replace('|| ', '||\n\t'))
|
||||
# create start script
|
||||
docker_command = [
|
||||
'docker', 'run', '--rm',
|
||||
@ -154,7 +164,8 @@ def tests(args):
|
||||
if args.kill:
|
||||
logfile = os.path.join(args.build_dir, 'logs', 'logs-partial.txt')
|
||||
container_name = 'odoo-container-test-%s' % datetime.datetime.now().microsecond
|
||||
docker_run(build_odoo_cmd(odoo_cmd), logfile, args.build_dir, container_name)
|
||||
# FIXME
|
||||
# docker_run(build_odoo_cmd(odoo_cmd), logfile, args.build_dir, container_name)
|
||||
# Test stopping the container
|
||||
_logger.info('Waiting 30 sec before killing the build')
|
||||
time.sleep(30)
|
||||
@ -169,7 +180,8 @@ def tests(args):
|
||||
with open(os.path.join(args.build_dir, 'odoo-bin'), 'r') as exfile:
|
||||
pyversion = 'python3' if 'python3' in exfile.readline() else 'python'
|
||||
odoo_cmd = [ pyversion, '-m', 'coverage', 'run', '--branch', '--source', '/data/build'] + omit + odoo_cmd
|
||||
docker_run(build_odoo_cmd(odoo_cmd), logfile, args.build_dir, container_name)
|
||||
# FIXME
|
||||
# docker_run(build_odoo_cmd(odoo_cmd), logfile, args.build_dir, container_name)
|
||||
time.sleep(1) # give time for the container to start
|
||||
|
||||
while docker_is_running(container_name):
|
||||
@ -200,7 +212,9 @@ def tests(args):
|
||||
if smtp_host:
|
||||
odoo_cmd.extend(['--smtp', smtp_host])
|
||||
container_name = 'odoo-container-test-%s' % datetime.datetime.now().microsecond
|
||||
docker_run(build_odoo_cmd(odoo_cmd), logfile, args.build_dir, container_name, exposed_ports=[args.odoo_port, args.odoo_port + 1], cpu_limit=300)
|
||||
|
||||
# FIXME
|
||||
# docker_run(build_odoo_cmd(odoo_cmd), logfile, args.build_dir, container_name, exposed_ports=[args.odoo_port, args.odoo_port + 1], cpu_limit=300)
|
||||
|
||||
if __name__ == '__main__':
|
||||
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s %(name)s: %(message)s')
|
||||
|
@ -9,7 +9,7 @@ import subprocess
|
||||
import time
|
||||
import datetime
|
||||
from ..common import dt2time, fqdn, now, grep, uniq_list, local_pgadmin_cursor, s2human, Commit
|
||||
from ..container import docker_build, docker_stop, docker_is_running
|
||||
from ..container import docker_build, docker_stop, docker_is_running, Command
|
||||
from odoo.addons.runbot.models.repo import HashMissingException
|
||||
from odoo import models, fields, api
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
@ -283,7 +283,7 @@ class runbot_build(models.Model):
|
||||
# maybe update duplicate priority if needed
|
||||
|
||||
docker_source_folders = set()
|
||||
for commit in build_id.get_all_commit():
|
||||
for commit in build_id._get_all_commit():
|
||||
docker_source_folder = build_id._docker_source_folder(commit)
|
||||
if docker_source_folder in docker_source_folders:
|
||||
extra_info['commit_path_mode'] = 'rep_sha'
|
||||
@ -384,6 +384,14 @@ class runbot_build(models.Model):
|
||||
params['dep'][result[0]] = result[1]
|
||||
return params
|
||||
|
||||
def _copy_dependency_ids(self):
|
||||
return [(0, 0, {
|
||||
'match_type': dep.match_type,
|
||||
'closest_branch_id': dep.closest_branch_id.id,
|
||||
'dependency_hash': dep.dependency_hash,
|
||||
'dependecy_repo_id': dep.dependecy_repo_id.id,
|
||||
}) for dep in self.dependency_ids]
|
||||
|
||||
def _force(self, message=None, exact=False):
|
||||
"""Force a rebuild and return a recordset of forced builds"""
|
||||
forced_builds = self.env['runbot.build']
|
||||
@ -408,19 +416,13 @@ class runbot_build(models.Model):
|
||||
'build_type': 'rebuild',
|
||||
}
|
||||
if exact:
|
||||
if build.dependency_ids:
|
||||
values['dependency_ids'] = [(0, 0, {
|
||||
'match_type': dep.match_type,
|
||||
'closest_branch_id': dep.closest_branch_id.id,
|
||||
'dependency_hash': dep.dependency_hash,
|
||||
'dependecy_repo_id': dep.dependecy_repo_id.id,
|
||||
}) for dep in build.dependency_ids]
|
||||
values.update({
|
||||
'config_id': build.config_id.id,
|
||||
'extra_params': build.extra_params,
|
||||
'orphan_result': build.orphan_result,
|
||||
'dependency_ids': build._copy_dependency_ids(),
|
||||
})
|
||||
#if replace: ?
|
||||
# if replace: ?
|
||||
if build.parent_id:
|
||||
values.update({
|
||||
'parent_id': build.parent_id.id, # attach it to parent
|
||||
@ -643,7 +645,7 @@ class runbot_build(models.Model):
|
||||
def _server(self, *path):
|
||||
"""Return the absolute path to the direcory containing the server file, adding optional *path"""
|
||||
self.ensure_one()
|
||||
commit = self.get_server_commit()
|
||||
commit = self._get_server_commit()
|
||||
if os.path.exists(commit._source_path('odoo')):
|
||||
return commit._source_path('odoo', *path)
|
||||
return commit._source_path('openerp', *path)
|
||||
@ -688,7 +690,7 @@ class runbot_build(models.Model):
|
||||
self.ensure_one() # will raise exception if hash not found, we don't want to fail for all build.
|
||||
# checkout branch
|
||||
exports = {}
|
||||
for commit in commits or self.get_all_commit():
|
||||
for commit in commits or self._get_all_commit():
|
||||
build_export_path = self._docker_source_folder(commit)
|
||||
if build_export_path in exports:
|
||||
self._log('_checkout', 'Multiple repo have same export path in build, some source may be missing for %s' % build_export_path, level='ERROR')
|
||||
@ -705,7 +707,7 @@ class runbot_build(models.Model):
|
||||
# checkout branch
|
||||
repo_modules = []
|
||||
available_modules = []
|
||||
for commit in commits or self.get_all_commit():
|
||||
for commit in commits or self._get_all_commit():
|
||||
for (addons_path, module, manifest_file_name) in self._get_available_modules(commit):
|
||||
if commit.repo == self.repo_id:
|
||||
repo_modules.append(module)
|
||||
@ -819,54 +821,58 @@ class runbot_build(models.Model):
|
||||
if not child.duplicate_id:
|
||||
child._ask_kill()
|
||||
|
||||
def get_all_commit(self):
|
||||
return [Commit(self.repo_id, self.name)] + [Commit(dep.get_repo(), dep.dependency_hash) for dep in self.dependency_ids]
|
||||
def _get_all_commit(self):
|
||||
return [Commit(self.repo_id, self.name)] + [Commit(dep._get_repo(), dep.dependency_hash) for dep in self.dependency_ids]
|
||||
|
||||
def get_server_commit(self, commits=None):
|
||||
def _get_server_commit(self, commits=None):
|
||||
"""
|
||||
returns a Commit() of the first repo containing server files found in commits or in build commits
|
||||
the commits param is not used in code base but could be usefull for jobs and crons
|
||||
"""
|
||||
for commit in (commits or self.get_all_commit()):
|
||||
for commit in (commits or self._get_all_commit()):
|
||||
if commit.repo.server_files:
|
||||
return commit
|
||||
raise ValidationError('No repo found with defined server_files')
|
||||
|
||||
def get_addons_path(self, commits=None):
|
||||
for commit in (commits or self.get_all_commit()):
|
||||
def _get_addons_path(self, commits=None):
|
||||
for commit in (commits or self._get_all_commit()):
|
||||
source_path = self._docker_source_folder(commit)
|
||||
for addons_path in commit.repo.addons_paths.split(','):
|
||||
if os.path.isdir(commit._source_path(addons_path)):
|
||||
yield os.path.join(source_path, addons_path).strip(os.sep)
|
||||
|
||||
def get_server_info(self, commit=None):
|
||||
def _get_server_info(self, commit=None):
|
||||
server_dir = False
|
||||
server = False
|
||||
commit = commit or self.get_server_commit()
|
||||
commit = commit or self._get_server_commit()
|
||||
for server_file in commit.repo.server_files.split(','):
|
||||
if os.path.isfile(commit._source_path(server_file)):
|
||||
return (self._docker_source_folder(commit), server_file)
|
||||
return (commit, server_file)
|
||||
self._log('server_info', 'No server found in %s' % commit, level='ERROR')
|
||||
raise ValidationError('No server found in %s' % commit)
|
||||
|
||||
def _cmd(self):
|
||||
"""Return a tuple describing the command to start the build
|
||||
First part is list with the command and parameters
|
||||
Second part is a list of Odoo modules
|
||||
def _cmd(self, python_params=None, py_version=None):
|
||||
"""Return a list describing the command to start the build
|
||||
"""
|
||||
self.ensure_one()
|
||||
build = self
|
||||
python_params = python_params or []
|
||||
py_version = py_version if py_version is not None else build._get_py_version()
|
||||
(server_commit, server_file) = self._get_server_info()
|
||||
server_dir = self._docker_source_folder(server_commit)
|
||||
addons_paths = self._get_addons_path()
|
||||
requirement_path = os.path.join(server_dir, 'requirements.txt')
|
||||
pres = [['sudo', 'pip%s' % py_version, 'install', '-r', '%s' % requirement_path]]
|
||||
|
||||
(server_dir, server_file) = self.get_server_info()
|
||||
addons_paths = self.get_addons_path()
|
||||
# commandline
|
||||
cmd = [os.path.join('/data/build', server_dir, server_file), '--addons-path', ",".join(addons_paths)]
|
||||
cmd = ['python%s' % py_version] + python_params + [os.path.join(server_dir, server_file), '--addons-path', ",".join(addons_paths)]
|
||||
# options
|
||||
if grep(build._server("tools/config.py"), "no-xmlrpcs"): # move that to configs ?
|
||||
config_path = build._server("tools/config.py")
|
||||
if grep(config_path, "no-xmlrpcs"): # move that to configs ?
|
||||
cmd.append("--no-xmlrpcs")
|
||||
if grep(build._server("tools/config.py"), "no-netrpc"):
|
||||
if grep(config_path, "no-netrpc"):
|
||||
cmd.append("--no-netrpc")
|
||||
if grep(build._server("tools/config.py"), "log-db"):
|
||||
if grep(config_path, "log-db"):
|
||||
logdb_uri = self.env['ir.config_parameter'].get_param('runbot.runbot_logdb_uri')
|
||||
logdb = self.env.cr.dbname
|
||||
if logdb_uri and grep(build._server('sql_db.py'), 'allow_uri'):
|
||||
@ -875,7 +881,7 @@ class runbot_build(models.Model):
|
||||
if grep(build._server('tools/config.py'), 'log-db-level'):
|
||||
cmd += ["--log-db-level", '25']
|
||||
|
||||
if grep(build._server("tools/config.py"), "data-dir"):
|
||||
if grep(config_path, "data-dir"):
|
||||
datadir = build._path('datadir')
|
||||
if not os.path.exists(datadir):
|
||||
os.mkdir(datadir)
|
||||
@ -883,8 +889,7 @@ class runbot_build(models.Model):
|
||||
|
||||
# use the username of the runbot host to connect to the databases
|
||||
cmd += ['-r %s' % pwd.getpwuid(os.getuid()).pw_name]
|
||||
|
||||
return cmd
|
||||
return Command(pres, cmd, [])
|
||||
|
||||
def _github_status_notify_all(self, status):
|
||||
"""Notify each repo with a status"""
|
||||
@ -936,6 +941,15 @@ class runbot_build(models.Model):
|
||||
new_step = step_ids[next_index] # job to do, state is job_state (testing or running)
|
||||
return {'active_step': new_step.id, 'local_state': new_step._step_state()}
|
||||
|
||||
def _get_py_version(self):
|
||||
"""return the python name to use from build instance"""
|
||||
(server_commit, server_file) = self._get_server_info()
|
||||
server_path = server_commit._source_path(server_file)
|
||||
with open(server_path, 'r') as f:
|
||||
if f.readline().strip().endswith('python3'):
|
||||
return '3'
|
||||
return ''
|
||||
|
||||
def read_file(self, file, mode='r'):
|
||||
file_path = self._path(file)
|
||||
try:
|
||||
|
@ -5,8 +5,8 @@ import os
|
||||
import re
|
||||
import shlex
|
||||
import time
|
||||
from ..common import now, grep, get_py_version, time2str, rfind, Commit
|
||||
from ..container import docker_run, docker_get_gateway_ip, build_odoo_cmd
|
||||
from ..common import now, grep, time2str, rfind, Commit
|
||||
from ..container import docker_run, docker_get_gateway_ip, Command
|
||||
from odoo import models, fields, api
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tools.safe_eval import safe_eval, test_python_expr
|
||||
@ -201,7 +201,7 @@ class ConfigStep(models.Model):
|
||||
build._logger('Too much build created')
|
||||
break
|
||||
children = Build.create({
|
||||
'dependency_ids': [(4, did.id) for did in build.dependency_ids],
|
||||
'dependency_ids': build._copy_dependency_ids(),
|
||||
'config_id': create_config.id,
|
||||
'parent_id': build.id,
|
||||
'branch_id': build.branch_id.id,
|
||||
@ -228,12 +228,11 @@ class ConfigStep(models.Model):
|
||||
'_logger': _logger,
|
||||
'log_path': log_path,
|
||||
'glob': glob.glob,
|
||||
'build_odoo_cmd': build_odoo_cmd,
|
||||
'Command': Command,
|
||||
'base64': base64,
|
||||
're': re,
|
||||
'time': time,
|
||||
'grep': grep,
|
||||
'get_py_version': get_py_version,
|
||||
'rfind': rfind,
|
||||
}
|
||||
return safe_eval(self.sudo().python_code.strip(), eval_ctx, mode="exec", nocopy=True)
|
||||
@ -244,8 +243,7 @@ class ConfigStep(models.Model):
|
||||
build._log('run', 'Start running build %s' % build.dest)
|
||||
# run server
|
||||
cmd = build._cmd()
|
||||
server = build._server()
|
||||
if os.path.exists(os.path.join(server, 'addons/im_livechat')):
|
||||
if os.path.exists(build._get_server_commit()._source_path('addons/im_livechat')):
|
||||
cmd += ["--workers", "2"]
|
||||
cmd += ["--longpolling-port", "8070"]
|
||||
cmd += ["--max-cron-threads", "1"]
|
||||
@ -257,7 +255,7 @@ class ConfigStep(models.Model):
|
||||
# we need to have at least one job of type install_odoo to run odoo, take the last one for db_name.
|
||||
cmd += ['-d', '%s-%s' % (build.dest, db_name)]
|
||||
|
||||
if grep(os.path.join(server, "tools/config.py"), "db-filter"):
|
||||
if grep(build._server("tools/config.py"), "db-filter"):
|
||||
if build.repo_id.nginx:
|
||||
cmd += ['--db-filter', '%d.*$']
|
||||
else:
|
||||
@ -271,19 +269,26 @@ class ConfigStep(models.Model):
|
||||
build_port = build.port
|
||||
self.env.cr.commit() # commit before docker run to be 100% sure that db state is consistent with dockers
|
||||
self.invalidate_cache()
|
||||
return docker_run(build_odoo_cmd(cmd), log_path, build_path, docker_name, exposed_ports=[build_port, build_port + 1], ro_volumes=exports)
|
||||
return docker_run(cmd.build(), log_path, build_path, docker_name, exposed_ports=[build_port, build_port + 1], ro_volumes=exports)
|
||||
|
||||
def _run_odoo_install(self, build, log_path):
|
||||
exports = build._checkout()
|
||||
cmd = build._cmd()
|
||||
|
||||
modules_to_install = self._modules_to_install(build)
|
||||
mods = ",".join(modules_to_install)
|
||||
python_params = []
|
||||
py_version = build._get_py_version()
|
||||
if self.coverage:
|
||||
build.coverage = True
|
||||
coverage_extra_params = self._coverage_params(build, modules_to_install)
|
||||
python_params = ['-m', 'coverage', 'run', '--branch', '--source', '/data/build'] + coverage_extra_params
|
||||
cmd = build._cmd(python_params, py_version)
|
||||
# create db if needed
|
||||
db_name = "%s-%s" % (build.dest, self.db_name)
|
||||
if self.create_db:
|
||||
build._local_pg_createdb(db_name)
|
||||
cmd += ['-d', db_name]
|
||||
# list module to install
|
||||
modules_to_install = self._modules_to_install(build)
|
||||
mods = ",".join(modules_to_install)
|
||||
if mods:
|
||||
cmd += ['-i', mods]
|
||||
if self.test_enable:
|
||||
@ -301,17 +306,11 @@ class ConfigStep(models.Model):
|
||||
if self.extra_params:
|
||||
cmd.extend(shlex.split(self.extra_params))
|
||||
|
||||
if self.coverage:
|
||||
build.coverage = True
|
||||
coverage_extra_params = self._coverage_params(build, modules_to_install)
|
||||
py_version = get_py_version(build)
|
||||
cmd = [py_version, '-m', 'coverage', 'run', '--branch', '--source', '/data/build'] + coverage_extra_params + cmd
|
||||
|
||||
cmd += self._post_install_command(build, modules_to_install) # coverage post, extra-checks, ...
|
||||
cmd.posts.append(self._post_install_command(build, modules_to_install, py_version)) # coverage post, extra-checks, ...
|
||||
|
||||
max_timeout = int(self.env['ir.config_parameter'].get_param('runbot.runbot_timeout', default=10000))
|
||||
timeout = min(self.cpu_limit, max_timeout)
|
||||
return docker_run(build_odoo_cmd(cmd), log_path, build._path(), build._get_docker_name(), cpu_limit=timeout, ro_volumes=exports)
|
||||
return docker_run(cmd.build(), log_path, build._path(), build._get_docker_name(), cpu_limit=timeout, ro_volumes=exports)
|
||||
|
||||
def _modules_to_install(self, build):
|
||||
modules_to_install = set([mod.strip() for mod in self.install_modules.split(',')])
|
||||
@ -322,18 +321,18 @@ class ConfigStep(models.Model):
|
||||
# todo add without support
|
||||
return modules_to_install
|
||||
|
||||
def _post_install_command(self, build, modules_to_install):
|
||||
def _post_install_command(self, build, modules_to_install, py_version=None):
|
||||
if self.coverage:
|
||||
py_version = get_py_version(build)
|
||||
py_version = py_version if py_version is not None else build._get_py_version()
|
||||
# prepare coverage result
|
||||
cov_path = build._path('coverage')
|
||||
os.makedirs(cov_path, exist_ok=True)
|
||||
return ['&&', py_version, "-m", "coverage", "html", "-d", "/data/build/coverage", "--ignore-errors"]
|
||||
return ['python%s' % py_version, "-m", "coverage", "html", "-d", "/data/build/coverage", "--ignore-errors"]
|
||||
return []
|
||||
|
||||
def _coverage_params(self, build, modules_to_install):
|
||||
pattern_to_omit = set()
|
||||
for commit in build.get_all_commit():
|
||||
for commit in build._get_all_commit():
|
||||
docker_source_folder = build._docker_source_folder(commit)
|
||||
for manifest_file in commit.repo.manifest_files.split(','):
|
||||
pattern_to_omit.add('*%s' % manifest_file)
|
||||
|
@ -10,6 +10,6 @@ class RunbotBuildDependency(models.Model):
|
||||
closest_branch_id = fields.Many2one('runbot.branch', 'Branch', required=True, ondelete='cascade')
|
||||
match_type = fields.Char('Match Type')
|
||||
|
||||
def get_repo(self):
|
||||
def _get_repo(self):
|
||||
return self.closest_branch_id.repo_id or self.dependecy_repo_id
|
||||
|
||||
|
@ -59,7 +59,7 @@ class runbot_repo(models.Model):
|
||||
config_id = fields.Many2one('runbot.build.config', 'Run Config', compute='_compute_config_id', inverse='_inverse_config_id')
|
||||
|
||||
server_files = fields.Char('Server files', help='Comma separated list of possible server files') # odoo-bin,openerp-server,openerp-server.py
|
||||
manifest_files = fields.Char('Addons files', help='Comma separated list of possible addons files', default='__manifest__.py,__openerp__.py')
|
||||
manifest_files = fields.Char('Addons files', help='Comma separated list of possible addons files', default='__manifest__.py')
|
||||
addons_paths = fields.Char('Addons files', help='Comma separated list of possible addons path', default='')
|
||||
|
||||
def _compute_config_id(self):
|
||||
|
@ -84,7 +84,7 @@ class Test_Build(common.TransactionCase):
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'port': '1234',
|
||||
})
|
||||
cmd = build._cmd()
|
||||
cmd = build._cmd(py_version=3)
|
||||
self.assertIn('--log-db=%s' % uri, cmd)
|
||||
|
||||
@patch('odoo.addons.runbot.models.build.os.path.isdir')
|
||||
@ -100,8 +100,9 @@ class Test_Build(common.TransactionCase):
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'port': '1234',
|
||||
})
|
||||
cmd = build._cmd()
|
||||
self.assertEqual('/data/build/bar/server.py', cmd[0])
|
||||
cmd = build._cmd(py_version=3)
|
||||
self.assertEqual('python3', cmd[0])
|
||||
self.assertEqual('bar/server.py', cmd[1])
|
||||
self.assertIn('--addons-path', cmd)
|
||||
addons_path_pos = cmd.index('--addons-path') + 1
|
||||
self.assertEqual(cmd[addons_path_pos], 'bar/addons,bar/core/addons')
|
||||
@ -151,11 +152,12 @@ class Test_Build(common.TransactionCase):
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'port': '1234',
|
||||
})
|
||||
cmd = build._cmd()
|
||||
cmd = build._cmd(py_version=3)
|
||||
self.assertIn('--addons-path', cmd)
|
||||
addons_path_pos = cmd.index('--addons-path') + 1
|
||||
self.assertEqual(cmd[addons_path_pos], 'bar-ent,bar/addons,bar/core/addons')
|
||||
self.assertEqual('/data/build/bar/server.py', cmd[0])
|
||||
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')
|
||||
@ -193,11 +195,12 @@ class Test_Build(common.TransactionCase):
|
||||
'name': 'd0d0caca0000ffffffffffffffffffffffffffff',
|
||||
'port': '1234',
|
||||
})
|
||||
cmd = build._cmd()
|
||||
cmd = build._cmd(py_version=3)
|
||||
self.assertIn('--addons-path', cmd)
|
||||
addons_path_pos = cmd.index('--addons-path') + 1
|
||||
self.assertEqual(cmd[addons_path_pos], 'bar-d0d0caca,bar-dfdfcfcf/addons,bar-dfdfcfcf/core/addons')
|
||||
self.assertEqual('/data/build/bar-dfdfcfcf/server.py', cmd[0])
|
||||
self.assertEqual('bar-dfdfcfcf/server.py', cmd[1])
|
||||
self.assertEqual('python3', cmd[0])
|
||||
|
||||
def test_build_config_from_branch_default(self):
|
||||
"""test build config_id is computed from branch default config_id"""
|
||||
|
@ -1,4 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from unittest.mock import patch
|
||||
from odoo.tests import common
|
||||
|
||||
|
||||
@ -79,3 +80,36 @@ class TestBuildConfigStep(common.TransactionCase):
|
||||
child_build.local_result = 'ko'
|
||||
|
||||
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):
|
||||
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], 'python3 -m coverage html -d /data/build/coverage --ignore-errors')
|
||||
self.assertEqual(log_path, 'dev/null/logpath')
|
||||
|
||||
mock_docker_run.side_effect = docker_run
|
||||
|
||||
config_step._run_odoo_install(self.parent_build, 'dev/null/logpath')
|
||||
|
@ -22,7 +22,7 @@ class Step(models.Model):
|
||||
|
||||
def _runbot_cla_check(self, build, log_path):
|
||||
build._checkout()
|
||||
cla_glob = glob.glob(build.get_server_commit()._source_path("doc/cla/*/*.md"))
|
||||
cla_glob = glob.glob(build._get_server_commit()._source_path("doc/cla/*/*.md"))
|
||||
if cla_glob:
|
||||
description = "%s Odoo CLA signature check" % build.author
|
||||
mo = re.search('[^ <@]+@[^ @>]+', build.author_email or '')
|
||||
|
Loading…
Reference in New Issue
Block a user