Move the script for running pre-releases into oslotest
Rather than maintaining the pre-release runner in oslo-incubator, put it in oslotest where it can be installed with the rest of the library. Change-Id: Idd58bfe3950d01725e239608f263dab5a0c9c908
This commit is contained in:
parent
e50b8b390e
commit
c69ddb9396
|
@ -25,6 +25,7 @@ packages =
|
|||
scripts =
|
||||
tools/oslo_debug_helper
|
||||
tools/oslo_run_cross_tests
|
||||
tools/oslo_run_pre_release_tests
|
||||
|
||||
[global]
|
||||
setup-hooks =
|
||||
|
|
|
@ -0,0 +1,211 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Run unit tests for projects that use a library.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import glob
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from oslo_config import cfg
|
||||
import oslo_tool_config as tconfig
|
||||
from pbr import packaging
|
||||
import pkg_resources
|
||||
|
||||
|
||||
def find_all_projects(repo_root):
|
||||
"""Scan the checked out repositories for all available projects.
|
||||
"""
|
||||
pattern = os.path.join(repo_root, 'openstack/*')
|
||||
candidates = glob.glob(pattern)
|
||||
prefix_len = len(repo_root)
|
||||
return [
|
||||
c[prefix_len:].lstrip('/')
|
||||
for c in candidates
|
||||
if os.path.isdir(c)
|
||||
]
|
||||
|
||||
|
||||
def find_consuming_projects(lib_name, repo_root, projects):
|
||||
"""Filter the list of projects to only include entries that use the library.
|
||||
"""
|
||||
for p in projects:
|
||||
consumer = False
|
||||
for base in packaging.get_requirements_files():
|
||||
req_file = os.path.join(repo_root, p, base)
|
||||
for req in packaging.parse_requirements([req_file]):
|
||||
try:
|
||||
parsed_req = pkg_resources.Requirement.parse(req)
|
||||
req_name = parsed_req.project_name
|
||||
except ValueError:
|
||||
continue
|
||||
if req_name == lib_name:
|
||||
consumer = True
|
||||
yield p
|
||||
break
|
||||
if consumer:
|
||||
break
|
||||
|
||||
|
||||
def main():
|
||||
conf = tconfig.get_config_parser()
|
||||
conf.register_cli_opt(
|
||||
cfg.StrOpt(
|
||||
'library-under-test',
|
||||
short='l',
|
||||
default='',
|
||||
help=('the name of the library being tested; '
|
||||
'defaults to current dir'),
|
||||
)
|
||||
)
|
||||
conf.register_cli_opt(
|
||||
cfg.BoolOpt(
|
||||
'update',
|
||||
short='u',
|
||||
default=False,
|
||||
help='update consumers before running tests',
|
||||
)
|
||||
)
|
||||
conf.register_cli_opt(
|
||||
cfg.BoolOpt(
|
||||
'verbose',
|
||||
short='v',
|
||||
default=False,
|
||||
help='print verbose output',
|
||||
)
|
||||
)
|
||||
conf.register_cli_opt(
|
||||
cfg.StrOpt(
|
||||
'ref',
|
||||
short='r',
|
||||
default='HEAD',
|
||||
help='the commit reference to test; defaults to HEAD',
|
||||
)
|
||||
)
|
||||
conf.register_cli_opt(
|
||||
cfg.MultiStrOpt(
|
||||
'env',
|
||||
short='e',
|
||||
default=['py27', 'pep8'],
|
||||
help=('the name of the tox environment to test; '
|
||||
'defaults to py27 and pep8'),
|
||||
)
|
||||
)
|
||||
conf.register_cli_opt(
|
||||
cfg.MultiStrOpt(
|
||||
'consumer',
|
||||
positional=True,
|
||||
default=[],
|
||||
help='the name of a project to test with; may be repeated',
|
||||
)
|
||||
)
|
||||
tconfig.parse_arguments(conf)
|
||||
|
||||
repo_root = os.path.expanduser(conf.repo_root)
|
||||
|
||||
# Figure out which library is being tested
|
||||
lib_name = conf.library_under_test
|
||||
if not lib_name:
|
||||
if conf.verbose:
|
||||
print('finding library name')
|
||||
lib_name = subprocess.check_output(
|
||||
['python', 'setup.py', '--name']
|
||||
).strip()
|
||||
lib_dir = os.getcwd()
|
||||
else:
|
||||
lib_dir = os.path.join(repo_root, 'openstack', lib_name)
|
||||
print('testing %s in %s' % (lib_name, lib_dir))
|
||||
|
||||
projects = set(conf.consumer)
|
||||
if not projects:
|
||||
# TODO(dhellmann): Need to update this to look at gerrit, so
|
||||
# we can check out the projects we want to test with.
|
||||
if conf.verbose:
|
||||
print('defaulting to all projects under %s/openstack' % repo_root)
|
||||
projects = find_all_projects(repo_root)
|
||||
|
||||
# Filter out projects that do not require the library under test
|
||||
before = len(projects)
|
||||
projects = list(find_consuming_projects(lib_name, repo_root, projects))
|
||||
after = len(projects)
|
||||
if (after < before) and conf.verbose:
|
||||
print('ignoring %s projects that do not use %s'
|
||||
% (before - after, lib_name))
|
||||
|
||||
projects = list(sorted(projects))
|
||||
if not projects:
|
||||
print('ERROR: found no projects using %s' % lib_name)
|
||||
return 1
|
||||
if conf.verbose:
|
||||
print('preparing to test %s projects' % after)
|
||||
|
||||
# Make sure the lib being tested is set to the reference intended.
|
||||
if conf.ref != 'HEAD':
|
||||
if conf.verbose:
|
||||
print('ensuring %s is updated to %s' % (lib_name, conf.ref))
|
||||
subprocess.check_call(
|
||||
['git', 'checkout', conf.ref],
|
||||
cwd=lib_dir,
|
||||
)
|
||||
|
||||
git_quiet = ['-q'] if not conf.verbose else []
|
||||
|
||||
failures = []
|
||||
for p in projects:
|
||||
if conf.verbose:
|
||||
print()
|
||||
proj_dir = os.path.join(repo_root, p)
|
||||
if conf.update:
|
||||
if conf.verbose:
|
||||
print('updating %s with "git pull"' % p)
|
||||
subprocess.Popen(
|
||||
['git', 'pull'] + git_quiet,
|
||||
cwd=proj_dir,
|
||||
).communicate()
|
||||
p_log_name = p.split('/')[-1].replace('.', '-')
|
||||
for e in conf.env:
|
||||
log_name = 'cross-test-%s-%s.log' % (p_log_name, e)
|
||||
with open(log_name, 'w') as log_file:
|
||||
print('testing %s in %s, logging to %s' % (e, p, log_name),
|
||||
end=' ')
|
||||
sys.stdout.flush()
|
||||
command = ['oslo_run_cross_tests', proj_dir, e]
|
||||
log_file.write('running: %s\n' % ' '.join(command))
|
||||
log_file.flush() # since Popen is going to use the fd directly
|
||||
cmd = subprocess.Popen(
|
||||
command,
|
||||
cwd=lib_dir,
|
||||
stdout=log_file,
|
||||
stderr=log_file
|
||||
)
|
||||
cmd.communicate()
|
||||
log_file.write('\nexit code: %s\n' % cmd.returncode)
|
||||
if cmd.returncode:
|
||||
print('FAIL')
|
||||
failures.append((p, e, cmd.returncode))
|
||||
else:
|
||||
print('PASS')
|
||||
|
||||
if failures:
|
||||
print('\nFAILED %d jobs' % len(failures))
|
||||
return 1
|
||||
print('\nPASSED all jobs')
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
Loading…
Reference in New Issue