Files
reelbox/tool/player_controls_test.py

84 lines
3.9 KiB
Python

#!/usr/bin/env python3
"""Run deterministic real Kotlin controls tests and optional Android SDK compilation.
Uses cached Kotlin jars, Android 36 and LibVLC 3.7.7; no downloads or Gradle.
All compiler invocations share the repository tooling lock.
"""
import argparse
import fcntl
import os
from pathlib import Path
import subprocess
import tempfile
ROOT = Path(__file__).resolve().parents[1]
SRC = ROOT / 'android/app/src/main/kotlin/org/reelbox/reelbox'
TEST = ROOT / 'android/app/src/test/kotlin/org/reelbox/reelbox'
CACHE = Path.home() / '.gradle/caches/modules-2/files-2.1'
SCRATCH = Path('/root/.hermes/cache/scratch')
def compiler_jars():
jars = []
for artifact, version in [
('org.jetbrains.kotlin/kotlin-compiler-embeddable', '2.4.0'),
('org.jetbrains.kotlin/kotlin-stdlib', '2.4.0'),
('org.jetbrains.kotlin/kotlin-script-runtime', '2.4.0'),
('org.jetbrains.kotlin/kotlin-reflect', '*'),
('org.jetbrains.intellij.deps/trove4j', '*'),
('org.jetbrains.kotlinx/kotlinx-coroutines-core-jvm', '*'),
('org.jetbrains/annotations', '*'),
]:
matches = sorted((CACHE / artifact).glob(version + '/*/*.jar'))
if matches:
jars.append(str(matches[-1]))
elif version != '*':
raise RuntimeError(f'Missing cached compiler dependency: {artifact}:{version}')
return jars
def compile_sources(jars, sources, classpath, out):
subprocess.run([
'java', '-Xmx320m', '-XX:MaxMetaspaceSize=192m', '-XX:+UseSerialGC',
f'-Djava.io.tmpdir={SCRATCH}', '-cp', os.pathsep.join(jars),
'org.jetbrains.kotlin.cli.jvm.K2JVMCompiler', '-jvm-target', '17',
'-no-stdlib', '-no-reflect', '-classpath', os.pathsep.join(classpath),
'-d', str(out), *map(str, sources),
], cwd=ROOT, check=True, timeout=180)
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--native', action='store_true', help='Also compile actual native player sources')
args = parser.parse_args()
print('Waiting for repository tooling lock', flush=True)
with (ROOT / '.tooling.lock').open('a') as lock:
fcntl.flock(lock, fcntl.LOCK_EX)
print('Repository tooling lock acquired', flush=True)
jars = compiler_jars()
with tempfile.TemporaryDirectory(prefix='player-controls-', dir=SCRATCH) as temp:
out = Path(temp) / 'state'
compile_sources(jars, [SRC / 'PlayerControlsState.kt', TEST / 'PlayerControlsStateTest.kt'], jars, out)
subprocess.run(['java', '-Xmx96m', '-cp', os.pathsep.join([str(out), *jars]),
'org.reelbox.reelbox.tests.PlayerControlsStateTestKt'],
check=True, cwd=ROOT, timeout=30)
if args.native:
deps = [
'/root/developer-tools/android/platforms/android-36/android.jar',
'/root/.hermes/cache/scratch/reelbox-vlc-api/classes.jar',
'/root/developer-tools/flutter/bin/cache/artifacts/engine/android-arm64-release/flutter.jar',
str(ROOT / 'build/app/tmp/kotlin-classes/release'),
]
deps += map(str, (Path.home() / '.gradle/caches/9.3.1/transforms').glob('*/transformed/core-1.16.0-api.jar'))
deps += map(str, (CACHE / 'androidx.lifecycle/lifecycle-common-jvm').glob('*/*/*.jar'))
sources = [SRC / name for name in [
'NativeUrlPolicy.kt', 'NativePlayerPolicy.kt', 'NativeFileIntents.kt',
'PlayerControlsState.kt', 'PlayerOverlayView.kt', 'VlcPlayerActivity.kt', 'MainActivity.kt',
]]
compile_sources(jars, sources, [*jars, *deps], Path(temp) / 'native')
print('Native player compilation PASS: actual Android 36 / LibVLC 3.7.7 SDKs', flush=True)
if __name__ == '__main__':
main()