Files
modulus/tests/test_artifacts.py
T
khodowany fb93acca1a
publish / publish (push) Successful in 11m4s
Cleanup
2026-10-08 01:31:14 -05:00

57 lines
3.4 KiB
Python

import modulus.build_context
import os
import pathlib
import tempfile
import unittest
import unittest.mock
import urllib.error
import modulus.artifacts
import modulus.config
class ArtifactTests(unittest.TestCase):
def setUp(self):
self.temporary = tempfile.TemporaryDirectory()
self.addCleanup(self.temporary.cleanup)
self.root = pathlib.Path(self.temporary.name)
config = modulus.config.normalize({'package': {'name': 'example', 'artifact': {'enabled': True, 'targets': ['arm_64_gcc12_release']}}})
self.context = modulus.build_context.build_context(self.root, config)
self.directory = self.root / 'build/packages'
self.directory.mkdir(parents=True)
self.archive = self.directory / modulus.artifacts.archive_name('example', 'arm_64_gcc12_release')
self.archive.write_bytes(b'package')
self.checksum = modulus.artifacts.write_checksum(self.archive)
self.enterContext(unittest.mock.patch.dict(os.environ, {'PACKAGE_REGISTRY_USER': 'test', 'PACKAGE_REGISTRY_TOKEN': 'secret'}))
def test_discovery_uses_the_same_names_as_creation(self):
self.assertEqual(self.archive.name, 'example_arm_64_gcc12_release.tar.gz')
self.assertEqual(modulus.artifacts.discover_artifacts(self.directory, 'example', ['arm_64_gcc12_release']), [self.archive, self.checksum])
def test_missing_or_invalid_checksums_never_touch_registry(self):
with unittest.mock.patch.object(modulus.artifacts, 'request') as request:
self.archive.write_bytes(b'corrupt')
with self.assertRaisesRegex(SystemExit, 'checksum mismatch'):
modulus.artifacts.main(self.context, [])
self.checksum.unlink()
with self.assertRaisesRegex(SystemExit, 'missing artifact'):
modulus.artifacts.main(self.context, [])
request.assert_not_called()
def test_replacement_and_cleanup_are_ordered_after_validation(self):
events = []
with unittest.mock.patch.object(modulus.artifacts, 'list_versions', return_value=['latest', 'old']), \
unittest.mock.patch.object(modulus.artifacts, 'delete_version', side_effect=lambda *args: events.append(('delete', args[-2]))), \
unittest.mock.patch.object(modulus.artifacts, 'upload_file', side_effect=lambda *args: events.append(('upload', args[2].name))):
self.assertEqual(modulus.artifacts.main(self.context, []), 0)
self.assertEqual(events, [('delete', 'latest'), ('upload', self.archive.name), ('upload', self.checksum.name), ('delete', 'old')])
def test_failed_upload_does_not_delete_other_slots(self):
with unittest.mock.patch.object(modulus.artifacts, 'list_versions', return_value=['latest', 'old']), \
unittest.mock.patch.object(modulus.artifacts, 'delete_version') as delete, \
unittest.mock.patch.object(modulus.artifacts, 'upload_file', side_effect=SystemExit('upload failed')):
with self.assertRaisesRegex(SystemExit, 'upload failed'):
modulus.artifacts.main(self.context, [])
self.assertEqual([call.args[-2] for call in delete.call_args_list], ['latest'])
def test_request_errors_and_credentials_are_not_logged(self):
for code in (401, 500):
with unittest.mock.patch.object(modulus.artifacts.urllib.request, 'urlopen', side_effect=urllib.error.HTTPError('https://example.test', code, 'failed', {}, None)):
with self.assertRaises(SystemExit) as caught:
modulus.artifacts.request('PUT', 'https://example.test', 'secret')
self.assertNotIn('secret', str(caught.exception))