def _track_sut_data(tracer: ExecutionTracer, test_cluster: TestCluster) -> None: """Track data from the SUT.""" tracker = StatisticsTracker() tracker.track_output_variable( RuntimeVariable.CodeObjects, len(tracer.get_known_data().existing_code_objects), ) tracker.track_output_variable( RuntimeVariable.Predicates, len(tracer.get_known_data().existing_predicates) ) tracker.track_output_variable( RuntimeVariable.AccessibleObjectsUnderTest, test_cluster.num_accessible_objects_under_test(), )
def test_integrate_branch_distance_instrumentation( simple_module, function_name, branchless_function_count, branches_count, ): tracer = ExecutionTracer() function_callable = getattr(simple_module, function_name) instr = BranchDistanceInstrumentation(tracer) function_callable.__code__ = instr._instrument_code_recursive( function_callable.__code__, 0) assert (len(tracer.get_known_data().branch_less_code_objects) == branchless_function_count) assert len(list( tracer.get_known_data().existing_predicates)) == branches_count
def test_compute_fitness_values_no_branches(): module_name = "tests.fixtures.branchcoverage.nobranches" tracer = ExecutionTracer() tracer.current_thread_ident = threading.currentThread().ident with install_import_hook(module_name, tracer): module = importlib.import_module(module_name) importlib.reload(module) executor = TestCaseExecutor(tracer) chromosome = _get_test_for_no_branches_fixture(module) goals = bcf.BranchCoverageFactory(executor).get_coverage_goals() goals_dict = {} for goal in goals: chromosome.add_fitness_function(goal) goals_dict[tracer.get_known_data().existing_code_objects[ goal._goal.code_object_id].code_object.co_name] = goal fitness = chromosome.get_fitness() assert fitness == 1 assert chromosome.fitness_values[goals_dict["__init__"]].fitness == 0.0 assert chromosome.fitness_values[goals_dict["other"]].fitness == 1.0 assert chromosome.fitness_values[goals_dict["<module>"]].fitness == 0.0 assert chromosome.fitness_values[goals_dict["get_x"]].fitness == 0.0 assert chromosome.fitness_values[goals_dict["identity"]].fitness == 0.0 assert chromosome.fitness_values[ goals_dict["DummyClass"]].fitness == 0.0
def test_no_branchless_code_object_register_multiple(): tracer = ExecutionTracer() tracer.register_code_object(MagicMock()) tracer.register_code_object(MagicMock()) tracer.register_predicate(MagicMock(code_object_id=0)) tracer.register_predicate(MagicMock(code_object_id=0)) assert tracer.get_known_data().branch_less_code_objects == {1}
def test_hook(): tracer = ExecutionTracer() with install_import_hook("tests.fixtures.instrumentation.mixed", tracer): module = importlib.import_module( "tests.fixtures.instrumentation.mixed") importlib.reload(module) assert len(tracer.get_known_data().existing_code_objects) > 0 assert module.function(6) == 0
def _track_sut_data(tracer: ExecutionTracer, test_cluster: TestCluster) -> None: """Track data from the SUT. Args: tracer: the execution tracer test_cluster: the test cluster """ stat.track_output_variable( RuntimeVariable.CodeObjects, len(tracer.get_known_data().existing_code_objects), ) stat.track_output_variable( RuntimeVariable.Predicates, len(tracer.get_known_data().existing_predicates), ) stat.track_output_variable( RuntimeVariable.AccessibleObjectsUnderTest, test_cluster.num_accessible_objects_under_test(), ) stat.track_output_variable( RuntimeVariable.GeneratableTypes, len(test_cluster.get_all_generatable_types()), )
def get_root_control_flow_distance( result: ExecutionResult, code_object_id: int, tracer: ExecutionTracer) -> ControlFlowDistance: """Computes the control flow distance for a root branch, i.e., if the given code object was executed. Args: result: the execution result. code_object_id: The code object id for which we want to get the root distance. tracer: the execution tracer Returns: The control flow distance, (0.0, 0.0) if it was executed, otherwise (1.0, 0.0) """ assert code_object_id in tracer.get_known_data().branch_less_code_objects distance = ControlFlowDistance() if code_object_id in result.execution_trace.executed_code_objects: # The code object was executed by the execution return distance distance.increase_approach_level() return distance
def test_predicate_exists(): tracer = ExecutionTracer() assert tracer.register_predicate(MagicMock(PredicateMetaData)) == 0 assert tracer.register_predicate(MagicMock(PredicateMetaData)) == 1 assert 0 in tracer.get_known_data().existing_predicates
def test_functions_exists(): tracer = ExecutionTracer() assert tracer.register_code_object(MagicMock(CodeObjectMetaData)) == 0 assert tracer.register_code_object(MagicMock(CodeObjectMetaData)) == 1 assert 0 in tracer.get_known_data().existing_code_objects
def get_non_root_control_flow_distance( result: ExecutionResult, predicate_id: int, value: bool, tracer: ExecutionTracer) -> ControlFlowDistance: """Computes the control flow distance for a predicate. Args: result: the execution result. predicate_id: The predicate id for which we want to get the root distance. value: compute distance to the true or the false branch? tracer: the execution tracer Returns: The control flow distance. """ trace = result.execution_trace code_object_id = (tracer.get_known_data(). existing_predicates[predicate_id].code_object_id) distance = ControlFlowDistance() # Code Object was not executed, simply use diameter as upper bound. if code_object_id not in trace.executed_code_objects: distance.approach_level = (tracer.get_known_data( ).existing_code_objects[code_object_id].cfg.diameter) return distance # Predicate was executed, simply use distance of correct branch. if predicate_id in trace.executed_predicates: if value: branch_distance = _predicate_fitness(predicate_id, trace.true_distances) else: branch_distance = _predicate_fitness(predicate_id, trace.false_distances) distance.branch_distance = branch_distance return distance cdg = tracer.get_known_data().existing_code_objects[code_object_id].cdg target_node = _get_node_with_predicate_id(cdg, predicate_id) # Choose diameter as upper bound distance.approach_level = (tracer.get_known_data( ).existing_code_objects[code_object_id].cfg.diameter) # We check for the closest predicate that was executed and compute the approach # level as the length of the path from such a predicate node to the desired # predicate node. for node in [ node for node in cdg.nodes if node.predicate_id is not None and node.predicate_id in trace.executed_predicates ]: try: candidate = ControlFlowDistance() candidate.approach_level = nx.shortest_path_length( cdg.graph, node, target_node) # Predicate was executed but did not lead to execution of desired predicate # So the remaining branch distance to the true or false branch is # the desired distance, right? # One of them has to be zero, so we can simply add them. assert node.predicate_id is not None candidate.branch_distance = _predicate_fitness( node.predicate_id, trace.true_distances) + _predicate_fitness( node.predicate_id, trace.false_distances) distance = min(distance, candidate) except nx.NetworkXNoPath: # No path from node to target. pass return distance
def test_predicate_exists(): tracer = ExecutionTracer() assert tracer.register_predicate(MagicMock(code_object_id=0)) == 0 assert tracer.register_predicate(MagicMock(code_object_id=0)) == 1 assert 0 in tracer.get_known_data().existing_predicates
def test_default_branchless_code_object(): tracer = ExecutionTracer() tracer.register_code_object(MagicMock()) assert tracer.get_known_data().branch_less_code_objects == {0}