Skip to content

Commit dc497e7

Browse files
committed
adding new pod-count test to the observability suite
Signed-off-by: Adam D. Cornett <adc@redhat.com>
1 parent 8b4cc13 commit dc497e7

File tree

8 files changed

+117
-14
lines changed

8 files changed

+117
-14
lines changed

cmd/certsuite/main_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ func TestCertsuiteInfoCmd(t *testing.T) {
6767
| observability-termination-policy |
6868
| observability-pod-disruption-budget |
6969
| observability-compatibility-with-next-ocp-release |
70+
| observability-pod-count |
7071
------------------------------------------------------------
7172
`
7273
assert.Equal(t, expectedOutput, string(out))

expected_results.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ testCases:
5656
- observability-pod-disruption-budget
5757
- observability-compatibility-with-next-ocp-release
5858
- observability-termination-policy
59+
- observability-pod-count
5960
- operator-crd-versioning
6061
- operator-crd-openapi-schema
6162
- operator-install-source

pkg/autodiscover/autodiscover.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ var data = DiscoveredTestData{}
129129
const labelRegex = `(\S*)\s*:\s*(\S*)`
130130
const labelRegexMatches = 3
131131

132-
func createLabels(labelStrings []string) (labelObjects []labelObject) {
132+
func CreateLabels(labelStrings []string) (labelObjects []labelObject) {
133133
for _, label := range labelStrings {
134134
r := regexp.MustCompile(labelRegex)
135135

@@ -158,8 +158,8 @@ func DoAutoDiscover(config *configuration.TestConfiguration) DiscoveredTestData
158158
log.Fatal("Failed to retrieve storageClasses - err: %v", err)
159159
}
160160

161-
podsUnderTestLabelsObjects := createLabels(config.PodsUnderTestLabels)
162-
operatorsUnderTestLabelsObjects := createLabels(config.OperatorsUnderTestLabels)
161+
podsUnderTestLabelsObjects := CreateLabels(config.PodsUnderTestLabels)
162+
operatorsUnderTestLabelsObjects := CreateLabels(config.OperatorsUnderTestLabels)
163163

164164
log.Debug("Pods under test labels: %+v", podsUnderTestLabelsObjects)
165165
log.Debug("Operators under test labels: %+v", operatorsUnderTestLabelsObjects)
@@ -180,11 +180,11 @@ func DoAutoDiscover(config *configuration.TestConfiguration) DiscoveredTestData
180180
data.AllPackageManifests = getAllPackageManifests(oc.OlmPkgClient.PackageManifests(""))
181181

182182
data.Namespaces = namespacesListToStringList(config.TargetNameSpaces)
183-
data.Pods, data.AllPods = findPodsByLabels(oc.K8sClient.CoreV1(), podsUnderTestLabelsObjects, data.Namespaces)
183+
data.Pods, data.AllPods = FindPodsByLabels(oc.K8sClient.CoreV1(), podsUnderTestLabelsObjects, data.Namespaces)
184184
data.AbnormalEvents = findAbnormalEvents(oc.K8sClient.CoreV1(), data.Namespaces)
185185
probeLabels := []labelObject{{LabelKey: probeHelperPodsLabelName, LabelValue: probeHelperPodsLabelValue}}
186186
probeNS := []string{config.ProbeDaemonSetNamespace}
187-
data.ProbePods, _ = findPodsByLabels(oc.K8sClient.CoreV1(), probeLabels, probeNS)
187+
data.ProbePods, _ = FindPodsByLabels(oc.K8sClient.CoreV1(), probeLabels, probeNS)
188188
data.ResourceQuotaItems, err = getResourceQuotas(oc.K8sClient.CoreV1())
189189
if err != nil {
190190
log.Fatal("Cannot get resource quotas, err: %v", err)
@@ -222,7 +222,7 @@ func DoAutoDiscover(config *configuration.TestConfiguration) DiscoveredTestData
222222
}
223223

224224
// Best effort mode autodiscovery for operand (running-only) pods.
225-
pods, _ := findPodsByLabels(oc.K8sClient.CoreV1(), nil, data.Namespaces)
225+
pods, _ := FindPodsByLabels(oc.K8sClient.CoreV1(), nil, data.Namespaces)
226226
if err != nil {
227227
log.Fatal("Failed to get running pods, err: %v", err)
228228
}

pkg/autodiscover/autodiscover_pods.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func findPodsMatchingAtLeastOneLabel(oc corev1client.CoreV1Interface, labels []l
4141
return allPods
4242
}
4343

44-
func findPodsByLabels(oc corev1client.CoreV1Interface, labels []labelObject, namespaces []string) (runningPods, allPods []corev1.Pod) {
44+
func FindPodsByLabels(oc corev1client.CoreV1Interface, labels []labelObject, namespaces []string) (runningPods, allPods []corev1.Pod) {
4545
runningPods = []corev1.Pod{}
4646
allPods = []corev1.Pod{}
4747
// Iterate through namespaces

pkg/autodiscover/autodiscover_pods_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func TestFindPodsUnderTest(t *testing.T) {
9191
testRuntimeObjects = append(testRuntimeObjects, generatePod(tc.testPodName, tc.testPodNamespace, tc.queryLabel))
9292
oc := clientsholder.GetTestClientsHolder(testRuntimeObjects)
9393

94-
podResult, _ := findPodsByLabels(oc.K8sClient.CoreV1(), testLabel, testNamespaces)
94+
podResult, _ := FindPodsByLabels(oc.K8sClient.CoreV1(), testLabel, testNamespaces)
9595
assert.Equal(t, tc.expectedResults, podResult)
9696
}
9797
}

pkg/autodiscover/autodiscover_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ func TestCreateLabels(t *testing.T) {
5050
}
5151
for _, tt := range tests {
5252
t.Run(tt.name, func(t *testing.T) {
53-
if gotLabelObjects := createLabels(tt.args.labelStrings); !reflect.DeepEqual(gotLabelObjects, tt.wantLabelObjects) {
54-
t.Errorf("createLabels() = %v, want %v", gotLabelObjects, tt.wantLabelObjects)
53+
if gotLabelObjects := CreateLabels(tt.args.labelStrings); !reflect.DeepEqual(gotLabelObjects, tt.wantLabelObjects) {
54+
t.Errorf("CreateLabels() = %v, want %v", gotLabelObjects, tt.wantLabelObjects)
5555
}
5656
})
5757
}

tests/identifiers/identifiers.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ var (
170170
TestNamespaceResourceQuotaIdentifier claim.Identifier
171171
TestPodDisruptionBudgetIdentifier claim.Identifier
172172
TestAPICompatibilityWithNextOCPReleaseIdentifier claim.Identifier
173+
TestPodCountIdentifier claim.Identifier
173174
TestPodTolerationBypassIdentifier claim.Identifier
174175
TestPersistentVolumeReclaimPolicyIdentifier claim.Identifier
175176
TestContainersImageTag claim.Identifier
@@ -1677,6 +1678,22 @@ that Node's kernel may not have the same hacks.'`,
16771678
},
16781679
TagCommon)
16791680

