-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: customize workload deserialization and serialization by type (#456
) #### What type of PR is this? /kind feature #### What this PR does / why we need it: Customize workload deserialization and serialization by type.
- Loading branch information
Showing
5 changed files
with
151 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,70 @@ | ||
package workload | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
) | ||
|
||
type WorkloadType string | ||
|
||
const ( | ||
WorkloadTypeJob = "Job" | ||
WorkloadTypeService = "Service" | ||
) | ||
|
||
type WorkloadHeader struct { | ||
Type WorkloadType `yaml:"_type" json:"_type"` | ||
} | ||
|
||
type Workload struct { | ||
Type WorkloadType `yaml:"type" json:"type"` | ||
*Service `yaml:",inline" json:",inline"` | ||
*Job `yaml:",inline" json:",inline"` | ||
WorkloadHeader `yaml:",inline" json:",inline"` | ||
*Service `yaml:",inline" json:",inline"` | ||
*Job `yaml:",inline" json:",inline"` | ||
} | ||
|
||
func (w Workload) MarshalJSON() ([]byte, error) { | ||
switch w.Type { | ||
case WorkloadTypeService: | ||
return json.Marshal(struct { | ||
WorkloadHeader `yaml:",inline" json:",inline"` | ||
*Service `json:",inline"` | ||
}{ | ||
WorkloadHeader: WorkloadHeader{w.Type}, | ||
Service: w.Service, | ||
}) | ||
case WorkloadTypeJob: | ||
return json.Marshal(struct { | ||
WorkloadHeader `yaml:",inline" json:",inline"` | ||
*Job `json:",inline"` | ||
}{ | ||
WorkloadHeader: WorkloadHeader{w.Type}, | ||
Job: w.Job, | ||
}) | ||
default: | ||
return nil, errors.New("unknown workload type") | ||
} | ||
} | ||
|
||
func (w *Workload) UnmarshalJSON(data []byte) error { | ||
var workloadData WorkloadHeader | ||
err := json.Unmarshal(data, &workloadData) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
w.Type = workloadData.Type | ||
switch w.Type { | ||
case WorkloadTypeJob: | ||
var v Job | ||
err = json.Unmarshal(data, &v) | ||
w.Job = &v | ||
case WorkloadTypeService: | ||
var v Service | ||
err = json.Unmarshal(data, &v) | ||
w.Service = &v | ||
default: | ||
err = errors.New("unknown workload type") | ||
} | ||
|
||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package workload | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
"testing" | ||
) | ||
|
||
func TestWorkload_MarshalJSON(t *testing.T) { | ||
workload := Workload{ | ||
WorkloadHeader: WorkloadHeader{ | ||
Type: WorkloadTypeService, | ||
}, | ||
Service: &Service{ | ||
WorkloadBase: WorkloadBase{ | ||
Replicas: 2, | ||
Labels: map[string]string{ | ||
"app": "my-service", | ||
}, | ||
}, | ||
}, | ||
Job: &Job{ | ||
Schedule: "* * * * *", | ||
}, | ||
} | ||
|
||
expected := `{"_type":"Service","replicas":2,"labels":{"app":"my-service"}}` | ||
|
||
data, err := json.Marshal(workload) | ||
if err != nil { | ||
t.Errorf("Error while marshaling workload: %v", err) | ||
} | ||
|
||
if string(data) != expected { | ||
t.Errorf("Expected marshaled JSON: %s, got: %s", expected, string(data)) | ||
} | ||
} | ||
|
||
func TestWorkload_UnmarshalJSON(t *testing.T) { | ||
jsonData := `{"_type":"Service","replicas":1,"labels":{},"annotations":{},"dirs":{},"schedule":"* * * * *"}` | ||
expected := Workload{ | ||
WorkloadHeader: WorkloadHeader{ | ||
Type: WorkloadTypeService, | ||
}, | ||
Service: &Service{ | ||
WorkloadBase: WorkloadBase{ | ||
Replicas: 1, | ||
Labels: map[string]string{}, | ||
Annotations: map[string]string{}, | ||
Dirs: map[string]string{}, | ||
}, | ||
}, | ||
} | ||
|
||
var actual Workload | ||
err := json.Unmarshal([]byte(jsonData), &actual) | ||
if err != nil { | ||
t.Errorf("Error while unmarshaling JSON: %v", err) | ||
} | ||
|
||
if actual.Type != expected.Type { | ||
t.Errorf("Expected workload type: %s, got: %s", expected.Type, actual.Type) | ||
} | ||
|
||
if actual.Service == nil { | ||
t.Errorf("Expected service is not nil, got: %v", expected.Service) | ||
} | ||
|
||
if actual.Job != nil { | ||
t.Errorf("Expected job is nil, got: %v", expected.Job) | ||
} | ||
} | ||
|
||
func TestWorkload_UnmarshalJSON_UnknownType(t *testing.T) { | ||
jsonData := `{"_type":"Unknown","replicas":1,"labels":{},"annotations":{},"dirs":{},"schedule":"* * * * *"}` | ||
|
||
var workload Workload | ||
err := json.Unmarshal([]byte(jsonData), &workload) | ||
if err == nil { | ||
t.Error("Expected error for unknown workload type") | ||
} | ||
|
||
expectedError := errors.New("unknown workload type") | ||
if err.Error() != expectedError.Error() { | ||
t.Errorf("Expected error: %v, got: %v", expectedError, err) | ||
} | ||
} |