...

Source file src/github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl/metadata/metadata_test.go

Documentation: github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl/metadata

     1  // Copyright 2022 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    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  // TODO(b/186159460): Delete this test once all DCL-based resources support
    99  // hierarchial references and the SupportsHierarchicalReferences flag is
   100  // deleted since that will allow for all resources that should support
   101  // hierarchical references to automatically support hierarchical references.
   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  					// Don't fail the test for resources that existed before
   140  					// hierarchical references support was added for DCL-based
   141  					// resources. The intention is to support hierarchical
   142  					// references for these resources on a rolling basis.
   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  // kindsThatPrecededHierarchicalRefs lists the kinds that had been supported by
   179  // the KCC-DCL bridge before hierarchical references support was added for
   180  // DCL-based resources.
   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