package populate_source_config_display_name_test import ( "fmt" "os" "testing" "time" "github.com/porter-dev/porter/api/server/shared/config/env" "github.com/porter-dev/porter/api/types" "github.com/porter-dev/porter/internal/adapter" "github.com/porter-dev/porter/internal/encryption" "github.com/porter-dev/porter/internal/features" "github.com/porter-dev/porter/internal/models" ints "github.com/porter-dev/porter/internal/models/integrations" "github.com/porter-dev/porter/internal/repository" "github.com/porter-dev/porter/internal/repository/gorm" _gorm "gorm.io/gorm" ) type tester struct { Key *[32]byte DB *_gorm.DB repo repository.Repository dbFileName string key *[32]byte initUsers []*models.User initProjects []*models.Project initClusters []*models.Cluster initKIs []*ints.KubeIntegration initStacks []*models.Stack } func setupTestEnv(tester *tester, t *testing.T) { t.Helper() db, err := adapter.New(&env.DBConf{ EncryptionKey: "__random_strong_encryption_key__", SQLLite: true, SQLLitePath: tester.dbFileName, }) if err != nil { t.Fatalf("%\n", err) } err = db.AutoMigrate( &models.Project{}, &models.User{}, &models.Cluster{}, &models.Stack{}, &models.StackEnvGroup{}, &models.StackSourceConfig{}, &models.StackRevision{}, &models.StackResource{}, &ints.KubeIntegration{}, &ints.ClusterTokenCache{}, ) if err != nil { t.Fatalf("%v\n", err) } var key [32]byte for i, b := range []byte("__random_strong_encryption_key__") { key[i] = b } tester.key = &key tester.Key = &key tester.DB = db tester.repo = gorm.NewRepository(db, &key, nil) } func cleanup(tester *tester, t *testing.T) { t.Helper() // remove the created file file os.Remove(tester.dbFileName) } func initUser(tester *tester, t *testing.T) { t.Helper() user := &models.User{ Email: "example@example.com", Password: "hello1234", } user, err := tester.repo.User().CreateUser(user) if err != nil { t.Fatalf("%v\n", err) } tester.initUsers = append(tester.initUsers, user) } func initCluster(tester *tester, t *testing.T) { t.Helper() if len(tester.initProjects) == 0 { initProject(tester, t) } if len(tester.initKIs) == 0 { initKubeIntegration(tester, t) } cluster := &models.Cluster{ ProjectID: tester.initProjects[0].ID, Name: "cluster-test", Server: "https://localhost", KubeIntegrationID: tester.initKIs[0].ID, CertificateAuthorityData: []byte("-----BEGIN"), TokenCache: ints.ClusterTokenCache{ TokenCache: ints.TokenCache{ Token: []byte("token-1"), Expiry: time.Now().Add(-1 * time.Hour), }, }, } cluster, err := tester.repo.Cluster().CreateCluster(cluster, &features.Client{}) if err != nil { t.Fatalf("%v\n", err) } tester.initClusters = append(tester.initClusters, cluster) } func initProject(tester *tester, t *testing.T) { t.Helper() proj := &models.Project{ Name: "project-test", } proj, err := tester.repo.Project().CreateProject(proj) if err != nil { t.Fatalf("%v\n", err) } tester.initProjects = append(tester.initProjects, proj) } func initKubeIntegration(tester *tester, t *testing.T) { t.Helper() if len(tester.initProjects) == 0 { initProject(tester, t) } if len(tester.initUsers) == 0 { initUser(tester, t) } ki := &ints.KubeIntegration{ Mechanism: ints.KubeLocal, ProjectID: tester.initProjects[0].ID, UserID: tester.initUsers[0].ID, Kubeconfig: []byte("current-context: testing\n"), ClientCertificateData: []byte("clientcertdata"), ClientKeyData: []byte("clientkeydata"), Token: []byte("token"), Username: []byte("username"), Password: []byte("password"), } ki, err := tester.repo.KubeIntegration().CreateKubeIntegration(ki) if err != nil { t.Fatalf("%v\n", err) } tester.initKIs = append(tester.initKIs, ki) } func initEmptyStack(tester *tester, t *testing.T, stackName string) { t.Helper() if len(tester.initProjects) == 0 { initProject(tester, t) } if len(tester.initUsers) == 0 { initUser(tester, t) } if len(tester.initClusters) == 0 { initCluster(tester, t) } uid, _ := encryption.GenerateRandomBytes(16) // write stack to the database with creating status stack := &models.Stack{ ProjectID: tester.initProjects[0].ID, ClusterID: tester.initClusters[0].ID, Namespace: "test-namespace", Name: stackName, UID: uid, Revisions: []models.StackRevision{ { RevisionNumber: 1, Status: string(types.StackRevisionStatusDeploying), SourceConfigs: []models.StackSourceConfig{}, }, }, } newStack, err := tester.repo.Stack().CreateStack(stack) if err != nil { t.Fatalf("%v\n", err) } tester.initStacks = append(tester.initStacks, newStack) } func initStack(tester *tester, t *testing.T, stackName string) { t.Helper() if len(tester.initProjects) == 0 { initProject(tester, t) } if len(tester.initUsers) == 0 { initUser(tester, t) } if len(tester.initClusters) == 0 { initCluster(tester, t) } uid, _ := encryption.GenerateRandomBytes(16) sourceConfigs := []models.StackSourceConfig{ { Name: "source-config-1", ImageRepoURI: "some-repo", ImageTag: "some-tag", UID: uid, }, } // write stack to the database with creating status stack := &models.Stack{ ProjectID: tester.initProjects[0].ID, ClusterID: tester.initClusters[0].ID, Namespace: "test-namespace", Name: stackName, UID: uid, Revisions: []models.StackRevision{ { RevisionNumber: 1, Status: string(types.StackRevisionStatusDeploying), SourceConfigs: sourceConfigs, }, }, } newStack, err := tester.repo.Stack().CreateStack(stack) if err != nil { t.Fatalf("%v\n", err) } tester.initStacks = append(tester.initStacks, newStack) } func createNewStackRevision(tester *tester, t *testing.T, stackName string) { t.Helper() if len(tester.initProjects) == 0 { initProject(tester, t) } if len(tester.initUsers) == 0 { initUser(tester, t) } if len(tester.initClusters) == 0 { initCluster(tester, t) } if len(tester.initStacks) == 0 { initStack(tester, t, stackName) } stack := tester.initStacks[0] for _, s := range tester.initStacks { if s.Name == stackName { stack = s break } } prevRevision := findLatestRevisionByRevisionNumber(t, stack.Revisions) oldSourceConfig := prevRevision.SourceConfigs[0] newUid, _ := encryption.GenerateRandomBytes(16) sourceConfigs := []models.StackSourceConfig{ { Name: oldSourceConfig.Name, ImageRepoURI: "some-repo-" + fmt.Sprint(prevRevision.RevisionNumber+1), ImageTag: "some-tag-" + fmt.Sprint(prevRevision.RevisionNumber+1), UID: newUid, }, } newRevision := models.StackRevision{ RevisionNumber: prevRevision.RevisionNumber + 1, Status: string(types.StackRevisionStatusDeploying), SourceConfigs: sourceConfigs, StackID: stack.ID, } tester.repo.Stack().AppendNewRevision(&newRevision) } func findLatestRevisionByRevisionNumber(t *testing.T, revisions []models.StackRevision) *models.StackRevision { t.Helper() latestRevision := revisions[0] for _, revision := range revisions { if revision.RevisionNumber > latestRevision.RevisionNumber { latestRevision = revision } } return &latestRevision } func appendNewSourceConfig(t *testing.T, tester *tester, stack *models.Stack, sourceConfig models.StackSourceConfig) { t.Helper() prevRevision := findLatestRevisionByRevisionNumber(t, stack.Revisions) previousSourceConfigs := []models.StackSourceConfig{} for _, sourceConfig := range prevRevision.SourceConfigs { newUid, _ := encryption.GenerateRandomBytes(16) sc := models.StackSourceConfig{ Name: sourceConfig.Name, ImageRepoURI: sourceConfig.ImageRepoURI, ImageTag: sourceConfig.ImageTag, UID: newUid, } previousSourceConfigs = append(previousSourceConfigs, sc) } newRevision := models.StackRevision{ RevisionNumber: prevRevision.RevisionNumber + 1, Status: string(types.StackRevisionStatusDeploying), SourceConfigs: append(prevRevision.SourceConfigs, sourceConfig), StackID: stack.ID, } tester.repo.Stack().AppendNewRevision(&newRevision) }