def test_recursive_call(set_up_test_data): EXPECTED = TEST_RESOURCES_DIR / "expect_recursive_chains.csv" outfile = TEST_DATA_DIR / "recursive_chains.csv" cmd = [QUERY_FC, "--calls", CALLS_FILE, "--from_function", "recursive_call", "--to_function", "recursive_call", "--out", outfile] assert subprocess.run(cmd).returncode == 0 assert EXPECTED.exists() df_expected = pd.read_csv(EXPECTED) df_generated = pd.read_csv(outfile) df_diff = test_utils.df_difference(df_expected, df_generated) assert df_diff.empty, test_utils.df_to_string(df_diff)
def test_from_function_with_fname(set_up_test_data): EXPECTED = TEST_RESOURCES_DIR / "expect_single_chain_right.csv" outfile = TEST_DATA_DIR / "single_chain_right.csv" cmd = [QUERY_FC, "--calls", CALLS_FILE, "--from_function", "test-chain.c:chain1", "--to_function", "chain3", "--direction", "right", "--out", outfile] assert subprocess.run(cmd).returncode == 0 assert EXPECTED.exists() df_expected = pd.read_csv(EXPECTED) df_generated = pd.read_csv(outfile) df_diff = test_utils.df_difference(df_expected, df_generated) assert df_diff.empty, test_utils.df_to_string(df_diff)
def check_function_calls_from(target_bc_file_name, cpp=False): target_bc_file = TEST_RESOURCES_DIR / target_bc_file_name assert Path(target_bc_file).exists() outfile = TEST_DATA_DIR / "calls.csv" if target_bc_file_name.endswith(".bclist"): target_bc_file = "@%s" % target_bc_file if cpp: cmd = [ CG_BIN, "-cpp_linked_bitcode", target_bc_file, "-o", outfile, target_bc_file, ] else: cmd = [ CG_BIN, "-o", outfile, target_bc_file, ] assert subprocess.run(cmd).returncode == 0 assert Path(outfile).exists() # Check the generated contents matches expected assert EXPECTED.exists() df_expected = pd.read_csv(EXPECTED) caller_regex = "^%s" % target_bc_file_name.split(".")[0] df_expected = df_regex_filter(df_expected, "caller_filename", caller_regex) df_generated = pd.read_csv(outfile) # Remove entries where caller or callee function name begins with '__cxx'. # These are library functions we want to ignore in the tests: df_generated = df_generated[ ~df_generated["caller_function"].str.startswith("__cxx", na=False) & ~df_generated["callee_function"].str.startswith("__cxx", na=False)] df_diff = test_utils.df_difference(df_expected, df_generated) assert df_diff.empty, test_utils.df_to_string(df_diff)
def test_function_specific(set_up_test_data): cmd = [QUERY_FC, "--calls", CALLS_FILE_DUPL, "--from_function", "test-chain.c:chain2", "--to_function", "chain[0-9]", "--direction", "both"] assert subprocess.run(cmd).returncode == 0 EXPECTED = TEST_RESOURCES_DIR / "expect_function_filename_specific.csv" outfile = TEST_DATA_DIR / "function_filename_specific.csv" cmd = [QUERY_FC, "--calls", CALLS_FILE_DUPL, "--from_function", "test-chain-alt.c:chain2", "--to_function", "chain[0-9]", "--direction", "left", "--out", outfile] assert subprocess.run(cmd).returncode == 0 assert EXPECTED.exists() df_expected = pd.read_csv(EXPECTED) df_generated = pd.read_csv(outfile) df_diff = test_utils.df_difference(df_expected, df_generated) assert df_diff.empty, test_utils.df_to_string(df_diff)
def test_csv_graph_duplicate(set_up_test_data): callgraph_csv = TEST_DATA_DIR / "calls.csv" generate_call_graph_from("test-duplicate-path.bclist", callgraph_csv) query_out = TEST_DATA_DIR / "graph.csv" cmd = [ QUERY_CG, "--csv", callgraph_csv, "--function", "main", "--depth", "10", "--out", query_out ] assert subprocess.run(cmd).returncode == 0 assert Path(query_out).exists() query_out_inverse = TEST_DATA_DIR / "graph_inverse.csv" cmd = [ QUERY_CG, "--csv", callgraph_csv, "--function", "printf", "--depth", "10", "--inverse", "--out", query_out_inverse ] assert subprocess.run(cmd).returncode == 0 assert Path(query_out_inverse).exists() # When 'depth' covers the entire callgraph, the output from # the two above commands should be the same, except for column # 'call_depth': below, we remove that column from both outputs and # compare the two dataframes df_csv = pd.read_csv(query_out) assert not df_csv.empty df_csv = df_csv.drop('call_depth', 1) df_csv = df_csv.sort_values(by=['caller_line']) df_csv_inv = pd.read_csv(query_out_inverse) assert not df_csv_inv.empty df_csv_inv = df_csv_inv.drop('call_depth', 1) df_csv_inv = df_csv_inv.sort_values(by=['caller_line']) df_diff = test_utils.df_difference(df_csv, df_csv_inv) assert df_diff.empty, test_utils.df_to_string(df_diff)