Skip to content

Commit 24e26c3

Browse files
Merge pull request #1698 from codeflash-ai/fix-runtime-calculation
fix runtime calculation for java
2 parents 04b0dbd + d9de2cf commit 24e26c3

7 files changed

Lines changed: 76 additions & 91 deletions

File tree

codeflash-java-runtime/src/main/java/com/codeflash/Comparator.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,11 @@ private static Map<String, byte[]> readTestResults(String dbPath) throws Excepti
144144
try (Connection conn = DriverManager.getConnection(url);
145145
Statement stmt = conn.createStatement();
146146
ResultSet rs = stmt.executeQuery(
147-
"SELECT iteration_id, return_value FROM test_results WHERE loop_index = 1")) {
147+
"SELECT test_module_path, test_class_name, test_function_name, iteration_id, return_value FROM test_results WHERE loop_index = 1")) {
148148
while (rs.next()) {
149+
String testModulePath = rs.getString("test_module_path");
150+
String testClassName = rs.getString("test_class_name");
151+
String testFunctionName = rs.getString("test_function_name");
149152
String iterationId = rs.getString("iteration_id");
150153
byte[] returnValue = rs.getBytes("return_value");
151154
// Strip the CODEFLASH_TEST_ITERATION suffix (e.g. "7_0" -> "7")
@@ -155,7 +158,10 @@ private static Map<String, byte[]> readTestResults(String dbPath) throws Excepti
155158
if (lastUnderscore > 0) {
156159
iterationId = iterationId.substring(0, lastUnderscore);
157160
}
158-
results.put(iterationId, returnValue);
161+
// Use module:class:function:iteration as key to uniquely identify
162+
// each invocation across different test files, classes, and methods
163+
String key = testModulePath + ":" + testClassName + ":" + testFunctionName + "::" + iterationId;
164+
results.put(key, returnValue);
159165
}
160166
}
161167
return results;

