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