feat(vmgui): GUI launcher command, VMX optional
Add top-level `vmgui` to open the VMware Workstation GUI (renamed from the earlier `vm open`). --vmx is optional: with it the GUI opens that VM, without it the GUI starts bare. Power-on/fullscreen flags ignored (with a notice) when no VMX is given. Needs an X display — sudo -u ci-runner strips $DISPLAY, so --display / xhost; see runbook §4.7. 9 tests; suite green ≥90%. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -499,7 +499,7 @@ def test_vm_cleanup_backend_unavailable(monkeypatch: pytest.MonkeyPatch, tmp_pat
|
||||
assert "vmrun not available" in result.output
|
||||
|
||||
|
||||
# ── vm open ───────────────────────────────────────────────────────────────────
|
||||
# ── vmgui ───────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
def _capture_launch(monkeypatch: pytest.MonkeyPatch) -> dict[str, Any]:
|
||||
@@ -516,7 +516,7 @@ def _capture_launch(monkeypatch: pytest.MonkeyPatch) -> dict[str, Any]:
|
||||
|
||||
|
||||
def test_vm_open_missing_vmx_errors(tmp_path: Path) -> None:
|
||||
result = CliRunner().invoke(cli, ["vm", "open", "--vmx", str(tmp_path / "nope.vmx")])
|
||||
result = CliRunner().invoke(cli, ["vmgui", "--vmx", str(tmp_path / "nope.vmx")])
|
||||
assert result.exit_code != 0
|
||||
assert "VMX file not found" in result.output
|
||||
|
||||
@@ -526,7 +526,7 @@ def test_vm_open_happy_path(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) ->
|
||||
vmx.write_text("config")
|
||||
cap = _capture_launch(monkeypatch)
|
||||
monkeypatch.setenv("DISPLAY", ":0")
|
||||
result = CliRunner().invoke(cli, ["vm", "open", "--vmx", str(vmx)])
|
||||
result = CliRunner().invoke(cli, ["vmgui", "--vmx", str(vmx)])
|
||||
assert result.exit_code == 0, result.output
|
||||
assert cap["argv"][-1] == str(vmx)
|
||||
assert "-x" not in cap["argv"] and "-X" not in cap["argv"]
|
||||
@@ -538,7 +538,7 @@ def test_vm_open_power_on_adds_x(monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
||||
vmx.write_text("config")
|
||||
cap = _capture_launch(monkeypatch)
|
||||
monkeypatch.setenv("DISPLAY", ":0")
|
||||
result = CliRunner().invoke(cli, ["vm", "open", "--vmx", str(vmx), "--power-on"])
|
||||
result = CliRunner().invoke(cli, ["vmgui", "--vmx", str(vmx), "--power-on"])
|
||||
assert result.exit_code == 0, result.output
|
||||
assert "-x" in cap["argv"]
|
||||
|
||||
@@ -549,7 +549,7 @@ def test_vm_open_fullscreen_adds_capital_x(monkeypatch: pytest.MonkeyPatch, tmp_
|
||||
cap = _capture_launch(monkeypatch)
|
||||
monkeypatch.setenv("DISPLAY", ":0")
|
||||
result = CliRunner().invoke(
|
||||
cli, ["vm", "open", "--vmx", str(vmx), "--fullscreen", "--new-window"]
|
||||
cli, ["vmgui", "--vmx", str(vmx), "--fullscreen", "--new-window"]
|
||||
)
|
||||
assert result.exit_code == 0, result.output
|
||||
assert "-X" in cap["argv"] and "-n" in cap["argv"]
|
||||
@@ -560,7 +560,7 @@ def test_vm_open_display_option_overrides_env(monkeypatch: pytest.MonkeyPatch, t
|
||||
vmx.write_text("config")
|
||||
cap = _capture_launch(monkeypatch)
|
||||
monkeypatch.delenv("DISPLAY", raising=False)
|
||||
result = CliRunner().invoke(cli, ["vm", "open", "--vmx", str(vmx), "--display", ":1"])
|
||||
result = CliRunner().invoke(cli, ["vmgui", "--vmx", str(vmx), "--display", ":1"])
|
||||
assert result.exit_code == 0, result.output
|
||||
assert cap["env"]["DISPLAY"] == ":1"
|
||||
assert "display=:1" in result.output
|
||||
@@ -571,7 +571,7 @@ def test_vm_open_warns_without_display(monkeypatch: pytest.MonkeyPatch, tmp_path
|
||||
vmx.write_text("config")
|
||||
_capture_launch(monkeypatch)
|
||||
monkeypatch.delenv("DISPLAY", raising=False)
|
||||
result = CliRunner().invoke(cli, ["vm", "open", "--vmx", str(vmx)])
|
||||
result = CliRunner().invoke(cli, ["vmgui", "--vmx", str(vmx)])
|
||||
assert result.exit_code == 0, result.output
|
||||
assert "no X display" in result.output
|
||||
|
||||
@@ -585,6 +585,26 @@ def test_vm_open_launch_failure_is_reported(monkeypatch: pytest.MonkeyPatch, tmp
|
||||
|
||||
monkeypatch.setattr(vm_module, "_launch_gui", _boom)
|
||||
monkeypatch.setenv("DISPLAY", ":0")
|
||||
result = CliRunner().invoke(cli, ["vm", "open", "--vmx", str(vmx)])
|
||||
result = CliRunner().invoke(cli, ["vmgui", "--vmx", str(vmx)])
|
||||
assert result.exit_code != 0
|
||||
assert "failed to launch VMware GUI" in result.output
|
||||
|
||||
|
||||
def test_vm_open_without_vmx_launches_bare_gui(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
cap = _capture_launch(monkeypatch)
|
||||
monkeypatch.setenv("DISPLAY", ":0")
|
||||
result = CliRunner().invoke(cli, ["vmgui"])
|
||||
assert result.exit_code == 0, result.output
|
||||
# Only the binary (no vmx path, no power-on flags).
|
||||
assert cap["argv"][1:] == [] or cap["argv"][1:] == ["-n"]
|
||||
assert "-x" not in cap["argv"] and "-X" not in cap["argv"]
|
||||
assert "pid 4242" in result.output
|
||||
|
||||
|
||||
def test_vm_open_power_on_ignored_without_vmx(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
cap = _capture_launch(monkeypatch)
|
||||
monkeypatch.setenv("DISPLAY", ":0")
|
||||
result = CliRunner().invoke(cli, ["vmgui", "--power-on"])
|
||||
assert result.exit_code == 0, result.output
|
||||
assert "-x" not in cap["argv"]
|
||||
assert "ignored without --vmx" in result.output
|
||||
|
||||
Reference in New Issue
Block a user