sigs.k8s.io/kubebuilder/v3@v3.14.0/pkg/plugins/golang/v3/scaffolds/internal/templates/controllers/controller_suitetest.go (about)

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package controllers
    18  
    19  import (
    20  	"fmt"
    21  	"path/filepath"
    22  
    23  	"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
    24  )
    25  
    26  var _ machinery.Template = &SuiteTest{}
    27  var _ machinery.Inserter = &SuiteTest{}
    28  
    29  // SuiteTest scaffolds the file that sets up the controller tests
    30  // nolint:maligned
    31  type SuiteTest struct {
    32  	machinery.TemplateMixin
    33  	machinery.MultiGroupMixin
    34  	machinery.BoilerplateMixin
    35  	machinery.ResourceMixin
    36  
    37  	// CRDDirectoryRelativePath define the Path for the CRD
    38  	CRDDirectoryRelativePath string
    39  
    40  	Force bool
    41  }
    42  
    43  // SetTemplateDefaults implements file.Template
    44  func (f *SuiteTest) SetTemplateDefaults() error {
    45  	if f.Path == "" {
    46  		if f.MultiGroup && f.Resource.Group != "" {
    47  			f.Path = filepath.Join("controllers", "%[group]", "suite_test.go")
    48  		} else {
    49  			f.Path = filepath.Join("controllers", "suite_test.go")
    50  		}
    51  	}
    52  	f.Path = f.Resource.Replacer().Replace(f.Path)
    53  
    54  	f.TemplateBody = fmt.Sprintf(controllerSuiteTestTemplate,
    55  		machinery.NewMarkerFor(f.Path, importMarker),
    56  		machinery.NewMarkerFor(f.Path, addSchemeMarker),
    57  	)
    58  
    59  	// If is multigroup the path needs to be ../../ since it has
    60  	// the group dir.
    61  	f.CRDDirectoryRelativePath = `".."`
    62  	if f.MultiGroup && f.Resource.Group != "" {
    63  		f.CRDDirectoryRelativePath = `"..", ".."`
    64  	}
    65  
    66  	if f.Force {
    67  		f.IfExistsAction = machinery.OverwriteFile
    68  	}
    69  
    70  	return nil
    71  }
    72  
    73  const (
    74  	importMarker    = "imports"
    75  	addSchemeMarker = "scheme"
    76  )
    77  
    78  // GetMarkers implements file.Inserter
    79  func (f *SuiteTest) GetMarkers() []machinery.Marker {
    80  	return []machinery.Marker{
    81  		machinery.NewMarkerFor(f.Path, importMarker),
    82  		machinery.NewMarkerFor(f.Path, addSchemeMarker),
    83  	}
    84  }
    85  
    86  const (
    87  	apiImportCodeFragment = `%s "%s"
    88  `
    89  	addschemeCodeFragment = `err = %s.AddToScheme(scheme.Scheme)
    90  Expect(err).NotTo(HaveOccurred())
    91  
    92  `
    93  )
    94  
    95  // GetCodeFragments implements file.Inserter
    96  func (f *SuiteTest) GetCodeFragments() machinery.CodeFragmentsMap {
    97  	fragments := make(machinery.CodeFragmentsMap, 2)
    98  
    99  	// Generate import code fragments
   100  	imports := make([]string, 0)
   101  	if f.Resource.Path != "" {
   102  		imports = append(imports, fmt.Sprintf(apiImportCodeFragment, f.Resource.ImportAlias(), f.Resource.Path))
   103  	}
   104  
   105  	// Generate add scheme code fragments
   106  	addScheme := make([]string, 0)
   107  	if f.Resource.Path != "" {
   108  		addScheme = append(addScheme, fmt.Sprintf(addschemeCodeFragment, f.Resource.ImportAlias()))
   109  	}
   110  
   111  	// Only store code fragments in the map if the slices are non-empty
   112  	if len(imports) != 0 {
   113  		fragments[machinery.NewMarkerFor(f.Path, importMarker)] = imports
   114  	}
   115  	if len(addScheme) != 0 {
   116  		fragments[machinery.NewMarkerFor(f.Path, addSchemeMarker)] = addScheme
   117  	}
   118  
   119  	return fragments
   120  }
   121  
   122  const controllerSuiteTestTemplate = `{{ .Boilerplate }}
   123  
   124  {{if and .MultiGroup .Resource.Group }}
   125  package {{ .Resource.PackageName }}
   126  {{else}}
   127  package controllers
   128  {{end}}
   129  
   130  import (
   131  	"path/filepath"
   132  	"testing"
   133  
   134  	. "github.com/onsi/ginkgo/v2"
   135  	. "github.com/onsi/gomega"
   136  
   137  	"k8s.io/client-go/kubernetes/scheme"
   138  	"k8s.io/client-go/rest"
   139  	"sigs.k8s.io/controller-runtime/pkg/client"
   140  	"sigs.k8s.io/controller-runtime/pkg/envtest"
   141  	logf "sigs.k8s.io/controller-runtime/pkg/log"
   142  	"sigs.k8s.io/controller-runtime/pkg/log/zap"
   143  	%s
   144  )
   145  
   146  // These tests use Ginkgo (BDD-style Go testing framework). Refer to
   147  // http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
   148  
   149  var cfg *rest.Config
   150  var k8sClient client.Client
   151  var testEnv *envtest.Environment
   152  
   153  func TestAPIs(t *testing.T) {
   154  	RegisterFailHandler(Fail)
   155  
   156  	RunSpecs(t, "Controller Suite")
   157  }
   158  
   159  var _ = BeforeSuite(func() {
   160  	logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
   161  
   162  	By("bootstrapping test environment")
   163  	testEnv = &envtest.Environment{
   164  		CRDDirectoryPaths:     []string{filepath.Join({{ .CRDDirectoryRelativePath }}, "config", "crd", "bases")},
   165  		ErrorIfCRDPathMissing: {{ .Resource.HasAPI }},
   166  	}
   167  
   168  	var err error
   169  	// cfg is defined in this file globally.
   170  	cfg, err = testEnv.Start()
   171  	Expect(err).NotTo(HaveOccurred())
   172  	Expect(cfg).NotTo(BeNil())
   173  
   174  	%s
   175  
   176  	k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
   177  	Expect(err).NotTo(HaveOccurred())
   178  	Expect(k8sClient).NotTo(BeNil())
   179  
   180  })
   181  
   182  var _ = AfterSuite(func() {
   183  	By("tearing down the test environment")
   184  	err := testEnv.Stop()
   185  	Expect(err).NotTo(HaveOccurred())
   186  })
   187  `