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