Source code for batools.spinoff._test

# Released under the MIT License. See LICENSE for details.
#
"""Tests for spinoff."""

from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    pass


[docs] def spinoff_test(args: list[str]) -> None: """High level test run command; accepts args and raises CleanErrors.""" # pylint: disable=too-many-locals # pylint: disable=too-many-branches # pylint: disable=too-many-statements import os import subprocess from efro.util import extract_flag from efro.terminal import Clr from efro.error import CleanError from batools.featureset import FeatureSet from efrotools.project import getprojectconfig submodule_parent = extract_flag(args, '--submodule-parent') shared_test_parent = extract_flag(args, '--shared-test-parent') if submodule_parent and shared_test_parent: raise CleanError( "spinoff-test: can't pass both submodule parent" ' and shared test parent.' ) public = getprojectconfig(Path('.'))['public'] if shared_test_parent and public: raise CleanError('--shared-test-parent not available in public repo.') # A spinoff symlink means we're a spun-off project. if os.path.islink('tools/spinoff'): raise CleanError( 'This must be run in a src project; this appears to be a dst.' ) if len(args) != 1: raise CleanError('Expected 1 arg.') featuresets = {fs.name: fs for fs in FeatureSet.get_all_for_project('.')} testtype = args[0] assert testtype if testtype in featuresets: path = f'build/spinofftest/{testtype}' print( f'{Clr.BLD}Running spinoff test{Clr.RST}' f" {Clr.SBLU}{Clr.BLD}'{testtype}'{Clr.RST}" f' {Clr.BLD}in{Clr.RST}' f" {Clr.BLU}'{path}'{Clr.RST}" f'{Clr.BLD}...{Clr.RST}', flush=True, ) # Normally we spin the project off from where we currently # are, but for cloud builds we may want to use a dedicated # shared source instead. (since we need a git managed source # we need to pull *something* fresh from git instead of just # using the files that were synced up by cloudshell). # Here we make sure that shared source is up to date. spinoff_src = '.' spinoff_path = path if shared_test_parent: spinoff_src = 'build/spinoff_shared_test_parent' # Need an abs target path since we change cwd in this case. spinoff_path = os.path.abspath(path) if bool(False): print('TEMP BLOWING AWAY') subprocess.run(['rm', '-rf', spinoff_src], check=True) if os.path.exists(spinoff_src): print( 'Pulling latest spinoff_shared_test_parent...', flush=True, ) subprocess.run( ['git', 'pull', '--ff-only'], check=True, cwd=spinoff_src, ) else: os.makedirs(spinoff_src, exist_ok=True) cmd = [ 'git', 'clone', 'git@github.com:efroemling/ballistica-internal.git', spinoff_src, ] print( f'{Clr.BLU}Creating spinoff shared test parent' f" at '{spinoff_src}' with command {cmd}...{Clr.RST}" ) subprocess.run( cmd, check=True, ) # If the spinoff project already exists and is submodule-based, # bring the submodule up to date. if os.path.exists(path): if bool(False): subprocess.run(['rm', '-rf', path], check=True) submpath = os.path.join(path, 'submodules/ballistica') if os.path.exists(submpath): print( f'{Clr.BLU}Pulling latest parent submodule' f' for existing test setup...{Clr.RST}', flush=True, ) subprocess.run( f'cd "{submpath}" && git checkout main && git pull', shell=True, check=True, ) else: # No spinoff project there yet; create it. cmd = [ './tools/spinoff', 'create', 'SpinoffTest', spinoff_path, '--featuresets', testtype, ] + (['--submodule-parent'] if submodule_parent else []) # Show the spinoff command we'd use here. print(Clr.MAG + ' '.join(cmd) + Clr.RST, flush=True) # Avoid the 'what to do next' help. subprocess.run( cmd + ['--noninteractive'], cwd=spinoff_src, check=True, ) print(f'{Clr.MAG}tools/spinoff update{Clr.RST}', flush=True) subprocess.run(['tools/spinoff', 'update'], cwd=path, check=True) # Now let's simply run the mypy target. This will compile a # binary, use that binary to generate dummy Python modules, and # then check the assembled set of Python scripts. If all that # goes through it tells us that this spinoff project is at least # basically functional. subprocess.run( ['make', 'mypy'], cwd=path, env=dict( os.environ, BA_APP_RUN_ENABLE_BUILDS='1', BA_APP_RUN_BUILD_HEADLESS='1', ), check=True, ) # Run the binary with a --help arg and make sure it spits # out what we expect it to. # DISABLING: the dummy-module generation part of the mypy target # covers this. if bool(False): help_output = subprocess.run( [ 'build/cmake/server-debug/staged/dist/' 'spinofftest_headless', '--help', ], cwd=path, check=True, capture_output=True, ).stdout.decode() if '-h, --help ' not in help_output: raise RuntimeError( 'Unexpected output when running test command.' ) else: raise CleanError(f"Invalid test type '{testtype}'.")