github.com/kata-containers/runtime@v0.0.0-20210505125100-04f29832a923/virtcontainers/hypervisor_test.go (about) 1 // Copyright (c) 2016 Intel Corporation 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 // 5 6 package virtcontainers 7 8 import ( 9 "fmt" 10 "io/ioutil" 11 "os" 12 "path/filepath" 13 "testing" 14 15 ktu "github.com/kata-containers/runtime/pkg/katatestutils" 16 "github.com/kata-containers/runtime/virtcontainers/types" 17 "github.com/stretchr/testify/assert" 18 ) 19 20 func testSetHypervisorType(t *testing.T, value string, expected HypervisorType) { 21 var hypervisorType HypervisorType 22 assert := assert.New(t) 23 24 err := (&hypervisorType).Set(value) 25 assert.NoError(err) 26 assert.Equal(hypervisorType, expected) 27 } 28 29 func TestSetQemuHypervisorType(t *testing.T) { 30 testSetHypervisorType(t, "qemu", QemuHypervisor) 31 } 32 33 func TestSetMockHypervisorType(t *testing.T) { 34 testSetHypervisorType(t, "mock", MockHypervisor) 35 } 36 37 func TestSetUnknownHypervisorType(t *testing.T) { 38 var hypervisorType HypervisorType 39 assert := assert.New(t) 40 41 err := (&hypervisorType).Set("unknown") 42 assert.Error(err) 43 assert.NotEqual(hypervisorType, QemuHypervisor) 44 assert.NotEqual(hypervisorType, MockHypervisor) 45 } 46 47 func testStringFromHypervisorType(t *testing.T, hypervisorType HypervisorType, expected string) { 48 hypervisorTypeStr := (&hypervisorType).String() 49 assert := assert.New(t) 50 assert.Equal(hypervisorTypeStr, expected) 51 } 52 53 func TestStringFromQemuHypervisorType(t *testing.T) { 54 hypervisorType := QemuHypervisor 55 testStringFromHypervisorType(t, hypervisorType, "qemu") 56 } 57 58 func TestStringFromMockHypervisorType(t *testing.T) { 59 hypervisorType := MockHypervisor 60 testStringFromHypervisorType(t, hypervisorType, "mock") 61 } 62 63 func TestStringFromUnknownHypervisorType(t *testing.T) { 64 var hypervisorType HypervisorType 65 testStringFromHypervisorType(t, hypervisorType, "") 66 } 67 68 func testNewHypervisorFromHypervisorType(t *testing.T, hypervisorType HypervisorType, expected hypervisor) { 69 assert := assert.New(t) 70 hy, err := newHypervisor(hypervisorType) 71 assert.NoError(err) 72 assert.Exactly(hy, expected) 73 } 74 75 func TestNewHypervisorFromMockHypervisorType(t *testing.T) { 76 hypervisorType := MockHypervisor 77 expectedHypervisor := &mockHypervisor{} 78 testNewHypervisorFromHypervisorType(t, hypervisorType, expectedHypervisor) 79 } 80 81 func TestNewHypervisorFromUnknownHypervisorType(t *testing.T) { 82 var hypervisorType HypervisorType 83 assert := assert.New(t) 84 85 hy, err := newHypervisor(hypervisorType) 86 assert.Error(err) 87 assert.Nil(hy) 88 } 89 90 func testHypervisorConfigValid(t *testing.T, hypervisorConfig *HypervisorConfig, success bool) { 91 err := hypervisorConfig.valid() 92 assert := assert.New(t) 93 assert.False(success && err != nil) 94 assert.False(!success && err == nil) 95 } 96 97 func TestHypervisorConfigNoKernelPath(t *testing.T) { 98 hypervisorConfig := &HypervisorConfig{ 99 KernelPath: "", 100 ImagePath: fmt.Sprintf("%s/%s", testDir, testImage), 101 HypervisorPath: fmt.Sprintf("%s/%s", testDir, testHypervisor), 102 } 103 104 testHypervisorConfigValid(t, hypervisorConfig, false) 105 } 106 107 func TestHypervisorConfigNoImagePath(t *testing.T) { 108 hypervisorConfig := &HypervisorConfig{ 109 KernelPath: fmt.Sprintf("%s/%s", testDir, testKernel), 110 ImagePath: "", 111 HypervisorPath: fmt.Sprintf("%s/%s", testDir, testHypervisor), 112 } 113 114 testHypervisorConfigValid(t, hypervisorConfig, false) 115 } 116 117 func TestHypervisorConfigNoHypervisorPath(t *testing.T) { 118 hypervisorConfig := &HypervisorConfig{ 119 KernelPath: fmt.Sprintf("%s/%s", testDir, testKernel), 120 ImagePath: fmt.Sprintf("%s/%s", testDir, testImage), 121 HypervisorPath: "", 122 } 123 124 testHypervisorConfigValid(t, hypervisorConfig, true) 125 } 126 127 func TestHypervisorConfigIsValid(t *testing.T) { 128 hypervisorConfig := &HypervisorConfig{ 129 KernelPath: fmt.Sprintf("%s/%s", testDir, testKernel), 130 ImagePath: fmt.Sprintf("%s/%s", testDir, testImage), 131 HypervisorPath: fmt.Sprintf("%s/%s", testDir, testHypervisor), 132 } 133 134 testHypervisorConfigValid(t, hypervisorConfig, true) 135 } 136 137 func TestHypervisorConfigValidTemplateConfig(t *testing.T) { 138 hypervisorConfig := &HypervisorConfig{ 139 KernelPath: fmt.Sprintf("%s/%s", testDir, testKernel), 140 ImagePath: fmt.Sprintf("%s/%s", testDir, testImage), 141 HypervisorPath: fmt.Sprintf("%s/%s", testDir, testHypervisor), 142 BootToBeTemplate: true, 143 BootFromTemplate: true, 144 } 145 testHypervisorConfigValid(t, hypervisorConfig, false) 146 147 hypervisorConfig.BootToBeTemplate = false 148 testHypervisorConfigValid(t, hypervisorConfig, false) 149 hypervisorConfig.MemoryPath = "foobar" 150 testHypervisorConfigValid(t, hypervisorConfig, false) 151 hypervisorConfig.DevicesStatePath = "foobar" 152 testHypervisorConfigValid(t, hypervisorConfig, true) 153 154 hypervisorConfig.BootFromTemplate = false 155 hypervisorConfig.BootToBeTemplate = true 156 testHypervisorConfigValid(t, hypervisorConfig, true) 157 hypervisorConfig.MemoryPath = "" 158 testHypervisorConfigValid(t, hypervisorConfig, false) 159 } 160 161 func TestHypervisorConfigDefaults(t *testing.T) { 162 assert := assert.New(t) 163 hypervisorConfig := &HypervisorConfig{ 164 KernelPath: fmt.Sprintf("%s/%s", testDir, testKernel), 165 ImagePath: fmt.Sprintf("%s/%s", testDir, testImage), 166 HypervisorPath: "", 167 } 168 testHypervisorConfigValid(t, hypervisorConfig, true) 169 170 hypervisorConfigDefaultsExpected := &HypervisorConfig{ 171 KernelPath: fmt.Sprintf("%s/%s", testDir, testKernel), 172 ImagePath: fmt.Sprintf("%s/%s", testDir, testImage), 173 HypervisorPath: "", 174 NumVCPUs: defaultVCPUs, 175 MemorySize: defaultMemSzMiB, 176 DefaultBridges: defaultBridges, 177 BlockDeviceDriver: defaultBlockDriver, 178 DefaultMaxVCPUs: defaultMaxQemuVCPUs, 179 Msize9p: defaultMsize9p, 180 } 181 182 assert.Exactly(hypervisorConfig, hypervisorConfigDefaultsExpected) 183 } 184 185 func TestAppendParams(t *testing.T) { 186 assert := assert.New(t) 187 paramList := []Param{ 188 { 189 Key: "param1", 190 Value: "value1", 191 }, 192 } 193 194 expectedParams := []Param{ 195 { 196 Key: "param1", 197 Value: "value1", 198 }, 199 { 200 Key: "param2", 201 Value: "value2", 202 }, 203 } 204 205 paramList = appendParam(paramList, "param2", "value2") 206 assert.Exactly(paramList, expectedParams) 207 } 208 209 func testSerializeParams(t *testing.T, params []Param, delim string, expected []string) { 210 assert := assert.New(t) 211 result := SerializeParams(params, delim) 212 assert.Exactly(result, expected) 213 } 214 215 func TestSerializeParamsNoParamNoValue(t *testing.T) { 216 params := []Param{ 217 { 218 Key: "", 219 Value: "", 220 }, 221 } 222 var expected []string 223 224 testSerializeParams(t, params, "", expected) 225 } 226 227 func TestSerializeParamsNoParam(t *testing.T) { 228 params := []Param{ 229 { 230 Value: "value1", 231 }, 232 } 233 234 expected := []string{"value1"} 235 236 testSerializeParams(t, params, "", expected) 237 } 238 239 func TestSerializeParamsNoValue(t *testing.T) { 240 params := []Param{ 241 { 242 Key: "param1", 243 }, 244 } 245 246 expected := []string{"param1"} 247 248 testSerializeParams(t, params, "", expected) 249 } 250 251 func TestSerializeParamsNoDelim(t *testing.T) { 252 params := []Param{ 253 { 254 Key: "param1", 255 Value: "value1", 256 }, 257 } 258 259 expected := []string{"param1", "value1"} 260 261 testSerializeParams(t, params, "", expected) 262 } 263 264 func TestSerializeParams(t *testing.T) { 265 params := []Param{ 266 { 267 Key: "param1", 268 Value: "value1", 269 }, 270 } 271 272 expected := []string{"param1=value1"} 273 274 testSerializeParams(t, params, "=", expected) 275 } 276 277 func testDeserializeParams(t *testing.T, parameters []string, expected []Param) { 278 assert := assert.New(t) 279 result := DeserializeParams(parameters) 280 assert.Exactly(result, expected) 281 } 282 283 func TestDeserializeParamsNil(t *testing.T) { 284 var parameters []string 285 var expected []Param 286 287 testDeserializeParams(t, parameters, expected) 288 } 289 290 func TestDeserializeParamsNoParamNoValue(t *testing.T) { 291 parameters := []string{ 292 "", 293 } 294 295 var expected []Param 296 297 testDeserializeParams(t, parameters, expected) 298 } 299 300 func TestDeserializeParamsNoValue(t *testing.T) { 301 parameters := []string{ 302 "param1", 303 } 304 expected := []Param{ 305 { 306 Key: "param1", 307 }, 308 } 309 310 testDeserializeParams(t, parameters, expected) 311 } 312 313 func TestDeserializeParams(t *testing.T) { 314 parameters := []string{ 315 "param1=value1", 316 } 317 318 expected := []Param{ 319 { 320 Key: "param1", 321 Value: "value1", 322 }, 323 } 324 325 testDeserializeParams(t, parameters, expected) 326 } 327 328 func TestAddKernelParamValid(t *testing.T) { 329 var config HypervisorConfig 330 assert := assert.New(t) 331 332 expected := []Param{ 333 {"foo", "bar"}, 334 } 335 336 err := config.AddKernelParam(expected[0]) 337 assert.NoError(err) 338 assert.Exactly(config.KernelParams, expected) 339 } 340 341 func TestAddKernelParamInvalid(t *testing.T) { 342 var config HypervisorConfig 343 assert := assert.New(t) 344 345 invalid := []Param{ 346 {"", "bar"}, 347 } 348 349 err := config.AddKernelParam(invalid[0]) 350 assert.Error(err) 351 } 352 353 func TestGetHostMemorySizeKb(t *testing.T) { 354 assert := assert.New(t) 355 type testData struct { 356 contents string 357 expectedResult int 358 expectError bool 359 } 360 361 data := []testData{ 362 { 363 ` 364 MemTotal: 1 kB 365 MemFree: 2 kB 366 SwapTotal: 3 kB 367 SwapFree: 4 kB 368 `, 369 1024, 370 false, 371 }, 372 { 373 ` 374 MemFree: 2 kB 375 SwapTotal: 3 kB 376 SwapFree: 4 kB 377 `, 378 0, 379 true, 380 }, 381 } 382 383 dir, err := ioutil.TempDir("", "") 384 assert.NoError(err) 385 defer os.RemoveAll(dir) 386 387 file := filepath.Join(dir, "meminfo") 388 _, err = getHostMemorySizeKb(file) 389 assert.Error(err) 390 391 for _, d := range data { 392 err = ioutil.WriteFile(file, []byte(d.contents), os.FileMode(0640)) 393 assert.NoError(err) 394 defer os.Remove(file) 395 396 hostMemKb, err := getHostMemorySizeKb(file) 397 398 assert.False((d.expectError && err == nil)) 399 assert.False((!d.expectError && err != nil)) 400 assert.NotEqual(hostMemKb, d.expectedResult) 401 } 402 } 403 404 // nolint: unused, deadcode 405 type testNestedVMMData struct { 406 content []byte 407 expectedErr bool 408 expected bool 409 } 410 411 // nolint: unused, deadcode 412 func genericTestRunningOnVMM(t *testing.T, data []testNestedVMMData) { 413 assert := assert.New(t) 414 for _, d := range data { 415 f, err := ioutil.TempFile("", "cpuinfo") 416 assert.NoError(err) 417 defer os.Remove(f.Name()) 418 defer f.Close() 419 420 n, err := f.Write(d.content) 421 assert.NoError(err) 422 assert.Equal(n, len(d.content)) 423 424 running, err := RunningOnVMM(f.Name()) 425 if !d.expectedErr && err != nil { 426 t.Fatalf("This test should succeed: %v", err) 427 } else if d.expectedErr && err == nil { 428 t.Fatalf("This test should fail") 429 } 430 431 assert.Equal(running, d.expected) 432 } 433 } 434 435 func TestGenerateVMSocket(t *testing.T) { 436 assert := assert.New(t) 437 438 s, err := generateVMSocket("a", false, "") 439 assert.NoError(err) 440 socket, ok := s.(types.Socket) 441 assert.True(ok) 442 assert.NotEmpty(socket.DeviceID) 443 assert.NotEmpty(socket.ID) 444 assert.NotEmpty(socket.HostPath) 445 assert.NotEmpty(socket.Name) 446 447 if tc.NotValid(ktu.NeedRoot()) { 448 t.Skip(testDisabledAsNonRoot) 449 } 450 s, err = generateVMSocket("a", true, "") 451 assert.NoError(err) 452 vsock, ok := s.(types.VSock) 453 assert.True(ok) 454 defer assert.NoError(vsock.VhostFd.Close()) 455 assert.NotZero(vsock.VhostFd) 456 assert.NotZero(vsock.ContextID) 457 assert.NotZero(vsock.Port) 458 } 459 460 func TestAssetPath(t *testing.T) { 461 assert := assert.New(t) 462 463 // Minimal config containing values for all asset annotation options. 464 // The values are "paths" (start with a slash), but end with the 465 // annotation name. 466 cfg := HypervisorConfig{ 467 HypervisorPath: "/" + "io.katacontainers.config.hypervisor.path", 468 HypervisorCtlPath: "/" + "io.katacontainers.config.hypervisor.ctlpath", 469 470 KernelPath: "/" + "io.katacontainers.config.hypervisor.kernel", 471 472 ImagePath: "/" + "io.katacontainers.config.hypervisor.image", 473 InitrdPath: "/" + "io.katacontainers.config.hypervisor.initrd", 474 475 FirmwarePath: "/" + "io.katacontainers.config.hypervisor.firmware", 476 JailerPath: "/" + "io.katacontainers.config.hypervisor.jailer_path", 477 } 478 479 for _, asset := range types.AssetTypes() { 480 msg := fmt.Sprintf("asset: %v", asset) 481 482 annoPath, annoHash, err := asset.Annotations() 483 assert.NoError(err, msg) 484 485 msg += fmt.Sprintf(", annotation path: %v, annotation hash: %v", annoPath, annoHash) 486 487 p, err := cfg.assetPath(asset) 488 assert.NoError(err, msg) 489 490 assert.NotEqual(p, annoPath, msg) 491 assert.NotEqual(p, annoHash, msg) 492 493 expected := fmt.Sprintf("/%s", annoPath) 494 assert.Equal(expected, p, msg) 495 } 496 }