Skip to content

Commit fef6d5c

Browse files
add initial test for ownerRefs
Signed-off-by: killianmuldoon <[email protected]>
1 parent 7167e09 commit fef6d5c

File tree

4 files changed

+476
-4
lines changed

4 files changed

+476
-4
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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 cluster
18+
19+
import (
20+
"github.com/pkg/errors"
21+
corev1 "k8s.io/api/core/v1"
22+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23+
)
24+
25+
// OwnerGraph contains a graph with all the objects considered by clusterctl move as nodes and the OwnerReference relationship
26+
// between those objects as edges.
27+
type OwnerGraph map[string]OwnerGraphNode
28+
29+
// OwnerGraphNode is a single node linking an ObjectReference to its OwnerReferences.
30+
type OwnerGraphNode struct {
31+
Object corev1.ObjectReference
32+
Owners []metav1.OwnerReference
33+
}
34+
35+
func nodeToOwnerRef(n *node, attributes ownerReferenceAttributes) metav1.OwnerReference {
36+
ref := metav1.OwnerReference{
37+
Name: n.identity.Name,
38+
APIVersion: n.identity.APIVersion,
39+
Kind: n.identity.Kind,
40+
UID: n.identity.UID,
41+
}
42+
if attributes.BlockOwnerDeletion != nil {
43+
ref.BlockOwnerDeletion = attributes.BlockOwnerDeletion
44+
}
45+
if attributes.Controller != nil {
46+
ref.Controller = attributes.Controller
47+
}
48+
return ref
49+
}
50+
51+
// GetOwnerGraph returns a graph with all the objects considered by clusterctl move as nodes and the OwnerReference relationship between those objects as edges.
52+
// NOTE: this data structure is exposed to allow implementation of E2E tests verifying that CAPI can properly rebuild its
53+
// own owner references; there is no guarantee about the stability of this API.
54+
func GetOwnerGraph(namespace, kubeconfigPath string) (OwnerGraph, error) {
55+
p := newProxy(Kubeconfig{Path: kubeconfigPath, Context: ""})
56+
invClient := newInventoryClient(p, nil)
57+
58+
graph := newObjectGraph(p, invClient)
59+
60+
// Gets all the types defined by the CRDs installed by clusterctl plus the ConfigMap/Secret core types.
61+
err := graph.getDiscoveryTypes()
62+
if err != nil {
63+
return OwnerGraph{}, errors.Wrap(err, "failed to retrieve discovery types")
64+
}
65+
66+
// Discovery the object graph for the selected types:
67+
// - Nodes are defined the Kubernetes objects (Clusters, Machines etc.) identified during the discovery process.
68+
// - Edges are derived by the OwnerReferences between nodes.
69+
if err := graph.Discovery(namespace); err != nil {
70+
return OwnerGraph{}, errors.Wrap(err, "failed to discover the object graph")
71+
}
72+
owners := OwnerGraph{}
73+
for _, v := range graph.uidToNode {
74+
n := OwnerGraphNode{Object: v.identity, Owners: []metav1.OwnerReference{}}
75+
for owner, attributes := range v.owners {
76+
n.Owners = append(n.Owners, nodeToOwnerRef(owner, attributes))
77+
}
78+
owners[string(v.identity.UID)] = n
79+
}
80+
return owners, nil
81+
}

test/e2e/quick_start.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ type QuickStartSpecInput struct {
4444
// Flavor, if specified is the template flavor used to create the cluster for testing.
4545
// If not specified, and the e2econfig variable IPFamily is IPV6, then "ipv6" is used,
4646
// otherwise the default flavor is used.
47-
Flavor *string
47+
Flavor *string
48+
PostMachinesProvisioned func(managementClusterProxy framework.ClusterProxy, workloadClusterNamespace, workloadClusterName string)
4849
}
4950

