Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
lima-vm
GitHub Repository: lima-vm/lima
Path: blob/master/cmd/limactl/editflags/editflags_test.go
1646 views
1
// SPDX-FileCopyrightText: Copyright The Lima Authors
2
// SPDX-License-Identifier: Apache-2.0
3
4
package editflags
5
6
import (
7
"strings"
8
"testing"
9
10
"github.com/spf13/cobra"
11
"gotest.tools/v3/assert"
12
13
"github.com/lima-vm/lima/v2/pkg/localpathutil"
14
)
15
16
func TestCompleteCPUs(t *testing.T) {
17
assert.DeepEqual(t, []int{1}, completeCPUs(1))
18
assert.DeepEqual(t, []int{1, 2}, completeCPUs(2))
19
assert.DeepEqual(t, []int{1, 2, 4, 8}, completeCPUs(8))
20
assert.DeepEqual(t, []int{1, 2, 4, 8, 16, 20}, completeCPUs(20))
21
}
22
23
func TestCompleteMemoryGiB(t *testing.T) {
24
assert.DeepEqual(t, []float32{0.5}, completeMemoryGiB(1<<30))
25
assert.DeepEqual(t, []float32{1}, completeMemoryGiB(2<<30))
26
assert.DeepEqual(t, []float32{1, 2}, completeMemoryGiB(4<<30))
27
assert.DeepEqual(t, []float32{1, 2, 4}, completeMemoryGiB(8<<30))
28
assert.DeepEqual(t, []float32{1, 2, 4, 8, 10}, completeMemoryGiB(20<<30))
29
}
30
31
func TestBuildPortForwardExpression(t *testing.T) {
32
tests := []struct {
33
name string
34
portForwards []string
35
expected string
36
expectError bool
37
}{
38
{
39
name: "empty port forwards",
40
portForwards: []string{},
41
expected: "",
42
},
43
{
44
name: "single dynamic port forward",
45
portForwards: []string{"8080:80"},
46
expected: `.portForwards += [{"guestPort": "80", "hostPort": "8080", "static": false}]`,
47
},
48
{
49
name: "single static port forward",
50
portForwards: []string{"8080:80,static=true"},
51
expected: `.portForwards += [{"guestPort": "80", "hostPort": "8080", "static": true}]`,
52
},
53
{
54
name: "multiple mixed port forwards",
55
portForwards: []string{"8080:80", "2222:22,static=true", "3000:3000"},
56
expected: `.portForwards += [{"guestPort": "80", "hostPort": "8080", "static": false},{"guestPort": "22", "hostPort": "2222", "static": true},{"guestPort": "3000", "hostPort": "3000", "static": false}]`,
57
},
58
{
59
name: "invalid format - missing colon",
60
portForwards: []string{"8080"},
61
expectError: true,
62
},
63
{
64
name: "invalid format - too many colons",
65
portForwards: []string{"8080:80:extra"},
66
expectError: true,
67
},
68
{
69
name: "invalid static parameter",
70
portForwards: []string{"8080:80,invalid=true"},
71
expectError: true,
72
},
73
{
74
name: "too many parameters",
75
portForwards: []string{"8080:80,static=true,extra=value"},
76
expectError: true,
77
},
78
{
79
name: "whitespace handling",
80
portForwards: []string{" 8080 : 80 , static=true "},
81
expected: `.portForwards += [{"guestPort": "80", "hostPort": "8080", "static": true}]`,
82
},
83
}
84
85
for _, tt := range tests {
86
t.Run(tt.name, func(t *testing.T) {
87
result, err := BuildPortForwardExpression(tt.portForwards)
88
if tt.expectError {
89
assert.Check(t, err != nil)
90
} else {
91
assert.NilError(t, err)
92
assert.Equal(t, tt.expected, result)
93
}
94
})
95
}
96
}
97
98
func TestParsePortForward(t *testing.T) {
99
tests := []struct {
100
name string
101
spec string
102
hostPort string
103
guestPort string
104
isStatic bool
105
expectError bool
106
}{
107
{
108
name: "dynamic port forward",
109
spec: "8080:80",
110
hostPort: "8080",
111
guestPort: "80",
112
isStatic: false,
113
},
114
{
115
name: "static port forward",
116
spec: "8080:80,static=true",
117
hostPort: "8080",
118
guestPort: "80",
119
isStatic: true,
120
},
121
{
122
name: "whitespace handling",
123
spec: " 8080 : 80 , static=true ",
124
hostPort: "8080",
125
guestPort: "80",
126
isStatic: true,
127
},
128
{
129
name: "invalid format - missing colon",
130
spec: "8080",
131
expectError: true,
132
},
133
{
134
name: "invalid format - too many colons",
135
spec: "8080:80:extra",
136
expectError: true,
137
},
138
{
139
name: "invalid parameter",
140
spec: "8080:80,invalid=true",
141
expectError: true,
142
},
143
{
144
name: "too many parameters",
145
spec: "8080:80,static=true,extra=value",
146
expectError: true,
147
},
148
}
149
150
for _, tt := range tests {
151
t.Run(tt.name, func(t *testing.T) {
152
hostPort, guestPort, isStatic, err := ParsePortForward(tt.spec)
153
if tt.expectError {
154
assert.Check(t, err != nil)
155
} else {
156
assert.NilError(t, err)
157
assert.Equal(t, tt.hostPort, hostPort)
158
assert.Equal(t, tt.guestPort, guestPort)
159
assert.Equal(t, tt.isStatic, isStatic)
160
}
161
})
162
}
163
}
164
165
func TestYQExpressions(t *testing.T) {
166
expand := func(s string) string {
167
s, err := localpathutil.Expand(s)
168
assert.NilError(t, err)
169
// `D:\foo` -> `D:\\foo` (appears in YAML)
170
s = strings.ReplaceAll(s, "\\", "\\\\")
171
return s
172
}
173
tests := []struct {
174
name string
175
args []string
176
newInstance bool
177
expected []string
178
expectError string
179
}{
180
{
181
name: "mount",
182
args: []string{"--mount", "/foo", "--mount", "./bar:w"},
183
newInstance: false,
184
expected: []string{`.mounts += [{"location": "` + expand("/foo") + `", "writable": false},{"location": "` + expand("./bar") + `", "writable": true}] | .mounts |= unique_by(.location)`},
185
},
186
{
187
name: "mount-only",
188
args: []string{"--mount-only", "/foo", "--mount-only", "/bar:w"},
189
newInstance: false,
190
expected: []string{`.mounts = [{"location": "` + expand("/foo") + `", "writable": false},{"location": "` + expand("/bar") + `", "writable": true}]`},
191
},
192
{
193
name: "mixture of mount and mount-only",
194
args: []string{"--mount", "/foo", "--mount-only", "/bar:w"},
195
newInstance: false,
196
expectError: "flag `--mount` conflicts with `--mount-only`",
197
},
198
}
199
for _, tt := range tests {
200
t.Run(tt.name, func(t *testing.T) {
201
cmd := &cobra.Command{}
202
RegisterEdit(cmd, "")
203
assert.NilError(t, cmd.ParseFlags(tt.args))
204
expr, err := YQExpressions(cmd.Flags(), tt.newInstance)
205
if tt.expectError != "" {
206
assert.ErrorContains(t, err, tt.expectError)
207
} else {
208
assert.NilError(t, err)
209
assert.DeepEqual(t, tt.expected, expr)
210
}
211
})
212
}
213
}
214
215