Skip to content

Commit

Permalink
test: include e2e test for KCP adoption
Browse files Browse the repository at this point in the history
  • Loading branch information
sethp-nr committed Mar 7, 2020
1 parent 5ac65a3 commit 6c81d4a
Show file tree
Hide file tree
Showing 7 changed files with 382 additions and 72 deletions.
71 changes: 5 additions & 66 deletions test/framework/control_plane.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ import (

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3"
Expand Down Expand Up @@ -128,67 +126,6 @@ func CreateKubeadmControlPlane(ctx context.Context, input CreateKubeadmControlPl
}, intervals...).Should(Succeed())
}

// CreateMachineDeploymentInput is the input for CreateMachineDeployment.
type CreateMachineDeploymentInput struct {
Creator Creator
MachineDeployment *clusterv1.MachineDeployment
BootstrapConfigTemplate runtime.Object
InfraMachineTemplate runtime.Object
}

// CreateMachineDeployment creates the machine deployment and dependencies.
func CreateMachineDeployment(ctx context.Context, input CreateMachineDeploymentInput) {
By("creating a core MachineDeployment resource")
Expect(input.Creator.Create(ctx, input.MachineDeployment)).To(Succeed())

By("creating a BootstrapConfigTemplate resource")
Expect(input.Creator.Create(ctx, input.BootstrapConfigTemplate)).To(Succeed())

By("creating an InfrastructureMachineTemplate resource")
Expect(input.Creator.Create(ctx, input.InfraMachineTemplate)).To(Succeed())
}

// WaitForMachineDeploymentNodesToExistInput is the input for WaitForMachineDeploymentNodesToExist.
type WaitForMachineDeploymentNodesToExistInput struct {
Lister Lister
Cluster *clusterv1.Cluster
MachineDeployment *clusterv1.MachineDeployment
}

// WaitForMachineDeploymentNodesToExist waits until all nodes associated with a machine deployment exist.
func WaitForMachineDeploymentNodesToExist(ctx context.Context, input WaitForMachineDeploymentNodesToExistInput, intervals ...interface{}) {
By("waiting for the workload nodes to exist")
Eventually(func() (int, error) {
selectorMap, err := metav1.LabelSelectorAsMap(&input.MachineDeployment.Spec.Selector)
if err != nil {
return 0, err
}
ms := &clusterv1.MachineSetList{}
if err := input.Lister.List(ctx, ms, client.InNamespace(input.Cluster.Namespace), client.MatchingLabels(selectorMap)); err != nil {
return 0, err
}
if len(ms.Items) == 0 {
return 0, errors.New("no machinesets were found")
}
machineSet := ms.Items[0]
selectorMap, err = metav1.LabelSelectorAsMap(&machineSet.Spec.Selector)
if err != nil {
return 0, err
}
machines := &clusterv1.MachineList{}
if err := input.Lister.List(ctx, machines, client.InNamespace(machineSet.Namespace), client.MatchingLabels(selectorMap)); err != nil {
return 0, err
}
count := 0
for _, machine := range machines.Items {
if machine.Status.NodeRef != nil {
count++
}
}
return count, nil
}, intervals...).Should(Equal(int(*input.MachineDeployment.Spec.Replicas)))
}

