This repository has no description
1//go:build linux
2
3package microvm
4
5import (
6 "context"
7 "encoding/json"
8 "log/slog"
9 "os"
10 "path/filepath"
11 "strings"
12 "testing"
13
14 "tangled.org/core/api/tangled"
15 "tangled.org/core/spindle/config"
16)
17
18func writeTestImageSpec(t *testing.T, dir, name string, spec ImageSpec) {
19 t.Helper()
20 data, err := json.Marshal(spec)
21 if err != nil {
22 t.Fatal(err)
23 }
24 if err := os.WriteFile(filepath.Join(dir, name+".json"), data, 0o644); err != nil {
25 t.Fatal(err)
26 }
27}
28
29func testEngine(t *testing.T, imageDir string) *Engine {
30 t.Helper()
31 return &Engine{
32 l: slog.Default(),
33 cfg: &config.Config{
34 MicroVMPipelines: config.MicroVMPipelines{
35 ImageDir: imageDir,
36 DefaultImage: "alpine",
37 },
38 },
39 }
40}
41
42func TestNewDefersAgentHubUntilWorkflowSetup(t *testing.T) {
43 e, err := New(context.Background(), &config.Config{}, nil)
44 if err != nil {
45 t.Fatal(err)
46 }
47 if e.agent != nil {
48 t.Fatal("agent hub started during engine initialization")
49 }
50}
51
52func TestInitWorkflowRejectsConfigOnNonNixOSImage(t *testing.T) {
53 dir := t.TempDir()
54 writeTestImageSpec(t, dir, "alpine", validImageSpec())
55
56 e := testEngine(t, dir)
57 _, err := e.InitWorkflow(tangled.Pipeline_Workflow{
58 Raw: `
59image: alpine
60dependencies:
61 - nixpkgs#hello
62steps:
63 - name: hello
64 command: hello
65`,
66 }, tangled.Pipeline{})
67 if err == nil {
68 t.Fatal("expected error for NixOS config options on a non-NixOS image")
69 }
70 if !strings.Contains(err.Error(), "NixOS") {
71 t.Fatalf("error should mention NixOS images, got: %v", err)
72 }
73}
74
75func TestInitWorkflowPlainStepsOnNonNixOSImage(t *testing.T) {
76 dir := t.TempDir()
77 writeTestImageSpec(t, dir, "alpine", validImageSpec())
78
79 e := testEngine(t, dir)
80 wf, err := e.InitWorkflow(tangled.Pipeline_Workflow{
81 Raw: `
82image: alpine
83steps:
84 - name: hello
85 command: echo hello
86`,
87 }, tangled.Pipeline{})
88 if err != nil {
89 t.Fatal(err)
90 }
91 if len(wf.Steps) != 1 {
92 t.Fatalf("expected exactly the user step, got %d steps", len(wf.Steps))
93 }
94 state, ok := wf.Data.(*workflowState)
95 if !ok {
96 t.Fatal("workflow data is not workflowState")
97 }
98 if state.ConfigKey != "" {
99 t.Fatalf("non-NixOS workflow should not have a config key, got %q", state.ConfigKey)
100 }
101}
102
103func TestInitWorkflowConfigOnNixOSImage(t *testing.T) {
104 dir := t.TempDir()
105 spec := validImageSpec()
106 spec.BaseConfigHash = "abcdef123456"
107 writeTestImageSpec(t, dir, "nixos", spec)
108
109 e := testEngine(t, dir)
110 wf, err := e.InitWorkflow(tangled.Pipeline_Workflow{
111 Raw: `
112image: nixos
113dependencies:
114 - nixpkgs#hello
115steps:
116 - name: hello
117 command: hello
118`,
119 }, tangled.Pipeline{})
120 if err != nil {
121 t.Fatal(err)
122 }
123 if len(wf.Steps) != 2 {
124 t.Fatalf("expected activation step + user step, got %d steps", len(wf.Steps))
125 }
126 if step, ok := wf.Steps[0].(Step); !ok || step.action != activationStepAction {
127 t.Fatalf("first step should be the activation step, got %+v", wf.Steps[0])
128 }
129}