1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package resourceskeleton_test
16
17 import (
18 "reflect"
19 "testing"
20
21 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/core/v1alpha1"
22 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/cli/asset"
23 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/cli/serviceclient"
24 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s"
25 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/resourceskeleton"
26 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/servicemapping/servicemappingloader"
27 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test/resourcefixture"
28 testservicemappingloader "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test/servicemappingloader"
29 testyaml "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test/yaml"
30 tfprovider "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/tf/provider"
31
32 "github.com/google/go-cmp/cmp"
33 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
34 )
35
36 func TestNewProject(t *testing.T) {
37 projectId := "my-project-id"
38 u, err := resourceskeleton.NewProject(projectId, testservicemappingloader.New(t))
39 if err != nil {
40 t.Fatalf("unexpected error: %v", err)
41 }
42 if u.GetName() != projectId {
43 t.Fatalf("unexpected value for name: got '%v', want '%v'", u.GetName(), projectId)
44 }
45 expectedKind := "Project"
46 if u.GetKind() != expectedKind {
47 t.Fatalf("unexpected value for kind: got '%v', want '%v'", u.GetKind(), expectedKind)
48 }
49 if _, ok := k8s.GetAnnotation(k8s.FolderIDAnnotation, u); !ok {
50 t.Fatalf("expected annotations to contain the folder id annotation '%v'", k8s.ProjectIDAnnotation)
51 }
52 }
53
54 type URISkeletonTestCase struct {
55 ResourceConfigId string
56 URI string
57 ExpectedSkeleton *unstructured.Unstructured
58 }
59
60 func TestNewFromURI(t *testing.T) {
61 tfProvider := tfprovider.NewOrLogFatal(tfprovider.DefaultConfig)
62 smLoader := testservicemappingloader.New(t)
63 idToRC := make(map[string]v1alpha1.ResourceConfig)
64 for _, sm := range smLoader.GetServiceMappings() {
65 for _, rc := range sm.Spec.Resources {
66 id := resourcefixture.GetUniqueResourceConfigId(rc)
67 idToRC[id] = rc
68 }
69 }
70 testCases := loadURISkeletonTestCases(t)
71 ensureURITCExistsForEachResourceConfig(t, smLoader, testCases)
72 for _, tc := range testCases {
73 rc := idToRC[tc.ResourceConfigId]
74 if !*rc.IDTemplateCanBeUsedToMatchResourceName {
75 continue
76 }
77 u, err := resourceskeleton.NewFromURI(tc.URI, smLoader, tfProvider)
78 if err != nil {
79 t.Fatalf("error getting skeleton unstruct from uri '%v': %v", tc.URI, err)
80 }
81 if !reflect.DeepEqual(tc.ExpectedSkeleton, u) {
82 diff := cmp.Diff(tc.ExpectedSkeleton, u)
83 t.Fatalf("mismatch between skeletons for resource id '%v', diff:\n%v", tc.ResourceConfigId, diff)
84 }
85 }
86 }
87
88 type AssetSkeletonTestCase struct {
89 ResourceConfigId string `json:"resourceConfigId,omitempty"`
90 Asset *asset.Asset `json:"asset,omitempty"`
91 ExpectedSkeleton *unstructured.Unstructured `json:"expectedSkeleton,omitempty"`
92 }
93
94 func TestNewFromAsset(t *testing.T) {
95 tfProvider := tfprovider.NewOrLogFatal(tfprovider.DefaultConfig)
96 smLoader := testservicemappingloader.New(t)
97 mockServiceClient := serviceclient.NewMockServiceClient(t)
98 testCases := loadAssetSkeletonTestCases(t)
99 ensureAssetTCExistsForEachResourceConfig(t, smLoader, testCases)
100 for _, tc := range testCases {
101 a := tc.Asset
102 if a == nil {
103 continue
104 }
105 u, err := resourceskeleton.NewFromAsset(a, smLoader, tfProvider, &mockServiceClient)
106 if err != nil {
107 t.Fatalf("error getting skeleton unstruct from asset '%v' with type '%v': %v", a.Name, a.AssetType, err)
108 }
109 if !reflect.DeepEqual(tc.ExpectedSkeleton, u) {
110 diff := cmp.Diff(tc.ExpectedSkeleton, u)
111 t.Fatalf("mismatch between skeletons for resource id '%v', diff:\n%v", tc.ResourceConfigId, diff)
112 }
113 }
114 }
115
116 func ensureAssetTCExistsForEachResourceConfig(t *testing.T, smLoader *servicemappingloader.ServiceMappingLoader, testCases []AssetSkeletonTestCase) {
117 t.Helper()
118 rcIdToTC := make(map[string]AssetSkeletonTestCase)
119 for _, tc := range testCases {
120 rcIdToTC[tc.ResourceConfigId] = tc
121 }
122 for _, sm := range smLoader.GetServiceMappings() {
123 for _, rc := range sm.Spec.Resources {
124 if rc.AutoGenerated {
125 continue
126 }
127 id := resourcefixture.GetUniqueResourceConfigId(rc)
128 if _, ok := rcIdToTC[id]; ok {
129 continue
130 }
131 t.Fatalf("missing test case for resource config with id '%v' and TF name '%v'", id, rc.Name)
132 }
133 }
134 }
135
136 func ensureURITCExistsForEachResourceConfig(t *testing.T, smLoader *servicemappingloader.ServiceMappingLoader, testCases []URISkeletonTestCase) {
137 t.Helper()
138 rcIdToTC := make(map[string]URISkeletonTestCase)
139 for _, tc := range testCases {
140 rcIdToTC[tc.ResourceConfigId] = tc
141 }
142 for _, sm := range smLoader.GetServiceMappings() {
143 for _, rc := range sm.Spec.Resources {
144 if rc.AutoGenerated {
145 continue
146 }
147 id := resourcefixture.GetUniqueResourceConfigId(rc)
148 if _, ok := rcIdToTC[id]; ok {
149 continue
150 }
151 t.Fatalf("missing test case for resource config with id '%v' and TF name '%v'", id, rc.Name)
152 }
153 }
154 }
155
156 const (
157 assetResourceSkeletonPath = "testdata/asset-skeleton.yaml"
158 uriResourceSkeletonPath = "testdata/uri-skeleton.yaml"
159 )
160
161 func loadURISkeletonTestCases(t *testing.T) []URISkeletonTestCase {
162 var value []URISkeletonTestCase
163 testyaml.UnmarshalFile(t, uriResourceSkeletonPath, &value)
164 return value
165 }
166
167 func loadAssetSkeletonTestCases(t *testing.T) []AssetSkeletonTestCase {
168 var value []AssetSkeletonTestCase
169 testyaml.UnmarshalFile(t, assetResourceSkeletonPath, &value)
170 return value
171 }
172
View as plain text