Skip to content

Commit 4f550bb

Browse files
cfsmp3claude
authored andcommitted
fix: Include target_url in GitHub status for timed-out tests
When a test times out due to exceeding the maximum runtime limit, the GitHub status was set to ERROR but without a target_url. This made it impossible for users to click through to see what happened - they would just see "ERROR" with no link. Root cause: In delete_expired_instances(), update_status_on_github() was called without the target_url parameter, which resulted in GitHub displaying a null/empty URL. Fix: Build the target_url (using url_for with fallback for non-request context) and pass it to update_status_on_github() so users can navigate to the test page to see results even when a test times out. Discovered while investigating why CCExtractor/ccextractor#2007 Linux test showed ERROR on GitHub with no clickable link. Test #7736 had run for ~4 hours, executed 116 regression tests (105 failed), but was canceled due to time limit. The test page existed and showed results, but GitHub had no link to it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 603f340 commit 4f550bb

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

mod_ci/controllers.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,14 @@ def delete_expired_instances(compute, max_runtime, project, zone, db, repository
471471

472472
gh_commit = repository.get_commit(test.commit)
473473
if gh_commit is not None:
474-
update_status_on_github(gh_commit, Status.ERROR, message, f"CI - {platform_name}")
474+
# Build target_url so users can see test results
475+
from flask import url_for
476+
try:
477+
target_url = url_for('test.by_id', test_id=test_id, _external=True)
478+
except RuntimeError:
479+
# Outside of request context
480+
target_url = f"https://sampleplatform.ccextractor.org/test/{test_id}"
481+
update_status_on_github(gh_commit, Status.ERROR, message, f"CI - {platform_name}", target_url)
475482

476483
# Delete VM instance with tracking for verification
477484
from run import log

tests/test_ci/test_controllers.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,6 +1517,45 @@ def test_delete_expired_instances_db_commit_failure(
15171517
# Should continue to next instance after commit failure
15181518
mock_delete.assert_not_called()
15191519

1520+
@mock.patch('mod_ci.controllers.delete_instance_with_tracking')
1521+
@mock.patch('mod_ci.controllers.update_status_on_github')
1522+
@mock.patch('mod_ci.controllers.safe_db_commit')
1523+
@mock.patch('mod_ci.controllers.is_instance_testing')
1524+
@mock.patch('run.log')
1525+
def test_delete_expired_instances_includes_target_url(
1526+
self, mock_log, mock_is_testing, mock_safe_commit,
1527+
mock_update_github, mock_delete_tracking):
1528+
"""Test delete_expired_instances includes target_url in GitHub status."""
1529+
from mod_ci.controllers import delete_expired_instances
1530+
1531+
mock_is_testing.return_value = True
1532+
mock_safe_commit.return_value = True
1533+
mock_delete_tracking.return_value = {'name': 'op-123'}
1534+
1535+
# Create a mock compute service with expired instance
1536+
mock_compute = MagicMock()
1537+
mock_compute.instances().list().execute.return_value = {
1538+
'items': [{
1539+
'name': 'linux-1',
1540+
'creationTimestamp': '2020-01-01T00:00:00.000+00:00'
1541+
}]
1542+
}
1543+
1544+
mock_repo = MagicMock()
1545+
mock_gh_commit = MagicMock()
1546+
mock_repo.get_commit.return_value = mock_gh_commit
1547+
1548+
delete_expired_instances(
1549+
mock_compute, 60, 'project', 'zone', g.db, mock_repo)
1550+
1551+
# Verify update_status_on_github was called with target_url
1552+
mock_update_github.assert_called_once()
1553+
call_args = mock_update_github.call_args
1554+
# Check that target_url (5th argument) contains the test ID
1555+
self.assertEqual(len(call_args[0]), 5) # 5 positional args
1556+
target_url = call_args[0][4]
1557+
self.assertIn('/test/1', target_url)
1558+
15201559
@mock.patch('github.Github.get_repo')
15211560
@mock.patch('requests.get', side_effect=mock_api_request_github)
15221561
@mock.patch('mod_ci.controllers.inform_mailing_list')

0 commit comments

Comments
 (0)