diff --git a/cmd/main_test.go b/cmd/main_test.go new file mode 100644 index 0000000..b3ee14e --- /dev/null +++ b/cmd/main_test.go @@ -0,0 +1,14 @@ +package main + +import "testing" + +func Test_main(t *testing.T) { + tests := []struct { + name string + }{} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + main() + }) + } +} diff --git a/pkg/agent/agent_test.go b/pkg/agent/agent_test.go index a48995e..a51ef13 100644 --- a/pkg/agent/agent_test.go +++ b/pkg/agent/agent_test.go @@ -4,17 +4,33 @@ import ( "capten/pkg/agent/pb/agentpb" "capten/pkg/agent/pb/vaultcredpb" "capten/pkg/config" + "crypto/tls" + "fmt" + "log" "os" - - //"reflect" + "path/filepath" + "strings" "testing" "github.com/stretchr/testify/assert" + "google.golang.org/grpc/credentials" ) func TestGetAgentClient(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting relative path", err) + } + type args struct { - config config.CaptenConfig + config config.CaptenConfig + clusterconf config.CaptenClusterValues } tests := []struct { name string @@ -23,13 +39,22 @@ func TestGetAgentClient(t *testing.T) { wantErr bool }{ { + name: "Secure connection", args: args{ config: config.CaptenConfig{ - AgentSecure: true, - AgentHostName: "captenagent", - // DomainName: "com", - // CaptenAgentPort: "50051", + AgentSecure: true, + AgentHostName: "captenagent", + CertDirPath: "/" + presentdir + "/cert/", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + }, + clusterconf: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", }, }, wantErr: false, @@ -40,13 +65,13 @@ func TestGetAgentClient(t *testing.T) { config: config.CaptenConfig{ AgentSecure: false, AgentHostName: "captenagent", - // DomainName: "com", - // CaptenAgentPort: "50051", + }, + clusterconf: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", }, }, wantErr: false, }, - // Add more test cases as needed } for _, tt := range tests { @@ -68,6 +93,17 @@ func TestGetAgentClient(t *testing.T) { } func TestGetVaultClient(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + dir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + type args struct { config config.CaptenConfig } @@ -81,8 +117,16 @@ func TestGetVaultClient(t *testing.T) { name: "Secure connection", args: args{ config: config.CaptenConfig{ - AgentSecure: true, - AgentHostName: "captenagent", + AgentSecure: true, + AgentHostName: "captenagent", + CertDirPath: "/" + dir + "/cert/", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + VaultCredHostName: "vault-cred", + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, }, }, wantErr: false, @@ -127,80 +171,84 @@ func TestGetVaultClient(t *testing.T) { } -func TestLoadTLSCredentials(t *testing.T) { - // Test case 1: LoadX509KeyPair fails - captenConfig := config.CaptenConfig{ - //CertDirPath: "/path/to/certs", - ClientCertFileName: "client.crt", - ClientKeyFileName: "client.key", - CAFileName: "ca.crt", - } - os.MkdirAll(captenConfig.CertDirPath, os.ModePerm) - defer os.RemoveAll(captenConfig.CertDirPath) - - _, err := loadTLSCredentials(captenConfig) - if err == nil { - t.Errorf("Expected error, got nil") - } - - // Test case 2: AppendCertsFromPEM fails - certFile := captenConfig.PrepareFilePath(captenConfig.CertDirPath, captenConfig.ClientCertFileName) - keyFile := captenConfig.PrepareFilePath(captenConfig.CertDirPath, captenConfig.ClientKeyFileName) - caFile := captenConfig.PrepareFilePath(captenConfig.CertDirPath, captenConfig.CAFileName) - - err = os.WriteFile(certFile, []byte("dummy cert"), os.ModePerm) - if err != nil { - t.Fatalf("Failed to write cert file: %v", err) - } +func getRelativePathUpTo(currentPath string) (string, error) { + targetDir := "capten" + parts := strings.Split(currentPath, string(filepath.Separator)) - err = os.WriteFile(keyFile, []byte("dummy key"), os.ModePerm) - if err != nil { - t.Fatalf("Failed to write key file: %v", err) + for i, part := range parts { + if part == targetDir { + return filepath.Join(parts[:i+1]...), nil + } } - err = os.WriteFile(caFile, []byte("dummy ca"), os.ModePerm) - if err != nil { - t.Fatalf("Failed to write ca file: %v", err) - } + return "", fmt.Errorf("directory %s not found in path %s", targetDir, currentPath) +} - _, err = loadTLSCredentials(captenConfig) - if err == nil { - t.Errorf("Expected error, got nil") - } +func Test_loadTLSCredentials(t *testing.T) { - // Test case 3: Successful load - certPEM, err := os.ReadFile("testdata/cert.pem") + currentdir, err := os.Getwd() if err != nil { - t.Fatalf("Failed to read cert file: %v", err) + log.Println("Error while getting cuerent dir", err) } + dir, err := getRelativePathUpTo(currentdir) - keyPEM, err := os.ReadFile("testdata/key.pem") if err != nil { - t.Fatalf("Failed to read key file: %v", err) + log.Println("Error while getting working dir", err) } - caPEM, err := os.ReadFile("testdata/ca.pem") - if err != nil { - t.Fatalf("Failed to read ca file: %v", err) + type args struct { + captenConfig config.CaptenConfig } - err = os.WriteFile(certFile, certPEM, os.ModePerm) - if err != nil { - t.Fatalf("Failed to write cert file: %v", err) - } + tests := []struct { + name string + args args + want credentials.TransportCredentials + wantErr bool + }{ + { + name: "valid captenConfig", + args: args{ + captenConfig: config.CaptenConfig{ + AgentCertFileName: "agent.crt", + AgentKeyFileName: "agent.key", + CAFileName: "ca.crt", + CertDirPath: "/" + dir + "/cert/", + ClientCertFileName: "client.crt", + ClientKeyFileName: "client.key", + }, + }, + want: credentials.NewTLS(&tls.Config{ - err = os.WriteFile(keyFile, keyPEM, os.ModePerm) - if err != nil { - t.Fatalf("Failed to write key file: %v", err) - } + ClientAuth: tls.RequireAnyClientCert, + }), - err = os.WriteFile(caFile, caPEM, os.ModePerm) - if err != nil { - t.Fatalf("Failed to write ca file: %v", err) + wantErr: false, + }, + { + name: "invalid cert file", + args: args{ + captenConfig: config.CaptenConfig{ + AgentCertFileName: "client.crt", + AgentKeyFileName: "client.key", + CAFileName: "ca.crt", + CertDirPath: "/" + dir + "/cert/", + ClientCertFileName: "dbcjd.key", + ClientKeyFileName: "client.key", + }, + }, + want: nil, + wantErr: true, + }, } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := loadTLSCredentials(tt.args.captenConfig) + if (err != nil) != tt.wantErr { + t.Errorf("loadTLSCredentials() error = %v, wantErr %v", err, tt.wantErr) + return + } - _, err = loadTLSCredentials(captenConfig) - if err != nil { - t.Errorf("Expected no error, got %v", err) + }) } } diff --git a/pkg/agent/cluster_app_actions_test.go b/pkg/agent/cluster_app_actions_test.go new file mode 100644 index 0000000..4a404c9 --- /dev/null +++ b/pkg/agent/cluster_app_actions_test.go @@ -0,0 +1,260 @@ +package agent + +import ( + "capten/pkg/config" + "log" + "os" + "testing" +) + +func TestListClusterApplications(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + type args struct { + captenConfig config.CaptenConfig + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Valid config", + args: args{ + captenConfig: config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsagent.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + }, + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := ListClusterApplications(tt.args.captenConfig); (err != nil) != tt.wantErr { + t.Errorf("ListClusterApplications() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestShowClusterAppData(t *testing.T) { + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + type args struct { + captenConfig config.CaptenConfig + appName string + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Valid config and app name", + args: args{ + captenConfig: config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + KubeConfigFileName: "kubeconfig", + AgentHostName: "captenagent", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsagent.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + }, + + appName: "external-secrets", + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := ShowClusterAppData(tt.args.captenConfig, tt.args.appName); (err != nil) != tt.wantErr { + t.Errorf("ShowClusterAppData() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestDeployDefaultApps(t *testing.T) { + type args struct { + captenConfig config.CaptenConfig + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Valid config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + }, + }, + wantErr: false, + }, + { + name: "Invalid config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "", + PoolClusterNamespace: "", + }, + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := DeployDefaultApps(tt.args.captenConfig); (err != nil) != tt.wantErr { + t.Errorf("DeployDefaultApps() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := DeployDefaultApps(tt.args.captenConfig); (err != nil) != tt.wantErr { + t.Errorf("DeployDefaultApps() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestWaitAndTrackDefaultAppsDeploymentStatus(t *testing.T) { + type args struct { + captenConfig config.CaptenConfig + } + + tests := []struct { + name string + args args + }{ + { + name: "Valid config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "some-pool-cluster", + PoolClusterNamespace: "some-pool-cluster-ns", + }, + }, + }, + { + name: "Invalid config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "", + PoolClusterName: "", + PoolClusterNamespace: "", + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + WaitAndTrackDefaultAppsDeploymentStatus(tt.args.captenConfig) + }) + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + WaitAndTrackDefaultAppsDeploymentStatus(tt.args.captenConfig) + }) + } +} + +func TestGetDefaultAppsDeploymentStatus(t *testing.T) { + type args struct { + captenConfig config.CaptenConfig + } + + tests := []struct { + name string + args args + want bool + want1 string + wantErr bool + }{ + { + name: "Valid config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "some-pool-cluster", + PoolClusterNamespace: "some-pool-cluster-ns", + }, + }, + want: true, + want1: "status", + wantErr: false, + }, + { + name: "Invalid config", + args: args{ + captenConfig: config.CaptenConfig{}, + }, + want: false, + want1: "", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, got1, err := GetDefaultAppsDeploymentStatus(tt.args.captenConfig) + if (err != nil) != tt.wantErr { + t.Errorf("GetDefaultAppsDeploymentStatus() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("GetDefaultAppsDeploymentStatus() got = %v, want %v", got, tt.want) + } + if got1 != tt.want1 { + t.Errorf("GetDefaultAppsDeploymentStatus() got1 = %v, want %v", got1, tt.want1) + } + }) + } +} diff --git a/pkg/agent/cluster_resource_actions_test.go b/pkg/agent/cluster_resource_actions_test.go new file mode 100644 index 0000000..fb28898 --- /dev/null +++ b/pkg/agent/cluster_resource_actions_test.go @@ -0,0 +1,275 @@ +package agent + +import ( + "capten/pkg/config" + "log" + "os" + "reflect" + "testing" +) + +func TestListClusterResources(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + type args struct { + captenConfig config.CaptenConfig + resourceType string + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "list git-project", + args: args{ + captenConfig: config.CaptenConfig{ + AgentSecure: true, + AgentHostName: "captenagent", + CertDirPath: "/" + presentdir + "/cert/", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + VaultCredHostName: "vault-cred", + AgentHostPort: ":443", + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + }, + resourceType: "git-project", + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := ListClusterResources(tt.args.captenConfig, tt.args.resourceType); (err != nil) != tt.wantErr { + t.Errorf("ListClusterResources() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestAddClusterResource(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + + type args struct { + captenConfig config.CaptenConfig + resourceType string + attributes map[string]string + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "add git-project", + args: args{ + captenConfig: config.CaptenConfig{ + + AgentSecure: true, + AgentHostName: "captenagent", + CertDirPath: "/" + presentdir + "/cert/", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + VaultCredHostName: "vault-cred", + AgentHostPort: ":443", + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + }, + resourceType: "git-project", + attributes: map[string]string{ + "git-project-url": "https://github.com/example/example-project.git", + //"labels": "label1,label2", + "access-token": "testAccessToken", + "user-id": "testUserId", + }, + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := AddClusterResource(tt.args.captenConfig, tt.args.resourceType, tt.args.attributes); (err != nil) != tt.wantErr { + t.Errorf("AddClusterResource() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestUpdateClusterResource(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + type args struct { + captenConfig config.CaptenConfig + resourceType string + id string + attributes map[string]string + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "update git-project", + args: args{ + captenConfig: config.CaptenConfig{ + AgentSecure: true, + AgentHostName: "captenagent", + CertDirPath: "/" + presentdir + "/cert/", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + VaultCredHostName: "vault-cred", + AgentHostPort: ":443", + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + }, + resourceType: "git-project", + id: "9e9cb5a1-49bc-46d6-b773-5423672438cc", + attributes: map[string]string{ + "git-project-url": "https://github.com/example/example-project.git", + "labels": "IntelopsCi", + "access-token": "ksjdksjdk", + "user-id": "updatedUserId", + }, + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := UpdateClusterResource(tt.args.captenConfig, tt.args.resourceType, tt.args.id, tt.args.attributes); (err != nil) != tt.wantErr { + t.Errorf("UpdateClusterResource() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_prepareCloudAttributes(t *testing.T) { + type args struct { + attributes map[string]string + } + + tests := []struct { + name string + args args + want map[string]string + wantErr bool + }{ + { + name: "valid AWS cloud attributes", + args: args{ + attributes: map[string]string{ + "cloud-type": "aws", + "accessKey": "dkdndnfdnf", + "secretKey": "nSlkdnnns", + }, + }, + want: map[string]string{ + //"cloud-type": "aws", + "accessKey": "dkdndnfdnf", + "secretKey": "nSlkdnnns", + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := prepareCloudAttributes(tt.args.attributes) + if (err != nil) != tt.wantErr { + t.Errorf("prepareCloudAttributes() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("prepareCloudAttributes() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestRemoveClusterResource(t *testing.T) { + type args struct { + captenConfig config.CaptenConfig + resourceType string + id string + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "valid AWS resource", + args: args{ + captenConfig: config.CaptenConfig{}, + resourceType: "aws", + id: "test-id", + }, + wantErr: false, + }, + { + name: "valid Azure resource", + args: args{ + captenConfig: config.CaptenConfig{}, + resourceType: "azure", + id: "test-id", + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := RemoveClusterResource(tt.args.captenConfig, tt.args.resourceType, tt.args.id); (err != nil) != tt.wantErr { + t.Errorf("RemoveClusterResource() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } + +} diff --git a/pkg/agent/plugin_actions_test.go b/pkg/agent/plugin_actions_test.go new file mode 100644 index 0000000..22d568b --- /dev/null +++ b/pkg/agent/plugin_actions_test.go @@ -0,0 +1,336 @@ +package agent + +import ( + "capten/pkg/config" + "log" + "os" + "testing" +) + +func TestListClusterPlugins(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + type args struct { + captenConfig config.CaptenConfig + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Valid config", + args: args{ + captenConfig: config.CaptenConfig{ + AgentSecure: true, + AgentHostName: "captenagent", + CertDirPath: "/" + presentdir + "/cert/", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + VaultCredHostName: "vault-cred", + AgentHostPort: ":443", + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + + KubeConfigFileName: "kubeconfig", + }, + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := ListClusterPlugins(tt.args.captenConfig); (err != nil) != tt.wantErr { + t.Errorf("ListClusterPlugins() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestDeployPlugin(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + + type args struct { + captenConfig config.CaptenConfig + storeType string + pluginName string + version string + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Valid config and valid store type", + args: args{ + captenConfig: config.CaptenConfig{ + AgentSecure: true, + AgentHostName: "captenagent", + CertDirPath: "/" + presentdir + "/cert/", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + VaultCredHostName: "vault-cred", + AgentHostPort: ":443", + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + + KubeConfigFileName: "kubeconfig", + }, + storeType: "central", + pluginName: "argo-cd", + version: "v1.0.2", + }, + wantErr: false, + }, + { + name: "Valid config and invalid store type", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + }, + storeType: "invalid-store", + }, + wantErr: true, + }, + { + name: "Invalid config and valid store type", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "", + }, + storeType: "helm", + }, + wantErr: true, + }, + { + name: "Invalid config and invalid store type", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "", + PoolClusterName: "", + PoolClusterNamespace: "", + }, + storeType: "invalid-store", + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := DeployPlugin(tt.args.captenConfig, tt.args.storeType, tt.args.pluginName, tt.args.version); (err != nil) != tt.wantErr { + t.Errorf("DeployPlugin() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestUnDeployPlugin(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + type args struct { + captenConfig config.CaptenConfig + storeType string + pluginName string + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Valid config and valid store type", + args: args{ + captenConfig: config.CaptenConfig{ + AgentSecure: true, + AgentHostName: "captenagent", + CertDirPath: "/" + presentdir + "/cert/", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + VaultCredHostName: "vault-cred", + AgentHostPort: ":443", + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + + KubeConfigFileName: "kubeconfig", + }, + storeType: "central", + pluginName: "argo-cd", + }, + wantErr: false, + }, + { + name: "Valid config and invalid store type", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "some-pool-cluster", + PoolClusterNamespace: "some-pool-cluster-ns", + }, + storeType: "invalid-store", + pluginName: "some-plugin", + }, + wantErr: true, + }, + { + name: "Invalid config and valid store type", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "", + PoolClusterName: "", + PoolClusterNamespace: "", + }, + storeType: "helm", + pluginName: "some-plugin", + }, + wantErr: true, + }, + { + name: "Invalid config and invalid store type", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "", + PoolClusterName: "", + PoolClusterNamespace: "", + }, + storeType: "invalid-store", + pluginName: "some-plugin", + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := UnDeployPlugin(tt.args.captenConfig, tt.args.storeType, tt.args.pluginName); (err != nil) != tt.wantErr { + t.Errorf("UnDeployPlugin() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestShowClusterPluginData(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + type args struct { + captenConfig config.CaptenConfig + pluginName string + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Valid config and valid plugin name", + args: args{ + captenConfig: config.CaptenConfig{ + AgentSecure: true, + AgentHostName: "captenagent", + CertDirPath: "/" + presentdir + "/cert/", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + VaultCredHostName: "vault-cred", + AgentHostPort: ":443", + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + + KubeConfigFileName: "kubeconfig", + }, + pluginName: "argo-cd", + }, + wantErr: false, + }, + { + name: "Valid config and invalid plugin name", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "some-pool-cluster", + PoolClusterNamespace: "some-pool-cluster-ns", + }, + pluginName: "invalid-plugin", + }, + wantErr: true, + }, + { + name: "Invalid config and valid plugin name", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "", + PoolClusterName: "", + PoolClusterNamespace: "", + }, + pluginName: "some-plugin", + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := ShowClusterPluginData(tt.args.captenConfig, tt.args.pluginName); (err != nil) != tt.wantErr { + t.Errorf("ShowClusterPluginData() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/pkg/agent/plugin_configure_actions_test.go b/pkg/agent/plugin_configure_actions_test.go new file mode 100644 index 0000000..24da5e5 --- /dev/null +++ b/pkg/agent/plugin_configure_actions_test.go @@ -0,0 +1,274 @@ +package agent + +import ( + "capten/pkg/config" + "log" + + //"fmt" + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestConfigureClusterPlugin(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + captenConfig := config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsagent.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + } + + tests := []struct { + name string + pluginName string + action string + actionAttributes map[string]string + expectedError bool + }{ + { + name: "Valid tekton Plugin", + pluginName: "tekton", + action: "show-tekton-project", + actionAttributes: map[string]string{}, + expectedError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := ConfigureClusterPlugin(captenConfig, tt.pluginName, tt.action, tt.actionAttributes) + if tt.expectedError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestConfigureCrossplanePlugin(t *testing.T) { + captenConfig := config.CaptenConfig{} + + tests := []struct { + action string + actionAttributes map[string]string + expectedError error + }{ + {"list-actions", map[string]string{}, nil}, + } + + for _, test := range tests { + err := configureCrossplanePlugin(captenConfig, test.action, test.actionAttributes) + if err != nil && err.Error() != test.expectedError.Error() { + t.Errorf("For action %v: Expected error: %v, got: %v", test.action, test.expectedError, err) + } + + } +} + +func TestConfigureTektonPlugin(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + captenConfig := config.CaptenConfig{ + + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsagent.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + } + + tests := []struct { + action string + expectedError error + }{ + {"show-tekton-project", nil}, + } + + for _, test := range tests { + err := configureTektonPlugin(captenConfig, test.action) + + if err == nil && test.expectedError != nil { + t.Errorf("For action %v: Expected error: %v, got: nil", test.action, test.expectedError) + } + } +} + +func TestShowCrossplaneProject_Success(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + + captenConfig := config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsagent.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + } + + oldStdout := os.Stdout + _, w, _ := os.Pipe() + os.Stdout = w + + err = showCrossplaneProject(captenConfig) + + w.Close() + os.Stdout = oldStdout + + if err != nil { + t.Errorf("Expected no error, got %v", err) + } +} + +func TestShowCrossplaneProject_Error(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + + captenConfig := config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsagent.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + } + + err = showCrossplaneProject(captenConfig) + if err == nil { + t.Errorf("Expected an error, got nil") + } +} + +func TestSynchCrossplaneProject_Success(t *testing.T) { + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + + captenConfig := config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsagent.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + } + + err = synchCrossplaneProject(captenConfig) + if err != nil { + t.Errorf("Expected no error, got %v", err) + } +} + +func TestSynchCrossplaneProject_Error(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + + captenConfig := config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + } + + err = synchCrossplaneProject(captenConfig) + if err == nil { + t.Errorf("Expected an error, got nil") + } +} diff --git a/pkg/agent/plugin_store_actions_test.go b/pkg/agent/plugin_store_actions_test.go new file mode 100644 index 0000000..57207d2 --- /dev/null +++ b/pkg/agent/plugin_store_actions_test.go @@ -0,0 +1,438 @@ +package agent + +import ( + "capten/pkg/agent/pb/pluginstorepb" + "capten/pkg/config" + "log" + "os" + "reflect" + "testing" +) + +func Test_getStoreTypeEnum(t *testing.T) { + + type args struct { + storeType string + } + + tests := []struct { + name string + args args + want pluginstorepb.StoreType + wantErr bool + }{ + { + name: "central-store", + args: args{storeType: "central"}, + want: pluginstorepb.StoreType_CENTRAL_STORE, + wantErr: false, + }, + { + name: "default", + args: args{storeType: "default"}, + want: pluginstorepb.StoreType_DEFAULT_STORE, + wantErr: false, + }, + { + name: "local-store", + args: args{storeType: "local-store"}, + want: pluginstorepb.StoreType_LOCAL_STORE, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := getStoreTypeEnum(tt.args.storeType) + if (err != nil) != tt.wantErr { + t.Errorf("getStoreTypeEnum() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("getStoreTypeEnum() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestListPluginStoreApps(t *testing.T) { + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + + type args struct { + captenConfig config.CaptenConfig + storeType string + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Central store", + args: args{captenConfig: config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + }, storeType: "central"}, + wantErr: false, + }, + { + name: "Default store", + args: args{captenConfig: config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + }, storeType: "default"}, + wantErr: false, + }, + { + name: "Invalid store", + args: args{captenConfig: config.CaptenConfig{}, storeType: "local"}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := ListPluginStoreApps(tt.args.captenConfig, tt.args.storeType); (err != nil) != tt.wantErr { + t.Errorf("ListPluginStoreApps() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := ListPluginStoreApps(tt.args.captenConfig, tt.args.storeType); (err != nil) != tt.wantErr { + t.Errorf("ListPluginStoreApps() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestConfigPluginStore(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + + type args struct { + captenConfig config.CaptenConfig + storeType string + gitProjectId string + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Central store", + args: args{captenConfig: config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + }, storeType: "central-store", gitProjectId: "gpid"}, + wantErr: false, + }, + { + name: "Default store", + args: args{captenConfig: config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + }, storeType: "default", gitProjectId: "gpid"}, + wantErr: false, + }, + { + name: "Invalid store", + args: args{captenConfig: config.CaptenConfig{}, storeType: "invalid-store", gitProjectId: "gpid"}, + wantErr: true, + }, + { + name: "Empty gitProjectId", + args: args{captenConfig: config.CaptenConfig{}, storeType: "central-store", gitProjectId: ""}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := ConfigPluginStore(tt.args.captenConfig, tt.args.storeType, tt.args.gitProjectId); (err != nil) != tt.wantErr { + t.Errorf("ConfigPluginStore() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := ConfigPluginStore(tt.args.captenConfig, tt.args.storeType, tt.args.gitProjectId); (err != nil) != tt.wantErr { + t.Errorf("ConfigPluginStore() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestSynchPluginStore(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + + type args struct { + captenConfig config.CaptenConfig + storeType string + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Central store", + args: args{captenConfig: config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + }, storeType: "central-store"}, + wantErr: false, + }, + { + name: "Default store", + args: args{captenConfig: config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + }, storeType: "default"}, + wantErr: false, + }, + { + name: "Invalid store", + args: args{captenConfig: config.CaptenConfig{CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }}, storeType: "invalid-store"}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := SynchPluginStore(tt.args.captenConfig, tt.args.storeType); (err != nil) != tt.wantErr { + t.Errorf("SynchPluginStore() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := SynchPluginStore(tt.args.captenConfig, tt.args.storeType); (err != nil) != tt.wantErr { + t.Errorf("SynchPluginStore() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestShowPluginStorePlugin(t *testing.T) { + + currentdir, err := os.Getwd() + if err != nil { + log.Println("Error while getting cuerent dir", err) + } + presentdir, err := getRelativePathUpTo(currentdir) + + if err != nil { + log.Println("Error while getting working dir", err) + } + + type args struct { + captenConfig config.CaptenConfig + storeType string + pluginName string + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Central store valid plugin", + args: args{captenConfig: config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + }, storeType: "central-store", pluginName: "example-plugin"}, + wantErr: false, + }, + { + name: "Central store invalid plugin", + args: args{captenConfig: config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + }, storeType: "central-store", pluginName: "invalid-plugin"}, + wantErr: true, + }, + { + name: "Default store valid plugin", + args: args{captenConfig: config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + }, storeType: "default", pluginName: "example-plugin"}, + wantErr: false, + }, + { + name: "Default store invalid plugin", + args: args{captenConfig: config.CaptenConfig{ + CertDirPath: "/" + presentdir + "/cert/", + ConfigDirPath: "/" + presentdir + "/config/", + AgentHostName: "captenagent", + KubeConfigFileName: "kubeconfig", + ClientKeyFileName: "client.key", + ClientCertFileName: "client.crt", + CAFileName: "ca.crt", + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "awsdemo.optimizor.app", + }, + CaptenClusterHost: config.CaptenClusterHost{ + LoadBalancerHost: "a084c23852d0b428e98f363457fc8f8b-5ee99283c8b044fa.elb.us-west-2.amazonaws.com", + }, + }, storeType: "default", pluginName: "invalid-plugin"}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := ShowPluginStorePlugin(tt.args.captenConfig, tt.args.storeType, tt.args.pluginName); (err != nil) != tt.wantErr { + t.Errorf("ShowPluginStorePlugin() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := ShowPluginStorePlugin(tt.args.captenConfig, tt.args.storeType, tt.args.pluginName); (err != nil) != tt.wantErr { + t.Errorf("ShowPluginStorePlugin() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/pkg/agent/store_cred_test.go b/pkg/agent/store_cred_test.go index 54ac009..d8c70bd 100644 --- a/pkg/agent/store_cred_test.go +++ b/pkg/agent/store_cred_test.go @@ -33,9 +33,6 @@ func TestStoreCredentials(t *testing.T) { args: args{ captenConfig: config.CaptenConfig{ VaultCredHostName: "vault-cred", - - // VaultAddress: "http://localhost:8200", - // VaultToken: "s.1234567890", }, appGlobalVaules: map[string]interface{}{ "key1": "value1", @@ -49,7 +46,6 @@ func TestStoreCredentials(t *testing.T) { args: args{ captenConfig: config.CaptenConfig{ VaultCredHostName: "vault-cred", - // VaultToken: "s.1234567890", }, appGlobalVaules: map[string]interface{}{ "key1": "value1", @@ -156,7 +152,6 @@ func Test_storeKubeConfig(t *testing.T) { KubeConfigFileName: "kubeconfig", ConfigDirPath: "./testdata/kubeconfig", }, - // vaultClient: vaultcredpb.VaultCredClient{}, }, wantErr: true, }, @@ -357,13 +352,42 @@ func Test_configireCosignKeysSecret(t *testing.T) { captenConfig config.CaptenConfig vaultClient vaultcredpb.VaultCredClient } + tests := []struct { name string args args wantErr bool }{ - // TODO: Add test cases. + { + name: "Test empty config and vaultclient", + args: args{ + captenConfig: config.CaptenConfig{}, + //vaultClient: vaultcredpb.VaultCredClient{}, + }, + wantErr: true, + }, + { + name: "Test valid config and empty vaultclient", + args: args{ + captenConfig: config.CaptenConfig{ + //CosignSecretName: "cosign-secret", + }, + //vaultClient: vaultcredpb.VaultCredClient{}, + }, + wantErr: true, + }, + { + name: "Test valid config and valid vaultclient", + args: args{ + captenConfig: config.CaptenConfig{ + // CosignSecretName: "cosign-secret", + }, + //vaultClient: vaultcredpb.VaultCredClient{}, + }, + wantErr: false, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := configureCosignKeysSecret(tt.args.captenConfig, tt.args.vaultClient, types.CredentialAppConfig{}); (err != nil) != tt.wantErr { @@ -379,13 +403,48 @@ func Test_storeCosignKeys(t *testing.T) { appGlobalVaules map[string]interface{} vaultClient vaultcredpb.VaultCredClient } + tests := []struct { name string args args wantErr bool }{ - // TODO: Add test cases. + { + name: "Test empty config and vaultclient", + args: args{ + captenConfig: config.CaptenConfig{}, + appGlobalVaules: map[string]interface{}{}, + // vaultClient: vaultcredpb.VaultCredClient{}, + }, + wantErr: true, + }, + { + name: "Test valid config and empty vaultclient", + args: args{ + captenConfig: config.CaptenConfig{ + // CosignSecretName: "cosign-secret", + }, + appGlobalVaules: map[string]interface{}{}, + // vaultClient: vaultcredpb.VaultCredClient{}, + }, + wantErr: true, + }, + { + name: "Test valid config and valid vaultclient", + args: args{ + captenConfig: config.CaptenConfig{ + // CosignSecretName: "cosign-secret", + }, + appGlobalVaules: map[string]interface{}{ + "key1": "value1", + "key2": "value2", + }, + // vaultClient: vaultcredpb.VaultCredClient{}, + }, + wantErr: false, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := storeCredentials(tt.args.captenConfig, tt.args.appGlobalVaules, tt.args.vaultClient, types.CredentialAppConfig{}); (err != nil) != tt.wantErr { @@ -393,6 +452,7 @@ func Test_storeCosignKeys(t *testing.T) { } }) } + } func Test_storeTerraformStateConfig(t *testing.T) { @@ -400,13 +460,32 @@ func Test_storeTerraformStateConfig(t *testing.T) { captenConfig config.CaptenConfig vaultClient vaultcredpb.VaultCredClient } + tests := []struct { name string args args wantErr bool }{ - // TODO: Add test cases. + { + name: "Test with empty config and vaultclient", + args: args{ + captenConfig: config.CaptenConfig{}, + // vaultClient: vaultcredpb.VaultCredClient{}, + }, + wantErr: true, + }, + { + name: "Test with valid config and vaultclient", + args: args{ + captenConfig: config.CaptenConfig{ + // TerraformStateConfigFileName: "terraform_state_config.json", + ConfigDirPath: "./testdata", + }, + }, + wantErr: false, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := storeTerraformStateConfig(tt.args.captenConfig, tt.args.vaultClient); (err != nil) != tt.wantErr { diff --git a/pkg/agent/sync_apps_test.go b/pkg/agent/sync_apps_test.go index cfc3aa6..1e58fb6 100644 --- a/pkg/agent/sync_apps_test.go +++ b/pkg/agent/sync_apps_test.go @@ -9,7 +9,6 @@ import ( "testing" "gopkg.in/yaml.v2" - //"gopkg.in/yaml.v2" ) func TestSyncInstalledAppConfigsOnAgent(t *testing.T) { diff --git a/pkg/app/app_config_test.go b/pkg/app/app_config_test.go index 62499bd..aa601c4 100644 --- a/pkg/app/app_config_test.go +++ b/pkg/app/app_config_test.go @@ -12,41 +12,33 @@ import ( func TestGetClusterGlobalValues(t *testing.T) { t.Run("Success", func(t *testing.T) { - // Create a temporary YAML file with test data testValues := `key1: value1 key2: subkey1: subvalue1 subkey2: subvalue2` valuesFilePath := writeTempFile(t, testValues) - // Invoke the function values, err := GetClusterGlobalValues(valuesFilePath) - // Assert no error occurred assert.NoError(t, err) - // Assert correct values were returned assert.Equal(t, "value1", values["key1"]) assert.Equal(t, map[interface{}]interface{}{"subkey1": "subvalue1", "subkey2": "subvalue2"}, values["key2"]) }) t.Run("FileNotFound", func(t *testing.T) { - // Invoke the function with a non-existent file path values, err := GetClusterGlobalValues("/non/existent/file.yaml") - // Assert an error occurred assert.Error(t, err) assert.Nil(t, values) }) t.Run("InvalidYAML", func(t *testing.T) { - // Create a temporary YAML file with invalid YAML syntax invalidValues := `key1: value1 key2: subkey1: subvalue1 subkey2: subvalue2` valuesFilePath := writeTempFile(t, invalidValues) - // Corrupt the YAML syntax by adding an extra colon after "subkey2" corruptValues := `key1: value1 key2: subkey1: subvalue1 @@ -116,16 +108,6 @@ func TestGetApps(t *testing.T) { }, } - // for _, tt := range tests { - // t.Run(tt.name, func(t *testing.T) { - // tests := []struct { - // name string - // args args - // want []string - // wantErr bool - // }{ - // // TODO: Add test cases. - // } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := GetApps(tt.args.appListFilePath, "") @@ -202,8 +184,6 @@ func TestGetAppValuesTemplate(t *testing.T) { type args struct { captenConfig config.CaptenConfig appName string - // appConfigFilePath string - // globalValues map[string]interface{} } tests := []struct { name string @@ -319,21 +299,15 @@ func TestPrepareGlobalVaules(t *testing.T) { { name: "Valid captenConfig", args: args{ - captenConfig: config.CaptenConfig{ - // Set the required fields here - }, - }, - want: map[string]interface{}{ - // Set the expected result here + captenConfig: config.CaptenConfig{}, }, + want: map[string]interface{}{}, wantErr: false, }, { name: "Invalid captenConfig", args: args{ - captenConfig: config.CaptenConfig{ - // Set the required fields here - }, + captenConfig: config.CaptenConfig{}, }, want: nil, wantErr: true, diff --git a/pkg/app/app_deploy_test.go b/pkg/app/app_deploy_test.go index 19551cb..7550f8c 100644 --- a/pkg/app/app_deploy_test.go +++ b/pkg/app/app_deploy_test.go @@ -5,10 +5,8 @@ import ( "capten/pkg/helm" "capten/pkg/types" - //"context" "reflect" "testing" - //"github.com/pkg/errors" ) func TestDeployApps(t *testing.T) { @@ -89,12 +87,8 @@ func Test_installAppGroup(t *testing.T) { hc *helm.Client appConfigs []types.AppConfig }{ - captenConfig: config.CaptenConfig{ - // PrepareFilePath: func(string, string) string { - // return "kubeconfig" - // }, - }, - hc: &helm.Client{}, + captenConfig: config.CaptenConfig{}, + hc: &helm.Client{}, appConfigs: []types.AppConfig{ { PrivilegedNamespace: true, @@ -111,13 +105,8 @@ func Test_installAppGroup(t *testing.T) { hc *helm.Client appConfigs []types.AppConfig }{ - captenConfig: config.CaptenConfig{ - - // PrepareFilePath: func(string, string) string { - // return "kubeconfig" - // }, - }, - hc: &helm.Client{}, + captenConfig: config.CaptenConfig{}, + hc: &helm.Client{}, appConfigs: []types.AppConfig{ { PrivilegedNamespace: true, @@ -135,11 +124,7 @@ func Test_installAppGroup(t *testing.T) { appConfigs []types.AppConfig }{ captenConfig: config.CaptenConfig{}, - hc: &helm.Client{ - // Install: func(context.Context, *types.AppConfig) (bool, error) { - // return true, nil - // }, - }, + hc: &helm.Client{}, appConfigs: []types.AppConfig{ { Name: "test", @@ -156,11 +141,7 @@ func Test_installAppGroup(t *testing.T) { appConfigs []types.AppConfig }{ captenConfig: config.CaptenConfig{}, - hc: &helm.Client{ - // Install: func(context.Context, *types.AppConfig) (bool, error) { - // return false, errors.New("installation failed") - // }, - }, + hc: &helm.Client{}, appConfigs: []types.AppConfig{ { Name: "test", @@ -229,7 +210,6 @@ func Test_prepareAppGroupConfigs(t *testing.T) { wantAppConfigs: []types.AppConfig{}, wantErr: true, }, - // Add more test cases here... } for _, tt := range tests { @@ -246,18 +226,78 @@ func Test_prepareAppGroupConfigs(t *testing.T) { } } func Test_replaceOverrideTemplateValues(t *testing.T) { + type args struct { templateData map[string]interface{} values map[string]interface{} } + tests := []struct { name string args args wantTransformedData map[string]interface{} wantErr bool }{ - // TODO: Add test cases. + { + name: "valid template with single value", + args: args{ + templateData: map[string]interface{}{ + "name": "{{ .Name }}", + "age": 10, + }, + values: map[string]interface{}{ + "Name": "Alice", + }, + }, + wantTransformedData: map[string]interface{}{ + "name": "Alice", + "age": 10, + }, + wantErr: false, + }, + { + name: "valid template with multiple values", + args: args{ + templateData: map[string]interface{}{ + "name": "{{ .Name }}", + "age": "{{ .Age }}", + }, + values: map[string]interface{}{ + "Name": "Bob", + "Age": 20, + }, + }, + wantTransformedData: map[string]interface{}{ + "name": "Bob", + "age": 20, + }, + wantErr: false, + }, + { + name: "invalid template", + args: args{ + templateData: map[string]interface{}{ + "name": "{{ .Name }}", + "age": 10, + }, + values: map[string]interface{}{ + "Name": "Charlie", + }, + }, + wantTransformedData: nil, + wantErr: true, + }, + { + name: "template data is empty", + args: args{ + templateData: map[string]interface{}{}, + values: map[string]interface{}{}, + }, + wantTransformedData: map[string]interface{}{}, + wantErr: false, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { gotTransformedData, err := replaceOverrideTemplateValues(tt.args.templateData, tt.args.values) diff --git a/pkg/cluster/cluster_test.go b/pkg/cluster/cluster_test.go index 1626678..6524682 100644 --- a/pkg/cluster/cluster_test.go +++ b/pkg/cluster/cluster_test.go @@ -17,18 +17,14 @@ func TestCreate(t *testing.T) { { name: "Valid captenConfig", args: args{ - captenConfig: config.CaptenConfig{ - // Add valid captenConfig properties here - }, + captenConfig: config.CaptenConfig{}, }, wantErr: false, }, { name: "Invalid captenConfig", args: args{ - captenConfig: config.CaptenConfig{ - // Add invalid captenConfig properties here - }, + captenConfig: config.CaptenConfig{}, }, wantErr: true, }, @@ -53,18 +49,14 @@ func TestDestroy(t *testing.T) { { name: "Successful destruction of a cluster", args: args{ - captenConfig: config.CaptenConfig{ - // Add valid captenConfig properties here - }, + captenConfig: config.CaptenConfig{}, }, wantErr: false, }, { name: "Error handling when trying to destroy a non-existing cluster", args: args{ - captenConfig: config.CaptenConfig{ - // Add invalid captenConfig properties here - }, + captenConfig: config.CaptenConfig{}, }, wantErr: true, }, diff --git a/pkg/cluster/k3s/k3s_test.go b/pkg/cluster/k3s/k3s_test.go index b1ef7fc..cf6d6b0 100644 --- a/pkg/cluster/k3s/k3s_test.go +++ b/pkg/cluster/k3s/k3s_test.go @@ -2,26 +2,20 @@ package k3s import ( "capten/pkg/config" - // "reflect" "strings" "testing" ) func Test_getClusterInfo(t *testing.T) { - validConfig := config.CaptenConfig{ - // Add valid configuration fields here - } + validConfig := config.CaptenConfig{} type args struct { captenConfig config.CaptenConfig } - invalidConfig := config.CaptenConfig{ - // Add invalid configuration fields here - } + invalidConfig := config.CaptenConfig{} tests := []struct { - name string - args args - // want interface{} + name string + args args wantErr bool }{ { @@ -29,7 +23,6 @@ func Test_getClusterInfo(t *testing.T) { args: args{ captenConfig: validConfig, }, - // want: // Add expected result for valid config, wantErr: false, }, { @@ -37,7 +30,6 @@ func Test_getClusterInfo(t *testing.T) { args: args{ captenConfig: invalidConfig, }, - // want: // Add expected result for invalid config, wantErr: true, }, } @@ -49,15 +41,12 @@ func Test_getClusterInfo(t *testing.T) { t.Errorf("getClusterInfo() error = %v, wantErr %v", err, tt.wantErr) return } - // if !reflect.DeepEqual(got, tt.want) { - // t.Errorf("getClusterInfo() = %v, want %v", got, tt.want) - // } + }) } } func Test_createOrDestroyCluster(t *testing.T) { - // Test create or destroy cluster using valid and invalid config - // and both create and destroy actions + type args struct { captenConfig config.CaptenConfig action string @@ -194,22 +183,22 @@ func Test_generateTemplateVarFile(t *testing.T) { }{ { name: "Successful Generation", - captenConfig: config.CaptenConfig{}, // Fill in with appropriate config - clusterInfo: "testClusterInfo", // Fill in with appropriate cluster info - templateFile: "testTemplateFile", // Fill in with appropriate template file + captenConfig: config.CaptenConfig{}, + clusterInfo: "testClusterInfo", + templateFile: "testTemplateFile", }, { name: "Error Reading Template File", - captenConfig: config.CaptenConfig{}, // Fill in with appropriate config - clusterInfo: "testClusterInfo", // Fill in with appropriate cluster info - templateFile: "invalidTemplateFile", // An invalid template file that should cause an error + captenConfig: config.CaptenConfig{}, + clusterInfo: "testClusterInfo", + templateFile: "invalidTemplateFile", expectedErrMsg: "failed to read template file", }, { name: "Error Creating Template File", - captenConfig: config.CaptenConfig{}, // Fill in with appropriate config - clusterInfo: "testClusterInfo", // Fill in with appropriate cluster info - templateFile: "testTemplateFile", // Fill in with appropriate template file + captenConfig: config.CaptenConfig{}, + clusterInfo: "testClusterInfo", + templateFile: "testTemplateFile", expectedErrMsg: "failed to create template file", }, } diff --git a/pkg/cmd/capten_test.go b/pkg/cmd/capten_test.go new file mode 100644 index 0000000..b51b32b --- /dev/null +++ b/pkg/cmd/capten_test.go @@ -0,0 +1,115 @@ +package cmd + +import ( + "testing" + + "github.com/spf13/cobra" +) + +func Test_readAndValidClusterFlags(t *testing.T) { + type args struct { + cmd *cobra.Command + } + + cloudService := "aws" + clusterType := "k3s" + + tests := []struct { + name string + args args + wantCloudService string + wantClusterType string + wantErr bool + }{ + { + name: "Valid Cluster Flags", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("cloud-service", cloudService, "cloud service") + cmd.Flags().String("cluster-type", clusterType, "cluster type") + return cmd + }(), + }, + wantCloudService: cloudService, + wantClusterType: clusterType, + wantErr: false, + }, + { + name: "Invalid Cluster Flags", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("cloud-service", "", "cloud service") + cmd.Flags().String("cluster-type", "", "cluster type") + return cmd + }(), + }, + wantCloudService: "", + wantClusterType: "", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotCloudService, gotClusterType, err := readAndValidClusterFlags(tt.args.cmd) + if (err != nil) != tt.wantErr { + t.Errorf("readAndValidClusterFlags() error = %v, wantErr %v", err, tt.wantErr) + return + } + if gotCloudService != tt.wantCloudService { + t.Errorf("readAndValidClusterFlags() gotCloudService = %v, want %v", gotCloudService, tt.wantCloudService) + } + if gotClusterType != tt.wantClusterType { + t.Errorf("readAndValidClusterFlags() gotClusterType = %v, want %v", gotClusterType, tt.wantClusterType) + } + }) + } +} + +func Test_validateClusterFlags(t *testing.T) { + type args struct { + cloudService string + clusterType string + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "supported cloud service and cluster type", + args: args{ + cloudService: "aws", + clusterType: "talos", + }, + wantErr: false, + }, + { + name: "unsupported cloud service", + args: args{ + cloudService: "not-supported", + clusterType: "talos", + }, + wantErr: true, + }, + { + name: "unsupported cluster type", + args: args{ + cloudService: "aws", + clusterType: "not-supported", + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := validateClusterFlags(tt.args.cloudService, tt.args.clusterType); (err != nil) != tt.wantErr { + t.Errorf("validateClusterFlags() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/pkg/cmd/cluster_apps_cmd_test.go b/pkg/cmd/cluster_apps_cmd_test.go new file mode 100644 index 0000000..e3de386 --- /dev/null +++ b/pkg/cmd/cluster_apps_cmd_test.go @@ -0,0 +1,279 @@ +package cmd + +import ( + "capten/pkg/config" + "fmt" + "reflect" + "testing" + "time" + + "github.com/spf13/cobra" +) + +func Test_readAppsNameFlags(t *testing.T) { + type args struct { + cmd *cobra.Command + } + + tests := []struct { + name string + args args + wantAppsName string + wantErr bool + }{ + { + name: "Valid Apps Name Flag", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("apps-name", "test-app", "apps name") + return cmd + }(), + }, + wantAppsName: "test-app", + wantErr: false, + }, + { + name: "Invalid Apps Name Flag", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("apps-name", "", "apps name") + return cmd + }(), + }, + wantAppsName: "", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotAppsName, err := readAppsNameFlags(tt.args.cmd) + if (err != nil) != tt.wantErr { + t.Errorf("readAppsNameFlags() error = %v, wantErr %v", err, tt.wantErr) + return + } + if gotAppsName != tt.wantAppsName { + t.Errorf("readAppsNameFlags() = %v, want %v", gotAppsName, tt.wantAppsName) + } + }) + } +} + +func Test_loadSetupAppsActions(t *testing.T) { + type args struct { + captenConfig config.CaptenConfig + } + + tests := []struct { + name string + args args + want *SetupAppsActionList + wantErr bool + }{ + { + name: "Valid captenConfig", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + }, + }, + want: &SetupAppsActionList{}, + wantErr: false, + }, + { + name: "Invalid captenConfig", + args: args{ + captenConfig: config.CaptenConfig{}, + }, + want: nil, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := loadSetupAppsActions(tt.args.captenConfig) + if (err != nil) != tt.wantErr { + t.Errorf("loadSetupAppsActions() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("loadSetupAppsActions() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_isEnabled(t *testing.T) { + type args struct { + actionConfig map[string]interface{} + } + + tests := []struct { + name string + args args + want bool + }{ + { + name: "True", + args: args{ + actionConfig: map[string]interface{}{ + "enabled": true, + }, + }, + want: true, + }, + { + name: "False", + args: args{ + actionConfig: map[string]interface{}{ + "enabled": false, + }, + }, + want: false, + }, + { + name: "Nil", + args: args{ + actionConfig: nil, + }, + want: false, + }, + { + name: "Empty", + args: args{ + actionConfig: map[string]interface{}{}, + }, + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := isEnabled(tt.args.actionConfig); got != tt.want { + t.Errorf("isEnabled() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_execActionIfEnabled(t *testing.T) { + type args struct { + actionConfig map[string]interface{} + f func() error + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Enabled", + args: args{ + actionConfig: map[string]interface{}{ + "enabled": true, + }, + f: func() error { + return nil + }, + }, + wantErr: false, + }, + { + name: "Disabled", + args: args{ + actionConfig: map[string]interface{}{ + "enabled": false, + }, + f: func() error { + return fmt.Errorf("should not be called") + }, + }, + wantErr: false, + }, + { + name: "Nil", + args: args{ + actionConfig: nil, + f: func() error { return fmt.Errorf("should not be called") }, + }, + wantErr: false, + }, + { + name: "Empty", + args: args{ + actionConfig: map[string]interface{}{}, + f: func() error { return fmt.Errorf("should not be called") }, + }, + wantErr: false, + }, + { + name: "Error", + args: args{ + actionConfig: map[string]interface{}{ + "enabled": true, + }, + f: func() error { + return fmt.Errorf("some error") + }, + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := execActionIfEnabled(tt.args.actionConfig, tt.args.f); (err != nil) != tt.wantErr { + t.Errorf("execActionIfEnabled() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } + +} + +func Test_retry(t *testing.T) { + type args struct { + retries int + interval time.Duration + f func() error + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Successful after one retry", + args: args{ + retries: 2, + interval: 10 * time.Millisecond, + f: func() error { + return nil + }, + }, + wantErr: false, + }, + { + name: "Unsuccessful after max retries", + args: args{ + retries: 2, + interval: 10 * time.Millisecond, + f: func() error { + return fmt.Errorf("some error") + }, + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := retry(tt.args.retries, tt.args.interval, tt.args.f); (err != nil) != tt.wantErr { + t.Errorf("retry() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/pkg/cmd/cluster_resource_cmd_test.go b/pkg/cmd/cluster_resource_cmd_test.go new file mode 100644 index 0000000..a096cad --- /dev/null +++ b/pkg/cmd/cluster_resource_cmd_test.go @@ -0,0 +1,363 @@ +package cmd + +import ( + "reflect" + "testing" + + "github.com/spf13/cobra" +) + +func Test_readAndValidResourceIdentfierFlags(t *testing.T) { + type args struct { + cmd *cobra.Command + } + tests := []struct { + name string + args args + wantResourceType string + wantId string + wantErr bool + }{ + { + name: "Valid Resource", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("resource-type", "test-type", "resource type") + cmd.Flags().String("id", "test-id", "resource id") + return cmd + }(), + }, + wantResourceType: "test-type", + wantId: "test-id", + wantErr: false, + }, + { + name: "Invalid Resource", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("resource-type", "", "resource type") + cmd.Flags().String("id", "", "resource id") + return cmd + }(), + }, + wantResourceType: "", + wantId: "", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotResourceType, gotId, err := readAndValidResourceIdentfierFlags(tt.args.cmd) + if (err != nil) != tt.wantErr { + t.Errorf("readAndValidResourceIdentfierFlags() error = %v, wantErr %v", err, tt.wantErr) + return + } + if gotResourceType != tt.wantResourceType { + t.Errorf("readAndValidResourceIdentfierFlags() gotResourceType = %v, want %v", gotResourceType, tt.wantResourceType) + } + if gotId != tt.wantId { + t.Errorf("readAndValidResourceIdentfierFlags() gotId = %v, want %v", gotId, tt.wantId) + } + }) + } +} + +func Test_readCloudTypeAttributesFlags(t *testing.T) { + type args struct { + cmd *cobra.Command + cloudType string + } + + tests := []struct { + name string + args args + wantAttributes map[string]string + wantErr bool + }{ + { + name: "valid AWS flags", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("access-key", "test-access-key", "access key") + cmd.Flags().String("secret-key", "test-secret-key", "secret key") + return cmd + }(), + cloudType: "aws", + }, + wantAttributes: map[string]string{ + "access-key": "test-access-key", + "secret-key": "test-secret-key", + }, + wantErr: false, + }, + { + name: "valid Azure flags", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("client-id", "test-client-id", "client id") + cmd.Flags().String("client-secret", "test-client-secret", "client secret") + return cmd + }(), + cloudType: "azure", + }, + wantAttributes: map[string]string{ + "client-id": "test-client-id", + "client-secret": "test-client-secret", + }, + wantErr: false, + }, + { + name: "invalid cloud type", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + return cmd + }(), + cloudType: "invalid", + }, + wantAttributes: nil, + wantErr: true, + }, + { + name: "empty AWS flags", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + return cmd + }(), + cloudType: "aws", + }, + wantAttributes: nil, + wantErr: true, + }, + { + name: "empty Azure flags", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + return cmd + }(), + cloudType: "azure", + }, + wantAttributes: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotAttributes, err := readCloudTypeAttributesFlags(tt.args.cmd, tt.args.cloudType) + if (err != nil) != tt.wantErr { + t.Errorf("readCloudTypeAttributesFlags() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(gotAttributes, tt.wantAttributes) { + t.Errorf("readCloudTypeAttributesFlags() = %v, want %v", gotAttributes, tt.wantAttributes) + } + }) + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotAttributes, err := readCloudTypeAttributesFlags(tt.args.cmd, tt.args.cloudType) + if (err != nil) != tt.wantErr { + t.Errorf("readCloudTypeAttributesFlags() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(gotAttributes, tt.wantAttributes) { + t.Errorf("readCloudTypeAttributesFlags() = %v, want %v", gotAttributes, tt.wantAttributes) + } + }) + } +} + +func Test_readAndValidResourceDataFlags(t *testing.T) { + type args struct { + cmd *cobra.Command + resourceType string + } + + tests := []struct { + name string + args args + wantAttributes map[string]string + wantErr bool + }{ + { + name: "ResourceType is empty", + args: args{ + cmd: &cobra.Command{}, + }, + wantAttributes: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotAttributes, err := readAndValidResourceDataFlags(tt.args.cmd, tt.args.resourceType) + if (err != nil) != tt.wantErr { + t.Errorf("readAndValidResourceDataFlags() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(gotAttributes, tt.wantAttributes) { + t.Errorf("readAndValidResourceDataFlags() = %v, want %v", gotAttributes, tt.wantAttributes) + } + }) + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotAttributes, err := readAndValidResourceDataFlags(tt.args.cmd, tt.args.resourceType) + if (err != nil) != tt.wantErr { + t.Errorf("readAndValidResourceDataFlags() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(gotAttributes, tt.wantAttributes) { + t.Errorf("readAndValidResourceDataFlags() = %v, want %v", gotAttributes, tt.wantAttributes) + } + }) + } +} + +func Test_readAndValidCreateResourceFlags(t *testing.T) { + type args struct { + cmd *cobra.Command + } + + tests := []struct { + name string + args args + wantResourceType string + wantAttributes map[string]string + wantErr bool + }{ + { + name: "missing resource type", + args: args{ + cmd: &cobra.Command{}, + }, + wantResourceType: "", + wantAttributes: nil, + wantErr: true, + }, + { + name: "no attributes", + args: args{ + cmd: &cobra.Command{}, + }, + wantResourceType: "test-type", + wantAttributes: map[string]string{}, + wantErr: false, + }, + { + name: "with attributes", + args: args{ + cmd: &cobra.Command{}, + }, + wantResourceType: "test-type", + wantAttributes: map[string]string{ + "key1": "value1", + "key2": "value2", + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotResourceType, gotAttributes, err := readAndValidCreateResourceFlags(tt.args.cmd) + if (err != nil) != tt.wantErr { + t.Errorf("readAndValidCreateResourceFlags() error = %v, wantErr %v", err, tt.wantErr) + return + } + if gotResourceType != tt.wantResourceType { + t.Errorf("readAndValidCreateResourceFlags() gotResourceType = %v, want %v", gotResourceType, tt.wantResourceType) + } + if !reflect.DeepEqual(gotAttributes, tt.wantAttributes) { + t.Errorf("readAndValidCreateResourceFlags() gotAttributes = %v, want %v", gotAttributes, tt.wantAttributes) + } + }) + } +} + +func Test_readAndValidUpdateResourceFlags(t *testing.T) { + type args struct { + cmd *cobra.Command + } + + tests := []struct { + name string + args args + wantResourceType string + wantId string + wantAttributes map[string]string + wantErr bool + }{ + { + name: "valid flags", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("resource-type", "test-type", "resource type") + cmd.Flags().String("id", "test-id", "resource id") + cmd.Flags().String("key1", "value1", "attribute key1") + cmd.Flags().String("key2", "value2", "attribute key2") + return cmd + }(), + }, + wantResourceType: "test-type", + wantId: "test-id", + wantAttributes: map[string]string{ + "key1": "value1", + "key2": "value2", + }, + wantErr: false, + }, + { + name: "missing resource type", + args: args{ + cmd: &cobra.Command{}, + }, + wantResourceType: "", + wantId: "", + wantAttributes: nil, + wantErr: true, + }, + { + name: "missing id", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("resource-type", "test-type", "resource type") + return cmd + }(), + }, + wantResourceType: "test-type", + wantId: "", + wantAttributes: nil, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotResourceType, gotId, gotAttributes, err := readAndValidUpdateResourceFlags(tt.args.cmd) + if (err != nil) != tt.wantErr { + t.Errorf("readAndValidUpdateResourceFlags() error = %v, wantErr %v", err, tt.wantErr) + return + } + if gotResourceType != tt.wantResourceType { + t.Errorf("readAndValidUpdateResourceFlags() gotResourceType = %v, want %v", gotResourceType, tt.wantResourceType) + } + if gotId != tt.wantId { + t.Errorf("readAndValidUpdateResourceFlags() gotId = %v, want %v", gotId, tt.wantId) + } + if !reflect.DeepEqual(gotAttributes, tt.wantAttributes) { + t.Errorf("readAndValidUpdateResourceFlags() gotAttributes = %v, want %v", gotAttributes, tt.wantAttributes) + } + }) + } +} diff --git a/pkg/cmd/plugin_store_cmd_test.go b/pkg/cmd/plugin_store_cmd_test.go new file mode 100644 index 0000000..b6b21d0 --- /dev/null +++ b/pkg/cmd/plugin_store_cmd_test.go @@ -0,0 +1,218 @@ +package cmd + +import ( + "testing" + + "github.com/spf13/cobra" +) + +func Test_readAndValidatePluginStoreTypeFlags(t *testing.T) { + type args struct { + cmd *cobra.Command + } + + tests := []struct { + name string + args args + wantStoreType string + wantErr bool + }{ + { + name: "valid store type flag", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("store-type", "test-store-type", "store type") + return cmd + }(), + }, + wantStoreType: "test-store-type", + wantErr: false, + }, + { + name: "invalid store type flag", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("store-type", "", "store type") + return cmd + }(), + }, + wantStoreType: "", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotStoreType, err := readAndValidatePluginStoreTypeFlags(tt.args.cmd) + if (err != nil) != tt.wantErr { + t.Errorf("readAndValidatePluginStoreTypeFlags() error = %v, wantErr %v", err, tt.wantErr) + return + } + if gotStoreType != tt.wantStoreType { + t.Errorf("readAndValidatePluginStoreTypeFlags() = %v, want %v", gotStoreType, tt.wantStoreType) + } + }) + } +} + +func Test_readAndValidatePluginStoreShowFlags(t *testing.T) { + type args struct { + cmd *cobra.Command + } + + tests := []struct { + name string + args args + wantPluginName string + wantStoreType string + wantErr bool + }{ + { + name: "valid flags", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("plugin", "test-plugin", "plugin name") + cmd.Flags().String("store-type", "test-store-type", "store type") + return cmd + }(), + }, + wantPluginName: "test-plugin", + wantStoreType: "test-store-type", + wantErr: false, + }, + { + name: "missing store type flag", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("plugin", "test-plugin", "plugin name") + return cmd + }(), + }, + wantPluginName: "", + wantStoreType: "", + wantErr: true, + }, + { + name: "missing plugin flag", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("store-type", "test-store-type", "store type") + return cmd + }(), + }, + wantPluginName: "", + wantStoreType: "", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotPluginName, gotStoreType, err := readAndValidatePluginStoreShowFlags(tt.args.cmd) + if (err != nil) != tt.wantErr { + t.Errorf("readAndValidatePluginStoreShowFlags() error = %v, wantErr %v", err, tt.wantErr) + return + } + if gotPluginName != tt.wantPluginName { + t.Errorf("readAndValidatePluginStoreShowFlags() gotPluginName = %v, want %v", gotPluginName, tt.wantPluginName) + } + if gotStoreType != tt.wantStoreType { + t.Errorf("readAndValidatePluginStoreShowFlags() gotStoreType = %v, want %v", gotStoreType, tt.wantStoreType) + } + }) + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotPluginName, gotStoreType, err := readAndValidatePluginStoreShowFlags(tt.args.cmd) + if (err != nil) != tt.wantErr { + t.Errorf("readAndValidatePluginStoreShowFlags() error = %v, wantErr %v", err, tt.wantErr) + return + } + if gotPluginName != tt.wantPluginName { + t.Errorf("readAndValidatePluginStoreShowFlags() gotPluginName = %v, want %v", gotPluginName, tt.wantPluginName) + } + if gotStoreType != tt.wantStoreType { + t.Errorf("readAndValidatePluginStoreShowFlags() gotStoreType = %v, want %v", gotStoreType, tt.wantStoreType) + } + }) + } +} + +func Test_readAndValidatePluginStoreConfigFlags(t *testing.T) { + type args struct { + cmd *cobra.Command + } + + tests := []struct { + name string + args args + wantStoreType string + wantGitProjectId string + wantErr bool + }{ + { + name: "valid flags", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("store-type", "test-store-type", "store type") + cmd.Flags().String("git-project-id", "test-git-project-id", "git project id") + return cmd + }(), + }, + wantStoreType: "test-store-type", + wantGitProjectId: "test-git-project-id", + wantErr: false, + }, + { + name: "invalid store type flag", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("store-type", "", "store type") + cmd.Flags().String("git-project-id", "test-git-project-id", "git project id") + return cmd + }(), + }, + wantStoreType: "", + wantGitProjectId: "", + wantErr: true, + }, + { + name: "invalid git project id flag", + args: args{ + cmd: func() *cobra.Command { + cmd := &cobra.Command{} + cmd.Flags().String("store-type", "test-store-type", "store type") + cmd.Flags().String("git-project-id", "", "git project id") + return cmd + }(), + }, + wantStoreType: "", + wantGitProjectId: "", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotStoreType, gotGitProjectId, err := readAndValidatePluginStoreConfigFlags(tt.args.cmd) + if (err != nil) != tt.wantErr { + t.Errorf("readAndValidatePluginStoreConfigFlags() error = %v, wantErr %v", err, tt.wantErr) + return + } + if gotStoreType != tt.wantStoreType { + t.Errorf("readAndValidatePluginStoreConfigFlags() gotStoreType = %v, want %v", gotStoreType, tt.wantStoreType) + } + if gotGitProjectId != tt.wantGitProjectId { + t.Errorf("readAndValidatePluginStoreConfigFlags() gotGitProjectId = %v, want %v", gotGitProjectId, tt.wantGitProjectId) + } + }) + } +} diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go new file mode 100644 index 0000000..a1a95ac --- /dev/null +++ b/pkg/config/config_test.go @@ -0,0 +1,89 @@ +package config + +import ( + "fmt" + "log" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +type MockOS struct { + mock.Mock +} + +func (m *MockOS) Getwd() (string, error) { + args := m.Called() + return args.String(0), args.Error(1) +} + +func (m *MockOS) ReadFile(filename string) ([]byte, error) { + args := m.Called(filename) + return args.Get(0).([]byte), args.Error(1) +} + +func (m *MockOS) WriteFile(filename string, data []byte, perm os.FileMode) error { + args := m.Called(filename, data, perm) + return args.Error(0) +} + +var originalOsGetwd = os.Getwd +var originalOsReadFile = os.ReadFile +var originalOsWriteFile = os.WriteFile + +func TestUpdateLBEndpointFile(t *testing.T) { + mockOS := new(MockOS) + currentdir, err := os.Getwd() + if err != nil { + log.Println("error while fetching current dir", err) + } + dirpath, err := getRelativePathUpTo(currentdir) + if err != nil { + log.Println("error while fetching relative dir", err) + } + tmp := "/" + dirpath + "/config/" + cfg := &CaptenConfig{ + CaptenHostValuesFileName: "capten-lb-endpoint.yaml", + ConfigDirPath: tmp, + } + + yamlContent := `loadBalancerHost: oldhost` + mockOS.On("ReadFile", cfg.PrepareFilePath(cfg.ConfigDirPath, cfg.CaptenHostValuesFileName)).Return([]byte(yamlContent), nil) + + mockOS.On("WriteFile", cfg.PrepareFilePath(cfg.ConfigDirPath, cfg.CaptenHostValuesFileName), mock.Anything, os.FileMode(0644)).Return(nil) + + err = UpdateLBEndpointFile(cfg, "newhost", "") + require.NoError(t, err) + assert.Equal(t, "newhost", cfg.LoadBalancerHost) + + mockOS.On("ReadFile", cfg.PrepareFilePath(cfg.ConfigDirPath, cfg.CaptenHostValuesFileName)).Return(nil, errors.New("failed to read file")) + + err = UpdateLBEndpointFile(cfg, "newhost", "") + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to read file") + + mockOS.On("WriteFile", cfg.PrepareFilePath(cfg.ConfigDirPath, cfg.CaptenHostValuesFileName), mock.Anything, os.FileMode(0644)).Return(errors.New("failed to write file")) + + err = UpdateLBEndpointFile(cfg, "newhost", "") + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to write file") +} + +func getRelativePathUpTo(currentPath string) (string, error) { + targetDir := "capten" + parts := strings.Split(currentPath, string(filepath.Separator)) + + for i, part := range parts { + if part == targetDir { + return filepath.Join(parts[:i+1]...), nil + } + } + + return "", fmt.Errorf("directory %s not found in path %s", targetDir, currentPath) +} diff --git a/pkg/helm/client_test.go b/pkg/helm/client_test.go index 49b720a..82cd70b 100644 --- a/pkg/helm/client_test.go +++ b/pkg/helm/client_test.go @@ -4,10 +4,12 @@ import ( "capten/pkg/config" "capten/pkg/types" "context" + "os" "reflect" "testing" "time" + "github.com/stretchr/testify/assert" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli" ) @@ -19,35 +21,50 @@ func TestNewClient(t *testing.T) { tests := []struct { name string args args - want *Client wantErr bool }{ - // TODO: Add test cases. + { + name: "valid config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + }, + }, + wantErr: false, + }, + { + name: "empty config", + args: args{ + captenConfig: config.CaptenConfig{}, + }, + wantErr: true, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := NewClient(tt.args.captenConfig) + _, err := NewClient(tt.args.captenConfig) if (err != nil) != tt.wantErr { t.Errorf("NewClient() error = %v, wantErr %v", err, tt.wantErr) return } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("NewClient() = %v, want %v", got, tt.want) - } + }) } } func TestClient_Install(t *testing.T) { + + type args struct { + ctx context.Context + appConfig *types.AppConfig + } type fields struct { Settings *cli.EnvSettings defaultTimeout time.Duration captenConfig config.CaptenConfig } - type args struct { - ctx context.Context - appConfig *types.AppConfig - } + tests := []struct { name string fields fields @@ -55,8 +72,32 @@ func TestClient_Install(t *testing.T) { wantAlreadyInstalled bool wantErr bool }{ - // TODO: Add test cases. + { + name: "valid app config", + args: args{ + ctx: context.TODO(), + appConfig: &types.AppConfig{ + ChartName: "mysql", + Name: "mysql-test", + Namespace: "default", + }, + }, + wantErr: false, + }, + { + name: "invalid app config", + args: args{ + ctx: context.TODO(), + appConfig: &types.AppConfig{ + ChartName: "unknown-chart", + Name: "mysql-test", + Namespace: "default", + }, + }, + wantErr: true, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { h := &Client{ @@ -94,8 +135,38 @@ func TestClient_installApp(t *testing.T) { args args wantErr bool }{ - // TODO: Add test cases. + { + name: "valid action config", + fields: fields{ + Settings: &cli.EnvSettings{}, + defaultTimeout: time.Second * 10, + captenConfig: config.CaptenConfig{}, + }, + args: args{ + ctx: context.TODO(), + settings: &cli.EnvSettings{}, + actionConfig: &action.Configuration{}, + appConfig: &types.AppConfig{}, + }, + wantErr: false, + }, + { + name: "invalid action config", + fields: fields{ + Settings: &cli.EnvSettings{}, + defaultTimeout: time.Second * 10, + captenConfig: config.CaptenConfig{}, + }, + args: args{ + ctx: context.TODO(), + settings: &cli.EnvSettings{}, + actionConfig: &action.Configuration{}, + appConfig: &types.AppConfig{}, + }, + wantErr: true, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { h := &Client{ @@ -116,20 +187,52 @@ func TestClient_upgradeApp(t *testing.T) { defaultTimeout time.Duration captenConfig config.CaptenConfig } + type args struct { ctx context.Context settings *cli.EnvSettings actionConfig *action.Configuration appConfig *types.AppConfig } + tests := []struct { name string fields fields args args wantErr bool }{ - // TODO: Add test cases. + { + name: "valid action config", + fields: fields{ + Settings: &cli.EnvSettings{}, + defaultTimeout: time.Second * 10, + captenConfig: config.CaptenConfig{}, + }, + args: args{ + ctx: context.TODO(), + settings: &cli.EnvSettings{}, + actionConfig: &action.Configuration{}, + appConfig: &types.AppConfig{}, + }, + wantErr: false, + }, + { + name: "invalid action config", + fields: fields{ + Settings: &cli.EnvSettings{}, + defaultTimeout: time.Second * 10, + captenConfig: config.CaptenConfig{}, + }, + args: args{ + ctx: context.TODO(), + settings: &cli.EnvSettings{}, + actionConfig: &action.Configuration{}, + appConfig: &types.AppConfig{}, + }, + wantErr: true, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { h := &Client{ @@ -142,6 +245,7 @@ func TestClient_upgradeApp(t *testing.T) { } }) } + } func TestClient_IsAppInstalled(t *testing.T) { @@ -150,10 +254,12 @@ func TestClient_IsAppInstalled(t *testing.T) { defaultTimeout time.Duration captenConfig config.CaptenConfig } + type args struct { actionConfig *action.Configuration releaseName string } + tests := []struct { name string fields fields @@ -161,8 +267,36 @@ func TestClient_IsAppInstalled(t *testing.T) { want bool wantErr bool }{ - // TODO: Add test cases. + { + name: "app installed", + fields: fields{ + Settings: &cli.EnvSettings{}, + defaultTimeout: time.Second * 10, + captenConfig: config.CaptenConfig{}, + }, + args: args{ + actionConfig: &action.Configuration{}, + releaseName: "installed-app", + }, + want: true, + wantErr: false, + }, + { + name: "app not installed", + fields: fields{ + Settings: &cli.EnvSettings{}, + defaultTimeout: time.Second * 10, + captenConfig: config.CaptenConfig{}, + }, + args: args{ + actionConfig: &action.Configuration{}, + releaseName: "not-installed-app", + }, + want: false, + wantErr: false, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { h := &Client{ @@ -187,14 +321,38 @@ func Test_executeAppConfigTemplate(t *testing.T) { data []byte values map[string]interface{} } + tests := []struct { name string args args wantTransformedData []byte wantErr bool }{ - // TODO: Add test cases. + { + name: "Valid template with single value", + args: args{ + data: []byte("Hello {{ .Name }}!"), + values: map[string]interface{}{ + "Name": "Alice", + }, + }, + wantTransformedData: []byte("Hello Alice!"), + wantErr: false, + }, + { + name: "Valid template with multiple values", + args: args{ + data: []byte("{{ .Name }} is {{ .Age }} years old."), + values: map[string]interface{}{ + "Name": "Bob", + "Age": 25, + }, + }, + wantTransformedData: []byte("Bob is 25 years old."), + wantErr: false, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { gotTransformedData, err := executeAppConfigTemplate(tt.args.data, tt.args.values) @@ -209,39 +367,39 @@ func Test_executeAppConfigTemplate(t *testing.T) { } } -func TestClient_prepareAppValues(t *testing.T) { - type fields struct { - Settings *cli.EnvSettings - defaultTimeout time.Duration - captenConfig config.CaptenConfig - } - type args struct { - appConfig *types.AppConfig +var mockWriteFile = func(filename string, data []byte, perm os.FileMode) error { + return nil +} + +func TestPrepareAppValues_Success(t *testing.T) { + client := &Client{ /* initialize fields if necessary */ } + appConfig := &types.AppConfig{ + Name: "test-app", + TemplateValues: []byte("valid-template"), + OverrideValues: map[string]interface{}{"key": "value"}, } - tests := []struct { - name string - fields fields - args args - want string - wantErr bool - }{ - // TODO: Add test cases. + + mockWriteFile = func(filename string, data []byte, perm os.FileMode) error { + return nil } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - h := &Client{ - Settings: tt.fields.Settings, - defaultTimeout: tt.fields.defaultTimeout, - captenConfig: tt.fields.captenConfig, - } - got, err := h.prepareAppValues(tt.args.appConfig) - if (err != nil) != tt.wantErr { - t.Errorf("Client.prepareAppValues() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got != tt.want { - t.Errorf("Client.prepareAppValues() = %v, want %v", got, tt.want) - } - }) + + tmpValuesPath, err := client.prepareAppValues(appConfig) + + assert.NoError(t, err) + assert.Contains(t, tmpValuesPath, "test-app-values.yaml") +} + +func TestPrepareAppValues_WriteFileError(t *testing.T) { + client := &Client{} + appConfig := &types.AppConfig{ + Name: "test-app", + TemplateValues: []byte("valid-template"), + OverrideValues: map[string]interface{}{"key": "value"}, } + + tmpValuesPath, err := client.prepareAppValues(appConfig) + + assert.Error(t, err) + assert.Equal(t, "", tmpValuesPath) + assert.Contains(t, err.Error(), "failed to write app values to file") } diff --git a/pkg/k8s/cert-issuer_test.go b/pkg/k8s/cert-issuer_test.go index c53e09f..679ca40 100644 --- a/pkg/k8s/cert-issuer_test.go +++ b/pkg/k8s/cert-issuer_test.go @@ -14,8 +14,39 @@ func TestCreateOrUpdateClusterIssuer(t *testing.T) { args args wantErr bool }{ - // TODO: Add test cases. + { + name: "valid config", + args: args{ + captenConfig: config.CaptenConfig{ + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "aws.intelops.com", + }, + }, + }, + wantErr: false, + }, + { + name: "invalid config: missing domain", + args: args{ + captenConfig: config.CaptenConfig{ + CaptenClusterValues: config.CaptenClusterValues{ + DomainName: "", + }, + }, + }, + wantErr: true, + }, + { + name: "invalid config: missing email", + args: args{ + captenConfig: config.CaptenConfig{ + CaptenClusterValues: config.CaptenClusterValues{}, + }, + }, + wantErr: true, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := CreateOrUpdateClusterIssuer(tt.args.captenConfig); (err != nil) != tt.wantErr { diff --git a/pkg/k8s/k8s_test.go b/pkg/k8s/k8s_test.go index e718eb8..d89c4ff 100644 --- a/pkg/k8s/k8s_test.go +++ b/pkg/k8s/k8s_test.go @@ -1,7 +1,6 @@ package k8s import ( - "reflect" "testing" "k8s.io/client-go/kubernetes" @@ -17,7 +16,21 @@ func TestMakeNamespacePrivilege(t *testing.T) { args args wantErr bool }{ - // TODO: Add test cases. + { + name: "Test empty kubeconfig path", + args: args{"", "testns"}, + wantErr: true, + }, + { + name: "Test empty namespace", + args: args{"../config/kubeconfig", ""}, + wantErr: true, + }, + { + name: "Test valid case", + args: args{"../config/kubeconfig", "testns"}, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -26,19 +39,32 @@ func TestMakeNamespacePrivilege(t *testing.T) { } }) } + } func TestGetK8SClient(t *testing.T) { type args struct { kubeconfigPath string } + tests := []struct { name string args args want *kubernetes.Clientset wantErr bool }{ - // TODO: Add test cases. + { + name: "Test empty kubeconfig path", + args: args{""}, + want: nil, + wantErr: true, + }, + { + name: "Test valid kubeconfig path", + args: args{"../config/kubeconfig"}, + want: nil, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -47,11 +73,12 @@ func TestGetK8SClient(t *testing.T) { t.Errorf("GetK8SClient() error = %v, wantErr %v", err, tt.wantErr) return } - if !reflect.DeepEqual(got, tt.want) { + if (got == nil) != (tt.want == nil) { t.Errorf("GetK8SClient() = %v, want %v", got, tt.want) } }) } + } func TestCreateNamespaceIfNotExists(t *testing.T) { @@ -59,12 +86,27 @@ func TestCreateNamespaceIfNotExists(t *testing.T) { kubeconfigPath string namespace string } + tests := []struct { name string args args wantErr bool }{ - // TODO: Add test cases. + { + name: "Test empty kubeconfig path", + args: args{"", "testns"}, + wantErr: true, + }, + { + name: "Test empty namespace", + args: args{"../config/kubeconfig", ""}, + wantErr: true, + }, + { + name: "Test valid case", + args: args{"../config/kubeconfig", "testns"}, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -73,4 +115,5 @@ func TestCreateNamespaceIfNotExists(t *testing.T) { } }) } + } diff --git a/pkg/k8s/namespace_test.go b/pkg/k8s/namespace_test.go index 34de48b..b1bd325 100644 --- a/pkg/k8s/namespace_test.go +++ b/pkg/k8s/namespace_test.go @@ -13,11 +13,37 @@ func TestCreateNamespaceIfNotExist(t *testing.T) { label map[string]string } tests := []struct { - name string - args args - wantErr bool + name string + args args + wantErr bool + kubeconfig string + namespaceName string + label map[string]string }{ - // TODO: Add test cases. + { + name: "should fail when kubeconfigPath is empty", + args: args{kubeconfigPath: "", namespaceName: "test", label: map[string]string{}}, + wantErr: true, + kubeconfig: "", + namespaceName: "test", + label: map[string]string{}, + }, + { + name: "should fail when namespaceName is empty", + args: args{kubeconfigPath: "../config/kubeconfig", namespaceName: "", label: map[string]string{}}, + wantErr: true, + kubeconfig: "test", + namespaceName: "", + label: map[string]string{}, + }, + { + name: "should pass when kubeconfigPath and namespaceName are valid", + args: args{kubeconfigPath: "../config/kubeconfig", namespaceName: "test", label: map[string]string{"test": "test"}}, + wantErr: false, + kubeconfig: "test", + namespaceName: "test", + label: map[string]string{"test": "test"}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -26,6 +52,7 @@ func TestCreateNamespaceIfNotExist(t *testing.T) { } }) } + } func TestCreateorUpdateNamespaceWithLabel(t *testing.T) { @@ -38,8 +65,23 @@ func TestCreateorUpdateNamespaceWithLabel(t *testing.T) { args args wantErr bool }{ - // TODO: Add test cases. + { + name: "should fail when kubeconfigPath is empty", + args: args{kubeconfigPath: "", namespaceName: "test"}, + wantErr: true, + }, + { + name: "should fail when namespaceName is empty", + args: args{kubeconfigPath: "../config/kubeconfig", namespaceName: ""}, + wantErr: false, + }, + { + name: "should pass when kubeconfigPath and namespaceName are valid", + args: args{kubeconfigPath: "../config/kubeconfig", namespaceName: "test"}, + wantErr: true, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := CreateorUpdateNamespaceWithLabel(tt.args.kubeconfigPath, tt.args.namespaceName); (err != nil) != tt.wantErr { @@ -54,13 +96,37 @@ func Test_namespaceExists(t *testing.T) { clientset *kubernetes.Clientset name string } + tests := []struct { name string args args want bool wantErr bool }{ - // TODO: Add test cases. + { + name: "should return false when namespace does not exist", + args: args{clientset: &kubernetes.Clientset{}, name: "non_existent_namespace"}, + want: false, + wantErr: false, + }, + { + name: "should return true when namespace exists", + args: args{clientset: &kubernetes.Clientset{}, name: "default"}, + want: true, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := namespaceExists(tt.args.clientset, tt.args.name) + if (err != nil) != tt.wantErr { + t.Errorf("namespaceExists() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("namespaceExists() = %v, want %v", got, tt.want) + } + }) } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -82,13 +148,36 @@ func Test_updateNamespaceLabel(t *testing.T) { name string labels map[string]string } + tests := []struct { name string args args wantErr bool }{ - // TODO: Add test cases. + { + name: "should update namespace labels", + args: args{ + clientset: &kubernetes.Clientset{}, + name: "default", + labels: map[string]string{ + "new-label": "new-value", + }, + }, + wantErr: false, + }, + { + name: "should not error when namespace does not exist", + args: args{ + clientset: &kubernetes.Clientset{}, + name: "non-existent-namespace", + labels: map[string]string{ + "new-label": "new-value", + }, + }, + wantErr: false, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := updateNamespaceLabel(tt.args.clientset, tt.args.name, tt.args.labels); (err != nil) != tt.wantErr { diff --git a/pkg/k8s/openebs_test.go b/pkg/k8s/openebs_test.go index 37db669..6a4e73a 100644 --- a/pkg/k8s/openebs_test.go +++ b/pkg/k8s/openebs_test.go @@ -2,6 +2,7 @@ package k8s import ( "capten/pkg/config" + "errors" "reflect" "testing" "time" @@ -13,14 +14,44 @@ func Test_getOpenEBSClient(t *testing.T) { type args struct { captenConfig config.CaptenConfig } + tests := []struct { name string args args want *clientset.Clientset wantErr bool }{ - // TODO: Add test cases. + { + name: "Empty config", + args: args{ + captenConfig: config.CaptenConfig{}, + }, + want: nil, + wantErr: true, + }, + { + name: "Empty kubeconfig", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "", + }, + }, + want: nil, + wantErr: true, + }, + + { + name: "Valid config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + }, + }, + want: nil, + wantErr: false, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := getOpenEBSClient(tt.args.captenConfig) @@ -40,14 +71,37 @@ func Test_getOpenEBSBlockDevices(t *testing.T) { openebsClientset *clientset.Clientset captenConfig config.CaptenConfig } + tests := []struct { name string args args want []map[string]string wantErr bool }{ - // TODO: Add test cases. + { + name: "Valid config", + args: args{ + openebsClientset: nil, + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "some-pool-cluster", + PoolClusterNamespace: "some-pool-cluster-ns", + }, + }, + want: []map[string]string{ + { + "blockDevice": "bd1", + "nodeName": "node1", + }, + { + "blockDevice": "bd2", + "nodeName": "node2", + }, + }, + wantErr: false, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := getOpenEBSBlockDevices(tt.args.openebsClientset, tt.args.captenConfig) @@ -66,13 +120,36 @@ func TestCreateCStorPoolClusters(t *testing.T) { type args struct { captenConfig config.CaptenConfig } + tests := []struct { name string args args wantErr bool }{ - // TODO: Add test cases. + { + name: "Valid config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "some-pool-cluster", + PoolClusterNamespace: "some-pool-cluster-ns", + }, + }, + wantErr: false, + }, + { + name: "Invalid config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "", + PoolClusterName: "", + PoolClusterNamespace: "", + }, + }, + wantErr: true, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := CreateCStorPoolClusters(tt.args.captenConfig); (err != nil) != tt.wantErr { @@ -80,6 +157,7 @@ func TestCreateCStorPoolClusters(t *testing.T) { } }) } + } func Test_retry(t *testing.T) { @@ -88,13 +166,36 @@ func Test_retry(t *testing.T) { interval time.Duration f func() error } + tests := []struct { name string args args wantErr bool }{ - // TODO: Add test cases. + { + name: "Successful after one retry", + args: args{ + retries: 2, + interval: 10 * time.Millisecond, + f: func() error { + return nil + }, + }, + wantErr: false, + }, + { + name: "Unsuccessful after max retries", + args: args{ + retries: 2, + interval: 10 * time.Millisecond, + f: func() error { + return errors.New("some error") + }, + }, + wantErr: true, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := retry(tt.args.retries, tt.args.interval, tt.args.f); (err != nil) != tt.wantErr { @@ -108,13 +209,36 @@ func TestCreateCStorPoolClusterWithRetries(t *testing.T) { type args struct { captenConfig config.CaptenConfig } + tests := []struct { name string args args wantErr bool }{ - // TODO: Add test cases. + { + name: "Successful", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "pool-cluster", + PoolClusterNamespace: "pool-cluster-ns", + }, + }, + wantErr: false, + }, + { + name: "Unsuccessful", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "pool-cluster", + PoolClusterNamespace: "pool-cluster-ns", + }, + }, + wantErr: true, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := CreateCStorPoolClusterWithRetries(tt.args.captenConfig); (err != nil) != tt.wantErr { diff --git a/pkg/k8s/secrets_test.go b/pkg/k8s/secrets_test.go index cbef06a..fdc5509 100644 --- a/pkg/k8s/secrets_test.go +++ b/pkg/k8s/secrets_test.go @@ -13,13 +13,38 @@ func Test_createOrUpdateSecret(t *testing.T) { k8sClient *kubernetes.Clientset secret *corev1.Secret } + tests := []struct { name string args args wantErr bool }{ - // TODO: Add test cases. + { + name: "Test empty client", + args: args{ + k8sClient: nil, + secret: &corev1.Secret{}, + }, + wantErr: true, + }, + { + name: "Test empty secret", + args: args{ + k8sClient: &kubernetes.Clientset{}, + secret: nil, + }, + wantErr: true, + }, + { + name: "Test valid input", + args: args{ + k8sClient: &kubernetes.Clientset{}, + secret: &corev1.Secret{}, + }, + wantErr: false, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := createOrUpdateSecret(tt.args.k8sClient, tt.args.secret); (err != nil) != tt.wantErr { @@ -38,8 +63,37 @@ func TestCreateOrUpdateCertSecrets(t *testing.T) { args args wantErr bool }{ - // TODO: Add test cases. + { + name: "Test nil config", + args: args{ + captenConfig: config.CaptenConfig{}, + }, + wantErr: true, + }, + { + name: "Test empty config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "", + PoolClusterNamespace: "", + }, + }, + wantErr: true, + }, + { + name: "Test valid config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "pool-cluster", + PoolClusterNamespace: "pool-cluster-ns", + }, + }, + wantErr: false, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := CreateOrUpdateCertSecrets(tt.args.captenConfig); (err != nil) != tt.wantErr { @@ -54,13 +108,52 @@ func Test_createOrUpdateAgentCertSecret(t *testing.T) { captenConfig config.CaptenConfig k8sClient *kubernetes.Clientset } + tests := []struct { name string args args wantErr bool }{ - // TODO: Add test cases. + { + name: "Test nil config", + args: args{ + captenConfig: config.CaptenConfig{}, + }, + wantErr: true, + }, + { + name: "Test empty config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "", + PoolClusterNamespace: "", + }, + }, + wantErr: true, + }, + { + name: "Test valid config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "pool-cluster", + PoolClusterNamespace: "pool-cluster-ns", + }, + k8sClient: &kubernetes.Clientset{}, + }, + wantErr: false, + }, } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := createOrUpdateAgentCertSecret(tt.args.captenConfig, tt.args.k8sClient); (err != nil) != tt.wantErr { + t.Errorf("createOrUpdateAgentCertSecret() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := createOrUpdateAgentCertSecret(tt.args.captenConfig, tt.args.k8sClient); (err != nil) != tt.wantErr { @@ -71,17 +164,49 @@ func Test_createOrUpdateAgentCertSecret(t *testing.T) { } func Test_createOrUpdateAgentCACert(t *testing.T) { + type args struct { captenConfig config.CaptenConfig k8sClient *kubernetes.Clientset } + tests := []struct { name string args args wantErr bool }{ - // TODO: Add test cases. + { + name: "Test nil config", + args: args{ + captenConfig: config.CaptenConfig{}, + }, + wantErr: true, + }, + { + name: "Test empty config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "", + PoolClusterNamespace: "", + }, + }, + wantErr: true, + }, + { + name: "Test valid config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "pool-cluster", + PoolClusterNamespace: "pool-cluster-ns", + }, + k8sClient: &kubernetes.Clientset{}, + }, + wantErr: false, + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := createOrUpdateAgentCACert(tt.args.captenConfig, tt.args.k8sClient); (err != nil) != tt.wantErr { @@ -96,13 +221,52 @@ func Test_createOrUpdateClusterCAIssuerSecret(t *testing.T) { captenConfig config.CaptenConfig k8sClient *kubernetes.Clientset } + tests := []struct { name string args args wantErr bool }{ - // TODO: Add test cases. + { + name: "Test nil config", + args: args{ + captenConfig: config.CaptenConfig{}, + }, + wantErr: true, + }, + { + name: "Test empty config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "", + PoolClusterNamespace: "", + }, + }, + wantErr: true, + }, + { + name: "Test valid config", + args: args{ + captenConfig: config.CaptenConfig{ + KubeConfigFileName: "kubeconfig", + PoolClusterName: "pool-cluster", + PoolClusterNamespace: "pool-cluster-ns", + }, + k8sClient: &kubernetes.Clientset{}, + }, + wantErr: false, + }, } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := createOrUpdateClusterCAIssuerSecret(tt.args.captenConfig, tt.args.k8sClient); (err != nil) != tt.wantErr { + t.Errorf("createOrUpdateClusterCAIssuerSecret() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := createOrUpdateClusterCAIssuerSecret(tt.args.captenConfig, tt.args.k8sClient); (err != nil) != tt.wantErr { diff --git a/pkg/terraform/terraform-azure.go b/pkg/terraform/terraform-azure.go index a7b7be5..4eac0a7 100644 --- a/pkg/terraform/terraform-azure.go +++ b/pkg/terraform/terraform-azure.go @@ -38,7 +38,6 @@ func NewAzure(captenConfig config.CaptenConfig, config types.AzureClusterInfo) ( } tf.SetLogger(clog.Logger) - //set the output files, defaulted to terminal tf.SetStdout(os.Stdout) tf.SetStderr(os.Stderr) return &terraform{azureconfig: config, exec: tf, captenConfig: captenConfig}, nil