fix: restore automatic startup of local ADB server
This commit is contained in:
1 parent
f826bdf3b0
commit
49873e7f05
9 files changed
+211
-23
No files matched your search
@@ -323,7 +323,9 @@ async def test_queue_worker_cmd_construction():
|
||||
endpoint = enqueue_result["tasks"][0]["adb_endpoint"]
|
||||
assert executed_kwargs[0]["env"]["ADB_HOST"] == endpoint["host"]
|
||||
assert executed_kwargs[0]["env"]["ADB_PORT"] == str(endpoint["port"])
|
||||
assert executed_kwargs[0]["env"]["ADB_SERVER_SOCKET"] == endpoint["socket"]
|
||||
assert executed_kwargs[0]["env"]["ADB_SERVER_SOCKET"] == (
|
||||
"tcp:localhost:5037" if endpoint["is_local_default"] else endpoint["socket"]
|
||||
)
|
||||
assert executed_kwargs[0]["env"]["ARTEMIS_ADB_ENDPOINT_ID"] == endpoint["identity"]
|
||||
if sys.platform == "win32":
|
||||
assert executed_kwargs[0]["creationflags"] == (
|
||||
|
||||
@@ -70,6 +70,34 @@ def test_adb_session_builds_explicit_endpoint_command_and_environment():
|
||||
assert environment[ADB_ENDPOINT_ID_ENV] == endpoint.identity
|
||||
|
||||
|
||||
@pytest.mark.parametrize("host", ["127.0.0.1", "localhost", "::1"])
|
||||
def test_local_endpoint_allows_adb_auto_start_without_changing_task_identity(host):
|
||||
endpoint = AdbServerEndpoint(host, 5037)
|
||||
session = AdbSession(endpoint, adb_path="adb")
|
||||
inherited = {
|
||||
"ADB_SERVER_SOCKET": "tcp:remote.example:5040",
|
||||
"ANDROID_ADB_SERVER_ADDRESS": "remote.example",
|
||||
"ANDROID_ADB_SERVER_PORT": "5040",
|
||||
}
|
||||
|
||||
assert session.command(["devices"]) == ["adb", "-H", "localhost", "-P", "5037", "devices"]
|
||||
environment = session.environment(inherited)
|
||||
assert environment["ADB_SERVER_SOCKET"] == "tcp:localhost:5037"
|
||||
assert environment["ADB_HOST"] == host
|
||||
assert environment[ADB_ENDPOINT_ID_ENV] == endpoint.identity
|
||||
assert inherited["ADB_SERVER_SOCKET"] == "tcp:remote.example:5040"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("host", "port"), [("127.0.0.1", 5038), ("::1", 5038), ("server.example", 5037)]
|
||||
)
|
||||
def test_forwarded_endpoint_never_uses_local_daemon_auto_start(host, port):
|
||||
endpoint = AdbServerEndpoint(host, port)
|
||||
session = AdbSession(endpoint, adb_path="adb")
|
||||
assert session.command(["devices"])[2] == host
|
||||
assert session.environment({})["ADB_SERVER_SOCKET"] == endpoint.socket
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_connect_activates_forwarded_server_after_success(monkeypatch):
|
||||
captured: dict[str, object] = {}
|
||||
@@ -253,7 +281,7 @@ async def test_use_local_server_restores_standard_endpoint(monkeypatch):
|
||||
assert result["success"] is True
|
||||
assert result["endpoint"] == AdbServerEndpoint("127.0.0.1", 5037).to_dict()
|
||||
assert settings.ADB_PORT == 5037
|
||||
assert os.environ["ADB_SERVER_SOCKET"] == "tcp:127.0.0.1:5037"
|
||||
assert os.environ["ADB_SERVER_SOCKET"] == "tcp:localhost:5037"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
||||
@@ -20,6 +20,7 @@ import pytest
|
||||
|
||||
from artemis.runtime.device_lock import DeviceExecutionLock
|
||||
from artemis.runtime.device_pool import DevicePool, DeviceStatus
|
||||
from artemis.config import settings
|
||||
|
||||
device_pool_module = importlib.import_module("artemis.runtime.device_pool")
|
||||
|
||||
@@ -245,6 +246,45 @@ def test_warm_up_without_adb_returns_false(monkeypatch):
|
||||
assert asyncio.run(pool.warm_up_async(settle_timeout=0.0)) is False
|
||||
|
||||
|
||||
def test_adb_warmup_does_not_start_local_server_for_remote_endpoint(monkeypatch):
|
||||
monkeypatch.setattr(settings, "ADB_HOST", "127.0.0.1")
|
||||
monkeypatch.setattr(settings, "ADB_PORT", 5038)
|
||||
|
||||
async def unexpected_spawn(*args, **kwargs):
|
||||
pytest.fail("A forwarded endpoint must not start a local ADB daemon")
|
||||
|
||||
monkeypatch.setattr(asyncio, "create_subprocess_exec", unexpected_spawn)
|
||||
asyncio.run(DevicePool(adb_path="adb")._start_adb_server(timeout=1.0))
|
||||
|
||||
|
||||
def test_adb_warmup_reports_failed_start_with_local_command(monkeypatch):
|
||||
monkeypatch.setattr(settings, "ADB_HOST", "127.0.0.1")
|
||||
monkeypatch.setattr(settings, "ADB_PORT", 5037)
|
||||
monkeypatch.setenv("ADB_SERVER_SOCKET", "tcp:remote.example:5040")
|
||||
captured = {}
|
||||
warnings = []
|
||||
|
||||
class FailedProcess:
|
||||
returncode = 1
|
||||
|
||||
async def communicate(self):
|
||||
return b"", b"cannot bind listener"
|
||||
|
||||
async def spawn(*args, **kwargs):
|
||||
captured["command"] = args
|
||||
captured["env"] = kwargs["env"]
|
||||
return FailedProcess()
|
||||
|
||||
monkeypatch.setattr(asyncio, "create_subprocess_exec", spawn)
|
||||
monkeypatch.setattr(device_pool_module.logger, "warning", warnings.append)
|
||||
asyncio.run(DevicePool(adb_path="adb")._start_adb_server(timeout=1.0))
|
||||
assert captured["command"] == ("adb", "-H", "localhost", "-P", "5037", "start-server")
|
||||
assert captured["env"]["ADB_SERVER_SOCKET"] == "tcp:localhost:5037"
|
||||
assert len(warnings) == 1
|
||||
assert "exit 1" in warnings[0]
|
||||
assert "cannot bind listener" in warnings[0]
|
||||
|
||||
|
||||
def test_try_list_devices_distinguishes_failure_from_empty(monkeypatch):
|
||||
pool = DevicePool()
|
||||
monkeypatch.setattr(pool, "_query_adb_devices_sync", lambda timeout=None: None)
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
"""Run just the ADB startup functions with fake commands; never touch host ADB."""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
import pytest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
@pytest.mark.skipif(not shutil.which("powershell.exe"), reason="Windows PowerShell required")
|
||||
@pytest.mark.parametrize("script_name", ["start.ps1", "install_deps.ps1"])
|
||||
@pytest.mark.parametrize("outcome", ["success", "failure", "exception"])
|
||||
def test_adb_startup_reports_failure_and_preserves_server_environment(
|
||||
tmp_path, script_name, outcome
|
||||
):
|
||||
harness = tmp_path / "adb-startup.ps1"
|
||||
harness.write_text(
|
||||
"""
|
||||
$ErrorActionPreference = 'Stop'
|
||||
[Console]::OutputEncoding = New-Object System.Text.UTF8Encoding($false)
|
||||
$tokens = $null
|
||||
$parseErrors = $null
|
||||
$ast = [System.Management.Automation.Language.Parser]::ParseFile(
|
||||
$env:ADB_TEST_SCRIPT, [ref]$tokens, [ref]$parseErrors)
|
||||
if ($parseErrors.Count) { throw ($parseErrors | Out-String) }
|
||||
$function = $ast.Find({ param($node)
|
||||
$node -is [System.Management.Automation.Language.FunctionDefinitionAst] -and
|
||||
$node.Name -eq 'Start-LocalAdbServer'
|
||||
}, $true)
|
||||
Invoke-Expression $function.Extent.Text
|
||||
function Test-CommandExists { return $true }
|
||||
function adb {
|
||||
Write-Host ('ADB_ARGS=' + ($args -join '|'))
|
||||
if ($env:ADB_TEST_OUTCOME -eq 'exception') { throw 'fixture launch error' }
|
||||
Write-Error 'fixture stderr' -ErrorAction Continue
|
||||
$global:LASTEXITCODE = $(if ($env:ADB_TEST_OUTCOME -eq 'failure') { 7 } else { 0 })
|
||||
}
|
||||
Start-LocalAdbServer
|
||||
if ($env:ADB_SERVER_SOCKET -ne 'tcp:remote.example:5040') { throw 'Socket was changed' }
|
||||
if ($env:ANDROID_ADB_SERVER_ADDRESS -ne 'remote.example') { throw 'Host was changed' }
|
||||
if ($env:ANDROID_ADB_SERVER_PORT -ne '5040') { throw 'Port was changed' }
|
||||
if ($ErrorActionPreference -ne 'Stop') { throw 'Error preference was changed' }
|
||||
Write-Host 'HARNESS_OK'
|
||||
""",
|
||||
encoding="utf-8-sig",
|
||||
)
|
||||
result = subprocess.run(
|
||||
["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", str(harness)],
|
||||
env={
|
||||
**os.environ,
|
||||
"ADB_TEST_SCRIPT": str(ROOT / "scripts" / script_name),
|
||||
"ADB_TEST_OUTCOME": outcome,
|
||||
"ADB_SERVER_SOCKET": "tcp:remote.example:5040",
|
||||
"ANDROID_ADB_SERVER_ADDRESS": "remote.example",
|
||||
"ANDROID_ADB_SERVER_PORT": "5040",
|
||||
},
|
||||
capture_output=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
timeout=15,
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
assert "ADB_ARGS=-H|localhost|-P|5037|start-server" in result.stdout
|
||||
assert "HARNESS_OK" in result.stdout
|
||||
if outcome == "success":
|
||||
assert "[警告]" not in result.stdout
|
||||
elif outcome == "failure":
|
||||
assert "退出码 7" in result.stdout
|
||||
assert "fixture stderr" in result.stdout
|
||||
else:
|
||||
assert "启动异常" in result.stdout
|
||||
assert "fixture launch error" in result.stdout
|
||||
Reference in new issue
Block a user