Skip to content

Commit e7294af

Browse files
authored
unit-tests for pipeline-execution resource (#183)
1 parent 4780720 commit e7294af

25 files changed

+840
-108
lines changed

apis/v1alpha1/generator.yaml

+54-54
Original file line numberDiff line numberDiff line change
@@ -23,60 +23,6 @@ operations:
2323
operation_type: Delete
2424
resource_name: PipelineExecution
2525
resources:
26-
PipelineExecution:
27-
# Resource state/status can have automatic retry-policy
28-
# Need to reconcile to catch these state/status changes
29-
reconcile:
30-
requeue_on_success_seconds: 60
31-
hooks:
32-
sdk_read_one_pre_set_output:
33-
code: rm.customSetSpec(ko,resp)
34-
sdk_read_one_post_set_output:
35-
code: rm.customSetOutput(&resource{ko})
36-
sdk_delete_pre_build_request:
37-
template_path: pipeline_execution/sdk_delete_pre_build_request.go.tpl
38-
sdk_delete_post_request:
39-
template_path: common/sdk_delete_post_request.go.tpl
40-
sdk_update_post_set_output:
41-
code: rm.customSetOutput(&resource{ko})
42-
fields:
43-
PipelineExecutionStatus:
44-
is_read_only: true
45-
print:
46-
name: STATUS
47-
from:
48-
operation: DescribePipelineExecution
49-
path: PipelineExecutionStatus
50-
FailureReason:
51-
is_read_only: true
52-
print:
53-
name: FAILURE-REASON
54-
priority: 1
55-
from:
56-
operation: DescribePipelineExecution
57-
path: FailureReason
58-
CreationTime:
59-
is_read_only: true
60-
from:
61-
operation: DescribePipelineExecution
62-
path: CreationTime
63-
LastModifiedTime:
64-
is_read_only: true
65-
from:
66-
operation: DescribePipelineExecution
67-
path: LastModifiedTime
68-
exceptions:
69-
errors:
70-
404:
71-
code: ResourceNotFound
72-
message_suffix: does not exist
73-
terminal_codes:
74-
- InvalidParameterCombination
75-
- InvalidParameterValue
76-
- MissingParameter
77-
- ResourceNotFound
78-
tags:
79-
ignore: true
8026
Model:
8127
hooks:
8228
delta_pre_compare:
@@ -949,6 +895,60 @@ resources:
949895
- InvalidParameterValue
950896
- MissingParameter
951897
- ResourceNotFound
898+
PipelineExecution:
899+
# Resource state/status can have automatic retry-policy
900+
# Need to reconcile to catch these state/status changes
901+
reconcile:
902+
requeue_on_success_seconds: 60
903+
hooks:
904+
sdk_read_one_pre_set_output:
905+
code: rm.customSetSpec(ko,resp)
906+
sdk_read_one_post_set_output:
907+
code: rm.customSetOutput(&resource{ko})
908+
sdk_delete_pre_build_request:
909+
template_path: pipeline_execution/sdk_delete_pre_build_request.go.tpl
910+
sdk_delete_post_request:
911+
template_path: common/sdk_delete_post_request.go.tpl
912+
sdk_update_post_set_output:
913+
code: rm.customSetOutput(&resource{ko})
914+
fields:
915+
PipelineExecutionStatus:
916+
is_read_only: true
917+
print:
918+
name: STATUS
919+
from:
920+
operation: DescribePipelineExecution
921+
path: PipelineExecutionStatus
922+
FailureReason:
923+
is_read_only: true
924+
print:
925+
name: FAILURE-REASON
926+
priority: 1
927+
from:
928+
operation: DescribePipelineExecution
929+
path: FailureReason
930+
CreationTime:
931+
is_read_only: true
932+
from:
933+
operation: DescribePipelineExecution
934+
path: CreationTime
935+
LastModifiedTime:
936+
is_read_only: true
937+
from:
938+
operation: DescribePipelineExecution
939+
path: LastModifiedTime
940+
exceptions:
941+
errors:
942+
404:
943+
code: ResourceNotFound
944+
message_suffix: does not exist
945+
terminal_codes:
946+
- InvalidParameterCombination
947+
- InvalidParameterValue
948+
- MissingParameter
949+
- ResourceNotFound
950+
tags:
951+
ignore: true
952952
ignore:
953953
resource_names:
954954
- Algorithm

generator.yaml

+54-54
Original file line numberDiff line numberDiff line change
@@ -23,60 +23,6 @@ operations:
2323
operation_type: Delete
2424
resource_name: PipelineExecution
2525
resources:
26-
PipelineExecution:
27-
# Resource state/status can have automatic retry-policy
28-
# Need to reconcile to catch these state/status changes
29-
reconcile:
30-
requeue_on_success_seconds: 60
31-
hooks:
32-
sdk_read_one_pre_set_output:
33-
code: rm.customSetSpec(ko,resp)
34-
sdk_read_one_post_set_output:
35-
code: rm.customSetOutput(&resource{ko})
36-
sdk_delete_pre_build_request:
37-
template_path: pipeline_execution/sdk_delete_pre_build_request.go.tpl
38-
sdk_delete_post_request:
39-
template_path: common/sdk_delete_post_request.go.tpl
40-
sdk_update_post_set_output:
41-
code: rm.customSetOutput(&resource{ko})
42-
fields:
43-
PipelineExecutionStatus:
44-
is_read_only: true
45-
print:
46-
name: STATUS
47-
from:
48-
operation: DescribePipelineExecution
49-
path: PipelineExecutionStatus
50-
FailureReason:
51-
is_read_only: true
52-
print:
53-
name: FAILURE-REASON
54-
priority: 1
55-
from:
56-
operation: DescribePipelineExecution
57-
path: FailureReason
58-
CreationTime:
59-
is_read_only: true
60-
from:
61-
operation: DescribePipelineExecution
62-
path: CreationTime
63-
LastModifiedTime:
64-
is_read_only: true
65-
from:
66-
operation: DescribePipelineExecution
67-
path: LastModifiedTime
68-
exceptions:
69-
errors:
70-
404:
71-
code: ResourceNotFound
72-
message_suffix: does not exist
73-
terminal_codes:
74-
- InvalidParameterCombination
75-
- InvalidParameterValue
76-
- MissingParameter
77-
- ResourceNotFound
78-
tags:
79-
ignore: true
8026
Model:
8127
hooks:
8228
delta_pre_compare:
@@ -949,6 +895,60 @@ resources:
949895
- InvalidParameterValue
950896
- MissingParameter
951897
- ResourceNotFound
898+
PipelineExecution:
899+
# Resource state/status can have automatic retry-policy
900+
# Need to reconcile to catch these state/status changes
901+
reconcile:
902+
requeue_on_success_seconds: 60
903+
hooks:
904+
sdk_read_one_pre_set_output:
905+
code: rm.customSetSpec(ko,resp)
906+
sdk_read_one_post_set_output:
907+
code: rm.customSetOutput(&resource{ko})
908+
sdk_delete_pre_build_request:
909+
template_path: pipeline_execution/sdk_delete_pre_build_request.go.tpl
910+
sdk_delete_post_request:
911+
template_path: common/sdk_delete_post_request.go.tpl
912+
sdk_update_post_set_output:
913+
code: rm.customSetOutput(&resource{ko})
914+
fields:
915+
PipelineExecutionStatus:
916+
is_read_only: true
917+
print:
918+
name: STATUS
919+
from:
920+
operation: DescribePipelineExecution
921+
path: PipelineExecutionStatus
922+
FailureReason:
923+
is_read_only: true
924+
print:
925+
name: FAILURE-REASON
926+
priority: 1
927+
from:
928+
operation: DescribePipelineExecution
929+
path: FailureReason
930+
CreationTime:
931+
is_read_only: true
932+
from:
933+
operation: DescribePipelineExecution
934+
path: CreationTime
935+
LastModifiedTime:
936+
is_read_only: true
937+
from:
938+
operation: DescribePipelineExecution
939+
path: LastModifiedTime
940+
exceptions:
941+
errors:
942+
404:
943+
code: ResourceNotFound
944+
message_suffix: does not exist
945+
terminal_codes:
946+
- InvalidParameterCombination
947+
- InvalidParameterValue
948+
- MissingParameter
949+
- ResourceNotFound
950+
tags:
951+
ignore: true
952952
ignore:
953953
resource_names:
954954
- Algorithm
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"). You may
4+
// not use this file except in compliance with the License. A copy of the
5+
// License is located at
6+
//
7+
// http://aws.amazon.com/apache2.0/
8+
//
9+
// or in the "license" file accompanying this file. This file is distributed
10+
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
// express or implied. See the License for the specific language governing
12+
// permissions and limitations under the License.
13+
14+
package pipeline_execution
15+
16+
import (
17+
"errors"
18+
"fmt"
19+
"path/filepath"
20+
"testing"
21+
22+
ackv1alpha1 "github.com/aws-controllers-k8s/runtime/apis/core/v1alpha1"
23+
ackmetrics "github.com/aws-controllers-k8s/runtime/pkg/metrics"
24+
acktypes "github.com/aws-controllers-k8s/runtime/pkg/types"
25+
svcapitypes "github.com/aws-controllers-k8s/sagemaker-controller/apis/v1alpha1"
26+
"github.com/aws-controllers-k8s/sagemaker-controller/pkg/testutil"
27+
mocksvcsdkapi "github.com/aws-controllers-k8s/sagemaker-controller/test/mocks/aws-sdk-go/sagemaker"
28+
svcsdk "github.com/aws/aws-sdk-go/service/sagemaker"
29+
"github.com/google/go-cmp/cmp"
30+
"github.com/google/go-cmp/cmp/cmpopts"
31+
"go.uber.org/zap/zapcore"
32+
ctrlrtzap "sigs.k8s.io/controller-runtime/pkg/log/zap"
33+
)
34+
35+
// provideResourceManagerWithMockSDKAPI accepts MockSageMakerAPI and returns pointer to resourceManager
36+
// the returned resourceManager is configured to use mockapi api.
37+
func provideResourceManagerWithMockSDKAPI(mockSageMakerAPI *mocksvcsdkapi.SageMakerAPI) *resourceManager {
38+
zapOptions := ctrlrtzap.Options{
39+
Development: true,
40+
Level: zapcore.InfoLevel,
41+
}
42+
fakeLogger := ctrlrtzap.New(ctrlrtzap.UseFlagOptions(&zapOptions))
43+
return &resourceManager{
44+
rr: nil,
45+
awsAccountID: "",
46+
awsRegion: "",
47+
sess: nil,
48+
sdkapi: mockSageMakerAPI,
49+
log: fakeLogger,
50+
metrics: ackmetrics.NewMetrics("sagemaker"),
51+
}
52+
}
53+
54+
// TestPipelineExecutionTestSuite runs the test suite for pipeline exeuction
55+
func TestPipelineExecutionTestSuite(t *testing.T) {
56+
var ts = testutil.TestSuite{}
57+
testutil.LoadFromFixture(filepath.Join("testdata", "test_suite.yaml"), &ts)
58+
var delegate = testRunnerDelegate{t: t}
59+
var runner = testutil.TestSuiteRunner{TestSuite: &ts, Delegate: &delegate}
60+
runner.RunTests()
61+
}
62+
63+
// testRunnerDelegate implements testutil.TestRunnerDelegate
64+
type testRunnerDelegate struct {
65+
t *testing.T
66+
}
67+
68+
func (d *testRunnerDelegate) ResourceDescriptor() acktypes.AWSResourceDescriptor {
69+
return &resourceDescriptor{}
70+
}
71+
72+
func (d *testRunnerDelegate) ResourceManager(mocksdkapi *mocksvcsdkapi.SageMakerAPI) acktypes.AWSResourceManager {
73+
return provideResourceManagerWithMockSDKAPI(mocksdkapi)
74+
}
75+
76+
func (d *testRunnerDelegate) GoTestRunner() *testing.T {
77+
return d.t
78+
}
79+
80+
func (d *testRunnerDelegate) EmptyServiceAPIOutput(apiName string) (interface{}, error) {
81+
if apiName == "" {
82+
return nil, errors.New("no API name specified")
83+
}
84+
//TODO: use reflection, template to auto generate this block/method.
85+
switch apiName {
86+
case "StartPipelineExecutionWithContext":
87+
var output svcsdk.StartPipelineExecutionOutput
88+
return &output, nil
89+
case "DescribePipelineExecutionWithContext":
90+
var output svcsdk.DescribePipelineExecutionOutput
91+
return &output, nil
92+
case "StopPipelineExecutionWithContext":
93+
var output svcsdk.StopPipelineExecutionOutput
94+
return &output, nil
95+
case "UpdatePipelineExecutionWithContext":
96+
var output svcsdk.UpdatePipelineExecutionOutput
97+
return &output, nil
98+
}
99+
return nil, errors.New(fmt.Sprintf("no matching API name found for: %s", apiName))
100+
}
101+
102+
func (d *testRunnerDelegate) Equal(a acktypes.AWSResource, b acktypes.AWSResource) bool {
103+
ac := a.(*resource)
104+
bc := b.(*resource)
105+
106+
// Ignore LastTransitionTime since it gets updated each run.
107+
opts := []cmp.Option{cmpopts.EquateEmpty(), cmpopts.IgnoreFields(ackv1alpha1.Condition{}, "LastTransitionTime"),
108+
cmpopts.IgnoreFields(svcapitypes.PipelineExecutionStatus{}, "CreationTime"),
109+
cmpopts.IgnoreFields(svcapitypes.PipelineExecutionStatus{}, "LastModifiedTime")}
110+
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
121+
if cmp.Equal(ac.ko.Status, bc.ko.Status, opts...) {
122+
statusMatch = true
123+
} else {
124+
fmt.Printf("Difference ko.Status (-expected +actual):\n\n")
125+
fmt.Println(cmp.Diff(ac.ko.Status, bc.ko.Status, opts...))
126+
statusMatch = false
127+
}
128+
return statusMatch && specMatch
129+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"PipelineExecutionArn": "arn:aws:sagemaker:us-west-2:13456789:pipeline/test-pipeline/execution/tufkd9rv07w2"
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"PipelineArn": "arn:aws:sagemaker:us-west-2:123456789:pipeline/test-pipeline",
3+
"PipelineExecutionArn": "arn:aws:sagemaker:us-west-2:123456789:pipeline/test-pipeline/execution/tufkd9rv07w2",
4+
"PipelineExecutionDisplayName": "test-pipeline-execution",
5+
"PipelineExecutionStatus": "Executing",
6+
"PipelineExecutionDescription": "test",
7+
"PipelineExperimentConfig": {
8+
"ExperimentName": "test-pipeline",
9+
"TrialName": "mf7dqcqqsnlp"
10+
},
11+
"CreationTime": "2022-10-06T23:39:45.629000-07:00",
12+
"LastModifiedTime": "2022-10-06T23:54:11.086000-07:00",
13+
"CreatedBy": {},
14+
"LastModifiedBy": {}
15+
}

0 commit comments

Comments
 (0)