pkg/testutil/componentsuite/validate.go (101 lines of code) (raw):

// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package componentsuite import ( "fmt" "strings" "testing" bundle "github.com/GoogleCloudPlatform/k8s-cluster-bundle/pkg/apis/bundle/v1alpha1" "github.com/GoogleCloudPlatform/k8s-cluster-bundle/pkg/converter" "github.com/GoogleCloudPlatform/k8s-cluster-bundle/pkg/options/patchtmpl" "github.com/GoogleCloudPlatform/k8s-cluster-bundle/pkg/validate" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" ) type objKey struct { name string kind string } // String returns the stringified objKey. func (o objKey) String() string { return fmt.Sprintf("{name: %s, kind: %s}", o.name, o.kind) } func objKeyFromObjCheck(oc ObjectCheck) objKey { return objKey{ name: oc.Name, kind: oc.Kind, } } func objKeyFromObj(oc *unstructured.Unstructured) objKey { return objKey{ name: oc.GetName(), kind: oc.GetKind(), } } func runValidate(t *testing.T, comp *bundle.Component, tc *TestCase) { if errList := validate.Component(comp); len(errList) > 0 { t.Errorf("There were errors validating component:\n%v", errList.ToAggregate()) } if tc.Expect.CanKubeDeserialize { checkObjectsDeserialize(t, comp) } checkObjectProperties(t, comp, tc) } func checkObjectsDeserialize(t *testing.T, comp *bundle.Component) { scheme := patchtmpl.DefaultPatcherScheme() deserializer := scheme.Codecs.UniversalDeserializer() for _, obj := range comp.Spec.Objects { key := objKeyFromObj(obj) objByt, err := converter.FromObject(obj).ToJSON() if err != nil { // This would be pretty unlikely t.Errorf("Error converting object %v to JSON: %v", key, err) continue } if _, err = runtime.Decode(deserializer, objByt); err != nil { t.Errorf("Error decode object %v: %v", key, err) } } } func checkObjectProperties(t *testing.T, comp *bundle.Component, tc *TestCase) { objCheckMap := make(map[objKey]ObjectCheck) for _, oc := range tc.Expect.Objects { objCheckMap[objKeyFromObjCheck(oc)] = oc } objMap := make(map[objKey]string) for _, obj := range comp.Spec.Objects { key := objKeyFromObj(obj) t.Run(fmt.Sprintf("for object %v", obj), func(t *testing.T) { matchFail := false objStr, err := converter.FromObject(obj).ToYAMLString() if err != nil { // This is a very unlikely error. t.Fatal(err) } objMap[key] = objStr check := objCheckMap[key] for _, expStr := range check.FindSubstrs { if !strings.Contains(objStr, expStr) { t.Errorf("Did not find %q in object %v, but expected to", expStr, key) matchFail = true } } for _, noExpStr := range check.NotFindSubstrs { if strings.Contains(objStr, noExpStr) { t.Errorf("Found %q in object %v, but did not expect to", noExpStr, key) matchFail = true } } if matchFail { t.Logf("Contents for object that didn't meet expectations %v:\n%s", key, objStr) } }) } for key := range objCheckMap { if _, ok := objMap[key]; !ok { t.Errorf("Got object-keys %s, but expected to find object %v", stringMapKeys(objMap), key) } } } func stringMapKeys(m map[objKey]string) []string { var out []string for k := range m { out = append(out, k.String()) } return out }