Files
ossm-configurator/tests/test_check_updates.py

241 lines
6.7 KiB
Python

#!/usr/bin/env python3
"""
Tests for check_updates.py
"""
import json
import sys
import tempfile
from pathlib import Path
from unittest.mock import patch
import pytest
import responses
# Import the module
sys.path.insert(0, str(Path(__file__).parent.parent / 'scripts'))
from check_updates import GitHubAPI, check_entry
@pytest.fixture
def github_api():
"""Create a GitHubAPI instance for testing."""
return GitHubAPI(token='test-token')
@pytest.fixture
def sample_manifest_entry():
"""Sample manifest entry for testing."""
return {
'id': 'test-entry',
'source_repo': 'owner/repo',
'source_path': 'path/to/file.stl',
'source_ref': 'main',
'pinned_sha': 'pinned-sha-123',
'pinned_raw_url': 'https://raw.githubusercontent.com/owner/repo/pinned-sha-123/path/to/file.stl',
'local_path': 'vendor/owner-repo/path/to/file.stl',
'checksum_sha256': 'abc123',
'last_checked': '2024-01-01T00:00:00Z',
'upstream_latest_sha': None,
'status': 'unknown',
'license': None
}
@responses.activate
def test_check_entry_up_to_date(github_api, sample_manifest_entry):
"""Test checking an entry that is up-to-date."""
owner = 'owner'
repo = 'repo'
path = 'path/to/file.stl'
ref = 'main'
pinned_sha = 'pinned-sha-123'
# Mock commits API - return same SHA as pinned
responses.add(
responses.GET,
f'https://api.github.com/repos/{owner}/{repo}/commits',
json=[{'sha': pinned_sha}],
match=[responses.matchers.query_param_matcher({
'path': path,
'sha': ref,
'per_page': 1
})]
)
updated_entry = check_entry(sample_manifest_entry, github_api)
assert updated_entry['status'] == 'up-to-date'
assert updated_entry['upstream_latest_sha'] == pinned_sha
assert updated_entry['last_checked'] is not None
@responses.activate
def test_check_entry_out_of_date(github_api, sample_manifest_entry):
"""Test checking an entry that is out-of-date."""
owner = 'owner'
repo = 'repo'
path = 'path/to/file.stl'
ref = 'main'
pinned_sha = 'pinned-sha-123'
latest_sha = 'latest-sha-456'
# Mock commits API - return different SHA
responses.add(
responses.GET,
f'https://api.github.com/repos/{owner}/{repo}/commits',
json=[{'sha': latest_sha}],
match=[responses.matchers.query_param_matcher({
'path': path,
'sha': ref,
'per_page': 1
})]
)
updated_entry = check_entry(sample_manifest_entry, github_api)
assert updated_entry['status'] == 'out-of-date'
assert updated_entry['upstream_latest_sha'] == latest_sha
assert updated_entry['pinned_sha'] == pinned_sha # Pinned SHA unchanged
assert updated_entry['last_checked'] is not None
@responses.activate
def test_check_entry_no_pinned_sha(github_api):
"""Test checking an entry with no pinned SHA."""
entry = {
'id': 'test-entry',
'source_repo': 'owner/repo',
'source_path': 'path/to/file.stl',
'source_ref': 'main',
'pinned_sha': None,
'status': 'unknown'
}
owner = 'owner'
repo = 'repo'
path = 'path/to/file.stl'
ref = 'main'
latest_sha = 'latest-sha-456'
responses.add(
responses.GET,
f'https://api.github.com/repos/{owner}/{repo}/commits',
json=[{'sha': latest_sha}],
match=[responses.matchers.query_param_matcher({
'path': path,
'sha': ref,
'per_page': 1
})]
)
updated_entry = check_entry(entry, github_api)
assert updated_entry['status'] == 'unknown'
assert updated_entry['upstream_latest_sha'] == latest_sha
@responses.activate
def test_check_entry_api_error(github_api, sample_manifest_entry):
"""Test handling of API errors."""
owner = 'owner'
repo = 'repo'
path = 'path/to/file.stl'
ref = 'main'
# Mock API error
responses.add(
responses.GET,
f'https://api.github.com/repos/{owner}/{repo}/commits',
status=500
)
updated_entry = check_entry(sample_manifest_entry, github_api)
assert updated_entry['status'] == 'unknown'
assert updated_entry['upstream_latest_sha'] is None
@responses.activate
def test_check_entry_file_not_found(github_api, sample_manifest_entry):
"""Test handling when file doesn't exist at ref."""
owner = 'owner'
repo = 'repo'
path = 'path/to/file.stl'
ref = 'main'
# Mock empty commits response (file doesn't exist)
responses.add(
responses.GET,
f'https://api.github.com/repos/{owner}/{repo}/commits',
json=[],
match=[responses.matchers.query_param_matcher({
'path': path,
'sha': ref,
'per_page': 1
})]
)
updated_entry = check_entry(sample_manifest_entry, github_api)
# Should still update last_checked but status might be unknown
assert updated_entry['last_checked'] is not None
def test_github_api_get_latest_commit_sha(github_api):
"""Test getting latest commit SHA."""
owner = 'owner'
repo = 'repo'
path = 'file.stl'
ref = 'main'
expected_sha = 'commit-sha-789'
with responses.RequestsMock() as rsps:
rsps.add(
responses.GET,
f'https://api.github.com/repos/{owner}/{repo}/commits',
json=[{'sha': expected_sha}],
match=[responses.matchers.query_param_matcher({
'path': path,
'sha': ref,
'per_page': 1
})]
)
sha = github_api.get_latest_commit_sha(owner, repo, path, ref)
assert sha == expected_sha
def test_github_api_get_latest_commit_sha_ref_is_sha(github_api):
"""Test when ref is already a SHA."""
owner = 'owner'
repo = 'repo'
path = 'file.stl'
ref = 'a' * 40 # Valid SHA format
# Should return the ref as-is if it's already a SHA
sha = github_api.get_latest_commit_sha(owner, repo, path, ref)
# Actually, the function tries to get commits first, so it will make an API call
# But if ref is a SHA, it should work
with responses.RequestsMock() as rsps:
rsps.add(
responses.GET,
f'https://api.github.com/repos/{owner}/{repo}/commits',
json=[{'sha': ref}],
match=[responses.matchers.query_param_matcher({
'path': path,
'sha': ref,
'per_page': 1
})]
)
sha = github_api.get_latest_commit_sha(owner, repo, path, ref)
assert sha == ref
if __name__ == '__main__':
pytest.main([__file__, '-v'])