Skip to content

Commit f67ea1d

Browse files
authored
Unit tests for training job (#121)
Description of changes: - Sdk.go coverage 70.1% - Custom code coverage > 80% By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent ad35f5a commit f67ea1d

30 files changed

+3090
-20
lines changed

pkg/resource/training_job/manager_test_suite_test.go

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,22 @@ import (
1717
"errors"
1818
"fmt"
1919

20+
"path/filepath"
21+
"testing"
22+
2023
ackv1alpha1 "github.com/aws-controllers-k8s/runtime/apis/core/v1alpha1"
2124
ackmetrics "github.com/aws-controllers-k8s/runtime/pkg/metrics"
2225
acktypes "github.com/aws-controllers-k8s/runtime/pkg/types"
26+
svcapitypes "github.com/aws-controllers-k8s/sagemaker-controller/apis/v1alpha1"
2327
"github.com/aws-controllers-k8s/sagemaker-controller/pkg/testutil"
2428
mocksvcsdkapi "github.com/aws-controllers-k8s/sagemaker-controller/test/mocks/aws-sdk-go/sagemaker"
2529
svcsdk "github.com/aws/aws-sdk-go/service/sagemaker"
30+
2631
"github.com/ghodss/yaml"
2732
"github.com/google/go-cmp/cmp"
2833
"github.com/google/go-cmp/cmp/cmpopts"
2934
"go.uber.org/zap/zapcore"
30-
"path/filepath"
3135
ctrlrtzap "sigs.k8s.io/controller-runtime/pkg/log/zap"
32-
"testing"
3336
)
3437

3538
// provideResourceManagerWithMockSDKAPI accepts MockSageMakerAPI and returns pointer to resourceManager
@@ -100,15 +103,30 @@ func (d *testRunnerDelegate) Equal(a acktypes.AWSResource, b acktypes.AWSResourc
100103
ac := a.(*resource)
101104
bc := b.(*resource)
102105
// Ignore LastTransitionTime since it gets updated each run.
103-
opts := []cmp.Option{cmpopts.EquateEmpty(), cmpopts.IgnoreFields(ackv1alpha1.Condition{}, "LastTransitionTime")}
106+
opts := []cmp.Option{cmpopts.EquateEmpty(),
107+
cmpopts.IgnoreFields(ackv1alpha1.Condition{}, "LastTransitionTime"),
108+
cmpopts.IgnoreFields(svcapitypes.ProfilerRuleEvaluationStatus{}, "LastModifiedTime"),
109+
cmpopts.IgnoreFields(svcapitypes.DebugRuleEvaluationStatus{}, "LastModifiedTime")}
104110

111+
var specMatch = false
112+
if cmp.Equal(ac.ko.Spec, bc.ko.Spec, opts...) {
113+
specMatch = true
114+
} else {
115+
fmt.Printf("Difference ko.Spec (-expected +actual):\n\n")
116+
fmt.Println(cmp.Diff(ac.ko.Spec, bc.ko.Spec, opts...))
117+
specMatch = false
118+
}
119+
120+
var statusMatch = false
105121
if cmp.Equal(ac.ko.Status, bc.ko.Status, opts...) {
106-
return true
122+
statusMatch = true
107123
} else {
108-
fmt.Printf("Difference (-expected +actual):\n\n")
124+
fmt.Printf("Difference ko.Status (-expected +actual):\n\n")
109125
fmt.Println(cmp.Diff(ac.ko.Status, bc.ko.Status, opts...))
110-
return false
126+
statusMatch = false
111127
}
128+
129+
return statusMatch && specMatch
112130
}
113131

114132
// Checks to see if the given yaml file, with name stored as expectation,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"TrainingJobArn": "arn:aws:sagemaker:us-west-2:123456789012:training-job/xgboost-training-job"
3+
}
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
{
2+
"AlgorithmSpecification": {
3+
"AlgorithmName": null,
4+
"EnableSageMakerMetricsTimeSeries": false,
5+
"MetricDefinitions": [
6+
{
7+
"Name": "train:mae",
8+
"Regex": ".*\\[[0-9]+\\].*#011train-mae:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
9+
},
10+
{
11+
"Name": "validation:auc",
12+
"Regex": ".*\\[[0-9]+\\].*#011validation-auc:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
13+
},
14+
{
15+
"Name": "train:merror",
16+
"Regex": ".*\\[[0-9]+\\].*#011train-merror:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
17+
},
18+
{
19+
"Name": "train:auc",
20+
"Regex": ".*\\[[0-9]+\\].*#011train-auc:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
21+
},
22+
{
23+
"Name": "validation:mae",
24+
"Regex": ".*\\[[0-9]+\\].*#011validation-mae:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
25+
},
26+
{
27+
"Name": "validation:error",
28+
"Regex": ".*\\[[0-9]+\\].*#011validation-error:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
29+
},
30+
{
31+
"Name": "validation:merror",
32+
"Regex": ".*\\[[0-9]+\\].*#011validation-merror:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
33+
},
34+
{
35+
"Name": "validation:logloss",
36+
"Regex": ".*\\[[0-9]+\\].*#011validation-logloss:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
37+
},
38+
{
39+
"Name": "train:rmse",
40+
"Regex": ".*\\[[0-9]+\\].*#011train-rmse:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
41+
},
42+
{
43+
"Name": "train:logloss",
44+
"Regex": ".*\\[[0-9]+\\].*#011train-logloss:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
45+
},
46+
{
47+
"Name": "train:mlogloss",
48+
"Regex": ".*\\[[0-9]+\\].*#011train-mlogloss:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
49+
},
50+
{
51+
"Name": "validation:rmse",
52+
"Regex": ".*\\[[0-9]+\\].*#011validation-rmse:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
53+
},
54+
{
55+
"Name": "validation:ndcg",
56+
"Regex": ".*\\[[0-9]+\\].*#011validation-ndcg:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
57+
},
58+
{
59+
"Name": "train:error",
60+
"Regex": ".*\\[[0-9]+\\].*#011train-error:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
61+
},
62+
{
63+
"Name": "validation:mlogloss",
64+
"Regex": ".*\\[[0-9]+\\].*#011validation-mlogloss:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
65+
},
66+
{
67+
"Name": "train:ndcg",
68+
"Regex": ".*\\[[0-9]+\\].*#011train-ndcg:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
69+
},
70+
{
71+
"Name": "train:map",
72+
"Regex": ".*\\[[0-9]+\\].*#011train-map:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
73+
},
74+
{
75+
"Name": "validation:map",
76+
"Regex": ".*\\[[0-9]+\\].*#011validation-map:([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?).*"
77+
}
78+
],
79+
"TrainingImage": "433757028032.dkr.ecr.us-west-2.amazonaws.com/xgboost:1",
80+
"TrainingInputMode": "File"
81+
},
82+
"AutoMLJobArn": null,
83+
"BillableTimeInSeconds": null,
84+
"CheckpointConfig": null,
85+
"CreationTime": "2021-10-12T05:49:40.493Z",
86+
"DebugHookConfig": null,
87+
"DebugRuleConfigurations": null,
88+
"DebugRuleEvaluationStatuses": null,
89+
"EnableInterContainerTrafficEncryption": false,
90+
"EnableManagedSpotTraining": false,
91+
"EnableNetworkIsolation": false,
92+
"Environment": null,
93+
"ExperimentConfig": null,
94+
"FailureReason": null,
95+
"FinalMetricDataList": null,
96+
"HyperParameters": {
97+
"eta": "0.2",
98+
"gamma": "4",
99+
"max_depth": "5",
100+
"min_child_weight": "6",
101+
"num_class": "10",
102+
"num_round": "10",
103+
"objective": "multi:softmax",
104+
"silent": "0"
105+
},
106+
"InputDataConfig": [
107+
{
108+
"ChannelName": "train",
109+
"CompressionType": "None",
110+
"ContentType": "text/csv",
111+
"DataSource": {
112+
"FileSystemDataSource": null,
113+
"S3DataSource": {
114+
"AttributeNames": null,
115+
"S3DataDistributionType": "FullyReplicated",
116+
"S3DataType": "S3Prefix",
117+
"S3Uri": "s3://source-data-bucket-592697580195-us-west-2/sagemaker/training/train"
118+
}
119+
},
120+
"InputMode": null,
121+
"RecordWrapperType": "None",
122+
"ShuffleConfig": null
123+
},
124+
{
125+
"ChannelName": "validation",
126+
"CompressionType": "None",
127+
"ContentType": "text/csv",
128+
"DataSource": {
129+
"FileSystemDataSource": null,
130+
"S3DataSource": {
131+
"AttributeNames": null,
132+
"S3DataDistributionType": "FullyReplicated",
133+
"S3DataType": "S3Prefix",
134+
"S3Uri": "s3://source-data-bucket-592697580195-us-west-2/sagemaker/training/validation"
135+
}
136+
},
137+
"InputMode": null,
138+
"RecordWrapperType": "None",
139+
"ShuffleConfig": null
140+
}
141+
],
142+
"LabelingJobArn": null,
143+
"LastModifiedTime": "2021-10-12T05:52:46.108Z",
144+
"ModelArtifacts": null,
145+
"OutputDataConfig": {
146+
"KmsKeyId": "",
147+
"S3OutputPath": "s3://source-data-bucket-592697580195-us-west-2/sagemaker/training/output"
148+
},
149+
"ProfilerConfig": null,
150+
"ProfilerRuleConfigurations": null,
151+
"ProfilerRuleEvaluationStatuses": null,
152+
"ProfilingStatus": "Disabled",
153+
"ResourceConfig": {
154+
"InstanceCount": 1,
155+
"InstanceType": "ml.m4.xlarge",
156+
"VolumeKmsKeyId": null,
157+
"VolumeSizeInGB": 5
158+
},
159+
"RoleArn": "arn:aws:iam::123456789012:role/service-role/AmazonSageMaker",
160+
"SecondaryStatus": "Downloading",
161+
"SecondaryStatusTransitions": [
162+
{
163+
"EndTime": "2021-10-12T05:52:46.108Z",
164+
"StartTime": "2021-10-12T05:49:40.493Z",
165+
"Status": "Starting",
166+
"StatusMessage": "Preparing the instances for training"
167+
},
168+
{
169+
"EndTime": null,
170+
"StartTime": "2021-10-12T05:52:46.108Z",
171+
"Status": "Downloading",
172+
"StatusMessage": "Downloading input data"
173+
}
174+
],
175+
"StoppingCondition": {
176+
"MaxRuntimeInSeconds": 86400,
177+
"MaxWaitTimeInSeconds": null
178+
},
179+
"TensorBoardOutputConfig": null,
180+
"TrainingEndTime": null,
181+
"TrainingJobArn": "arn:aws:sagemaker:us-west-2:123456789012:training-job/xgboost-training-jobsa",
182+
"TrainingJobName": "xgboost-training-jobsa",
183+
"TrainingJobStatus": "InProgress",
184+
"TrainingStartTime": "2021-10-12T05:52:46.108Z",
185+
"TrainingTimeInSeconds": 31,
186+
"TuningJobArn": null,
187+
"VpcConfig": null
188+
}

0 commit comments

Comments
 (0)