Files
Primora/apps/backend/internal/services/function_docker_test.go
T
Tomas DvorakandDevin 9ae1c22af0 feat: Sandboxed function execution via FUNCTIONS_DRIVER=docker
Each invoke runs in an ephemeral locked-down container — no network,
read-only rootfs, 128MiB/0.5CPU/64-pid caps, non-root, cap-drop ALL.
Source travels as base64 in the container env and materializes in the
tmpfs, so no bind mount is needed (Docker Desktop / remote daemons work).
Timeout force-removes the named container.

exec driver stays the default; the trust-model docs now describe both.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-24 20:45:33 +02:00

60 lines
1.8 KiB
Go

package services
import (
"context"
"encoding/json"
"os/exec"
"strings"
"testing"
"time"
)
func dockerAvailable(t *testing.T) {
t.Helper()
if _, err := exec.LookPath("docker"); err != nil {
t.Skip("docker CLI not installed")
}
if err := exec.Command("docker", "info").Run(); err != nil {
t.Skip("docker daemon not reachable")
}
// The test pulls the runtime image on first run.
if err := exec.Command("docker", "image", "inspect", "oven/bun:1.3.14").Run(); err != nil {
t.Skip("oven/bun:1.3.14 image not pulled")
}
}
func TestDockerRunnerRunsCode(t *testing.T) {
dockerAvailable(t)
r := NewDockerRunner(30*time.Second, 65536)
res := r.Run(context.Background(), "bun",
`const p = JSON.parse(await new Response(Bun.stdin.stream()).text()); console.log("hi " + p.name);`,
json.RawMessage(`{"name":"sandbox"}`))
if res.Status != "success" {
t.Fatalf("status = %q stderr = %q", res.Status, res.Stderr)
}
if !strings.Contains(res.Stdout, "hi sandbox") {
t.Fatalf("stdout = %q", res.Stdout)
}
}
func TestDockerRunnerIsolatesNetwork(t *testing.T) {
dockerAvailable(t)
r := NewDockerRunner(30*time.Second, 65536)
// --network none: even a DNS/connect attempt must fail inside.
res := r.Run(context.Background(), "bun",
`try { await fetch("http://169.254.169.254/"); console.log("NET-OPEN") } catch { console.log("NET-CLOSED") }`,
json.RawMessage(`{}`))
if !strings.Contains(res.Stdout, "NET-CLOSED") {
t.Fatalf("network should be unreachable, stdout = %q stderr = %q status = %q", res.Stdout, res.Stderr, res.Status)
}
}
func TestDockerRunnerTimesOut(t *testing.T) {
dockerAvailable(t)
r := NewDockerRunner(2*time.Second, 65536)
res := r.Run(context.Background(), "bun", `while (true) {}`, json.RawMessage(`{}`))
if res.Status != "timeout" {
t.Fatalf("status = %q", res.Status)
}
}