1681+
TestPodCountIdentifier = AddCatalogEntry(
1682+
"pod-count",
1683+
common.ObservabilityTestKey,
1684+
`Checks that all pods running at the beginning of the tests, continue to run throughout the test`,
1685+
"Ensure all expected pods are running",
1686+
NoExceptions,
1687+
"https://redhat-best-practices-for-k8s.github.io/guide/#observability-pod-count",
1688+
true,
1689+
map[string]string{
1690+
FarEdge: Optional,
1691+
Telco: Optional,
1692+
NonTelco: Optional,
1693+
Extended: Optional,
1694+
},
1695+
TagCommon)
1696+
16801697
TestPodTolerationBypassIdentifier = AddCatalogEntry(
16811698
"pod-toleration-bypass",
16821699
common.LifecycleTestKey,

tests/observability/suite.go

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,16 @@ import (
2424
"strings"
2525

2626
"github.com/Masterminds/semver"
27-
"github.com/redhat-best-practices-for-k8s/certsuite/tests/common"
28-
"github.com/redhat-best-practices-for-k8s/certsuite/tests/identifiers"
29-
pdbv1 "github.com/redhat-best-practices-for-k8s/certsuite/tests/observability/pdb"
30-
3127
apiserv1 "github.com/openshift/api/apiserver/v1"
3228
"github.com/redhat-best-practices-for-k8s/certsuite/internal/clientsholder"
3329
"github.com/redhat-best-practices-for-k8s/certsuite/internal/log"
30+
"github.com/redhat-best-practices-for-k8s/certsuite/pkg/autodiscover"
3431
"github.com/redhat-best-practices-for-k8s/certsuite/pkg/checksdb"
3532
"github.com/redhat-best-practices-for-k8s/certsuite/pkg/provider"
3633
"github.com/redhat-best-practices-for-k8s/certsuite/pkg/testhelper"
34+
"github.com/redhat-best-practices-for-k8s/certsuite/tests/common"
35+
"github.com/redhat-best-practices-for-k8s/certsuite/tests/identifiers"
36+
pdbv1 "github.com/redhat-best-practices-for-k8s/certsuite/tests/observability/pdb"
3737
corev1 "k8s.io/api/core/v1"
3838
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3939
"k8s.io/apimachinery/pkg/labels"
@@ -88,6 +88,13 @@ func LoadChecks() {
8888
testAPICompatibilityWithNextOCPRelease(c, &env)
8989
return nil
9090
}))
91+
92+
checksGroup.Add(checksdb.NewCheck(identifiers.GetTestIDAndLabels(identifiers.TestPodCountIdentifier)).
93+
WithSkipCheckFn(testhelper.GetNoPodsUnderTestSkipFn(&env)).
94+
WithCheckFn(func(c *checksdb.Check) error {
95+
testComparePodCount(c, &env)
96+
return nil
97+
}))
9198
}
9299

