Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion mod_ci/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,14 @@ def delete_expired_instances(compute, max_runtime, project, zone, db, repository

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

# Delete VM instance with tracking for verification
from run import log
Expand Down
39 changes: 39 additions & 0 deletions tests/test_ci/test_controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1517,6 +1517,45 @@ def test_delete_expired_instances_db_commit_failure(
# Should continue to next instance after commit failure
mock_delete.assert_not_called()

@mock.patch('mod_ci.controllers.delete_instance_with_tracking')
@mock.patch('mod_ci.controllers.update_status_on_github')
@mock.patch('mod_ci.controllers.safe_db_commit')
@mock.patch('mod_ci.controllers.is_instance_testing')
@mock.patch('run.log')
def test_delete_expired_instances_includes_target_url(
self, mock_log, mock_is_testing, mock_safe_commit,
mock_update_github, mock_delete_tracking):
"""Test delete_expired_instances includes target_url in GitHub status."""
from mod_ci.controllers import delete_expired_instances

mock_is_testing.return_value = True
mock_safe_commit.return_value = True
mock_delete_tracking.return_value = {'name': 'op-123'}

# Create a mock compute service with expired instance
mock_compute = MagicMock()
mock_compute.instances().list().execute.return_value = {
'items': [{
'name': 'linux-1',
'creationTimestamp': '2020-01-01T00:00:00.000+00:00'
}]
}

mock_repo = MagicMock()
mock_gh_commit = MagicMock()
mock_repo.get_commit.return_value = mock_gh_commit

delete_expired_instances(
mock_compute, 60, 'project', 'zone', g.db, mock_repo)

# Verify update_status_on_github was called with target_url
mock_update_github.assert_called_once()
call_args = mock_update_github.call_args
# Check that target_url (5th argument) contains the test ID
self.assertEqual(len(call_args[0]), 5) # 5 positional args
target_url = call_args[0][4]
self.assertIn('/test/1', target_url)

@mock.patch('github.Github.get_repo')
@mock.patch('requests.get', side_effect=mock_api_request_github)
@mock.patch('mod_ci.controllers.inform_mailing_list')
Expand Down