test/extended/image_ecosystem/postgresql_replica.go
7d11aa91
 package image_ecosystem
30feb2b0
 
 import (
 	"fmt"
 	"time"
 
 	g "github.com/onsi/ginkgo"
 	o "github.com/onsi/gomega"
 
91e0c151
 	templateapi "github.com/openshift/origin/pkg/template/api"
30feb2b0
 	exutil "github.com/openshift/origin/test/extended/util"
c4311221
 	"github.com/openshift/origin/test/extended/util/db"
30feb2b0
 	testutil "github.com/openshift/origin/test/util"
f638b86d
 
 	kapi "k8s.io/kubernetes/pkg/api"
97e6f1de
 	kcoreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned"
30feb2b0
 )
 
 var (
507221e9
 	postgreSQLReplicationTemplate = "https://raw.githubusercontent.com/sclorg/postgresql-container/master/examples/replica/postgresql_replica.json"
30feb2b0
 	postgreSQLEphemeralTemplate   = exutil.FixturePath("..", "..", "examples", "db-templates", "postgresql-ephemeral-template.json")
 	postgreSQLHelperName          = "postgresql-helper"
 	postgreSQLImages              = []string{
2563840d
 		"postgresql:9.2",
 		"postgresql:9.4",
 		"postgresql:9.5",
30feb2b0
 	}
 )
 
7d11aa91
 var _ = g.Describe("[LocalNode][image_ecosystem][postgresql][Slow] openshift postgresql replication", func() {
30feb2b0
 	defer g.GinkgoRecover()
 
 	for i, image := range postgreSQLImages {
 		oc := exutil.NewCLI(fmt.Sprintf("postgresql-replication-%d", i), exutil.KubeConfigPath())
 		testFn := PostgreSQLReplicationTestFactory(oc, image)
 		g.It(fmt.Sprintf("postgresql replication works for %s", image), testFn)
 	}
 })
 
 // CreatePostgreSQLReplicationHelpers creates a set of PostgreSQL helpers for master,
 // slave an en extra helper that is used for remote login test.
