Skip to content

Commit

Permalink
test: first draft w/ 3.15.0
Browse files Browse the repository at this point in the history
  • Loading branch information
leovct committed May 16, 2024
1 parent a24e141 commit aee6b11
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 189 deletions.
203 changes: 44 additions & 159 deletions operator-v2-with-tests/internal/controller/foo_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,179 +21,64 @@ import (

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/reconcile"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"

tutorialv1 "my.domain/tutorial/api/v1"
)

var _ = Describe("Foo controller", func() {

const (
foo1Name = "foo-1"
foo1Friend = "jack"

foo2Name = "foo-2"
foo2Friend = "joe"

namespace = "default"
)

Context("When setting up the test environment", func() {
It("Should create Foo custom resources", func() {
By("Creating a first Foo custom resource")
ctx := context.Background()
foo1 := tutorialv1.Foo{
ObjectMeta: metav1.ObjectMeta{
Name: foo1Name,
Namespace: namespace,
},
Spec: tutorialv1.FooSpec{
Name: foo1Friend,
},
}
Expect(k8sClient.Create(ctx, &foo1)).Should(Succeed())

By("Creating another Foo custom resource")
foo2 := tutorialv1.Foo{
ObjectMeta: metav1.ObjectMeta{
Name: foo2Name,
Namespace: namespace,
},
Spec: tutorialv1.FooSpec{
Name: foo2Friend,
},
}
Expect(k8sClient.Create(ctx, &foo2)).Should(Succeed())
})
})

Context("When creating a pod with the same name as one of the Foo custom resources' friends", func() {
It("Should update the status of the first Foo custom resource", func() {
By("Creating the pod")
ctx := context.Background()
pod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: foo1Friend,
Namespace: namespace,
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "ubuntu",
Image: "ubuntu:latest",
Command: []string{"sleep"},
Args: []string{"infinity"},
},
var _ = Describe("Foo Controller", func() {
Context("When reconciling a resource", func() {
const resourceName = "test-resource"

ctx := context.Background()

typeNamespacedName := types.NamespacedName{
Name: resourceName,
Namespace: "default", // TODO(user):Modify as needed
}
foo := &tutorialv1.Foo{}

BeforeEach(func() {
By("creating the custom resource for the Kind Foo")
err := k8sClient.Get(ctx, typeNamespacedName, foo)
if err != nil && errors.IsNotFound(err) {
resource := &tutorialv1.Foo{
ObjectMeta: metav1.ObjectMeta{
Name: resourceName,
Namespace: "default",
},
},
}
Expect(k8sClient.Create(ctx, &pod)).Should(Succeed())

By("Updating the status of the first Foo custom resource")
var foo1 tutorialv1.Foo
foo1Request := types.NamespacedName{
Name: foo1Name,
Namespace: namespace,
}
Eventually(func() bool {
if err := k8sClient.Get(ctx, foo1Request, &foo1); err != nil {
return false
// TODO(user): Specify other spec details if needed.
}
return foo1.Status.Happy
}).Should(BeTrue())

By("Not updating the status of the other Foo custom resource")
var foo2 tutorialv1.Foo
foo2Request := types.NamespacedName{
Name: foo2Name,
Namespace: namespace,
Expect(k8sClient.Create(ctx, resource)).To(Succeed())
}
Consistently(func() bool {
if err := k8sClient.Get(ctx, foo2Request, &foo2); err != nil {
return false
}
return foo2.Status.Happy
}).Should(BeFalse())
})
})

Context("When updating the name of a Foo custom resource's friend", func() {
It("Should update the status of the Foo custom resource", func() {
By("Getting the second Foo custom resource")
ctx := context.Background()
var foo2 tutorialv1.Foo
foo2Request := types.NamespacedName{
Name: foo2Name,
Namespace: namespace,
}
Expect(k8sClient.Get(ctx, foo2Request, &foo2)).To(Succeed())

By("Updating the name of a Foo custom resource's friend")
foo2.Spec.Name = foo1Friend
Expect(k8sClient.Update(ctx, &foo2)).To(Succeed())

By("Updating the status of the other Foo custom resource")
Eventually(func() bool {
if err := k8sClient.Get(ctx, foo2Request, &foo2); err != nil {
return false
}
return foo2.Status.Happy
}).Should(BeTrue())
AfterEach(func() {
// TODO(user): Cleanup logic after each test, like removing the resource instance.
resource := &tutorialv1.Foo{}
err := k8sClient.Get(ctx, typeNamespacedName, resource)
Expect(err).NotTo(HaveOccurred())

By("Not updating the status of the first Foo custom resource")
var foo1 tutorialv1.Foo
foo1Request := types.NamespacedName{
Name: foo1Name,
Namespace: namespace,
}
Consistently(func() bool {
if err := k8sClient.Get(ctx, foo1Request, &foo1); err != nil {
return false
}
return foo1.Status.Happy
}).Should(BeTrue())
By("Cleanup the specific resource instance Foo")
Expect(k8sClient.Delete(ctx, resource)).To(Succeed())
})
})

Context("When deleting a pod with the same name as one of the Foo custom resourcess' friends", func() {
It("Should update the status of the first Foo custom resource", func() {
By("Deleting the pod")
ctx := context.Background()
pod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: foo1Friend,
Namespace: namespace,
},
}
Expect(k8sClient.Delete(ctx, &pod)).Should(Succeed())

By("Updating the status of the first Foo custom resource")
var foo1 tutorialv1.Foo
foo1Request := types.NamespacedName{
Name: foo1Name,
Namespace: namespace,
It("should successfully reconcile the resource", func() {
By("Reconciling the created resource")
controllerReconciler := &FooReconciler{
Client: k8sClient,
Scheme: k8sClient.Scheme(),
}
Eventually(func() bool {
if err := k8sClient.Get(ctx, foo1Request, &foo1); err != nil {
return false
}
return foo1.Status.Happy
}).Should(BeFalse())

By("Updating the status of the other Foo custom resource")
var foo2 tutorialv1.Foo
foo2Request := types.NamespacedName{
Name: foo2Name,
Namespace: namespace,
}
Consistently(func() bool {
if err := k8sClient.Get(ctx, foo2Request, &foo2); err != nil {
return false
}
return foo2.Status.Happy
}).Should(BeFalse())
_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{
NamespacedName: typeNamespacedName,
})
Expect(err).NotTo(HaveOccurred())
// TODO(user): Add more specific assertions depending on your controller's reconciliation logic.
// Example: If you expect a certain status condition after reconciliation, verify it here.
})
})
})
34 changes: 4 additions & 30 deletions operator-v2-with-tests/internal/controller/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,11 @@ limitations under the License.
package controller

import (
"context"
"fmt"
"path/filepath"
"runtime"
"testing"

ctrl "sigs.k8s.io/controller-runtime"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

Expand All @@ -42,13 +39,9 @@ import (
// These tests use Ginkgo (BDD-style Go testing framework). Refer to
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.

var (
cfg *rest.Config
k8sClient client.Client
testEnv *envtest.Environment
ctx context.Context
cancel context.CancelFunc
)
var cfg *rest.Config
var k8sClient client.Client
var testEnv *envtest.Environment

func TestControllers(t *testing.T) {
RegisterFailHandler(Fail)
Expand All @@ -58,7 +51,6 @@ func TestControllers(t *testing.T) {

var _ = BeforeSuite(func() {
logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
ctx, cancel = context.WithCancel(context.TODO())

By("bootstrapping test environment")
testEnv = &envtest.Environment{
Expand All @@ -71,7 +63,7 @@ var _ = BeforeSuite(func() {
// Note that you must have the required binaries setup under the bin directory to perform
// the tests directly. When we run make test it will be setup and used automatically.
BinaryAssetsDirectory: filepath.Join("..", "..", "bin", "k8s",
fmt.Sprintf("1.28.3-%s-%s", runtime.GOOS, runtime.GOARCH)),
fmt.Sprintf("1.29.0-%s-%s", runtime.GOOS, runtime.GOARCH)),
}

var err error
Expand All @@ -89,27 +81,9 @@ var _ = BeforeSuite(func() {
Expect(err).NotTo(HaveOccurred())
Expect(k8sClient).NotTo(BeNil())

// Register and start the Foo controller
k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: scheme.Scheme,
})
Expect(err).ToNot(HaveOccurred())

err = (&FooReconciler{
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
}).SetupWithManager(k8sManager)
Expect(err).ToNot(HaveOccurred())

go func() {
defer GinkgoRecover()
err = k8sManager.Start(ctx)
Expect(err).ToNot(HaveOccurred(), "failed to run manager")
}()
})

var _ = AfterSuite(func() {
cancel()
By("tearing down the test environment")
err := testEnv.Stop()
Expect(err).NotTo(HaveOccurred())
Expand Down

0 comments on commit aee6b11

Please sign in to comment.