Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/testsuites/standard_suites.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ var staticSuites = []ginkgo.TestSuite{
This test suite runs tests to validate two-node.
`),
Qualifiers: []string{
`name.contains("[Suite:openshift/two-node") || name.contains("[FeatureGate:DualReplica]") || name.contains("[FeatureGate:HighlyAvailableArbiter]")`,
`name.contains("[Suite:openshift/two-node") || name.contains("[OCPFeatureGate:DualReplica]") || name.contains("[OCPFeatureGate:HighlyAvailableArbiter]")`,
},
TestTimeout: 60 * time.Minute,
},
Expand Down
95 changes: 66 additions & 29 deletions test/extended/two_node/tnf_topology.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@ package two_node
import (
"context"
"fmt"
"strings"

g "github.com/onsi/ginkgo/v2"
o "github.com/onsi/gomega"
v1 "github.com/openshift/api/config/v1"
exutil "github.com/openshift/origin/test/extended/util"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)

const ensurePodmanEtcdContainerIsRunning = "podman inspect --format '{{.State.Running}}' etcd"

var _ = g.Describe("[sig-node][apigroup:config.openshift.io][OCPFeatureGate:DualReplica][Suite:openshift/two-node] Two Node with Fencing topology", func() {
var _ = g.Describe("[sig-node][apigroup:config.openshift.io][OCPFeatureGate:DualReplica] Two Node with Fencing topology", func() {
defer g.GinkgoRecover()
var (
oc = exutil.NewCLIWithoutNamespace("")
Expand All @@ -24,13 +26,13 @@ var _ = g.Describe("[sig-node][apigroup:config.openshift.io][OCPFeatureGate:Dual
skipIfNotTopology(oc, v1.DualReplicaTopologyMode)
})

g.It("Should validate the number of control-planes, arbiters as configured", func() {
g.It("should only have two control plane nodes and no arbiter nodes", func() {
const (
expectedControlPlanes = 2
expectedArbiters = 0
)

g.By(fmt.Sprintf("Ensuring only %d Control-plane nodes in the cluster, and %d Arbiter nodes", expectedControlPlanes, expectedArbiters))
g.By(fmt.Sprintf("Ensuring only %d control-plane nodes in the cluster and no arbiter nodes", expectedControlPlanes))
controlPlaneNodes, err := oc.AdminKubeClient().CoreV1().Nodes().List(context.Background(), metav1.ListOptions{
LabelSelector: labelNodeRoleControlPlane,
})
Expand All @@ -43,61 +45,96 @@ var _ = g.Describe("[sig-node][apigroup:config.openshift.io][OCPFeatureGate:Dual
o.Expect(err).ShouldNot(o.HaveOccurred(), "Expected to retrieve arbiter nodes without error")
o.Expect(len(arbiterNodes.Items)).To(o.Equal(expectedArbiters), fmt.Sprintf("Expected %d Arbiter Nodes, found %d", expectedArbiters, len(arbiterNodes.Items)))
})

g.It("should have infrastructure platform type set correctly", func() {
g.By("Checking that the infrastructure platform is set to baremetal or none or external")
infrastructure, err := oc.AdminConfigClient().ConfigV1().Infrastructures().Get(context.Background(), "cluster", metav1.GetOptions{})
o.Expect(err).ShouldNot(o.HaveOccurred(), "Expected to retrieve infrastructure configuration without error")

platformType := infrastructure.Status.PlatformStatus.Type
o.Expect(platformType).To(o.Or(o.Equal(v1.BareMetalPlatformType), o.Equal(v1.NonePlatformType), o.Equal(v1.ExternalPlatformType)),
fmt.Sprintf("Expected infrastructure platform to be baremetal or none or external, but found %s", platformType))
})

g.It("should have BareMetalHost operational status set to detached if they exist", func() {
g.By("Checking that BareMetalHost objects have operational status set to detached")
dc := oc.AdminDynamicClient()

// Use Dynamic Client to get BareMetalHost objects
// Note: move this to common.go if this is used in other tests
baremetalGVR := schema.GroupVersionResource{Group: "metal3.io", Resource: "baremetalhosts", Version: "v1alpha1"}
baremetalClient := dc.Resource(baremetalGVR).Namespace("openshift-machine-api")

hosts, err := baremetalClient.List(context.Background(), metav1.ListOptions{})
o.Expect(err).ShouldNot(o.HaveOccurred(), "Expected to retrieve BareMetalHost objects without error")

// If no BareMetalHost objects exist, skip the test, this is valid for TNF deployments
if len(hosts.Items) == 0 {
g.Skip("No BareMetalHost objects found in openshift-machine-api namespace")
}

// Check each BareMetalHost has operational status set to detached
for _, host := range hosts.Items {
operationalStatus, found, err := unstructured.NestedString(host.Object, "status", "operationalStatus")
o.Expect(err).ShouldNot(o.HaveOccurred(), fmt.Sprintf("Expected to parse operational status for BareMetalHost %s without error", host.GetName()))
o.Expect(found).To(o.BeTrue(), fmt.Sprintf("Expected operational status field to exist for BareMetalHost %s", host.GetName()))
o.Expect(operationalStatus).To(o.Equal("detached"),
fmt.Sprintf("Expected BareMetalHost %s operational status to be 'detached', but found '%s'", host.GetName(), operationalStatus))
}
})

})

var _ = g.Describe("[sig-etcd][apigroup:config.openshift.io][OCPFeatureGate:DualReplica][Suite:openshift/two-node] Two Node with Fencing pods and podman containers", func() {
var _ = g.Describe("[sig-etcd][apigroup:config.openshift.io][OCPFeatureGate:DualReplica] Two Node with Fencing", func() {
defer g.GinkgoRecover()
var (
oc = exutil.NewCLIWithoutNamespace("")
nodes *corev1.NodeList
oc = exutil.NewCLIWithoutNamespace("")
)

g.BeforeEach(func() {
skipIfNotTopology(oc, v1.DualReplicaTopologyMode)

var err error
nodes, err = oc.AdminKubeClient().CoreV1().Nodes().List(context.Background(), metav1.ListOptions{})
o.Expect(err).To(o.BeNil(), "Expected to retrieve all nodes without error")
})
g.It("Should validate the number of etcd pods and containers as configured", func() {
g.It("should have etcd pods and containers configured correctly", func() {
const (
expectedEtcdPod = 2
expectedEtcdCtlContainers = 2
expectedEtcdContainers = 0
)

nodeNameA := nodes.Items[0].Name
nodeNameB := nodes.Items[1].Name

g.By("Ensuring 0 etcd pod containers and 2 etcdctl pod containers are running in the cluster ")
pods, err := oc.AdminKubeClient().CoreV1().Pods("openshift-etcd").List(context.Background(), metav1.ListOptions{})
pods, err := oc.AdminKubeClient().CoreV1().Pods("openshift-etcd").List(context.Background(), metav1.ListOptions{
LabelSelector: "app=etcd",
})
o.Expect(err).To(o.BeNil(), "Expected to retrieve etcd pods in openshift-etcd namespace without error")
o.Expect(pods.Items).To(o.HaveLen(expectedEtcdPod), "Expected to retrieve %d etcd pods in openshift-etcd namespace", expectedEtcdPod)

etcdPodCount := 0
etcdContainerCount := 0
etcdctlContainerCount := 0

for _, pod := range pods.Items {
if pod.Name == "etcd-"+nodeNameA || pod.Name == "etcd-"+nodeNameB {
etcdPodCount += 1
for _, container := range pod.Spec.Containers {
if container.Name == "etcd" {
etcdContainerCount += 1
}
if container.Name == "etcdctl" {
etcdctlContainerCount += 1
}
for _, container := range pod.Spec.Containers {
if container.Name == "etcd" {
etcdContainerCount += 1
}
if container.Name == "etcdctl" {
etcdctlContainerCount += 1
}
}
}
o.Expect(etcdPodCount).To(o.Equal(expectedEtcdPod))
o.Expect(etcdctlContainerCount).To(o.Equal(expectedEtcdCtlContainers))
o.Expect(etcdContainerCount).To(o.Equal(expectedEtcdContainers))
})

g.It("Should verify the number of podman-etcd containers as configured", func() {
g.It("should have podman etcd containers running on each node", func() {
nodes, err := oc.AdminKubeClient().CoreV1().Nodes().List(context.Background(), metav1.ListOptions{
LabelSelector: labelNodeRoleControlPlane,
})
o.Expect(err).To(o.BeNil(), "Expected to retrieve control plane nodes without error")
o.Expect(nodes.Items).To(o.HaveLen(2), "Expected to retrieve two control plane nodes for DualReplica topology")

g.By("Ensuring one podman etcd container is running on each node")
for _, node := range nodes.Items {
got, err := exutil.DebugNodeRetryWithOptionsAndChroot(oc, node.Name, "openshift-etcd", "podman", "inspect", "--format", "'{{.State.Running}}'", "etcd")
got, err := exutil.DebugNodeRetryWithOptionsAndChroot(oc, node.Name, "openshift-etcd", strings.Split(ensurePodmanEtcdContainerIsRunning, " ")...)
o.Expect(err).To(o.BeNil(), fmt.Sprintf("expected to call podman without errors on Node %s: error %v", node.Name, err))
o.Expect(got).To(o.Equal("'true'"), fmt.Sprintf("expected a podman etcd container running on Node %s: got running %s", node.Name, got))
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 13 additions & 9 deletions zz_generated.manifests/test-reporting.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -184,21 +184,25 @@ spec:
[Beta] [Feature:OffByDefault]'
- featureGate: DualReplica
tests:
- testName: '[sig-etcd][apigroup:config.openshift.io][OCPFeatureGate:DualReplica][Suite:openshift/two-node]
Two Node with Fencing pods and podman containers Should validate the number
of etcd pods and containers as configured'
- testName: '[sig-etcd][apigroup:config.openshift.io][OCPFeatureGate:DualReplica][Suite:openshift/two-node]
Two Node with Fencing pods and podman containers Should verify the number
of podman-etcd containers as configured'
- testName: '[sig-etcd][apigroup:config.openshift.io][OCPFeatureGate:DualReplica]
Two Node with Fencing should have etcd pods and containers configured correctly'
- testName: '[sig-etcd][apigroup:config.openshift.io][OCPFeatureGate:DualReplica]
Two Node with Fencing should have podman etcd containers running on each node'
- testName: '[sig-etcd][apigroup:config.openshift.io][OCPFeatureGate:DualReplica][Suite:openshift/two-node][Disruptive]
Two Node with Fencing etcd recovery Should recover from graceful node shutdown
with etcd member re-addition'
- testName: '[sig-etcd][apigroup:config.openshift.io][OCPFeatureGate:DualReplica][Suite:openshift/two-node][Disruptive]
Two Node with Fencing etcd recovery Should recover from ungraceful node shutdown
with etcd member re-addition'
- testName: '[sig-node][apigroup:config.openshift.io][OCPFeatureGate:DualReplica][Suite:openshift/two-node]
Two Node with Fencing topology Should validate the number of control-planes,
arbiters as configured'
- testName: '[sig-node][apigroup:config.openshift.io][OCPFeatureGate:DualReplica]
Two Node with Fencing topology should have BareMetalHost operational status
set to detached if they exist'
- testName: '[sig-node][apigroup:config.openshift.io][OCPFeatureGate:DualReplica]
Two Node with Fencing topology should have infrastructure platform type set
correctly'
- testName: '[sig-node][apigroup:config.openshift.io][OCPFeatureGate:DualReplica]
Two Node with Fencing topology should only have two control plane nodes and
no arbiter nodes'
- featureGate: DynamicResourceAllocation
tests:
- testName: '[sig-node] DRA [Feature:DynamicResourceAllocation] [FeatureGate:DynamicResourceAllocation]
Expand Down