pkg/testutil/componentsuite/componentsuite.go (98 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 provides a test-suite helper for running component tests. package componentsuite import ( "context" "io/ioutil" "os" "path/filepath" "testing" bundle "github.com/GoogleCloudPlatform/k8s-cluster-bundle/pkg/apis/bundle/v1alpha1" "github.com/GoogleCloudPlatform/k8s-cluster-bundle/pkg/build" "github.com/GoogleCloudPlatform/k8s-cluster-bundle/pkg/converter" "github.com/GoogleCloudPlatform/k8s-cluster-bundle/pkg/filter" "github.com/GoogleCloudPlatform/k8s-cluster-bundle/pkg/options/multi" "github.com/GoogleCloudPlatform/k8s-cluster-bundle/pkg/testutil" "github.com/GoogleCloudPlatform/k8s-cluster-bundle/pkg/wrapper" ) // Run runs a component-tester test-suite. testSuiteFile specifies the path to // the a component-test-suite YAML file. // // By default, go runs tests with the cwd being the current directory. func Run(t *testing.T, testSuiteFile string) { t.Logf("Running tests for suite %q", testSuiteFile) ctx := context.Background() data, err := ioutil.ReadFile(testSuiteFile) if err != nil { t.Fatalf("while reading test suite file %q, %v", testSuiteFile, err) } ts := &ComponentTestSuite{} if err := converter.FromFileName(testSuiteFile, data).ToObject(ts); err != nil { t.Fatalf("while parsing test-suite file %q, %v", testSuiteFile, err) } os.Chdir(filepath.Join(filepath.Dir(testSuiteFile), ts.RootDirectory)) // Inlining expects an absolute parent path, so make the path absolute now. cfile := ts.ComponentFile if !filepath.IsAbs(cfile) { cfile, err = filepath.Abs(cfile) if err != nil { t.Fatalf("While making an absolute path out of %s: %v", cfile, err) } } cdata, err := ioutil.ReadFile(cfile) if err != nil { t.Fatalf("While reading component file %q, %v", cfile, err) } bw, err := wrapper.FromRaw(string(converter.YAML), cdata) if err != nil { t.Fatalf("While converting component file %q, %v", cfile, err) } if bw.Kind() != "Component" && bw.Kind() != "ComponentBuilder" { t.Fatalf("Got kind %q, but component kind must be \"Component\" or \"ComponentBuilder\"", bw.Kind()) } var comp *bundle.Component if bw.Kind() == "ComponentBuilder" { inliner := build.NewLocalInliner(ts.RootDirectory) comp, err = inliner.ComponentFiles(ctx, bw.ComponentBuilder(), cfile) if err != nil { t.Fatalf("Inlining component files: %v", err) } } else { comp = bw.Component() } for _, tc := range ts.TestCases { tci := tc // necessary. t.Run(tc.Description, func(t *testing.T) { t.Parallel() runTest(t, comp.DeepCopy(), tci) }) } } func runTest(t *testing.T, comp *bundle.Component, tc *TestCase) { comp = runBuild(t, comp, tc) if comp == nil { return } comp = runApply(t, comp, tc) if comp == nil { return } runValidate(t, comp, tc) } func runBuild(t *testing.T, comp *bundle.Component, tc *TestCase) *bundle.Component { buildFilter := &filter.Options{} comp, err := build.ComponentPatchTemplates(comp, buildFilter, tc.Build.Options) cerr := testutil.CheckErrorCases(err, tc.Expect.BuildErrSubstr) if cerr != nil { t.Fatal(cerr) } if err != nil { // Since there's an error, it's a terminal condition. We can't proceed. return nil } return comp } func runApply(t *testing.T, comp *bundle.Component, tc *TestCase) *bundle.Component { applier := multi.NewDefaultApplier() comp, err := applier.ApplyOptions(comp, tc.Apply.Options) cerr := testutil.CheckErrorCases(err, tc.Expect.ApplyErrSubstr) if cerr != nil { t.Fatal(cerr) } if err != nil { // Since there's an error, it's a terminal condition. We've already checked // that the err is as expected in CheckErrorCases. return nil } return comp }