@@ -34,6 +34,7 @@ import (
34
34
"github.com/firecracker-microvm/firecracker-go-sdk/fctesting"
35
35
"github.com/golang/mock/gomock"
36
36
log "github.com/sirupsen/logrus"
37
+ "github.com/stretchr/testify/assert"
37
38
)
38
39
39
40
const (
@@ -92,13 +93,7 @@ func TestMicroVMExecution(t *testing.T) {
92
93
os .Remove (metricsFifo )
93
94
}()
94
95
95
- vmlinuxPath := filepath .Join (testDataPath , "./vmlinux" )
96
- if _ , err := os .Stat (vmlinuxPath ); err != nil {
97
- t .Fatalf ("Cannot find vmlinux file: %s\n " +
98
- `Verify that you have a vmlinux file at "%s" or set the ` +
99
- "`%s` environment variable to the correct location." ,
100
- err , vmlinuxPath , testDataPathEnv )
101
- }
96
+ vmlinuxPath := getVmlinuxPath (t )
102
97
103
98
cfg := Config {
104
99
SocketPath : socketPath ,
@@ -183,19 +178,64 @@ func TestStartVMM(t *testing.T) {
183
178
defer cancel ()
184
179
err = m .startVMM (timeout )
185
180
if err != nil {
186
- t .Errorf ("startVMM failed: %s" , err )
187
- } else {
188
- defer m .StopVMM ()
181
+ t .Fatalf ("startVMM failed: %s" , err )
182
+ }
183
+ defer m .StopVMM ()
189
184
190
- select {
191
- case <- timeout .Done ():
192
- if timeout .Err () == context .DeadlineExceeded {
193
- t .Log ("firecracker ran for 250ms" )
194
- } else {
195
- t .Errorf ("startVMM returned %s" , m .Wait (ctx ))
196
- }
185
+ select {
186
+ case <- timeout .Done ():
187
+ if timeout .Err () == context .DeadlineExceeded {
188
+ t .Log ("firecracker ran for 250ms" )
189
+ } else {
190
+ t .Errorf ("startVMM returned %s" , m .Wait (ctx ))
197
191
}
198
192
}
193
+
194
+ }
195
+
196
+ func TestStartVMMOnce (t * testing.T ) {
197
+ socketPath := filepath .Join ("testdata" , "fc-start-vmm-test.sock" )
198
+ defer os .Remove (socketPath )
199
+
200
+ cfg := Config {
201
+ SocketPath : socketPath ,
202
+ DisableValidation : true ,
203
+ KernelImagePath : getVmlinuxPath (t ),
204
+ MachineCfg : models.MachineConfiguration {
205
+ VcpuCount : 1 ,
206
+ },
207
+ }
208
+ ctx := context .Background ()
209
+ cmd := VMCommandBuilder {}.
210
+ WithSocketPath (cfg .SocketPath ).
211
+ WithBin (getFirecrackerBinaryPath ()).
212
+ Build (ctx )
213
+ m , err := NewMachine (ctx , cfg , WithProcessRunner (cmd ))
214
+ if err != nil {
215
+ t .Fatalf ("unexpected error: %v" , err )
216
+ }
217
+ defer m .StopVMM ()
218
+
219
+ timeout , cancel := context .WithTimeout (ctx , 250 * time .Millisecond )
220
+ defer cancel ()
221
+ err = m .Start (timeout )
222
+ if err != nil {
223
+ t .Fatalf ("startVMM failed: %s" , err )
224
+ }
225
+ defer m .StopVMM ()
226
+ err = m .Start (timeout )
227
+ assert .Error (t , err , "should return an error when Start is called multiple times" )
228
+ assert .Equal (t , ErrAlreadyStarted , err , "should be ErrAlreadyStarted" )
229
+
230
+ select {
231
+ case <- timeout .Done ():
232
+ if timeout .Err () == context .DeadlineExceeded {
233
+ t .Log ("firecracker ran for 250ms" )
234
+ } else {
235
+ t .Errorf ("startVMM returned %s" , m .Wait (ctx ))
236
+ }
237
+ }
238
+
199
239
}
200
240
201
241
func getFirecrackerBinaryPath () string {
@@ -205,6 +245,18 @@ func getFirecrackerBinaryPath() string {
205
245
return filepath .Join (testDataPath , firecrackerBinaryPath )
206
246
}
207
247
248
+ func getVmlinuxPath (t * testing.T ) string {
249
+ t .Helper ()
250
+ vmlinuxPath := filepath .Join (testDataPath , "./vmlinux" )
251
+ if _ , err := os .Stat (vmlinuxPath ); err != nil {
252
+ t .Fatalf ("Cannot find vmlinux file: %s\n " +
253
+ `Verify that you have a vmlinux file at "%s" or set the ` +
254
+ "`%s` environment variable to the correct location." ,
255
+ err , vmlinuxPath , testDataPathEnv )
256
+ }
257
+ return vmlinuxPath
258
+ }
259
+
208
260
func testCreateMachine (ctx context.Context , t * testing.T , m * Machine ) {
209
261
err := m .createMachine (ctx )
210
262
if err != nil {
0 commit comments