97e6f1de
 func CreatePostgreSQLReplicationHelpers(c kcoreclient.PodInterface, masterDeployment, slaveDeployment, helperDeployment string, slaveCount int) (exutil.Database, []exutil.Database, exutil.Database) {
30feb2b0
 	podNames, err := exutil.WaitForPods(c, exutil.ParseLabelsOrDie(fmt.Sprintf("deployment=%s", masterDeployment)), exutil.CheckPodIsRunningFn, 1, 2*time.Minute)
 	o.Expect(err).NotTo(o.HaveOccurred())
 	masterPod := podNames[0]
 
 	slavePods, err := exutil.WaitForPods(c, exutil.ParseLabelsOrDie(fmt.Sprintf("deployment=%s", slaveDeployment)), exutil.CheckPodIsRunningFn, slaveCount, 3*time.Minute)
 	o.Expect(err).NotTo(o.HaveOccurred())
 
 	// Create PostgreSQL helper for master
c4311221
 	master := db.NewPostgreSQL(masterPod, "")
30feb2b0
 
 	// Create PostgreSQL helpers for slaves
 	slaves := make([]exutil.Database, len(slavePods))
 	for i := range slavePods {
c4311221
 		slave := db.NewPostgreSQL(slavePods[i], masterPod)
30feb2b0
 		slaves[i] = slave
 	}
 
64f6714d
 	helperNames, err := exutil.WaitForPods(c, exutil.ParseLabelsOrDie(fmt.Sprintf("deployment=%s", helperDeployment)), exutil.CheckPodIsRunningFn, 1, 1*time.Minute)
30feb2b0
 	o.Expect(err).NotTo(o.HaveOccurred())
c4311221
 	helper := db.NewPostgreSQL(helperNames[0], masterPod)
30feb2b0
 
 	return master, slaves, helper
 }
 
 func PostgreSQLReplicationTestFactory(oc *exutil.CLI, image string) func() {
 	return func() {
 		oc.SetOutputDir(exutil.TestContext.OutputDir)
 		defer cleanup(oc)
 
97e6f1de
 		_, err := exutil.SetupHostPathVolumes(oc.AdminKubeClient().Core().PersistentVolumes(), oc.Namespace(), "512Mi", 1)
30feb2b0
 		o.Expect(err).NotTo(o.HaveOccurred())
 
97e6f1de
 		err = testutil.WaitForPolicyUpdate(oc.Client(), oc.Namespace(), "create", templateapi.Resource("templates"), true)
30feb2b0
 		o.Expect(err).NotTo(o.HaveOccurred())
 
28270502
 		exutil.CheckOpenShiftNamespaceImageStreams(oc)
2563840d
 		err = oc.Run("new-app").Args("-f", postgreSQLReplicationTemplate, "-p", fmt.Sprintf("IMAGESTREAMTAG=%s", image)).Execute()
30feb2b0
 		o.Expect(err).NotTo(o.HaveOccurred())
 
 		err = oc.Run("new-app").Args("-f", postgreSQLEphemeralTemplate, "-p", fmt.Sprintf("DATABASE_SERVICE_NAME=%s", postgreSQLHelperName)).Execute()
 		o.Expect(err).NotTo(o.HaveOccurred())
d9d00195
 
 		// oc.KubeFramework().WaitForAnEndpoint currently will wait forever;  for now, prefacing with our WaitForADeploymentToComplete,
 		// which does have a timeout, since in most cases a failure in the service coming up stems from a failed deployment
97e6f1de
 		err = exutil.WaitForADeploymentToComplete(oc.KubeClient().Core().ReplicationControllers(oc.Namespace()), postgreSQLHelperName, oc)
d9d00195
 		o.Expect(err).NotTo(o.HaveOccurred())
 
30feb2b0
 		err = oc.KubeFramework().WaitForAnEndpoint(postgreSQLHelperName)
 		o.Expect(err).NotTo(o.HaveOccurred())
 
 		tableCounter := 0
 		assertReplicationIsWorking := func(masterDeployment, slaveDeployment string, slaveCount int) (exutil.Database, []exutil.Database, exutil.Database) {
befe04f1
 			check := func(err error) {
 				if err != nil {
 					exutil.DumpDeploymentLogs("postgresql-master", oc)
 					exutil.DumpDeploymentLogs("postgresql-slave", oc)
 				}
 				o.Expect(err).NotTo(o.HaveOccurred())
 			}
 
30feb2b0
 			tableCounter++
 			table := fmt.Sprintf("table_%0.2d", tableCounter)
 
97e6f1de
 			master, slaves, helper := CreatePostgreSQLReplicationHelpers(oc.KubeClient().Core().Pods(oc.Namespace()), masterDeployment, slaveDeployment, fmt.Sprintf("%s-1", postgreSQLHelperName), slaveCount)
28270502
 			err := exutil.WaitUntilAllHelpersAreUp(oc, []exutil.Database{master, helper})
 			if err != nil {
befe04f1
 				exutil.DumpDeploymentLogs("postgresql-master", oc)
28270502
 				exutil.DumpDeploymentLogs("postgresql-helper", oc)
 			}
 			o.Expect(err).NotTo(o.HaveOccurred())
befe04f1
 
28270502
 			err = exutil.WaitUntilAllHelpersAreUp(oc, slaves)
befe04f1
 			check(err)
30feb2b0
 
 			// Test if we can query as admin
 			oc.KubeFramework().WaitForAnEndpoint("postgresql-master")
28270502
 			err = helper.TestRemoteLogin(oc, "postgresql-master")
befe04f1
 			check(err)
30feb2b0
 
 			// Create a new table with random name
 			_, err = master.Query(oc, fmt.Sprintf("CREATE TABLE %s (col1 VARCHAR(20), col2 VARCHAR(20));", table))
befe04f1
 			check(err)
30feb2b0
 
 			// Write new data to the table through master
 			_, err = master.Query(oc, fmt.Sprintf("INSERT INTO %s (col1, col2) VALUES ('val1', 'val2');", table))
befe04f1
 			check(err)
30feb2b0
 
 			// Make sure data is present on master
1d0348b8
 			err = exutil.WaitForQueryOutputContains(oc, master, 10*time.Second, false,
30feb2b0
 				fmt.Sprintf("SELECT * FROM %s;", table),
 				"col1 | val1\ncol2 | val2")
befe04f1
 			check(err)
30feb2b0
 
 			// Make sure data was replicated to all slaves
 			for _, slave := range slaves {
1d0348b8
 				err = exutil.WaitForQueryOutputContains(oc, slave, 90*time.Second, false,
30feb2b0
 					fmt.Sprintf("SELECT * FROM %s;", table),
 					"col1 | val1\ncol2 | val2")
befe04f1
 				check(err)
30feb2b0
 			}
 
 			return master, slaves, helper
 		}
 
 		g.By("after initial deployment")
 		master, _, _ := assertReplicationIsWorking("postgresql-master-1", "postgresql-slave-1", 1)
 
 		g.By("after master is restarted by changing the Deployment Config")
 		err = oc.Run("env").Args("dc", "postgresql-master", "POSTGRESQL_ADMIN_PASSWORD=newpass").Execute()
 		o.Expect(err).NotTo(o.HaveOccurred())
97e6f1de
 		err = exutil.WaitUntilPodIsGone(oc.KubeClient().Core().Pods(oc.Namespace()), master.PodName(), 1*time.Minute)
30feb2b0
 		master, _, _ = assertReplicationIsWorking("postgresql-master-2", "postgresql-slave-1", 1)
 
 		g.By("after master is restarted by deleting the pod")
 		err = oc.Run("delete").Args("pod", "-l", "deployment=postgresql-master-2").Execute()
 		o.Expect(err).NotTo(o.HaveOccurred())
97e6f1de
 		err = exutil.WaitUntilPodIsGone(oc.KubeClient().Core().Pods(oc.Namespace()), master.PodName(), 1*time.Minute)
30feb2b0
 		o.Expect(err).NotTo(o.HaveOccurred())
 		_, slaves, _ := assertReplicationIsWorking("postgresql-master-2", "postgresql-slave-1", 1)
 
 		g.By("after slave is restarted by deleting the pod")
 		err = oc.Run("delete").Args("pod", "-l", "deployment=postgresql-slave-1").Execute()
 		o.Expect(err).NotTo(o.HaveOccurred())
97e6f1de
 		err = exutil.WaitUntilPodIsGone(oc.KubeClient().Core().Pods(oc.Namespace()), slaves[0].PodName(), 1*time.Minute)
30feb2b0
 		o.Expect(err).NotTo(o.HaveOccurred())
 		assertReplicationIsWorking("postgresql-master-2", "postgresql-slave-1", 1)
 
97e6f1de
 		pods, err := oc.KubeClient().Core().Pods(oc.Namespace()).List(kapi.ListOptions{LabelSelector: exutil.ParseLabelsOrDie("deployment=postgresql-slave-1")})
30feb2b0
 		o.Expect(err).NotTo(o.HaveOccurred())
 		o.Expect(len(pods.Items)).To(o.Equal(1))
 
 		g.By("after slave is scaled to 0 and then back to 4 replicas")
 		err = oc.Run("scale").Args("dc", "postgresql-slave", "--replicas=0").Execute()
 		o.Expect(err).NotTo(o.HaveOccurred())
97e6f1de
 		err = exutil.WaitUntilPodIsGone(oc.KubeClient().Core().Pods(oc.Namespace()), pods.Items[0].Name, 1*time.Minute)
30feb2b0
 		o.Expect(err).NotTo(o.HaveOccurred())
 		err = oc.Run("scale").Args("dc", "postgresql-slave", "--replicas=4").Execute()
 		o.Expect(err).NotTo(o.HaveOccurred())
 		assertReplicationIsWorking("postgresql-master-2", "postgresql-slave-1", 4)
 	}
 }