93100
// containerHasLoggingOutput helper function to get the last line of logging output from
@@ -423,3 +430,80 @@ func testAPICompatibilityWithNextOCPRelease(check *checksdb.Check, env *provider
423430
// Add test results
424431
check.SetResult(compliantObjects, nonCompliantObjects)
425432
}
433+
434+
// Function to compare the number of running pods to those loaded during autodiscover at the start of test execution.
435+
func testComparePodCount(check *checksdb.Check, env *provider.TestEnvironment) {
436+
oc := clientsholder.GetClientsHolder()
437+
438+
originalPods := env.Pods
439+
440+
currentPods, _ := autodiscover.FindPodsByLabels(oc.K8sClient.CoreV1(), autodiscover.CreateLabels(env.Config.PodsUnderTestLabels), env.Namespaces)
441+
442+
var compliantObjects []*testhelper.ReportObject
443+
var nonCompliantObjects []*testhelper.ReportObject
444+
445+
// Compare pod counts
446+
originalPodCount := len(originalPods)
447+
currentPodCount := len(currentPods)
448+
449+
check.LogInfo("Original pod count: %d, Current pod count: %d", originalPodCount, currentPodCount)
450+
451+
if originalPodCount == currentPodCount {
452+
check.LogInfo("Pod count is consistent")
453+
compliantObjects = append(compliantObjects,
454+
testhelper.NewReportObject("Pod count is consistent", "PodCount", true).
455+
AddField("OriginalCount", fmt.Sprintf("%d", originalPodCount)).
456+
AddField("CurrentCount", fmt.Sprintf("%d", currentPodCount)))
457+
} else {
458+
check.LogError("Pod count mismatch: original=%d, current=%d", originalPodCount, currentPodCount)
459+
nonCompliantObjects = append(nonCompliantObjects,
460+
testhelper.NewReportObject("Pod count mismatch", "PodCount", false).
461+
AddField("OriginalCount", fmt.Sprintf("%d", originalPodCount)).
462+
AddField("CurrentCount", fmt.Sprintf("%d", currentPodCount)))
463+
}
464+
465+
// Create maps for detailed comparison
466+
originalPodsMap := make(map[string]struct{})
467+
for _, pod := range originalPods {
468+
key := fmt.Sprintf("%s/%s", pod.Namespace, pod.Name)
469+
originalPodsMap[key] = struct{}{}
470+
}
471+
472+
currentPodsMap := make(map[string]struct{})
473+
for _, pod := range currentPods {
474+
key := fmt.Sprintf("%s/%s", pod.Namespace, pod.Name)
475+
currentPodsMap[key] = struct{}{}
476+
}
477+
478+
// Check for missing pods (in original but not in current)
479+
for _, originalPod := range originalPods {
480+
podKey := fmt.Sprintf("%s/%s", originalPod.Namespace, originalPod.Name)
481+
if _, exists := currentPodsMap[podKey]; !exists {
482+
check.LogError("Pod %q is missing from current state", originalPod.String())
483+
nonCompliantObjects = append(nonCompliantObjects,
484+
testhelper.NewReportObject("Pod is missing from current state", testhelper.PodType, false).
485+
AddField(testhelper.PodName, originalPod.Name).
486+
AddField(testhelper.Namespace, originalPod.Namespace))
487+
} else {
488+
check.LogInfo("Pod %q is present in current state", originalPod.String())
489+
compliantObjects = append(compliantObjects,
490+
testhelper.NewReportObject("Pod is present in current state", testhelper.PodType, true).
491+
AddField(testhelper.PodName, originalPod.Name).
492+
AddField(testhelper.Namespace, originalPod.Namespace))
493+
}
494+
}
495+
496+
// Check for extra pods (in current but not in original)
497+
for _, currentPod := range currentPods {
498+
podKey := fmt.Sprintf("%s/%s", currentPod.Namespace, currentPod.Name)
499+
if _, exists := originalPodsMap[podKey]; !exists {
500+
check.LogError("Extra pod %s/%s found in current state", currentPod.Namespace, currentPod.Name)
501+
nonCompliantObjects = append(nonCompliantObjects,
502+
testhelper.NewReportObject("Extra pod found in current state", testhelper.PodType, false).
503+
AddField(testhelper.PodName, currentPod.Name).
504+
AddField(testhelper.Namespace, currentPod.Namespace))
505+
}
506+
}
507+
508+
check.SetResult(compliantObjects, nonCompliantObjects)
509+
}

0 commit comments

Comments
 (0)