Skip to content

Commit 4489709

Browse files
committed
test(grpc): e2e ForkVm boots a distinct child from a running parent
1 parent f68bde0 commit 4489709

1 file changed

Lines changed: 32 additions & 1 deletion

File tree

test/e2e/grpc_contract_test.exs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,35 @@ defmodule Hyper.E2e.GrpcContractTest do
77
VM lifecycle are asserted over the real wire, catching proto/codec/server
88
drift a BEAM-side client cannot produce (e.g. unrecognised enum integers).
99
10+
Also carries one BEAM-side test of `ForkVm`: it needs a real booted parent
11+
VM (Firecracker + device-mapper), which the TypeScript suite cannot boot,
12+
so it drives `Hyper.Grpc.V0.Hyper.Stub` directly over the same server
13+
instead.
14+
1015
Runs only under `--only integration` on a provisioned host (CI: the
1116
`integration` job). Requires node/npm on PATH; installs the suite's npm
1217
deps on first run.
1318
"""
1419
use ExUnit.Case, async: false
1520

21+
alias Hyper.Grpc.V0.{ForkVmRequest, ForkVmResponse, StopVmRequest}
22+
alias Hyper.Grpc.V0.Hyper.Stub
23+
1624
@moduletag :integration
1725
@moduletag timeout: :timer.minutes(25)
1826

1927
@port 50_061
2028
@suite_dir Path.expand("../grpc", __DIR__)
2129

30+
# public.ecr.aws mirrors library images without Docker Hub's per-IP pull
31+
# limits, which shared GHA egress IPs routinely exhaust.
32+
@image System.get_env("HYPER_E2E_IMAGE", "public.ecr.aws/docker/library/alpine:3.19")
33+
2234
setup_all do
2335
config = %Hyper.Cfg.Grpc{enabled: true, port: @port}
2436
start_supervised!({GRPC.Server.Supervisor, Hyper.Cfg.Grpc.server_options(config)})
25-
:ok
37+
{:ok, channel} = GRPC.Stub.connect("127.0.0.1:#{@port}", adapter: GRPC.Client.Adapters.Gun)
38+
{:ok, channel: channel}
2639
end
2740

2841
test "TypeScript contract suite passes against the live server" do
@@ -39,6 +52,24 @@ defmodule Hyper.E2e.GrpcContractTest do
3952
assert status == 0, "TypeScript gRPC contract suite failed (exit #{status}); see output above"
4053
end
4154

55+
test "ForkVm boots a distinct child from a running parent", %{channel: channel} do
56+
assert {:ok, img_id} = Hyper.Img.OciLoader.load(@image)
57+
58+
assert {:ok, parent} = Hyper.create_vm(%Hyper.Vm.Spec{img_id: img_id, type: :micro})
59+
on_exit(fn -> Hyper.Node.stop_image_vm(parent) end)
60+
61+
parent_id = Hyper.id(parent)
62+
assert parent_id, "Hyper.id/1 returned nil for a freshly-created VM"
63+
64+
assert {:ok, %ForkVmResponse{vm_id: child_id, node: child_node}} =
65+
Stub.fork_vm(channel, %ForkVmRequest{vm_id: parent_id})
66+
67+
assert is_binary(child_id) and child_id != parent_id
68+
assert child_node != ""
69+
70+
on_exit(fn -> Stub.stop_vm(channel, %StopVmRequest{vm_id: child_id}) end)
71+
end
72+
4273
defp ensure_node_deps! do
4374
if not File.dir?(Path.join(@suite_dir, "node_modules")) do
4475
{out, status} = System.cmd("npm", ["ci"], cd: @suite_dir, stderr_to_stdout: true)

0 commit comments

Comments
 (0)