5051
// QuickStartSpec implements a spec that mimics the operation described in the Cluster API quick start, that is
@@ -82,7 +83,7 @@ func QuickStartSpec(ctx context.Context, inputGetter func() QuickStartSpecInput)
8283
if input.Flavor != nil {
8384
flavor = *input.Flavor
8485
}
85-
86+
clusterName := fmt.Sprintf("%s-%s", specName, util.RandomString(6))
8687
clusterctl.ApplyClusterTemplateAndWait(ctx, clusterctl.ApplyClusterTemplateAndWaitInput{
8788
ClusterProxy: input.BootstrapClusterProxy,
8889
ConfigCluster: clusterctl.ConfigClusterInput{
@@ -92,7 +93,7 @@ func QuickStartSpec(ctx context.Context, inputGetter func() QuickStartSpecInput)
9293
InfrastructureProvider: clusterctl.DefaultInfrastructureProvider,
9394
Flavor: flavor,
9495
Namespace: namespace.Name,
95-
ClusterName: fmt.Sprintf("%s-%s", specName, util.RandomString(6)),
96+
ClusterName: clusterName,
9697
KubernetesVersion: input.E2EConfig.GetVariable(KubernetesVersion),
9798
ControlPlaneMachineCount: pointer.Int64(1),
9899
WorkerMachineCount: pointer.Int64(1),
@@ -101,8 +102,12 @@ func QuickStartSpec(ctx context.Context, inputGetter func() QuickStartSpecInput)
101102
WaitForClusterIntervals: input.E2EConfig.GetIntervals(specName, "wait-cluster"),
102103
WaitForControlPlaneIntervals: input.E2EConfig.GetIntervals(specName, "wait-control-plane"),
103104
WaitForMachineDeployments: input.E2EConfig.GetIntervals(specName, "wait-worker-nodes"),
105+
PostMachinesProvisioned: func() {
106+
if input.PostMachinesProvisioned != nil {
107+
input.PostMachinesProvisioned(input.BootstrapClusterProxy, namespace.Name, clusterName)
108+
}
109+
},
104110
}, clusterResources)
105-
106111
By("PASSED!")
107112
})
108113

test/e2e/quick_start_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ package e2e
2222
import (
2323
. "github.com/onsi/ginkgo/v2"
2424
"k8s.io/utils/pointer"
25+
26+
"sigs.k8s.io/cluster-api/test/framework"
2527
)
2628

2729
var _ = Describe("When following the Cluster API quick-start [PR-Blocking]", func() {
@@ -75,3 +77,48 @@ var _ = Describe("When following the Cluster API quick-start with Ignition", fun
7577
}
7678
})
7779
})
80+
81+
var _ = Describe("When following the Cluster API quick-start check owner references are correctly reconciled and rereconciled if deleted", func() {
82+
QuickStartSpec(ctx, func() QuickStartSpecInput {
83+
return QuickStartSpecInput{
84+
E2EConfig: e2eConfig,
85+
ClusterctlConfigPath: clusterctlConfigPath,
86+
BootstrapClusterProxy: bootstrapClusterProxy,
87+
ArtifactFolder: artifactFolder,
88+
SkipCleanup: skipCleanup,
89+
PostMachinesProvisioned: func(proxy framework.ClusterProxy, namespace, clusterName string) {
90+
framework.ValidateOwnerReferencesResilience(ctx, proxy, namespace, clusterName,
91+
framework.CoreTypeOwnerReferenceAssertion,
92+
framework.ExpOwnerReferenceAssertions,
93+
framework.DockerInfraOwnerReferenceAssertions,
94+
framework.KubeadmBootstrapOwnerReferenceAssertions,
95+
framework.KubeadmControlPlaneOwnerReferenceAssertions,
96+
framework.KubernetesReferenceAssertions,
97+
)
98+
},
99+
}
100+
})
101+
})
102+
103+
var _ = Describe("When following the Cluster API quick-start with ClusterClass check owner references are correctly reconciled and rereconciled if deleted [ClusterClass]", func() {
104+
QuickStartSpec(ctx, func() QuickStartSpecInput {
105+
return QuickStartSpecInput{
106+
E2EConfig: e2eConfig,
107+
ClusterctlConfigPath: clusterctlConfigPath,
108+
BootstrapClusterProxy: bootstrapClusterProxy,
109+
ArtifactFolder: artifactFolder,
110+
SkipCleanup: skipCleanup,
111+
Flavor: pointer.String("topology"),
112+
PostMachinesProvisioned: func(proxy framework.ClusterProxy, namespace, clusterName string) {
113+
framework.ValidateOwnerReferencesResilience(ctx, proxy, namespace, clusterName,
114+
framework.CoreTypeOwnerReferenceAssertion,
115+
framework.ExpOwnerReferenceAssertions,
116+
framework.DockerInfraOwnerReferenceAssertions,
117+
framework.KubeadmBootstrapOwnerReferenceAssertions,
118+
framework.KubeadmControlPlaneOwnerReferenceAssertions,
119+
framework.KubernetesReferenceAssertions,
120+
)
121+
},
122+
}
123+
})
124+
})

0 commit comments

Comments
 (0)