1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package metadata_test
16
17 import (
18 "strings"
19 "testing"
20
21 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl"
22 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl/metadata"
23 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl/schema/dclschemaloader"
24 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s"
25 )
26
27 func TestNoDuplicateService(t *testing.T) {
28 t.Parallel()
29 smLoader := metadata.New()
30 allServices := smLoader.GetAllServiceMetadata()
31 m := make(map[string]bool)
32 for _, s := range allServices {
33 serviceName := metadata.CanonicalizeServiceName(s.Name)
34 if _, ok := m[metadata.CanonicalizeServiceName(serviceName)]; ok {
35 t.Fatalf("found duplicate service: %s", s.Name)
36 }
37 m[serviceName] = true
38 }
39 }
40
41 func TestServiceNamedDifferentlyInDCLAndKCC(t *testing.T) {
42 t.Parallel()
43 serviceList := []metadata.ServiceMetadata{
44 {
45 Name: "KMS",
46 APIVersion: "v1beta1",
47 ServiceNameUsedByDCL: "cloudkms",
48 },
49 }
50 smLoader := metadata.NewFromServiceList(serviceList)
51 serviceNameInDCL := "cloudkms"
52 _, found := smLoader.GetServiceMetadata(serviceNameInDCL)
53 if !found {
54 t.Fatalf("service metadata for service %v is not found", serviceNameInDCL)
55 }
56 serviceNameInKCC := "KMS"
57 _, found = smLoader.GetServiceMetadata(serviceNameInKCC)
58 if !found {
59 t.Fatalf("service metadata for service %v is not found", serviceNameInKCC)
60 }
61 }
62
63 func TestResourceNamesAreCaseInsensitiveEqual(t *testing.T) {
64 t.Parallel()
65 smLoader := metadata.New()
66 allServices := smLoader.GetAllServiceMetadata()
67 for _, s := range allServices {
68 for _, r := range s.Resources {
69 gvk := metadata.GVKForResource(s, r)
70 kindWithoutService := k8s.KindWithoutServicePrefix(gvk)
71 if strings.ToLower(kindWithoutService) != strings.ToLower(r.DCLType) {
72 t.Fatalf("Kind %v (with service prefix ignored) is not the same (case-insensitive) with the DCL Type %v, there might be a typo.", r.Kind, r.DCLType)
73 }
74 }
75 }
76 }
77
78 func TestServicesAndResourcesListedAlphabetically(t *testing.T) {
79 t.Parallel()
80 smLoader := metadata.New()
81 allServices := smLoader.GetAllServiceMetadata()
82 var prevServiceName string
83 for _, s := range allServices {
84 if prevServiceName > s.Name {
85 t.Errorf("services are not listed alphabetically: %v listed before %v", prevServiceName, s.Name)
86 }
87 prevServiceName = s.Name
88 var preResourceKind string
89 for _, r := range s.Resources {
90 if preResourceKind > r.Kind {
91 t.Errorf("resource are not listed alphabetically: %v listed before %v", preResourceKind, r.Kind)
92 }
93 preResourceKind = r.Kind
94 }
95 }
96 }
97
98
99
100
101
102 func TestResourceSupportsHierarchicalReferencesIfHasParentReferenceField(t *testing.T) {
103 t.Parallel()
104 dclSchemaLoader, err := dclschemaloader.New()
105 if err != nil {
106 t.Fatalf("error creating a DCL schema loader: %v", err)
107 }
108 smLoader := metadata.New()
109 allServices := smLoader.GetAllServiceMetadata()
110 for _, s := range allServices {
111 for _, r := range s.Resources {
112 s := s
113 r := r
114 t.Run(r.Kind, func(t *testing.T) {
115 t.Parallel()
116 if !r.Releasable {
117 if r.SupportsHierarchicalReferences {
118 t.Fatalf("kind %v should not have SupportsHierarchicalReferences=true since it is not Releasable", r.Kind)
119 }
120 return
121 }
122
123 gvk := metadata.GVKForResource(s, r)
124 schema, err := dclschemaloader.GetDCLSchemaForGVK(gvk, smLoader, dclSchemaLoader)
125 if err != nil {
126 t.Fatalf("error getting the DCL schema for GroupVersionKind %v: %v", gvk, err)
127 }
128
129 hasParentReferenceField := false
130 for _, f := range dcl.ParentReferenceFields() {
131 s, ok := schema.Properties[f]
132 if ok && !s.ReadOnly {
133 hasParentReferenceField = true
134 break
135 }
136 }
137
138 if hasParentReferenceField && !r.SupportsHierarchicalReferences {
139
140
141
142
143 if _, ok := kindsThatPrecededHierarchicalRefs[r.Kind]; ok {
144 return
145 }
146 t.Fatalf("kind %v has a parent reference field, but has SupportsHierarchicalReferences=false", r.Kind)
147 } else if !hasParentReferenceField && r.SupportsHierarchicalReferences {
148 t.Fatalf("kind %v doesn't have a parent reference field, but has SupportsHierarchicalReferences=true", r.Kind)
149 }
150 })
151 }
152 }
153 }
154
155 func TestResourceSupportsContainerAnnotationsOnlyIfPrecededHierarchicalReferences(t *testing.T) {
156 t.Parallel()
157 smLoader := metadata.New()
158 allServices := smLoader.GetAllServiceMetadata()
159 for _, s := range allServices {
160 for _, r := range s.Resources {
161 r := r
162 t.Run(r.Kind, func(t *testing.T) {
163 t.Parallel()
164 if !r.SupportsContainerAnnotations {
165 return
166 }
167 if !r.Releasable {
168 t.Fatalf("kind %v should not have SupportsContainerAnnotations=true since it is not Releasable", r.Kind)
169 }
170 if _, ok := kindsThatPrecededHierarchicalRefs[r.Kind]; !ok {
171 t.Fatalf("kind %v should not have SupportsContainerAnnotations=true since it is not one of the resources that preceded hierarchical references support", r.Kind)
172 }
173 })
174 }
175 }
176 }
177
178
179
180
181 var kindsThatPrecededHierarchicalRefs = map[string]bool{
182 "CloudSchedulerJob": true,
183 "ContainerAnalysisNote": true,
184 "DataFusionInstance": true,
185 "DataprocAutoscalingPolicy": true,
186 "DataprocCluster": true,
187 "DataprocWorkflowTemplate": true,
188 "GKEHubMembership": true,
189 "IAPBrand": true,
190 "IAPIdentityAwareProxyClient": true,
191 "IdentityPlatformOAuthIDPConfig": true,
192 "IdentityPlatformTenant": true,
193 "IdentityPlatformTenantOAuthIDPConfig": true,
194 "MonitoringGroup": true,
195 "NetworkSecurityClientTLSPolicy": true,
196 "NetworkSecurityServerTLSPolicy": true,
197 "OSConfigGuestPolicy": true,
198 }
199
200 func TestServiceListApiVersionsAreAllV1Beta1(t *testing.T) {
201 t.Parallel()
202 smLoader := metadata.New()
203 allServices := smLoader.GetAllServiceMetadata()
204 for _, s := range allServices {
205 if s.APIVersion != k8s.KCCAPIVersion {
206 t.Errorf("service %v should have APIVersion set to %v using the constant k8s.KCCAPIVersion", s.Name, k8s.KCCAPIVersion)
207 }
208 }
209 }
210
View as plain text