1
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class EngineBuildTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.temporary = tempfile.TemporaryDirectory()
|
||||
self.root = Path(self.temporary.name)
|
||||
engine = Path(__file__).resolve().parents[1]
|
||||
for name in ['engine-fingerprint.sh', 'ensure-engine.sh']:
|
||||
shutil.copyfile(engine / name, self.root / name)
|
||||
for name in ['engine.py', 'exports.py', 'requirements.txt', 'requirements.lock.txt',
|
||||
'personal-expense-template.xlsx', 'helper.entitlements']:
|
||||
(self.root / name).write_text('fixture\n')
|
||||
self.binary = self.root / 'dist/receipt-engine-helper.app/Contents/MacOS/receipt-engine-helper'
|
||||
(self.root / 'build-engine.sh').write_text('''#!/bin/bash
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")"
|
||||
echo build >> builds.log
|
||||
mkdir -p dist/receipt-engine-helper.app/Contents/MacOS
|
||||
printf 'fixture engine\\n' > dist/receipt-engine-helper.app/Contents/MacOS/receipt-engine-helper
|
||||
chmod +x dist/receipt-engine-helper.app/Contents/MacOS/receipt-engine-helper
|
||||
SOURCE_HASH="$(bash engine-fingerprint.sh)"
|
||||
BINARY_HASH="$(shasum -a 256 dist/receipt-engine-helper.app/Contents/MacOS/receipt-engine-helper | cut -d ' ' -f 1)"
|
||||
printf '%s\\n%s\\n' "$SOURCE_HASH" "$BINARY_HASH" > dist/receipt-engine-helper.source.sha256
|
||||
''')
|
||||
|
||||
def tearDown(self):
|
||||
self.temporary.cleanup()
|
||||
|
||||
def ensure(self):
|
||||
return subprocess.run(['bash', str(self.root / 'ensure-engine.sh')],
|
||||
capture_output=True, text=True, timeout=20)
|
||||
|
||||
def build_count(self):
|
||||
return len((self.root / 'builds.log').read_text().splitlines())
|
||||
|
||||
def test_missing_engine_builds_and_unchanged_engine_is_reused(self):
|
||||
self.assertEqual(self.ensure().returncode, 0)
|
||||
self.assertEqual(self.build_count(), 1)
|
||||
self.assertEqual(self.ensure().returncode, 0)
|
||||
self.assertEqual(self.build_count(), 1)
|
||||
|
||||
def test_changed_sources_rebuild_even_when_timestamp_is_unchanged(self):
|
||||
self.assertEqual(self.ensure().returncode, 0)
|
||||
source = self.root / 'exports.py'
|
||||
original = source.stat()
|
||||
source.write_text('new grouping implementation\n')
|
||||
os.utime(source, ns=(original.st_atime_ns, original.st_mtime_ns))
|
||||
self.assertEqual(self.ensure().returncode, 0)
|
||||
self.assertEqual(self.build_count(), 2)
|
||||
|
||||
def test_replaced_binary_rebuilds(self):
|
||||
self.assertEqual(self.ensure().returncode, 0)
|
||||
self.binary.write_text('old engine\n')
|
||||
self.assertEqual(self.ensure().returncode, 0)
|
||||
self.assertEqual(self.build_count(), 2)
|
||||
|
||||
def test_missing_stamp_rebuilds(self):
|
||||
self.assertEqual(self.ensure().returncode, 0)
|
||||
(self.root / 'dist/receipt-engine-helper.source.sha256').unlink()
|
||||
self.assertEqual(self.ensure().returncode, 0)
|
||||
self.assertEqual(self.build_count(), 2)
|
||||
|
||||
def test_failed_rebuild_does_not_accept_old_engine(self):
|
||||
self.assertEqual(self.ensure().returncode, 0)
|
||||
(self.root / 'build-engine.sh').write_text('exit 17\n')
|
||||
self.assertEqual(self.ensure().returncode, 17)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user