add Unmarshal method and tests for PostgresStatus
This commit is contained in:
parent
c3834df57a
commit
e2e2441ee1
|
|
@ -69,6 +69,31 @@ func (m *MaintenanceWindow) UnmarshalJSON(data []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON converts a JSON to the status subresource definition.
|
||||||
|
func (ps *PostgresStatus) UnmarshalJSON(data []byte) error {
|
||||||
|
var got PostgresStatus
|
||||||
|
|
||||||
|
str := string(data)
|
||||||
|
str = strings.Replace(str, "{", "", -1)
|
||||||
|
str = strings.Replace(str, "}", "", -1)
|
||||||
|
str = strings.Replace(str, "\"", "", -1)
|
||||||
|
parts := strings.Split(str, ":")
|
||||||
|
|
||||||
|
if len(parts) == 2 || len(parts) == 3 {
|
||||||
|
if parts[1] != "" {
|
||||||
|
got.PostgresClusterStatus = parts[len(parts)-1]
|
||||||
|
} else {
|
||||||
|
got.PostgresClusterStatus = ClusterStatusUnknown
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("incorrect status field of CR")
|
||||||
|
}
|
||||||
|
|
||||||
|
*ps = got
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// UnmarshalJSON converts a JSON into the PostgreSQL object.
|
// UnmarshalJSON converts a JSON into the PostgreSQL object.
|
||||||
func (p *Postgresql) UnmarshalJSON(data []byte) error {
|
func (p *Postgresql) UnmarshalJSON(data []byte) error {
|
||||||
var tmp postgresqlCopy
|
var tmp postgresqlCopy
|
||||||
|
|
|
||||||
|
|
@ -130,5 +130,5 @@ type UserFlags []string
|
||||||
|
|
||||||
// PostgresStatus contains status of the PostgreSQL cluster (running, creation failed etc.)
|
// PostgresStatus contains status of the PostgreSQL cluster (running, creation failed etc.)
|
||||||
type PostgresStatus struct {
|
type PostgresStatus struct {
|
||||||
PostgresClusterStatus string `json:"PostgresClusterStatus,omitempty"`
|
PostgresClusterStatus string `json:"PostgresClusterStatus"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,5 +97,5 @@ func (postgresStatus PostgresStatus) Running() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (postgresStatus PostgresStatus) String() string {
|
func (postgresStatus PostgresStatus) String() string {
|
||||||
return string(postgresStatus.PostgresClusterStatus)
|
return fmt.Sprintf(`status=%s`, postgresStatus.PostgresClusterStatus)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -111,12 +111,48 @@ var maintenanceWindows = []struct {
|
||||||
{[]byte(`"Mon: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")}}
|
{[]byte(`"Mon:00:00-00:00:00"`), MaintenanceWindow{}, errors.New("could not parse end time: incorrect time format")}}
|
||||||
|
|
||||||
|
var postgresStatus = []struct {
|
||||||
|
in []byte
|
||||||
|
out PostgresStatus
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
{[]byte(`"status":"Running"`),
|
||||||
|
PostgresStatus{PostgresClusterStatus: ClusterStatusRunning}, nil},
|
||||||
|
{[]byte(`"status":{"PostgresClusterStatus":"Running"}`),
|
||||||
|
PostgresStatus{PostgresClusterStatus: ClusterStatusRunning}, nil},
|
||||||
|
{[]byte(`"status":""`),
|
||||||
|
PostgresStatus{PostgresClusterStatus: ClusterStatusUnknown}, nil},
|
||||||
|
{[]byte(`"status":{}`),
|
||||||
|
PostgresStatus{PostgresClusterStatus: ClusterStatusUnknown}, nil},
|
||||||
|
{[]byte(`"status":`),
|
||||||
|
PostgresStatus{PostgresClusterStatus: ClusterStatusUnknown}, nil}}
|
||||||
|
|
||||||
var unmarshalCluster = []struct {
|
var unmarshalCluster = []struct {
|
||||||
in []byte
|
in []byte
|
||||||
out Postgresql
|
out Postgresql
|
||||||
marshal []byte
|
marshal []byte
|
||||||
err error
|
err error
|
||||||
}{
|
}{
|
||||||
|
// example with simple status field
|
||||||
|
{
|
||||||
|
in: []byte(`{
|
||||||
|
"kind": "Postgresql","apiVersion": "acid.zalan.do/v1",
|
||||||
|
"metadata": {"name": "acid-testcluster1"}, "spec": {"teamId": 100}}`),
|
||||||
|
out: Postgresql{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
Kind: "Postgresql",
|
||||||
|
APIVersion: "acid.zalan.do/v1",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "acid-testcluster1",
|
||||||
|
},
|
||||||
|
Status: PostgresStatus{PostgresClusterStatus: ClusterStatusInvalid},
|
||||||
|
// This error message can vary between Go versions, so compute it for the current version.
|
||||||
|
Error: json.Unmarshal([]byte(`{"teamId": 0}`), &PostgresSpec{}).Error(),
|
||||||
|
},
|
||||||
|
marshal: []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,"slots":null},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"","allowedSourceRanges":null,"numberOfInstances":0,"users":null,"clone":{}},"status":"Invalid"}`),
|
||||||
|
err: nil},
|
||||||
|
// example with /status subresource
|
||||||
{
|
{
|
||||||
in: []byte(`{
|
in: []byte(`{
|
||||||
"kind": "Postgresql","apiVersion": "acid.zalan.do/v1",
|
"kind": "Postgresql","apiVersion": "acid.zalan.do/v1",
|
||||||
|
|
@ -135,6 +171,7 @@ var unmarshalCluster = []struct {
|
||||||
},
|
},
|
||||||
marshal: []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,"slots":null},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"","allowedSourceRanges":null,"numberOfInstances":0,"users":null,"clone":{}},"status":{"PostgresClusterStatus":"Invalid"}}`),
|
marshal: []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,"slots":null},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"","allowedSourceRanges":null,"numberOfInstances":0,"users":null,"clone":{}},"status":{"PostgresClusterStatus":"Invalid"}}`),
|
||||||
err: nil},
|
err: nil},
|
||||||
|
// example with detailed input manifest
|
||||||
{
|
{
|
||||||
in: []byte(`{
|
in: []byte(`{
|
||||||
"kind": "Postgresql",
|
"kind": "Postgresql",
|
||||||
|
|
@ -276,8 +313,9 @@ var unmarshalCluster = []struct {
|
||||||
},
|
},
|
||||||
Error: "",
|
Error: "",
|
||||||
},
|
},
|
||||||
marshal: []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,"slots":{"permanent_logical_1":{"database":"foo","plugin":"pgoutput","type":"logical"}}},"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"],"clone":{"cluster":"acid-batman"}},"status":{}}`),
|
marshal: []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,"slots":{"permanent_logical_1":{"database":"foo","plugin":"pgoutput","type":"logical"}}},"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"],"clone":{"cluster":"acid-batman"}},"status":{"PostgresClusterStatus":""}}`),
|
||||||
err: nil},
|
err: nil},
|
||||||
|
// example with teamId set in input
|
||||||
{
|
{
|
||||||
in: []byte(`{"kind": "Postgresql","apiVersion": "acid.zalan.do/v1","metadata": {"name": "teapot-testcluster1"}, "spec": {"teamId": "acid"}}`),
|
in: []byte(`{"kind": "Postgresql","apiVersion": "acid.zalan.do/v1","metadata": {"name": "teapot-testcluster1"}, "spec": {"teamId": "acid"}}`),
|
||||||
out: Postgresql{
|
out: Postgresql{
|
||||||
|
|
@ -294,6 +332,7 @@ var unmarshalCluster = []struct {
|
||||||
},
|
},
|
||||||
marshal: []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,"slots":null},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"acid","allowedSourceRanges":null,"numberOfInstances":0,"users":null,"clone":{}},"status":{"PostgresClusterStatus":"Invalid"}}`),
|
marshal: []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,"slots":null},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"acid","allowedSourceRanges":null,"numberOfInstances":0,"users":null,"clone":{}},"status":{"PostgresClusterStatus":"Invalid"}}`),
|
||||||
err: nil},
|
err: nil},
|
||||||
|
// clone example
|
||||||
{
|
{
|
||||||
in: []byte(`{"kind": "Postgresql","apiVersion": "acid.zalan.do/v1","metadata": {"name": "acid-testcluster1"}, "spec": {"teamId": "acid", "clone": {"cluster": "team-batman"}}}`),
|
in: []byte(`{"kind": "Postgresql","apiVersion": "acid.zalan.do/v1","metadata": {"name": "acid-testcluster1"}, "spec": {"teamId": "acid", "clone": {"cluster": "team-batman"}}}`),
|
||||||
out: Postgresql{
|
out: Postgresql{
|
||||||
|
|
@ -313,8 +352,9 @@ var unmarshalCluster = []struct {
|
||||||
},
|
},
|
||||||
Error: "",
|
Error: "",
|
||||||
},
|
},
|
||||||
marshal: []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,"slots":null},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"acid","allowedSourceRanges":null,"numberOfInstances":0,"users":null,"clone":{"cluster":"team-batman"}},"status":{}}`),
|
marshal: []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,"slots":null},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"acid","allowedSourceRanges":null,"numberOfInstances":0,"users":null,"clone":{"cluster":"team-batman"}},"status":{"PostgresClusterStatus":""}}`),
|
||||||
err: nil},
|
err: nil},
|
||||||
|
// erroneous examples
|
||||||
{
|
{
|
||||||
in: []byte(`{"kind": "Postgresql","apiVersion": "acid.zalan.do/v1"`),
|
in: []byte(`{"kind": "Postgresql","apiVersion": "acid.zalan.do/v1"`),
|
||||||
out: Postgresql{},
|
out: Postgresql{},
|
||||||
|
|
@ -479,6 +519,25 @@ func TestMarshalMaintenanceWindow(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalPostgresStatus(t *testing.T) {
|
||||||
|
for _, tt := range postgresStatus {
|
||||||
|
var ps PostgresStatus
|
||||||
|
err := ps.UnmarshalJSON(tt.in)
|
||||||
|
if err != nil {
|
||||||
|
if tt.err == nil || err.Error() != tt.err.Error() {
|
||||||
|
t.Errorf("CR status unmarshal expected error: %v, got %v", tt.err, err)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
//} else if tt.err != nil {
|
||||||
|
//t.Errorf("Expected error: %v", tt.err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(ps, tt.out) {
|
||||||
|
t.Errorf("Expected status: %#v, got: %#v", tt.out, ps)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPostgresUnmarshal(t *testing.T) {
|
func TestPostgresUnmarshal(t *testing.T) {
|
||||||
for _, tt := range unmarshalCluster {
|
for _, tt := range unmarshalCluster {
|
||||||
var cluster Postgresql
|
var cluster Postgresql
|
||||||
|
|
@ -504,12 +563,23 @@ func TestMarshal(t *testing.T) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unmarshal and marshal example to capture api changes
|
||||||
|
var cluster Postgresql
|
||||||
|
err := cluster.UnmarshalJSON(tt.marshal)
|
||||||
|
if err != nil {
|
||||||
|
if tt.err == nil || err.Error() != tt.err.Error() {
|
||||||
|
t.Errorf("Unmarshal expected error: %v, got: %v", tt.err, err)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
expected, err := json.Marshal(cluster)
|
||||||
|
|
||||||
m, err := json.Marshal(tt.out)
|
m, err := json.Marshal(tt.out)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Marshal error: %v", err)
|
t.Errorf("Marshal error: %v", err)
|
||||||
}
|
}
|
||||||
if !bytes.Equal(m, tt.marshal) {
|
if !bytes.Equal(m, expected) {
|
||||||
t.Errorf("Marshal Postgresql \nexpected: %q, \ngot: %q", string(tt.marshal), string(m))
|
t.Errorf("Marshal Postgresql \nexpected: %q, \ngot: %q", string(expected), string(m))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue