diff --git a/pkg/controller/cluster/cluster_reconcile_test.go b/pkg/controller/cluster/cluster_reconcile_test.go index d9e62d9d..73f10675 100644 --- a/pkg/controller/cluster/cluster_reconcile_test.go +++ b/pkg/controller/cluster/cluster_reconcile_test.go @@ -300,6 +300,8 @@ func (m *TestMockClient) RemoveSecrets(secrets []vault.VaultSecret) error { return nil } +func (m *TestMockClient) SetDeletionPolicy(deletionPolicy synv1alpha1.DeletionPolicy) {} + func TestReconcileCluster_getServiceAccountToken(t *testing.T) { type args struct { instance metav1.Object diff --git a/pkg/controller/tenant/tenant_reconcile_test.go b/pkg/controller/tenant/tenant_reconcile_test.go index 8c4e9abe..42f65668 100644 --- a/pkg/controller/tenant/tenant_reconcile_test.go +++ b/pkg/controller/tenant/tenant_reconcile_test.go @@ -53,7 +53,7 @@ func TestHandleNilGitRepoTemplate(t *testing.T) { updatedTenant := &synv1alpha1.Tenant{} err = cl.Get(context.TODO(), types.NamespacedName{Name: tenant.Name}, updatedTenant) assert.NoError(t, err) - assert.Empty(t, updatedTenant.Spec.GitRepoTemplate.TemplateFiles["common.yml"]) + assert.Contains(t, updatedTenant.Spec.GitRepoTemplate.TemplateFiles, "common.yml") } func TestCreateGitRepo(t *testing.T) { diff --git a/pkg/pipeline/git_test.go b/pkg/pipeline/git_test.go index 4d325a4d..8aa7abfa 100644 --- a/pkg/pipeline/git_test.go +++ b/pkg/pipeline/git_test.go @@ -2,14 +2,18 @@ package pipeline import ( "context" + "fmt" + "net/url" "testing" synv1alpha1 "github.com/projectsyn/lieutenant-operator/pkg/apis/syn/v1alpha1" + "github.com/projectsyn/lieutenant-operator/pkg/git/manager" "github.com/stretchr/testify/assert" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" ) func TestCreateOrUpdateGitRepo(t *testing.T) { @@ -176,3 +180,174 @@ func Test_fetchGitRepoTemplate(t *testing.T) { }) } } + +type repoMock struct { + failRead bool +} + +func (r *repoMock) Type() string { return "mock" } +func (r *repoMock) FullURL() *url.URL { return &url.URL{} } +func (r *repoMock) Create() error { return nil } +func (r *repoMock) Update() (bool, error) { return false, nil } +func (r *repoMock) Read() error { + if r.failRead { + return fmt.Errorf("this should fail") + } + return nil +} +func (r *repoMock) Connect() error { return nil } +func (r *repoMock) Remove() error { return nil } +func (r *repoMock) CommitTemplateFiles() error { return nil } + +func Test_repoExists(t *testing.T) { + type args struct { + repo manager.Repo + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "repo exists", + want: true, + args: args{ + repo: &repoMock{}, + }, + }, + { + name: "repo doesn't exist", + want: false, + args: args{ + repo: &repoMock{ + failRead: true, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := repoExists(tt.args.repo); got != tt.want { + t.Errorf("repoExists() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_handleRepoError(t *testing.T) { + type args struct { + err error + instance *synv1alpha1.GitRepo + repo manager.Repo + fail bool + } + tests := []struct { + name string + args args + }{ + { + name: "add error", + args: args{ + err: fmt.Errorf("lol nope"), + instance: &synv1alpha1.GitRepo{}, + repo: &repoMock{}, + }, + }, + { + name: "add error failure", + args: args{ + err: fmt.Errorf("lol nope"), + instance: &synv1alpha1.GitRepo{}, + repo: &repoMock{}, + fail: true, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + var client client.Client + + if tt.args.fail { + client, _ = testSetupClient([]runtime.Object{}) + } else { + client, _ = testSetupClient([]runtime.Object{tt.args.instance}) + } + + err := handleRepoError(tt.args.err, tt.args.instance, tt.args.repo, client) + assert.Error(t, err) + failedPhase := synv1alpha1.Failed + assert.Equal(t, &failedPhase, tt.args.instance.Status.Phase) + + if tt.args.fail { + assert.Contains(t, err.Error(), "could not set status") + } + + }) + } +} + +func Test_setGitRepoURLAndHostKeys(t *testing.T) { + type args struct { + obj *synv1alpha1.Cluster + gitRepo *synv1alpha1.GitRepo + data *ExecutionContext + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "set url and keys", + wantErr: false, + args: args{ + obj: &synv1alpha1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + }, + }, + data: &ExecutionContext{}, + gitRepo: &synv1alpha1.GitRepo{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + }, + Status: synv1alpha1.GitRepoStatus{ + URL: "someURL", + HostKeys: "someKeys", + }, + }, + }, + }, + { + name: "set url and keys not found", + wantErr: false, + args: args{ + obj: &synv1alpha1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "invalid", + }, + }, + data: &ExecutionContext{}, + gitRepo: &synv1alpha1.GitRepo{}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + tt.args.data.Client, _ = testSetupClient([]runtime.Object{ + tt.args.obj, + tt.args.gitRepo, + }) + + if got := setGitRepoURLAndHostKeys(tt.args.obj, tt.args.data); (got.Err != nil) != tt.wantErr { + t.Errorf("setGitRepoURLAndHostKeys() = had error: %v", got.Err) + } + + assert.Equal(t, tt.args.gitRepo.Status.URL, tt.args.obj.Spec.GitRepoURL) + assert.Equal(t, tt.args.gitRepo.Status.HostKeys, tt.args.obj.Spec.GitHostKeys) + + }) + } +} diff --git a/pkg/pipeline/tenant_steps.go b/pkg/pipeline/tenant_steps.go index 20816a4f..b0b89c04 100644 --- a/pkg/pipeline/tenant_steps.go +++ b/pkg/pipeline/tenant_steps.go @@ -30,7 +30,12 @@ func updateTenantGitRepo(obj PipelineObject, data *ExecutionContext) ExecutionRe return ExecutionResult{Err: fmt.Errorf("object is not a tenant")} } - oldFiles := tenantCR.Spec.GitRepoTemplate.TemplateFiles + var oldFiles map[string]string + if tenantCR.Spec.GitRepoTemplate != nil { + oldFiles = tenantCR.Spec.GitRepoTemplate.TemplateFiles + } else { + tenantCR.Spec.GitRepoTemplate = &synv1alpha1.GitRepoTemplate{} + } tenantCR.Spec.GitRepoTemplate.TemplateFiles = map[string]string{} diff --git a/pkg/pipeline/tenant_steps_test.go b/pkg/pipeline/tenant_steps_test.go new file mode 100644 index 00000000..44fab059 --- /dev/null +++ b/pkg/pipeline/tenant_steps_test.go @@ -0,0 +1,188 @@ +package pipeline + +import ( + "os" + "testing" + + "github.com/projectsyn/lieutenant-operator/pkg/apis" + synv1alpha1 "github.com/projectsyn/lieutenant-operator/pkg/apis/syn/v1alpha1" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +func Test_addDefaultClassFile(t *testing.T) { + type args struct { + obj *synv1alpha1.Tenant + data *ExecutionContext + } + tests := []struct { + name string + args args + }{ + { + name: "add default class", + args: args{ + obj: &synv1alpha1.Tenant{}, + data: &ExecutionContext{}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + got := addDefaultClassFile(tt.args.obj, tt.args.data) + assert.NoError(t, got.Err) + + assert.Contains(t, tt.args.obj.Spec.GitRepoTemplate.TemplateFiles, "common.yml") + assert.NotEmpty(t, tt.args.obj.Spec.GitRepoTemplate.TemplateFiles) + + }) + } +} + +func Test_setGlobalGitRepoURL(t *testing.T) { + type args struct { + obj *synv1alpha1.Tenant + data *ExecutionContext + defaultRepo string + } + tests := []struct { + name string + want string + args args + }{ + { + name: "set global git repo url via env var", + want: "test", + args: args{ + obj: &synv1alpha1.Tenant{}, + defaultRepo: "test", + }, + }, + { + name: "don't override", + want: "foo", + args: args{ + obj: &synv1alpha1.Tenant{ + Spec: synv1alpha1.TenantSpec{ + GlobalGitRepoURL: "foo", + }, + }, + defaultRepo: "test", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + os.Setenv(DefaultGlobalGitRepoURL, tt.args.defaultRepo) + + got := setGlobalGitRepoURL(tt.args.obj, tt.args.data) + assert.NoError(t, got.Err) + + assert.Equal(t, tt.want, tt.args.obj.Spec.GlobalGitRepoURL) + + }) + } +} + +func Test_updateTenantGitRepo(t *testing.T) { + type args struct { + obj *synv1alpha1.Tenant + cluster *synv1alpha1.Cluster + data *ExecutionContext + } + tests := []struct { + name string + args args + want *synv1alpha1.GitRepoTemplate + }{ + { + name: "fetch git repos", + want: &synv1alpha1.GitRepoTemplate{ + TemplateFiles: map[string]string{ + "testCluster.yml": "classes:\n- testCluster.common\n", + }, + }, + args: args{ + data: &ExecutionContext{}, + obj: &synv1alpha1.Tenant{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testTenant", + }, + }, + cluster: &synv1alpha1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testCluster", + Labels: map[string]string{ + apis.LabelNameTenant: "testTenant", + }, + }, + Spec: synv1alpha1.ClusterSpec{ + GitRepoTemplate: &synv1alpha1.GitRepoTemplate{ + TemplateFiles: map[string]string{ + "testCluster.yml": "classes:\n- testCluster.common\n", + }, + }, + }, + }, + }, + }, + { + name: "remove files", + want: &synv1alpha1.GitRepoTemplate{ + TemplateFiles: map[string]string{ + "testCluster.yml": "classes:\n- testCluster.common\n", + "oldFile.yml": "{delete}", + }, + }, + args: args{ + data: &ExecutionContext{}, + obj: &synv1alpha1.Tenant{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testTenant", + }, + Spec: synv1alpha1.TenantSpec{ + GitRepoTemplate: &synv1alpha1.GitRepoTemplate{ + TemplateFiles: map[string]string{ + "oldFile.yml": "not important", + }, + }, + }, + }, + cluster: &synv1alpha1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testCluster", + Labels: map[string]string{ + apis.LabelNameTenant: "testTenant", + }, + }, + Spec: synv1alpha1.ClusterSpec{ + GitRepoTemplate: &synv1alpha1.GitRepoTemplate{ + TemplateFiles: map[string]string{ + "testCluster.yml": "classes:\n- testCluster.common\n", + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + tt.args.data.Client, _ = testSetupClient([]runtime.Object{ + tt.args.cluster, + tt.args.obj, + &synv1alpha1.ClusterList{}, + }) + + got := updateTenantGitRepo(tt.args.obj, tt.args.data) + assert.NoError(t, got.Err) + + assert.Equal(t, tt.want, tt.args.obj.GetGitTemplate()) + + }) + } +}