sigs.k8s.io/kubebuilder/v3@v3.14.0/hack/docs/internal/cronjob-tutorial/writing_tests_env.go (about)

     1  /*
     2  Copyright 2023 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 cronjob
    18  
    19  const SuiteTestIntro = `
    20  // +kubebuilder:docs-gen:collapse=Apache License
    21  
    22  /*
    23  When we created the CronJob API with` + " `" + `kubebuilder create api` + "`" + ` in a [previous chapter](/cronjob-tutorial/new-api.md), Kubebuilder already did some test work for you.
    24  Kubebuilder scaffolded a` + " `" + `internal/controller/suite_test.go` + "`" + ` file that does the bare bones of setting up a test environment.
    25  
    26  First, it will contain the necessary imports.
    27  */
    28  `
    29  
    30  const SuiteTestEnv = `
    31  // +kubebuilder:docs-gen:collapse=Imports
    32  
    33  /*
    34  Now, let's go through the code generated.
    35  */
    36  
    37  var (
    38  	cfg       *rest.Config
    39  	k8sClient client.Client // You'll be using this client in your tests.
    40  	testEnv   *envtest.Environment
    41  	ctx       context.Context
    42  	cancel    context.CancelFunc
    43  )
    44  `
    45  
    46  const SuiteTestReadCRD = `
    47  	ctx, cancel = context.WithCancel(context.TODO())
    48  
    49  	/*
    50  		First, the envtest cluster is configured to read CRDs from the CRD directory Kubebuilder scaffolds for you.
    51  	*/`
    52  
    53  const SuiteTestAddSchema = `
    54  	/*
    55  		The autogenerated test code will add the CronJob Kind schema to the default client-go k8s scheme.
    56  		This ensures that the CronJob API/Kind will be used in our test controller.
    57  	*/
    58  	err = batchv1.AddToScheme(scheme.Scheme)
    59  	Expect(err).NotTo(HaveOccurred())
    60  	/*
    61  		After the schemas, you will see the following marker.
    62  		This marker is what allows new schemas to be added here automatically when a new API is added to the project.
    63  	*/
    64  
    65  	//+kubebuilder:scaffold:scheme
    66  
    67  	/*
    68  		A client is created for our test CRUD operations.
    69  	*/`
    70  
    71  const SuiteTestDescription = `
    72  	/*
    73  		One thing that this autogenerated file is missing, however, is a way to actually start your controller.
    74  		The code above will set up a client for interacting with your custom Kind,
    75  		but will not be able to test your controller behavior.
    76  		If you want to test your custom controller logic, you’ll need to add some familiar-looking manager logic
    77  		to your BeforeSuite() function, so you can register your custom controller to run on this test cluster.
    78  
    79  		You may notice that the code below runs your controller with nearly identical logic to your CronJob project’s main.go!
    80  		The only difference is that the manager is started in a separate goroutine so it does not block the cleanup of envtest
    81  		when you’re done running your tests.
    82  
    83  		Note that we set up both a "live" k8s client and a separate client from the manager. This is because when making
    84  		assertions in tests, you generally want to assert against the live state of the API server. If you use the client
    85  		from the manager (` + "`" + `k8sManager.GetClient` + "`" + `), you'd end up asserting against the contents of the cache instead, which is
    86  		slower and can introduce flakiness into your tests. We could use the manager's ` + "`" + `APIReader` + "`" + ` to accomplish the same
    87  		thing, but that would leave us with two clients in our test assertions and setup (one for reading, one for writing),
    88  		and it'd be easy to make mistakes.
    89  
    90  		Note that we keep the reconciler running against the manager's cache client, though -- we want our controller to
    91  		behave as it would in production, and we use features of the cache (like indicies) in our controller which aren't
    92  		available when talking directly to the API server.
    93  	*/
    94  	k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{
    95  		Scheme: scheme.Scheme,
    96  	})
    97  	Expect(err).ToNot(HaveOccurred())
    98  
    99  	err = (&CronJobReconciler{
   100  		Client: k8sManager.GetClient(),
   101  		Scheme: k8sManager.GetScheme(),
   102  	}).SetupWithManager(k8sManager)
   103  	Expect(err).ToNot(HaveOccurred())
   104  
   105  	go func() {
   106  		defer GinkgoRecover()
   107  		err = k8sManager.Start(ctx)
   108  		Expect(err).ToNot(HaveOccurred(), "failed to run manager")
   109  	}()
   110  `
   111  
   112  const SuiteTestCleanup = `
   113  /*
   114  Kubebuilder also generates boilerplate functions for cleaning up envtest and actually running your test files in your controllers/ directory.
   115  You won't need to touch these.
   116  */
   117  
   118  var _ = AfterSuite(func() {
   119  	cancel()
   120  	By("tearing down the test environment")
   121  	err := testEnv.Stop()
   122  	Expect(err).NotTo(HaveOccurred())
   123  })
   124  
   125  /*
   126  Now that you have your controller running on a test cluster and a client ready to perform operations on your CronJob, we can start writing integration tests!
   127  */
   128  `