From bdc2db97ac536763e0e5880671e98510ba75bb1b Mon Sep 17 00:00:00 2001 From: Murat Kabilov Date: Thu, 8 Jun 2017 10:58:48 +0200 Subject: [PATCH] Tests for Specs and Teams API --- pkg/spec/postgresql_test.go | 485 ++++++++++++++++++++++++++++++++++++ pkg/spec/types.go | 15 +- pkg/spec/types_test.go | 55 ++++ pkg/util/util_test.go | 118 +++++++++ 4 files changed, 668 insertions(+), 5 deletions(-) create mode 100644 pkg/spec/postgresql_test.go create mode 100644 pkg/spec/types_test.go create mode 100644 pkg/util/util_test.go diff --git a/pkg/spec/postgresql_test.go b/pkg/spec/postgresql_test.go new file mode 100644 index 000000000..48314d376 --- /dev/null +++ b/pkg/spec/postgresql_test.go @@ -0,0 +1,485 @@ +package spec + +import ( + "bytes" + "encoding/json" + "errors" + "reflect" + "testing" + "time" + + "k8s.io/client-go/pkg/api/unversioned" + "k8s.io/client-go/pkg/api/v1" +) + +var parseTimeTests = []struct { + in string + out time.Time + err error +}{ + {"16:08", mustParseTime("16:08"), nil}, + {"11:00", mustParseTime("11:00"), nil}, + {"23:59", mustParseTime("23:59"), nil}, + + {"26:09", time.Now(), errors.New(`parsing time "26:09": hour out of range`)}, + {"23:69", time.Now(), errors.New(`parsing time "23:69": minute out of range`)}, +} + +var parseWeekdayTests = []struct { + in string + out time.Weekday + err error +}{ + {"Wed", time.Wednesday, nil}, + {"Sunday", time.Weekday(0), errors.New("incorrect weekday")}, + {"", time.Weekday(0), errors.New("incorrect weekday")}, +} + +var clusterNames = []struct { + in string + inTeam string + clusterName string + err error +}{ + {"acid-test", "acid", "test", nil}, + {"test-my-name", "test", "my-name", nil}, + {"my-team-another-test", "my-team", "another-test", nil}, + {"------strange-team-cluster", "-----", "strange-team-cluster", nil}, + {"acid-test", "test", "", errors.New("name must match {TEAM}-{NAME} format")}, + {"-test", "", "", errors.New("team name is empty")}, + {"-test", "-", "", errors.New("name must match {TEAM}-{NAME} format")}, + {"", "-", "", errors.New("name is too short")}, + {"-", "-", "", errors.New("name is too short")}, +} + +var maintenanceWindows = []struct { + in []byte + out MaintenanceWindow + err error +}{{[]byte(`"Tue:10:00-20:00"`), + MaintenanceWindow{ + Everyday: false, + Weekday: time.Tuesday, + StartTime: mustParseTime("10:00"), + EndTime: mustParseTime("20:00"), + }, nil}, + {[]byte(`"Mon:10:00-10:00"`), + MaintenanceWindow{ + Everyday: false, + Weekday: time.Monday, + StartTime: mustParseTime("10:00"), + EndTime: mustParseTime("10:00"), + }, nil}, + {[]byte(`"Sun:00:00-00:00"`), + MaintenanceWindow{ + Everyday: false, + Weekday: time.Sunday, + StartTime: mustParseTime("00:00"), + EndTime: mustParseTime("00:00"), + }, nil}, + {[]byte(`"01:00-10:00"`), + MaintenanceWindow{ + Everyday: true, + Weekday: time.Sunday, + StartTime: mustParseTime("01:00"), + EndTime: mustParseTime("10:00"), + }, nil}, + {[]byte(`"Mon:12:00-11:00"`), MaintenanceWindow{}, errors.New(`'From' time must be prior to the 'To' time`)}, + {[]byte(`"Wed:33:00-00:00"`), MaintenanceWindow{}, errors.New(`could not parse start time: parsing time "33:00": hour out of range`)}, + {[]byte(`"Wed:00:00-26:00"`), MaintenanceWindow{}, errors.New(`could not parse end time: parsing time "26:00": hour out of range`)}, + {[]byte(`"Sunday:00:00-00:00"`), MaintenanceWindow{}, errors.New(`could not parse weekday: incorrect weekday`)}, + {[]byte(`":00:00-10:00"`), MaintenanceWindow{}, errors.New(`could not parse weekday: incorrect weekday`)}, + {[]byte(`"Mon:10:00-00:00"`), MaintenanceWindow{}, errors.New(`'From' time must be prior to the 'To' time`)}, + {[]byte(`"Mon:00:00:00-10:00:00"`), MaintenanceWindow{}, errors.New(`incorrect maintenance window format`)}, + {[]byte(`"Mon:00:00"`), MaintenanceWindow{}, errors.New("incorrect maintenance window format")}, + {[]byte(`"Mon:00:00-00:00:00"`), MaintenanceWindow{}, errors.New("could not parse end time: incorrect time format")}} + +var unmarshalCluster = []struct { + in []byte + out Postgresql + marshal []byte + err error +}{{ + []byte(`{ + "kind": "Postgresql","apiVersion": "acid.zalan.do/v1", + "metadata": {"name": "acid-testcluster1"}, "spec": {"teamId": 100}}`), + Postgresql{ + TypeMeta: unversioned.TypeMeta{ + Kind: "Postgresql", + APIVersion: "acid.zalan.do/v1", + }, + Metadata: v1.ObjectMeta{ + Name: "acid-testcluster1", + }, + Status: ClusterStatusInvalid, + Error: &json.UnmarshalTypeError{ + Value: "number", + Type: reflect.TypeOf(""), + Offset: 126, + Struct: "PostgresSpec", + Field: "teamId", + }, + }, + []byte(`{"kind":"Postgresql","apiVersion":"acid.zalan.do/v1","metadata":{"name":"acid-testcluster1","creationTimestamp":null},"spec":{"postgresql":{"version":"","parameters":null},"volume":{"size":"","storageClass":""},"patroni":{"initdb":null,"pg_hba":null,"ttl":0,"loop_wait":0,"retry_timeout":0,"maximum_lag_on_failover":0},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"","allowedSourceRanges":null,"numberOfInstances":0,"users":null},"status":"Invalid"}`), nil}, + {[]byte(`{ + "kind": "Postgresql", + "apiVersion": "acid.zalan.do/v1", + "metadata": { + "name": "acid-testcluster1" + }, + "spec": { + "teamId": "ACID", + "volume": { + "size": "5Gi", + "storageClass": "SSD" + }, + "numberOfInstances": 2, + "users": { + "zalando": [ + "superuser", + "createdb" + ] + }, + "allowedSourceRanges": [ + "127.0.0.1/32" + ], + "postgresql": { + "version": "9.6", + "parameters": { + "shared_buffers": "32MB", + "max_connections": "10", + "log_statement": "all" + } + }, + "resources": { + "requests": { + "cpu": "10m", + "memory": "50Mi" + }, + "limits": { + "cpu": "300m", + "memory": "3000Mi" + } + }, + "patroni": { + "initdb": { + "encoding": "UTF8", + "locale": "en_US.UTF-8", + "data-checksums": "true" + }, + "pg_hba": [ + "hostssl all all 0.0.0.0/0 md5", + "host all all 0.0.0.0/0 md5" + ], + "ttl": 30, + "loop_wait": 10, + "retry_timeout": 10, + "maximum_lag_on_failover": 33554432 + }, + "maintenanceWindows": [ + "Mon:01:00-06:00", + "Sat:00:00-04:00", + "05:00-05:15" + ] + } +}`), + Postgresql{ + TypeMeta: unversioned.TypeMeta{ + Kind: "Postgresql", + APIVersion: "acid.zalan.do/v1", + }, + Metadata: v1.ObjectMeta{ + Name: "acid-testcluster1", + }, + Spec: PostgresSpec{ + PostgresqlParam: PostgresqlParam{ + PgVersion: "9.6", + Parameters: map[string]string{ + "shared_buffers": "32MB", + "max_connections": "10", + "log_statement": "all", + }, + }, + Volume: Volume{ + Size: "5Gi", + StorageClass: "SSD", + }, + Patroni: Patroni{ + InitDB: map[string]string{ + "encoding": "UTF8", + "locale": "en_US.UTF-8", + "data-checksums": "true", + }, + PgHba: []string{"hostssl all all 0.0.0.0/0 md5", "host all all 0.0.0.0/0 md5"}, + TTL: 30, + LoopWait: 10, + RetryTimeout: 10, + MaximumLagOnFailover: 33554432, + }, + Resources: Resources{ + ResourceRequest: ResourceDescription{CPU: "10m", Memory: "50Mi"}, + ResourceLimits: ResourceDescription{CPU: "300m", Memory: "3000Mi"}, + }, + TeamID: "ACID", + AllowedSourceRanges: []string{"127.0.0.1/32"}, + NumberOfInstances: 2, + Users: map[string]UserFlags{"zalando": {"superuser", "createdb"}}, + MaintenanceWindows: []MaintenanceWindow{{ + Everyday: false, + Weekday: time.Monday, + StartTime: mustParseTime("01:00"), + EndTime: mustParseTime("06:00"), + }, { + Everyday: false, + Weekday: time.Saturday, + StartTime: mustParseTime("00:00"), + EndTime: mustParseTime("04:00"), + }, + { + Everyday: true, + Weekday: time.Sunday, + StartTime: mustParseTime("05:00"), + EndTime: mustParseTime("05:15"), + }, + }, + ClusterName: "testcluster1", + }, + Error: nil, + }, + []byte(`{"kind":"Postgresql","apiVersion":"acid.zalan.do/v1","metadata":{"name":"acid-testcluster1","creationTimestamp":null},"spec":{"postgresql":{"version":"9.6","parameters":{"log_statement":"all","max_connections":"10","shared_buffers":"32MB"}},"volume":{"size":"5Gi","storageClass":"SSD"},"patroni":{"initdb":{"data-checksums":"true","encoding":"UTF8","locale":"en_US.UTF-8"},"pg_hba":["hostssl all all 0.0.0.0/0 md5","host all all 0.0.0.0/0 md5"],"ttl":30,"loop_wait":10,"retry_timeout":10,"maximum_lag_on_failover":33554432},"resources":{"requests":{"cpu":"10m","memory":"50Mi"},"limits":{"cpu":"300m","memory":"3000Mi"}},"teamId":"ACID","allowedSourceRanges":["127.0.0.1/32"],"numberOfInstances":2,"users":{"zalando":["superuser","createdb"]},"maintenanceWindows":["Mon:01:00-06:00","Sat:00:00-04:00","05:00-05:15"]}}`), nil}, + { + []byte(`{"kind": "Postgresql","apiVersion": "acid.zalan.do/v1","metadata": {"name": "teapot-testcluster1"}, "spec": {"teamId": "acid"}}`), + Postgresql{ + TypeMeta: unversioned.TypeMeta{ + Kind: "Postgresql", + APIVersion: "acid.zalan.do/v1", + }, + Metadata: v1.ObjectMeta{ + Name: "teapot-testcluster1", + }, + Spec: PostgresSpec{TeamID: "acid"}, + Status: ClusterStatusInvalid, + Error: errors.New("name must match {TEAM}-{NAME} format"), + }, + []byte(`{"kind":"Postgresql","apiVersion":"acid.zalan.do/v1","metadata":{"name":"teapot-testcluster1","creationTimestamp":null},"spec":{"postgresql":{"version":"","parameters":null},"volume":{"size":"","storageClass":""},"patroni":{"initdb":null,"pg_hba":null,"ttl":0,"loop_wait":0,"retry_timeout":0,"maximum_lag_on_failover":0},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"acid","allowedSourceRanges":null,"numberOfInstances":0,"users":null},"status":"Invalid"}`), nil}, + {[]byte(`{"kind": "Postgresql","apiVersion": "acid.zalan.do/v1"`), + Postgresql{}, + []byte{}, + errors.New("unexpected end of JSON input")}, + {[]byte(`{"kind":"Postgresql","apiVersion":"acid.zalan.do/v1","metadata":{"name":"acid-testcluster","creationTimestamp":qaz},"spec":{"postgresql":{"version":"","parameters":null},"volume":{"size":"","storageClass":""},"patroni":{"initdb":null,"pg_hba":null,"ttl":0,"loop_wait":0,"retry_timeout":0,"maximum_lag_on_failover":0},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"acid","allowedSourceRanges":null,"numberOfInstances":0,"users":null},"status":"Invalid"}`), + Postgresql{}, + []byte{}, + errors.New("invalid character 'q' looking for beginning of value")}} + +var postgresqlList = []struct { + in []byte + out PostgresqlList + err error +}{ + {[]byte(`{"apiVersion":"v1","items":[{"apiVersion":"acid.zalan.do/v1","kind":"Postgresql","metadata":{"labels":{"team":"acid"},"name":"acid-testcluster42","namespace":"default","resourceVersion":"30446957","selfLink":"/apis/acid.zalan.do/v1/namespaces/default/postgresqls/acid-testcluster42","uid":"857cd208-33dc-11e7-b20a-0699041e4b03"},"spec":{"allowedSourceRanges":["185.85.220.0/22"],"numberOfInstances":1,"postgresql":{"version":"9.6"},"teamId":"acid","volume":{"size":"10Gi"}},"status":"Running"}],"kind":"List","metadata":{},"resourceVersion":"","selfLink":""}`), + PostgresqlList{ + TypeMeta: unversioned.TypeMeta{ + Kind: "List", + APIVersion: "v1", + }, + Items: []Postgresql{Postgresql{ + TypeMeta: unversioned.TypeMeta{ + Kind: "Postgresql", + APIVersion: "acid.zalan.do/v1", + }, + Metadata: v1.ObjectMeta{ + Name: "acid-testcluster42", + Namespace: "default", + Labels: map[string]string{"team": "acid"}, + ResourceVersion: "30446957", + SelfLink: "/apis/acid.zalan.do/v1/namespaces/default/postgresqls/acid-testcluster42", + UID: "857cd208-33dc-11e7-b20a-0699041e4b03", + }, + Spec: PostgresSpec{ + ClusterName: "testcluster42", + PostgresqlParam: PostgresqlParam{PgVersion: "9.6"}, + Volume: Volume{Size: "10Gi"}, + TeamID: "acid", + AllowedSourceRanges: []string{"185.85.220.0/22"}, + NumberOfInstances: 1, + }, + Status: ClusterStatusRunning, + Error: nil, + }}, + }, + nil}, + {[]byte(`{"apiVersion":"v1","items":[{"apiVersion":"acid.zalan.do/v1","kind":"Postgresql","metadata":{"labels":{"team":"acid"},"name":"acid-testcluster42","namespace"`), + PostgresqlList{}, + errors.New("unexpected end of JSON input")}} + +func mustParseTime(s string) time.Time { + v, err := time.Parse("15:04", s) + if err != nil { + panic(err) + } + + return v.UTC() +} + +func TestParseTime(t *testing.T) { + for _, tt := range parseTimeTests { + aTime, err := parseTime(tt.in) + if err != nil { + if err.Error() != tt.err.Error() { + t.Errorf("ParseTime expected error: %v, got: %v", tt.err, err) + } + + continue + } + + if aTime != tt.out { + t.Errorf("Expected time: %v, got: %v", tt.out, aTime) + } + } +} + +func TestWeekdayTime(t *testing.T) { + for _, tt := range parseWeekdayTests { + aTime, err := parseWeekday(tt.in) + if err != nil { + if err.Error() != tt.err.Error() { + t.Errorf("ParseWeekday expected error: %v, got: %v", tt.err, err) + } + + continue + } + + if aTime != tt.out { + t.Errorf("Expected weekday: %v, got: %v", tt.out, aTime) + } + } +} + +func TestClusterName(t *testing.T) { + for _, tt := range clusterNames { + name, err := extractClusterName(tt.in, tt.inTeam) + if err != nil && err.Error() != tt.err.Error() { + t.Errorf("extractClusterName expected error: %v, got: %v", tt.err, err) + continue + } + if name != tt.clusterName { + t.Errorf("Expected cluserName: %s, got: %s", tt.clusterName, name) + } + } +} + +func TestUnmarshalMaintenanceWindow(t *testing.T) { + for _, tt := range maintenanceWindows { + var m MaintenanceWindow + err := m.UnmarshalJSON(tt.in) + if err != nil && err.Error() != tt.err.Error() { + t.Errorf("MaintenanceWindow unmarshal expected error: %v, got %v", tt.err, err) + continue + } + if tt.err != nil && err == nil { + t.Errorf("Expected error") + continue + } + + if !reflect.DeepEqual(m, tt.out) { + t.Errorf("Expected maintenace window: %#v, got: %#v", tt.out, m) + } + } +} + +func TestMarshalMaintenanceWindow(t *testing.T) { + for _, tt := range maintenanceWindows { + if tt.err != nil { + continue + } + + s, err := tt.out.MarshalJSON() + if err != nil { + t.Errorf("Marshal Error: %v", err) + continue + } + + if !bytes.Equal(s, tt.in) { + t.Errorf("Expected Marshal: %s, got: %s", string(tt.in), string(s)) + } + } +} + +func TestPostgresUnmarshal(t *testing.T) { + for _, tt := range unmarshalCluster { + var cluster Postgresql + err := cluster.UnmarshalJSON(tt.in) + if err != nil { + if err.Error() != tt.err.Error() { + t.Errorf("Unmarshal expected error: %v, got: %v", tt.err, err) + } + + continue + } + + if !reflect.DeepEqual(cluster, tt.out) { + t.Errorf("Expected Postgresql: %#v, got %#v", tt.out, cluster) + } + } +} + +func TestMarshal(t *testing.T) { + for _, tt := range unmarshalCluster { + if tt.err != nil { + continue + } + + m, err := json.Marshal(tt.out) + if err != nil { + t.Errorf("Marshal error: %v", err) + continue + } + if !bytes.Equal(m, tt.marshal) { + t.Errorf("Marshal Postgresql expected: %s, got: %s", string(tt.marshal), string(m)) + } + } +} + +func TestPostgresMeta(t *testing.T) { + for _, tt := range unmarshalCluster { + if a := tt.out.GetObjectKind(); a != &tt.out.TypeMeta { + t.Errorf("GetObjectKindMeta expected: %v, got: %v", tt.out.TypeMeta, a) + } + + if a := tt.out.GetObjectMeta(); reflect.DeepEqual(a, tt.out.Metadata) { + t.Errorf("GetObjectMeta expected: %v, got: %v", tt.out.Metadata, a) + } + } +} + +func TestUnmarshalPostgresList(t *testing.T) { + for _, tt := range postgresqlList { + var list PostgresqlList + err := list.UnmarshalJSON(tt.in) + if err != nil && err.Error() != tt.err.Error() { + t.Errorf("PostgresqlList unmarshal expected error: %v, got: %v", tt.err, err) + return + } + if !reflect.DeepEqual(list, tt.out) { + t.Errorf("Postgresql list unmarshall expected: %#v, got: %#v", tt.out, list) + } + } +} + +func TestPostgresListMeta(t *testing.T) { + for _, tt := range postgresqlList { + if tt.err != nil { + continue + } + + if a := tt.out.GetObjectKind(); a != &tt.out.TypeMeta { + t.Errorf("GetObjectKindMeta expected: %v, got: %v", tt.out.TypeMeta, a) + } + + if a := tt.out.GetListMeta(); reflect.DeepEqual(a, tt.out.Metadata) { + t.Errorf("GetObjectMeta expected: %v, got: %v", tt.out.Metadata, a) + } + + return + } +} diff --git a/pkg/spec/types.go b/pkg/spec/types.go index 720bffcd0..9d189d906 100644 --- a/pkg/spec/types.go +++ b/pkg/spec/types.go @@ -2,6 +2,8 @@ package spec import ( "database/sql" + "fmt" + "strings" "k8s.io/client-go/pkg/api/v1" "k8s.io/client-go/pkg/types" @@ -72,10 +74,6 @@ type UserSyncer interface { } func (n NamespacedName) String() string { - if n.Namespace == "" && n.Name == "" { - return "" - } - return types.NamespacedName(n).String() } @@ -87,9 +85,16 @@ func (n NamespacedName) MarshalJSON() ([]byte, error) { // Decode converts a (possibly unqualified) string into the namespaced name object. func (n *NamespacedName) Decode(value string) error { name := types.NewNamespacedNameFromString(value) - if value != "" && name == (types.NamespacedName{}) { + + if strings.Trim(value, string(types.Separator)) != "" && name == (types.NamespacedName{}) { name.Name = value name.Namespace = v1.NamespaceDefault + } else if name.Namespace == "" { + name.Namespace = v1.NamespaceDefault + } + + if name.Name == "" { + return fmt.Errorf("Incorrect namespaced name") } *n = NamespacedName(name) diff --git a/pkg/spec/types_test.go b/pkg/spec/types_test.go new file mode 100644 index 000000000..b690586e9 --- /dev/null +++ b/pkg/spec/types_test.go @@ -0,0 +1,55 @@ +package spec + +import ( + "bytes" + "testing" +) + +var nnTests = []struct { + s string + expected NamespacedName + expectedMarshal []byte +}{ + {`acid/cluster`, NamespacedName{Namespace: "acid", Name: "cluster"}, []byte(`"acid/cluster"`)}, + {`/name`, NamespacedName{Namespace: "default", Name: "name"}, []byte(`"default/name"`)}, + {`test`, NamespacedName{Namespace: "default", Name: "test"}, []byte(`"default/test"`)}, +} + +var nnErr = []string{"test/", "/", "", "//"} + +func TestNamespacedNameDecode(t *testing.T) { + for _, tt := range nnTests { + var actual NamespacedName + err := actual.Decode(tt.s) + if err != nil { + t.Errorf("Decode error: %v", err) + } + if actual != tt.expected { + t.Errorf("Expected: %v, got %#v", tt.expected, actual) + } + } +} + +func TestNamespacedNameMarshal(t *testing.T) { + for _, tt := range nnTests { + var actual NamespacedName + + m, err := actual.MarshalJSON() + if err != nil { + t.Errorf("Marshal error: %v", err) + } + if bytes.Equal(m, tt.expectedMarshal) { + t.Errorf("Expected marshal: %v, got %#v", tt.expected, actual) + } + } +} + +func TestNamespacedNameError(t *testing.T) { + for _, tt := range nnErr { + var actual NamespacedName + err := actual.Decode(tt) + if err == nil { + t.Errorf("Error expected for '%s', got: %#v", tt, actual) + } + } +} diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go new file mode 100644 index 000000000..ddf42760f --- /dev/null +++ b/pkg/util/util_test.go @@ -0,0 +1,118 @@ +package util + +import ( + "fmt" + "reflect" + "testing" + + "k8s.io/client-go/pkg/api/v1" + + "github.com/zalando-incubator/postgres-operator/pkg/spec" +) + +var pgUsers = []struct { + in spec.PgUser + out string +}{{spec.PgUser{ + Name: "test", + Password: "password", + Flags: []string{}, + MemberOf: []string{}}, + "md587f77988ccb5aa917c93201ba314fcd4"}, + {spec.PgUser{ + Name: "test", + Password: "md592f413f3974bdf3799bb6fecb5f9f2c6", + Flags: []string{}, + MemberOf: []string{}}, + "md592f413f3974bdf3799bb6fecb5f9f2c6"}} + +var prettyTest = []struct { + in interface{} + out string +}{ + {pgUsers, `[{{test password [] []} md587f77988ccb5aa917c93201ba314fcd4} {{test md592f413f3974bdf3799bb6fecb5f9f2c6 [] []} md592f413f3974bdf3799bb6fecb5f9f2c6}]`}, +} + +var prettyDiffTest = []struct { + inA interface{} + inB interface{} + out string +}{ + {[]int{1, 2, 3, 4}, []int{1, 2, 3}, "[]int[4] != []int[3]"}, + {[]int{1, 2, 3, 4}, []int{1, 2, 3, 4}, ""}, +} + +var substractTest = []struct { + inA []string + inB []string + out []string + outEqual bool +}{ + {[]string{"a", "b", "c", "d"}, []string{"a", "b", "c", "d"}, []string{}, true}, + {[]string{"a", "b", "c", "d"}, []string{"a", "bb", "c", "d"}, []string{"b"}, false}, +} + +func TestRandomPassword(t *testing.T) { + const pwdLength = 10 + pwd := RandomPassword(pwdLength) + if a := len(pwd); a != pwdLength { + t.Errorf("Password length expected: %d, got: %d", pwdLength, a) + } +} + +func TestNameFromMeta(t *testing.T) { + meta := v1.ObjectMeta{ + Name: "testcluster", + Namespace: "default", + } + + expected := spec.NamespacedName{ + Name: "testcluster", + Namespace: "default", + } + + actual := NameFromMeta(meta) + if actual != expected { + t.Errorf("NameFromMeta expected: %#v, got: %#v", expected, actual) + } +} + +func TestPGUserPassword(t *testing.T) { + for _, tt := range pgUsers { + pwd := PGUserPassword(tt.in) + if pwd != tt.out { + t.Errorf("PgUserPassword expected: %s, got: %s", tt.out, pwd) + } + } +} + +func TestPretty(t *testing.T) { + for _, tt := range prettyTest { + if actual := Pretty(tt.in); fmt.Sprintf("%v", actual) != tt.out { + t.Errorf("Pretty expected: %s, got: %s", tt.out, actual) + } + } +} + +func TestPrettyDiff(t *testing.T) { + for _, tt := range prettyDiffTest { + if actual := PrettyDiff(tt.inA, tt.inB); actual != tt.out { + t.Errorf("PrettyDiff expected: %s, got: %s", tt.out, actual) + } + } +} + +func TestSubstractSlices(t *testing.T) { + for _, tt := range substractTest { + actualRes, actualEqual := SubstractStringSlices(tt.inA, tt.inB) + if actualEqual != tt.outEqual { + t.Errorf("SubstractStringSlices expected equal: %t, got: %t", tt.outEqual, actualEqual) + } + + if len(actualRes) == 0 && len(tt.out) == 0 { + continue + } else if !reflect.DeepEqual(actualRes, tt.out) { + t.Errorf("SubstractStringSlices expected res: %v, got: %v", tt.out, actualRes) + } + } +}