Skip to content

Commit 2951d80

Browse files
committed
test(driverutil): add EnsureDisk tests for ISO and non-ISO base images
Add pkg/driverutil/disk_test.go covering: - Base image is ISO: EnsureDisk creates/keeps diffdisk and converts to asif and raw; base ISO remains unchanged (content hash and ISO signature). - Base image is non-ISO: EnsureDisk converts diffdisk to raw and asif. Signed-off-by: ashwat287 <ashwatpas@gmail.com>
1 parent 260ba36 commit 2951d80

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-0
lines changed

pkg/driverutil/disk_test.go

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
// SPDX-FileCopyrightText: Copyright The Lima Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package driverutil
5+
6+
import (
7+
"crypto/sha256"
8+
"encoding/hex"
9+
"os"
10+
"os/exec"
11+
"path/filepath"
12+
"runtime"
13+
"strconv"
14+
"strings"
15+
"testing"
16+
17+
"github.com/lima-vm/go-qcow2reader"
18+
"github.com/lima-vm/go-qcow2reader/image"
19+
"gotest.tools/v3/assert"
20+
21+
"github.com/lima-vm/lima/v2/pkg/iso9660util"
22+
"github.com/lima-vm/lima/v2/pkg/limatype/filenames"
23+
)
24+
25+
const (
26+
typeRAW = image.Type("raw")
27+
typeASIF = image.Type("asif")
28+
)
29+
30+
func makeTempInstanceDir(t *testing.T) string {
31+
t.Helper()
32+
return t.TempDir()
33+
}
34+
35+
func writeMinimalISO(t *testing.T, path string) {
36+
t.Helper()
37+
entries := []iso9660util.Entry{
38+
{Path: "/hello.txt", Reader: strings.NewReader("hello world")},
39+
}
40+
assert.NilError(t, iso9660util.Write(path, "TESTISO", entries))
41+
}
42+
43+
func writeNonISO(t *testing.T, path string) {
44+
t.Helper()
45+
size := 64 * 1024
46+
buf := make([]byte, size)
47+
copy(buf[0x8001:], "XXXXX")
48+
assert.NilError(t, os.WriteFile(path, buf, 0o644))
49+
}
50+
51+
func sha256File(t *testing.T, path string) string {
52+
t.Helper()
53+
b, err := os.ReadFile(path)
54+
assert.NilError(t, err)
55+
sum := sha256.Sum256(b)
56+
return hex.EncodeToString(sum[:])
57+
}
58+
59+
func detectImageType(t *testing.T, path string) image.Type {
60+
t.Helper()
61+
f, err := os.Open(path)
62+
assert.NilError(t, err)
63+
defer f.Close()
64+
img, err := qcow2reader.Open(f)
65+
assert.NilError(t, err)
66+
return img.Type()
67+
}
68+
69+
func checkDisk(t *testing.T, diff string, expectedType image.Type) {
70+
t.Helper()
71+
fi, err := os.Stat(diff)
72+
assert.NilError(t, err)
73+
assert.Assert(t, fi.Size() > 0)
74+
assert.Equal(t, detectImageType(t, diff), expectedType)
75+
}
76+
77+
func removeAndCheck(t *testing.T, path string) {
78+
t.Helper()
79+
assert.NilError(t, os.Remove(path))
80+
_, err := os.Stat(path)
81+
assert.ErrorIs(t, err, os.ErrNotExist)
82+
}
83+
84+
func isMacOS26OrHigher(t *testing.T) bool {
85+
if runtime.GOOS != "darwin" {
86+
return false
87+
}
88+
out, err := exec.CommandContext(t.Context(), "sw_vers", "-productVersion").Output()
89+
if err != nil {
90+
return false
91+
}
92+
parts := strings.Split(strings.TrimSpace(string(out)), ".")
93+
if len(parts) < 1 {
94+
return false
95+
}
96+
major, err := strconv.Atoi(parts[0])
97+
if err != nil {
98+
return false
99+
}
100+
return major >= 26
101+
}
102+
103+
func TestEnsureDisk_WithISOBaseImage(t *testing.T) {
104+
instDir := makeTempInstanceDir(t)
105+
base := filepath.Join(instDir, filenames.BaseDisk)
106+
diff := filepath.Join(instDir, filenames.DiffDisk)
107+
108+
writeMinimalISO(t, base)
109+
isISO, err := iso9660util.IsISO9660(base)
110+
assert.NilError(t, err)
111+
assert.Assert(t, isISO)
112+
baseHashBefore := sha256File(t, base)
113+
114+
formats := []image.Type{typeRAW}
115+
if isMacOS26OrHigher(t) {
116+
formats = append(formats, typeASIF)
117+
}
118+
119+
for _, format := range formats {
120+
assert.NilError(t, EnsureDisk(t.Context(), instDir, "2MiB", format))
121+
isISO, err = iso9660util.IsISO9660(base)
122+
assert.NilError(t, err)
123+
assert.Assert(t, isISO)
124+
assert.Equal(t, baseHashBefore, sha256File(t, base))
125+
checkDisk(t, diff, format)
126+
if format != formats[len(formats)-1] {
127+
removeAndCheck(t, diff)
128+
}
129+
}
130+
}
131+
132+
func TestEnsureDisk_WithNonISOBaseImage(t *testing.T) {
133+
instDir := makeTempInstanceDir(t)
134+
base := filepath.Join(instDir, filenames.BaseDisk)
135+
diff := filepath.Join(instDir, filenames.DiffDisk)
136+
137+
writeNonISO(t, base)
138+
isISO, err := iso9660util.IsISO9660(base)
139+
assert.NilError(t, err)
140+
assert.Assert(t, !isISO)
141+
142+
formats := []image.Type{typeRAW}
143+
if isMacOS26OrHigher(t) {
144+
formats = append(formats, typeASIF)
145+
}
146+
147+
for _, format := range formats {
148+
assert.NilError(t, EnsureDisk(t.Context(), instDir, "2MiB", format))
149+
checkDisk(t, diff, format)
150+
if format != formats[len(formats)-1] {
151+
removeAndCheck(t, diff)
152+
}
153+
}
154+
}
155+
156+
func TestEnsureDisk_ExistingDiffDisk(t *testing.T) {
157+
instDir := makeTempInstanceDir(t)
158+
base := filepath.Join(instDir, filenames.BaseDisk)
159+
diff := filepath.Join(instDir, filenames.DiffDisk)
160+
161+
writeNonISO(t, base)
162+
163+
formats := []image.Type{typeRAW}
164+
if isMacOS26OrHigher(t) {
165+
formats = append(formats, typeASIF)
166+
}
167+
168+
for _, format := range formats {
169+
assert.NilError(t, os.WriteFile(diff, []byte("preexisting"), 0o644))
170+
origHash := sha256File(t, diff)
171+
assert.NilError(t, EnsureDisk(t.Context(), instDir, "2MiB", format))
172+
assert.Equal(t, sha256File(t, diff), origHash)
173+
removeAndCheck(t, diff)
174+
}
175+
}

0 commit comments

Comments
 (0)