github.com/jenkins-x/jx-api@v0.0.24/pkg/config/install_requirements_test.go (about) 1 package config_test 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path" 8 "path/filepath" 9 "testing" 10 11 "github.com/stretchr/testify/require" 12 13 "github.com/ghodss/yaml" 14 "github.com/jenkins-x/jx-api/pkg/cloud" 15 "github.com/jenkins-x/jx-api/pkg/config" 16 "github.com/jenkins-x/jx-api/pkg/util" 17 "github.com/jenkins-x/jx-logging/pkg/log" 18 "github.com/stretchr/testify/assert" 19 ) 20 21 const ( 22 KindGitHub = "github" 23 ) 24 25 var ( 26 testDataDir = path.Join("test_data") 27 ) 28 29 func TestRequirementsConfigMarshalExistingFile(t *testing.T) { 30 t.Parallel() 31 32 dir, err := ioutil.TempDir("", "test-requirements-config-") 33 assert.NoError(t, err, "should create a temporary config dir") 34 35 expectedClusterName := "my-cluster" 36 expectedSecretStorage := config.SecretStorageTypeVault 37 expectedDomain := "cheese.co.uk" 38 expectedPipelineUserName := "someone" 39 expectedPipelineUserEmail := "someone@acme.com" 40 41 file := filepath.Join(dir, config.RequirementsConfigFileName) 42 requirements := config.NewRequirementsConfig() 43 requirements.SecretStorage = expectedSecretStorage 44 requirements.Cluster.ClusterName = expectedClusterName 45 requirements.Ingress.Domain = expectedDomain 46 requirements.Kaniko = true 47 requirements.PipelineUser = &config.UserNameEmailConfig{ 48 Username: expectedPipelineUserName, 49 Email: expectedPipelineUserEmail, 50 } 51 52 err = requirements.SaveConfig(file) 53 assert.NoError(t, err, "failed to save file %s", file) 54 55 requirements, fileName, err := config.LoadRequirementsConfig(dir, config.DefaultFailOnValidationError) 56 assert.NoError(t, err, "failed to load requirements file in dir %s", dir) 57 assert.FileExists(t, fileName) 58 59 assert.Equal(t, true, requirements.Kaniko, "requirements.Kaniko") 60 assert.Equal(t, expectedClusterName, requirements.Cluster.ClusterName, "requirements.ClusterName") 61 assert.Equal(t, expectedSecretStorage, requirements.SecretStorage, "requirements.SecretStorage") 62 assert.Equal(t, expectedDomain, requirements.Ingress.Domain, "requirements.Domain") 63 64 // lets check we can load the file from a sub dir 65 subDir := filepath.Join(dir, "subdir") 66 requirements, fileName, err = config.LoadRequirementsConfig(subDir, config.DefaultFailOnValidationError) 67 assert.NoError(t, err, "failed to load requirements file in subDir: %s", subDir) 68 assert.FileExists(t, fileName) 69 70 t.Logf("generated requirements file %s\n", fileName) 71 72 assert.Equal(t, true, requirements.Kaniko, "requirements.Kaniko") 73 assert.Equal(t, expectedClusterName, requirements.Cluster.ClusterName, "requirements.ClusterName") 74 assert.Equal(t, expectedSecretStorage, requirements.SecretStorage, "requirements.SecretStorage") 75 assert.Equal(t, expectedDomain, requirements.Ingress.Domain, "requirements.Domain") 76 77 require.NotNil(t, requirements.PipelineUser, "requirements.PipelineUser") 78 assert.Equal(t, expectedPipelineUserName, requirements.PipelineUser.Username, "requirements.PipelineUser.Username") 79 assert.Equal(t, expectedPipelineUserEmail, requirements.PipelineUser.Email, "requirements.PipelineUser.Email") 80 81 } 82 83 func Test_OverrideRequirementsFromEnvironment_does_not_initialise_nil_structs(t *testing.T) { 84 requirements, fileName, err := config.LoadRequirementsConfig(testDataDir, config.DefaultFailOnValidationError) 85 assert.NoError(t, err, "failed to load requirements file in dir %s", testDataDir) 86 assert.FileExists(t, fileName) 87 88 requirements.OverrideRequirementsFromEnvironment(func(in string) (string, error) { 89 return "", nil 90 }) 91 92 tempDir, err := ioutil.TempDir("", "test-requirements-config") 93 assert.NoError(t, err, "should create a temporary config dir") 94 defer func() { 95 _ = os.RemoveAll(tempDir) 96 }() 97 98 err = requirements.SaveConfig(filepath.Join(tempDir, config.RequirementsConfigFileName)) 99 assert.NoError(t, err, "failed to save requirements file in dir %s", tempDir) 100 101 overrideRequirements, fileName, err := config.LoadRequirementsConfig(tempDir, config.DefaultFailOnValidationError) 102 assert.NoError(t, err, "failed to load requirements file in dir %s", testDataDir) 103 assert.FileExists(t, fileName) 104 105 assert.Nil(t, overrideRequirements.BuildPacks, "nil values should not be populated") 106 } 107 108 func Test_OverrideRequirementsFromEnvironment_populate_requirements_from_environment_variables(t *testing.T) { 109 var overrideTests = []struct { 110 envKey string 111 envValue string 112 expectedRequirements config.RequirementsConfig 113 }{ 114 // RequirementsConfig 115 {config.RequirementSecretStorageType, "vault", config.RequirementsConfig{SecretStorage: "vault"}}, 116 {config.RequirementKaniko, "true", config.RequirementsConfig{Kaniko: true}}, 117 {config.RequirementKaniko, "false", config.RequirementsConfig{Kaniko: false}}, 118 {config.RequirementKaniko, "", config.RequirementsConfig{Kaniko: false}}, 119 {config.RequirementRepository, "bucketrepo", config.RequirementsConfig{Repository: "bucketrepo"}}, 120 {config.RequirementWebhook, "prow", config.RequirementsConfig{Webhook: "prow"}}, 121 {config.RequirementGitAppEnabled, "true", config.RequirementsConfig{GithubApp: &config.GithubAppConfig{Enabled: true}}}, 122 {config.RequirementGitAppEnabled, "false", config.RequirementsConfig{GithubApp: &config.GithubAppConfig{Enabled: false}}}, 123 {config.RequirementGitAppURL, "https://my-github-app", config.RequirementsConfig{GithubApp: &config.GithubAppConfig{URL: "https://my-github-app"}}}, 124 125 // ClusterConfig 126 {config.RequirementClusterName, "my-cluster", config.RequirementsConfig{Cluster: config.ClusterConfig{ClusterName: "my-cluster"}}}, 127 {config.RequirementProject, "my-project", config.RequirementsConfig{Cluster: config.ClusterConfig{ProjectID: "my-project"}}}, 128 {config.RequirementZone, "my-zone", config.RequirementsConfig{Cluster: config.ClusterConfig{Zone: "my-zone"}}}, 129 {config.RequirementChartRepository, "my-chart-museum", config.RequirementsConfig{Cluster: config.ClusterConfig{ChartRepository: "my-chart-museum"}}}, 130 {config.RequirementRegistry, "my-registry", config.RequirementsConfig{Cluster: config.ClusterConfig{Registry: "my-registry"}}}, 131 {config.RequirementEnvGitOwner, "john-doe", config.RequirementsConfig{Cluster: config.ClusterConfig{EnvironmentGitOwner: "john-doe"}}}, 132 {config.RequirementKanikoServiceAccountName, "kaniko-sa", config.RequirementsConfig{Cluster: config.ClusterConfig{KanikoSAName: "kaniko-sa"}}}, 133 {config.RequirementEnvGitPublic, "true", config.RequirementsConfig{Cluster: config.ClusterConfig{EnvironmentGitPublic: true}}}, 134 {config.RequirementEnvGitPublic, "false", config.RequirementsConfig{Cluster: config.ClusterConfig{EnvironmentGitPublic: false}}}, 135 {config.RequirementEnvGitPublic, "", config.RequirementsConfig{Cluster: config.ClusterConfig{EnvironmentGitPublic: false}}}, 136 {config.RequirementGitPublic, "true", config.RequirementsConfig{Cluster: config.ClusterConfig{GitPublic: true}}}, 137 {config.RequirementGitPublic, "false", config.RequirementsConfig{Cluster: config.ClusterConfig{GitPublic: false}}}, 138 {config.RequirementGitPublic, "", config.RequirementsConfig{Cluster: config.ClusterConfig{GitPublic: false}}}, 139 {config.RequirementExternalDNSServiceAccountName, "externaldns-sa", config.RequirementsConfig{Cluster: config.ClusterConfig{ExternalDNSSAName: "externaldns-sa"}}}, 140 141 // VaultConfig 142 {config.RequirementVaultName, "my-vault", config.RequirementsConfig{Vault: config.VaultConfig{Name: "my-vault"}}}, 143 {config.RequirementVaultServiceAccountName, "my-vault-sa", config.RequirementsConfig{Vault: config.VaultConfig{ServiceAccount: "my-vault-sa"}}}, 144 {config.RequirementVaultKeyringName, "my-keyring", config.RequirementsConfig{Vault: config.VaultConfig{Keyring: "my-keyring"}}}, 145 {config.RequirementVaultKeyName, "my-key", config.RequirementsConfig{Vault: config.VaultConfig{Key: "my-key"}}}, 146 {config.RequirementVaultBucketName, "my-bucket", config.RequirementsConfig{Vault: config.VaultConfig{Bucket: "my-bucket"}}}, 147 {config.RequirementVaultRecreateBucket, "true", config.RequirementsConfig{Vault: config.VaultConfig{RecreateBucket: true}}}, 148 {config.RequirementVaultRecreateBucket, "false", config.RequirementsConfig{Vault: config.VaultConfig{RecreateBucket: false}}}, 149 {config.RequirementVaultRecreateBucket, "", config.RequirementsConfig{Vault: config.VaultConfig{RecreateBucket: false}}}, 150 {config.RequirementVaultDisableURLDiscovery, "true", config.RequirementsConfig{Vault: config.VaultConfig{DisableURLDiscovery: true}}}, 151 {config.RequirementVaultDisableURLDiscovery, "false", config.RequirementsConfig{Vault: config.VaultConfig{DisableURLDiscovery: false}}}, 152 {config.RequirementVaultDisableURLDiscovery, "", config.RequirementsConfig{Vault: config.VaultConfig{DisableURLDiscovery: false}}}, 153 154 // VeleroConfig 155 {config.RequirementVeleroServiceAccountName, "my-velero-sa", config.RequirementsConfig{Velero: config.VeleroConfig{ServiceAccount: "my-velero-sa"}}}, 156 {config.RequirementVeleroTTL, "60", config.RequirementsConfig{Velero: config.VeleroConfig{TimeToLive: "60"}}}, 157 {config.RequirementVeleroSchedule, "0 * * * *", config.RequirementsConfig{Velero: config.VeleroConfig{Schedule: "0 * * * *"}}}, 158 159 // IngressConfig 160 {config.RequirementDomainIssuerURL, "my-issuer-url", config.RequirementsConfig{Ingress: config.IngressConfig{DomainIssuerURL: "my-issuer-url"}}}, 161 162 // Storage 163 {config.RequirementStorageBackupEnabled, "true", config.RequirementsConfig{Storage: config.StorageConfig{Backup: config.StorageEntryConfig{Enabled: true}}}}, 164 {config.RequirementStorageBackupEnabled, "false", config.RequirementsConfig{Storage: config.StorageConfig{Backup: config.StorageEntryConfig{Enabled: false}}}}, 165 {config.RequirementStorageBackupEnabled, "", config.RequirementsConfig{Storage: config.StorageConfig{Backup: config.StorageEntryConfig{Enabled: false}}}}, 166 {config.RequirementStorageBackupURL, "gs://my-backup", config.RequirementsConfig{Storage: config.StorageConfig{Backup: config.StorageEntryConfig{URL: "gs://my-backup"}}}}, 167 168 {config.RequirementStorageLogsEnabled, "true", config.RequirementsConfig{Storage: config.StorageConfig{Logs: config.StorageEntryConfig{Enabled: true}}}}, 169 {config.RequirementStorageLogsEnabled, "false", config.RequirementsConfig{Storage: config.StorageConfig{Logs: config.StorageEntryConfig{Enabled: false}}}}, 170 {config.RequirementStorageLogsEnabled, "", config.RequirementsConfig{Storage: config.StorageConfig{Logs: config.StorageEntryConfig{Enabled: false}}}}, 171 {config.RequirementStorageLogsURL, "gs://my-logs", config.RequirementsConfig{Storage: config.StorageConfig{Logs: config.StorageEntryConfig{URL: "gs://my-logs"}}}}, 172 173 {config.RequirementStorageReportsEnabled, "true", config.RequirementsConfig{Storage: config.StorageConfig{Reports: config.StorageEntryConfig{Enabled: true}}}}, 174 {config.RequirementStorageReportsEnabled, "false", config.RequirementsConfig{Storage: config.StorageConfig{Reports: config.StorageEntryConfig{Enabled: false}}}}, 175 {config.RequirementStorageReportsEnabled, "", config.RequirementsConfig{Storage: config.StorageConfig{Reports: config.StorageEntryConfig{Enabled: false}}}}, 176 {config.RequirementStorageReportsURL, "gs://my-reports", config.RequirementsConfig{Storage: config.StorageConfig{Reports: config.StorageEntryConfig{URL: "gs://my-reports"}}}}, 177 178 {config.RequirementStorageRepositoryEnabled, "true", config.RequirementsConfig{Storage: config.StorageConfig{Repository: config.StorageEntryConfig{Enabled: true}}}}, 179 {config.RequirementStorageRepositoryEnabled, "false", config.RequirementsConfig{Storage: config.StorageConfig{Repository: config.StorageEntryConfig{Enabled: false}}}}, 180 {config.RequirementStorageRepositoryEnabled, "", config.RequirementsConfig{Storage: config.StorageConfig{Repository: config.StorageEntryConfig{Enabled: false}}}}, 181 {config.RequirementStorageRepositoryURL, "gs://my-repo", config.RequirementsConfig{Storage: config.StorageConfig{Repository: config.StorageEntryConfig{URL: "gs://my-repo"}}}}, 182 183 // GKEConfig 184 {config.RequirementGkeProjectNumber, "my-gke-project", config.RequirementsConfig{Cluster: config.ClusterConfig{GKEConfig: &config.GKEConfig{ProjectNumber: "my-gke-project"}}}}, 185 186 // VersionStreamConfig 187 {config.RequirementVersionsGitRef, "v1.0.0", config.RequirementsConfig{VersionStream: config.VersionStreamConfig{Ref: "v1.0.0"}}}, 188 } 189 190 for _, overrideTest := range overrideTests { 191 origEnvValue, origValueSet := os.LookupEnv(overrideTest.envKey) 192 err := os.Setenv(overrideTest.envKey, overrideTest.envValue) 193 assert.NoError(t, err) 194 resetEnvVariable := func() { 195 var err error 196 if origValueSet { 197 err = os.Setenv(overrideTest.envKey, origEnvValue) 198 } else { 199 err = os.Unsetenv(overrideTest.envKey) 200 } 201 if err != nil { 202 log.Logger().Warnf("error resetting environment after test: %v", err) 203 } 204 } 205 206 t.Run(overrideTest.envKey, func(t *testing.T) { 207 actualRequirements := config.RequirementsConfig{} 208 actualRequirements.OverrideRequirementsFromEnvironment(func(projectId string) (string, error) { 209 return "", nil 210 }) 211 212 assert.Equal(t, overrideTest.expectedRequirements, actualRequirements) 213 }) 214 215 resetEnvVariable() 216 } 217 } 218 219 func TestRequirementsConfigMarshalExistingFileKanikoFalse(t *testing.T) { 220 t.Parallel() 221 222 dir, err := ioutil.TempDir("", "test-requirements-config-") 223 assert.NoError(t, err, "should create a temporary config dir") 224 225 file := filepath.Join(dir, config.RequirementsConfigFileName) 226 requirements := config.NewRequirementsConfig() 227 requirements.Kaniko = false 228 229 err = requirements.SaveConfig(file) 230 assert.NoError(t, err, "failed to save file %s", file) 231 232 requirements, fileName, err := config.LoadRequirementsConfig(dir, config.DefaultFailOnValidationError) 233 assert.NoError(t, err, "failed to load requirements file in dir %s", dir) 234 assert.FileExists(t, fileName) 235 236 assert.Equal(t, false, requirements.Kaniko, "requirements.Kaniko") 237 238 } 239 240 func TestRequirementsConfigMarshalInEmptyDir(t *testing.T) { 241 t.Parallel() 242 243 dir, err := ioutil.TempDir("", "test-requirements-config-empty-") 244 assert.NoError(t, err) 245 246 requirements, fileName, err := config.LoadRequirementsConfig(dir, config.DefaultFailOnValidationError) 247 assert.Error(t, err) 248 assert.Empty(t, fileName) 249 assert.Nil(t, requirements) 250 } 251 252 func TestRequirementsConfigIngressAutoDNS(t *testing.T) { 253 t.Parallel() 254 255 requirements := config.NewRequirementsConfig() 256 257 requirements.Ingress.Domain = "1.2.3.4.nip.io" 258 assert.Equal(t, true, requirements.Ingress.IsAutoDNSDomain(), "requirements.Ingress.IsAutoDNSDomain() for domain %s", requirements.Ingress.Domain) 259 260 requirements.Ingress.Domain = "foo.bar" 261 assert.Equal(t, false, requirements.Ingress.IsAutoDNSDomain(), "requirements.Ingress.IsAutoDNSDomain() for domain %s", requirements.Ingress.Domain) 262 263 requirements.Ingress.Domain = "" 264 assert.Equal(t, false, requirements.Ingress.IsAutoDNSDomain(), "requirements.Ingress.IsAutoDNSDomain() for domain %s", requirements.Ingress.Domain) 265 } 266 267 func Test_unmarshalling_requirements_config_with_build_pack_configuration_succeeds(t *testing.T) { 268 t.Parallel() 269 270 requirements := config.NewRequirementsConfig() 271 272 content, err := ioutil.ReadFile(path.Join(testDataDir, "build_pack_library.yaml")) 273 assert.NoError(t, err) 274 275 err = yaml.Unmarshal(content, requirements) 276 assert.NoError(t, err) 277 assert.Equal(t, "Test name", requirements.BuildPacks.BuildPackLibrary.Name, "requirements.buildPacks.BuildPackLibrary.name is not equivalent to test name") 278 assert.Equal(t, "github.com", requirements.BuildPacks.BuildPackLibrary.GitURL, "requirements.buildPacks.BuildPackLibrary.gitURL is not equivalent to git url ") 279 assert.Equal(t, "master", requirements.BuildPacks.BuildPackLibrary.GitRef, "requirements.buildPacks.BuildPackLibrary.gitRef is not equivalent git Ref") 280 } 281 282 func Test_marshalling_empty_requirements_config_creates_no_build_pack_configuration(t *testing.T) { 283 t.Parallel() 284 285 requirements := config.NewRequirementsConfig() 286 data, err := yaml.Marshal(requirements) 287 assert.NoError(t, err) 288 assert.NotContains(t, string(data), "buildPacks") 289 290 err = yaml.Unmarshal(data, requirements) 291 assert.NoError(t, err) 292 assert.Nil(t, requirements.BuildPacks) 293 } 294 295 func Test_marshalling_vault_config(t *testing.T) { 296 t.Parallel() 297 298 requirements := config.NewRequirementsConfig() 299 requirements.Vault = config.VaultConfig{ 300 Name: "myVault", 301 URL: "http://myvault", 302 ServiceAccount: "vault-sa", 303 Namespace: "jx", 304 KubernetesAuthPath: "kubernetes", 305 SecretEngineMountPoint: "secret", 306 } 307 data, err := yaml.Marshal(requirements) 308 assert.NoError(t, err) 309 310 assert.Contains(t, string(data), "name: myVault") 311 assert.Contains(t, string(data), "url: http://myvault") 312 assert.Contains(t, string(data), "serviceAccount: vault-sa") 313 assert.Contains(t, string(data), "namespace: jx") 314 assert.Contains(t, string(data), "kubernetesAuthPath: kubernetes") 315 assert.Contains(t, string(data), "secretEngineMountPoint: secret") 316 } 317 318 func Test_env_repository_visibility(t *testing.T) { 319 t.Parallel() 320 321 var gitPublicTests = []struct { 322 yamlFile string 323 expectedGitPublic bool 324 }{ 325 {"git_public_nil_git_private_true.yaml", false}, 326 {"git_public_nil_git_private_false.yaml", true}, 327 {"git_public_false_git_private_nil.yaml", false}, 328 {"git_public_true_git_private_nil.yaml", true}, 329 } 330 331 for _, testCase := range gitPublicTests { 332 t.Run(testCase.yamlFile, func(t *testing.T) { 333 content, err := ioutil.ReadFile(path.Join(testDataDir, testCase.yamlFile)) 334 assert.NoError(t, err) 335 336 config := config.NewRequirementsConfig() 337 338 _ = log.CaptureOutput(func() { 339 err = yaml.Unmarshal(content, config) 340 assert.NoError(t, err) 341 assert.Equal(t, testCase.expectedGitPublic, config.Cluster.EnvironmentGitPublic, "unexpected value for repository visibility") 342 }) 343 }) 344 } 345 } 346 347 func TestMergeSave(t *testing.T) { 348 t.Parallel() 349 type TestSpec struct { 350 Name string 351 Original *config.RequirementsConfig 352 Changed *config.RequirementsConfig 353 ValidationFunc func(orig *config.RequirementsConfig, ch *config.RequirementsConfig) 354 } 355 356 testCases := []TestSpec{ 357 { 358 Name: "Merge Cluster Config Test", 359 Original: &config.RequirementsConfig{ 360 Cluster: config.ClusterConfig{ 361 EnvironmentGitOwner: "owner", 362 EnvironmentGitPublic: false, 363 GitPublic: false, 364 Provider: cloud.GKE, 365 Namespace: "jx", 366 ProjectID: "project-id", 367 ClusterName: "cluster-name", 368 Region: "region", 369 GitKind: KindGitHub, 370 GitServer: KindGitHub, 371 }, 372 }, 373 Changed: &config.RequirementsConfig{ 374 Cluster: config.ClusterConfig{ 375 EnvironmentGitPublic: true, 376 GitPublic: true, 377 Provider: cloud.GKE, 378 }, 379 }, 380 ValidationFunc: func(orig *config.RequirementsConfig, ch *config.RequirementsConfig) { 381 assert.True(t, orig.Cluster.EnvironmentGitPublic == ch.Cluster.EnvironmentGitPublic && 382 orig.Cluster.GitPublic == ch.Cluster.GitPublic && 383 orig.Cluster.ProjectID != ch.Cluster.ProjectID, "ClusterConfig validation failed") 384 }, 385 }, 386 { 387 Name: "Merge EnvironmentConfig slices Test", 388 Original: &config.RequirementsConfig{ 389 Environments: []config.EnvironmentConfig{ 390 { 391 Key: "dev", 392 Repository: "repo", 393 }, 394 { 395 Key: "production", 396 Ingress: config.IngressConfig{ 397 Domain: "domain", 398 }, 399 }, 400 { 401 Key: "staging", 402 Ingress: config.IngressConfig{ 403 Domain: "domainStaging", 404 TLS: config.TLSConfig{ 405 Email: "email", 406 }, 407 }, 408 }, 409 }, 410 }, 411 Changed: &config.RequirementsConfig{ 412 Environments: []config.EnvironmentConfig{ 413 { 414 Key: "dev", 415 Owner: "owner", 416 }, 417 { 418 Key: "production", 419 Ingress: config.IngressConfig{ 420 CloudDNSSecretName: "secret", 421 }, 422 }, 423 { 424 Key: "staging", 425 Ingress: config.IngressConfig{ 426 Domain: "newDomain", 427 DomainIssuerURL: "issuer", 428 TLS: config.TLSConfig{ 429 Enabled: true, 430 }, 431 }, 432 }, 433 { 434 Key: "ns2", 435 }, 436 }, 437 }, 438 ValidationFunc: func(orig *config.RequirementsConfig, ch *config.RequirementsConfig) { 439 assert.True(t, len(orig.Environments) == len(ch.Environments), "the environment slices should be of the same len") 440 // -- Dev Environment's asserts 441 devOrig, devCh := orig.Environments[0], ch.Environments[0] 442 assert.True(t, devOrig.Owner == devCh.Owner && devOrig.Repository != devCh.Repository, 443 "the dev environment should've been merged correctly") 444 // -- Production Environment's asserts 445 prOrig, prCh := orig.Environments[1], ch.Environments[1] 446 assert.True(t, prOrig.Ingress.Domain == "domain" && 447 prOrig.Ingress.CloudDNSSecretName == prCh.Ingress.CloudDNSSecretName, 448 "the production environment should've been merged correctly") 449 // -- Staging Environmnet's asserts 450 stgOrig, stgCh := orig.Environments[2], ch.Environments[2] 451 assert.True(t, stgOrig.Ingress.Domain == stgCh.Ingress.Domain && 452 stgOrig.Ingress.TLS.Email == "email" && stgOrig.Ingress.TLS.Enabled == stgCh.Ingress.TLS.Enabled, 453 "the staging environment should've been merged correctly") 454 }, 455 }, 456 { 457 Name: "Merge StorageConfig test", 458 Original: &config.RequirementsConfig{ 459 Storage: config.StorageConfig{ 460 Logs: config.StorageEntryConfig{ 461 Enabled: true, 462 URL: "value1", 463 }, 464 Reports: config.StorageEntryConfig{}, 465 Repository: config.StorageEntryConfig{ 466 Enabled: true, 467 URL: "value3", 468 }, 469 }, 470 }, 471 Changed: &config.RequirementsConfig{ 472 Storage: config.StorageConfig{ 473 Reports: config.StorageEntryConfig{ 474 Enabled: true, 475 URL: "", 476 }, 477 }, 478 }, 479 ValidationFunc: func(orig *config.RequirementsConfig, ch *config.RequirementsConfig) { 480 assert.True(t, orig.Storage.Logs.Enabled && orig.Storage.Logs.URL == "value1" && 481 orig.Storage.Repository.Enabled && orig.Storage.Repository.URL == "value3" && 482 orig.Storage.Reports.Enabled == ch.Storage.Reports.Enabled, 483 "The storage configuration should've been merged correctly") 484 }, 485 }, 486 } 487 f, err := ioutil.TempFile("", "") 488 assert.NoError(t, err) 489 defer func() { 490 err := util.DeleteFile(f.Name()) 491 if err != nil { 492 t.Logf("unable to clean up, %s", err) 493 } 494 }() 495 496 for _, tc := range testCases { 497 t.Run(tc.Name, func(t *testing.T) { 498 err = tc.Original.MergeSave(tc.Changed, f.Name()) 499 assert.NoError(t, err, "the merge shouldn't fail for case %s", tc.Name) 500 tc.ValidationFunc(tc.Original, tc.Changed) 501 }) 502 } 503 } 504 505 func Test_EnvironmentGitPublic_and_EnvironmentGitPrivate_specified_together_return_error(t *testing.T) { 506 content, err := ioutil.ReadFile(path.Join(testDataDir, "git_public_true_git_private_true.yaml")) 507 assert.NoError(t, err) 508 509 config := config.NewRequirementsConfig() 510 err = yaml.Unmarshal(content, config) 511 assert.Error(t, err) 512 assert.Contains(t, err.Error(), "only EnvironmentGitPublic should be used") 513 } 514 515 func TestHelmfileRequirementValues(t *testing.T) { 516 t.Parallel() 517 518 dir, err := ioutil.TempDir("", "test-requirements-config-") 519 assert.NoError(t, err, "should create a temporary config dir") 520 521 file := filepath.Join(dir, config.RequirementsConfigFileName) 522 requirements := config.NewRequirementsConfig() 523 requirements.Cluster.ClusterName = "jx_rocks" 524 525 err = requirements.SaveConfig(file) 526 assert.NoError(t, err, "failed to save file %s", file) 527 assert.FileExists(t, file) 528 valuesFile := filepath.Join(dir, config.RequirementsValuesFileName) 529 530 valuesFileExists, err := util.FileExists(valuesFile) 531 assert.NoError(t, err) 532 assert.False(t, valuesFileExists, "file %s should not exist", valuesFile) 533 534 requirements.Helmfile = true 535 err = requirements.SaveConfig(file) 536 assert.NoError(t, err, "failed to save file %s", file) 537 assert.FileExists(t, file) 538 assert.FileExists(t, valuesFile, "file %s should exist", valuesFile) 539 } 540 541 func Test_LoadRequirementsConfig(t *testing.T) { 542 t.Parallel() 543 544 var gitPublicTests = []struct { 545 requirementsPath string 546 createRequirements bool 547 }{ 548 {"a", false}, 549 {"a/b", false}, 550 {"a/b/c", false}, 551 {"e", true}, 552 {"e/f", true}, 553 {"e/f/g", true}, 554 } 555 556 for _, testCase := range gitPublicTests { 557 t.Run(testCase.requirementsPath, func(t *testing.T) { 558 dir, err := ioutil.TempDir("", "jx-test-load-requirements-config") 559 require.NoError(t, err, "failed to create tmp directory") 560 defer func() { 561 _ = os.RemoveAll(dir) 562 }() 563 564 testPath := filepath.Join(dir, testCase.requirementsPath) 565 err = os.MkdirAll(testPath, 0700) 566 require.NoError(t, err, "unable to create test path %s", testPath) 567 568 var expectedRequirementsFile string 569 if testCase.createRequirements { 570 expectedRequirementsFile = filepath.Join(testPath, config.RequirementsConfigFileName) 571 dummyRequirementsData := []byte("webhook: prow\n") 572 err := ioutil.WriteFile(expectedRequirementsFile, dummyRequirementsData, 0600) 573 require.NoError(t, err, "unable to write requirements file %s", expectedRequirementsFile) 574 } 575 576 requirements, requirementsFile, err := config.LoadRequirementsConfig(testPath, config.DefaultFailOnValidationError) 577 if testCase.createRequirements { 578 require.NoError(t, err) 579 assert.Equal(t, expectedRequirementsFile, requirementsFile) 580 assert.Equal(t, string(requirements.Webhook), "prow") 581 } else { 582 require.Error(t, err) 583 assert.Equal(t, "", requirementsFile) 584 assert.Nil(t, requirements) 585 } 586 }) 587 } 588 } 589 590 func TestLoadRequirementsConfig_load_invalid_yaml(t *testing.T) { 591 testDir := path.Join(testDataDir, "jx-requirements-syntax-error") 592 593 absolute, err := filepath.Abs(testDir) 594 assert.NoError(t, err, "could not find absolute path of dir %s", testDataDir) 595 596 _, _, err = config.LoadRequirementsConfig(testDir, config.DefaultFailOnValidationError) 597 requirementsConfigPath := path.Join(absolute, config.RequirementsConfigFileName) 598 assert.EqualError(t, err, fmt.Sprintf("validation failures in YAML file %s:\nenvironments.0: Additional property namespace is not allowed", requirementsConfigPath)) 599 }