codeflash/languages/java/instrumentation.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,7 +1073,7 @@ def build_instrumented_body(
10731073
timing_lines = [
10741074
f"{indent}for (int _cf_i{current_id} = 0; _cf_i{current_id} < _cf_innerIterations{current_id}; _cf_i{current_id}++) {{",
10751075
f"{inner_indent}int _cf_loopId{current_id} = _cf_outerLoop{current_id} * _cf_maxInnerIterations{current_id} + _cf_i{current_id};",
1076-
f'{inner_indent}System.out.println("!$######" + _cf_mod{current_id} + ":" + _cf_cls{current_id} + "." + _cf_test{current_id} + ":" + _cf_fn{current_id} + ":" + _cf_loopId{current_id} + ":" + _cf_i{current_id} + "######$!");',
1076+
f'{inner_indent}System.out.println("!$######" + _cf_mod{current_id} + ":" + _cf_cls{current_id} + "." + _cf_test{current_id} + ":" + _cf_fn{current_id} + ":" + _cf_loopId{current_id} + ":" + "{current_id}" + "######$!");',
10771077
f"{inner_indent}long _cf_end{current_id} = -1;",
10781078
f"{inner_indent}long _cf_start{current_id} = 0;",
10791079
f"{inner_indent}try {{",
@@ -1083,7 +1083,7 @@ def build_instrumented_body(
10831083
f"{inner_indent}}} finally {{",
10841084
f"{inner_body_indent}long _cf_end{current_id}_finally = System.nanoTime();",
10851085
f"{inner_body_indent}long _cf_dur{current_id} = (_cf_end{current_id} != -1 ? _cf_end{current_id} : _cf_end{current_id}_finally) - _cf_start{current_id};",
1086-
f'{inner_body_indent}System.out.println("!######" + _cf_mod{current_id} + ":" + _cf_cls{current_id} + "." + _cf_test{current_id} + ":" + _cf_fn{current_id} + ":" + _cf_loopId{current_id} + ":" + _cf_i{current_id} + ":" + _cf_dur{current_id} + "######!");',
1086+
f'{inner_body_indent}System.out.println("!######" + _cf_mod{current_id} + ":" + _cf_cls{current_id} + "." + _cf_test{current_id} + ":" + _cf_fn{current_id} + ":" + _cf_loopId{current_id} + ":" + "{current_id}" + ":" + _cf_dur{current_id} + "######!");',
10871087
f"{inner_indent}}}",
10881088
f"{indent}}}",
10891089
]
@@ -1140,7 +1140,7 @@ def build_instrumented_body(
11401140
timing_lines = [
11411141
f"{indent}for (int _cf_i{current_id} = 0; _cf_i{current_id} < _cf_innerIterations{current_id}; _cf_i{current_id}++) {{",
11421142
f"{inner_indent}int _cf_loopId{current_id} = _cf_outerLoop{current_id} * _cf_maxInnerIterations{current_id} + _cf_i{current_id};",
1143-
f'{inner_indent}System.out.println("!$######" + _cf_mod{current_id} + ":" + _cf_cls{current_id} + "." + _cf_test{current_id} + ":" + _cf_fn{current_id} + ":" + _cf_loopId{current_id} + ":{current_id}_" + _cf_i{current_id} + "######$!");',
1143+
f'{inner_indent}System.out.println("!$######" + _cf_mod{current_id} + ":" + _cf_cls{current_id} + "." + _cf_test{current_id} + ":" + _cf_fn{current_id} + ":" + _cf_loopId{current_id} + ":{current_id}" + "######$!");',
11441144
f"{inner_indent}long _cf_end{current_id} = -1;",
11451145
f"{inner_indent}long _cf_start{current_id} = 0;",
11461146
f"{inner_indent}try {{",
@@ -1150,7 +1150,7 @@ def build_instrumented_body(
11501150
f"{inner_indent}}} finally {{",
11511151
f"{inner_body_indent}long _cf_end{current_id}_finally = System.nanoTime();",
11521152
f"{inner_body_indent}long _cf_dur{current_id} = (_cf_end{current_id} != -1 ? _cf_end{current_id} : _cf_end{current_id}_finally) - _cf_start{current_id};",
1153-
f'{inner_body_indent}System.out.println("!######" + _cf_mod{current_id} + ":" + _cf_cls{current_id} + "." + _cf_test{current_id} + ":" + _cf_fn{current_id} + ":" + _cf_loopId{current_id} + ":{current_id}_" + _cf_i{current_id} + ":" + _cf_dur{current_id} + "######!");',
1153+
f'{inner_body_indent}System.out.println("!######" + _cf_mod{current_id} + ":" + _cf_cls{current_id} + "." + _cf_test{current_id} + ":" + _cf_fn{current_id} + ":" + _cf_loopId{current_id} + ":{current_id}" + ":" + _cf_dur{current_id} + "######!");',
11541154
f"{inner_indent}}}",
11551155
f"{indent}}}",
11561156
]
179 Bytes
Binary file not shown.

codeflash/languages/python/context/unused_definition_remover.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,6 @@ def detect_unused_helper_functions(
748748
"""
749749
# Skip this analysis for non-Python languages since we use Python's ast module
750750
if not is_python():
751-
logger.debug("Skipping unused helper function detection for non-Python languages")
752751
return []
753752

754753
if isinstance(optimized_code, CodeStringsMarkdown) and len(optimized_code.code_strings) > 0:

codeflash/verification/parse_test_output.py

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -605,23 +605,16 @@ def parse_sqlite_test_results(sqlite_file_path: Path, test_files: TestFiles, tes
605605
else:
606606
# Try original_file_path first (for existing tests that were instrumented)
607607
test_type = test_files.get_test_type_by_original_file_path(test_file_path)
608-
logger.debug(f"[PARSE-DEBUG] test_module={test_module_path}, test_file_path={test_file_path}")
609-
logger.debug(f"[PARSE-DEBUG] by_original_file_path: {test_type}")
610608
# If not found, try instrumented_behavior_file_path (for generated tests)
611609
if test_type is None:
612610
test_type = test_files.get_test_type_by_instrumented_file_path(test_file_path)
613-
logger.debug(f"[PARSE-DEBUG] by_instrumented_file_path: {test_type}")
614611
# Default to GENERATED_REGRESSION for Jest/Java tests when test type can't be determined
615612
if test_type is None and (is_jest or is_java_test):
616613
test_type = TestType.GENERATED_REGRESSION
617-
logger.debug(
618-
f"[PARSE-DEBUG] defaulting to GENERATED_REGRESSION ({'Jest' if is_jest else 'Java'})"
619-
)
620614
elif test_type is None:
621615
# Skip results where test type cannot be determined
622616
logger.debug(f"Skipping result for {test_function_name}: could not determine test type")
623617
continue
624-
logger.debug(f"[PARSE-DEBUG] FINAL test_type={test_type}")
625618

626619
# Deserialize return value
627620
# For Jest/Java: Store as serialized JSON - comparison happens via language-specific comparator
@@ -699,10 +692,6 @@ def parse_test_xml(
699692
return test_results
700693
# Always use tests_project_rootdir since pytest is now the test runner for all frameworks
701694
base_dir = test_config.tests_project_rootdir
702-
logger.debug(f"[PARSE-XML] base_dir for resolution: {base_dir}")
703-
logger.debug(
704-
f"[PARSE-XML] Registered test files: {[str(tf.instrumented_behavior_file_path) for tf in test_files.test_files]}"
705-
)
706695

707696
# For Java: pre-parse fallback stdout once (not per testcase) to avoid O(n²) complexity
708697
java_fallback_stdout = None
@@ -763,13 +752,9 @@ def parse_test_xml(
763752
if test_file_name is None:
764753
if test_class_path:
765754
# TODO : This might not be true if the test is organized under a class
766-
logger.debug(f"[PARSE-XML] Resolving test_class_path={test_class_path} in base_dir={base_dir}")
767755
test_file_path = resolve_test_file_from_class_path(test_class_path, base_dir)
768756

769757
if test_file_path is None:
770-
logger.error(
771-
f"[PARSE-XML] ERROR: Could not resolve test_class_path={test_class_path}, base_dir={base_dir}"
772-
)
773758
logger.warning(f"Could not find the test for file name - {test_class_path} ")
774759
continue
775760
else:
@@ -782,15 +767,11 @@ def parse_test_xml(
782767
logger.warning(f"Could not find the test for file name - {test_file_path} ")
783768
continue
784769
# Try to match by instrumented file path first (for generated/instrumented tests)
785-
logger.debug(f"[PARSE-XML] Looking up test_type by instrumented_file_path: {test_file_path}")
786770
test_type = test_files.get_test_type_by_instrumented_file_path(test_file_path)
787-
logger.debug(f"[PARSE-XML] Lookup by instrumented path result: {test_type}")
788771
if test_type is None:
789772
# Fallback: try to match by original file path (for existing unit tests that were instrumented)
790773
# JUnit XML may reference the original class name, resolving to the original file path
791-
logger.debug(f"[PARSE-XML] Looking up test_type by original_file_path: {test_file_path}")
792774
test_type = test_files.get_test_type_by_original_file_path(test_file_path)
793-
logger.debug(f"[PARSE-XML] Lookup by original path result: {test_type}")
794775
if test_type is None:
795776
# Log registered paths for debugging
796777
registered_paths = [str(tf.instrumented_behavior_file_path) for tf in test_files.test_files]

0 commit comments

Comments
 (0)