Skip to content

Commit 2e4b068

Browse files
committed
fix(ci): use get_test_results as single source of truth for commit status
1 parent 1062055 commit 2e4b068

1 file changed

Lines changed: 17 additions & 32 deletions

File tree

mod_ci/controllers.py

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
from pymysql.err import IntegrityError
2929
from sqlalchemy import and_, func, select
3030
from sqlalchemy.sql import label
31-
from sqlalchemy.sql.functions import count
3231
from werkzeug.utils import secure_filename
3332

3433
from database import DeclEnum, create_session
@@ -2276,14 +2275,16 @@ def start_ci():
22762275
return json.dumps({'msg': 'EOL'})
22772276

22782277

2279-
def update_build_badge(status, test) -> None:
2278+
def update_build_badge(status, test, test_results=None) -> None:
22802279
"""
22812280
Build status badge for current test to be displayed on sample-platform.
22822281
22832282
:param status: current testing status
22842283
:type status: str
22852284
:param test: current commit that is tested
22862285
:type test: Test
2286+
:param test_results: pre-computed results from get_test_results; if None, fetched internally
2287+
:type test_results: list | None
22872288
:return: null
22882289
:rtype: null
22892290
"""
@@ -2294,7 +2295,8 @@ def update_build_badge(status, test) -> None:
22942295
shutil.copyfile(original_location, build_status_location)
22952296
g.log.info('Build badge updated successfully!')
22962297

2297-
test_results = get_test_results(test)
2298+
if test_results is None:
2299+
test_results = get_test_results(test)
22982300
test_ids_to_update = []
22992301
for category_results in test_results:
23002302
test_ids_to_update.extend([test['test'].id for test in category_results['tests'] if not test['error']])
@@ -2429,46 +2431,29 @@ def progress_type_request(log, test, test_id, request) -> bool:
24292431
message = 'Tests aborted due to an error; please check'
24302432

24312433
elif status == TestStatus.completed:
2432-
# Determine if success or failure
2433-
# It fails if any of these happen:
2434-
# - A crash (unexpected exit code)
2435-
# - A not None value on the "got" of a TestResultFile (
2436-
# meaning the hashes do not match)
2437-
crashes = g.db.query(count(TestResult.exit_code)).filter(
2438-
and_(
2439-
TestResult.test_id == test.id,
2440-
TestResult.exit_code != TestResult.expected_rc
2441-
)).scalar()
2442-
results_zero_rc = select(RegressionTest.id).filter(
2443-
RegressionTest.expected_rc == 0
2444-
)
2445-
results = g.db.query(count(TestResultFile.got)).filter(
2446-
and_(
2447-
TestResultFile.test_id == test.id,
2448-
TestResultFile.regression_test_id.in_(
2449-
results_zero_rc.select()
2450-
),
2451-
TestResultFile.got.isnot(None)
2452-
)
2453-
).scalar()
2454-
log.debug(f'[Test: {test.id}] Test completed: {crashes} crashes, {results} results')
2455-
if crashes > 0 or results > 0:
2434+
# Use get_test_results as the single source of truth for pass/fail.
2435+
# The old dual-query (crash count + TestResultFile.got count) would silently
2436+
# mark a test SUCCESS when a TestResultFile row was never created (e.g. the VM
2437+
# never wrote output), because COUNT(got IS NOT NULL) returns 0 and the check
2438+
# passes. get_test_results correctly treats a missing row as an error.
2439+
test_results = get_test_results(test)
2440+
has_error = any(category['error'] for category in test_results)
2441+
log.debug(f'[Test: {test.id}] Test completed: has_error={has_error}')
2442+
if has_error:
24562443
state = Status.FAILURE
24572444
message = 'Not all tests completed successfully, please check'
2458-
24592445
else:
24602446
state = Status.SUCCESS
24612447
message = 'Tests completed'
24622448
if test.test_type == TestType.pull_request:
24632449
state = comment_pr(test)
2464-
# Update message to match the state returned by comment_pr()
2465-
# comment_pr() uses different logic: it returns SUCCESS if there are
2466-
# no NEW failures compared to master (pre-existing failures are OK)
2450+
# comment_pr() returns SUCCESS only if there are no NEW failures
2451+
# compared to master (pre-existing failures are acceptable).
24672452
if state == Status.SUCCESS:
24682453
message = 'All tests passed'
24692454
else:
24702455
message = 'Not all tests completed successfully, please check'
2471-
update_build_badge(state, test)
2456+
update_build_badge(state, test, test_results)
24722457

24732458
else:
24742459
message = progress.message

0 commit comments

Comments
 (0)