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