From f585b8d5bc1509fa051e21268cd6b93f25ab029c Mon Sep 17 00:00:00 2001 From: 26tanishabanik <26tanishabanik@gmail.com> Date: Tue, 1 Nov 2022 17:40:07 +0000 Subject: [PATCH] formatted code Signed-off-by: 26tanishabanik <26tanishabanik@gmail.com> --- pkg/scalers/couchdb_scaler.go | 9 +- pkg/scalers/couchdb_scaler_test.go | 6 +- tests/scalers/couchdb/couchdb_test.go | 190 +++++----- tests/scalers/couchdb/couchdb_test.go.save | 402 +++++++++++++++++++++ 4 files changed, 493 insertions(+), 114 deletions(-) create mode 100644 tests/scalers/couchdb/couchdb_test.go.save diff --git a/pkg/scalers/couchdb_scaler.go b/pkg/scalers/couchdb_scaler.go index 4d6480c2051..e97117c89be 100644 --- a/pkg/scalers/couchdb_scaler.go +++ b/pkg/scalers/couchdb_scaler.go @@ -2,16 +2,15 @@ package scalers import ( "context" - "fmt" - "strconv" "encoding/json" + "fmt" couchdb "github.com/go-kivik/couchdb/v3" "github.com/go-kivik/kivik/v3" "github.com/go-logr/logr" v2 "k8s.io/api/autoscaling/v2" "k8s.io/apimachinery/pkg/labels" "k8s.io/metrics/pkg/apis/external_metrics" - + "strconv" kedautil "github.com/kedacore/keda/v2/pkg/util" // kedascaler "couchbase/keda/pkg/scalers" ) @@ -71,7 +70,7 @@ func (s couchDBScaler) Close(ctx context.Context) error { func (s *couchDBScaler) getQueryResult(ctx context.Context) (int64, error) { db := s.client.DB(ctx, s.metadata.dbName) var request couchDBQueryRequest - err := json.Unmarshal([]byte (s.metadata.query),&request) + err := json.Unmarshal([]byte(s.metadata.query), &request) if err != nil { fmt.Println("Couldn't unmarshal query string: ", err) s.logger.Error(err, fmt.Sprintf("Couldn't unmarshal query string because of %v", err)) @@ -83,7 +82,7 @@ func (s *couchDBScaler) getQueryResult(ctx context.Context) (int64, error) { s.logger.Error(err, fmt.Sprintf("failed to fetch rows because of %v", err)) return 0, err } - var count int64 = 0 + var count int64 for rows.Next() { count++ res := Res{} diff --git a/pkg/scalers/couchdb_scaler_test.go b/pkg/scalers/couchdb_scaler_test.go index 5e8a5f17011..bfb1c52f35a 100644 --- a/pkg/scalers/couchdb_scaler_test.go +++ b/pkg/scalers/couchdb_scaler_test.go @@ -2,10 +2,10 @@ package scalers import ( "context" - "testing" _ "github.com/go-kivik/couchdb/v3" "github.com/go-kivik/kivik/v3" "github.com/go-logr/logr" + "testing" ) var testCouchDBResolvedEnv = map[string]string{ @@ -44,7 +44,7 @@ var testCOUCHDBMetadata = []parseCouchDBMetadataTestData{ }, // with metric name { - metadata: map[string]string{"query": `{ "selector": { "feet": { "$gt": 0 } }, "fields": ["_id", "feet", "greeting"] }`, "queryValue": "1", "connectionStringFromEnv": "CouchDB_CONN_STR", "dbName": "animals"}, + metadata: map[string]string{"query": `{ "selector": { "feet": { "$gt": 0 } }, "fields": ["_id", "feet", "greeting"] }`, "queryValue": "1", "connectionStringFromEnv": "CouchDB_CONN_STR", "dbName": "animals"}, authParams: map[string]string{}, resolvedEnv: testCouchDBResolvedEnv, raisesError: false, @@ -95,4 +95,4 @@ func TestCouchDBGetMetricSpecForScaling(t *testing.T) { t.Error("Wrong External metric source name:", metricName) } } -} \ No newline at end of file +} diff --git a/tests/scalers/couchdb/couchdb_test.go b/tests/scalers/couchdb/couchdb_test.go index 6c0439dca6b..b1a1aef08a3 100644 --- a/tests/scalers/couchdb/couchdb_test.go +++ b/tests/scalers/couchdb/couchdb_test.go @@ -4,23 +4,22 @@ package couchdb_test import ( - "encoding/base64" - "reflect" - batchv1 "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" - "fmt" - "strings" - "testing" "bytes" - "io" - "time" "context" - "github.com/joho/godotenv" - "github.com/stretchr/testify/assert" - "k8s.io/client-go/kubernetes" + "encoding/base64" + "fmt" "github.com/google/uuid" + "github.com/joho/godotenv" . "github.com/kedacore/keda/v2/tests/helper" + "github.com/stretchr/testify/assert" + "io" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "reflect" + "strings" + "testing" + "time" ) // Load environment variables from .env file @@ -31,27 +30,24 @@ const ( ) var ( - testNamespace = fmt.Sprintf("%s-ns", testName) - deploymentName = fmt.Sprintf("%s-deployment", testName) - jobName = fmt.Sprintf("%s-job", testName) - secretName = fmt.Sprintf("%s-secret", testName) - triggerAuthName = fmt.Sprintf("%s-ta", testName) - scaledObjectName = fmt.Sprintf("%s-sj", testName) - couchdbNamespace = "couchdb-ns" - couchdbUser = "admin" - couchdbPassword = "YeFvQno9LylIm5MDgwcV" - couchdbHelmRepo = "https://apache.github.io/couchdb-helm" - couchdbDBName = "animals" - minReplicaCount = 1 - maxReplicaCount = 2 + testNamespace = fmt.Sprintf("%s-ns", testName) + deploymentName = fmt.Sprintf("%s-deployment", testName) + jobName = fmt.Sprintf("%s-job", testName) + secretName = fmt.Sprintf("%s-secret", testName) + triggerAuthName = fmt.Sprintf("%s-ta", testName) + scaledObjectName = fmt.Sprintf("%s-sj", testName) + couchdbNamespace = "couchdb-ns" + couchdbUser = "admin" + couchdbPassword = "YeFvQno9LylIm5MDgwcV" + couchdbHelmRepo = "https://apache.github.io/couchdb-helm" + couchdbDBName = "animals" + minReplicaCount = 1 + maxReplicaCount = 2 ) -type templateJob struct { - JobName string -} - + type templateData struct { TestNamespace string - DeploymentName string + DeploymentName string HostName string Port string Username string @@ -61,26 +57,10 @@ type templateData struct { TriggerAuthName string ScaledObjectName string Connection, Base64Connection string - Database string + Database string } const ( - jobTemplate = ` -apiVersion: batch/v1 -kind: Job -metadata: - name: {{.JobName}} - namespace: {{.TestNamespace}} -spec: - template: - spec: - containers: - - name: busybox - image: busybox - command: ["curl", "-X", "PUT", {{.Connection}} + "animals"] - restartPolicy: Never - backoffLimit: 4 -` deploymentTemplate = ` apiVersion: apps/v1 kind: Deployment @@ -183,7 +163,7 @@ func TestCouchDBScaler(t *testing.T) { DeleteKubernetesResources(t, kc, testNamespace, data, templates) } -func generateUUID() string{ +func generateUUID() string { id := strings.ReplaceAll(uuid.New().String(), "-", "") return id } @@ -191,20 +171,19 @@ func generateUUID() string{ func installCouchDB(t *testing.T) { _, err := ExecuteCommand(fmt.Sprintf("helm repo add couchdb %s", couchdbHelmRepo)) assert.NoErrorf(t, err, "cannot execute command - %s", err) - _, err := ExecuteCommand("sudo helm repo update") + _, err = ExecuteCommand("sudo helm repo update") assert.NoErrorf(t, err, "cannot execute command - %s", err) uuid := generateUUID() _, err = ExecuteCommand(fmt.Sprintf("sudo helm install test-release --set couchdbConfig.couchdb.uuid=%s --namespace %s couchdb/couchdb", uuid, testNamespace)) assert.NoErrorf(t, err, "cannot execute command - %s", err) } -func getPassword(kc *kubernetes.Clientset, namespace string) string{ +func getPassword(kc *kubernetes.Clientset, namespace string) string { secret, _ := kc.CoreV1().Secrets(namespace).Get(context.Background(), "test-release-couchdb", metav1.GetOptions{}) encoded_password := secret.Data["adminPassword"] password := string(encoded_password) fmt.Println("Secret Data: ", password) return password - } func WaitForDeploymentReplicaCountChangeCouchDB(t *testing.T, kc *kubernetes.Clientset, name, namespace string, iterations, intervalSeconds int) bool { @@ -229,7 +208,7 @@ func WaitForDeploymentReplicaCountChangeCouchDB(t *testing.T, kc *kubernetes.Cli return int(replicas) > 1 } -func deployPod (kc *kubernetes.Clientset, podName, args string) { +func deployPod(kc *kubernetes.Clientset, podName, args string) { podSpec := &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: "test-pod-couchdb-" + podName, @@ -239,43 +218,44 @@ func deployPod (kc *kubernetes.Clientset, podName, args string) { RestartPolicy: "OnFailure", Containers: []corev1.Container{ { - Name: "test-couchdb-container", - Image: "nginx:alpine", - Command: []string{"curl"}, - Args: strings.Split(args, " "), + Name: "test-couchdb-container", + Image: "nginx:alpine", + Command: []string{"curl"}, + Args: strings.Split(args, " "), }, }, }, } _, err := kc.CoreV1().Pods(testNamespace).Create(context.Background(), podSpec, metav1.CreateOptions{}) - if err != nil { - fmt.Println("Failed to create test pod: ", err) - } + if err != nil { + fmt.Println("Failed to create test pod: ", err) + } } func testActivation(t *testing.T, kc *kubernetes.Clientset) { t.Log("--- testing activation ---") - password := getPassword(kc, testNamespace) + password := getPassword(kc, testNamespace) - if WaitForStatefulsetReplicaReadyCount(t, kc, "test-release-couchdb", testNamespace, 3, 15, 1){ + if WaitForStatefulsetReplicaReadyCount(t, kc, "test-release-couchdb", testNamespace, 3, 15, 1) { dsn := fmt.Sprintf("http://admin:%s@test-release-svc-couchdb.%s.svc.cluster.local:5984/animals", password, testNamespace) cmd := "-vX PUT " + dsn - fmt.Println("Splitted command: ",strings.Split(cmd, " ")) + fmt.Println("Splitted command: ", strings.Split(cmd, " ")) deployPod(kc, "activation", cmd) AssertReplicaCountNotChangeDuringTimePeriod(t, kc, deploymentName, testNamespace, minReplicaCount, 5) } } -func insertRecord(kc *kubernetes.Clientset, password, record, name , uuid string) { +func insertRecord(kc *kubernetes.Clientset, password, record, name, uuid string) { dsn := fmt.Sprintf(`http://admin:%s@test-release-svc-couchdb.%s.svc.cluster.local:5984/animals/%s`, password, testNamespace, uuid) - cmd := ` -X PUT `+ dsn + ` -d `+ record + cmd := ` -X PUT ` + dsn + ` -d ` + record fmt.Println(cmd) deployPod(kc, name, cmd) } -func deployPodDelete (kc *kubernetes.Clientset, podName, args string) { + +func deployPodDelete(kc *kubernetes.Clientset, podName, args string) { podSpec := &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: "test-pod-couchdb-" + podName, @@ -285,19 +265,18 @@ func deployPodDelete (kc *kubernetes.Clientset, podName, args string) { RestartPolicy: "OnFailure", Containers: []corev1.Container{ { - Name: "test-couchdb-container", - Image: "nginx:alpine", + Name: "test-couchdb-container", + Image: "nginx:alpine", Command: []string{"curl"}, - Args: strings.Split(args, " "), + Args: strings.Split(args, " "), }, }, }, } - _, err := kc.CoreV1().Pods(testNamespace).Create(context.Background(), podSpec, metav1.CreateOptions{}) - if err != nil { - fmt.Println("Failed to create test pod: ", err) - } + if err != nil { + fmt.Println("Failed to create test pod: ", err) + } } func deleteRecord(kc *kubernetes.Clientset, password, name , uuid, rev string) { @@ -311,40 +290,40 @@ func deleteRecord(kc *kubernetes.Clientset, password, name , uuid, rev string) { } type PodLog struct { - OK bool `json:"ok"` - ID string `json:"id"` - Rev string `json:"rev"` + OK bool `json:"ok"` + ID string `json:"id"` + Rev string `json:"rev"` } -func getPodLogs(kc *kubernetes.Clientset, podName string) (string, error){ - podLogOpts := corev1.PodLogOptions{} +func getPodLogs(kc *kubernetes.Clientset, podName string) (string, error) { + podLogOpts := corev1.PodLogOptions{} - req := kc.CoreV1().Pods(testNamespace).GetLogs(podName, &podLogOpts) - podLogs, err := req.Stream(context.Background()) - if err != nil { - fmt.Println("error in opening stream: ", err) + req := kc.CoreV1().Pods(testNamespace).GetLogs(podName, &podLogOpts) + podLogs, err := req.Stream(context.Background()) + if err != nil { + fmt.Println("error in opening stream: ", err) return "", err - } - defer podLogs.Close() + } + defer podLogs.Close() - buf := new(bytes.Buffer) - _, err = io.Copy(buf, podLogs) - if err != nil { - fmt.Println("error in copy information from podLogs to buf: ", err) + buf := new(bytes.Buffer) + _, err = io.Copy(buf, podLogs) + if err != nil { + fmt.Println("error in copy information from podLogs to buf: ", err) return "", err - } - str := buf.String() - fmt.Println("Index: ", strings.Index(str, `"rev":`)) + } + str := buf.String() + fmt.Println("Index: ", strings.Index(str, `"rev":`)) chars := str[strings.Index(str, `"rev":`)+7 : strings.Index(str, `}`)-1] fmt.Println(chars) fmt.Println("Type of chars: ", reflect.TypeOf(chars)) return chars, nil } -func testScaleUp(t *testing.T, kc *kubernetes.Clientset){ +func testScaleUp(t *testing.T, kc *kubernetes.Clientset) { t.Log("--- testing scale up ---") - password := getPassword(kc, testNamespace) + password := getPassword(kc, testNamespace) if WaitForStatefulsetReplicaReadyCount(t, kc, "test-release-couchdb", testNamespace, 3, 1, 1) { record := `{ "_id":"Cow", @@ -357,8 +336,7 @@ func testScaleUp(t *testing.T, kc *kubernetes.Clientset){ if err != nil { fmt.Println("couldn't get pods logs for scaleup-1 due to : ", err) } - - + record = `{ "_id":"Cat", "feet":4, @@ -372,14 +350,14 @@ func testScaleUp(t *testing.T, kc *kubernetes.Clientset){ } assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, maxReplicaCount, 60, 1), - "replica count should be %d after 1 minute", maxReplicaCount) + "replica count should be %d after 1 minute", maxReplicaCount) time.Sleep(time.Second * 60) } } func testScaleDown(t *testing.T, kc *kubernetes.Clientset) { t.Log("--- testing scale down ---") - password := getPassword(kc, testNamespace) + password := getPassword(kc, testNamespace) if WaitForStatefulsetReplicaReadyCount(t, kc, "test-release-couchdb", testNamespace, 3, 1, 1) { rev1, err := getPodLogs(kc, "test-pod-couchdb-scaleup-1") if err != nil { @@ -392,13 +370,13 @@ func testScaleDown(t *testing.T, kc *kubernetes.Clientset) { } deleteRecord(kc, password, "scaledown-2", "818bba66323b40bf83f42c04374cab23", rev2) assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 300, 1), - "replica count should be %d after 5 minutes", minReplicaCount) + "replica count should be %d after 5 minutes", minReplicaCount) time.Sleep(time.Second * 60) } } func getTemplateData(kc *kubernetes.Clientset) (templateData, []Template) { - password := getPassword(kc, testNamespace) + password := getPassword(kc, testNamespace) passwordEncoded := base64.StdEncoding.EncodeToString([]byte(password)) connectionString := fmt.Sprintf("http://test-release-svc-couchdb.%s.svc.cluster.local:5984", testNamespace) fmt.Println("Connection String 242: ", connectionString) @@ -406,19 +384,19 @@ func getTemplateData(kc *kubernetes.Clientset) (templateData, []Template) { base64ConnectionString := base64.StdEncoding.EncodeToString([]byte(connectionString)) return templateData{ - TestNamespace: testNamespace, + TestNamespace: testNamespace, DeploymentName: deploymentName, HostName: hostName, Port: "5984", Username: base64.StdEncoding.EncodeToString([]byte(couchdbUser)), Password: passwordEncoded, - TriggerAuthName: triggerAuthName, - SecretName: secretName, - ScaledObjectName: scaledObjectName, - CouchDBNamespace: couchdbNamespace, - Database: couchdbDBName, - Connection: connectionString, - Base64Connection: base64ConnectionString, + TriggerAuthName: triggerAuthName, + SecretName: secretName, + ScaledObjectName: scaledObjectName, + CouchDBNamespace: couchdbNamespace, + Database: couchdbDBName, + Connection: connectionString, + Base64Connection: base64ConnectionString, }, []Template{ {Name: "deploymentTemplate", Config: deploymentTemplate}, {Name: "secretTemplate", Config: secretTemplate}, diff --git a/tests/scalers/couchdb/couchdb_test.go.save b/tests/scalers/couchdb/couchdb_test.go.save new file mode 100644 index 00000000000..854f5a737e7 --- /dev/null +++ b/tests/scalers/couchdb/couchdb_test.go.save @@ -0,0 +1,402 @@ +//go:build e2e +// +build e2e + +package couchdb_test + +import ( + "bytes" + "context" + "encoding/base64" + "fmt" + "fmt" + "github.com/google/uuid" + "github.com/joho/godotenv" + . "github.com/kedacore/keda/v2/tests/helper" + "github.com/stretchr/testify/assert" + "io" + corev1 "k8s.io/api/core/v1" + +) + +// Load environment variables from .env file +var _ = godotenv.Load("../../.env") + +const ( + testName = "couchdb-test" +) + +var ( + testNamespace = fmt.Sprintf("%s-ns", testName) + deploymentName = fmt.Sprintf("%s-deployment", testName) + jobName = fmt.Sprintf("%s-job", testName) + secretName = fmt.Sprintf("%s-secret", testName) + triggerAuthName = fmt.Sprintf("%s-ta", testName) + scaledObjectName = fmt.Sprintf("%s-sj", testName) + couchdbNamespace = "couchdb-ns" + couchdbUser = "admin" + couchdbPassword = "YeFvQno9LylIm5MDgwcV" + couchdbHelmRepo = "https://apache.github.io/couchdb-helm" + couchdbDBName = "animals" + minReplicaCount = 1 + maxReplicaCount = 2 +) + +type templateData struct { + TestNamespace string + DeploymentName string + HostName string + Port string + Username string + Password string + CouchDBNamespace string + SecretName string + TriggerAuthName string + ScaledObjectName string + Connection, Base64Connection string + Database string +} + +const ( + deploymentTemplate = ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{.DeploymentName}} + namespace: {{.TestNamespace}} + labels: + app: {{.DeploymentName}} +spec: + replicas: 1 + selector: + matchLabels: + app: {{.DeploymentName}} + template: + metadata: + labels: + app: {{.DeploymentName}} + spec: + containers: + - name: nginx + image: nginx:alpine +` + + secretTemplate = ` +apiVersion: v1 +kind: Secret +metadata: + name: {{.SecretName}} + namespace: {{.TestNamespace}} +data: + connectionString: {{.Base64Connection}} + username: {{.Username}} + password: {{.Password}} +` + triggerAuthTemplate = `apiVersion: keda.sh/v1alpha1 +kind: TriggerAuthentication +metadata: + name: {{.TriggerAuthName}} + namespace: {{.TestNamespace}} +spec: + secretTargetRef: + - parameter: password + name: {{.SecretName}} + key: password + - parameter: username + name: {{.SecretName}} + key: username +` + scaledObjectTemplate = ` +apiVersion: keda.sh/v1alpha1 +kind: ScaledObject +metadata: + name: {{.ScaledObjectName}} + namespace: {{.TestNamespace}} +spec: + scaleTargetRef: + name: {{.DeploymentName}} + minReplicaCount: 1 + maxReplicaCount: 2 + triggers: + - type: couchdb + metadata: + host: {{.HostName}} + port: "5984" + dbName: "animals" + queryValue: "1" + query: '{ "selector": { "feet": { "$gt": 0 } }, "fields": ["_id", "feet", "greeting"] }' + activationQueryValue: "1" + metricName: "global-metric" + authenticationRef: + name: {{.TriggerAuthName}} +` +) + + +func CreateKubernetesResourcesCouchDB(t *testing.T, kc *kubernetes.Clientset, nsName string, data interface{}, templates []Template) { + KubectlApplyMultipleWithTemplate(t, data, templates) +} + +func TestCouchDBScaler(t *testing.T) { + // Create kubernetes resources + kc := GetKubernetesClient(t) + // setup couchdb + CreateNamespace(t, kc, testNamespace) + installCouchDB(t) + + data, templates := getTemplateData(kc) + CreateKubernetesResourcesCouchDB(t, kc, testNamespace, data, templates) + + + assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 3), + "replica count should be %d after 3 minutes", minReplicaCount) + + // test scaling + testActivation(t, kc) + testScaleUp(t, kc) + testScaleDown(t, kc) + + // cleanup + DeleteKubernetesResources(t, kc, testNamespace, data, templates) +} + +func generateUUID() string { + id := strings.ReplaceAll(uuid.New().String(), "-", "") + return id +} + +func installCouchDB(t *testing.T) { + _, err := ExecuteCommand(fmt.Sprintf("helm repo add couchdb %s", couchdbHelmRepo)) + assert.NoErrorf(t, err, "cannot execute command - %s", err) + _, err = ExecuteCommand("sudo helm repo update") + assert.NoErrorf(t, err, "cannot execute command - %s", err) + uuid := generateUUID() + _, err = ExecuteCommand(fmt.Sprintf("sudo helm install test-release --set couchdbConfig.couchdb.uuid=%s --namespace %s couchdb/couchdb", uuid, testNamespace)) + assert.NoErrorf(t, err, "cannot execute command - %s", err) +} + +func getPassword(kc *kubernetes.Clientset, namespace string) string { + secret, _ := kc.CoreV1().Secrets(namespace).Get(context.Background(), "test-release-couchdb", metav1.GetOptions{}) + encoded_password := secret.Data["adminPassword"] + password := string(encoded_password) + fmt.Println("Secret Data: ", password) + return password +} + +func WaitForDeploymentReplicaCountChangeCouchDB(t *testing.T, kc *kubernetes.Clientset, name, namespace string, iterations, intervalSeconds int) bool { + t.Log("Waiting for some time to see if deployment replica count changes") + var replicas, prevReplicas int32 + prevReplicas = -1 + + for i := 0; i < iterations; i++ { + deployment, _ := kc.AppsV1().Deployments(namespace).Get(context.Background(), name, metav1.GetOptions{}) + replicas = deployment.Status.Replicas + + t.Logf("Deployment - %s, Current - %d", name, replicas) + + if replicas != prevReplicas && prevReplicas != -1 { + break + } + + prevReplicas = replicas + time.Sleep(time.Duration(intervalSeconds) * time.Second) + } + + return int(replicas) > 1 +} + +func deployPod(kc *kubernetes.Clientset, podName, args string) { + podSpec := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod-couchdb-" + podName, + Namespace: testNamespace, + }, + Spec: corev1.PodSpec{ + RestartPolicy: "OnFailure", + Containers: []corev1.Container{ + { + Name: "test-couchdb-container", + Image: "nginx:alpine", + Command: []string{"curl"}, + Args: strings.Split(args, " "), + }, + }, + }, + } + + _, err := kc.CoreV1().Pods(testNamespace).Create(context.Background(), podSpec, metav1.CreateOptions{}) + if err != nil { + fmt.Println("Failed to create test pod: ", err) + } +} + +func testActivation(t *testing.T, kc *kubernetes.Clientset) { + t.Log("--- testing activation ---") + + password := getPassword(kc, testNamespace) + + if WaitForStatefulsetReplicaReadyCount(t, kc, "test-release-couchdb", testNamespace, 3, 15, 1) { + dsn := fmt.Sprintf("http://admin:%s@test-release-svc-couchdb.%s.svc.cluster.local:5984/animals", password, testNamespace) + cmd := "-vX PUT " + dsn + fmt.Println("Splitted command: ", strings.Split(cmd, " ")) + deployPod(kc, "activation", cmd) + AssertReplicaCountNotChangeDuringTimePeriod(t, kc, deploymentName, testNamespace, minReplicaCount, 5) + } +} + + +func insertRecord(kc *kubernetes.Clientset, password, record, name, uuid string) { + dsn := fmt.Sprintf(`http://admin:%s@test-release-svc-couchdb.%s.svc.cluster.local:5984/animals/%s`, password, testNamespace, uuid) + cmd := ` -X PUT ` + dsn + ` -d ` + record + fmt.Println(cmd) + deployPod(kc, name, cmd) +} + +func deployPodDelete(kc *kubernetes.Clientset, podName, args string) { + podSpec := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod-couchdb-" + podName, + Namespace: testNamespace, + }, + Spec: corev1.PodSpec{ + RestartPolicy: "OnFailure", + Containers: []corev1.Container{ + { + Name: "test-couchdb-container", + Image: "nginx:alpine", + Command: []string{"curl"}, + Args: strings.Split(args, " "), + }, + }, + }, + } + _, err := kc.CoreV1().Pods(testNamespace).Create(context.Background(), podSpec, metav1.CreateOptions{}) + if err != nil { + fmt.Println("Failed to create test pod: ", err) + } +} + +func deleteRecord(kc *kubernetes.Clientset, password, name , uuid, rev string) { + fmt.Printf("Rev id: %s-test", rev) + fmt.Println() + dsn := fmt.Sprintf("http://admin:%s@test-release-svc-couchdb.%s.svc.cluster.local:5984/animals/%s?rev=%s", password, testNamespace, uuid, rev) + cmd := " -X DELETE " + dsn + fmt.Println("curl" + cmd) + fmt.Println("curl" + cmd) + deployPodDelete(kc, name, cmd) +} + +type PodLog struct { + OK bool `json:"ok"` + ID string `json:"id"` + Rev string `json:"rev"` +} + + +func getPodLogs(kc *kubernetes.Clientset, podName string) (string, error) { + podLogOpts := corev1.PodLogOptions{} + + req := kc.CoreV1().Pods(testNamespace).GetLogs(podName, &podLogOpts) + podLogs, err := req.Stream(context.Background()) + if err != nil { + fmt.Println("error in opening stream: ", err) + return "", err + } + defer podLogs.Close() + + buf := new(bytes.Buffer) + _, err = io.Copy(buf, podLogs) + if err != nil { + fmt.Println("error in copy information from podLogs to buf: ", err) + return "", err + } + str := buf.String() + fmt.Println("Index: ", strings.Index(str, `"rev":`)) + chars := str[strings.Index(str, `"rev":`)+7 : strings.Index(str, `}`)-1] + fmt.Println(chars) + fmt.Println("Type of chars: ", reflect.TypeOf(chars)) + return chars, nil +} + +func testScaleUp(t *testing.T, kc *kubernetes.Clientset) { + t.Log("--- testing scale up ---") + password := getPassword(kc, testNamespace) + if WaitForStatefulsetReplicaReadyCount(t, kc, "test-release-couchdb", testNamespace, 3, 1, 1) { + record := `{ + "_id":"Cow", + "feet":4, + "greeting":"moo" + }` + insertRecord(kc, password, record, "scaleup-1", "e488df68180d4c759d38bcf0881faca1") + time.Sleep(time.Second * 60) + _, err := getPodLogs(kc, "test-pod-couchdb-scaleup-1") + if err != nil { + fmt.Println("couldn't get pods logs for scaleup-1 due to : ", err) + } + + record = `{ + "_id":"Cat", + "feet":4, + "greeting":"meow" + }` + insertRecord(kc, password, record, "scaleup-2", "818bba66323b40bf83f42c04374cab23") + time.Sleep(time.Second * 60) + _, err = getPodLogs(kc, "test-pod-couchdb-scaleup-2") + if err != nil { + fmt.Println("couldn't get pods logs for scaleup-2 due to : ", err) + } + + assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, maxReplicaCount, 60, 1), + "replica count should be %d after 1 minute", maxReplicaCount) + time.Sleep(time.Second * 60) + } +} + +func testScaleDown(t *testing.T, kc *kubernetes.Clientset) { + t.Log("--- testing scale down ---") + password := getPassword(kc, testNamespace) + if WaitForStatefulsetReplicaReadyCount(t, kc, "test-release-couchdb", testNamespace, 3, 1, 1) { + rev1, err := getPodLogs(kc, "test-pod-couchdb-scaleup-1") + if err != nil { + fmt.Println("couldn't get pods logs for scaleup-1 due to : ", err) + } + deleteRecord(kc, password, "scaledown-1", "e488df68180d4c759d38bcf0881faca1", rev1) + rev2, err := getPodLogs(kc, "test-pod-couchdb-scaleup-2") + if err != nil { + fmt.Println("couldn't get pods logs for scaleup-2 due to : ", err) + } + deleteRecord(kc, password, "scaledown-2", "818bba66323b40bf83f42c04374cab23", rev2) + assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 300, 1), + "replica count should be %d after 5 minutes", minReplicaCount) + time.Sleep(time.Second * 60) + } +} + +func getTemplateData(kc *kubernetes.Clientset) (templateData, []Template) { + password := getPassword(kc, testNamespace) + passwordEncoded := base64.StdEncoding.EncodeToString([]byte(password)) + connectionString := fmt.Sprintf("http://test-release-svc-couchdb.%s.svc.cluster.local:5984", testNamespace) + fmt.Println("Connection String 242: ", connectionString) + hostName := fmt.Sprintf("test-release-svc-couchdb.%s.svc.cluster.local", testNamespace) + base64ConnectionString := base64.StdEncoding.EncodeToString([]byte(connectionString)) + + return templateData{ + TestNamespace: testNamespace, + DeploymentName: deploymentName, + HostName: hostName, + Port: "5984", + Username: base64.StdEncoding.EncodeToString([]byte(couchdbUser)), + Password: passwordEncoded, + TriggerAuthName: triggerAuthName, + SecretName: secretName, + ScaledObjectName: scaledObjectName, + CouchDBNamespace: couchdbNamespace, + Database: couchdbDBName, + Connection: connectionString, + Base64Connection: base64ConnectionString, + }, []Template{ + {Name: "deploymentTemplate", Config: deploymentTemplate}, + {Name: "secretTemplate", Config: secretTemplate}, + {Name: "triggerAuthTemplate", Config: triggerAuthTemplate}, + {Name: "scaledObjectTemplate", Config: scaledObjectTemplate}, + } +}