import os.path
import re
import sys
import yaml
from common import *
from itertools import chain
LOG_DIR = os.path.join('local', 'tests')
set_toolbox_trace(env_var='TRACE_TEST_MATRIX')
def main():
load_globals_from_metadata('test-matrix', globals(),
{
'LOG_DIR',
})
travis = yaml.load(open('.travis.yml'))
script = translate_script(travis.get('script', None))
default_rust_vers = travis['rust']
matrix_includes = travis.get('matrix', {}).get('include', [])
vers = set(default_rust_vers)
include_vers = []
exclude_vers = set()
if not os.path.exists(LOG_DIR):
os.makedirs(LOG_DIR)
for arg in sys.argv[1:]:
if arg in vers and arg not in include_vers:
include_vers.append(arg)
elif arg.startswith('-') and arg[1:] in vers:
exclude_vers.add(arg[1:])
else:
msg("Don't know how to deal with argument `%s`." % arg)
sys.exit(1)
if include_vers == []:
include_vers = default_rust_vers[:]
rust_vers = [v for v in include_vers if v not in exclude_vers]
msg('Tests will be run for: %s' % ', '.join(rust_vers))
results = []
for rust_ver in rust_vers:
seq_id = 0
for env_var_str in travis.get('env', [""]):
env_vars = parse_env_vars(env_var_str)
for row in chain([{}], matrix_includes):
if row.get('rust', None) not in (None, rust_ver):
continue
row_env_vars = parse_env_vars(row.get('env', ""))
cmd_env = {}
cmd_env.update(env_vars)
cmd_env.update(row_env_vars)
success = run_script(script, rust_ver, seq_id, cmd_env)
results.append((rust_ver, seq_id, success))
seq_id += 1
print("")
msg('Results:')
for rust_ver, seq_id, success in results:
msg('%s #%d: %s' % (rust_ver, seq_id, 'OK' if success else 'Failed!'))
def parse_env_vars(s):
env_vars = {}
for m in re.finditer(r"""([A-Za-z0-9_]+)=(?:"([^"]+)"|(\S*))""", s.strip()):
k = m.group(1)
v = m.group(2) or m.group(3)
env_vars[k] = v
return env_vars
def run_script(script, rust_ver, seq_id, env):
target_dir = os.path.join('target', '%s-%d' % (rust_ver, seq_id))
log_path = os.path.join(LOG_DIR, '%s-%d.log' % (rust_ver, seq_id))
log_file = open(log_path, 'wt')
msg('Running tests for %s #%d...' % (rust_ver, seq_id))
success = True
def sub_env(m):
name = m.group(1) or m.group(2)
return cmd_env[name]
log_file.write('# %s #%d\n' % (rust_ver, seq_id))
for k, v in env.items():
log_file.write('# %s=%r\n' % (k, v))
cmd_env = os.environ.copy()
cmd_env['CARGO_TARGET_DIR'] = target_dir
cmd_env.update(env)
for cmd in script:
cmd = re.sub(r"\$(?:([A-Za-z0-9_]+)|{([A-Za-z0-9_]+)})\b", sub_env, cmd)
cmd_str = '> %s run %s %s' % (RUSTUP, rust_ver, cmd)
log_file.write(cmd_str)
log_file.write("\n")
log_file.flush()
success = sh(
'%s run %s %s' % (RUSTUP, rust_ver, cmd),
checked=False,
stdout=log_file, stderr=log_file,
env=cmd_env,
)
if not success:
log_file.write('Command failed.\n')
log_file.flush()
break
msg('... ', 'OK' if success else 'Failed!')
log_file.close()
return success
def translate_script(script):
script = script or "rustc -vV && cargo -vV && cargo build --verbose && cargo test --verbose"
parts = script.split("&&")
return [p.strip() for p in parts]
if __name__ == '__main__':
main()