diff --git a/pkg/scalers/couchdb_scaler.go b/pkg/scalers/couchdb_scaler.go index e97117c89be..b616baa49ed 100644 --- a/pkg/scalers/couchdb_scaler.go +++ b/pkg/scalers/couchdb_scaler.go @@ -7,12 +7,11 @@ import ( couchdb "github.com/go-kivik/couchdb/v3" "github.com/go-kivik/kivik/v3" "github.com/go-logr/logr" + kedautil "github.com/kedacore/keda/v2/pkg/util" 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" ) type couchDBScaler struct { @@ -112,7 +111,6 @@ func parseCouchDBMetadata(config *ScalerConfig) (*couchDBMetadata, string, error meta := couchDBMetadata{} // parse metaData from ScaledJob config - if val, ok := config.TriggerMetadata["query"]; ok { meta.query = val } else { @@ -203,8 +201,6 @@ func NewCouchDBScaler(ctx context.Context, config *ScalerConfig) (Scaler, error) return nil, fmt.Errorf("failed to parsing couchDB metadata, because of %v", err) } - - client, err := kivik.New("couch", connStr) if err != nil { fmt.Println("Couldn't connect to couchdb: ", err) diff --git a/pkg/scalers/couchdb_scaler_test.go b/pkg/scalers/couchdb_scaler_test.go index bfb1c52f35a..c3f88acfd06 100644 --- a/pkg/scalers/couchdb_scaler_test.go +++ b/pkg/scalers/couchdb_scaler_test.go @@ -13,7 +13,6 @@ var testCouchDBResolvedEnv = map[string]string{ "CouchDB_PASSWORD": "YeFvQno9LylIm5MDgwcV", } - type parseCouchDBMetadataTestData struct { metadata map[string]string authParams map[string]string diff --git a/tests/scalers/couchdb/couchdb_test.go b/tests/scalers/couchdb/couchdb_test.go index b1a1aef08a3..4a21db67bd6 100644 --- a/tests/scalers/couchdb/couchdb_test.go +++ b/tests/scalers/couchdb/couchdb_test.go @@ -30,7 +30,7 @@ const ( ) var ( - testNamespace = fmt.Sprintf("%s-ns", testName) + testNamespace = fmt.Sprintf("%s-ns", testName) deploymentName = fmt.Sprintf("%s-deployment", testName) jobName = fmt.Sprintf("%s-job", testName) secretName = fmt.Sprintf("%s-secret", testName) @@ -135,7 +135,6 @@ spec: ` ) - func CreateKubernetesResourcesCouchDB(t *testing.T, kc *kubernetes.Clientset, nsName string, data interface{}, templates []Template) { KubectlApplyMultipleWithTemplate(t, data, templates) } @@ -150,7 +149,6 @@ func TestCouchDBScaler(t *testing.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) @@ -228,9 +226,9 @@ func deployPod(kc *kubernetes.Clientset, podName, args string) { } _, 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) { @@ -247,7 +245,6 @@ func testActivation(t *testing.T, kc *kubernetes.Clientset) { } } - 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 @@ -274,9 +271,9 @@ func deployPodDelete(kc *kubernetes.Clientset, podName, args string) { }, } _, 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) { @@ -290,31 +287,30 @@ func deleteRecord(kc *kubernetes.Clientset, password, name , uuid, rev string) { } type PodLog struct { - OK bool `json:"ok"` + 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":`)) + 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)) @@ -384,19 +380,19 @@ func getTemplateData(kc *kubernetes.Clientset) (templateData, []Template) { 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, + 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}, diff --git a/tests/scalers/couchdb/couchdb_test.go.save b/tests/scalers/couchdb/couchdb_test.go.save deleted file mode 100644 index 854f5a737e7..00000000000 --- a/tests/scalers/couchdb/couchdb_test.go.save +++ /dev/null @@ -1,402 +0,0 @@ -//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}, - } -}