def check_filter(self, _objdir, arch, board, _filter, origin=None): """ This is going to be called by the App Builder's build function to evaluate if we need to filter out a build of a testcase. In any other case, it will be ignored. :param str objdir: name of the Zephyr's object directory where to find configuration files :param str arch: name of the architecture we are building :param str board: Zephyr's board we are building :param str _filter: Zephyr's sanity Check style filter expression :param str origin: where does this come from? """ if not origin: origin = commonl.origin_get() if _filter == None or _filter == "": return self.target.report_info("filter: processing '%s' @%s" % (_filter, origin), dlevel=1) self.target.report_info("filter: reading defconfig", dlevel=2) _defconfig = self.config_file_read() defconfig = {} for key, value in _defconfig.iteritems(): # The testcase.ini filter language doesn't prefix the # CONFIG_ stuff, so we are going to strip it with [7:] if key.startswith("CONFIG_"): defconfig[key[7:]] = value # The testcase.yaml filter language prefixes with # CONFIG_ stuff, so we don't strip it defconfig[key] = value self.target.report_info("filter: evaluating", dlevel=2) try: res = commonl.expr_parser.parse(_filter, defconfig) self.target.report_info("filter: evaluated defconfig: %s" % res, dlevel=1) if res == False: raise tc.skip_e("filter '%s' @ %s causes TC to be skipped" % (_filter, origin)) else: self.target.report_info( "filter '%s' @ %s causes TC to be continued" % (_filter, origin), dlevel=2) except SyntaxError as se: raise tc.error_e("filter: failed processing '%s' @ %s: %s" % (_filter, origin, se))
def check_filter(self, _objdir, arch, board, _filter, origin = None): """ This is going to be called by the App Builder's build function to evaluate if we need to filter out a build of a testcase. In any other case, it will be ignored. :param str objdir: name of the Zephyr's object directory where to find configuration files :param str arch: name of the architecture we are building :param str board: Zephyr's board we are building :param str _filter: Zephyr's sanity Check style filter expression :param str origin: where does this come from? """ if not origin: origin = commonl.origin_get() if _filter == None or _filter == "": return self.target.report_info("filter: processing '%s' @%s" % (_filter, origin), dlevel = 1) self.target.report_info("filter: reading defconfig", dlevel = 2) _defconfig = self.config_file_read() defconfig = {} for key, value in _defconfig.iteritems(): # The testcase.ini filter language doesn't prefix the # CONFIG_ stuff, so we are going to strip it with [7:] if key.startswith("CONFIG_"): defconfig[key[7:]] = value # The testcase.yaml filter language prefixes with # CONFIG_ stuff, so we don't strip it defconfig[key] = value self.target.report_info("filter: evaluating", dlevel = 2) try: res = commonl.expr_parser.parse(_filter, defconfig) self.target.report_info("filter: evaluated defconfig: %s" % res, dlevel = 1) if res == False: raise tc.skip_e("filter '%s' @ %s causes TC to be skipped" % (_filter, origin)) else: self.target.report_info( "filter '%s' @ %s causes TC to be continued" % (_filter, origin), dlevel = 2) except SyntaxError as se: raise tc.error_e("filter: failed processing '%s' @ %s: %s" % (_filter, origin, se))
def console_rx_eval(expecter, target, regex, console=None, _timeout=None, result=None, uid=None): """ Check what came on a console and act on it :param str uid: (optional) identifier to use to store offset data """ if hasattr(regex, "pattern"): what = regex.pattern else: what = regex regex = re.compile(re.escape(regex)) if not uid: uid = console_mk_uid(target, what, console, _timeout, result) console_id_name, console_code = console_mk_code(target, console) # These were set by the poller of = expecter.buffers.get(console_code, None) if of == None: # FIXME: debug lof output here? expecter->tc backlink? return None ofd = of.fileno() ts = time.time() # Get the offset we saved before as the last part where we looked # at. If none, then get the last offset the poller has # recorded. Otherwise, just default to look from the start # Note the idea is each eval function has a different offset where # it is looking at. Likewise the poller for each console. offset_poller_code = "offset_" + console_code offset = expecter.buffers_persistent.get( uid, expecter.buffers_persistent.get(offset_poller_code, 0)) if _timeout != False: timeout = expecter.timeout if _timeout == None else _timeout # We can do timeout checks that provide better information # than a generic 'timeout' if ts - expecter.ts0 > timeout: of.seek(offset) # so we report console from where searched raise tc.error_e( "expected console output '%s' from console '%s:%s' " \ "NOT FOUND after %.1f s" \ % (what, target.id, console_id_name, ts - expecter.ts0), { 'target': target, "console output": of }) # mmap the whole file (which doesn't alter the file pointer) # # We have to mmap as the file might be getting huge and thus, # reading line by line might be dumb. # # However, we only search starting at @offset, which is set later # to the last success searching we had. So we shan't really map # the whole file, shall map on demand. stat_info = os.fstat(ofd) if stat_info.st_size == 0: # Nothing to read return None with contextlib.closing( mmap.mmap(of.fileno(), 0, mmap.MAP_PRIVATE, mmap.PROT_READ, 0)) as mapping: target.report_info("looking for `%s` in console %s:%s @%d-%d at " "%.2fs [%s]" % (what, target.fullid, console_id_name, offset, stat_info.st_size, ts - expecter.ts0, of.name), dlevel=3) m = regex.search(mapping[offset:]) if m: new_offset = offset + m.end() expecter.buffers_persistent[uid] = new_offset if result == None or result == "pass": # raising pass gets stopped at expecter.run(), so we # print instead, so we can see the console offset_tip = of.tell() # we report console from where searched of.seek(offset) # so we report console from where searched target.report_pass( "found expected `%s` in console `%s:%s` at %.2fs @%d" % (what, target.fullid, console_id_name, ts - expecter.ts0, offset + m.start()), {"console output": of}, dlevel=1, alevel=2) of.seek(offset_tip) raise tc.pass_e( "found expected `%s` in console `%s:%s` at %.2fs" % (what, target.fullid, console_id_name, ts - expecter.ts0), {'target': target}) elif result == "fail": of.seek(offset) # so we report console from where searched raise tc.failed_e( "found expected (for failure) `%s` in console " "`%s:%s` at %.2fs" % (what, target.fullid, console_id_name, ts - expecter.ts0), { 'target': target, "console output": of }) elif result == "error" or result == "errr": of.seek(offset) # so we report console from where searched raise tc.error_e( "found expected (for error) `%s` in console " "`%s:%s` at %.2fs" % (what, target.fullid, console_id_name, ts - expecter.ts0), { 'target': target, "console output": of }) elif result == "skip": of.seek(offset) # so we report console from where searched raise tc.skip_e( "found expected (for skip) `%s` in console " "'%s:%s' at %.2fs" % (what, target.fullid, console_id_name, ts - expecter.ts0), { 'target': target, "console output": of }) else: of.seek(offset) # so we report console from where searched raise tc.blocked_e("BUG: invalid result requested (%s)" % result) return None
def console_rx_eval(expecter, target, regex, console = None, _timeout = None, result = None, uid = None): """ Check what came on a console and act on it :param str uid: (optional) identifier to use to store offset data """ if hasattr(regex, "pattern"): what = regex.pattern else: what = regex regex = re.compile(re.escape(regex)) if not uid: uid = console_mk_uid(target, what, console, _timeout, result) console_id_name, console_code = console_mk_code(target, console) # These were set by the poller of = expecter.buffers.get(console_code, None) if of == None: # FIXME: debug lof output here? expecter->tc backlink? return None ofd = of.fileno() ts = time.time() # Get the offset we saved before as the last part where we looked # at. If none, then get the last offset the poller has # recorded. Otherwise, just default to look from the start # Note the idea is each eval function has a different offset where # it is looking at. Likewise the poller for each console. offset_poller_code = "offset_" + console_code offset = expecter.buffers_persistent.get( uid, expecter.buffers_persistent.get(offset_poller_code, 0)) if _timeout != False: timeout = expecter.timeout if _timeout == None else _timeout # We can do timeout checks that provide better information # than a generic 'timeout' if ts - expecter.ts0 > timeout: of.seek(offset) # so we report console from where searched raise tc.error_e( "expected console output '%s' from console '%s:%s' " \ "NOT FOUND after %.1f s" \ % (what, target.id, console_id_name, ts - expecter.ts0), { 'target': target, "console output": of }) # mmap the whole file (which doesn't alter the file pointer) # # We have to mmap as the file might be getting huge and thus, # reading line by line might be dumb. # # However, we only search starting at @offset, which is set later # to the last success searching we had. So we shan't really map # the whole file, shall map on demand. stat_info = os.fstat(ofd) if stat_info.st_size == 0: # Nothing to read return None with contextlib.closing(mmap.mmap(of.fileno(), 0, mmap.MAP_PRIVATE, mmap.PROT_READ, 0)) as mapping: target.report_info("looking for `%s` in console %s:%s @%d-%d at " "%.2fs [%s]" % (what, target.fullid, console_id_name, offset, stat_info.st_size, ts - expecter.ts0, of.name), dlevel = 3) m = regex.search(mapping[offset:]) if m: new_offset = offset + m.end() expecter.buffers_persistent[uid] = new_offset if result == None or result == "pass": # raising pass gets stopped at expecter.run(), so we # print instead, so we can see the console offset_tip = of.tell() # we report console from where searched of.seek(offset) # so we report console from where searched target.report_pass( "found expected `%s` in console `%s:%s` at %.2fs" % (what, target.fullid, console_id_name, ts - expecter.ts0), { "console output": of }, dlevel = 1, alevel = 2) of.seek(offset_tip) raise tc.pass_e( "found expected `%s` in console `%s:%s` at %.2fs" % (what, target.fullid, console_id_name, ts - expecter.ts0), {'target': target }) elif result == "fail": of.seek(offset) # so we report console from where searched raise tc.failed_e( "found expected (for failure) `%s` in console " "`%s:%s` at %.2fs" % (what, target.fullid, console_id_name, ts - expecter.ts0), { 'target': target, "console output": of }) elif result == "error" or result == "errr": of.seek(offset) # so we report console from where searched raise tc.error_e( "found expected (for error) `%s` in console " "`%s:%s` at %.2fs" % (what, target.fullid, console_id_name, ts - expecter.ts0), { 'target': target, "console output": of }) elif result == "skip": of.seek(offset) # so we report console from where searched raise tc.skip_e( "found expected (for skip) `%s` in console " "'%s:%s' at %.2fs" % (what, target.fullid, console_id_name, ts - expecter.ts0), { 'target': target, "console output": of }) else: of.seek(offset) # so we report console from where searched raise tc.blocked_e( "BUG: invalid result requested (%s)" % result) return None