github.com/zhizhiboom/nomad@v0.8.5-0.20180907175415-f28fd3a1a056/client/fingerprint_manager_test.go (about) 1 package client 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/hashicorp/nomad/client/config" 8 "github.com/hashicorp/nomad/helper/testlog" 9 "github.com/hashicorp/nomad/testutil" 10 "github.com/stretchr/testify/require" 11 ) 12 13 func TestFingerprintManager_Run_MockDriver(t *testing.T) { 14 t.Parallel() 15 require := require.New(t) 16 testClient := TestClient(t, nil) 17 18 testClient.logger = testlog.Logger(t) 19 defer testClient.Shutdown() 20 21 fm := NewFingerprintManager( 22 testClient.GetConfig, 23 testClient.config.Node, 24 testClient.shutdownCh, 25 testClient.updateNodeFromFingerprint, 26 testClient.updateNodeFromDriver, 27 testlog.Logger(t), 28 ) 29 30 err := fm.Run() 31 require.Nil(err) 32 33 node := testClient.config.Node 34 35 require.NotNil(node.Drivers["mock_driver"]) 36 require.True(node.Drivers["mock_driver"].Detected) 37 require.True(node.Drivers["mock_driver"].Healthy) 38 } 39 40 func TestFingerprintManager_Run_ResourcesFingerprint(t *testing.T) { 41 t.Parallel() 42 require := require.New(t) 43 testClient := TestClient(t, nil) 44 45 testClient.logger = testlog.Logger(t) 46 defer testClient.Shutdown() 47 48 fm := NewFingerprintManager( 49 testClient.GetConfig, 50 testClient.config.Node, 51 testClient.shutdownCh, 52 testClient.updateNodeFromFingerprint, 53 testClient.updateNodeFromDriver, 54 testClient.logger, 55 ) 56 57 err := fm.Run() 58 require.Nil(err) 59 60 node := testClient.config.Node 61 62 require.NotEqual(0, node.Resources.CPU) 63 require.NotEqual(0, node.Resources.MemoryMB) 64 require.NotZero(node.Resources.DiskMB) 65 } 66 67 func TestFingerprintManager_Fingerprint_Run(t *testing.T) { 68 t.Parallel() 69 require := require.New(t) 70 testClient := TestClient(t, nil) 71 72 testClient.logger = testlog.Logger(t) 73 defer testClient.Shutdown() 74 75 fm := NewFingerprintManager( 76 testClient.GetConfig, 77 testClient.config.Node, 78 testClient.shutdownCh, 79 testClient.updateNodeFromFingerprint, 80 testClient.updateNodeFromDriver, 81 testClient.logger, 82 ) 83 84 err := fm.Run() 85 require.Nil(err) 86 87 node := testClient.config.Node 88 89 require.NotNil(node.Drivers["raw_exec"]) 90 require.True(node.Drivers["raw_exec"].Detected) 91 require.True(node.Drivers["raw_exec"].Healthy) 92 } 93 94 func TestFingerprintManager_Fingerprint_Periodic(t *testing.T) { 95 t.Parallel() 96 require := require.New(t) 97 testClient := TestClient(t, func(c *config.Config) { 98 c.Options = map[string]string{ 99 "test.shutdown_periodic_after": "true", 100 "test.shutdown_periodic_duration": "2", 101 } 102 }) 103 104 testClient.logger = testlog.Logger(t) 105 defer testClient.Shutdown() 106 107 fm := NewFingerprintManager( 108 testClient.GetConfig, 109 testClient.config.Node, 110 testClient.shutdownCh, 111 testClient.updateNodeFromFingerprint, 112 testClient.updateNodeFromDriver, 113 testClient.logger, 114 ) 115 116 err := fm.Run() 117 require.Nil(err) 118 119 { 120 // Ensure the mock driver is registered and healthy on the client 121 testutil.WaitForResult(func() (bool, error) { 122 fm.nodeLock.Lock() 123 defer fm.nodeLock.Unlock() 124 node := fm.node 125 dinfo, ok := node.Drivers["mock_driver"] 126 if !ok || !dinfo.Detected || !dinfo.Healthy { 127 return false, fmt.Errorf("mock driver should be detected and healthy: %+v", dinfo) 128 } 129 130 return true, nil 131 }, func(err error) { 132 t.Fatalf("err: %v", err) 133 }) 134 } 135 // Ensure that the client fingerprinter eventually removes this attribute and 136 // marks the driver as unhealthy 137 { 138 testutil.WaitForResult(func() (bool, error) { 139 fm.nodeLock.Lock() 140 defer fm.nodeLock.Unlock() 141 node := fm.node 142 dinfo, ok := node.Drivers["mock_driver"] 143 if !ok || dinfo.Detected || dinfo.Healthy { 144 return false, fmt.Errorf("mock driver should not be detected and healthy") 145 } 146 return true, nil 147 }, func(err error) { 148 t.Fatalf("err: %v", err) 149 }) 150 } 151 } 152 153 // This is a temporary measure to check that a driver has both attributes on a 154 // node set as well as DriverInfo. 155 func TestFingerprintManager_HealthCheck_Driver(t *testing.T) { 156 t.Parallel() 157 require := require.New(t) 158 testClient := TestClient(t, func(c *config.Config) { 159 c.Options = map[string]string{ 160 "driver.raw_exec.enable": "1", 161 "test.shutdown_periodic_after": "true", 162 "test.shutdown_periodic_duration": "2", 163 } 164 }) 165 166 testClient.logger = testlog.Logger(t) 167 defer testClient.Shutdown() 168 169 fm := NewFingerprintManager( 170 testClient.GetConfig, 171 testClient.config.Node, 172 testClient.shutdownCh, 173 testClient.updateNodeFromFingerprint, 174 testClient.updateNodeFromDriver, 175 testClient.logger, 176 ) 177 178 err := fm.Run() 179 require.Nil(err) 180 181 // Ensure the mock driver is registered and healthy on the client 182 testutil.WaitForResult(func() (bool, error) { 183 fm.nodeLock.Lock() 184 node := fm.node 185 defer fm.nodeLock.Unlock() 186 187 mockDriverAttribute := node.Attributes["driver.mock_driver"] 188 if mockDriverAttribute == "" { 189 return false, fmt.Errorf("mock driver info should be set on the client attributes") 190 } 191 mockDriverInfo := node.Drivers["mock_driver"] 192 if mockDriverInfo == nil { 193 return false, fmt.Errorf("mock driver info should be set on the client") 194 } 195 if !mockDriverInfo.Healthy { 196 return false, fmt.Errorf("mock driver info should be healthy") 197 } 198 return true, nil 199 }, func(err error) { 200 t.Fatalf("err: %v", err) 201 }) 202 203 // Ensure that a default driver without health checks enabled is registered and healthy on the client 204 testutil.WaitForResult(func() (bool, error) { 205 fm.nodeLock.Lock() 206 node := fm.node 207 defer fm.nodeLock.Unlock() 208 209 rawExecAttribute := node.Attributes["driver.raw_exec"] 210 if rawExecAttribute == "" { 211 return false, fmt.Errorf("raw exec info should be set on the client attributes") 212 } 213 rawExecInfo := node.Drivers["raw_exec"] 214 if rawExecInfo == nil { 215 return false, fmt.Errorf("raw exec driver info should be set on the client") 216 } 217 if !rawExecInfo.Detected { 218 return false, fmt.Errorf("raw exec driver should be detected") 219 } 220 return true, nil 221 }, func(err error) { 222 t.Fatalf("err: %v", err) 223 }) 224 225 // Ensure the mock driver is registered 226 testutil.WaitForResult(func() (bool, error) { 227 fm.nodeLock.Lock() 228 node := fm.node 229 defer fm.nodeLock.Unlock() 230 231 mockDriverAttribute := node.Attributes["driver.mock_driver"] 232 if mockDriverAttribute == "" { 233 return false, fmt.Errorf("mock driver info should set on the client attributes") 234 } 235 mockDriverInfo := node.Drivers["mock_driver"] 236 if mockDriverInfo == nil { 237 return false, fmt.Errorf("mock driver info should be set on the client") 238 } 239 if !mockDriverInfo.Healthy { 240 return false, fmt.Errorf("mock driver info should not be healthy") 241 } 242 return true, nil 243 }, func(err error) { 244 t.Fatalf("err: %v", err) 245 }) 246 247 // Ensure that we don't duplicate health check information on the driver 248 // health information 249 fm.nodeLock.Lock() 250 node := fm.node 251 fm.nodeLock.Unlock() 252 mockDriverAttributes := node.Drivers["mock_driver"].Attributes 253 require.NotContains(mockDriverAttributes, "driver.mock_driver") 254 } 255 256 func TestFingerprintManager_HealthCheck_Periodic(t *testing.T) { 257 t.Parallel() 258 require := require.New(t) 259 testClient := TestClient(t, func(c *config.Config) { 260 c.Options = map[string]string{ 261 "test.shutdown_periodic_after": "true", 262 "test.shutdown_periodic_duration": "2", 263 } 264 }) 265 266 testClient.logger = testlog.Logger(t) 267 defer testClient.Shutdown() 268 269 fm := NewFingerprintManager( 270 testClient.GetConfig, 271 testClient.config.Node, 272 testClient.shutdownCh, 273 testClient.updateNodeFromFingerprint, 274 testClient.updateNodeFromDriver, 275 testClient.logger, 276 ) 277 278 err := fm.Run() 279 require.Nil(err) 280 281 { 282 // Ensure the mock driver is registered and healthy on the client 283 testutil.WaitForResult(func() (bool, error) { 284 fm.nodeLock.Lock() 285 node := fm.node 286 defer fm.nodeLock.Unlock() 287 288 mockDriverInfo := node.Drivers["mock_driver"] 289 if mockDriverInfo == nil { 290 return false, fmt.Errorf("mock driver info should be set on the client") 291 } 292 if !mockDriverInfo.Detected { 293 return false, fmt.Errorf("mock driver info should be detected") 294 } 295 if !mockDriverInfo.Healthy { 296 return false, fmt.Errorf("mock driver info should be healthy") 297 } 298 return true, nil 299 }, func(err error) { 300 t.Fatalf("err: %v", err) 301 }) 302 } 303 { 304 // Ensure that the client health check eventually removes this attribute and 305 // marks the driver as unhealthy 306 testutil.WaitForResult(func() (bool, error) { 307 fm.nodeLock.Lock() 308 node := fm.node 309 defer fm.nodeLock.Unlock() 310 311 mockDriverInfo := node.Drivers["mock_driver"] 312 if mockDriverInfo == nil { 313 return false, fmt.Errorf("mock driver info should be set on the client") 314 } 315 if !mockDriverInfo.Detected { 316 return false, fmt.Errorf("mock driver info should be detected") 317 } 318 if !mockDriverInfo.Healthy { 319 return false, fmt.Errorf("mock driver info should be healthy") 320 } 321 return true, nil 322 }, func(err error) { 323 t.Fatalf("err: %v", err) 324 }) 325 } 326 { 327 // Ensure that the client health check eventually removes this attribute and 328 // marks the driver as unhealthy 329 testutil.WaitForResult(func() (bool, error) { 330 fm.nodeLock.Lock() 331 node := fm.node 332 defer fm.nodeLock.Unlock() 333 334 mockDriverInfo := node.Drivers["mock_driver"] 335 if mockDriverInfo == nil { 336 return false, fmt.Errorf("mock driver info should be set on the client") 337 } 338 if mockDriverInfo.Detected { 339 return false, fmt.Errorf("mock driver should be detected") 340 } 341 if mockDriverInfo.Healthy { 342 return false, fmt.Errorf("mock driver should not be healthy") 343 } 344 return true, nil 345 }, func(err error) { 346 t.Fatalf("err: %v", err) 347 }) 348 } 349 } 350 351 func TestFimgerprintManager_Run_InWhitelist(t *testing.T) { 352 t.Parallel() 353 require := require.New(t) 354 355 testClient := TestClient(t, func(c *config.Config) { 356 c.Options = map[string]string{ 357 "test.shutdown_periodic_after": "true", 358 "test.shutdown_periodic_duration": "2", 359 } 360 }) 361 362 testClient.logger = testlog.Logger(t) 363 defer testClient.Shutdown() 364 365 fm := NewFingerprintManager( 366 testClient.GetConfig, 367 testClient.config.Node, 368 testClient.shutdownCh, 369 testClient.updateNodeFromFingerprint, 370 testClient.updateNodeFromDriver, 371 testClient.logger, 372 ) 373 374 err := fm.Run() 375 require.Nil(err) 376 377 node := testClient.config.Node 378 379 require.NotEqual(node.Attributes["cpu.frequency"], "") 380 } 381 382 func TestFingerprintManager_Run_InBlacklist(t *testing.T) { 383 t.Parallel() 384 require := require.New(t) 385 testClient := TestClient(t, func(c *config.Config) { 386 c.Options = map[string]string{ 387 "fingerprint.whitelist": " arch,memory,foo,bar ", 388 "fingerprint.blacklist": " cpu ", 389 } 390 }) 391 392 testClient.logger = testlog.Logger(t) 393 defer testClient.Shutdown() 394 395 fm := NewFingerprintManager( 396 testClient.GetConfig, 397 testClient.config.Node, 398 testClient.shutdownCh, 399 testClient.updateNodeFromFingerprint, 400 testClient.updateNodeFromDriver, 401 testClient.logger, 402 ) 403 404 err := fm.Run() 405 require.Nil(err) 406 407 node := testClient.config.Node 408 409 require.NotContains(node.Attributes, "cpu.frequency") 410 require.NotEqual(node.Attributes["memory.totalbytes"], "") 411 } 412 413 func TestFingerprintManager_Run_Combination(t *testing.T) { 414 t.Parallel() 415 require := require.New(t) 416 417 testClient := TestClient(t, func(c *config.Config) { 418 c.Options = map[string]string{ 419 "fingerprint.whitelist": " arch,cpu,memory,foo,bar ", 420 "fingerprint.blacklist": " memory,nomad ", 421 } 422 }) 423 424 testClient.logger = testlog.Logger(t) 425 defer testClient.Shutdown() 426 427 fm := NewFingerprintManager( 428 testClient.GetConfig, 429 testClient.config.Node, 430 testClient.shutdownCh, 431 testClient.updateNodeFromFingerprint, 432 testClient.updateNodeFromDriver, 433 testClient.logger, 434 ) 435 436 err := fm.Run() 437 require.Nil(err) 438 439 node := testClient.config.Node 440 441 require.NotEqual(node.Attributes["cpu.frequency"], "") 442 require.NotEqual(node.Attributes["cpu.arch"], "") 443 require.NotContains(node.Attributes, "memory.totalbytes") 444 require.NotContains(node.Attributes, "nomad.version") 445 } 446 447 func TestFingerprintManager_Run_WhitelistDrivers(t *testing.T) { 448 t.Parallel() 449 require := require.New(t) 450 testClient := TestClient(t, func(c *config.Config) { 451 c.Options = map[string]string{ 452 "driver.raw_exec.enable": "1", 453 "driver.whitelist": " raw_exec , foo ", 454 } 455 }) 456 457 testClient.logger = testlog.Logger(t) 458 defer testClient.Shutdown() 459 460 fm := NewFingerprintManager( 461 testClient.GetConfig, 462 testClient.config.Node, 463 testClient.shutdownCh, 464 testClient.updateNodeFromFingerprint, 465 testClient.updateNodeFromDriver, 466 testClient.logger, 467 ) 468 469 err := fm.Run() 470 require.Nil(err) 471 472 node := testClient.config.Node 473 require.NotNil(node.Drivers["raw_exec"]) 474 require.NotContains(node.Drivers, "java") 475 } 476 477 func TestFingerprintManager_Run_AllDriversBlacklisted(t *testing.T) { 478 t.Parallel() 479 require := require.New(t) 480 481 testClient := TestClient(t, func(c *config.Config) { 482 c.Options = map[string]string{ 483 "driver.whitelist": " foo,bar,baz ", 484 } 485 }) 486 487 testClient.logger = testlog.Logger(t) 488 defer testClient.Shutdown() 489 490 fm := NewFingerprintManager( 491 testClient.GetConfig, 492 testClient.config.Node, 493 testClient.shutdownCh, 494 testClient.updateNodeFromFingerprint, 495 testClient.updateNodeFromDriver, 496 testClient.logger, 497 ) 498 499 err := fm.Run() 500 require.Nil(err) 501 502 node := testClient.config.Node 503 504 require.NotContains(node.Attributes, "driver.raw_exec") 505 require.NotContains(node.Attributes, "driver.exec") 506 require.NotContains(node.Attributes, "driver.docker") 507 } 508 509 func TestFingerprintManager_Run_DriversWhiteListBlacklistCombination(t *testing.T) { 510 t.Parallel() 511 require := require.New(t) 512 513 testClient := TestClient(t, func(c *config.Config) { 514 c.Options = map[string]string{ 515 "driver.raw_exec.enable": "1", 516 "driver.whitelist": " raw_exec,exec,foo,bar,baz ", 517 "driver.blacklist": " exec,foo,bar,baz ", 518 } 519 }) 520 521 testClient.logger = testlog.Logger(t) 522 defer testClient.Shutdown() 523 524 fm := NewFingerprintManager( 525 testClient.GetConfig, 526 testClient.config.Node, 527 testClient.shutdownCh, 528 testClient.updateNodeFromFingerprint, 529 testClient.updateNodeFromDriver, 530 testClient.logger, 531 ) 532 533 err := fm.Run() 534 require.Nil(err) 535 536 node := testClient.config.Node 537 538 require.NotNil(node.Drivers["raw_exec"]) 539 require.NotContains(node.Drivers, "exec") 540 } 541 542 func TestFingerprintManager_Run_DriversInBlacklist(t *testing.T) { 543 t.Parallel() 544 require := require.New(t) 545 546 testClient := TestClient(t, func(c *config.Config) { 547 c.Options = map[string]string{ 548 "driver.raw_exec.enable": "1", 549 "driver.whitelist": " raw_exec,foo,bar,baz ", 550 "driver.blacklist": " exec,foo,bar,baz ", 551 } 552 }) 553 554 testClient.logger = testlog.Logger(t) 555 defer testClient.Shutdown() 556 557 fm := NewFingerprintManager( 558 testClient.GetConfig, 559 testClient.config.Node, 560 testClient.shutdownCh, 561 testClient.updateNodeFromFingerprint, 562 testClient.updateNodeFromDriver, 563 testClient.logger, 564 ) 565 566 err := fm.Run() 567 require.Nil(err) 568 569 node := testClient.config.Node 570 571 require.NotNil(node.Drivers["raw_exec"]) 572 require.NotContains(node.Drivers, "exec") 573 }