From 122ec475cfe377290b209dafc62a92b4f1bbf42f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Fei?= Date: Thu, 3 Oct 2024 17:59:56 +0200 Subject: [PATCH] test(e2e): refactor assertions to create, insert and validate data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactors: - Unify AssertCreateTestData,AssertCreateTestDataWithDatabaseName,AssertCreateTestDataInTablespace - Unify insertRecordIntoTable,insertRecordIntoTableWithDatabaseName - Unify AssertDataExpectedCount,AssertDataExpectedCountWithDatabaseName - Remove ExecCommandWithPsqlClient given that we previously removed the psqlCLient - Remove RunQueryFromPod, which is not needed anymore since now we can connect directly using port-forwarding - Convert ExecCommand usages that were connecting locally to run a query to instead use ExecQueryInInstancePod - Convert EventuallyExecCommand usages that were connecting locally to run a query to instead use EventuallyExecQueryInInstancePod - Add RunExecOverForward which allows running queries that don't return any rows via port-forwarding Fixes: - Client should close the connection when it is done. This improves timings on switchover/failover because we rely on smartShutdown by default E2E fixes: - Drain with PDB disabled: actually wait for the Cluster to be back - Replica Mode: synchronize secret value in the Replica Cluster before connecting - Configuration update: simplify pg_ident assertion Signed-off-by: Niccolò Fei --- tests/e2e/asserts_test.go | 514 ++++++++++++---------- tests/e2e/backup_restore_test.go | 81 +++- tests/e2e/cluster_microservice_test.go | 116 +++-- tests/e2e/cluster_monolithic_test.go | 1 + tests/e2e/cluster_setup_test.go | 1 + tests/e2e/configuration_update_test.go | 214 +++++---- tests/e2e/declarative_hibernation_test.go | 17 +- tests/e2e/disk_space_test.go | 18 +- tests/e2e/drain_node_test.go | 52 ++- tests/e2e/failover_test.go | 66 ++- tests/e2e/fastswitchover_test.go | 30 +- tests/e2e/fencing_test.go | 11 +- tests/e2e/hibernation_test.go | 20 +- tests/e2e/managed_roles_test.go | 22 +- tests/e2e/metrics_test.go | 1 + tests/e2e/operator_unavailable_test.go | 27 +- tests/e2e/pg_basebackup_test.go | 42 +- tests/e2e/pg_data_corruption_test.go | 10 +- tests/e2e/replica_mode_cluster_test.go | 55 ++- tests/e2e/replication_slot_test.go | 12 +- tests/e2e/tablespaces_test.go | 76 +++- tests/e2e/update_user_test.go | 19 +- tests/e2e/upgrade_test.go | 63 ++- tests/e2e/volume_snapshot_test.go | 60 ++- tests/utils/environment.go | 26 -- tests/utils/pod.go | 28 ++ tests/utils/postgres.go | 35 +- tests/utils/psql_connection.go | 30 +- tests/utils/replication_slots.go | 35 +- 29 files changed, 1053 insertions(+), 629 deletions(-) diff --git a/tests/e2e/asserts_test.go b/tests/e2e/asserts_test.go index badcfe420c..4a3637b8c7 100644 --- a/tests/e2e/asserts_test.go +++ b/tests/e2e/asserts_test.go @@ -432,69 +432,35 @@ func AssertDatabaseIsReady(namespace, clusterName, dbName string) { }) } -// AssertCreateTestData create test on the "app" database -func AssertCreateTestData(env *testsUtils.TestingEnvironment, namespace, clusterName, tableName string) { - AssertDatabaseIsReady(namespace, clusterName, testsUtils.AppDBName) - By(fmt.Sprintf("creating test data in cluster %v", clusterName), func() { - forward, conn, err := testsUtils.ForwardPSQLConnection( - env, - namespace, - clusterName, - testsUtils.AppDBName, - apiv1.ApplicationUserSecretSuffix, - ) - Expect(err).ToNot(HaveOccurred()) - - query := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %v AS VALUES (1),(2);", tableName) - _, err = conn.Exec(query) - Expect(err).ToNot(HaveOccurred()) - forward.Close() - }) -} - -// AssertCreateTestDataWithDatabaseName create test data in a given database. -func AssertCreateTestDataWithDatabaseName( - env *testsUtils.TestingEnvironment, - namespace, - clusterName, - databaseName, - tableName string, -) { - By(fmt.Sprintf("creating test data in cluster %v", clusterName), func() { - forward, conn, err := testsUtils.ForwardPSQLConnection( - env, - namespace, - clusterName, - databaseName, - apiv1.ApplicationUserSecretSuffix, - ) - Expect(err).ToNot(HaveOccurred()) - query := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %v AS VALUES (1),(2);", tableName) - _, err = conn.Exec(query) - Expect(err).ToNot(HaveOccurred()) - forward.Close() - }) -} - type TableLocator struct { - Namespace string - ClusterName string - TableName string - Tablespace string + Namespace string + ClusterName string + DatabaseName string + TableName string + Tablespace string } -// AssertCreateTestDataInTablespace create test data. -func AssertCreateTestDataInTablespace(env *testsUtils.TestingEnvironment, tl TableLocator) { - AssertDatabaseIsReady(tl.Namespace, tl.ClusterName, testsUtils.AppDBName) - By(fmt.Sprintf("creating test data in tablespace %q", tl.Tablespace), func() { +// AssertCreateTestData create test data on a given TableLocator +func AssertCreateTestData(env *testsUtils.TestingEnvironment, tl TableLocator) { + if tl.DatabaseName == "" { + tl.DatabaseName = testsUtils.AppDBName + } + if tl.Tablespace == "" { + tl.Tablespace = testsUtils.TablespaceDefaultName + } + AssertDatabaseIsReady(tl.Namespace, tl.ClusterName, tl.DatabaseName) + + By(fmt.Sprintf("creating test data in table %v (cluster %v, database %v, tablespace %v)", + tl.TableName, tl.ClusterName, tl.DatabaseName, tl.Tablespace), func() { forward, conn, err := testsUtils.ForwardPSQLConnection( env, tl.Namespace, tl.ClusterName, - testsUtils.AppDBName, + tl.DatabaseName, apiv1.ApplicationUserSecretSuffix, ) defer func() { + _ = conn.Close() forward.Close() }() Expect(err).ToNot(HaveOccurred()) @@ -508,51 +474,17 @@ func AssertCreateTestDataInTablespace(env *testsUtils.TestingEnvironment, tl Tab } // AssertCreateTestDataLargeObject create large objects with oid and data -func AssertCreateTestDataLargeObject(namespace, clusterName string, oid int, data string, pod *corev1.Pod) { +func AssertCreateTestDataLargeObject(namespace, clusterName string, oid int, data string) { By("creating large object", func() { query := fmt.Sprintf("CREATE TABLE IF NOT EXISTS image (name text,raster oid); "+ "INSERT INTO image (name, raster) VALUES ('beautiful image', lo_from_bytea(%d, '%s'));", oid, data) - appUser, appUserPass, err := testsUtils.GetCredentials(clusterName, namespace, apiv1.ApplicationUserSecretSuffix, env) - Expect(err).ToNot(HaveOccurred()) - host, err := testsUtils.GetHostName(namespace, clusterName, env) - Expect(err).ToNot(HaveOccurred()) - _, _, err = testsUtils.RunQueryFromPod( - pod, - host, - testsUtils.AppDBName, - appUser, - appUserPass, - query, - env) + + _, err := testsUtils.RunExecOverForward(env, namespace, clusterName, testsUtils.AppDBName, + apiv1.ApplicationUserSecretSuffix, query) Expect(err).ToNot(HaveOccurred()) }) } -// insertRecordIntoTableWithDatabaseName insert an entry into a table -func insertRecordIntoTableWithDatabaseName( - env *testsUtils.TestingEnvironment, - namespace, - clusterName, - databaseName, - tableName string, - value int, -) { - forward, conn, err := testsUtils.ForwardPSQLConnection( - env, - namespace, - clusterName, - databaseName, - apiv1.ApplicationUserSecretSuffix, - ) - defer func() { - forward.Close() - }() - Expect(err).ToNot(HaveOccurred()) - - _, err = conn.Exec(fmt.Sprintf("INSERT INTO %s VALUES (%d);", tableName, value)) - Expect(err).ToNot(HaveOccurred()) -} - // insertRecordIntoTable insert an entry into a table func insertRecordIntoTable(tableName string, value int, conn *sql.DB) { _, err := conn.Exec(fmt.Sprintf("INSERT INTO %s VALUES (%d)", tableName, value)) @@ -560,16 +492,21 @@ func insertRecordIntoTable(tableName string, value int, conn *sql.DB) { } // AssertDatabaseExists assert if database exists -func AssertDatabaseExists(namespace, podName, databaseName string, expectedValue bool) { +func AssertDatabaseExists(pod *corev1.Pod, databaseName string, expectedValue bool) { By(fmt.Sprintf("verifying if database %v exists", databaseName), func() { - pod := &corev1.Pod{} - commandTimeout := time.Second * 10 query := fmt.Sprintf("SELECT EXISTS(SELECT 1 FROM pg_database WHERE lower(datname) = lower('%v'));", databaseName) - err := env.Client.Get(env.Ctx, ctrlclient.ObjectKey{Namespace: namespace, Name: podName}, pod) - Expect(err).ToNot(HaveOccurred()) - stdout, _, err := env.ExecCommand(env.Ctx, *pod, specs.PostgresContainerName, - &commandTimeout, "psql", "-U", "postgres", "postgres", "-tAc", query) + stdout, stderr, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + testsUtils.PostgresDBName, + query) + if err != nil { + GinkgoWriter.Printf("stdout: %v\nstderr: %v", stdout, stderr) + } Expect(err).ToNot(HaveOccurred()) + if expectedValue { Expect(strings.Trim(stdout, "\n")).To(BeEquivalentTo("t")) } else { @@ -579,19 +516,21 @@ func AssertDatabaseExists(namespace, podName, databaseName string, expectedValue } // AssertUserExists assert if user exists -func AssertUserExists(namespace, podName, userName string, expectedValue bool) { +func AssertUserExists(pod *corev1.Pod, userName string, expectedValue bool) { By(fmt.Sprintf("verifying if user %v exists", userName), func() { - pod := &corev1.Pod{} - commandTimeout := time.Second * 10 query := fmt.Sprintf("SELECT EXISTS(SELECT 1 FROM pg_user WHERE lower(usename) = lower('%v'));", userName) - err := env.Client.Get(env.Ctx, ctrlclient.ObjectKey{Namespace: namespace, Name: podName}, pod) - Expect(err).ToNot(HaveOccurred()) - stdout, stderr, err := env.ExecCommand(env.Ctx, *pod, specs.PostgresContainerName, - &commandTimeout, "psql", "-U", "postgres", "postgres", "-tAc", query) + stdout, stderr, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + testsUtils.PostgresDBName, + query) if err != nil { GinkgoWriter.Printf("stdout: %v\nstderr: %v", stdout, stderr) } Expect(err).ToNot(HaveOccurred()) + if expectedValue { Expect(strings.Trim(stdout, "\n")).To(BeEquivalentTo("t")) } else { @@ -600,48 +539,21 @@ func AssertUserExists(namespace, podName, userName string, expectedValue bool) { }) } -// AssertDataExpectedCountWithDatabaseName verifies that an expected amount of rows exists on the table -func AssertDataExpectedCountWithDatabaseName(namespace, podName, databaseName string, - tableName string, expectedValue int, -) { - By(fmt.Sprintf("verifying test data on pod %v", podName), func() { - query := fmt.Sprintf("select count(*) from %v", tableName) - commandTimeout := time.Second * 10 - - Eventually(func() (int, error) { - // We keep getting the pod, since there could be a new pod with the same name - pod := &corev1.Pod{} - err := env.Client.Get(env.Ctx, ctrlclient.ObjectKey{Namespace: namespace, Name: podName}, pod) - if err != nil { - return 0, err - } - stdout, _, err := env.ExecCommand(env.Ctx, *pod, specs.PostgresContainerName, - &commandTimeout, "psql", "-U", "postgres", databaseName, "-tAc", query) - if err != nil { - return 0, err - } - nRows, err := strconv.Atoi(strings.Trim(stdout, "\n")) - return nRows, err - }, 300).Should(BeEquivalentTo(expectedValue)) - }) -} - // AssertDataExpectedCount verifies that an expected amount of rows exists on the table func AssertDataExpectedCount( env *testsUtils.TestingEnvironment, - namespace, - clusterName, - tableName string, + tl TableLocator, expectedValue int, ) { - By(fmt.Sprintf("verifying test data in table %v", tableName), func() { + By(fmt.Sprintf("verifying test data in table %v (cluster %v, database %v, tablespace %v)", + tl.TableName, tl.ClusterName, tl.DatabaseName, tl.Tablespace), func() { row, err := testsUtils.RunQueryRowOverForward( env, - namespace, - clusterName, - testsUtils.AppDBName, + tl.Namespace, + tl.ClusterName, + tl.DatabaseName, apiv1.ApplicationUserSecretSuffix, - fmt.Sprintf("SELECT COUNT(*) FROM %s", tableName), + fmt.Sprintf("SELECT COUNT(*) FROM %s", tl.TableName), ) Expect(err).ToNot(HaveOccurred()) @@ -653,24 +565,22 @@ func AssertDataExpectedCount( } // AssertLargeObjectValue verifies the presence of a Large Object given by its OID and data -func AssertLargeObjectValue(namespace, clusterName string, oid int, data string, pod *corev1.Pod) { +func AssertLargeObjectValue(namespace, clusterName string, oid int, data string) { By("verifying large object", func() { query := fmt.Sprintf("SELECT encode(lo_get(%v), 'escape');", oid) Eventually(func() (string, error) { // We keep getting the pod, since there could be a new pod with the same name - appUser, appUserPass, err := testsUtils.GetCredentials( - clusterName, namespace, apiv1.ApplicationUserSecretSuffix, env) - Expect(err).ToNot(HaveOccurred()) - host, err := testsUtils.GetHostName(namespace, clusterName, env) - Expect(err).ToNot(HaveOccurred()) - stdout, _, err := testsUtils.RunQueryFromPod( - pod, - host, + primaryPod, err := env.GetClusterPrimary(namespace, clusterName) + if err != nil { + return "", err + } + stdout, _, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: primaryPod.Namespace, + PodName: primaryPod.Name, + }, testsUtils.AppDBName, - appUser, - appUserPass, - query, - env) + query) if err != nil { return "", err } @@ -681,6 +591,7 @@ func AssertLargeObjectValue(namespace, clusterName string, oid int, data string, // AssertClusterStandbysAreStreaming verifies that all the standbys of a cluster have a wal-receiver running. func AssertClusterStandbysAreStreaming(namespace string, clusterName string, timeout int32) { + query := "SELECT count(*) FROM pg_stat_wal_receiver" Eventually(func() error { standbyPods, err := env.GetClusterReplicas(namespace, clusterName) if err != nil { @@ -688,9 +599,13 @@ func AssertClusterStandbysAreStreaming(namespace string, clusterName string, tim } for _, pod := range standbyPods.Items { - timeout := time.Second * 10 - out, _, err := env.EventuallyExecCommand(env.Ctx, pod, specs.PostgresContainerName, &timeout, - "psql", "-U", "postgres", "-tAc", "SELECT count(*) FROM pg_stat_wal_receiver") + out, _, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + testsUtils.PostgresDBName, + query) if err != nil { return err } @@ -721,22 +636,25 @@ func AssertStandbysFollowPromotion(namespace string, clusterName string, timeout // and are following the promotion, we should find those // records on each of them. - commandTimeout := time.Second * 10 for i := 1; i < 4; i++ { podName := fmt.Sprintf("%v-%v", clusterName, i) podNamespacedName := types.NamespacedName{ Namespace: namespace, Name: podName, } + query := "SELECT count(*) > 0 FROM tps.tl WHERE timeline = '00000002'" Eventually(func() (string, error) { pod := &corev1.Pod{} if err := env.Client.Get(env.Ctx, podNamespacedName, pod); err != nil { return "", err } - out, _, err := env.ExecCommand(env.Ctx, *pod, specs.PostgresContainerName, - &commandTimeout, "psql", "-U", "postgres", "app", "-tAc", - "SELECT count(*) > 0 FROM tps.tl "+ - "WHERE timeline = '00000002'") + out, _, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + testsUtils.AppDBName, + query) return strings.TrimSpace(out), err }, timeout).Should(BeEquivalentTo("t"), "Pod %v should have moved to timeline 2", podName) @@ -781,12 +699,18 @@ func AssertWritesResumedBeforeTimeout(namespace string, clusterName string, time Name: podName, } var switchTime float64 - commandTimeout := time.Second * 10 pod := &corev1.Pod{} err := env.Client.Get(env.Ctx, namespacedName, pod) Expect(err).ToNot(HaveOccurred()) - out, _, err := env.EventuallyExecCommand(env.Ctx, *pod, specs.PostgresContainerName, - &commandTimeout, "psql", "-U", "postgres", "app", "-tAc", query) + out, _, err := env.EventuallyExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, testsUtils.AppDBName, + query, + RetryTimeout, + PollingTime, + ) Expect(err).ToNot(HaveOccurred()) switchTime, err = strconv.ParseFloat(strings.TrimSpace(out), 64) if err != nil { @@ -827,7 +751,6 @@ func AssertNewPrimary(namespace string, clusterName string, oldPrimary string) { newPrimaryPod = newPrimary }) By(fmt.Sprintf("verifying write operation on the new primary pod: %s", newPrimaryPod), func() { - commandTimeout := time.Second * 10 namespacedName := types.NamespacedName{ Namespace: namespace, Name: newPrimaryPod, @@ -837,8 +760,15 @@ func AssertNewPrimary(namespace string, clusterName string, oldPrimary string) { Expect(err).ToNot(HaveOccurred()) // Expect write operation to succeed query := "CREATE TABLE IF NOT EXISTS assert_new_primary(var1 text);" - _, _, err = env.EventuallyExecCommand(env.Ctx, pod, specs.PostgresContainerName, - &commandTimeout, "psql", "-U", "postgres", "app", "-tAc", query) + _, _, err = env.EventuallyExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, testsUtils.AppDBName, + query, + RetryTimeout, + PollingTime, + ) Expect(err).ToNot(HaveOccurred()) }) } @@ -971,9 +901,13 @@ func AssertPgRecoveryMode(pod *corev1.Pod, expectedValue bool) { } Eventually(func() (string, error) { - commandTimeout := time.Second * 10 - stdOut, stdErr, err := env.ExecCommand(env.Ctx, *pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "postgres", "-tAc", "select pg_is_in_recovery();") + stdOut, stdErr, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + testsUtils.PostgresDBName, + "select pg_is_in_recovery();") if err != nil { GinkgoWriter.Printf("stdout: %v\ntderr: %v\n", stdOut, stdErr) } @@ -993,12 +927,17 @@ func AssertReplicaModeCluster( testTableName string, ) { var primaryReplicaCluster *corev1.Pod - commandTimeout := time.Second * 10 checkQuery := fmt.Sprintf("SELECT count(*) FROM %v", testTableName) AssertDatabaseIsReady(namespace, srcClusterName, srcClusterDBName) - AssertCreateTestDataWithDatabaseName(env, namespace, srcClusterName, srcClusterDBName, testTableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: srcClusterName, + DatabaseName: srcClusterDBName, + TableName: testTableName, + } + AssertCreateTestData(env, tableLocator) By("creating replica cluster", func() { replicaClusterName, err := env.GetResourceNameFromYAML(replicaClusterSample) @@ -1014,20 +953,42 @@ func AssertReplicaModeCluster( By("checking data have been copied correctly in replica cluster", func() { Eventually(func() (string, error) { - stdOut, _, err := env.ExecCommand(env.Ctx, *primaryReplicaCluster, specs.PostgresContainerName, - &commandTimeout, "psql", "-U", "postgres", srcClusterDBName, "-tAc", checkQuery) + stdOut, _, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: primaryReplicaCluster.Namespace, + PodName: primaryReplicaCluster.Name, + }, + testsUtils.DatabaseName(srcClusterDBName), + checkQuery) return strings.Trim(stdOut, "\n"), err }, 180, 10).Should(BeEquivalentTo("2")) }) By("writing some new data to the source cluster", func() { - insertRecordIntoTableWithDatabaseName(env, namespace, srcClusterName, srcClusterDBName, testTableName, 3) + forwardSource, connSource, err := testsUtils.ForwardPSQLConnection( + env, + namespace, + srcClusterName, + srcClusterDBName, + apiv1.ApplicationUserSecretSuffix, + ) + defer func() { + _ = connSource.Close() + forwardSource.Close() + }() + Expect(err).ToNot(HaveOccurred()) + insertRecordIntoTable(testTableName, 3, connSource) }) By("checking new data have been copied correctly in replica cluster", func() { Eventually(func() (string, error) { - stdOut, _, err := env.ExecCommand(env.Ctx, *primaryReplicaCluster, specs.PostgresContainerName, - &commandTimeout, "psql", "-U", "postgres", srcClusterDBName, "-tAc", checkQuery) + stdOut, _, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: primaryReplicaCluster.Namespace, + PodName: primaryReplicaCluster.Name, + }, + testsUtils.DatabaseName(srcClusterDBName), + checkQuery) return strings.Trim(stdOut, "\n"), err }, 180, 15).Should(BeEquivalentTo("3")) }) @@ -1036,8 +997,8 @@ func AssertReplicaModeCluster( // verify the replica database created followed the source database, rather than // default to the "app" db and user By("checking that in replica cluster there is no database app and user app", func() { - AssertDatabaseExists(namespace, primaryReplicaCluster.Name, "app", false) - AssertUserExists(namespace, primaryReplicaCluster.Name, "app", false) + AssertDatabaseExists(primaryReplicaCluster, "app", false) + AssertUserExists(primaryReplicaCluster, "app", false) }) } } @@ -1057,7 +1018,6 @@ func AssertDetachReplicaModeCluster( testTableName string, ) { var primaryReplicaCluster *corev1.Pod - replicaCommandTimeout := time.Second * 10 var referenceTime time.Time By("taking the reference time before the detaching", func() { @@ -1104,8 +1064,13 @@ func AssertDetachReplicaModeCluster( // Get primary from replica cluster primaryReplicaCluster, err = env.GetClusterPrimary(namespace, replicaClusterName) g.Expect(err).ToNot(HaveOccurred()) - _, _, err = env.EventuallyExecCommand(env.Ctx, *primaryReplicaCluster, specs.PostgresContainerName, - &replicaCommandTimeout, "psql", "-U", "postgres", srcDatabaseName, "-tAc", query) + _, _, err = env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: primaryReplicaCluster.Namespace, + PodName: primaryReplicaCluster.Name, + }, testsUtils.DatabaseName(srcDatabaseName), + query, + ) g.Expect(err).ToNot(HaveOccurred()) }, 300, 15).Should(Succeed()) }) @@ -1113,17 +1078,30 @@ func AssertDetachReplicaModeCluster( By("verifying the replica database doesn't exist in the replica cluster", func() { // Application database configuration is skipped for replica clusters, // so we expect these to not be present - AssertDatabaseExists(namespace, primaryReplicaCluster.Name, replicaDatabaseName, false) - AssertUserExists(namespace, primaryReplicaCluster.Name, replicaUserName, false) + AssertDatabaseExists(primaryReplicaCluster, replicaDatabaseName, false) + AssertUserExists(primaryReplicaCluster, replicaUserName, false) }) By("writing some new data to the source cluster", func() { - AssertCreateTestDataWithDatabaseName(env, namespace, srcClusterName, srcDatabaseName, testTableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: srcClusterName, + DatabaseName: srcDatabaseName, + TableName: testTableName, + } + AssertCreateTestData(env, tableLocator) }) By("verifying that replica cluster was not modified", func() { - outTables, stdErr, err := env.EventuallyExecCommand(env.Ctx, *primaryReplicaCluster, specs.PostgresContainerName, - &replicaCommandTimeout, "psql", "-U", "postgres", srcDatabaseName, "-tAc", "\\dt") + outTables, stdErr, err := env.EventuallyExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: primaryReplicaCluster.Namespace, + PodName: primaryReplicaCluster.Name, + }, testsUtils.DatabaseName(srcDatabaseName), + "\\dt", + RetryTimeout, + PollingTime, + ) if err != nil { GinkgoWriter.Printf("stdout: %v\nstderr: %v\n", outTables, stdErr) } @@ -1253,16 +1231,8 @@ func AssertFastFailOver( ", PRIMARY KEY (id)" + ")" - primaryPod, err := env.GetClusterPrimary(namespace, clusterName) - Expect(err).ToNot(HaveOccurred()) - _, _, err = env.ExecCommandWithPsqlClient( - namespace, - clusterName, - primaryPod, - apiv1.ApplicationUserSecretSuffix, - testsUtils.AppDBName, - query, - ) + _, err = testsUtils.RunExecOverForward(env, namespace, clusterName, testsUtils.AppDBName, + apiv1.ApplicationUserSecretSuffix, query) Expect(err).ToNot(HaveOccurred()) }) @@ -1280,25 +1250,27 @@ func AssertFastFailOver( " -f " + webTestJob) Expect(err).ToNot(HaveOccurred()) - commandTimeout := time.Second * 10 - timeout := 60 primaryPodName := clusterName + "-1" primaryPodNamespacedName := types.NamespacedName{ Namespace: namespace, Name: primaryPodName, } + query := "SELECT count(*) > 0 FROM tps.tl" Eventually(func() (string, error) { primaryPod := &corev1.Pod{} - err = env.Client.Get(env.Ctx, primaryPodNamespacedName, primaryPod) - if err != nil { + if err = env.Client.Get(env.Ctx, primaryPodNamespacedName, primaryPod); err != nil { return "", err } - out, _, err := env.ExecCommand(env.Ctx, *primaryPod, specs.PostgresContainerName, - &commandTimeout, "psql", "-U", "postgres", "app", "-tAc", - "SELECT count(*) > 0 FROM tps.tl") + out, _, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: primaryPod.Namespace, + PodName: primaryPod.Name, + }, + testsUtils.AppDBName, + query) return strings.TrimSpace(out), err - }, timeout).Should(BeEquivalentTo("t")) + }, RetryTimeout).Should(BeEquivalentTo("t")) }) By("deleting the primary", func() { @@ -1361,17 +1333,17 @@ func AssertCreationOfTestDataForTargetDB( Expect(err).ToNot(HaveOccurred()) // Create database - commandTimeout := time.Second * 10 createDBQuery := fmt.Sprintf("CREATE DATABASE %v OWNER %v", targetDBName, appUser) - _, _, err = env.ExecCommand( - env.Ctx, - *currentPrimary, - specs.PostgresContainerName, - &commandTimeout, - "psql", "-U", "postgres", "-tAc", createDBQuery, - ) + _, _, err = env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: currentPrimary.Namespace, + PodName: currentPrimary.Name, + }, + testsUtils.PostgresDBName, + createDBQuery) Expect(err).ToNot(HaveOccurred()) + // Open a connection to the newly created database forward, conn, err := testsUtils.ForwardPSQLConnection( env, namespace, @@ -1379,6 +1351,10 @@ func AssertCreationOfTestDataForTargetDB( targetDBName, apiv1.ApplicationUserSecretSuffix, ) + defer func() { + _ = conn.Close() + forward.Close() + }() Expect(err).ToNot(HaveOccurred()) // Create table on target database @@ -1390,9 +1366,6 @@ func AssertCreationOfTestDataForTargetDB( grantRoleQuery := "GRANT SELECT ON all tables in schema public to pg_monitor;" _, err = conn.Exec(grantRoleQuery) Expect(err).ToNot(HaveOccurred()) - - // Close the connection and forward - forward.Close() }) } @@ -1618,7 +1591,13 @@ func AssertClusterAsyncReplica(namespace, sourceClusterFile, restoreClusterFile, // Insert new data in the source cluster insertRecordIntoTable(tableName, 3, connSource) AssertArchiveWalOnMinio(namespace, sourceClusterName, sourceClusterName) - AssertDataExpectedCount(env, namespace, sourceClusterName, tableName, 3) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: sourceClusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 3) cluster, err := env.GetCluster(namespace, restoredClusterName) Expect(err).ToNot(HaveOccurred()) @@ -1640,7 +1619,13 @@ func AssertClusterRestoreWithApplicationDB(namespace, restoreClusterFile, tableN AssertClusterIsReady(namespace, restoredClusterName, testTimeouts[testsUtils.ClusterIsReadySlow], env) // Test data should be present on restored primary - AssertDataExpectedCount(env, namespace, restoredClusterName, tableName, 2) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: restoredClusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 2) }) By("Ensuring the restored cluster is on timeline 2", func() { @@ -1712,7 +1697,13 @@ func AssertClusterRestore(namespace, restoreClusterFile, tableName string) { // Test data should be present on restored primary primary := restoredClusterName + "-1" - AssertDataExpectedCount(env, namespace, restoredClusterName, tableName, 2) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: restoredClusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 2) // Restored primary should be on timeline 2 out, _, err := env.ExecQueryInInstancePod( @@ -1720,7 +1711,7 @@ func AssertClusterRestore(namespace, restoreClusterFile, tableName string) { Namespace: namespace, PodName: primary, }, - testsUtils.DatabaseName("app"), + testsUtils.AppDBName, "select substring(pg_walfile_name(pg_current_wal_lsn()), 1, 8)") Expect(strings.Trim(out, "\n"), err).To(Equal("00000002")) @@ -1892,7 +1883,13 @@ func AssertClusterWasRestoredWithPITRAndApplicationDB(namespace, clusterName, ta By(fmt.Sprintf("after restored, 3rd entry should not be exists in table '%v'", tableName), func() { // Only 2 entries should be present - AssertDataExpectedCount(env, namespace, clusterName, tableName, 2) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 2) }) // Gather credentials @@ -1956,7 +1953,13 @@ func AssertClusterWasRestoredWithPITR(namespace, clusterName, tableName, lsn str By(fmt.Sprintf("after restored, 3rd entry should not be exists in table '%v'", tableName), func() { // Only 2 entries should be present - AssertDataExpectedCount(env, namespace, clusterName, tableName, 2) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 2) }) } @@ -2010,7 +2013,7 @@ func switchWalAndGetLatestArchive(namespace, podName string) string { Namespace: namespace, PodName: podName, }, - testsUtils.DatabaseName("postgres"), + testsUtils.PostgresDBName, "CHECKPOINT;") Expect(err).ToNot(HaveOccurred()) @@ -2019,7 +2022,7 @@ func switchWalAndGetLatestArchive(namespace, podName string) string { Namespace: namespace, PodName: podName, }, - testsUtils.DatabaseName("postgres"), + testsUtils.PostgresDBName, "SELECT pg_walfile_name(pg_switch_wal());") Expect(err).ToNot(HaveOccurred()) @@ -2051,7 +2054,13 @@ func prepareClusterForPITROnMinio( }) // Write a table and insert 2 entries on the "app" database - AssertCreateTestData(env, namespace, clusterName, tableNamePitr) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableNamePitr, + } + AssertCreateTestData(env, tableLocator) By("getting currentTimestamp", func() { ts, err := testsUtils.GetCurrentTimestamp(namespace, clusterName, env) @@ -2068,6 +2077,7 @@ func prepareClusterForPITROnMinio( apiv1.ApplicationUserSecretSuffix, ) defer func() { + _ = conn.Close() forward.Close() }() Expect(err).ToNot(HaveOccurred()) @@ -2102,7 +2112,13 @@ func prepareClusterForPITROnAzureBlob( }) // Write a table and insert 2 entries on the "app" database - AssertCreateTestData(env, namespace, clusterName, tableNamePitr) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableNamePitr, + } + AssertCreateTestData(env, tableLocator) By("getting currentTimestamp", func() { ts, err := testsUtils.GetCurrentTimestamp(namespace, clusterName, env) @@ -2119,6 +2135,7 @@ func prepareClusterForPITROnAzureBlob( apiv1.ApplicationUserSecretSuffix, ) defer func() { + _ = conn.Close() forward.Close() }() Expect(err).ToNot(HaveOccurred()) @@ -2164,7 +2181,13 @@ func prepareClusterBackupOnAzurite( // Setting up Azurite and az cli along with Postgresql cluster prepareClusterOnAzurite(namespace, clusterName, clusterSampleFile) // Write a table and some data on the "app" database - AssertCreateTestData(env, namespace, clusterName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) AssertArchiveWalOnAzurite(namespace, clusterName) By("backing up a cluster and verifying it exists on azurite", func() { @@ -2204,7 +2227,13 @@ func prepareClusterForPITROnAzurite( }) // Write a table and insert 2 entries on the "app" database - AssertCreateTestData(env, namespace, clusterName, "for_restore") + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: "for_restore", + } + AssertCreateTestData(env, tableLocator) By("getting currentTimestamp", func() { ts, err := testsUtils.GetCurrentTimestamp(namespace, clusterName, env) @@ -2221,6 +2250,7 @@ func prepareClusterForPITROnAzurite( apiv1.ApplicationUserSecretSuffix, ) defer func() { + _ = conn.Close() forward.Close() }() Expect(err).ToNot(HaveOccurred()) @@ -2660,10 +2690,11 @@ func DeleteTableUsingPgBouncerService( Expect(err).ToNot(HaveOccurred()) AssertConnection(poolerService, appUser, "app", generatedAppUserPassword, pod, 180, env) - _, _, err = testsUtils.RunQueryFromPod( - pod, poolerService, "app", appUser, generatedAppUserPassword, - "DROP TABLE table1", - env) + connectionTimeout := time.Second * 10 + dsn := testsUtils.CreateDSN(poolerService, appUser, testsUtils.AppDBName, generatedAppUserPassword, + testsUtils.Require, 5432) + _, _, err = env.EventuallyExecCommand(env.Ctx, *pod, specs.PostgresContainerName, &connectionTimeout, + "psql", dsn, "-tAc", "DROP TABLE table1") Expect(err).ToNot(HaveOccurred()) } @@ -2873,16 +2904,22 @@ func DeleteResourcesFromFile(namespace, sampleFilePath string) error { } // Assert in the giving cluster, all the postgres db has no pending restart -func AssertPostgresNoPendingRestart(namespace, clusterName string, cmdTimeout time.Duration, timeout int) { +func AssertPostgresNoPendingRestart(namespace, clusterName string, timeout int) { By("waiting for all pods have no pending restart", func() { podList, err := env.GetClusterPodList(namespace, clusterName) Expect(err).ToNot(HaveOccurred()) + query := "SELECT EXISTS(SELECT 1 FROM pg_settings WHERE pending_restart)" // Check that the new parameter has been modified in every pod Eventually(func() (bool, error) { noPendingRestart := true for _, pod := range podList.Items { - stdout, _, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &cmdTimeout, - "psql", "-U", "postgres", "-tAc", "SELECT EXISTS(SELECT 1 FROM pg_settings WHERE pending_restart)") + stdout, _, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + testsUtils.PostgresDBName, + query) if err != nil { return false, nil } @@ -3029,8 +3066,13 @@ func AssertReplicationSlotsOnPod( "AND temporary = 'f' AND slot_type = 'physical')", slot, isActiveOnPrimary) } Eventually(func() (string, error) { - stdout, _, err := testsUtils.RunQueryFromPod(&pod, testsUtils.PGLocalSocketDir, - "app", "postgres", "''", query, env) + stdout, _, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + testsUtils.PostgresDBName, + query) return strings.TrimSpace(stdout), err }, 300).Should(BeEquivalentTo("t"), func() string { diff --git a/tests/e2e/backup_restore_test.go b/tests/e2e/backup_restore_test.go index 8ba08452e4..a452eaee94 100644 --- a/tests/e2e/backup_restore_test.go +++ b/tests/e2e/backup_restore_test.go @@ -123,7 +123,13 @@ var _ = Describe("Backup and restore", Label(tests.LabelBackupRestore), func() { AssertCreationOfTestDataForTargetDB(env, namespace, clusterName, targetDBSecret, testTableName) // Write a table and some data on the "app" database - AssertCreateTestData(env, namespace, clusterName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) AssertArchiveWalOnMinio(namespace, clusterName, clusterName) latestTar := minioPath(clusterName, "data.tar") @@ -269,7 +275,13 @@ var _ = Describe("Backup and restore", Label(tests.LabelBackupRestore), func() { AssertCreationOfTestDataForTargetDB(env, namespace, targetClusterName, targetDBSecret, testTableName) // Write a table and some data on the "app" database - AssertCreateTestData(env, namespace, targetClusterName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: targetClusterName, + DatabaseName: testUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) AssertArchiveWalOnMinio(namespace, targetClusterName, targetClusterName) latestTar := minioPath(targetClusterName, "data.tar") @@ -313,7 +325,13 @@ var _ = Describe("Backup and restore", Label(tests.LabelBackupRestore), func() { AssertCreationOfTestDataForTargetDB(env, namespace, targetClusterName, targetDBSecret, testTableName) // Write a table and some data on the "app" database - AssertCreateTestData(env, namespace, targetClusterName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: targetClusterName, + DatabaseName: testUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) AssertArchiveWalOnMinio(namespace, targetClusterName, targetClusterName) latestTar := minioPath(targetClusterName, "data.tar") @@ -366,7 +384,13 @@ var _ = Describe("Backup and restore", Label(tests.LabelBackupRestore), func() { AssertCreationOfTestDataForTargetDB(env, namespace, customClusterName, targetDBSecret, testTableName) // Write a table and some data on the "app" database - AssertCreateTestData(env, namespace, customClusterName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: customClusterName, + DatabaseName: testUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) AssertArchiveWalOnMinio(namespace, customClusterName, clusterServerName) @@ -539,7 +563,13 @@ var _ = Describe("Backup and restore", Label(tests.LabelBackupRestore), func() { // be there It("backs up and restore a cluster", func() { // Write a table and some data on the "app" database - AssertCreateTestData(env, namespace, clusterName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) AssertArchiveWalOnAzureBlob(namespace, clusterName, env.AzureConfiguration) By("uploading a backup", func() { // We create a backup @@ -821,7 +851,13 @@ var _ = Describe("Clusters Recovery From Barman Object Store", Label(tests.Label Expect(err).ToNot(HaveOccurred()) // Write a table and some data on the "app" database - AssertCreateTestData(env, namespace, clusterName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) AssertArchiveWalOnMinio(namespace, clusterName, clusterName) @@ -854,7 +890,13 @@ var _ = Describe("Clusters Recovery From Barman Object Store", Label(tests.Label AssertClusterRestore(namespace, externalClusterFileMinio, tableName) // verify test data on restored external cluster - AssertDataExpectedCount(env, namespace, externalClusterName, tableName, 2) + tableLocator = TableLocator{ + Namespace: namespace, + ClusterName: externalClusterName, + DatabaseName: testUtils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 2) By("deleting the restored cluster", func() { err = DeleteResourcesFromFile(namespace, externalClusterFileMinio) @@ -882,6 +924,7 @@ var _ = Describe("Clusters Recovery From Barman Object Store", Label(tests.Label apiv1.ApplicationUserSecretSuffix, ) defer func() { + _ = conn.Close() forward.Close() }() Expect(err).ToNot(HaveOccurred()) @@ -919,7 +962,13 @@ var _ = Describe("Clusters Recovery From Barman Object Store", Label(tests.Label It("restore cluster from barman object using replica option in spec", func() { // Write a table and some data on the "app" database - AssertCreateTestData(env, namespace, clusterName, "for_restore_repl") + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testUtils.AppDBName, + TableName: "for_restore_repl", + } + AssertCreateTestData(env, tableLocator) AssertArchiveWalOnMinio(namespace, clusterName, clusterName) @@ -974,7 +1023,13 @@ var _ = Describe("Clusters Recovery From Barman Object Store", Label(tests.Label It("restores a cluster from barman object using 'barmanObjectStore' option in 'externalClusters' section", func() { // Write a table and some data on the "app" database - AssertCreateTestData(env, namespace, clusterName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) AssertArchiveWalOnAzureBlob(namespace, clusterName, env.AzureConfiguration) By("backing up a cluster and verifying it exists on azure blob storage", func() { @@ -1060,7 +1115,13 @@ var _ = Describe("Clusters Recovery From Barman Object Store", Label(tests.Label It("restores cluster from barman object using 'barmanObjectStore' option in 'externalClusters' section", func() { // Write a table and some data on the "app" database - AssertCreateTestData(env, namespace, clusterName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) // Create a WAL on the primary and check if it arrives in the // Azure Blob Storage within a short time diff --git a/tests/e2e/cluster_microservice_test.go b/tests/e2e/cluster_microservice_test.go index 57704d213a..6019086aa3 100644 --- a/tests/e2e/cluster_microservice_test.go +++ b/tests/e2e/cluster_microservice_test.go @@ -20,7 +20,6 @@ import ( "fmt" "os" "strings" - "time" "github.com/cloudnative-pg/machinery/pkg/image/reference" "github.com/cloudnative-pg/machinery/pkg/postgres/version" @@ -28,7 +27,6 @@ import ( "k8s.io/apimachinery/pkg/types" apiv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1" - "github.com/cloudnative-pg/cloudnative-pg/pkg/specs" "github.com/cloudnative-pg/cloudnative-pg/pkg/versions" "github.com/cloudnative-pg/cloudnative-pg/tests" testsUtils "github.com/cloudnative-pg/cloudnative-pg/tests/utils" @@ -71,15 +69,25 @@ var _ = Describe("Imports with Microservice Approach", Label(tests.LabelImportin Expect(err).ToNot(HaveOccurred()) AssertCreateCluster(namespace, sourceClusterName, sourceSampleFile, env) - AssertCreateTestData(env, namespace, sourceClusterName, tableName) - primaryPod, err := env.GetClusterPrimary(namespace, sourceClusterName) - Expect(err).ToNot(HaveOccurred()) - AssertCreateTestDataLargeObject(namespace, sourceClusterName, oid, data, primaryPod) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: sourceClusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) + AssertCreateTestDataLargeObject(namespace, sourceClusterName, oid, data) importedClusterName = "cluster-pgdump-large-object" cluster := AssertClusterImport(namespace, importedClusterName, sourceClusterName, "app") - AssertDataExpectedCount(env, namespace, importedClusterName, tableName, 2) - AssertLargeObjectValue(namespace, importedClusterName, oid, data, primaryPod) + tableLocator = TableLocator{ + Namespace: namespace, + ClusterName: importedClusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 2) + AssertLargeObjectValue(namespace, importedClusterName, oid, data) By("deleting the imported database", func() { Expect(testsUtils.DeleteObject(env, cluster)).To(Succeed()) }) @@ -98,7 +106,13 @@ var _ = Describe("Imports with Microservice Approach", Label(tests.LabelImportin importedClusterName = "cluster-pgdump" AssertClusterImport(namespace, importedClusterName, sourceClusterName, "app") - AssertDataExpectedCount(env, namespace, importedClusterName, tableName, 2) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: importedClusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 2) assertTableAndDataOnImportedCluster(namespace, tableName, importedClusterName) }) @@ -199,7 +213,6 @@ func assertCreateTableWithDataOnSourceCluster( "and grant read only to app user", func() { pod, err := env.GetClusterPrimary(namespace, clusterName) Expect(err).ToNot(HaveOccurred()) - commandTimeout := time.Second * 10 query := fmt.Sprintf( "DROP USER IF EXISTS micro; "+ @@ -209,12 +222,13 @@ func assertCreateTableWithDataOnSourceCluster( "GRANT SELECT ON %[1]v TO app;", tableName) - _, _, err = env.ExecCommand( - env.Ctx, - *pod, - specs.PostgresContainerName, - &commandTimeout, - "psql", "-U", "postgres", "app", "-tAc", query) + _, _, err = env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + testsUtils.AppDBName, + query) Expect(err).ToNot(HaveOccurred()) }) } @@ -235,29 +249,19 @@ func assertTableAndDataOnImportedCluster( tableName, testsUtils.AppUser, ) - out, _, err := env.ExecCommandWithPsqlClient( - namespace, - importedClusterName, - pod, - apiv1.ApplicationUserSecretSuffix, + out, _, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, testsUtils.AppDBName, - queryImported, - ) + queryImported) Expect(err).ToNot(HaveOccurred()) Expect(strings.Contains(out, tableName), err).Should(BeTrue()) }) By("verifying the user named 'micro' on source is not in imported database", func() { - outUser, _, err := env.ExecCommandWithPsqlClient( - namespace, - importedClusterName, - pod, - apiv1.ApplicationUserSecretSuffix, - testsUtils.AppDBName, - "\\du", - ) - Expect(err).ToNot(HaveOccurred()) - Expect(strings.Contains(outUser, "micro"), err).Should(BeFalse()) + AssertUserExists(pod, "micro", false) }) }) } @@ -280,18 +284,18 @@ func assertImportRenamesSelectedDatabase( AssertCreateCluster(namespace, clusterName, sampleFile, env) primaryPod, err := env.GetClusterPrimary(namespace, clusterName) Expect(err).ToNot(HaveOccurred()) - commandTimeout := time.Second * 10 By("creating multiple dbs on source and set ownership to app", func() { for _, db := range dbList { // Create database createDBQuery := fmt.Sprintf("CREATE DATABASE %v OWNER app", db) - _, _, err = env.ExecCommand( - env.Ctx, - *primaryPod, - specs.PostgresContainerName, - &commandTimeout, - "psql", "-U", "postgres", "-tAc", createDBQuery) + _, _, err = env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: primaryPod.Namespace, + PodName: primaryPod.Name, + }, + testsUtils.PostgresDBName, + createDBQuery) Expect(err).ToNot(HaveOccurred()) } }) @@ -299,14 +303,8 @@ func assertImportRenamesSelectedDatabase( By(fmt.Sprintf("creating table '%s' and insert records on selected db %v", tableName, dbToImport), func() { // create a table with two records query := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s AS VALUES (1),(2);", tableName) - _, _, err := env.ExecCommandWithPsqlClient( - namespace, - clusterName, - primaryPod, - apiv1.ApplicationUserSecretSuffix, - dbToImport, - query, - ) + _, err = testsUtils.RunExecOverForward(env, namespace, clusterName, dbToImport, + apiv1.ApplicationUserSecretSuffix, query) Expect(err).ToNot(HaveOccurred()) }) @@ -320,22 +318,20 @@ func assertImportRenamesSelectedDatabase( AssertClusterStandbysAreStreaming(namespace, importedClusterName, 120) }) - AssertDataExpectedCount(env, namespace, importedClusterName, tableName, 2) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: importedClusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 2) By("verifying that only 'app' DB exists in the imported cluster", func() { importedPrimaryPod, err := env.GetClusterPrimary(namespace, importedClusterName) Expect(err).ToNot(HaveOccurred()) - out, _, err := env.ExecCommandWithPsqlClient( - namespace, - importedClusterName, - importedPrimaryPod, - apiv1.ApplicationUserSecretSuffix, - testsUtils.AppDBName, - "\\l", - ) - Expect(err).ToNot(HaveOccurred(), err) - Expect(strings.Contains(out, "db2"), err).Should(BeFalse()) - Expect(strings.Contains(out, "app"), err).Should(BeTrue()) + + AssertUserExists(importedPrimaryPod, "db2", false) + AssertUserExists(importedPrimaryPod, "app", true) }) By("cleaning up the clusters", func() { diff --git a/tests/e2e/cluster_monolithic_test.go b/tests/e2e/cluster_monolithic_test.go index 89281f09b6..34d1f3de9e 100644 --- a/tests/e2e/cluster_monolithic_test.go +++ b/tests/e2e/cluster_monolithic_test.go @@ -84,6 +84,7 @@ var _ = Describe("Imports with Monolithic Approach", Label(tests.LabelImportingD apiv1.SuperUserSecretSuffix, ) defer func() { + _ = conn.Close() forward.Close() }() Expect(err).ToNot(HaveOccurred()) diff --git a/tests/e2e/cluster_setup_test.go b/tests/e2e/cluster_setup_test.go index 3515d9c3d0..9f2d124712 100644 --- a/tests/e2e/cluster_setup_test.go +++ b/tests/e2e/cluster_setup_test.go @@ -131,6 +131,7 @@ var _ = Describe("Cluster setup", Label(tests.LabelSmoke, tests.LabelBasic), fun apiv1.ApplicationUserSecretSuffix, ) defer func() { + _ = conn.Close() forward.Close() }() Expect(err).NotTo(HaveOccurred()) diff --git a/tests/e2e/configuration_update_test.go b/tests/e2e/configuration_update_test.go index 9c0346ea49..74800a23ab 100644 --- a/tests/e2e/configuration_update_test.go +++ b/tests/e2e/configuration_update_test.go @@ -31,7 +31,6 @@ import ( apiv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1" "github.com/cloudnative-pg/cloudnative-pg/pkg/specs" - devUtils "github.com/cloudnative-pg/cloudnative-pg/pkg/utils" "github.com/cloudnative-pg/cloudnative-pg/tests" "github.com/cloudnative-pg/cloudnative-pg/tests/utils" @@ -117,8 +116,13 @@ var _ = Describe("Configuration update", Ordered, Label(tests.LabelClusterMetada for idx := range podList.Items { pod := podList.Items[idx] Eventually(func(g Gomega) int { - stdout, _, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", "show autovacuum_max_workers") + stdout, _, err := env.ExecQueryInInstancePod( + utils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + utils.PostgresDBName, + "show autovacuum_max_workers") g.Expect(err).ToNot(HaveOccurred()) value, atoiErr := strconv.Atoi(strings.Trim(stdout, "\n")) @@ -150,15 +154,20 @@ var _ = Describe("Configuration update", Ordered, Label(tests.LabelClusterMetada By("apply configuration update", func() { // Update the configuration updateClusterPostgresParams(postgresParams, namespace) - AssertPostgresNoPendingRestart(namespace, clusterName, commandTimeout, 300) + AssertPostgresNoPendingRestart(namespace, clusterName, 300) }) By("verify that work_mem result as expected", func() { // Check that the parameter has been modified in every pod for _, pod := range podList.Items { Eventually(func() (int, error, error) { - stdout, _, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", "show work_mem") + stdout, _, err := env.ExecQueryInInstancePod( + utils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + utils.PostgresDBName, + "show work_mem") value, atoiErr := strconv.Atoi(strings.Trim(stdout, "MB\n")) return value, err, atoiErr }, timeout).Should(BeEquivalentTo(8)) @@ -173,14 +182,9 @@ var _ = Describe("Configuration update", Ordered, Label(tests.LabelClusterMetada podList, err := env.GetClusterPodList(namespace, clusterName) Expect(err).ToNot(HaveOccurred()) - By("verify that connection should failed by default", func() { - _, _, err := devUtils.ExecCommand( - env.Ctx, - env.Interface, - env.RestClientConfig, - podList.Items[0], - specs.PostgresContainerName, - &commandTimeout, + By("verify that connections fail by default", func() { + _, _, err := env.ExecCommand(env.Ctx, podList.Items[0], + specs.PostgresContainerName, &commandTimeout, "psql", "-U", "postgres", "-h", endpointName, "-tAc", "select 1", ) Expect(err).To(HaveOccurred()) @@ -189,16 +193,21 @@ var _ = Describe("Configuration update", Ordered, Label(tests.LabelClusterMetada By("apply configuration update", func() { // Update the configuration updateClusterPostgresPgHBA(namespace) - AssertPostgresNoPendingRestart(namespace, clusterName, commandTimeout, 300) + AssertPostgresNoPendingRestart(namespace, clusterName, 300) }) - By("verify that connection should success after pg_hba_reload", func() { + By("verify that connections succeed after pg_hba_reload", func() { // The new pg_hba rule should be present in every pod + query := "select count(*) from pg_hba_file_rules where type = 'host' and auth_method = 'trust'" for _, pod := range podList.Items { Eventually(func() (string, error) { - stdout, _, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", - "select count(*) from pg_hba_file_rules where type = 'host' and auth_method = 'trust'") + stdout, _, err := env.ExecQueryInInstancePod( + utils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + utils.PostgresDBName, + query) return strings.Trim(stdout, "\n"), err }, timeout).Should(BeEquivalentTo("1")) } @@ -227,15 +236,20 @@ var _ = Describe("Configuration update", Ordered, Label(tests.LabelClusterMetada // Update the configuration postgresParams["shared_buffers"] = "256MB" updateClusterPostgresParams(postgresParams, namespace) - AssertPostgresNoPendingRestart(namespace, clusterName, commandTimeout, timeout) + AssertPostgresNoPendingRestart(namespace, clusterName, timeout) }) By("verify that shared_buffers setting changed", func() { // Check that the new parameter has been modified in every pod for _, pod := range podList.Items { Eventually(func() (int, error, error) { - stdout, _, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", "show shared_buffers") + stdout, _, err := env.ExecQueryInInstancePod( + utils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + utils.PostgresDBName, + "show shared_buffers") value, atoiErr := strconv.Atoi(strings.Trim(stdout, "MB\n")) return value, err, atoiErr }, timeout).Should(BeEquivalentTo(256), @@ -265,22 +279,32 @@ var _ = Describe("Configuration update", Ordered, Label(tests.LabelClusterMetada postgresParams["max_replication_slots"] = "16" postgresParams["maintenance_work_mem"] = "128MB" updateClusterPostgresParams(postgresParams, namespace) - AssertPostgresNoPendingRestart(namespace, clusterName, commandTimeout, timeout) + AssertPostgresNoPendingRestart(namespace, clusterName, timeout) }) By("verify that both parameters have been modified in each pod", func() { // Check that both parameters have been modified in each pod for _, pod := range podList.Items { Eventually(func() (int, error, error) { - stdout, _, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", "show max_replication_slots") + stdout, _, err := env.ExecQueryInInstancePod( + utils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + utils.PostgresDBName, + "show max_replication_slots") value, atoiErr := strconv.Atoi(strings.Trim(stdout, "\n")) return value, err, atoiErr }, timeout).Should(BeEquivalentTo(16)) Eventually(func() (int, error, error) { - stdout, _, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", "show maintenance_work_mem") + stdout, _, err := env.ExecQueryInInstancePod( + utils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + utils.PostgresDBName, + "show maintenance_work_mem") value, atoiErr := strconv.Atoi(strings.Trim(stdout, "MB\n")) return value, err, atoiErr }, timeout).Should(BeEquivalentTo(128)) @@ -325,15 +349,20 @@ var _ = Describe("Configuration update", Ordered, Label(tests.LabelClusterMetada delete(postgresParams, "port") postgresParams["max_connections"] = "105" updateClusterPostgresParams(postgresParams, namespace) - AssertPostgresNoPendingRestart(namespace, clusterName, commandTimeout, timeout) + AssertPostgresNoPendingRestart(namespace, clusterName, timeout) }) By("verify that max_connections has been decreased in every pod", func() { // Check that the new parameter has been modified in every pod for _, pod := range podList.Items { Eventually(func() (int, error, error) { - stdout, _, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", "show max_connections") + stdout, _, err := env.ExecQueryInInstancePod( + utils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + utils.PostgresDBName, + "show max_connections") value, atoiErr := strconv.Atoi(strings.Trim(stdout, "\n")) return value, err, atoiErr }, timeout).Should(BeEquivalentTo(105), @@ -366,15 +395,20 @@ var _ = Describe("Configuration update", Ordered, Label(tests.LabelClusterMetada // Update the configuration delete(postgresParams, "max_connections") updateClusterPostgresParams(postgresParams, namespace) - AssertPostgresNoPendingRestart(namespace, clusterName, commandTimeout, timeout) + AssertPostgresNoPendingRestart(namespace, clusterName, timeout) }) By("verify that the max_connections has been set to default in every pod", func() { // Check that the new parameter has been modified in every pod for _, pod := range podList.Items { Eventually(func() (int, error, error) { - stdout, _, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", "show max_connections") + stdout, _, err := env.ExecQueryInInstancePod( + utils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + utils.PostgresDBName, + "show max_connections") value, atoiErr := strconv.Atoi(strings.Trim(stdout, "\n")) return value, err, atoiErr }, timeout).Should(BeEquivalentTo(100), @@ -390,53 +424,45 @@ var _ = Describe("Configuration update", Ordered, Label(tests.LabelClusterMetada }) }) + // pg_ident_file_mappings is available from v15 only It("09. reloading Pg when pg_ident rules are modified", func() { - podList, err := env.GetClusterPodList(namespace, clusterName) - Expect(err).ToNot(HaveOccurred()) - - stdout, _, err := env.ExecCommand(env.Ctx, podList.Items[0], specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", - "select count(1) from pg_views where viewname = 'pg_ident_file_mappings';") - psqlHasIdentView := err == nil && strings.Trim(stdout, "\n") == "1" + if env.PostgresVersion > 14 { + primaryPod, err := env.GetClusterPrimary(namespace, clusterName) + Expect(err).ToNot(HaveOccurred()) + query := "select count(1) from pg_ident_file_mappings;" - By("check that there is only one entry in pg_ident_file_mappings", func() { - for _, pod := range podList.Items { - if psqlHasIdentView { - Eventually(func() (string, error) { - stdout, _, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", - "select count(1) from pg_ident_file_mappings;") - return strings.Trim(stdout, "\n"), err - }, timeout).Should(BeEquivalentTo("1")) - } - } - }) + By("check that there is only one entry in pg_ident_file_mappings", func() { + Eventually(func() (string, error) { + stdout, _, err := env.ExecQueryInInstancePod( + utils.PodLocator{ + Namespace: primaryPod.Namespace, + PodName: primaryPod.Name, + }, + utils.PostgresDBName, + query) + return strings.Trim(stdout, "\n"), err + }, timeout).Should(BeEquivalentTo("1")) + }) - By("apply configuration update", func() { - // Update the configuration - updateClusterPostgresPgIdent(namespace) - AssertPostgresNoPendingRestart(namespace, clusterName, commandTimeout, 300) - }) + By("apply configuration update", func() { + // Update the configuration + updateClusterPostgresPgIdent(namespace) + AssertPostgresNoPendingRestart(namespace, clusterName, 300) + }) - By("verify that there are now two entries in pg_ident_file_mappings", func() { - for _, pod := range podList.Items { - if psqlHasIdentView { - Eventually(func() (string, error) { - stdout, _, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", - "select count(1) from pg_ident_file_mappings;") - return strings.Trim(stdout, "\n"), err - }, timeout).Should(BeEquivalentTo("2")) - } else { - // Can't check for the actual content of the file, but let's check that we can reload the config - Eventually(func() (string, error) { - stdout, _, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", "select count(1) where pg_reload_conf();") - return strings.Trim(stdout, "\n"), err - }, timeout).Should(BeEquivalentTo("1")) - } - } - }) + By("verify that there are now two entries in pg_ident_file_mappings", func() { + Eventually(func() (string, error) { + stdout, _, err := env.ExecQueryInInstancePod( + utils.PodLocator{ + Namespace: primaryPod.Namespace, + PodName: primaryPod.Name, + }, + utils.PostgresDBName, + query) + return strings.Trim(stdout, "\n"), err + }, timeout).Should(BeEquivalentTo("2")) + }) + } }) }) @@ -532,11 +558,15 @@ var _ = Describe("Configuration update with primaryUpdateMethod", Label(tests.La podList, err := env.GetClusterPodList(namespace, clusterName) Expect(err).ToNot(HaveOccurred()) - commandTimeout := time.Second * 10 for _, pod := range podList.Items { Eventually(func() (int, error, error) { - stdout, _, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", "show max_connections") + stdout, _, err := env.ExecQueryInInstancePod( + utils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + utils.PostgresDBName, + "show max_connections") value, atoiErr := strconv.Atoi(strings.Trim(stdout, "\n")) return value, err, atoiErr }, 180).Should(BeEquivalentTo(newMaxConnectionsValue), @@ -552,7 +582,6 @@ var _ = Describe("Configuration update with primaryUpdateMethod", Label(tests.La }) By("verifying that old primary was actually restarted", func() { - commandTimeout := time.Second * 10 pod := corev1.Pod{} err := env.Client.Get(env.Ctx, types.NamespacedName{ Namespace: namespace, @@ -561,9 +590,16 @@ var _ = Describe("Configuration update with primaryUpdateMethod", Label(tests.La Expect(err).ToNot(HaveOccurred()) // take pg postmaster start time - stdout, _, cmdErr := env.EventuallyExecCommand(env.Ctx, pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", - "select to_char(pg_postmaster_start_time(), 'YYYY-MM-DD HH24:MI:SS');") + query := "select to_char(pg_postmaster_start_time(), 'YYYY-MM-DD HH24:MI:SS');" + stdout, _, cmdErr := env.EventuallyExecQueryInInstancePod( + utils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, utils.PostgresDBName, + query, + RetryTimeout, + PollingTime, + ) Expect(cmdErr).ToNot(HaveOccurred()) newStartTime, err := cnpgTypes.ParseTargetTime(nil, strings.Trim(stdout, "\n")) @@ -576,7 +612,6 @@ var _ = Describe("Configuration update with primaryUpdateMethod", Label(tests.La It("work_mem config change should not require a restart", func() { const expectedNewValueForWorkMem = "10MB" - commandTimeout := time.Second * 10 By("updating work mem ", func() { cluster, err := env.GetCluster(namespace, clusterName) @@ -595,14 +630,19 @@ var _ = Describe("Configuration update with primaryUpdateMethod", Label(tests.La // Check that the parameter has been modified in every pod for _, pod := range podList.Items { Eventually(func() (int, error, error) { - stdout, _, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", "show work_mem") + stdout, _, err := env.ExecQueryInInstancePod( + utils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + utils.PostgresDBName, + "show work_mem") value, atoiErr := strconv.Atoi(strings.Trim(stdout, "MB\n")) return value, err, atoiErr }, 160).Should(BeEquivalentTo(10)) } }) - AssertPostgresNoPendingRestart(namespace, clusterName, commandTimeout, 120) + AssertPostgresNoPendingRestart(namespace, clusterName, 120) }) }) }) diff --git a/tests/e2e/declarative_hibernation_test.go b/tests/e2e/declarative_hibernation_test.go index 3b88a044a9..7f30bf1070 100644 --- a/tests/e2e/declarative_hibernation_test.go +++ b/tests/e2e/declarative_hibernation_test.go @@ -24,6 +24,7 @@ import ( "github.com/cloudnative-pg/cloudnative-pg/pkg/reconciler/hibernation" "github.com/cloudnative-pg/cloudnative-pg/pkg/utils" "github.com/cloudnative-pg/cloudnative-pg/tests" + testsUtils "github.com/cloudnative-pg/cloudnative-pg/tests/utils" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -55,7 +56,13 @@ var _ = Describe("Cluster declarative hibernation", func() { By("creating a new cluster", func() { AssertCreateCluster(namespace, clusterName, sampleFileCluster, env) // Write a table and some data on the "app" database - AssertCreateTestData(env, namespace, clusterName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) }) By("hibernating the new cluster", func() { @@ -114,7 +121,13 @@ var _ = Describe("Cluster declarative hibernation", func() { }) By("verifying the data has been preserved", func() { - AssertDataExpectedCount(env, namespace, clusterName, tableName, 2) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 2) }) }) }) diff --git a/tests/e2e/disk_space_test.go b/tests/e2e/disk_space_test.go index 84986cd3c1..d838034d9d 100644 --- a/tests/e2e/disk_space_test.go +++ b/tests/e2e/disk_space_test.go @@ -73,22 +73,22 @@ var _ = Describe("Volume space unavailable", Label(tests.LabelStorage), func() { By("writing something when no space is available", func() { // Create the table used by the scenario query := "CREATE TABLE diskspace AS SELECT generate_series(1, 1000000);" - _, _, err := env.ExecCommandWithPsqlClient( - namespace, - clusterName, - primaryPod, - apiv1.ApplicationUserSecretSuffix, + _, _, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: primaryPod.Namespace, + PodName: primaryPod.Name, + }, testsUtils.AppDBName, - query, - ) + query) Expect(err).To(HaveOccurred()) + query = "CHECKPOINT; SELECT pg_switch_wal(); CHECKPOINT" _, _, err = env.ExecQueryInInstancePod( testsUtils.PodLocator{ Namespace: primaryPod.Namespace, PodName: primaryPod.Name, }, - testsUtils.DatabaseName("postgres"), + testsUtils.PostgresDBName, query) Expect(err).To(HaveOccurred()) }) @@ -171,7 +171,7 @@ var _ = Describe("Volume space unavailable", Label(tests.LabelStorage), func() { Namespace: primaryPod.Namespace, PodName: primaryPod.Name, }, - testsUtils.DatabaseName("postgres"), + testsUtils.PostgresDBName, query) Expect(err).NotTo(HaveOccurred()) }) diff --git a/tests/e2e/drain_node_test.go b/tests/e2e/drain_node_test.go index 19e183db2d..b018065c1b 100644 --- a/tests/e2e/drain_node_test.go +++ b/tests/e2e/drain_node_test.go @@ -118,7 +118,13 @@ var _ = Describe("E2E Drain Node", Serial, Label(tests.LabelDisruptive, tests.La // Load test data oldPrimary := clusterName + "-1" - AssertCreateTestData(env, namespace, clusterName, "test") + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: "test", + } + AssertCreateTestData(env, tableLocator) // We create a mapping between the pod names and the UIDs of // their volumes. We do not expect the UIDs to change. @@ -178,10 +184,7 @@ var _ = Describe("E2E Drain Node", Serial, Label(tests.LabelDisruptive, tests.La } }) - // Expect the (previously created) test data to be available - primary, err := env.GetClusterPrimary(namespace, clusterName) - Expect(err).ToNot(HaveOccurred()) - AssertDataExpectedCountWithDatabaseName(namespace, primary.Name, "app", "test", 2) + AssertDataExpectedCount(env, tableLocator, 2) AssertClusterStandbysAreStreaming(namespace, clusterName, 120) }) @@ -230,7 +233,13 @@ var _ = Describe("E2E Drain Node", Serial, Label(tests.LabelDisruptive, tests.La // Load test data oldPrimary := clusterName + "-1" - AssertCreateTestData(env, namespace, clusterName, "test") + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: "test", + } + AssertCreateTestData(env, tableLocator) // We create a mapping between the pod names and the UIDs of // their volumes. We do not expect the UIDs to change. @@ -294,10 +303,7 @@ var _ = Describe("E2E Drain Node", Serial, Label(tests.LabelDisruptive, tests.La } }) - // Expect the (previously created) test data to be available - primary, err := env.GetClusterPrimary(namespace, clusterName) - Expect(err).ToNot(HaveOccurred()) - AssertDataExpectedCountWithDatabaseName(namespace, primary.Name, "app", "test", 2) + AssertDataExpectedCount(env, tableLocator, 2) AssertClusterStandbysAreStreaming(namespace, clusterName, 120) }) }) @@ -360,7 +366,13 @@ var _ = Describe("E2E Drain Node", Serial, Label(tests.LabelDisruptive, tests.La }) // Load test data - AssertCreateTestData(env, namespace, clusterName, "test") + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: "test", + } + AssertCreateTestData(env, tableLocator) // We uncordon a cordoned node. New pods can go there. By("uncordon node for pod failover", func() { @@ -396,10 +408,7 @@ var _ = Describe("E2E Drain Node", Serial, Label(tests.LabelDisruptive, tests.La }, timeout).Should(Succeed()) }) - // Expect the (previously created) test data to be available - primary, err := env.GetClusterPrimary(namespace, clusterName) - Expect(err).ToNot(HaveOccurred()) - AssertDataExpectedCountWithDatabaseName(namespace, primary.Name, "app", "test", 2) + AssertDataExpectedCount(env, tableLocator, 2) AssertClusterStandbysAreStreaming(namespace, clusterName, 120) err = nodes.UncordonAllNodes(env) Expect(err).ToNot(HaveOccurred()) @@ -433,9 +442,13 @@ var _ = Describe("E2E Drain Node", Serial, Label(tests.LabelDisruptive, tests.La }) // Load test data - primary, err := env.GetClusterPrimary(namespace, clusterName) - Expect(err).ToNot(HaveOccurred()) - AssertCreateTestData(env, namespace, clusterName, "test") + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: "test", + } + AssertCreateTestData(env, tableLocator) // Drain the node containing the primary pod and store the list of running pods _ = nodes.DrainPrimaryNode(namespace, clusterName, @@ -458,7 +471,8 @@ var _ = Describe("E2E Drain Node", Serial, Label(tests.LabelDisruptive, tests.La Expect(err).ToNot(HaveOccurred()) }) - AssertDataExpectedCountWithDatabaseName(namespace, primary.Name, "app", "test", 2) + AssertClusterIsReady(namespace, clusterName, testTimeouts[testsUtils.ClusterIsReady], env) + AssertDataExpectedCount(env, tableLocator, 2) }) }) diff --git a/tests/e2e/failover_test.go b/tests/e2e/failover_test.go index b3f6731aa1..a59695bad6 100644 --- a/tests/e2e/failover_test.go +++ b/tests/e2e/failover_test.go @@ -79,9 +79,15 @@ var _ = Describe("Failover", Label(tests.LabelSelfHealing), func() { // Get the walreceiver pid query := "SELECT pid FROM pg_stat_activity WHERE backend_type = 'walreceiver'" - out, _, err := env.EventuallyExecCommand( - env.Ctx, *pausedPod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", query) + out, _, err := env.EventuallyExecQueryInInstancePod( + utils.PodLocator{ + Namespace: pausedPod.Namespace, + PodName: pausedPod.Name, + }, utils.PostgresDBName, + query, + RetryTimeout, + PollingTime, + ) Expect(err).ToNot(HaveOccurred()) pid = strings.Trim(out, "\n") @@ -94,9 +100,15 @@ var _ = Describe("Failover", Label(tests.LabelSelfHealing), func() { // We don't want to wait for the replication timeout. query = fmt.Sprintf("SELECT pg_terminate_backend(pid) FROM pg_stat_replication "+ "WHERE application_name = '%v'", pausedReplica) - _, _, err = env.EventuallyExecCommand( - env.Ctx, *primaryPod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", query) + _, _, err = env.EventuallyExecQueryInInstancePod( + utils.PodLocator{ + Namespace: primaryPod.Namespace, + PodName: primaryPod.Name, + }, utils.PostgresDBName, + query, + RetryTimeout, + PollingTime, + ) Expect(err).ToNot(HaveOccurred()) // Expect the primary to have lost connection with the stopped standby @@ -114,28 +126,46 @@ var _ = Describe("Failover", Label(tests.LabelSelfHealing), func() { Expect(err).ToNot(HaveOccurred()) // Gather the current WAL LSN - initialLSN, _, err := env.EventuallyExecCommand( - env.Ctx, *primaryPod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", "SELECT pg_current_wal_lsn()") + initialLSN, _, err := env.EventuallyExecQueryInInstancePod( + utils.PodLocator{ + Namespace: primaryPod.Namespace, + PodName: primaryPod.Name, + }, utils.PostgresDBName, + "SELECT pg_current_wal_lsn()", + RetryTimeout, + PollingTime, + ) Expect(err).ToNot(HaveOccurred()) // Execute a checkpoint - _, _, err = env.EventuallyExecCommand( - env.Ctx, *primaryPod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", "CHECKPOINT") + _, _, err = env.EventuallyExecQueryInInstancePod( + utils.PodLocator{ + Namespace: primaryPod.Namespace, + PodName: primaryPod.Name, + }, utils.PostgresDBName, + "CHECKPOINT", + RetryTimeout, + PollingTime, + ) Expect(err).ToNot(HaveOccurred()) + query := fmt.Sprintf("SELECT true FROM pg_stat_replication "+ + "WHERE application_name = '%v' AND replay_lsn > '%v'", + targetPrimary, strings.Trim(initialLSN, "\n")) // The replay_lsn of the targetPrimary should be ahead // of the one before the checkpoint Eventually(func() (string, error) { primaryPod, err = env.GetPod(namespace, currentPrimary) Expect(err).ToNot(HaveOccurred()) - query := fmt.Sprintf("SELECT true FROM pg_stat_replication "+ - "WHERE application_name = '%v' AND replay_lsn > '%v'", - targetPrimary, strings.Trim(initialLSN, "\n")) - out, _, err := env.EventuallyExecCommand( - env.Ctx, *primaryPod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", query) + out, _, err := env.EventuallyExecQueryInInstancePod( + utils.PodLocator{ + Namespace: primaryPod.Namespace, + PodName: primaryPod.Name, + }, utils.PostgresDBName, + query, + RetryTimeout, + PollingTime, + ) return strings.TrimSpace(out), err }, RetryTimeout).Should(BeEquivalentTo("t")) }) diff --git a/tests/e2e/fastswitchover_test.go b/tests/e2e/fastswitchover_test.go index 86aac345ca..d7a45efd47 100644 --- a/tests/e2e/fastswitchover_test.go +++ b/tests/e2e/fastswitchover_test.go @@ -19,14 +19,12 @@ package e2e import ( "fmt" "strings" - "time" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/util/retry" apiv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1" - "github.com/cloudnative-pg/cloudnative-pg/pkg/specs" "github.com/cloudnative-pg/cloudnative-pg/tests" "github.com/cloudnative-pg/cloudnative-pg/tests/utils" @@ -137,17 +135,8 @@ func assertFastSwitchover(namespace, sampleFile, clusterName, webTestFile, webTe ", PRIMARY KEY (id)" + ")" - primaryPod, err := env.GetClusterPrimary(namespace, clusterName) - Expect(err).ToNot(HaveOccurred()) - - _, _, err = env.ExecCommandWithPsqlClient( - namespace, - clusterName, - primaryPod, - apiv1.ApplicationUserSecretSuffix, - utils.AppDBName, - query, - ) + _, err := utils.RunExecOverForward(env, namespace, clusterName, utils.AppDBName, + apiv1.ApplicationUserSecretSuffix, query) Expect(err).ToNot(HaveOccurred()) }) @@ -164,23 +153,26 @@ func assertFastSwitchover(namespace, sampleFile, clusterName, webTestFile, webTe " -f " + webTestJob) Expect(err).ToNot(HaveOccurred()) - commandTimeout := time.Second * 10 - timeout := 60 primaryPodNamespacedName := types.NamespacedName{ Namespace: namespace, Name: oldPrimary, } + query := "SELECT count(*) > 0 FROM tps.tl" Eventually(func() (string, error) { primaryPod := &corev1.Pod{} err := env.Client.Get(env.Ctx, primaryPodNamespacedName, primaryPod) if err != nil { return "", err } - out, _, err := env.ExecCommand(env.Ctx, *primaryPod, specs.PostgresContainerName, - &commandTimeout, "psql", "-U", "postgres", "app", "-tAc", - "SELECT count(*) > 0 FROM tps.tl") + out, _, err := env.ExecQueryInInstancePod( + utils.PodLocator{ + Namespace: primaryPod.Namespace, + PodName: primaryPod.Name, + }, + utils.AppDBName, + query) return strings.TrimSpace(out), err - }, timeout).Should(BeEquivalentTo("t")) + }, RetryTimeout).Should(BeEquivalentTo("t")) }) By("setting the TargetPrimary to node2 to trigger a switchover", func() { diff --git a/tests/e2e/fencing_test.go b/tests/e2e/fencing_test.go index d160cbb583..4644a4b3ab 100644 --- a/tests/e2e/fencing_test.go +++ b/tests/e2e/fencing_test.go @@ -70,7 +70,7 @@ var _ = Describe("Fencing", Label(tests.LabelPlugin), func() { } checkInstanceIsStreaming := func(instanceName, namespace string) { - timeout := time.Second * 10 + query := "SELECT count(*) FROM pg_stat_wal_receiver" Eventually(func() (int, error) { err := env.Client.Get(env.Ctx, ctrlclient.ObjectKey{Namespace: namespace, Name: instanceName}, @@ -78,8 +78,13 @@ var _ = Describe("Fencing", Label(tests.LabelPlugin), func() { if err != nil { return 0, err } - out, _, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &timeout, - "psql", "-U", "postgres", "-tAc", "SELECT count(*) FROM pg_stat_wal_receiver") + out, _, err := env.ExecQueryInInstancePod( + testUtils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + testUtils.PostgresDBName, + query) if err != nil { return 0, err } diff --git a/tests/e2e/hibernation_test.go b/tests/e2e/hibernation_test.go index 58f68418ee..ce4f38ea64 100644 --- a/tests/e2e/hibernation_test.go +++ b/tests/e2e/hibernation_test.go @@ -225,7 +225,13 @@ var _ = Describe("Cluster Hibernation with plugin", Label(tests.LabelPlugin), fu var beforeHibernationPgDataPvcUID types.UID // Write a table and some data on the "app" database - AssertCreateTestData(env, namespace, clusterName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) clusterManifest, currentPrimary := getPrimaryAndClusterManifest(namespace, clusterName) By("collecting pgWal pvc details of current primary", func() { @@ -289,7 +295,7 @@ var _ = Describe("Cluster Hibernation with plugin", Label(tests.LabelPlugin), fu AssertClusterIsReady(namespace, clusterName, testTimeouts[testsUtils.ClusterIsReady], env) // Test data should be present after hibernation off - AssertDataExpectedCount(env, namespace, clusterName, tableName, 2) + AssertDataExpectedCount(env, tableLocator, 2) } When("cluster setup with PG-WAL volume", func() { @@ -316,7 +322,13 @@ var _ = Describe("Cluster Hibernation with plugin", Label(tests.LabelPlugin), fu Expect(err).ToNot(HaveOccurred()) AssertCreateCluster(namespace, clusterName, sampleFileClusterWithOutPGWalVolume, env) // Write a table and some data on the "app" database - AssertCreateTestData(env, namespace, clusterName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) clusterManifest, currentPrimary := getPrimaryAndClusterManifest(namespace, clusterName) @@ -363,7 +375,7 @@ var _ = Describe("Cluster Hibernation with plugin", Label(tests.LabelPlugin), fu AssertClusterIsReady(namespace, clusterName, testTimeouts[testsUtils.ClusterIsReady], env) // Test data should be present after hibernation off - AssertDataExpectedCount(env, namespace, clusterName, tableName, 2) + AssertDataExpectedCount(env, tableLocator, 2) }) }) When("cluster hibernation after switchover", func() { diff --git a/tests/e2e/managed_roles_test.go b/tests/e2e/managed_roles_test.go index 0f77768921..534867203d 100644 --- a/tests/e2e/managed_roles_test.go +++ b/tests/e2e/managed_roles_test.go @@ -94,7 +94,7 @@ var _ = Describe("Managed roles tests", Label(tests.LabelSmoke, tests.LabelBasic Namespace: namespace, PodName: primaryPod, }, - utils.DatabaseName("postgres"), + utils.PostgresDBName, "\\du") g.Expect(err).ToNot(HaveOccurred()) if shouldExists { @@ -121,7 +121,7 @@ var _ = Describe("Managed roles tests", Label(tests.LabelSmoke, tests.LabelBasic Namespace: namespace, PodName: primaryPod, }, - utils.DatabaseName("postgres"), + utils.PostgresDBName, query) if err != nil { return []string{ERROR} @@ -163,7 +163,7 @@ var _ = Describe("Managed roles tests", Label(tests.LabelSmoke, tests.LabelBasic Namespace: namespace, PodName: primaryPodInfo.Name, }, - utils.DatabaseName("postgres"), + utils.PostgresDBName, q) Expect(err).ToNot(HaveOccurred()) Expect(stdout).To(Equal("t\n")) @@ -195,7 +195,7 @@ var _ = Describe("Managed roles tests", Label(tests.LabelSmoke, tests.LabelBasic Namespace: namespace, PodName: primaryPodInfo.Name, }, - utils.DatabaseName("postgres"), + utils.PostgresDBName, query) Expect(err).ToNot(HaveOccurred()) Expect(stdout).To(Equal("t\n")) @@ -274,7 +274,7 @@ var _ = Describe("Managed roles tests", Label(tests.LabelSmoke, tests.LabelBasic Namespace: namespace, PodName: primaryPod.Name, }, - utils.DatabaseName("postgres"), + utils.PostgresDBName, query) if err != nil { return "" @@ -348,7 +348,7 @@ var _ = Describe("Managed roles tests", Label(tests.LabelSmoke, tests.LabelBasic Namespace: namespace, PodName: primaryPodInfo.Name, }, - utils.DatabaseName("postgres"), + utils.PostgresDBName, query) if err != nil { return "" @@ -390,7 +390,7 @@ var _ = Describe("Managed roles tests", Label(tests.LabelSmoke, tests.LabelBasic Namespace: namespace, PodName: primaryPodInfo.Name, }, - utils.DatabaseName("postgres"), + utils.PostgresDBName, query) if err != nil { return ERROR @@ -410,7 +410,7 @@ var _ = Describe("Managed roles tests", Label(tests.LabelSmoke, tests.LabelBasic Namespace: namespace, PodName: primaryPodInfo.Name, }, - utils.DatabaseName("postgres"), + utils.PostgresDBName, query) if err != nil { return ERROR @@ -556,7 +556,7 @@ var _ = Describe("Managed roles tests", Label(tests.LabelSmoke, tests.LabelBasic Namespace: namespace, PodName: primaryPod.Name, }, - utils.DatabaseName("postgres"), + utils.PostgresDBName, query) Expect(err).ToNot(HaveOccurred()) }) @@ -603,7 +603,7 @@ var _ = Describe("Managed roles tests", Label(tests.LabelSmoke, tests.LabelBasic Namespace: namespace, PodName: primaryPodInfo.Name, }, - utils.DatabaseName("postgres"), + utils.PostgresDBName, query) if err != nil { return ERROR @@ -623,7 +623,7 @@ var _ = Describe("Managed roles tests", Label(tests.LabelSmoke, tests.LabelBasic Namespace: namespace, PodName: primaryPodInfo.Name, }, - utils.DatabaseName("postgres"), + utils.PostgresDBName, query) if err != nil { return ERROR diff --git a/tests/e2e/metrics_test.go b/tests/e2e/metrics_test.go index 9907f59266..e057220f35 100644 --- a/tests/e2e/metrics_test.go +++ b/tests/e2e/metrics_test.go @@ -298,6 +298,7 @@ var _ = Describe("Metrics", Label(tests.LabelObservability), func() { apiv1.ApplicationUserSecretSuffix, ) defer func() { + _ = conn.Close() forward.Close() }() Expect(err).ToNot(HaveOccurred()) diff --git a/tests/e2e/operator_unavailable_test.go b/tests/e2e/operator_unavailable_test.go index d2088c7a68..5f23913135 100644 --- a/tests/e2e/operator_unavailable_test.go +++ b/tests/e2e/operator_unavailable_test.go @@ -26,6 +26,7 @@ import ( "github.com/cloudnative-pg/cloudnative-pg/pkg/specs" "github.com/cloudnative-pg/cloudnative-pg/pkg/utils" "github.com/cloudnative-pg/cloudnative-pg/tests" + testsUtils "github.com/cloudnative-pg/cloudnative-pg/tests/utils" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -59,7 +60,13 @@ var _ = Describe("Operator unavailable", Serial, Label(tests.LabelDisruptive, te // Load test data currentPrimary := clusterName + "-1" - AssertCreateTestData(env, namespace, clusterName, "test") + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: "test", + } + AssertCreateTestData(env, tableLocator) By("scaling down operator replicas to zero", func() { err := env.ScaleOperatorDeployment(0) @@ -120,10 +127,7 @@ var _ = Describe("Operator unavailable", Serial, Label(tests.LabelDisruptive, te return specs.IsPodStandby(pod), err }, timeout).Should(BeTrue()) }) - // Expect the test data previously created to be available - primary, err := env.GetClusterPrimary(namespace, clusterName) - Expect(err).ToNot(HaveOccurred()) - AssertDataExpectedCountWithDatabaseName(namespace, primary.Name, "app", "test", 2) + AssertDataExpectedCount(env, tableLocator, 2) }) }) @@ -140,7 +144,13 @@ var _ = Describe("Operator unavailable", Serial, Label(tests.LabelDisruptive, te // Load test data currentPrimary := clusterName + "-1" - AssertCreateTestData(env, namespace, clusterName, "test") + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: "test", + } + AssertCreateTestData(env, tableLocator) operatorNamespace, err := env.GetOperatorNamespaceName() Expect(err).ToNot(HaveOccurred()) @@ -211,10 +221,7 @@ var _ = Describe("Operator unavailable", Serial, Label(tests.LabelDisruptive, te return specs.IsPodStandby(pod), err }, timeout).Should(BeTrue()) }) - // Expect the test data previously created to be available - primary, err := env.GetClusterPrimary(namespace, clusterName) - Expect(err).ToNot(HaveOccurred()) - AssertDataExpectedCountWithDatabaseName(namespace, primary.Name, "app", "test", 2) + AssertDataExpectedCount(env, tableLocator, 2) }) }) }) diff --git a/tests/e2e/pg_basebackup_test.go b/tests/e2e/pg_basebackup_test.go index 59cb5542ad..6ec697fd4a 100644 --- a/tests/e2e/pg_basebackup_test.go +++ b/tests/e2e/pg_basebackup_test.go @@ -52,7 +52,13 @@ var _ = Describe("Bootstrap with pg_basebackup", Label(tests.LabelRecovery), fun srcClusterName, err = env.GetResourceNameFromYAML(srcCluster) Expect(err).ToNot(HaveOccurred()) AssertCreateCluster(namespace, srcClusterName, srcCluster, env) - AssertCreateTestData(env, namespace, srcClusterName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: srcClusterName, + DatabaseName: utils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) }) It("using basic authentication", func() { @@ -87,7 +93,13 @@ var _ = Describe("Bootstrap with pg_basebackup", Label(tests.LabelRecovery), fun }) By("checking data have been copied correctly", func() { - AssertDataExpectedCount(env, namespace, dstClusterName, tableName, 2) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: dstClusterName, + DatabaseName: utils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 2) }) By("writing some new data to the dst cluster", func() { @@ -99,6 +111,7 @@ var _ = Describe("Bootstrap with pg_basebackup", Label(tests.LabelRecovery), fun apiv1.ApplicationUserSecretSuffix, ) defer func() { + _ = conn.Close() forward.Close() }() Expect(err).ToNot(HaveOccurred()) @@ -106,7 +119,13 @@ var _ = Describe("Bootstrap with pg_basebackup", Label(tests.LabelRecovery), fun }) By("checking the src cluster was not modified", func() { - AssertDataExpectedCount(env, namespace, srcClusterName, tableName, 2) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: srcClusterName, + DatabaseName: utils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 2) }) }) @@ -119,7 +138,13 @@ var _ = Describe("Bootstrap with pg_basebackup", Label(tests.LabelRecovery), fun AssertClusterIsReady(namespace, dstClusterName, testTimeouts[utils.ClusterIsReadySlow], env) By("checking data have been copied correctly", func() { - AssertDataExpectedCount(env, namespace, dstClusterName, tableName, 2) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: dstClusterName, + DatabaseName: utils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 2) }) By("writing some new data to the dst cluster", func() { @@ -131,6 +156,7 @@ var _ = Describe("Bootstrap with pg_basebackup", Label(tests.LabelRecovery), fun apiv1.ApplicationUserSecretSuffix, ) defer func() { + _ = conn.Close() forward.Close() }() Expect(err).ToNot(HaveOccurred()) @@ -138,7 +164,13 @@ var _ = Describe("Bootstrap with pg_basebackup", Label(tests.LabelRecovery), fun }) By("checking the src cluster was not modified", func() { - AssertDataExpectedCount(env, namespace, srcClusterName, tableName, 2) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: srcClusterName, + DatabaseName: utils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 2) }) }) }) diff --git a/tests/e2e/pg_data_corruption_test.go b/tests/e2e/pg_data_corruption_test.go index 996e886f12..c8c6fbe321 100644 --- a/tests/e2e/pg_data_corruption_test.go +++ b/tests/e2e/pg_data_corruption_test.go @@ -58,7 +58,13 @@ var _ = Describe("PGDATA Corruption", Label(tests.LabelRecovery), Ordered, func( clusterName, err := env.GetResourceNameFromYAML(sampleFile) Expect(err).ToNot(HaveOccurred()) AssertCreateCluster(namespace, clusterName, sampleFile, env) - AssertCreateTestData(env, namespace, clusterName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testsUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) By("gathering current primary pod and pvc", func() { oldPrimaryPod, err := env.GetClusterPrimary(namespace, clusterName) @@ -187,7 +193,7 @@ var _ = Describe("PGDATA Corruption", Label(tests.LabelRecovery), Ordered, func( }, 300).Should(BeTrue()) }) AssertClusterIsReady(namespace, clusterName, testTimeouts[testsUtils.ClusterIsReadyQuick], env) - AssertDataExpectedCount(env, namespace, clusterName, tableName, 2) + AssertDataExpectedCount(env, tableLocator, 2) AssertClusterStandbysAreStreaming(namespace, clusterName, 120) } diff --git a/tests/e2e/replica_mode_cluster_test.go b/tests/e2e/replica_mode_cluster_test.go index 977b0a7daf..45998be4ae 100644 --- a/tests/e2e/replica_mode_cluster_test.go +++ b/tests/e2e/replica_mode_cluster_test.go @@ -33,7 +33,6 @@ import ( apiv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1" "github.com/cloudnative-pg/cloudnative-pg/pkg/reconciler/replicaclusterswitch" - "github.com/cloudnative-pg/cloudnative-pg/pkg/specs" "github.com/cloudnative-pg/cloudnative-pg/pkg/utils" "github.com/cloudnative-pg/cloudnative-pg/tests" testUtils "github.com/cloudnative-pg/cloudnative-pg/tests/utils" @@ -211,17 +210,35 @@ var _ = Describe("Replica Mode", Label(tests.LabelReplication), func() { }) By("creating a new data in the new source cluster", func() { - AssertCreateTestDataWithDatabaseName(env, namespace, clusterTwoName, sourceDBName, "new_test_table") + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterTwoName, + DatabaseName: sourceDBName, + TableName: "new_test_table", + } + AssertCreateTestData(env, tableLocator) + }) + + // The dst Cluster gets promoted to primary, hence the new appUser password will + // be updated to reflect its "-app" secret. + // We need to copy the password changes over to the src Cluster, which is now a Replica + // Cluster, in order to connect using the "-app" secret. + By("updating the appUser secret of the src cluster", func() { + _, appSecretPassword, err := testUtils.GetCredentials(clusterTwoName, namespace, + apiv1.ApplicationUserSecretSuffix, env) + Expect(err).ToNot(HaveOccurred()) + AssertUpdateSecret("password", appSecretPassword, clusterOneName+apiv1.ApplicationUserSecretSuffix, + namespace, clusterOneName, 30, env) }) By("checking that the data is present in the old src cluster", func() { - AssertDataExpectedCountWithDatabaseName( - namespace, - clusterOnePrimary.Name, - sourceDBName, - "new_test_table", - 2, - ) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterOneName, + DatabaseName: sourceDBName, + TableName: "new_test_table", + } + AssertDataExpectedCount(env, tableLocator, 2) }) }) }) @@ -261,13 +278,16 @@ var _ = Describe("Replica Mode", Label(tests.LabelReplication), func() { primaryReplicaCluster, err := env.GetClusterPrimary(replicaNamespace, replicaClusterName) Expect(err).ToNot(HaveOccurred()) - commandTimeout := time.Second * 10 - By("verify archive mode is set to 'always on' designated primary", func() { query := "show archive_mode;" Eventually(func() (string, error) { - stdOut, _, err := env.ExecCommand(env.Ctx, *primaryReplicaCluster, specs.PostgresContainerName, - &commandTimeout, "psql", "-U", "postgres", sourceDBName, "-tAc", query) + stdOut, _, err := env.ExecQueryInInstancePod( + testUtils.PodLocator{ + Namespace: primaryReplicaCluster.Namespace, + PodName: primaryReplicaCluster.Name, + }, + sourceDBName, + query) return strings.Trim(stdOut, "\n"), err }, 30).Should(BeEquivalentTo("always")) }) @@ -645,8 +665,13 @@ var _ = Describe("Replica switchover", Label(tests.LabelReplication), Ordered, f Consistently(func(g Gomega) { pod, err := env.GetClusterPrimary(namespace, clusterBName) g.Expect(err).ToNot(HaveOccurred()) - stdOut, _, err := env.ExecCommand(env.Ctx, *pod, specs.PostgresContainerName, ptr.To(time.Second*10), - "psql", "-U", "postgres", "postgres", "-tAc", "select pg_is_in_recovery();") + stdOut, _, err := env.ExecQueryInInstancePod( + testUtils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + testUtils.PostgresDBName, + "select pg_is_in_recovery();") g.Expect(err).ToNot(HaveOccurred()) g.Expect(strings.Trim(stdOut, "\n")).To(Equal("t")) }, 60, 10).Should(Succeed()) diff --git a/tests/e2e/replication_slot_test.go b/tests/e2e/replication_slot_test.go index 4a576de7bb..c57404f93f 100644 --- a/tests/e2e/replication_slot_test.go +++ b/tests/e2e/replication_slot_test.go @@ -109,10 +109,14 @@ var _ = Describe("Replication Slot", Label(tests.LabelReplication), func() { primaryPod, err := env.GetClusterPrimary(namespace, clusterName) Expect(err).ToNot(HaveOccurred()) - _, _, err = testsUtils.RunQueryFromPod(primaryPod, testsUtils.PGLocalSocketDir, - "app", "postgres", "''", - fmt.Sprintf("SELECT pg_create_physical_replication_slot('%s');", userPhysicalSlot), - env) + query := fmt.Sprintf("SELECT pg_create_physical_replication_slot('%s');", userPhysicalSlot) + _, _, err = env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: primaryPod.Namespace, + PodName: primaryPod.Name, + }, + testsUtils.PostgresDBName, + query) Expect(err).ToNot(HaveOccurred()) }) diff --git a/tests/e2e/tablespaces_test.go b/tests/e2e/tablespaces_test.go index b3093e5ab0..72987be873 100644 --- a/tests/e2e/tablespaces_test.go +++ b/tests/e2e/tablespaces_test.go @@ -361,7 +361,6 @@ var _ = Describe("Tablespaces tests", Label(tests.LabelTablespaces, tablespace2 = "tbs2" table2 = "test_tbs2" ) - checkPointTimeout := time.Second * 10 BeforeAll(func() { // Create a cluster in a namespace we'll delete after the test @@ -418,26 +417,34 @@ var _ = Describe("Tablespaces tests", Label(tests.LabelTablespaces, By("inserting test data and creating WALs on the cluster to be snapshotted", func() { // Create a table and insert data 1,2 in each tablespace tl1 := TableLocator{ - Namespace: namespace, - ClusterName: clusterName, - TableName: table1, - Tablespace: tablespace1, + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testUtils.AppDBName, + TableName: table1, + Tablespace: tablespace1, } - AssertCreateTestDataInTablespace(env, tl1) + AssertCreateTestData(env, tl1) tl2 := TableLocator{ - Namespace: namespace, - ClusterName: clusterName, - TableName: table2, - Tablespace: tablespace2, + Namespace: namespace, + ClusterName: clusterName, + DatabaseName: testUtils.AppDBName, + TableName: table2, + Tablespace: tablespace2, } - AssertCreateTestDataInTablespace(env, tl2) + AssertCreateTestData(env, tl2) primaryPod, err := env.GetClusterPrimary(namespace, clusterName) Expect(err).ToNot(HaveOccurred()) // Execute a checkpoint - _, _, err = env.EventuallyExecCommand( - env.Ctx, *primaryPod, specs.PostgresContainerName, &checkPointTimeout, - "psql", "-U", "postgres", "-tAc", "CHECKPOINT") + _, _, err = env.EventuallyExecQueryInInstancePod( + testUtils.PodLocator{ + Namespace: primaryPod.Namespace, + PodName: primaryPod.Name, + }, testUtils.PostgresDBName, + "CHECKPOINT", + RetryTimeout, + PollingTime, + ) Expect(err).ToNot(HaveOccurred()) }) @@ -510,8 +517,20 @@ var _ = Describe("Tablespaces tests", Label(tests.LabelTablespaces, }) By("verifying the correct data exists in the restored cluster", func() { - AssertDataExpectedCount(env, namespace, clusterToRestoreName, table1, 2) - AssertDataExpectedCount(env, namespace, clusterToRestoreName, table2, 2) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterToRestoreName, + DatabaseName: testUtils.AppDBName, + TableName: table1, + } + AssertDataExpectedCount(env, tableLocator, 2) + tableLocator = TableLocator{ + Namespace: namespace, + ClusterName: clusterToRestoreName, + DatabaseName: testUtils.AppDBName, + TableName: table2, + } + AssertDataExpectedCount(env, tableLocator, 2) }) }) @@ -526,6 +545,7 @@ var _ = Describe("Tablespaces tests", Label(tests.LabelTablespaces, apiv1.ApplicationUserSecretSuffix, ) defer func() { + _ = conn.Close() forward.Close() }() Expect(err).ToNot(HaveOccurred()) @@ -590,8 +610,20 @@ var _ = Describe("Tablespaces tests", Label(tests.LabelTablespaces, }) By("verifying the correct data exists in the restored cluster", func() { - AssertDataExpectedCount(env, namespace, clusterToPITRName, table1, 4) - AssertDataExpectedCount(env, namespace, clusterToPITRName, table2, 4) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterToPITRName, + DatabaseName: testUtils.AppDBName, + TableName: table1, + } + AssertDataExpectedCount(env, tableLocator, 4) + tableLocator = TableLocator{ + Namespace: namespace, + ClusterName: clusterToPITRName, + DatabaseName: testUtils.AppDBName, + TableName: table2, + } + AssertDataExpectedCount(env, tableLocator, 4) }) }) }) @@ -1004,7 +1036,7 @@ func AssertDatabaseContainsTablespaces(cluster *apiv1.Cluster, timeout int) { testUtils.PodLocator{ Namespace: namespace, PodName: instance.Name, - }, testUtils.DatabaseName("app"), + }, testUtils.AppDBName, "SELECT oid, spcname, pg_get_userbyid(spcowner) FROM pg_tablespace;", ) g.Expect(stdErr).To(BeEmpty()) @@ -1032,7 +1064,7 @@ func AssertTempTablespaceContent(cluster *apiv1.Cluster, timeout int, content st testUtils.PodLocator{ Namespace: namespace, PodName: primary.Name, - }, testUtils.DatabaseName("app"), + }, testUtils.AppDBName, "SHOW temp_tablespaces", ) g.Expect(stdErr).To(BeEmpty()) @@ -1057,7 +1089,7 @@ func AssertTempTablespaceBehavior(cluster *apiv1.Cluster, expectedTempTablespace testUtils.PodLocator{ Namespace: namespace, PodName: primary.Name, - }, testUtils.DatabaseName("app"), + }, testUtils.AppDBName, "CREATE TEMPORARY TABLE cnp_e2e_test_table (i INTEGER); "+ "SELECT spcname FROM pg_tablespace WHERE OID="+ "(SELECT reltablespace FROM pg_class WHERE oid = 'cnp_e2e_test_table'::regclass)", @@ -1079,7 +1111,7 @@ func AssertTablespaceAndOwnerExist(cluster *apiv1.Cluster, tablespace, owner str testUtils.PodLocator{ Namespace: namespace, PodName: primaryPod.Name, - }, testUtils.DatabaseName("app"), + }, testUtils.AppDBName, fmt.Sprintf("SELECT 1 FROM pg_tablespace WHERE spcname = '%s' AND pg_get_userbyid(spcowner) = '%s';", tablespace, owner), diff --git a/tests/e2e/update_user_test.go b/tests/e2e/update_user_test.go index 5d8455be05..d614e8ad75 100644 --- a/tests/e2e/update_user_test.go +++ b/tests/e2e/update_user_test.go @@ -126,6 +126,12 @@ var _ = Describe("Enable superuser password", Label(tests.LabelServiceConnectivi ) var namespace string + BeforeEach(func() { + if testLevelEnv.Depth < int(level) { + Skip("Test depth is lower than the amount requested for this test") + } + }) + It("enable and disable superuser access", func() { var err error // Create a cluster in a namespace we'll delete after the test @@ -152,13 +158,16 @@ var _ = Describe("Enable superuser password", Label(tests.LabelServiceConnectivi g.Expect(apierrors.IsNotFound(err)).To(BeTrue()) }, 200).Should(Succeed()) - timeout := time.Second * 10 - + query := "SELECT rolpassword IS NULL FROM pg_authid WHERE rolname='postgres'" // We should have the `postgres` user with a null password Eventually(func() string { - stdout, _, err := env.ExecCommand(env.Ctx, *primaryPod, specs.PostgresContainerName, &timeout, - "psql", "-U", "postgres", "-tAc", - "SELECT rolpassword IS NULL FROM pg_authid WHERE rolname='postgres'") + stdout, _, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: primaryPod.Namespace, + PodName: primaryPod.Name, + }, + testsUtils.PostgresDBName, + query) if err != nil { return "" } diff --git a/tests/e2e/upgrade_test.go b/tests/e2e/upgrade_test.go index f7182daecd..f0445d3506 100644 --- a/tests/e2e/upgrade_test.go +++ b/tests/e2e/upgrade_test.go @@ -35,7 +35,6 @@ import ( ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" apiv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1" - "github.com/cloudnative-pg/cloudnative-pg/pkg/specs" "github.com/cloudnative-pg/cloudnative-pg/tests" testsUtils "github.com/cloudnative-pg/cloudnative-pg/tests/utils" @@ -167,6 +166,8 @@ var _ = Describe("Upgrade", Label(tests.LabelUpgrade, tests.LabelNoOpenshift), O } AssertConfUpgrade := func(clusterName, upgradeNamespace string) { + databaseName := "appdb" + By("checking basic functionality performing a configuration upgrade on the cluster", func() { podList, err := env.GetClusterPodList(upgradeNamespace, clusterName) Expect(err).ToNot(HaveOccurred()) @@ -186,12 +187,16 @@ var _ = Describe("Upgrade", Label(tests.LabelUpgrade, tests.LabelNoOpenshift), O }, 60).ShouldNot(HaveOccurred()) timeout := 300 - commandTimeout := time.Second * 10 // Check that both parameters have been modified in each pod for _, pod := range podList.Items { Eventually(func() (int, error) { - stdout, stderr, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", "show max_replication_slots") + stdout, stderr, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + testsUtils.PostgresDBName, + "show max_replication_slots") if err != nil { return 0, err } @@ -204,8 +209,13 @@ var _ = Describe("Upgrade", Label(tests.LabelUpgrade, tests.LabelNoOpenshift), O "Pod %v should have updated its config", pod.Name) Eventually(func() (int, error, error) { - stdout, _, err := env.ExecCommand(env.Ctx, pod, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "-tAc", "show maintenance_work_mem") + stdout, _, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + testsUtils.PostgresDBName, + "show maintenance_work_mem") value, atoiErr := strconv.Atoi(strings.Trim(stdout, "MB\n")) return value, err, atoiErr }, timeout).Should(BeEquivalentTo(256), @@ -235,10 +245,16 @@ var _ = Describe("Upgrade", Label(tests.LabelUpgrade, tests.LabelNoOpenshift), O primary, err := env.GetClusterPrimary(upgradeNamespace, clusterName) Expect(err).ToNot(HaveOccurred()) - commandTimeout := time.Second * 10 query := "CREATE TABLE IF NOT EXISTS postswitch(i int);" - _, _, err = env.EventuallyExecCommand(env.Ctx, *primary, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "appdb", "-tAc", query) + _, _, err = env.EventuallyExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: primary.Namespace, + PodName: primary.Name, + }, testsUtils.DatabaseName(databaseName), + query, + RetryTimeout, + PollingTime, + ) Expect(err).ToNot(HaveOccurred()) for i := 1; i < 4; i++ { @@ -252,8 +268,13 @@ var _ = Describe("Upgrade", Label(tests.LabelUpgrade, tests.LabelNoOpenshift), O if err := env.Client.Get(env.Ctx, podNamespacedName, pod); err != nil { return "", err } - out, _, err := env.ExecCommand(env.Ctx, *pod, specs.PostgresContainerName, - &commandTimeout, "psql", "-U", "postgres", "appdb", "-tAc", + + out, _, err := env.ExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + testsUtils.DatabaseName(databaseName), "SELECT count(*) = 0 FROM postswitch") return strings.TrimSpace(out), err }, 240).Should(BeEquivalentTo("t"), @@ -448,6 +469,8 @@ var _ = Describe("Upgrade", Label(tests.LabelUpgrade, tests.LabelNoOpenshift), O } assertClustersWorkAfterOperatorUpgrade := func(upgradeNamespace, operatorManifest string) { + databaseName := "appdb" + // generate random serverNames for the clusters each time serverName1 := fmt.Sprintf("%s-%d", clusterName1, funk.RandomInt(0, 9999)) serverName2 := fmt.Sprintf("%s-%d", clusterName2, funk.RandomInt(0, 9999)) @@ -487,10 +510,16 @@ var _ = Describe("Upgrade", Label(tests.LabelUpgrade, tests.LabelNoOpenshift), O primary, err := env.GetClusterPrimary(upgradeNamespace, clusterName1) Expect(err).ToNot(HaveOccurred()) - commandTimeout := time.Second * 10 query := "CREATE TABLE IF NOT EXISTS to_restore AS VALUES (1),(2);" - _, _, err = env.EventuallyExecCommand(env.Ctx, *primary, specs.PostgresContainerName, &commandTimeout, - "psql", "-U", "postgres", "appdb", "-tAc", query) + _, _, err = env.EventuallyExecQueryInInstancePod( + testsUtils.PodLocator{ + Namespace: primary.Namespace, + PodName: primary.Name, + }, testsUtils.DatabaseName(databaseName), + query, + RetryTimeout, + PollingTime, + ) Expect(err).ToNot(HaveOccurred()) }) @@ -618,7 +647,7 @@ var _ = Describe("Upgrade", Label(tests.LabelUpgrade, tests.LabelNoOpenshift), O Namespace: upgradeNamespace, PodName: primary, }, - testsUtils.DatabaseName("appdb"), + testsUtils.DatabaseName(databaseName), "SELECT count(*) FROM to_restore") Expect(strings.Trim(out, "\n"), err).To(BeEquivalentTo("2")) @@ -631,7 +660,7 @@ var _ = Describe("Upgrade", Label(tests.LabelUpgrade, tests.LabelNoOpenshift), O Namespace: upgradeNamespace, PodName: primary, }, - testsUtils.DatabaseName("appdb"), + testsUtils.DatabaseName(databaseName), "select substring(pg_walfile_name(pg_current_wal_lsn()), 1, 8)") Expect(err).NotTo(HaveOccurred()) Expect(strconv.Atoi(strings.Trim(out, "\n"))).To( @@ -644,7 +673,7 @@ var _ = Describe("Upgrade", Label(tests.LabelUpgrade, tests.LabelNoOpenshift), O Namespace: upgradeNamespace, PodName: primary, }, - testsUtils.DatabaseName("appdb"), + testsUtils.DatabaseName(databaseName), "SELECT count(*) FROM pg_stat_replication") return strings.Trim(out, "\n"), err }, 180).Should(BeEquivalentTo("2")) diff --git a/tests/e2e/volume_snapshot_test.go b/tests/e2e/volume_snapshot_test.go index 55718ee38c..ff0b016ec0 100644 --- a/tests/e2e/volume_snapshot_test.go +++ b/tests/e2e/volume_snapshot_test.go @@ -242,7 +242,13 @@ var _ = Describe("Verify Volume Snapshot", By("inserting test data and creating WALs on the cluster to be snapshotted", func() { // Create a "test" table with values 1,2 - AssertCreateTestData(env, namespace, clusterToSnapshotName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterToSnapshotName, + DatabaseName: testUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) // Because GetCurrentTimestamp() rounds down to the second and is executed // right after the creation of the test data, we wait for 1s to avoid not @@ -262,6 +268,7 @@ var _ = Describe("Verify Volume Snapshot", apiv1.ApplicationUserSecretSuffix, ) defer func() { + _ = conn.Close() forward.Close() }() Expect(err).ToNot(HaveOccurred()) @@ -282,7 +289,13 @@ var _ = Describe("Verify Volume Snapshot", }) By("verifying the correct data exists in the restored cluster", func() { - AssertDataExpectedCount(env, namespace, clusterToRestoreName, tableName, 2) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterToRestoreName, + DatabaseName: testUtils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 2) }) }) }) @@ -366,7 +379,13 @@ var _ = Describe("Verify Volume Snapshot", It("can create a declarative cold backup and restoring using it", func() { By("inserting test data", func() { - AssertCreateTestData(env, namespace, clusterToBackupName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterToBackupName, + DatabaseName: testUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) }) backupName, err := env.GetResourceNameFromYAML(backupFileFilePath) @@ -426,7 +445,13 @@ var _ = Describe("Verify Volume Snapshot", }) By("checking that the data is present on the restored cluster", func() { - AssertDataExpectedCount(env, namespace, clusterToRestoreName, tableName, 2) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterToRestoreName, + DatabaseName: testUtils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 2) }) }) It("can take a snapshot targeting the primary", func() { @@ -615,11 +640,18 @@ var _ = Describe("Verify Volume Snapshot", apiv1.ApplicationUserSecretSuffix, ) defer func() { + _ = conn.Close() forward.Close() }() Expect(err).ToNot(HaveOccurred()) // Create a "test" table with values 1,2 - AssertCreateTestData(env, namespace, clusterToSnapshotName, tableName) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterToSnapshotName, + DatabaseName: testUtils.AppDBName, + TableName: tableName, + } + AssertCreateTestData(env, tableLocator) // Insert 2 more rows which we expect not to be present at the end of the recovery insertRecordIntoTable(tableName, 3, conn) @@ -684,7 +716,13 @@ var _ = Describe("Verify Volume Snapshot", }) By("verifying the correct data exists in the restored cluster", func() { - AssertDataExpectedCount(env, namespace, clusterToRestoreName, tableName, 4) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterToRestoreName, + DatabaseName: testUtils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 4) }) }) @@ -700,6 +738,7 @@ var _ = Describe("Verify Volume Snapshot", apiv1.ApplicationUserSecretSuffix, ) defer func() { + _ = conn.Close() forward.Close() }() Expect(err).ToNot(HaveOccurred()) @@ -740,8 +779,13 @@ var _ = Describe("Verify Volume Snapshot", podList, err := env.GetClusterReplicas(namespace, clusterToSnapshotName) Expect(err).ToNot(HaveOccurred()) Expect(podList.Items).To(HaveLen(2)) - AssertDataExpectedCount(env, namespace, clusterToSnapshotName, tableName, 6) - AssertDataExpectedCount(env, namespace, clusterToSnapshotName, tableName, 6) + tableLocator := TableLocator{ + Namespace: namespace, + ClusterName: clusterToSnapshotName, + DatabaseName: testUtils.AppDBName, + TableName: tableName, + } + AssertDataExpectedCount(env, tableLocator, 6) }) }) }) diff --git a/tests/utils/environment.go b/tests/utils/environment.go index 90e019327e..2596f87186 100644 --- a/tests/utils/environment.go +++ b/tests/utils/environment.go @@ -48,7 +48,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" apiv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1" - "github.com/cloudnative-pg/cloudnative-pg/pkg/specs" "github.com/cloudnative-pg/cloudnative-pg/pkg/utils" "github.com/cloudnative-pg/cloudnative-pg/pkg/versions" @@ -204,31 +203,6 @@ func (env TestingEnvironment) ExecCommand( pod, containerName, timeout, command...) } -// ExecCommandWithPsqlClient wraps the utils.ExecCommand pre-setting values and -// run query on psql client pod with rw service as host. -func (env TestingEnvironment) ExecCommandWithPsqlClient( - namespace, - clusterName string, - pod *corev1.Pod, - secretSuffix string, - dbname string, - query string, -) (string, string, error) { - timeout := time.Second * 10 - username, password, err := GetCredentials(clusterName, namespace, secretSuffix, &env) - if err != nil { - return "", "", err - } - rwService, err := GetRwServiceObject(namespace, clusterName, &env) - if err != nil { - return "", "", err - } - host := CreateServiceFQDN(namespace, rwService.GetName()) - dsn := CreateDSN(host, username, dbname, password, Prefer, 5432) - return utils.ExecCommand(env.Ctx, env.Interface, env.RestClientConfig, - *pod, specs.PostgresContainerName, &timeout, "psql", dsn, "-tAc", query) -} - // GetPVCList gathers the current list of PVCs in a namespace func (env TestingEnvironment) GetPVCList(namespace string) (*corev1.PersistentVolumeClaimList, error) { pvcList := &corev1.PersistentVolumeClaimList{} diff --git a/tests/utils/pod.go b/tests/utils/pod.go index f62b4fcba1..25841da6a1 100644 --- a/tests/utils/pod.go +++ b/tests/utils/pod.go @@ -33,6 +33,8 @@ import ( "github.com/cloudnative-pg/cloudnative-pg/pkg/specs" pkgutils "github.com/cloudnative-pg/cloudnative-pg/pkg/utils" + + . "github.com/onsi/gomega" // nolint ) // PodCreateAndWaitForReady creates a given pod object and wait for it to be ready @@ -246,3 +248,29 @@ func (env TestingEnvironment) ExecQueryInInstancePod( PodName: podLocator.PodName, }, &timeout, "psql", "-U", "postgres", string(dbname), "-tAc", query) } + +// EventuallyExecQueryInInstancePod wraps ExecQueryInInstancePod with an Eventually clause +func (env TestingEnvironment) EventuallyExecQueryInInstancePod( + podLocator PodLocator, + dbname DatabaseName, + query string, + retryTimeout int, + pollingTime int, +) (string, string, error) { + var stdOut, stdErr string + var err error + + Eventually(func() error { + stdOut, stdErr, err = env.ExecQueryInInstancePod( + PodLocator{ + Namespace: podLocator.Namespace, + PodName: podLocator.PodName, + }, dbname, query) + if err != nil { + return err + } + return nil + }, retryTimeout, pollingTime).Should(BeNil()) + + return stdOut, stdErr, err +} diff --git a/tests/utils/postgres.go b/tests/utils/postgres.go index e85f1bf573..9c4011c9f1 100644 --- a/tests/utils/postgres.go +++ b/tests/utils/postgres.go @@ -19,11 +19,8 @@ package utils import ( "strconv" "strings" - "time" corev1 "k8s.io/api/core/v1" - - "github.com/cloudnative-pg/cloudnative-pg/pkg/specs" ) const ( @@ -37,32 +34,22 @@ const ( AppDBName = "app" // PostgresDBName database name postgres PostgresDBName = "postgres" + // TablespaceDefaultName is the default tablespace location + TablespaceDefaultName = "pg_default" ) -// RunQueryFromPod executes a query from a pod to a host -func RunQueryFromPod( - connectingPod *corev1.Pod, - host string, - dbname string, - user string, - password string, - query string, - env *TestingEnvironment, -) (string, string, error) { - timeout := time.Second * 10 - dsn := CreateDSN(host, user, dbname, password, Prefer, 5432) - - stdout, stderr, err := env.EventuallyExecCommand(env.Ctx, *connectingPod, specs.PostgresContainerName, &timeout, - "psql", dsn, "-tAc", query) - return stdout, stderr, err -} - // CountReplicas counts the number of replicas attached to an instance func CountReplicas(env *TestingEnvironment, pod *corev1.Pod) (int, error) { query := "SELECT count(*) FROM pg_stat_replication" - commandTimeout := time.Second * 10 - stdOut, _, err := env.EventuallyExecCommand(env.Ctx, *pod, specs.PostgresContainerName, - &commandTimeout, "psql", "-U", "postgres", "app", "-tAc", query) + stdOut, _, err := env.EventuallyExecQueryInInstancePod( + PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, AppDBName, + query, + RetryTimeout, + PollingTime, + ) if err != nil { return 0, nil } diff --git a/tests/utils/psql_connection.go b/tests/utils/psql_connection.go index b88e07c50b..a0d8a7a1fb 100644 --- a/tests/utils/psql_connection.go +++ b/tests/utils/psql_connection.go @@ -200,7 +200,7 @@ func ForwardPSQLConnectionWithCreds( return forward, conn, err } -// RunQueryRowOverForward runs QueryRow with a given query, returning the result Row +// RunQueryRowOverForward runs QueryRow with a given query, returning the Row of the SQL command func RunQueryRowOverForward( env *TestingEnvironment, namespace, @@ -220,8 +220,36 @@ func RunQueryRowOverForward( return nil, err } defer func() { + _ = conn.Close() forward.Close() }() return conn.QueryRow(query), nil } + +// RunExecOverForward runs Exec with a given query, returning the Result of the SQL command +func RunExecOverForward( + env *TestingEnvironment, + namespace, + clusterName, + dbname, + secretSuffix, + query string, +) (sql.Result, error) { + forward, conn, err := ForwardPSQLConnection( + env, + namespace, + clusterName, + dbname, + secretSuffix, + ) + if err != nil { + return nil, err + } + defer func() { + _ = conn.Close() + forward.Close() + }() + + return conn.Exec(query) +} diff --git a/tests/utils/replication_slots.go b/tests/utils/replication_slots.go index 9279a01ce1..dab55b9e9e 100644 --- a/tests/utils/replication_slots.go +++ b/tests/utils/replication_slots.go @@ -54,13 +54,14 @@ func PrintReplicationSlots( } m := make(map[string]string) for _, slot := range slots { - restartLsn, _, err := RunQueryFromPod( - &podList.Items[i], PGLocalSocketDir, - "app", - "postgres", - "''", - fmt.Sprintf("SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = '%v'", slot), - env) + query := fmt.Sprintf("SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = '%v'", slot) + restartLsn, _, err := env.ExecQueryInInstancePod( + PodLocator{ + Namespace: podList.Items[i].Namespace, + PodName: podList.Items[i].Name, + }, + AppDBName, + query) if err != nil { output.WriteString(fmt.Sprintf("Couldn't retrieve restart_lsn for slot %v: %v\n", slot, err)) } @@ -125,9 +126,14 @@ func GetReplicationSlotsOnPod(namespace, podName string, env *TestingEnvironment return nil, err } - stdout, _, err := RunQueryFromPod(targetPod, PGLocalSocketDir, - "app", "postgres", "''", - "SELECT slot_name FROM pg_replication_slots WHERE temporary = 'f' AND slot_type = 'physical'", env) + query := "SELECT slot_name FROM pg_replication_slots WHERE temporary = 'f' AND slot_type = 'physical'" + stdout, _, err := env.ExecQueryInInstancePod( + PodLocator{ + Namespace: targetPod.Namespace, + PodName: targetPod.Name, + }, + AppDBName, + query) if err != nil { return nil, err } @@ -157,8 +163,13 @@ func GetReplicationSlotLsnsOnPod( for _, slot := range slots { query := fmt.Sprintf("SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = '%v'", slot) - restartLsn, _, err := RunQueryFromPod(&pod, PGLocalSocketDir, - "app", "postgres", "''", query, env) + restartLsn, _, err := env.ExecQueryInInstancePod( + PodLocator{ + Namespace: pod.Namespace, + PodName: pod.Name, + }, + AppDBName, + query) if err != nil { return nil, err }