github.com/jaylevin/jenkins-library@v1.230.4/pkg/kubernetes/helm_test.go (about) 1 package kubernetes 2 3 import ( 4 "errors" 5 "testing" 6 7 "github.com/SAP/jenkins-library/pkg/log" 8 "github.com/SAP/jenkins-library/pkg/mock" 9 "github.com/stretchr/testify/assert" 10 ) 11 12 type helmMockUtilsBundle struct { 13 *mock.ExecMockRunner 14 *mock.FilesMock 15 *mock.HttpClientMock 16 } 17 18 func newHelmMockUtilsBundle() helmMockUtilsBundle { 19 utils := helmMockUtilsBundle{ 20 ExecMockRunner: &mock.ExecMockRunner{}, 21 FilesMock: &mock.FilesMock{}, 22 HttpClientMock: &mock.HttpClientMock{ 23 FileUploads: map[string]string{}, 24 }, 25 } 26 return utils 27 } 28 29 func TestRunHelm(t *testing.T) { 30 31 t.Run("Helm add command", func(t *testing.T) { 32 utils := newHelmMockUtilsBundle() 33 34 testTable := []struct { 35 config HelmExecuteOptions 36 expectedConfig []string 37 generalVerbose bool 38 }{ 39 { 40 config: HelmExecuteOptions{ 41 TargetRepositoryURL: "https://charts.helm.sh/stable", 42 TargetRepositoryName: "stable", 43 TargetRepositoryUser: "userAccount", 44 TargetRepositoryPassword: "pwdAccount", 45 }, 46 expectedConfig: []string{"repo", "add", "--username", "userAccount", "--password", "pwdAccount", "stable", "https://charts.helm.sh/stable"}, 47 generalVerbose: false, 48 }, 49 { 50 config: HelmExecuteOptions{ 51 TargetRepositoryURL: "https://charts.helm.sh/stable", 52 TargetRepositoryName: "test", 53 }, 54 expectedConfig: []string{"repo", "add", "test", "https://charts.helm.sh/stable", "--debug"}, 55 generalVerbose: true, 56 }, 57 } 58 59 for i, testCase := range testTable { 60 helmExecute := HelmExecute{ 61 utils: utils, 62 config: testCase.config, 63 verbose: testCase.generalVerbose, 64 stdout: log.Writer(), 65 } 66 err := helmExecute.runHelmAdd() 67 assert.NoError(t, err) 68 assert.Equal(t, mock.ExecCall{Exec: "helm", Params: testCase.expectedConfig}, utils.Calls[i]) 69 } 70 }) 71 72 t.Run("Helm upgrade command", func(t *testing.T) { 73 utils := newHelmMockUtilsBundle() 74 75 testTable := []struct { 76 config HelmExecuteOptions 77 generalVerbose bool 78 expectedAddConfig []string 79 expectedUpgradeConfig []string 80 }{ 81 { 82 config: HelmExecuteOptions{ 83 DeploymentName: "test_deployment", 84 ChartPath: ".", 85 Namespace: "test_namespace", 86 ForceUpdates: true, 87 HelmDeployWaitSeconds: 3456, 88 AdditionalParameters: []string{"additional parameter"}, 89 Image: "dtzar/helm-kubectl:3.4.1", 90 TargetRepositoryName: "test", 91 TargetRepositoryURL: "https://charts.helm.sh/stable", 92 }, 93 generalVerbose: true, 94 expectedAddConfig: []string{"repo", "add", "test", "https://charts.helm.sh/stable", "--debug"}, 95 expectedUpgradeConfig: []string{"upgrade", "test_deployment", ".", "--debug", "--install", "--namespace", "test_namespace", "--force", "--wait", "--timeout", "3456s", "--atomic", "additional parameter"}, 96 }, 97 } 98 99 for _, testCase := range testTable { 100 helmExecute := HelmExecute{ 101 utils: utils, 102 config: testCase.config, 103 verbose: testCase.generalVerbose, 104 stdout: log.Writer(), 105 } 106 err := helmExecute.RunHelmUpgrade() 107 assert.NoError(t, err) 108 assert.Equal(t, mock.ExecCall{Exec: "helm", Params: testCase.expectedAddConfig}, utils.Calls[0]) 109 assert.Equal(t, mock.ExecCall{Exec: "helm", Params: testCase.expectedUpgradeConfig}, utils.Calls[1]) 110 } 111 }) 112 113 t.Run("Helm lint command", func(t *testing.T) { 114 utils := newHelmMockUtilsBundle() 115 116 testTable := []struct { 117 config HelmExecuteOptions 118 expectedConfig []string 119 }{ 120 { 121 config: HelmExecuteOptions{ 122 ChartPath: ".", 123 }, 124 expectedConfig: []string{"lint", "."}, 125 }, 126 } 127 128 for i, testCase := range testTable { 129 helmExecute := HelmExecute{ 130 utils: utils, 131 config: testCase.config, 132 verbose: false, 133 stdout: log.Writer(), 134 } 135 err := helmExecute.RunHelmLint() 136 assert.NoError(t, err) 137 assert.Equal(t, mock.ExecCall{Exec: "helm", Params: testCase.expectedConfig}, utils.Calls[i]) 138 } 139 }) 140 141 t.Run("Helm install command", func(t *testing.T) { 142 t.Parallel() 143 144 testTable := []struct { 145 config HelmExecuteOptions 146 generalVerbose bool 147 expectedConfigInstall []string 148 expectedConfigAdd []string 149 }{ 150 { 151 config: HelmExecuteOptions{ 152 ChartPath: ".", 153 DeploymentName: "testPackage", 154 Namespace: "test-namespace", 155 HelmDeployWaitSeconds: 525, 156 TargetRepositoryURL: "https://charts.helm.sh/stable", 157 TargetRepositoryName: "test", 158 }, 159 generalVerbose: false, 160 expectedConfigAdd: []string{"repo", "add", "test", "https://charts.helm.sh/stable"}, 161 expectedConfigInstall: []string{"install", "testPackage", ".", "--namespace", "test-namespace", "--create-namespace", "--atomic", "--wait", "--timeout", "525s"}, 162 }, 163 { 164 config: HelmExecuteOptions{ 165 ChartPath: ".", 166 DeploymentName: "testPackage", 167 Namespace: "test-namespace", 168 HelmDeployWaitSeconds: 525, 169 KeepFailedDeployments: false, 170 AdditionalParameters: []string{"--set-file my_script=dothings.sh"}, 171 TargetRepositoryURL: "https://charts.helm.sh/stable", 172 TargetRepositoryName: "test", 173 }, 174 generalVerbose: true, 175 expectedConfigAdd: []string{"repo", "add", "test", "https://charts.helm.sh/stable", "--debug"}, 176 expectedConfigInstall: []string{"install", "testPackage", ".", "--namespace", "test-namespace", "--create-namespace", "--atomic", "--wait", "--timeout", "525s", "--set-file my_script=dothings.sh", "--debug", "--dry-run"}, 177 }, 178 } 179 180 for _, testCase := range testTable { 181 utils := newHelmMockUtilsBundle() 182 helmExecute := HelmExecute{ 183 utils: utils, 184 config: testCase.config, 185 verbose: testCase.generalVerbose, 186 stdout: log.Writer(), 187 } 188 err := helmExecute.RunHelmInstall() 189 assert.NoError(t, err) 190 assert.Equal(t, mock.ExecCall{Exec: "helm", Params: testCase.expectedConfigAdd}, utils.Calls[0]) 191 assert.Equal(t, mock.ExecCall{Exec: "helm", Params: testCase.expectedConfigInstall}, utils.Calls[1]) 192 } 193 }) 194 195 t.Run("Helm uninstal command", func(t *testing.T) { 196 t.Parallel() 197 198 testTable := []struct { 199 config HelmExecuteOptions 200 generalVerbose bool 201 expectedConfig []string 202 }{ 203 { 204 config: HelmExecuteOptions{ 205 ChartPath: ".", 206 DeploymentName: "testPackage", 207 Namespace: "test-namespace", 208 TargetRepositoryName: "test", 209 }, 210 expectedConfig: []string{"uninstall", "testPackage", "--namespace", "test-namespace"}, 211 }, 212 { 213 config: HelmExecuteOptions{ 214 ChartPath: ".", 215 DeploymentName: "testPackage", 216 Namespace: "test-namespace", 217 HelmDeployWaitSeconds: 524, 218 TargetRepositoryName: "test", 219 }, 220 generalVerbose: true, 221 expectedConfig: []string{"uninstall", "testPackage", "--namespace", "test-namespace", "--wait", "--timeout", "524s", "--debug", "--dry-run"}, 222 }, 223 } 224 225 for _, testCase := range testTable { 226 utils := newHelmMockUtilsBundle() 227 helmExecute := HelmExecute{ 228 utils: utils, 229 config: testCase.config, 230 verbose: testCase.generalVerbose, 231 stdout: log.Writer(), 232 } 233 err := helmExecute.RunHelmUninstall() 234 assert.NoError(t, err) 235 assert.Equal(t, mock.ExecCall{Exec: "helm", Params: testCase.expectedConfig}, utils.Calls[1]) 236 } 237 }) 238 239 t.Run("Helm package command", func(t *testing.T) { 240 utils := newHelmMockUtilsBundle() 241 242 testTable := []struct { 243 config HelmExecuteOptions 244 expectedConfig []string 245 }{ 246 { 247 config: HelmExecuteOptions{ 248 ChartPath: ".", 249 DeploymentName: "testPackage", 250 }, 251 expectedConfig: []string{"package", "."}, 252 }, 253 { 254 config: HelmExecuteOptions{ 255 ChartPath: ".", 256 DeploymentName: "testPackage", 257 Version: "1.2.3", 258 PackageDependencyUpdate: true, 259 AppVersion: "9.8.7", 260 }, 261 expectedConfig: []string{"package", ".", "--version", "1.2.3", "--dependency-update", "--app-version", "9.8.7"}, 262 }, 263 } 264 265 for i, testCase := range testTable { 266 helmExecute := HelmExecute{ 267 utils: utils, 268 config: testCase.config, 269 verbose: false, 270 stdout: log.Writer(), 271 } 272 err := helmExecute.runHelmPackage() 273 assert.NoError(t, err) 274 assert.Equal(t, mock.ExecCall{Exec: "helm", Params: testCase.expectedConfig}, utils.Calls[i]) 275 } 276 }) 277 278 t.Run("Helm test command", func(t *testing.T) { 279 t.Parallel() 280 utils := newHelmMockUtilsBundle() 281 282 testTable := []struct { 283 config HelmExecuteOptions 284 expectedConfig []string 285 }{ 286 { 287 config: HelmExecuteOptions{ 288 ChartPath: ".", 289 DeploymentName: "testPackage", 290 }, 291 expectedConfig: []string{"test", "."}, 292 }, 293 { 294 config: HelmExecuteOptions{ 295 ChartPath: ".", 296 DeploymentName: "testPackage", 297 FilterTest: "name=test1,name=test2", 298 DumpLogs: true, 299 }, 300 expectedConfig: []string{"test", ".", "--filter", "name=test1,name=test2", "--logs"}, 301 }, 302 } 303 304 for i, testCase := range testTable { 305 helmExecute := HelmExecute{ 306 utils: utils, 307 config: testCase.config, 308 verbose: false, 309 stdout: log.Writer(), 310 } 311 err := helmExecute.RunHelmTest() 312 assert.NoError(t, err) 313 assert.Equal(t, mock.ExecCall{Exec: "helm", Params: testCase.expectedConfig}, utils.Calls[i]) 314 } 315 }) 316 317 t.Run("Helm unistall command(error processing)", func(t *testing.T) { 318 t.Parallel() 319 utils := newHelmMockUtilsBundle() 320 321 testTable := []struct { 322 config HelmExecuteOptions 323 expectedError error 324 }{ 325 { 326 config: HelmExecuteOptions{ 327 ChartPath: ".", 328 DeploymentName: "testPackage", 329 }, 330 expectedError: errors.New("failed to execute deployments: there is no TargetRepositoryName value. 'helm repo add' command requires 2 arguments"), 331 }, 332 { 333 config: HelmExecuteOptions{ 334 ChartPath: ".", 335 DeploymentName: "testPackage", 336 TargetRepositoryName: "test", 337 }, 338 expectedError: errors.New("namespace has not been set, please configure namespace parameter"), 339 }, 340 } 341 342 for _, testCase := range testTable { 343 helmExecute := HelmExecute{ 344 utils: utils, 345 config: testCase.config, 346 verbose: false, 347 stdout: log.Writer(), 348 } 349 err := helmExecute.RunHelmUninstall() 350 if testCase.expectedError != nil { 351 assert.Error(t, err) 352 assert.Equal(t, testCase.expectedError, err) 353 } 354 } 355 }) 356 357 t.Run("Helm init", func(t *testing.T) { 358 t.Parallel() 359 utils := newHelmMockUtilsBundle() 360 361 testTable := []struct { 362 config HelmExecuteOptions 363 expectedError error 364 }{ 365 { 366 config: HelmExecuteOptions{ 367 ChartPath: ".", 368 Namespace: "test-namespace", 369 DeploymentName: "testPackage", 370 KubeContext: "kubeContext", 371 KubeConfig: "kubeConfig", 372 }, 373 expectedError: nil, 374 }, 375 } 376 377 for _, testCase := range testTable { 378 helmExecute := HelmExecute{ 379 utils: utils, 380 config: testCase.config, 381 verbose: false, 382 stdout: log.Writer(), 383 } 384 err := helmExecute.runHelmInit() 385 if testCase.expectedError != nil { 386 assert.Error(t, err) 387 assert.Equal(t, testCase.expectedError, err) 388 } else { 389 assert.NoError(t, err) 390 } 391 392 } 393 }) 394 395 t.Run("Helm dependency command", func(t *testing.T) { 396 utils := newHelmMockUtilsBundle() 397 398 testTable := []struct { 399 config HelmExecuteOptions 400 expectedError error 401 expectedResult []string 402 }{ 403 { 404 config: HelmExecuteOptions{ 405 ChartPath: ".", 406 }, 407 expectedError: errors.New("there is no dependency value. Possible values are build, list, update"), 408 expectedResult: nil, 409 }, 410 { 411 config: HelmExecuteOptions{ 412 ChartPath: ".", 413 Dependency: "update", 414 }, 415 expectedError: nil, 416 expectedResult: []string{"dependency", "update", "."}, 417 }, 418 } 419 420 for _, testCase := range testTable { 421 helmExecute := HelmExecute{ 422 utils: utils, 423 config: testCase.config, 424 verbose: false, 425 stdout: log.Writer(), 426 } 427 err := helmExecute.RunHelmDependency() 428 if testCase.expectedError != nil { 429 assert.Error(t, err) 430 assert.Equal(t, testCase.expectedError, err) 431 } else { 432 assert.NoError(t, err) 433 assert.Equal(t, mock.ExecCall{Exec: "helm", Params: testCase.expectedResult}, utils.Calls[0]) 434 } 435 436 } 437 }) 438 439 t.Run("Helm publish command", func(t *testing.T) { 440 utils := newHelmMockUtilsBundle() 441 442 config := HelmExecuteOptions{ 443 TargetRepositoryURL: "https://my.target.repository.local/", 444 TargetRepositoryUser: "testUser", 445 TargetRepositoryPassword: "testPWD", 446 PublishVersion: "1.2.3", 447 DeploymentName: "test_helm_chart", 448 ChartPath: ".", 449 } 450 utils.ReturnFileUploadStatus = 200 451 452 helmExecute := HelmExecute{ 453 utils: utils, 454 config: config, 455 verbose: false, 456 stdout: log.Writer(), 457 } 458 459 err := helmExecute.RunHelmPublish() 460 if assert.NoError(t, err) { 461 assert.Equal(t, 1, len(utils.FileUploads)) 462 assert.Equal(t, "https://my.target.repository.local/test_helm_chart/test_helm_chart-1.2.3.tgz", utils.FileUploads["test_helm_chart-1.2.3.tgz"]) 463 } 464 }) 465 466 t.Run("Helm run command", func(t *testing.T) { 467 utils := newHelmMockUtilsBundle() 468 469 testTable := []struct { 470 helmParams []string 471 config HelmExecuteOptions 472 expectedConfig []string 473 }{ 474 { 475 helmParams: []string{"lint, package, publish"}, 476 config: HelmExecuteOptions{ 477 HelmCommand: "lint_package_publish", 478 }, 479 expectedConfig: []string{"lint, package, publish"}, 480 }, 481 } 482 483 for _, testCase := range testTable { 484 helmExecute := HelmExecute{ 485 utils: utils, 486 config: testCase.config, 487 verbose: false, 488 stdout: log.Writer(), 489 } 490 err := helmExecute.runHelmCommand(testCase.helmParams) 491 assert.NoError(t, err) 492 assert.Equal(t, mock.ExecCall{Exec: "helm", Params: testCase.expectedConfig}, utils.Calls[0]) 493 } 494 495 }) 496 497 }