github.com/verrazzano/verrazzano@v1.7.1/tools/vz/pkg/analysis/main_test.go (about) 1 // Copyright (c) 2021, 2024, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 package analysis 4 5 import ( 6 "fmt" 7 "os" 8 "testing" 9 10 "github.com/stretchr/testify/assert" 11 "github.com/verrazzano/verrazzano/tools/vz/pkg/internal/util/log" 12 "github.com/verrazzano/verrazzano/tools/vz/pkg/internal/util/report" 13 vzhelper "github.com/verrazzano/verrazzano/tools/vz/test/helpers" 14 "k8s.io/cli-runtime/pkg/genericclioptions" 15 ) 16 17 // TestHandleMain Tests the handleMain function 18 // GIVEN a call to handleMain 19 // WHEN with valid/invalid inputs 20 // THEN exit codes returned are as expected 21 func TestHandleMain(_ *testing.T) { 22 // This is setting up the main.logger, do NOT set it as a var here (or you will get a nil reference running 23 // the test) 24 logger = log.GetDebugEnabledLogger() 25 analyzerType = "cluster" 26 } 27 28 // TestAnalyzeBad Tests the main Analyze function 29 // GIVEN a call to Analyze 30 // WHEN with invalid inputs 31 // THEN errors are generated as expected 32 func TestExecuteAnalysisBadArgs(t *testing.T) { 33 logger := log.GetDebugEnabledLogger() 34 stdoutFile, stderrFile := createStdTempFiles(t) 35 defer func() { 36 os.Remove(stdoutFile.Name()) 37 os.Remove(stderrFile.Name()) 38 }() 39 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 40 // Call the analyzer with an unknown type, give it a good cluster dump directory 41 err := Analyze(rc, logger, "badnamehere", "../test/cluster/image-pull-case1") 42 assert.NotNil(t, err) 43 // TODO: Check error message is what we expected here 44 45 } 46 func TestProblemPodsInCattleSystem(t *testing.T) { 47 logger := log.GetDebugEnabledLogger() 48 stdoutFile, stderrFile := createStdTempFiles(t) 49 defer func() { 50 os.Remove(stdoutFile.Name()) 51 os.Remove(stderrFile.Name()) 52 }() 53 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 54 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/testCattleSystempods") 55 assert.Nil(t, err) 56 57 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 58 assert.Nil(t, reportedIssues) 59 assert.False(t, len(reportedIssues) > 0) 60 problemPodsFound := 0 61 for _, issue := range reportedIssues { 62 if issue.Type == report.PodProblemsNotReported { 63 problemPodsFound++ 64 } 65 66 } 67 assert.True(t, problemPodsFound == 0) 68 } 69 70 // TestImagePullCase1 Tests that analysis of a cluster dump with image pull issues is handled 71 // GIVEN a call to analyze a cluster-snapshot 72 // WHEN the cluster-snapshot shows image pull issues 73 // THEN a report is generated with image pull issues identified 74 func TestImagePull(t *testing.T) { 75 logger := log.GetDebugEnabledLogger() 76 stdoutFile, stderrFile := createStdTempFiles(t) 77 defer func() { 78 os.Remove(stdoutFile.Name()) 79 os.Remove(stderrFile.Name()) 80 }() 81 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 82 report.ClearReports() 83 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/image-pull-case1") 84 assert.Nil(t, err) 85 86 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 87 assert.NotNil(t, reportedIssues) 88 assert.True(t, len(reportedIssues) > 0) 89 imagePullsFound := 0 90 for _, issue := range reportedIssues { 91 if issue.Type == report.ImagePullNotFound { 92 imagePullsFound++ 93 } 94 } 95 assert.True(t, imagePullsFound > 0) 96 } 97 98 // TestInsufficientMemory Tests that analysis of a cluster dump with pods that failed due to insufficient memory 99 // GIVEN a call to analyze a cluster-snapshot 100 // WHEN the cluster-snapshot shows pods with insufficient memory problems 101 // THEN a report is generated with issues identified 102 func TestInsufficientMemory(t *testing.T) { 103 logger := log.GetDebugEnabledLogger() 104 stdoutFile, stderrFile := createStdTempFiles(t) 105 defer func() { 106 os.Remove(stdoutFile.Name()) 107 os.Remove(stderrFile.Name()) 108 }() 109 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 110 report.ClearReports() 111 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/insufficient-mem") 112 assert.Nil(t, err) 113 114 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 115 assert.NotNil(t, reportedIssues) 116 assert.True(t, len(reportedIssues) > 0) 117 issuesFound := 0 118 for _, issue := range reportedIssues { 119 if issue.Type == report.InsufficientMemory { 120 issuesFound++ 121 } 122 } 123 assert.True(t, issuesFound > 0) 124 } 125 126 // TestProblemPodsNotReportedUninstall Tests that analysis of a cluster dump with pods that have unknown issues during 127 // uninstall, is handled 128 // GIVEN a call to analyze a cluster-snapshot 129 // WHEN the cluster-snapshot shows pods with problems that are not known issues 130 // THEN a report is generated with problem pod issues identified 131 func TestProblemPodsNotReportedUninstall(t *testing.T) { 132 logger := log.GetDebugEnabledLogger() 133 stdoutFile, stderrFile := createStdTempFiles(t) 134 defer func() { 135 os.Remove(stdoutFile.Name()) 136 os.Remove(stderrFile.Name()) 137 }() 138 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 139 report.ClearReports() 140 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/problem-pods") 141 assert.Nil(t, err) 142 143 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 144 assert.NotNil(t, reportedIssues) 145 assert.True(t, len(reportedIssues) > 0) 146 problemPodsFound := 0 147 for _, issue := range reportedIssues { 148 if issue.Type == report.PodProblemsNotReported { 149 problemPodsFound++ 150 } 151 } 152 assert.True(t, problemPodsFound > 0) 153 } 154 155 // TestProblemPodsNotReportedInstall Tests that analysis of a cluster dump with pods that have unknown issues during 156 // install, is handled 157 // GIVEN a call to analyze a cluster-snapshot 158 // WHEN the cluster-snapshot shows pods with problems that are not known issues 159 // THEN a report is generated with problem pod issues identified 160 func TestProblemPodsNotReportedInstall(t *testing.T) { 161 logger := log.GetDebugEnabledLogger() 162 stdoutFile, stderrFile := createStdTempFiles(t) 163 defer func() { 164 os.Remove(stdoutFile.Name()) 165 os.Remove(stderrFile.Name()) 166 }() 167 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 168 report.ClearReports() 169 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/problem-pods-install") 170 assert.Nil(t, err) 171 172 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 173 assert.NotNil(t, reportedIssues) 174 assert.True(t, len(reportedIssues) > 0) 175 176 exceededLBLimit := 0 177 for _, issue := range reportedIssues { 178 if issue.Type == report.IngressLBLimitExceeded { 179 exceededLBLimit++ 180 } 181 182 } 183 assert.True(t, exceededLBLimit > 0) 184 } 185 186 // TestLBIpNotSet Tests that analysis of a cluster dump where LB issue occurred with no IP set is handled 187 // GIVEN a call to analyze a cluster-snapshot 188 // WHEN the cluster-snapshot shows pods with problems that are not known issues 189 // THEN a report is generated with problem pod issues identified 190 // Note: With the latest changes to platform operator and analysis tool, the issue is reported differently. 191 // Commenting the test for now, and added a new test TestLBIpNotFound 192 //func TestLBIpNotSet(t *testing.T) { 193 // logger := log.GetDebugEnabledLogger() 194 195 // err := Analyze(logger, "cluster", "../internal/test/cluster/lb-ipnotset") 196 // assert.Nil(t, err) 197 198 // reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 199 // assert.NotNil(t, reportedIssues) 200 // assert.True(t, len(reportedIssues) > 0) 201 // problemsFound := 0 202 // for _, issue := range reportedIssues { 203 // if issue.Type == report.IngressNoLoadBalancerIP { 204 // problemsFound++ 205 // } 206 // } 207 // assert.True(t, problemsFound > 0) 208 //} 209 210 // TestLBIpNotFound Tests that analysis of a cluster dump where no IP was found for load balancer 211 // GIVEN a call to analyze a cluster-snapshot 212 // WHEN the cluster-snapshot shows pods with problems that are not known issues 213 // THEN a report is generated with problem pod issues identified 214 func TestLBIpNotFound(t *testing.T) { 215 logger := log.GetDebugEnabledLogger() 216 stdoutFile, stderrFile := createStdTempFiles(t) 217 defer func() { 218 os.Remove(stdoutFile.Name()) 219 os.Remove(stderrFile.Name()) 220 }() 221 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 222 report.ClearReports() 223 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/ingress-ip-not-found") 224 assert.Nil(t, err) 225 226 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 227 assert.NotNil(t, reportedIssues) 228 assert.True(t, len(reportedIssues) > 0) 229 problemsFound := 0 230 for _, issue := range reportedIssues { 231 if issue.Type == report.IngressNoIPFound { 232 problemsFound++ 233 } 234 } 235 assert.True(t, problemsFound > 0) 236 } 237 238 // TestIstioLBIpNotFound Tests that analysis of a cluster dump where no Istio Gateway IP was found 239 // GIVEN a call to analyze a cluster-snapshot 240 // WHEN the cluster-snapshot shows services with external IP problems 241 // THEN a report is generated with issues identified 242 func TestIstioLBIpNotFound(t *testing.T) { 243 logger := log.GetDebugEnabledLogger() 244 stdoutFile, stderrFile := createStdTempFiles(t) 245 defer func() { 246 os.Remove(stdoutFile.Name()) 247 os.Remove(stderrFile.Name()) 248 }() 249 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 250 report.ClearReports() 251 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/istio-ingress-ip-not-found") 252 assert.Nil(t, err) 253 254 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 255 assert.NotNil(t, reportedIssues) 256 assert.True(t, len(reportedIssues) > 0) 257 problemsFound := 0 258 for _, issue := range reportedIssues { 259 if issue.Type == report.IstioIngressNoIP { 260 problemsFound++ 261 } 262 } 263 assert.True(t, problemsFound > 0) 264 } 265 266 // TODO: Enable this test once there is a cluster dump for this use case 267 // TestIngressInstall Tests that analysis of a cluster dump where Ingress install failed without more info handled 268 // GIVEN a call to analyze a cluster-snapshot 269 // WHEN the cluster-snapshot shows pods with problems that are not known issues 270 // THEN a report is generated with problem pod issues identified 271 // func TestIngressInstall(t *testing.T) { 272 // logger := log.GetDebugEnabledLogger() 273 274 // err := Analyze(logger, "cluster", "../internal/test/cluster/ingress-install-unknown") 275 // assert.Nil(t, err) 276 277 // reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 278 // assert.NotNil(t, reportedIssues) 279 // assert.True(t, len(reportedIssues) > 0) 280 // problemsFound := 0 281 // for _, issue := range reportedIssues { 282 // if issue.Type == report.IngressInstallFailure { 283 // problemsFound++ 284 // } 285 // } 286 // assert.True(t, problemsFound > 0) 287 //} 288 289 // TestLBLimitExceeded Test that analysis of a cluster dump where Ingress install failed due to LoadBalancer service limit handled 290 // GIVEN a call to analyze a cluster-snapshot 291 // WHEN the cluster-snapshot shows pods with problems that are not known issues 292 // THEN a report is generated with problem pod issues identified 293 func TestLBLimitExceeded(t *testing.T) { 294 logger := log.GetDebugEnabledLogger() 295 stdoutFile, stderrFile := createStdTempFiles(t) 296 defer func() { 297 os.Remove(stdoutFile.Name()) 298 os.Remove(stderrFile.Name()) 299 }() 300 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 301 report.ClearReports() 302 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/ingress-lb-limit") 303 assert.Nil(t, err) 304 305 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 306 assert.NotNil(t, reportedIssues) 307 assert.True(t, len(reportedIssues) > 0) 308 problemsFound := 0 309 for _, issue := range reportedIssues { 310 if issue.Type == report.IngressLBLimitExceeded { 311 problemsFound++ 312 } 313 } 314 assert.True(t, problemsFound > 0) 315 } 316 317 // TestOciIPLimitExceeded Tests that analysis of a cluster dump where Ingress install failed due to OCI limit handled 318 // GIVEN a call to analyze a cluster-snapshot 319 // WHEN the cluster-snapshot shows pods with problems that are not known issues 320 // THEN a report is generated with problem pod issues identified 321 func TestOciIPLimitExceeded(t *testing.T) { 322 logger := log.GetDebugEnabledLogger() 323 stdoutFile, stderrFile := createStdTempFiles(t) 324 defer func() { 325 os.Remove(stdoutFile.Name()) 326 os.Remove(stderrFile.Name()) 327 }() 328 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 329 report.ClearReports() 330 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/ingress-oci-limit") 331 assert.Nil(t, err) 332 333 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 334 assert.NotNil(t, reportedIssues) 335 assert.True(t, len(reportedIssues) > 0) 336 problemsFound := 0 337 for _, issue := range reportedIssues { 338 if issue.Type == report.IngressOciIPLimitExceeded { 339 problemsFound++ 340 } 341 } 342 assert.True(t, problemsFound > 0) 343 } 344 345 // TestOciLBInvalidShape Tests that analysis of a cluster dump where an invalid shape specified for OCI load balancer 346 // GIVEN a call to analyze a cluster-snapshot 347 // WHEN the cluster-snapshot shows pods with problems that are not known issues 348 // THEN a report is generated with problem pod issues identified 349 func TestOciLBInvalidShape(t *testing.T) { 350 logger := log.GetDebugEnabledLogger() 351 stdoutFile, stderrFile := createStdTempFiles(t) 352 defer func() { 353 os.Remove(stdoutFile.Name()) 354 os.Remove(stderrFile.Name()) 355 }() 356 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 357 report.ClearReports() 358 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/ingress-invalid-shape") 359 assert.Nil(t, err) 360 361 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 362 assert.NotNil(t, reportedIssues) 363 assert.True(t, len(reportedIssues) > 0) 364 problemsFound := 0 365 for _, issue := range reportedIssues { 366 if issue.Type == report.IngressShapeInvalid { 367 problemsFound++ 368 } 369 } 370 assert.True(t, problemsFound > 0) 371 } 372 373 // TestPendingPods that analysis of a cluster dump where pending pods only is handled 374 // GIVEN a call to analyze a cluster-snapshot 375 // WHEN the cluster-snapshot shows pods with problems that are not known issues 376 // THEN a report is generated with problem pod issues identified 377 func TestPendingPods(t *testing.T) { 378 logger := log.GetDebugEnabledLogger() 379 stdoutFile, stderrFile := createStdTempFiles(t) 380 defer func() { 381 os.Remove(stdoutFile.Name()) 382 os.Remove(stderrFile.Name()) 383 }() 384 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 385 report.ClearReports() 386 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/pending-pods") 387 assert.Nil(t, err) 388 389 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 390 assert.NotNil(t, reportedIssues) 391 assert.True(t, len(reportedIssues) > 0) 392 problemsFound := 0 393 for _, issue := range reportedIssues { 394 if issue.Type == report.PendingPods { 395 problemsFound++ 396 } 397 } 398 assert.True(t, problemsFound > 0) 399 } 400 401 // TestUnknownInstall Tests that analysis of a cluster dump where install failed without more info handled 402 // GIVEN a call to analyze a cluster-snapshot 403 // WHEN the cluster-snapshot shows pods with problems that are not known issues 404 // THEN a report is generated with problem pod issues identified 405 // Commenting this test as there might not be an install issue like this now. 406 //func TestUnknownInstall(t *testing.T) { 407 // logger := log.GetDebugEnabledLogger() 408 409 // err := Analyze(logger, "cluster", "../internal/test/cluster/install-unknown") 410 // assert.Nil(t, err) 411 412 // reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 413 // assert.NotNil(t, reportedIssues) 414 // assert.True(t, len(reportedIssues) > 0) 415 // problemsFound := 0 416 // for _, issue := range reportedIssues { 417 // if issue.Type == report.InstallFailure { 418 // problemsFound++ 419 // } 420 // } 421 // assert.True(t, problemsFound > 0) 422 //} 423 424 // TestIstioIngressInstallFailure Tests that analysis of a cluster dump when IstioIngressLoadBalancer was not created 425 // GIVEN a call to analyze a cluster-snapshot 426 // WHEN the cluster-snapshot shows private subnet not allowed in public LB. 427 // THEN a report is generated with issues identified 428 func TestIstioIngressInstallFailure(t *testing.T) { 429 logger := log.GetDebugEnabledLogger() 430 stdoutFile, stderrFile := createStdTempFiles(t) 431 defer func() { 432 os.Remove(stdoutFile.Name()) 433 os.Remove(stderrFile.Name()) 434 }() 435 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 436 report.ClearReports() 437 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/istio-loadbalancer-creation-issue") 438 assert.Nil(t, err) 439 440 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 441 assert.NotNil(t, reportedIssues) 442 assert.True(t, len(reportedIssues) > 0) 443 problemsFound := 0 444 for _, issue := range reportedIssues { 445 if issue.Type == report.IstioIngressPrivateSubnet { 446 problemsFound++ 447 } 448 } 449 assert.True(t, problemsFound > 0) 450 } 451 452 // TestComponentsNotReadyNoErrorMsg Tests that analysis of a cluster dump where there are failed components with no error message in the VPO logs 453 // GIVEN a call to analyze a cluster-snapshot 454 // WHEN the cluster-snapshot shows that there is install failure with no known root cause 455 // THEN a report is generated with supporting messages from the events related to those failed components' pods 456 func TestComponentsNotReadyNoErrorMsg(t *testing.T) { 457 logger := log.GetDebugEnabledLogger() 458 stdoutFile, stderrFile := createStdTempFiles(t) 459 defer func() { 460 os.Remove(stdoutFile.Name()) 461 os.Remove(stderrFile.Name()) 462 }() 463 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 464 report.ClearReports() 465 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/components-not-ready") 466 assert.Nil(t, err) 467 468 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 469 assert.NotNil(t, reportedIssues) 470 assert.True(t, len(reportedIssues) > 0) 471 472 problemsFound := 0 473 for _, issue := range reportedIssues { 474 if issue.Type == report.InstallFailure { 475 problemsFound++ 476 // Two supporting messages are always included. Rest should come from events related to failed components 477 assert.True(t, len(issue.SupportingData[0].Messages) > 2) 478 } 479 } 480 assert.True(t, problemsFound > 0) 481 } 482 483 // TestExternalDNSConfigurationIssue Tests that analysis of a cluster dump when dns(oci,custom dns) was not configured 484 // GIVEN a call to analyze a cluster-snapshot 485 // WHEN the cluster-snapshot shows private subnet not allowed in public LB. 486 // THEN a report is generated with issues identified 487 func TestExternalDNSConfigurationIssue(t *testing.T) { 488 logger := log.GetDebugEnabledLogger() 489 stdoutFile, stderrFile := createStdTempFiles(t) 490 defer func() { 491 os.Remove(stdoutFile.Name()) 492 os.Remove(stderrFile.Name()) 493 }() 494 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 495 report.ClearReports() 496 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/external-dns-issue") 497 assert.Nil(t, err) 498 499 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 500 assert.NotNil(t, reportedIssues) 501 assert.True(t, len(reportedIssues) > 0) 502 problemsFound := 0 503 for _, issue := range reportedIssues { 504 if issue.Type == report.ExternalDNSConfigureIssue { 505 problemsFound++ 506 } 507 } 508 assert.True(t, problemsFound > 0) 509 } 510 511 // TestResourceJSONWithVerrazzanoFormat Tests that analysis of a cluster dump 512 // when there is an install failure and the verrazzano-resource.json contains Verrazzano type instead of VerrazzanoList type 513 // GIVEN a call to analyze a cluster-snapshot 514 // WHEN the cluster-snapshot shows components not in ready state 515 // THEN a report is generated with install failure 516 func TestResourceJSONWithVerrazzanoFormat(t *testing.T) { 517 logger := log.GetDebugEnabledLogger() 518 stdoutFile, stderrFile := createStdTempFiles(t) 519 defer func() { 520 os.Remove(stdoutFile.Name()) 521 os.Remove(stderrFile.Name()) 522 }() 523 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 524 report.ClearReports() 525 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/install-failure-verrazzano-format-json") 526 assert.Nil(t, err) 527 528 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 529 assert.NotNil(t, reportedIssues) 530 assert.True(t, len(reportedIssues) > 0) 531 problemsFound := 0 532 for _, issue := range reportedIssues { 533 fmt.Println(issue) 534 if issue.Type == report.InstallFailure { 535 problemsFound++ 536 } 537 } 538 assert.True(t, problemsFound > 0) 539 } 540 541 // TestKeycloakDataMigrationFailure tests that analysis of a cluster dump when keycloak data migration during upgrade has failed 542 // GIVEN a call to analyze a cluster-snapshot 543 // WHEN the cluster-snapshot data load job failure 544 // THEN a report is generated with issues identified 545 func TestKeycloakDataMigrationFailure(t *testing.T) { 546 logger := log.GetDebugEnabledLogger() 547 stdoutFile, stderrFile := createStdTempFiles(t) 548 defer func() { 549 os.Remove(stdoutFile.Name()) 550 os.Remove(stderrFile.Name()) 551 }() 552 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 553 report.ClearReports() 554 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/keycloak-data-migration-failure") 555 assert.Nil(t, err) 556 557 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 558 assert.NotNil(t, reportedIssues) 559 assert.True(t, len(reportedIssues) > 0) 560 problemsFound := 0 561 for _, issue := range reportedIssues { 562 if issue.Type == report.KeycloakDataMigrationFailure { 563 problemsFound++ 564 } 565 } 566 assert.True(t, problemsFound > 0) 567 } 568 569 // TestCertificateVZClientHangingIssue tests analysis of a cluster dump when the VZ Client is hanging 570 // GIVEN a call to analyze a cluster-snapshot 571 // WHEN the VZ Client is hanging on a certificate, but the certificate is not expired 572 // THEN a report is generated with issues identified 573 // This test also tests for detecting a separate expired certificate in the certificates.json 574 func TestCertificateVZClientHangingIssue(t *testing.T) { 575 logger := log.GetDebugEnabledLogger() 576 stdoutFile, stderrFile := createStdTempFiles(t) 577 defer func() { 578 os.Remove(stdoutFile.Name()) 579 os.Remove(stderrFile.Name()) 580 }() 581 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 582 report.ClearReports() 583 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/testCLIHangingIssue") 584 assert.Nil(t, err) 585 586 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 587 assert.NotNil(t, reportedIssues) 588 assert.True(t, len(reportedIssues) > 0) 589 problemsFound := 0 590 for _, issue := range reportedIssues { 591 if issue.Type == report.VZClientHangingIssueDueToLongCertificateApproval { 592 problemsFound++ 593 } 594 if issue.Type == report.CertificateExpired { 595 problemsFound++ 596 } 597 } 598 assert.True(t, problemsFound == 2) 599 } 600 601 // TestBlockStorageFailure Tests that analysis of a cluster dump when Block Storage limit is exceeded 602 // GIVEN a call to analyze a cluster-snapshot 603 // WHEN the cluster-snapshot shows private subnet not allowed in public LB. 604 // THEN a report is generated with issues identified 605 func TestBlockStorageFailure(t *testing.T) { 606 logger := log.GetDebugEnabledLogger() 607 stdoutFile, stderrFile := createStdTempFiles(t) 608 defer func() { 609 os.Remove(stdoutFile.Name()) 610 os.Remove(stderrFile.Name()) 611 }() 612 rc := vzhelper.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile}) 613 report.ClearReports() 614 err := Analyze(rc, logger, "cluster", "../internal/test/cluster/blockstorage-limitexceeded") 615 assert.Nil(t, err) 616 617 reportedIssues := report.GetAllSourcesFilteredIssues(logger, true, 0, 0) 618 assert.NotNil(t, reportedIssues) 619 assert.True(t, len(reportedIssues) > 0) 620 problemsFound := 0 621 for _, issue := range reportedIssues { 622 if issue.Type == report.BlockStorageLimitExceeded { 623 problemsFound++ 624 } 625 } 626 assert.True(t, problemsFound > 0) 627 } 628 629 // createStdTempFiles creates temporary files for stdout and stderr. 630 func createStdTempFiles(t *testing.T) (*os.File, *os.File) { 631 stdoutFile, err := os.CreateTemp("", "tmpstdout") 632 assert.NoError(t, err) 633 634 stderrFile, err := os.CreateTemp("", "tmpstderr") 635 assert.NoError(t, err) 636 637 return stdoutFile, stderrFile 638 }