Fix code coverage data by removing hits from old binaries (#12635)

* Fix code coverage data by removing hits from old binaries

Otherwise, the data are counting from old binaries that may have different lines
and thus inflating the total number of probes.

* Address a review comment
This commit is contained in:
Jingyu Zhou
2026-01-13 16:44:36 -08:00
committed by GitHub
parent 5614ae64aa
commit 3b574c4e9b
2 changed files with 12 additions and 8 deletions

View File

@@ -394,6 +394,7 @@ class TestRun:
expected_unseed=self.expected_unseed,
will_restart=will_restart,
long_running=config.long_running,
is_old_binary=False, # will be set after the run
)
self.run_time: int = 0
self.success = self.run()
@@ -539,6 +540,8 @@ class TestRun:
err_out: str = ""
try:
out_bytes, err_bytes = process.communicate(timeout=timeout)
# Check if we're running with an old binary (restarting test with non-current binary)
self.is_old_binary = (self.binary != config.binary)
# Try normal UTF-8 decode first
try:
out = out_bytes.decode('utf-8') if out_bytes else ""
@@ -548,9 +551,7 @@ class TestRun:
decode_error_occurred = True
out = out_bytes.decode('utf-8', errors='replace') if out_bytes else ""
err_out = err_bytes.decode('utf-8', errors='replace') if err_bytes else ""
# Check if we're running with an old binary (restarting test with non-current binary)
is_old_binary = self.binary != config.binary
if is_old_binary:
if self.is_old_binary:
print(f"WARNING: UnicodeDecodeError at position {decode_ex.start} - invalid byte {hex(out_bytes[decode_ex.start])}. Output decoded with replacement. (Old binary - not failing test)", file=sys.stderr)
# Don't fail tests for old binaries - we can't fix them
else:
@@ -575,16 +576,16 @@ class TestRun:
self.summary.was_killed = did_kill
self.summary.valgrind_out_file = valgrind_file
self.summary.error_out = err_out
self.summary.is_old_binary = self.is_old_binary
# Add diagnostic info if decode error occurred (BEFORE summarize calculates Ok attribute)
if decode_error_occurred:
is_old_binary = self.binary != config.binary
decode_error_node = SummaryTree("UnicodeDecodeError")
# Use Severity 30 (warning) for old binaries, 40 (error) for current binary
decode_error_node.attributes["Severity"] = "30" if is_old_binary else "40"
decode_error_node.attributes["Severity"] = "30" if self.is_old_binary else "40"
decode_error_node.attributes["Message"] = "fdbserver output contained invalid UTF-8 bytes. Output decoded with replacement characters."
decode_error_node.attributes["Position"] = "Check fdbserver.stdout for <20> characters"
if is_old_binary:
if self.is_old_binary:
decode_error_node.attributes["Note"] = "Old binary - binary output tolerated"
self.summary.out.append(decode_error_node)

View File

@@ -326,6 +326,7 @@ class Summary:
error_out: str = None,
will_restart: bool = False,
long_running: bool = False,
is_old_binary: bool = False,
):
self.binary = binary
self.runtime: float = runtime
@@ -354,6 +355,7 @@ class Summary:
self.negative_test_success = False
self.max_trace_time = -1
self.max_trace_time_type = "None"
self.is_old_binary: bool = is_old_binary
if uid is not None:
self.out.attributes["TestUID"] = str(uid)
@@ -387,7 +389,8 @@ class Summary:
self.out.append(child)
return
self.summarize_files(trace_files[0])
if config.joshua_dir is not None:
# Skip write_coverage for old binaries in restarting tests
if config.joshua_dir is not None and not self.is_old_binary:
import test_harness.fdb
test_harness.fdb.write_coverage(