Some checks failed
Dev CI / Backend — Lint (push) Failing after 1m5s
Dev CI / Backend — Unit Tests (push) Has been skipped
Dev CI / Security gate (push) Failing after 1m20s
Dev CI / Frontend — Lint & Type-check (push) Successful in 1m46s
Dev CI / Frontend — Unit Tests (push) Successful in 1m21s
Dev CI / Notify Failure (push) Has been skipped
84 lines
3.9 KiB
Python
84 lines
3.9 KiB
Python
"""Offline architecture/PATH regressions for Gitea Linux runners."""
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
import tempfile
|
|
import unittest
|
|
|
|
SCRIPTS = Path(__file__).resolve().parent
|
|
|
|
|
|
class ToolSetup(unittest.TestCase):
|
|
def setUp(self):
|
|
self.temp = tempfile.TemporaryDirectory()
|
|
self.addCleanup(self.temp.cleanup)
|
|
self.root = Path(self.temp.name)
|
|
self.bin = self.root / 'bin'
|
|
self.bin.mkdir()
|
|
self.env = dict(os.environ, PATH=f'{self.bin}:{os.environ["PATH"]}',
|
|
FAKE_ARCH='aarch64', FAKE_OS='Linux',
|
|
RUNNER_TEMP=str(self.root), RUNNER_TOOL_CACHE=str(self.root / 'cache'),
|
|
GITHUB_PATH=str(self.root / 'path'), GITHUB_ENV=str(self.root / 'env'))
|
|
self.mock(self.bin / 'uname', 'if [ "$1" = -s ]; then echo "$FAKE_OS"; else echo "$FAKE_ARCH"; fi\n')
|
|
|
|
def mock(self, path, body):
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
path.write_text('#!/bin/sh\n' + body)
|
|
path.chmod(0o755)
|
|
|
|
def run_script(self, script, *args):
|
|
return subprocess.run(['bash', str(SCRIPTS / script), *args], env=self.env,
|
|
capture_output=True, text=True)
|
|
|
|
def test_all_native_tool_urls_and_checksums(self):
|
|
for arch, suffix in [('aarch64', 'arm64'), ('x86_64', 'amd64')]:
|
|
self.env['FAKE_ARCH'] = arch
|
|
for tool in ['trivy', 'actionlint', 'hcloud']:
|
|
with self.subTest(arch=arch, tool=tool):
|
|
result = self.run_script('install-tool.sh', tool, '--print-source')
|
|
self.assertEqual(result.returncode, 0, result.stderr)
|
|
url, checksum = result.stdout.splitlines()
|
|
expected = 'Linux-ARM64' if tool == 'trivy' and suffix == 'arm64' else (
|
|
'Linux-64bit' if tool == 'trivy' else suffix)
|
|
self.assertIn(expected, url)
|
|
self.assertRegex(checksum, r'^[0-9a-f]{64}$')
|
|
|
|
def test_unsupported_architecture_rejected_before_download(self):
|
|
self.env['FAKE_ARCH'] = 'armv7l'
|
|
self.assertNotEqual(self.run_script('install-tool.sh', 'trivy', '--print-source').returncode, 0)
|
|
|
|
def test_non_linux_rejected(self):
|
|
self.env['FAKE_OS'] = 'Darwin'
|
|
self.assertNotEqual(self.run_script('install-tool.sh', 'trivy', '--print-source').returncode, 0)
|
|
|
|
def test_wrong_checksum_cannot_install_or_activate_binary(self):
|
|
self.mock(self.bin / 'curl', 'exit 0\n')
|
|
self.mock(self.bin / 'sha256sum', 'exit 1\n')
|
|
self.mock(self.bin / 'tar', f'touch "{self.root}/extracted"\n')
|
|
self.assertNotEqual(self.run_script('install-tool.sh', 'trivy').returncode, 0)
|
|
self.assertFalse((self.root / 'extracted').exists())
|
|
self.assertFalse((self.root / 'path').exists())
|
|
|
|
def test_node22_takes_precedence_over_preinstalled_node18(self):
|
|
self.mock(self.bin / 'node', 'echo v18.20.8\nexit 1\n')
|
|
self.mock(self.bin / 'npm', 'echo old-npm\nexit 1\n')
|
|
for version in ['22.9.0', '22.23.2']:
|
|
node_bin = self.root / 'cache' / 'node' / version / 'arm64' / 'bin'
|
|
self.mock(node_bin / 'node', f'if [ "$1" = -e ]; then exit 0; fi\necho v{version}\n')
|
|
self.mock(node_bin / 'npm', 'echo 10.9.0\n')
|
|
result = self.run_script('activate-node.sh')
|
|
self.assertEqual(result.returncode, 0, result.stderr)
|
|
self.assertIn('v22.23.2', result.stdout)
|
|
self.assertNotIn('v18.', result.stdout)
|
|
self.assertIn('/22.23.2/arm64/bin', (self.root / 'path').read_text())
|
|
self.assertTrue((self.root / 'env').read_text().startswith('PATH='))
|
|
|
|
def test_missing_native_node22_fails(self):
|
|
wrong_arch = self.root / 'cache' / 'node' / '22.23.2' / 'x64' / 'bin'
|
|
self.mock(wrong_arch / 'node', 'exit 0\n')
|
|
self.assertNotEqual(self.run_script('activate-node.sh').returncode, 0)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|