feat(chv): 完整 Chromium 改装数据盘
根盘只剩 ~600MB,playwright install chromium 装根盘 109 秒后 ENOSPC 失败(2026-11-08 构建 #8 驱动实证)。完整版改装数据盘 /home/chv/workspace/.chv-browsers(9.3G 空闲),仍不 bake 进 base、按需;full 引擎启动时直接传 executable_path(channel 与 executable_path 互斥,且驱动进程启动时才读 env,运行中改 env 无效);status 增 full_browsers_dir,mount 失败报错给数据盘 安装命令。驱动的安装步同步改数据盘并 chown 给 chv-browser。
This commit is contained in:
1 parent
435664925e
commit
9d986becaf
2 files changed
+135
-27
No files matched your search
@@ -111,7 +111,7 @@ class FakePlaywright:
|
||||
return False
|
||||
|
||||
|
||||
def _agent(pages, tmp):
|
||||
def _agent(pages, tmp, full_browsers_dir=None):
|
||||
ctx = FakeContext(pages)
|
||||
entered_holder = {}
|
||||
|
||||
@@ -126,7 +126,8 @@ def _agent(pages, tmp):
|
||||
|
||||
agent = BROWSER.BrowserAgent(
|
||||
playwright_factory=lambda: PW(), shots_dir=tmp,
|
||||
profile_dir=os.path.join(tmp, "profile"))
|
||||
profile_dir=os.path.join(tmp, "profile"),
|
||||
full_browsers_dir=full_browsers_dir)
|
||||
return agent, ctx, entered_holder
|
||||
|
||||
|
||||
@@ -172,6 +173,45 @@ class FullPresentTest(unittest.TestCase):
|
||||
self.assertFalse(BROWSER.full_chromium_present(tmp))
|
||||
|
||||
|
||||
class FullBrowsersDirTest(unittest.TestCase):
|
||||
def test_resolve_data_disk_path(self):
|
||||
self.assertEqual(
|
||||
BROWSER.resolve_full_browsers_dir(True, env={}),
|
||||
BROWSER.FULL_BROWSERS_DATA_DIR)
|
||||
|
||||
def test_resolve_fallback_path(self):
|
||||
self.assertEqual(
|
||||
BROWSER.resolve_full_browsers_dir(False, env={}),
|
||||
BROWSER.FULL_BROWSERS_FALLBACK_DIR)
|
||||
|
||||
def test_resolve_env_override_wins(self):
|
||||
self.assertEqual(
|
||||
BROWSER.resolve_full_browsers_dir(
|
||||
True, env={"CHV_BROWSER_FULL_BROWSERS_DIR":
|
||||
"/data/browsers"}),
|
||||
"/data/browsers")
|
||||
|
||||
def test_executable_found_ignores_headless_shell(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
os.makedirs(os.path.join(
|
||||
tmp, "chromium_headless_shell-1248", "chrome-linux"))
|
||||
self.assertIsNone(BROWSER.full_chromium_executable(tmp))
|
||||
exe_dir = os.path.join(
|
||||
tmp, "chromium-141.0.7390.37", "chrome-linux")
|
||||
os.makedirs(exe_dir)
|
||||
exe = os.path.join(exe_dir, "chrome")
|
||||
open(exe, "w").write("x")
|
||||
self.assertEqual(BROWSER.full_chromium_executable(tmp), exe)
|
||||
|
||||
def test_status_reports_data_disk_dir(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
agent, _c, _h = _agent([FakePage()], tmp,
|
||||
full_browsers_dir=tmp)
|
||||
st = agent.status()
|
||||
self.assertEqual(st["full_browsers_dir"], tmp)
|
||||
self.assertFalse(st["full_present"])
|
||||
|
||||
|
||||
class MultiSessionTest(unittest.TestCase):
|
||||
def test_two_sessions_do_not_interfere(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
@@ -423,25 +463,42 @@ class EngineSwitchTest(unittest.TestCase):
|
||||
# 回落后 shell 仍可工作。
|
||||
self.assertTrue(agent.open("https://example.com")["ok"])
|
||||
|
||||
def test_mount_unmount_full_switches_channel(self):
|
||||
def test_mount_unmount_full_uses_executable_path(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
agent, _c, holder = _agent([FakePage()], tmp)
|
||||
with mock.patch.object(BROWSER, "full_chromium_present",
|
||||
return_value=True):
|
||||
mounted = agent.mount_full()
|
||||
exe_dir = os.path.join(
|
||||
tmp, "chromium-141.0.7390.37", "chrome-linux")
|
||||
os.makedirs(exe_dir)
|
||||
exe = os.path.join(exe_dir, "chrome")
|
||||
open(exe, "w").write("x")
|
||||
agent, _c, holder = _agent([FakePage()], tmp,
|
||||
full_browsers_dir=tmp)
|
||||
mounted = agent.mount_full()
|
||||
self.assertTrue(mounted["ok"])
|
||||
self.assertEqual(mounted["engine"], "full")
|
||||
self.assertTrue(mounted["mounted_full"])
|
||||
entered = holder["entered"]
|
||||
self.assertEqual(entered.calls[-1][1].get("channel"),
|
||||
"chromium")
|
||||
kwargs = entered.calls[-1][1]
|
||||
self.assertEqual(kwargs.get("executable_path"), exe)
|
||||
self.assertNotIn("channel", kwargs)
|
||||
unmounted = agent.unmount_full()
|
||||
self.assertTrue(unmounted["ok"])
|
||||
self.assertEqual(unmounted["engine"], "shell")
|
||||
self.assertFalse(unmounted["mounted_full"])
|
||||
self.assertNotIn("channel", entered.calls[-1][1])
|
||||
self.assertNotIn("executable_path", entered.calls[-1][1])
|
||||
self.assertTrue(agent.open("https://example.com")["ok"])
|
||||
|
||||
def test_mount_full_error_names_data_disk_install(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
agent, _c, _h = _agent([FakePage()], tmp,
|
||||
full_browsers_dir=os.path.join(
|
||||
tmp, "browsers"))
|
||||
resp = agent.mount_full()
|
||||
self.assertFalse(resp["ok"])
|
||||
self.assertTrue(resp["fallback"])
|
||||
self.assertIn(os.path.join(tmp, "browsers"),
|
||||
resp["error"])
|
||||
|
||||
def test_handle_request_routes_new_ops(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
agent, _c, _h = _agent([FakePage()], tmp)
|
||||
|
||||
Reference in new issue
Block a user