def run_iteration(fn: Callable, sig: Signature, space: StateSpace) -> Optional[PathSummary]: with NoTracing(): args = gen_args(sig) pre_args = copy.deepcopy(args) ret = None with measure_fn_coverage(fn) as coverage, ExceptionFilter() as efilter: # coverage = lambda _: CoverageResult(set(), set(), 1.0) # with ExceptionFilter() as efilter: ret = fn(*args.args, **args.kwargs) space.detach_path() if efilter.user_exc is not None: exc = efilter.user_exc[0] debug("user-level exception found", repr(exc), *efilter.user_exc[1]) return PathSummary(pre_args, ret, type(exc), args, coverage(fn)) elif efilter.ignore: return None else: return PathSummary( deep_realize(pre_args), deep_realize(ret), None, deep_realize(args), coverage(fn), )
def run_iteration( fn1: Callable, fn2: Callable, sig: inspect.Signature, space: StateSpace ) -> Tuple[Optional[VerificationStatus], Optional[BehaviorDiff]]: with NoTracing(): original_args = gen_args(sig) args1 = copy.deepcopy(original_args) args2 = copy.deepcopy(original_args) coverage_manager = measure_fn_coverage(fn1, fn2) with ExceptionFilter() as efilter, coverage_manager as coverage: result1 = describe_behavior(fn1, args1) result2 = describe_behavior(fn2, args2) space.detach_path() if result1 == result2 and args1 == args2: debug("Functions equivalent") return (VerificationStatus.CONFIRMED, None) debug("Functions differ") realized_args = {k: repr(v) for (k, v) in original_args.arguments.items()} post_execution_args1 = {k: repr(v) for k, v in args1.arguments.items()} post_execution_args2 = {k: repr(v) for k, v in args2.arguments.items()} diff = BehaviorDiff( realized_args, Result(repr(result1[0]), result1[1], post_execution_args1), Result(repr(result2[0]), result2[1], post_execution_args2), coverage(fn1), coverage(fn2), ) return (VerificationStatus.REFUTED, diff) if efilter.user_exc: debug( "User-level exception found", repr(efilter.user_exc[0]), efilter.user_exc[1] ) return (None, None)
def symbolic_run( self, fn: Callable[[StateSpace, Dict[str, object]], object], typed_args: Dict[str, type], ) -> Tuple[ object, # return value Optional[Dict[str, object]], # arguments after execution Optional[BaseException], # exception thrown, if any StateSpace, ]: search_root = SinglePathNode(True) with COMPOSITE_TRACER, Patched(): for itr in range(1, 200): debug("iteration", itr) space = StateSpace( time.monotonic() + 10.0, 1.0, search_root=search_root ) symbolic_args = {} try: with StateSpaceContext(space): symbolic_args = { name: proxy_for_type(typ, name) for name, typ in typed_args.items() } ret = fn(space, symbolic_args) ret = (deep_realize(ret), symbolic_args, None, space) space.detach_path() return ret except IgnoreAttempt as e: debug("ignore iteration attempt: ", str(e)) pass except BaseException as e: debug(traceback.format_exc()) return (None, symbolic_args, e, space) top_analysis, space_exhausted = space.bubble_status(CallAnalysis()) if space_exhausted: return ( None, symbolic_args, CrosshairInternal(f"exhausted after {itr} iterations"), space, ) return ( None, None, CrosshairInternal("Unable to find a successful symbolic execution"), space, )