From e1a4ff227131a07a48723e04a81fe8c1aafb0490 Mon Sep 17 00:00:00 2001 From: Chris O'Hara Date: Thu, 13 Jul 2023 08:14:05 +1000 Subject: [PATCH] Test spawning using the host network Signed-off-by: Chris O'Hara --- replay_test.go | 11 +++++++++++ testdata/go/spawn.go | 31 ++++++++++++++++++++----------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/replay_test.go b/replay_test.go index 81c85e23..bdba8ee0 100644 --- a/replay_test.go +++ b/replay_test.go @@ -64,4 +64,15 @@ var replay = tests{ assert.Equal(t, exitCode, 0) assert.Equal(t, replay, stdout) }, + + "guests can spawn processes": func(t *testing.T) { + stdout, stderr, exitCode := timecraft(t, "run", "--", "./testdata/go/spawn.wasm") + assert.Equal(t, exitCode, 0) + + processID, _, _ := strings.Cut(stderr, "\n") + + replay, _, exitCode := timecraft(t, "replay", strings.TrimSpace(processID)) + assert.Equal(t, exitCode, 0) + assert.Equal(t, replay, stdout) + }, } diff --git a/testdata/go/spawn.go b/testdata/go/spawn.go index 83e2510b..f9c79511 100644 --- a/testdata/go/spawn.go +++ b/testdata/go/spawn.go @@ -7,7 +7,6 @@ import ( "fmt" "net" "net/http" - "net/netip" "net/url" "os" "time" @@ -16,6 +15,8 @@ import ( "github.com/stealthrocket/timecraft/sdk/go/timecraft" ) +const workerPort = 10948 + func main() { var err error switch { @@ -49,14 +50,23 @@ func supervisor(ctx context.Context) error { fmt.Printf("executing as process %s in timecraft %s\n", processID, version) // Spawn the same WASM module, but with the "worker" arg. - workerModule := timecraft.ModuleSpec{Args: []string{"worker"}} + workerModule := timecraft.ModuleSpec{ + Args: []string{"worker"}, + Capabilities: timecraft.HostNetworkingCapability, + } - workerID, workerAddr, err := client.Spawn(ctx, workerModule) + workerID, _, err := client.Spawn(ctx, workerModule) if err != nil { return fmt.Errorf("failed to spawn worker: %w", err) } defer client.Kill(ctx, workerID) + // FIXME: the retry loop doesn't currently work. The sandbox seems to say that + // the connection succeeds, but then on fd_read it returns ECONNREFUSED?? + time.Sleep(2 * time.Second) + + workerAddr := fmt.Sprintf("127.0.0.1:%d", workerPort) + fmt.Printf("connecting to worker process %s on address %s\n", workerID, workerAddr) httpClient := &http.Client{ @@ -77,7 +87,7 @@ func supervisor(ctx context.Context) error { }, } - u, _ := url.Parse(fmt.Sprintf("http://%s/", netip.AddrPortFrom(workerAddr, 3000))) + u, _ := url.Parse(fmt.Sprintf("http://%s/", workerAddr)) req := &http.Request{ Method: "GET", URL: u, @@ -89,19 +99,18 @@ func supervisor(ctx context.Context) error { } fmt.Printf("worker responded with %d\n", res.StatusCode) - + if res.StatusCode != 200 { + return fmt.Errorf("unexpected worker status code: %d", res.StatusCode) + } return nil } func worker() error { - defer fmt.Println("worker exiting") - - addr := ":3000" - listener, err := wasip1.Listen("tcp", addr) + workerAddr := fmt.Sprintf(":%d", workerPort) + listener, err := wasip1.Listen("tcp", workerAddr) if err != nil { - return fmt.Errorf("failed to listen on %s: %w", addr, err) + return fmt.Errorf("failed to listen on %s: %w", workerAddr, err) } - fmt.Println("worker listening on", addr) return http.Serve(listener, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) }))