def load(self, name, variation): if not path.exists(name): raise error.general('config: cannot read configuration: %s' % (name)) self.name = name try: self.config.read(name) except configparser.ParsingError as ce: raise error.general('config: %s' % (ce)) archs = [] self.profiles['profiles'] = self._comma_list('profiles', 'profiles', error = False) if len(self.profiles['profiles']) == 0: self.profiles['profiles'] = ['tier_%d' % (t) for t in range(1,4)] for p in self.profiles['profiles']: profile = {} profile['name'] = p profile['archs'] = self._comma_list(profile['name'], 'archs') archs += profile['archs'] for arch in profile['archs']: bsps = 'bsps_%s' % (arch) profile[bsps] = self._comma_list(profile['name'], bsps) self.profiles[profile['name']] = profile for a in set(archs): arch = {} arch['excludes'] = {} for exclude in self._comma_list(a, 'exclude', error = False): arch['excludes'][exclude] = ['all'] for i in self._get_items(a, False): if i[0].startswith('exclude_'): exclude = i[0][len('exclude_'):] if exclude not in arch['excludes']: arch['excludes'][exclude] = [] arch['excludes'][exclude] += sorted(set([b.strip() for b in i[1].split(',')])) arch['bsps'] = self._comma_list(a, 'bsps', error = False) for b in arch['bsps']: arch[b] = {} arch[b]['bspopts'] = self._comma_list(a, 'bspopts_%s' % (b), error = False) self.archs[a] = arch builds = {} builds['default'] = self._get_item('builds', 'default').split() builds['variations'] = self._comma_list('builds', 'variations') if variation is None: variation = builds['default'] builds['variation'] = variation builds['base'] = self._get_item('builds', 'standard').split() builds['variations'] = self._comma_list('builds', variation) builds['var_options'] = {} for v in builds['variations']: if v == 'base': builds['var_options'][v] = self._get_item('builds', v).split() else: builds['var_options'][v] = [] self.builds = builds
def __init__(self, dev): if options.host_windows: raise error.general('termios not support on host') self.dev = dev self.default_attr = None self.fd = None self.if_on = False if options.host_windows: raise error.general('TTY consoles not supported on Windows.') if not path.exists(dev): raise error.general('dev not found: %s' % (dev)) try: self.fd = open(dev, 'rw') except IOError, ioe: raise error.general('opening tty dev: %s: %s' % (dev, ioe))
def load(self, name): if not path.exists(name): raise error.general('config: cannot read configuration: %s' % (name)) self.name = name self.config.read(name) archs = [] self.profiles['profiles'] = self._comma_list('profiles', 'profiles', error = False) if len(self.profiles['profiles']) == 0: self.profiles['profiles'] = ['tier_%d' % (t) for t in range(1,4)] for p in self.profiles['profiles']: profile = {} profile['name'] = p profile['archs'] = self._comma_list(profile['name'], 'archs') archs += profile['archs'] for arch in profile['archs']: bsps = 'bsps_%s' % (arch) profile[bsps] = self._comma_list(profile['name'], bsps) self.profiles[profile['name']] = profile for a in set(archs): arch = {} arch['excludes'] = self._comma_list(a, 'excludes', error = False) arch['bsps'] = self._comma_list(a, 'bsps', error = False) for b in arch['bsps']: arch[b] = {} arch[b]['bspopts'] = self._comma_list(a, 'bspopts_%s' % (b), error = False) arch[b]['config'] = self._comma_list(a, 'config_%s' % (b), error = False) self.archs[a] = arch builds = {} builds['default'] = self._get_item('builds', 'default').split() builds['variations'] = self._comma_list('builds', 'variations') builds['var_options'] = {} for v in builds['variations']: builds['var_options'][v] = self._get_item('builds', v).split() self.builds = builds
def log(self, name, mode): status_fails = [ 'failed', 'timeout', 'invalid', 'wrong-version', 'wrong-build', 'wrong-tools' ] if mode != 'none': self.lock.acquire() if name not in self.results: self.lock.release() raise error.general('test report missing: %s' % (name)) exe = path.basename(self.results[name]['exe']) result = self.results[name]['result'] time = self.results[name]['end'] - self.results[name]['start'] failed = result in status_fails result = 'Result: %-10s Time: %s %s' % (result, str(time), exe) if mode != 'none': header = self.results[name]['header'] if mode == 'all' or failed: output = self.results[name]['output'] else: output = None self.lock.release() if header: log.output(header) if output: log.output(result) log.output(output)
def start(self, index, total, name, executable, bsp_arch, bsp): header = '[%*d/%*d] p:%-*d f:%-*d t:%-*d i:%-*d | %s/%s: %s' % \ (len(str(total)), index, len(str(total)), total, len(str(total)), self.passed, len(str(total)), self.failed, len(str(total)), self.timeouts, len(str(total)), self.invalids, bsp_arch, bsp, path.basename(executable)) self.lock.acquire() if name in self.results: self.lock.release() raise error.general('duplicate test: %s' % (name)) self.results[name] = { 'index': index, 'bsp': bsp, 'bsp_arch': bsp_arch, 'exe': executable, 'start': datetime.datetime.now(), 'end': None, 'result': None, 'output': None, 'header': header } self.lock.release() log.notice(header, stdout_only=True)
def find_executables(files): executables = [] for f in files: if not path.isfile(f): raise error.general('executable is not a file: %s' % (f)) executables += [f] return sorted(executables)
def _dir_gdb(self, data, total, index, exe, bsp_arch, bsp): if len(data) < 3 or len(data) > 4: raise error.general('invalid %gdb arguments') self.process = tester.rt.gdb.gdb(bsp_arch, bsp, trace=self.exe_trace('gdb'), mi_trace=self.exe_trace('gdb-mi')) script = self.expand('%%{%s}' % data[2]) if script: script = [l.strip() for l in script.splitlines()] if not self.in_error: if self.console: self.console.open() if not self.opts.dry_run(): self.process.open( data[0], data[1], script=script, output=self.capture, gdb_console=self.capture_console, timeout=(int(self.expand('%{timeout}')), int(self.expand('%{max_test_period}')), self._timeout, self._test_too_long)) if self.console: self.console.close()
def _target_exe_filter(self, exe): if self.defined('target_exe_filter'): f = self.expand('%{target_exe_filter}').strip() # Be like sed and use the first character as the delmiter. if len(f) > 0: delimiter = f[0] pat = '' repl = '' repl_not_pat = False esc = False for c in f[1:]: add = True if not esc and c == '\\': esc = True add = False elif esc: if c == delimiter: c = delimiter else: c = '\\' + c esc = False elif c == delimiter: if repl_not_pat: exe = re.sub(r'%s' % (pat), repl, exe) self._capture_console('target exe filter: find:%s subst:%s -> %s' % \ (pat, repl, exe)) return exe repl_not_pat = True add = False if add: if repl_not_pat: repl += c else: pat += c raise error.general('invalid exe filter: %s' % (f))
def open(self, command, capture=True, shell=False, cwd=None, env=None, stdin=None, stdout=None, stderr=None, timeout=None): if not capture: raise error.general( 'output capture must be true; leave as default') #self.snapper.get_and_clear() exit_code, proc = execute.open(self, command, capture=True, shell=shell, cwd=cwd, env=env, stdin=stdin, stdout=stdout, stderr=stderr, timeout=timeout) return (exit_code, proc, self.snapper.get_and_clear())
def open(self, command, executable, output, gdb_console, script = None, tty = None, timeout = 300): self._lock('_open') try: cmds = execute.arg_list(command) + ['-i=mi', '--nx', '--quiet'] if tty: cmds += ['--tty=%s' % tty] if executable: cmds += [executable] self.output = output self.gdb_console = gdb_console self.script = script self.running = False self.process = execute.execute(output = self._reader, input = self._writer, cleanup = self._cleanup) finally: self._unlock('_open') try: self.gdb_console('gdb: %s' % (' '.join(cmds))) ec, proc = self.process.open(cmds, timeout = (timeout, self._timeout)) if self.trace: print 'gdb done', ec if ec > 0: raise error.general('gdb exec: %s' % (os.strerror(ec))) except: raise self._lock('_open') try: self.process = None finally: self._unlock('_open')
def start(self, index, total, name, executable, bsp_arch, bsp): header = '[%*d/%*d] p:%-*d f:%-*d t:%-*d i:%-*d | %s/%s: %s' % \ (len(str(total)), index, len(str(total)), total, len(str(total)), self.passed, len(str(total)), self.failed, len(str(total)), self.timeouts, len(str(total)), self.invalids, bsp_arch, bsp, path.basename(executable)) self.lock.acquire() if name in self.results: self.lock.release() raise error.general('duplicate test: %s' % (name)) self.results[name] = { 'index': index, 'bsp': bsp, 'bsp_arch': bsp_arch, 'exe': executable, 'start': datetime.datetime.now(), 'end': None, 'result': None, 'output': None, 'header': header } self.lock.release() log.notice(header, stdout_only = True)
def _ifs(self, config, ls, label, iftrue, isvalid, dir, info): in_iftrue = True data = [] while True: if isvalid and \ ((iftrue and in_iftrue) or (not iftrue and not in_iftrue)): this_isvalid = True else: this_isvalid = False r = self._parse(config, dir, info, roc = True, isvalid = this_isvalid) if r[0] == 'control': if r[1] == '%end': self._error(label + ' without %endif') raise error.general('terminating build') if r[1] == '%endif': log.trace('config: %s: _ifs: %s %s' % (self.init_name, r[1], this_isvalid)) return data if r[1] == '%else': in_iftrue = False elif r[0] == 'directive': if this_isvalid: if r[1] == '%include': self.load(r[2][0]) continue dir, info, data = self._process_directive(r, dir, info, data) elif r[0] == 'data': if this_isvalid: dir, info, data = self._process_data(r, dir, info, data) else: dir, info, data = self._process_block(r, dir, info, data)
def process(self): arg = 0 while arg < len(self.args): a = self.args[arg] if a == '-?': self.help() elif a.startswith('--'): los = a.split('=') lo = los[0] if lo in self.long_opts: long_opt = self.long_opts[lo] if len(los) == 1: if long_opt[2]: if arg == len(self.args) - 1: raise error.general( 'option requires a parameter: %s' % (lo)) arg += 1 value = self.args[arg] else: value = None else: value = '='.join(los[1:]) long_opt[1](lo, long_opt[0], value) else: self.opts['params'].append(a) arg += 1
def __init__(self, config, version, prefix, tools, rtems, build_dir, options): self.config = config self.build_dir = build_dir self.rtems_version = version self.prefix = prefix self.tools = tools self.rtems = rtems self.options = options self.counts = {'h': 0, 'exes': 0, 'objs': 0, 'libs': 0} self.results = results( rtems, { 'groups': ['Shared', 'BSP', 'Network', 'Tests', 'LibCPU', 'CPU Kit'], 'exclude': '.*Makefile.*', 'CPU Kit': '.*cpukit/.*', 'Network': '.*libnetworking/.*|.*librpc/.*', 'Tests': '.*testsuites/.*', 'BSP': '.*libbsp/.*', 'LibCPU': '.*libcpu/.*', 'Shared': '.*shared/.*' }) if not path.exists(path.join(rtems, 'configure')) or \ not path.exists(path.join(rtems, 'Makefile.in')) or \ not path.exists(path.join(rtems, 'cpukit')): raise error.general('RTEMS source path does not look like RTEMS')
def run(self): try: if self.executables is None: raise error.general('no test executables provided.') build_dir = build_path_generator(self.executables, self.target).run() parser = symbol_parser(self.symbol_config_path, self.symbol_select_path, self.symbol_set, build_dir, self.bsp_name, self.target) symbol_sets = parser.parse() for sset in symbol_sets: parser.write_ini(sset) covoar_runner = covoar(self.test_dir, self.symbol_select_path, self.executables, self.trace, self.prefix, self.covoar_cmd) covoar_runner.run(sset, self.symbol_select_path) self._generate_reports(symbol_sets); self._summarize(); finally: self._cleanup();
def _process_data(self, results, directive, info, data): new_data = [] for l in results[1]: if l.startswith('%error'): l = self._expand(l) raise error.general('config error: %s' % (l[7:])) elif l.startswith('%warning'): l = self._expand(l) log.stderr('warning: %s' % (l[9:])) log.warning(l[9:]) if not directive: l = self._expand(l) ls = self.tags.split(l, 1) log.trace('config: %s: _tag: %s %s' % (self.init_name, l, ls)) if len(ls) > 1: info = ls[0].lower() if info[-1] == ':': info = info[:-1] info_data = ls[1].strip() else: info_data = ls[0].strip() if info is not None: self._info_append(info, info_data) else: log.warning("invalid format: '%s'" % (info_data[:-1])) else: log.trace('config: %s: _data: %s %s' % (self.init_name, l, new_data)) new_data.append(l) return (directive, info, data + new_data)
def arch_jobs(self, archs): jobs = [] for arch in archs: if not self.config.arch_present(arch): raise error.general('Architecture not found: %s' % (arch)) jobs += self.arch_bsp_jobs(arch, self._bsps(arch)) return jobs
def open(self, command, executable, output, gdb_console, timeout, script=None, tty=None): self._lock('_open') self.timeout = timeout[2] self.test_too_long = timeout[3] try: cmds = execute.arg_list(command) + ['-i=mi', '--nx', '--quiet'] if tty: cmds += ['--tty=%s' % tty] if executable: cmds += [executable] self.output = output self.gdb_console = gdb_console self.script = script self.process = execute.execute(output=self._reader, input=self._writer, cleanup=self._cleanup) exec_thread = threading.Thread(target=self._execute_gdb, args=[cmds]) exec_thread.start() self._monitor(timeout) if self.ecode is not None and self.ecode > 0: raise error.general('gdb exec: %s: %s' % (cmds[0], os.strerror(self.ecode))) finally: self._unlock('_open')
def _interpolate(self, section, rec): # # On Python 2.7 there is no extended interpolation so add support here. # On Python 3 we disable the built in support and also the code here. # if not self.raw: not_found = [] while True: macros = [ m for m in self.macro_filter.findall(rec) if m not in not_found ] if len(macros) == 0: break for m in macros: if m in not_found: continue if ':' in m: section_value = m[2:-1].split(':') if len(section_value) != 2: err = 'config: interpolation is ${section:item}: %s' % ( m) raise error.general(err) else: section_value = [section, m[2:-1]] try: ref = self.config.get(section_value[0], section_value[1], raw=True).replace( os.linesep, ' ') rec = rec.replace(m, ref) except: not_found += [m] pass return rec
def _load_released_version(): '''Load the release data if present. If not found the package is not released. A release can be made by adding a file called `VERSION` to the top level directory of a package. This is useful for user deploying a package and making custom releases. The RTEMS project reserves the `rtems-version.ini` file for it's releases. This is the base release and should not be touched by users deploying a package. ''' global _version global _revision global _released global _version_str global _is_loaded if not _is_loaded: vc, v = _load_released_version_config() if v is not None: try: ver_str = v.get('version', 'revision') except Exception as e: raise error.general('Invalid version file: %s: %s' % (vc, e)) ver_split = ver_str.split('.') if len(ver_split) < 2: raise error.general('Invalid version release value: %s: %s' % (vc, ver_str)) ver = ver_split[0] rev = '.'.join(ver_split[1:]) try: _version = int(ver) except: raise error.general('Invalid version config value: %s: %s' % (vc, ver)) try: _revision = int(''.join( itertools.takewhile(str.isdigit, str(rev)))) except Exception as e: raise error.general( 'Invalid revision config value: %s: %s: %s' % (vc, rev, e)) if not 'not_released' in ver: _released = True _version_str = ver_str _is_loaded = True return _released
def _directive_filter(self, results, directive, info, data): if results[0] == 'directive': _directive = results[1] _data = results[2] ds = [] if len(_data): ds = [_data[0]] if len(_data) > 1: ds += _data[1].split() ds = self.expand(ds) if _directive == '%console': self._dir_console(ds) else: self._lock() try: self.output = [] total = int(self.expand('%{test_total}')) index = int(self.expand('%{test_index}')) exe = self.expand('%{test_executable}') bsp_arch = self.expand('%{arch}') bsp = self.expand('%{bsp}') fexe = self._target_exe_filter(exe) self.report.start(index, total, exe, fexe, bsp_arch, bsp, self.show_header) if self.index == 1: self._target_command('on', bsp_arch, bsp, exe, fexe) self._target_command('pretest', bsp_arch, bsp, exe, fexe) finally: self._unlock() if _directive == '%execute': self._dir_execute(ds, total, index, fexe, bsp_arch, bsp) elif _directive == '%gdb': self._dir_gdb(ds, total, index, fexe, bsp_arch, bsp) elif _directive == '%tftp': self._dir_tftp(ds, total, index, fexe, bsp_arch, bsp) else: raise error.general(self._name_line_msg('invalid directive')) self._lock() if self.index == self.total: self._target_command('off', bsp_arch, bsp, exe, fexe) self._target_command('posttest', bsp_arch, bsp, exe, fexe) try: status = self.report.end(exe, self.output, self.console_prefix) version = self.report.get_config('version', not_found = 'n/p') build = self.report.get_config('build', not_found = 'n/p') tools = self.report.get_config('tools', not_found = 'n/p') self._capture_console('test result: %s' % (status)) self._capture_console('test version: %s' % (version)) self._capture_console('test build: %s' % (build)) self._capture_console('test tools: %s' % (tools)) if status == 'timeout': if self.index != self.total: self._target_command('reset', bsp_arch, bsp, exe, fexe) self.process = None self.output = None finally: self._unlock() return None, None, None
def profile_jobs(self, profiles): jobs = [] for profile in profiles: if not self.config.profile_present(profile): raise error.general('Profile not found: %s' % (profile)) for arch in self.config.profile_archs(profile): jobs += self.bsp_jobs(self.config.profile_arch_bsps(profile, arch)) return jobs
def bsp_jobs(self, bsps): jobs = [] for bsp in bsps: if bsp.count('/') != 1: raise error.general('invalid bsp format (use: arch/bsp): %s' % (bsp)) arch, bsp = bsp.split('/') jobs += build_jobs(self.config, arch, bsp).jobs() return jobs
def _load(self, config): self.config.load(config) clients = self.config.comma_list('default', 'clients', err=False) if len(clients) == 0: raise error.general( '\'clients\'" entry not found in config [defaults]') for client in clients: self._load_client(client)
def _get_items(self, section, err=True): try: items = self.config.items(section) return items except: if err: raise error.general('config: section %s not found' % (section)) return []
def get_item_names(self, section, err=True): try: return [item[0] for item in self.config.items(section, raw=True)] except: if err: raise error.general('config: section "%s" not found' % (section)) return []
def _listener(self): tftpy.log.setLevel(100) try: self.server = tftpy.TftpServer(tftproot='.', dyn_file_func=self._exe_handle) except tftpy.TftpException as te: raise error.general('tftp: %s' % (str(te))) if self.server is not None: try: self.server.listen('0.0.0.0', self.port, 0.5) except tftpy.TftpException as te: raise error.general('tftp: %s' % (str(te))) except IOError as ie: if ie.errno == errno.EACCES: raise error.general( 'tftp: permissions error: check tftp server port') raise error.general('tftp: io error: %s' % (str(ie)))
def end(self, name, output): start = False end = False timeout = False prefixed_output = [] for line in output: if line[0] == ']': if line[1].startswith('*** '): if line[1][4:].startswith('END OF '): end = True if line[1][4:].startswith('TIMEOUT TIMEOUT'): timeout = True else: start = True prefixed_output += [line[0] + ' ' + line[1]] self.lock.acquire() if name not in self.results: self.lock.release() raise error.general('test report missing: %s' % (name)) if self.results[name]['end'] is not None: self.lock.release() raise error.general('test already finished: %s' % (name)) self.results[name]['end'] = datetime.datetime.now() if start and end: status = 'passed' self.passed += 1 elif timeout: status = 'timeout' self.timeouts += 1 elif start: if not end: status = 'failed' self.failed += 1 else: if self.invalid_tests and path.basename( name) in self.invalid_tests: status = 'passed' self.passed += 1 else: status = 'invalid' self.invalids += 1 self.results[name]['result'] = status self.results[name]['output'] = prefixed_output if self.name_max_len < len(path.basename(name)): self.name_max_len = len(path.basename(name)) self.lock.release()
def _get_items(self, section, err = True): try: items = self.config.items(section) return items except: if err: raise error.general('config: section %s not found' % (section)) return []
def _get_item(self, section, label, err = True): try: rec = self.config.get(section, label).replace(os.linesep, ' ') return rec except: if err: raise error.general('config: no %s found in %s' % (label, section)) return None
def baudrate(self, flag): mask = self._baudrate_mask(flag) if mask: self.attr[4] = mask self.attr[5] = mask else: raise error.general('invalid setting: %s' % (flag)) self._update()
def listdir(path, error = True): path = host(path) files = [] if not os.path.exists(path): if error: raise error.general('path does not exist : %s' % (path)) elif not isdir(path): if error: raise error.general('path is not a directory: %s' % (path)) else: if windows: try: files = os.listdir(host(path)) except IOError: raise error.general('Could not list files: %s' % (path)) except OSError as e: raise error.general('Could not list files: %s: %s' % (path, str(e))) except WindowsError as e: raise error.general('Could not list files: %s: %s' % (path, str(e))) else: try: files = os.listdir(host(path)) except IOError: raise error.general('Could not list files: %s' % (path)) except OSError as e: raise error.general('Could not list files: %s: %s' % (path, str(e))) return files
def end(self, name, output): start = False end = False timeout = False prefixed_output = [] for line in output: if line[0] == ']': if line[1].startswith('*** '): if line[1][4:].startswith('END OF '): end = True if line[1][4:].startswith('TIMEOUT TIMEOUT'): timeout = True else: start = True prefixed_output += [line[0] + ' ' + line[1]] self.lock.acquire() if name not in self.results: self.lock.release() raise error.general('test report missing: %s' % (name)) if self.results[name]['end'] is not None: self.lock.release() raise error.general('test already finished: %s' % (name)) self.results[name]['end'] = datetime.datetime.now() if start and end: status = 'passed' self.passed += 1 elif timeout: status = 'timeout' self.timeouts += 1 elif start: if not end: status = 'failed' self.failed += 1 else: if self.invalid_tests and path.basename(name) in self.invalid_tests: status = 'passed' self.passed += 1 else: status = 'invalid' self.invalids += 1 self.results[name]['result'] = status self.results[name]['output'] = prefixed_output if self.name_max_len < len(path.basename(name)): self.name_max_len = len(path.basename(name)) self.lock.release()
def __init__(self, dev): if host.is_windows: raise error.general('termios not support on host') self.dev = dev self.default_attr = None self.fd = None self.if_on = False if host.is_windows: raise error.general('TTY consoles not supported on Windows.') if not path.exists(dev): raise error.general('dev not found: %s' % (dev)) try: self.fd = open(dev, 'rw') except IOError as ioe: raise error.general('opening tty dev: %s: %s' % (dev, ioe)) except: raise error.general('opening tty dev: %s: unknown' % (dev)) try: self.default_attr = termios.tcgetattr(self.fd) except: close(self.fd) raise error.general('cannot get termios attrs: %s' % (dev)) try: fcntl.fcntl(self.fd, fcntl.F_SETFL, fcntl.fcntl(self.fd, fcntl.F_GETFL) | os.O_NONBLOCK) except: close(self.fd) raise error.general('cannot make tty non-blocking: %s' % (dev)) self.attr = self.default_attr
def _get_item(self, section, label, err=True): try: rec = self.config.get(section, label).replace(os.linesep, ' ') return rec except: if err: raise error.general('config: no %s found in %s' % (label, section)) return None
def get_items(self, section, err = True): try: items = [(name, key.replace(os.linesep, ' ')) \ for name, key in self.config.items(section)] return items except: if err: raise error.general('config: section "%s" not found' % (section)) return []
def send_file_as_body(self, to_addr, subject, name, intro=None): try: with open(name, 'r') as f: body = f.readlines() except IOError as err: raise error.general('error reading mail body: %s' % (name)) if intro is not None: body = intro + body self.send(to_addr, from_addr, body)
def host_format_partition(self, device, pformat, plabel): formats = { 'fat16': ('newfs_msdos', '16'), 'fat32': ('newfs_msdos', '32') } if pformat not in formats: raise error.general('unknown format: %s' % (pformat)) self.command('sudo %s -F %s %s' % (formats[pformat][0], formats[pformat][1], device))
def __init__(self, index, total, report, executable, rtems_tools, bsp, bsp_config, opts): self.index = index self.total = total self.report = report self.bsp = bsp self.bsp_config = bsp_config self.opts = copy.copy(opts) self.opts.defaults['test_index'] = str(index) self.opts.defaults['test_total'] = str(total) self.opts.defaults['bsp'] = bsp self.opts.defaults['bsp_arch'] = '%%{%s_arch}' % (bsp) self.opts.defaults['bsp_opts'] = '%%{%s_opts}' % (bsp) if not path.isfile(executable): raise error.general('cannot find executable: %s' % (executable)) self.opts.defaults['test_executable'] = executable if rtems_tools: rtems_tools_bin = path.join(self.opts.defaults.expand(rtems_tools), 'bin') if not path.isdir(rtems_tools_bin): raise error.general('cannot find RTEMS tools path: %s' % (rtems_tools_bin)) self.opts.defaults['rtems_tools'] = rtems_tools_bin self.config = config.file(self.report, self.bsp_config, self.opts)
def _dir_console(self, data): if self.console is not None: raise error.general(self._name_line_msg('console already configured')) if len(data) == 0: raise error.general(self._name_line_msg('no console configuration provided')) console_trace = trace = self.debug_trace('console') if data[0] == 'stdio': self.console = console.stdio(trace = console_trace) elif data[0] == 'tty': if len(data) < 2 or len(data) >3: raise error.general(self._name_line_msg('no tty configuration provided')) if len(data) == 3: settings = data[2] else: settings = None self.console = console.tty(data[1], output = self.capture, setup = settings, trace = console_trace) else: raise error.general(self._name_line_msg('invalid console type'))
def set(self, flags): for f in flags.split(','): if len(f) < 2: raise error.general('invalid flag: %s' % (f)) if f[0] == '~': on = False flag = f[1:] else: on = True flag = f if f.startswith('VMIN'): vs = f.split('=') if len(vs) != 2: raise error.general('invalid vmin flag: %s' % (f)) try: _vmin = int(vs[1]) except: raise error.general('invalid vmin flag: %s' % (f)) self.vmin(_vmin) continue if f.startswith('VTIME'): vs = f.split('=') if len(vs) != 2: raise error.general('invalid vtime flag: %s' % (f)) try: _vtime = int(vs[1]) except: raise error.general('invalid vtime flag: %s' % (f)) self.vtime(_vtime) continue mask = self._baudrate_mask(flag) if mask: if not on: raise error.general('baudrates are not flags: %s' % (f)) self.attr[4] = mask self.attr[5] = mask continue mask = self._input_mask(flag) if mask: self._set(0, mask, on) continue mask = self._output_mask(flag) if mask: self._set(1, mask, on) continue mask = self._control_mask(flag) if mask: self._set(2, mask, on) continue mask = self._local_mask(flag) if mask: self._set(3, mask, on) continue raise error.general('unknown tty flag: %s' % (f)) self._update()
def build_arch(self, arch): start = datetime.datetime.now() log.output('=' * 70) log.notice(']] Architecture: %s' % (arch)) if not self.confif.arch_present(arch): raise error.general('Architecture not found: %s' % (arch)) for bsp in self._bsps(arch): self.build_arch_bsp(arch, bsp) log.notice('^ Architecture Time %s' % (str(end - start))) log.notice(' warnings:%d exes:%d objs:%s libs:%d' % \ self.warnings.get(), self.counts['exes'], self.counts['objs'], self.counts['libs']) log.output('Architecture Warnings:') log.output(self.warnings.report())
def build_profile(self, profile): if not self.config.profile_present(profile): raise error.general('BSP not found: %s/%s' % (arch, bsp)) start = datetime.datetime.now() log.notice(']] Profile: %s' % (profile)) for arch in self.config.profile_archs(profile): for bsp in self.config.profile_arch_bsps(profile, arch): self.build_arch_bsp(arch, bsp) end = datetime.datetime.now() log.notice('^ Profile Time %s' % (str(end - start))) log.notice(' warnings:%d exes:%d objs:%d libs:%d' % \ (self.warnings.get(), self.counts['exes'], self.counts['objs'], self.counts['libs'])) log.output('Profile Warnings:') log.output(self.warnings.report())
def _dir_gdb(self, data, total, index, exe, bsp_arch, bsp): if len(data) < 3 or len(data) > 4: raise error.general('invalid %gdb arguments') self.process = gdb.gdb(bsp_arch, bsp, trace = self.debug_trace('gdb'), mi_trace = self.debug_trace('gdb-mi')) script = self.expand('%%{%s}' % data[2]) if script: script = [l.strip() for l in script.splitlines()] if not self.in_error: if self.console: self.console.open() self.process.open(data[0], data[1], script = script, output = self.capture, gdb_console = self.capture_console, timeout = int(self.expand('%{timeout}'))) if self.console: self.console.close()
def __init__(self, config, version, prefix, tools, rtems, build_dir, options): self.config = config self.build_dir = build_dir self.rtems_version = version self.prefix = prefix self.tools = tools self.rtems = rtems self.options = options self.errors = { 'configure': 0, 'build': 0, 'tests': 0 } self.counts = { 'h' : 0, 'exes' : 0, 'objs' : 0, 'libs' : 0 } self.warnings = warnings_counter(rtems) if not path.exists(path.join(rtems, 'configure')) or \ not path.exists(path.join(rtems, 'Makefile.in')) or \ not path.exists(path.join(rtems, 'cpukit')): raise error.general('RTEMS source path does not look like RTEMS')
def log(self, name, mode): if mode != 'none': self.lock.acquire() if name not in self.results: self.lock.release() raise error.general('test report missing: %s' % (name)) exe = path.basename(self.results[name]['exe']) result = self.results[name]['result'] time = self.results[name]['end'] - self.results[name]['start'] if mode != 'none': header = self.results[name]['header'] if mode == 'all' or result != 'passed': output = self.results[name]['output'] else: output = None self.lock.release() if header: log.output(header) if output: log.output(output) log.output('Result: %-10s Time: %s %s' % (result, str(time), exe))
def _directive_filter(self, results, directive, info, data): if results[0] == 'directive': _directive = results[1] _data = results[2] ds = [] if len(_data): ds = [_data[0]] if len(_data) > 1: ds += _data[1].split() ds = self.expand(ds) if _directive == '%console': self._dir_console(ds) else: self._lock() try: total = int(self.expand('%{test_total}')) index = int(self.expand('%{test_index}')) exe = self.expand('%{test_executable}') bsp_arch = self.expand('%{bsp_arch}') bsp = self.expand('%{bsp}') self.report.start(index, total, exe, exe, bsp_arch, bsp) self.output = [] finally: self._unlock() if _directive == '%execute': self._dir_execute(ds, total, index, exe, bsp_arch, bsp) elif _directive == '%gdb': self._dir_gdb(ds, total, index, exe, bsp_arch, bsp) else: raise error.general(self._name_line_msg('invalid directive')) self._lock() try: self.report.end(exe, self.output) self.process = None self.output = None finally: self._unlock() return None, None, None
def run(command_path = None): import sys stdtty = console.save() opts = None try: optargs = { '--rtems-tools': 'The path to the RTEMS tools', '--rtems-bsp': 'The RTEMS BSP to run the test on', '--report-mode': 'Reporting modes, failures (default),all,none', '--list-bsps': 'List the supported BSPs', '--debug-trace': 'Debug trace based on specific flags', '--stacktrace': 'Dump a stack trace on a user termination (^C)' } opts = options.load(sys.argv, optargs = optargs, command_path = command_path) log.notice('RTEMS Testing - Tester, v%s' % (version.str())) if opts.find_arg('--list-bsps'): list_bsps(opts) opts.log_info() debug_trace = opts.find_arg('--debug-trace') if debug_trace: debug_trace = debug_trace[1] else: debug_trace = '' opts.defaults['debug_trace'] = debug_trace job_trace = 'jobs' in debug_trace.split(',') rtems_tools = opts.find_arg('--rtems-tools') if rtems_tools: rtems_tools = rtems_tools[1] bsp = opts.find_arg('--rtems-bsp') if bsp is None: raise error.general('no RTEMS BSP provided') opts.defaults.load('%%{_configdir}/bsps/%s.mc' % (bsp[1])) bsp = opts.defaults.get('%{bsp}') if not bsp: raise error.general('BSP definition (%{bsp}) not found in the global map') bsp = bsp[2] if not opts.defaults.set_read_map(bsp): raise error.general('no BSP map found') bsp_script = opts.defaults.get(bsp) if not bsp_script: raise error.general('BSP script not found: %s' % (bsp)) bsp_config = opts.defaults.expand(opts.defaults[bsp]) report_mode = opts.find_arg('--report-mode') if report_mode: if report_mode[1] != 'failures' and \ report_mode[1] != 'all' and \ report_mode[1] != 'none': raise error.general('invalid report mode') report_mode = report_mode[1] else: report_mode = 'failures' executables = find_executables(opts.params()) if len(executables) == 0: raise error.general('no executbles supplied') start_time = datetime.datetime.now() total = len(executables) reports = report.report(total) invalid_tests = opts.defaults['invalid_tests'] if invalid_tests: reports.set_invalid_tests([l.strip() for l in invalid_tests.splitlines()]) reporting = 1 jobs = int(opts.jobs(opts.defaults['_ncpus'])) exe = 0 tests = [] finished = [] if jobs > len(executables): jobs = len(executables) while exe < total or len(tests) > 0: if exe < total and len(tests) < jobs: tst = test_run(exe + 1, total, reports, executables[exe], rtems_tools, bsp, bsp_config, opts) exe += 1 tests += [tst] if job_trace: _job_trace(tst, 'create', total, exe, tests, reporting) tst.run() else: dead = [t for t in tests if not t.is_alive()] tests[:] = [t for t in tests if t not in dead] for tst in dead: if job_trace: _job_trace(tst, 'dead', total, exe, tests, reporting) finished += [tst] tst.reraise() del dead if len(tests) >= jobs or exe >= total: time.sleep(0.250) if len(finished): reporting = report_finished(reports, report_mode, reporting, finished, job_trace) finished_time = datetime.datetime.now() reporting = report_finished(reports, report_mode, reporting, finished, job_trace) if reporting < total: log.warning('finished jobs does match: %d' % (reporting)) report_finished(reports, report_mode, -1, finished, job_trace) reports.summary() end_time = datetime.datetime.now() log.notice('Testing time: %s' % (str(end_time - start_time))) except error.general, gerr: print gerr sys.exit(1)
def run_args(args): b = None ec = 0 try: # # On Windows MSYS2 prepends a path to itself to the environment # path. This means the RTEMS specific automake is not found and which # breaks the bootstrap. We need to remove the prepended path. Also # remove any ACLOCAL paths from the environment. # if os.name == 'nt': cspath = os.environ['PATH'].split(os.pathsep) if 'msys' in cspath[0] and cspath[0].endswith('bin'): os.environ['PATH'] = os.pathsep.join(cspath[1:]) top = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0]))) prefix = '/opt/rtems/%s' % (rtems_version()) tools = prefix build_dir = 'bsp-builds' logf = 'bsp-build-%s.txt' % (datetime.datetime.now().strftime('%Y%m%d-%H%M%S')) config_file = path.join(top, 'share', 'rtems', 'tester', 'rtems', 'rtems-bsps.ini') if not path.exists(config_file): config_file = path.join(top, 'tester', 'rtems', 'rtems-bsps.ini') argsp = argparse.ArgumentParser() argsp.add_argument('--prefix', help = 'Prefix to build the BSP.', type = str) argsp.add_argument('--rtems-tools', help = 'The RTEMS tools directory.', type = str) argsp.add_argument('--rtems', help = 'The RTEMS source tree.', type = str) argsp.add_argument('--build-path', help = 'Path to build in.', type = str) argsp.add_argument('--log', help = 'Log file.', type = str) argsp.add_argument('--stop-on-error', help = 'Stop on an error.', action = 'store_true') argsp.add_argument('--no-clean', help = 'Do not clean the build output.', action = 'store_true') argsp.add_argument('--profiles', help = 'Build the listed profiles.', type = str, default = 'tier-1') argsp.add_argument('--build', help = 'Build variation.', type = str) argsp.add_argument('--arch', help = 'Build the specific architecture.', type = str) argsp.add_argument('--bsp', help = 'Build the specific BSP.', type = str) argsp.add_argument('--dry-run', help = 'Do not run the actual builds.', action = 'store_true') opts = argsp.parse_args(args[1:]) if opts.log is not None: logf = opts.log log.default = log.log([logf]) log.notice('RTEMS Tools Project - RTEMS Kernel BSP Builder, %s' % (version.str())) if opts.rtems is None: raise error.general('No RTEMS source provided on the command line') if opts.prefix is not None: prefix = path.shell(opts.prefix) if opts.rtems_tools is not None: tools = path.shell(opts.rtems_tools) if opts.build_path is not None: build_dir = path.shell(opts.build_path) if opts.bsp is not None and opts.arch is None: raise error.general('BSP provided but no architecture') config = configuration() config.load(config_file, opts.build) options = { 'stop-on-error' : opts.stop_on_error, 'no-clean' : opts.no_clean, 'dry-run' : opts.dry_run, 'jobs' : 8 } b = build(config, rtems_version(), prefix, tools, path.shell(opts.rtems), build_dir, options) if opts.arch is not None: if opts.bsp is not None: b.build_arch_bsp(opts.arch, opts.bsp) else: b.build_arch(opts.arch) else: for profile in opts.profiles.split(','): b.build_profile(profile.strip()) except error.general as gerr: print(gerr) print('BSP Build FAILED', file = sys.stderr) ec = 1 except error.internal as ierr: print(ierr) print('BSP Build FAILED', file = sys.stderr) ec = 1 except error.exit as eerr: pass except KeyboardInterrupt: log.notice('abort: user terminated') ec = 1 if b is not None: b.results.report() sys.exit(ec)
def run(command_path = None): import sys tests = [] stdtty = console.save() opts = None default_exefilter = '*.exe' try: optargs = { '--rtems-tools': 'The path to the RTEMS tools', '--rtems-bsp': 'The RTEMS BSP to run the test on', '--report-mode': 'Reporting modes, failures (default),all,none', '--list-bsps': 'List the supported BSPs', '--debug-trace': 'Debug trace based on specific flags', '--filter': 'Glob that executables must match to run (default: ' + default_exefilter + ')', '--stacktrace': 'Dump a stack trace on a user termination (^C)' } opts = options.load(sys.argv, optargs = optargs, command_path = command_path) log.notice('RTEMS Testing - Tester, v%s' % (version.str())) if opts.find_arg('--list-bsps'): bsps.list(opts) exe_filter = opts.find_arg('--filter') if exe_filter: exe_filter = exe_filter[1] else: exe_filter = default_exefilter opts.log_info() debug_trace = opts.find_arg('--debug-trace') if debug_trace: debug_trace = debug_trace[1] else: debug_trace = '' opts.defaults['debug_trace'] = debug_trace job_trace = 'jobs' in debug_trace.split(',') rtems_tools = opts.find_arg('--rtems-tools') if rtems_tools: if len(rtems_tools) != 2: raise error.general('invalid RTEMS tools option') rtems_tools = rtems_tools[1] else: rtems_tools = '%{_prefix}' bsp = opts.find_arg('--rtems-bsp') if bsp is None or len(bsp) != 2: raise error.general('RTEMS BSP not provided or invalid option') opts.defaults.load('%%{_configdir}/bsps/%s.mc' % (bsp[1])) bsp = opts.defaults.get('%{bsp}') if not bsp: raise error.general('BSP definition (%{bsp}) not found in the global map') bsp = bsp[2] if not opts.defaults.set_read_map(bsp): raise error.general('no BSP map found') bsp_script = opts.defaults.get(bsp) if not bsp_script: raise error.general('BSP script not found: %s' % (bsp)) bsp_config = opts.defaults.expand(opts.defaults[bsp]) report_mode = opts.find_arg('--report-mode') if report_mode: if report_mode[1] != 'failures' and \ report_mode[1] != 'all' and \ report_mode[1] != 'none': raise error.general('invalid report mode') report_mode = report_mode[1] else: report_mode = 'failures' executables = find_executables(opts.params(), exe_filter) if len(executables) == 0: raise error.general('no executables supplied') start_time = datetime.datetime.now() total = len(executables) reports = report.report(total) invalid_tests = opts.defaults['invalid_tests'] if invalid_tests: reports.set_invalid_tests([l.strip() for l in invalid_tests.splitlines()]) reporting = 1 jobs = int(opts.jobs(opts.defaults['_ncpus'])) exe = 0 finished = [] if jobs > len(executables): jobs = len(executables) while exe < total or len(tests) > 0: if exe < total and len(tests) < jobs: tst = test_run(exe + 1, total, reports, executables[exe], rtems_tools, bsp, bsp_config, opts) exe += 1 tests += [tst] if job_trace: _job_trace(tst, 'create', total, exe, tests, reporting) tst.run() else: dead = [t for t in tests if not t.is_alive()] tests[:] = [t for t in tests if t not in dead] for tst in dead: if job_trace: _job_trace(tst, 'dead', total, exe, tests, reporting) finished += [tst] tst.reraise() del dead if len(tests) >= jobs or exe >= total: time.sleep(0.250) if len(finished): reporting = report_finished(reports, report_mode, reporting, finished, job_trace) finished_time = datetime.datetime.now() reporting = report_finished(reports, report_mode, reporting, finished, job_trace) if reporting < total: log.warning('finished jobs does match: %d' % (reporting)) report_finished(reports, report_mode, -1, finished, job_trace) reports.summary() end_time = datetime.datetime.now() log.notice('Average test time: %s' % (str((end_time - start_time) / total))) log.notice('Testing time : %s' % (str(end_time - start_time))) except error.general as gerr: print(gerr) sys.exit(1) except error.internal as ierr: print(ierr) sys.exit(1) except error.exit: sys.exit(2) except KeyboardInterrupt: if opts is not None and opts.find_arg('--stacktrace'): print('}} dumping:', threading.active_count()) for t in threading.enumerate(): print('}} ', t.name) print(stacktraces.trace()) log.notice('abort: user terminated') killall(tests) sys.exit(1) finally: console.restore(stdtty) sys.exit(0)
def build_arch_bsp(self, arch, bsp): if not self.config.bsp_present(arch, bsp): raise error.general('BSP not found: %s/%s' % (arch, bsp)) log.output('-' * 70) log.notice('] BSP: %s/%s' % (arch, bsp)) log.notice('. Creating: %s' % (self._path(arch, bsp))) self._arch_bsp_dir_clean(arch, bsp) self._arch_bsp_dir_make(arch, bsp) variations = self._variations(arch, bsp) build_set = self._build_set(variations) bsp_start = datetime.datetime.now() bsp_warnings = warnings_counter(self.rtems) env_path = os.environ['PATH'] os.environ['PATH'] = path.host(path.join(self.tools, 'bin')) + \ os.pathsep + os.environ['PATH'] for bs in sorted(build_set.keys()): warnings = warnings_counter(self.rtems) start = datetime.datetime.now() log.output('- ' * 35) log.notice('. Configuring: %s' % (bs)) try: result = '+ Pass' bpath = self._build_dir(arch, bsp, bs) path.mkdir(bpath) config_cmd = self._config_command(build_set[bs], arch, bsp) cmd = config_cmd e = execute.capture_execution(log = warnings) log.output('run: ' + cmd) if self.options['dry-run']: exit_code = 0 else: exit_code, proc, output = e.shell(cmd, cwd = path.host(bpath)) if exit_code != 0: result = '- FAIL' self.errors['configure'] += 1 log.notice('- Configure failed: %s' % (bs)) log.output('cmd failed: %s' % (cmd)) if self.options['stop-on-error']: raise error.general('Configuring %s failed' % (bs)) else: log.notice('. Building: %s' % (bs)) cmd = 'make' if 'jobs' in self.options: cmd += ' -j %s' % (self.options['jobs']) log.output('run: ' + cmd) if self.options['dry-run']: exit_code = 0 else: exit_code, proc, output = e.shell(cmd, cwd = path.host(bpath)) if exit_code != 0: result = '- FAIL' self.errors['build'] += 1 log.notice('- FAIL: %s: %s' % (bs, self._error_str())) log.output('cmd failed: %s' % (cmd)) if self.options['stop-on-error']: raise error.general('Building %s failed' % (bs)) files = self._count_files(arch, bsp, bs) log.notice('%s: %s: warnings:%d exes:%d objs:%s libs:%d' % \ (result, bs, warnings.get(), files['exes'], files['objs'], files['libs'])) log.notice(' %s' % (self._error_str())) self.results.add(result[0] == '+', arch, bsp, config_cmd, warnings.get()) finally: end = datetime.datetime.now() if not self.options['no-clean']: log.notice('. Cleaning: %s' % (self._build_dir(arch, bsp, bs))) path.removeall(self._build_dir(arch, bsp, bs)) log.notice('^ Time %s' % (str(end - start))) log.output('Warnings Report:') log.output(warnings.report()) warnings.accumulate(bsp_warnings) warnings.accumulate(self.warnings) bsp_end = datetime.datetime.now() log.notice('^ BSP Time %s' % (str(bsp_end - bsp_start))) log.output('BSP Warnings Report:') log.output(bsp_warnings.report()) os.environ['PATH'] = env_path
if options.host_windows: raise error.general('termios not support on host') self.dev = dev self.default_attr = None self.fd = None self.if_on = False if options.host_windows: raise error.general('TTY consoles not supported on Windows.') if not path.exists(dev): raise error.general('dev not found: %s' % (dev)) try: self.fd = open(dev, 'rw') except IOError, ioe: raise error.general('opening tty dev: %s: %s' % (dev, ioe)) except: raise error.general('opening tty dev: %s: unknown' % (dev)) try: self.default_attr = termios.tcgetattr(self.fd) except: raise error.general('cannot get termios attrs: %s' % (dev)) self.attr = self.default_attr def __del__(self): if self.fd and self.default_attr: try: self.fd.close() except: pass def __str__(self): def _input(attr):
def output(self, flag, on): mask = self._output_mask(flag) if mask is None: raise error.general('invalid output flag: %s' % (flag)) self._set(1, mask, on) self._update()
def control(self, flag, on): mask = self._control_mask(flag) if mask is None: raise error.general('invalid control flag: %s' % (flag)) self._set(2, mask, on) self._update()
def local(self, flag, on): mask = self._local_mask(flag) if mask is None: raise error.general('invalid local flag: %s' % (flag)) self._set(3, mask, on) self._update()
def run(command_path = None): import sys tests = [] stdtty = console.save() opts = None default_exefilter = '*.exe' try: optargs = { '--rtems-tools': 'The path to the RTEMS tools', '--rtems-bsp': 'The RTEMS BSP to run the test on', '--report-mode': 'Reporting modes, failures (default),all,none', '--list-bsps': 'List the supported BSPs', '--debug-trace': 'Debug trace based on specific flags', '--filter': 'Glob that executables must match to run (default: ' + default_exefilter + ')', '--stacktrace': 'Dump a stack trace on a user termination (^C)', '--rtems-builddir': 'The path to the build directory ( including e.g. /b-leon2/ )'} opts = options.load(sys.argv, optargs = optargs, command_path = command_path) log.notice('RTEMS Testing - Tester, v%s' % (version.str())) if opts.find_arg('--list-bsps'): bsps.list(opts) exe_filter = opts.find_arg('--filter') if exe_filter: exe_filter = exe_filter[1] else: exe_filter = default_exefilter opts.log_info() debug_trace = opts.find_arg('--debug-trace') if debug_trace: debug_trace = debug_trace[1] else: debug_trace = '' opts.defaults['debug_trace'] = debug_trace job_trace = 'jobs' in debug_trace.split(',') rtems_tools = opts.find_arg('--rtems-tools') if rtems_tools: bla = '%{_prefix}' print "prefixx: " + bla if len(rtems_tools) != 2: raise error.general('invalid RTEMS tools option') rtems_tools = rtems_tools[1] else: rtems_tools = '%{_prefix}' bsp = opts.find_arg('--rtems-bsp') if bsp is None or len(bsp) != 2: raise error.general('RTEMS BSP not provided or invalid option') opts.defaults.load('%%{_configdir}/bsps/%s.mc' % (bsp[1])) bsp = opts.defaults.get('%{bsp}') if not bsp: raise error.general('BSP definition (%{bsp}) not found in the global map') bsp = bsp[2] if not opts.defaults.set_read_map(bsp): raise error.general('no BSP map found') bsp_script = opts.defaults.get(bsp) if not bsp_script: raise error.general('BSP script not found: %s' % (bsp)) bsp_config = opts.defaults.expand(opts.defaults[bsp]) path_to_builddir= opts.find_arg('--rtems-builddir') if not path_to_builddir: raise error.general("Path to build directory not provided") coverage_enabled = opts.coverage() if coverage_enabled: import coverage from rtemstoolkit import check log.notice("Coverage analysis requested") opts.defaults.load('%%{_configdir}/coverage.mc') if not check.check_exe('__covoar', opts.defaults['__covoar']): raise error.general("Covoar not found!") coverage = coverage.coverage_run(opts.defaults, path_to_builddir[1]) coverage.prepareEnvironment(); report_mode = opts.find_arg('--report-mode') if report_mode: if report_mode[1] != 'failures' and \ report_mode[1] != 'all' and \ report_mode[1] != 'none': raise error.general('invalid report mode') report_mode = report_mode[1] else: report_mode = 'failures' executables = find_executables(opts.params(), exe_filter, path_to_builddir[1]) if len(executables) == 0: raise error.general('no executables supplied') start_time = datetime.datetime.now() total = len(executables) reports = report.report(total) invalid_tests = opts.defaults['invalid_tests'] if invalid_tests: reports.set_invalid_tests([l.strip() for l in invalid_tests.splitlines()]) reporting = 1 jobs = int(opts.jobs(opts.defaults['_ncpus'])) exe = 0 finished = [] if jobs > len(executables): jobs = len(executables) while exe < total or len(tests) > 0: if exe < total and len(tests) < jobs: tst = test_run(exe + 1, total, reports, executables[exe], rtems_tools, bsp, bsp_config, opts) exe += 1 tests += [tst] if job_trace: _job_trace(tst, 'create', total, exe, tests, reporting) tst.run() else: dead = [t for t in tests if not t.is_alive()] tests[:] = [t for t in tests if t not in dead] for tst in dead: if job_trace: _job_trace(tst, 'dead', total, exe, tests, reporting) finished += [tst] tst.reraise() del dead if len(tests) >= jobs or exe >= total: time.sleep(0.250) if len(finished): reporting = report_finished(reports, report_mode, reporting, finished, job_trace) finished_time = datetime.datetime.now() reporting = report_finished(reports, report_mode, reporting, finished, job_trace) if reporting < total: log.warning('finished jobs does match: %d' % (reporting)) report_finished(reports, report_mode, -1, finished, job_trace) reports.summary() end_time = datetime.datetime.now() log.notice('Average test time: %s' % (str((end_time - start_time) / total))) log.notice('Testing time : %s' % (str(end_time - start_time))) if coverage_enabled: coverage.config_map = opts.defaults.macros['coverage'] coverage.executables = executables print [c for c in coverage.config_map] print [e for e in executables]