Move project test environments into the workspace
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
"""Host-only relocation and preservation checks; no network, devices or installs."""
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import local_env as env
|
||||
|
||||
|
||||
class LocalEnvironmentTests(unittest.TestCase):
|
||||
def test_workspace_location_uses_source_not_cwd(self):
|
||||
self.assertEqual(env.ROOT / '测试相关资料/如何测试/本机测试环境', env.HERE)
|
||||
module = env.ROOT / '移动端相关内容/安卓app/如何安卓测试/local_test_paths.py'
|
||||
spec = importlib.util.spec_from_file_location('test_paths', module)
|
||||
value = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(value)
|
||||
self.assertEqual(value.SSH_KNOWN_HOSTS, env.LOCAL / 'private/qms-mobile-known_hosts')
|
||||
|
||||
def test_copied_venv_is_rejected_without_overwriting(self):
|
||||
with tempfile.TemporaryDirectory(prefix='中文 relocation ') as tmp:
|
||||
local = Path(tmp)
|
||||
venv = local / 'ssh/venv'
|
||||
(venv / 'Scripts').mkdir(parents=True)
|
||||
(venv / 'Scripts/python.exe').touch()
|
||||
cfg = venv / 'pyvenv.cfg'
|
||||
cfg.write_text('command = python -m venv old-location\n', encoding='utf-8')
|
||||
with patch.object(env, 'LOCAL', local), patch.object(env, 'run', side_effect=AssertionError('unexpected install')):
|
||||
with self.assertRaisesRegex(RuntimeError, 'preserve/rename'):
|
||||
env.setup_python('ssh', offline=True)
|
||||
self.assertEqual(cfg.read_text(encoding='utf-8'), 'command = python -m venv old-location\n')
|
||||
|
||||
def test_source_dependency_change_requires_a_new_lock(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root = Path(tmp)
|
||||
source = root / '移动端相关内容/安卓app/如何安卓测试/requirements-host.txt'
|
||||
source.parent.mkdir(parents=True)
|
||||
source.write_text('paramiko==5.0.0\n', encoding='utf-8')
|
||||
(root / 'requirements-ssh.lock.txt').write_text('paramiko==4.0.0 --hash=sha256:old\n', encoding='utf-8')
|
||||
with patch.object(env, 'ROOT', root), patch.object(env, 'HERE', root):
|
||||
with self.assertRaisesRegex(RuntimeError, 'source requirements changed'):
|
||||
env.validate_lock('ssh')
|
||||
|
||||
def test_offline_missing_image_does_not_download(self):
|
||||
with tempfile.TemporaryDirectory(prefix='中文 offline ') as tmp:
|
||||
local = Path(tmp)
|
||||
args = type('Args', (), {'offline': True, 'image_archive': None})()
|
||||
with patch.object(env, 'LOCAL', local), patch.object(env, 'CONFIG', local / 'tools.local.json'), patch('urllib.request.urlopen', side_effect=AssertionError('network')):
|
||||
with self.assertRaisesRegex(RuntimeError, 'missing image'):
|
||||
env.setup_android(args)
|
||||
|
||||
def test_stale_avd_can_refresh_paths_without_resetting_userdata(self):
|
||||
with tempfile.TemporaryDirectory(prefix='中文 avd ') as tmp:
|
||||
local = Path(tmp)
|
||||
directory = local / 'android/sdk/system-images/android-35/google_apis/x86_64'
|
||||
directory.mkdir(parents=True)
|
||||
avd = local / 'android/avd/qms-local-api35.avd'
|
||||
avd.mkdir(parents=True)
|
||||
(avd / '.qms-managed').touch()
|
||||
(avd / 'config.ini').write_text('hw.ramSize=3072\nimage.sysdir.1=old\n', encoding='utf-8')
|
||||
userdata = avd / 'userdata-qemu.img'
|
||||
userdata.write_bytes(b'preserve')
|
||||
args = type('Args', (), {'offline': True, 'image_archive': None})()
|
||||
with patch.object(env, 'LOCAL', local), patch.object(env, 'CONFIG', local / 'tools.local.json'), patch.object(env, 'check_android'):
|
||||
env.setup_android(args)
|
||||
config = (avd / 'config.ini').read_text(encoding='utf-8')
|
||||
self.assertIn('hw.ramSize=3072', config)
|
||||
self.assertIn(str(directory.resolve()), config)
|
||||
self.assertEqual(userdata.read_bytes(), b'preserve')
|
||||
|
||||
def test_unmanaged_avd_is_never_overwritten(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
local = Path(tmp)
|
||||
(local / 'android/sdk/system-images/android-35/google_apis/x86_64').mkdir(parents=True)
|
||||
avd = local / 'android/avd/qms-local-api35.avd'
|
||||
avd.mkdir(parents=True)
|
||||
cfg = avd / 'config.ini'
|
||||
cfg.write_text('owner=someone-else\n', encoding='utf-8')
|
||||
args = type('Args', (), {'offline': True, 'image_archive': None})()
|
||||
with patch.object(env, 'LOCAL', local), patch.object(env, 'CONFIG', local / 'tools.local.json'):
|
||||
with self.assertRaisesRegex(RuntimeError, 'unmanaged'):
|
||||
env.setup_android(args)
|
||||
self.assertEqual(cfg.read_text(encoding='utf-8'), 'owner=someone-else\n')
|
||||
|
||||
@unittest.skipUnless(__import__('os').name == 'nt', 'Windows junction lifecycle')
|
||||
def test_emulator_session_restores_image_path_and_removes_only_alias(self):
|
||||
with tempfile.TemporaryDirectory(prefix='中文 session ') as tmp:
|
||||
local = Path(tmp)
|
||||
avd = local / 'android/avd/qms-local-api35.avd'
|
||||
avd.mkdir(parents=True)
|
||||
cfg = avd / 'config.ini'
|
||||
cfg.write_text('hw.ramSize = 3072\nimage.sysdir.1 = before\n', encoding='utf-8')
|
||||
(local / 'android/emulator-home').mkdir()
|
||||
with patch.object(env, 'LOCAL', local):
|
||||
with env.android_session() as (launch, image, alias):
|
||||
self.assertTrue(alias.is_junction())
|
||||
self.assertTrue(str(image).isascii())
|
||||
self.assertTrue(str(launch['ANDROID_AVD_HOME']).isascii())
|
||||
cfg.write_text(f'hw.ramSize = 3072\nimage.sysdir.1 = {image}\n', encoding='utf-8')
|
||||
self.assertFalse(alias.exists())
|
||||
self.assertEqual(env.ini_values(cfg)['image.sysdir.1'], str(env.image_dir().resolve()))
|
||||
self.assertEqual(env.ini_values(cfg)['hw.ramSize'], '3072')
|
||||
self.assertTrue(avd.is_dir())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user