// WaitForClusterToProvisionInput is the input for WaitForClusterToProvision.
type WaitForClusterToProvisionInput struct {
Getter Getter
Expand Down Expand Up @@ -223,14 +160,16 @@ func WaitForKubeadmControlPlaneMachinesToExist(ctx context.Context, input WaitFo
By("waiting for all control plane nodes to exist")
inClustersNamespaceListOption := client.InNamespace(input.Cluster.Namespace)
// ControlPlane labels
matchControlPlaneListOption := client.HasLabels{
clusterv1.MachineControlPlaneLabelName,
}
matchClusterListOption := client.MatchingLabels{
clusterv1.MachineControlPlaneLabelName: "",
clusterv1.ClusterLabelName: input.Cluster.Name,
clusterv1.ClusterLabelName: input.Cluster.Name,
}

Eventually(func() (int, error) {
machineList := &clusterv1.MachineList{}
if err := input.Lister.List(ctx, machineList, inClustersNamespaceListOption, matchClusterListOption); err != nil {
if err := input.Lister.List(ctx, machineList, inClustersNamespaceListOption, matchControlPlaneListOption, matchClusterListOption); err != nil {
fmt.Println(err)
return 0, err
}
Expand Down
11 changes: 6 additions & 5 deletions test/framework/convenience.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ func WaitForAPIServiceAvailable(ctx context.Context, mgmt Waiter, serviceName st
Expect(err).NotTo(HaveOccurred(), "stack: %+v", err)
}

// WaitForPodsReadyInNamespace will wait for all pods to be Ready in the
// WaitForDeploymentsInNamespace will wait for all deployments to be Available in the
// specified namespace.
// For example, kubectl wait --for=condition=Ready --timeout=300s --namespace capi-system pods --all
func WaitForPodsReadyInNamespace(ctx context.Context, cluster Waiter, namespace string) {
By(fmt.Sprintf("waiting for pods to be ready in namespace %q", namespace))
err := cluster.Wait(ctx, "--for", "condition=Ready", "--timeout", "300s", "--namespace", namespace, "pods", "--all")
// For example, kubectl wait --for=condition=Available --timeout=300s --namespace capi-system deployments --all
func WaitForDeploymentsInNamespace(ctx context.Context, cluster Waiter, namespace string) {
By(fmt.Sprintf("waiting for deployments to be available in namespace %q", namespace))

err := cluster.Wait(ctx, "--for", "condition=Available", "--timeout", "300s", "--namespace", namespace, "deployments", "--all")
Expect(err).NotTo(HaveOccurred(), "stack: %+v", err)
}

Expand Down
118 changes: 118 additions & 0 deletions test/framework/machines.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package framework

import (
"context"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3"
"sigs.k8s.io/controller-runtime/pkg/client"
)

// CreateMachineInput is the input for CreateMachine.
type CreateMachineInput struct {
Creator Creator
Machine *clusterv1.Machine
BootstrapConfig runtime.Object
InfraMachine runtime.Object
}

// CreateMachine creates the machine and dependencies.
func CreateMachine(ctx context.Context, input CreateMachineInput) {
By("creating a core Machine resource")
Expect(input.Creator.Create(ctx, input.Machine)).To(Succeed())

By("creating a BootstrapConfigTemplate resource")
Expect(input.Creator.Create(ctx, input.BootstrapConfig)).To(Succeed())

By("creating an InfrastructureMachineTemplate resource")
Expect(input.Creator.Create(ctx, input.InfraMachine)).To(Succeed())
}

// WaitForMachineNodesToExistInput is the input for WaitForMachineNodesToExist.
type WaitForMachineNodesToExistInput struct {
Getter Getter
Machines []*clusterv1.Machine
}

// WaitForMachineDeploymentNodesToExist waits until all nodes associated with a machine deployment exist.
func WaitForMachineNodesToExist(ctx context.Context, input WaitForMachineNodesToExistInput, intervals ...interface{}) {
By("waiting for the machines' nodes to exist")
Eventually(func() (count int, err error) {
for _, m := range input.Machines {
machine := &clusterv1.Machine{}
err = input.Getter.Get(ctx, client.ObjectKey{Namespace: m.Namespace, Name: m.Name}, machine)
if err != nil {
return
}
if machine.Status.NodeRef != nil {
count++
}
}
return
}, intervals...).Should(Equal(len(input.Machines)))
}

// CreateMachineDeploymentInput is the input for CreateMachineDeployment.
type CreateMachineDeploymentInput struct {
Creator Creator
MachineDeployment *clusterv1.MachineDeployment
BootstrapConfigTemplate runtime.Object
InfraMachineTemplate runtime.Object
}

// CreateMachineDeployment creates the machine deployment and dependencies.
func CreateMachineDeployment(ctx context.Context, input CreateMachineDeploymentInput) {
By("creating a core MachineDeployment resource")
Expect(input.Creator.Create(ctx, input.MachineDeployment)).To(Succeed())

By("creating a BootstrapConfigTemplate resource")
Expect(input.Creator.Create(ctx, input.BootstrapConfigTemplate)).To(Succeed())

By("creating an InfrastructureMachineTemplate resource")
Expect(input.Creator.Create(ctx, input.InfraMachineTemplate)).To(Succeed())
}

// WaitForMachineDeploymentNodesToExistInput is the input for WaitForMachineDeploymentNodesToExist.
type WaitForMachineDeploymentNodesToExistInput struct {
Lister Lister
Cluster *clusterv1.Cluster
MachineDeployment *clusterv1.MachineDeployment
}

// WaitForMachineDeploymentNodesToExist waits until all nodes associated with a machine deployment exist.
func WaitForMachineDeploymentNodesToExist(ctx context.Context, input WaitForMachineDeploymentNodesToExistInput, intervals ...interface{}) {
By("waiting for the workload nodes to exist")
Eventually(func() (int, error) {
selectorMap, err := metav1.LabelSelectorAsMap(&input.MachineDeployment.Spec.Selector)
if err != nil {
return 0, err
}
ms := &clusterv1.MachineSetList{}
if err := input.Lister.List(ctx, ms, client.InNamespace(input.Cluster.Namespace), client.MatchingLabels(selectorMap)); err != nil {
return 0, err
}
if len(ms.Items) == 0 {
return 0, errors.New("no machinesets were found")
}
machineSet := ms.Items[0]
selectorMap, err = metav1.LabelSelectorAsMap(&machineSet.Spec.Selector)
if err != nil {
return 0, err
}
machines := &clusterv1.MachineList{}
if err := input.Lister.List(ctx, machines, client.InNamespace(machineSet.Namespace), client.MatchingLabels(selectorMap)); err != nil {
return 0, err
}
count := 0
for _, machine := range machines.Items {
if machine.Status.NodeRef != nil {
count++
}
}
return count, nil
}, intervals...).Should(Equal(int(*input.MachineDeployment.Spec.Replicas)))
}
2 changes: 1 addition & 1 deletion test/framework/management_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func InitManagementCluster(ctx context.Context, input *InitManagementClusterInpu
for _, waiter := range component.Waiters {
switch waiter.Type {
case PodsWaiter:
WaitForPodsReadyInNamespace(ctx, managementCluster, waiter.Value)
WaitForDeploymentsInNamespace(ctx, managementCluster, waiter.Value)
case ServiceWaiter:
WaitForAPIServiceAvailable(ctx, managementCluster, waiter.Value)
}
Expand Down
37 changes: 37 additions & 0 deletions test/infrastructure/docker/e2e/custom_assertions.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import (

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
types "github.com/onsi/gomega/types"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"

clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3"
Expand Down Expand Up @@ -64,3 +67,37 @@ func ensureDockerArtifactsDeleted(input ensureDockerArtifactsDeletedInput) {
Expect(dmtl.Items).To(HaveLen(0))
By("Succeeding in deleting all docker artifacts")
}

type controllerMatch struct {
kind string
owner metav1.Object
}

func (m *controllerMatch) Match(actual interface{}) (success bool, err error) {
actualMeta, err := meta.Accessor(actual)
if err != nil {
return false, fmt.Errorf("unable to read meta for %T: %v", actual, err)
}

owner := metav1.GetControllerOf(actualMeta)
if owner == nil {
return false, fmt.Errorf("no controller found (owner ref with controller = true) for object %#v", actual)
}

match := (owner.Kind == m.kind &&
owner.Name == m.owner.GetName() && owner.UID == m.owner.GetUID())

return match, nil
}

func (m *controllerMatch) FailureMessage(actual interface{}) string {
return fmt.Sprintf("Expected\n\t%#vto have a controller reference pointing to %s/%s (%v)", actual, m.kind, m.owner.GetName(), m.owner.GetUID())
}

func (m *controllerMatch) NegatedFailureMessage(actual interface{}) string {
return fmt.Sprintf("Expected\n\t%#vto not have a controller reference pointing to %s/%s (%v)", actual, m.kind, m.owner.GetName(), m.owner.GetUID())
}

func HaveControllerRef(kind string, owner metav1.Object) types.GomegaMatcher {
return &controllerMatch{kind, owner}
}
4 changes: 4 additions & 0 deletions test/infrastructure/docker/e2e/docker_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ var _ = AfterSuite(func() {
})

func writeLogs(mgmt *CAPDCluster, namespace, deploymentName, logDir string) error {
if mgmt == nil {
return nil
}

c, err := mgmt.GetClient()
if err != nil {
return err
Expand Down
Loading

0 comments on commit 6c81d4a

Please sign in to comment.