Skip to content

Commit

Permalink
[OSSM-8259] Add test for CNI annotation + create function to getting …
Browse files Browse the repository at this point in the history
…all names of a particular resource (#755)
  • Loading branch information
mkralik3 authored Oct 18, 2024
1 parent 627bd3d commit 051e5cc
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 44 deletions.
2 changes: 1 addition & 1 deletion pkg/tests/non-dependant/olm_webhooks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,6 @@ func checkSmcpWebhooksDoesNotExist(t TestHelper, kind string, label string) {
}

func deleteGlobalWebhook(t TestHelper, kind string, label string) {
name := oc.GetResouceNameByLabel(t, "", kind, label)
name := oc.GetAllResoucesNamesByLabel(t, "", kind, label)[0]
oc.DeleteResource(t, "", kind, name)
}
4 changes: 2 additions & 2 deletions pkg/tests/ossm/deploy_on_infra_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,9 @@ func assertPodScheduledToNode(t test.TestHelper, pLabel string) {
}

func pickWorkerNode(t test.TestHelper) string {
workerNodes := shell.Execute(t, "oc get nodes -l node-role.kubernetes.io/worker= -o jsonpath='{.items[*].metadata.name}'")
workerNodes := oc.GetAllResoucesNamesByLabel(t, "", "nodes", "node-role.kubernetes.io/worker=")
operatorNode := shell.Execute(t, "oc get pods -n openshift-operators -l name=istio-operator -o jsonpath='{.items[0].spec.nodeName}'")
for _, node := range strings.Split(workerNodes, " ") {
for _, node := range workerNodes {
node = strings.TrimSpace(node)
if node != operatorNode {
return node
Expand Down
6 changes: 1 addition & 5 deletions pkg/tests/ossm/ior_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,11 +394,7 @@ func getRoutes(t test.TestHelper, ns string) []Route {
}

func getRouteNames(t test.TestHelper, ns string) []string {
return strings.Split(
shell.Executef(t,
"oc -n %s get --selector 'maistra.io/generated-by=ior' --output 'jsonpath={.items[*].metadata.name}' route",
ns),
" ")
return oc.GetAllResoucesNamesByLabel(t, ns, "route", "maistra.io/generated-by=ior")
}

func buildManagedRouteYamlDocument(t test.TestHelper, ns string) string {
Expand Down
21 changes: 3 additions & 18 deletions pkg/tests/ossm/smcp_annotation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import (
_ "embed"
"testing"

"gopkg.in/yaml.v2"

"github.com/maistra/maistra-test-tool/pkg/util/ns"
"github.com/maistra/maistra-test-tool/pkg/util/oc"
"github.com/maistra/maistra-test-tool/pkg/util/pod"
Expand All @@ -30,6 +28,7 @@ import (
func TestSMCPAnnotations(t *testing.T) {
test.NewTest(t).Id("T29").Groups(test.Full, test.ARM).Run(func(t test.TestHelper) {
t.Log("Test annotations: verify deployment with sidecar.maistra.io/proxyEnv annotations and Enable automatic injection in SMCP to propagate the annotations to the sidecar")
t.Log("See https://issues.redhat.com/browse/OSSM-1074")

DeployControlPlane(t) // TODO: move this to individual subtests and integrate patch if one exists

Expand Down Expand Up @@ -78,26 +77,12 @@ func TestSMCPAnnotations(t *testing.T) {
}

func VerifyAndGetPodAnnotation(t test.TestHelper, podLocator oc.PodLocatorFunc) map[string]string {
var data struct {
Metadata struct {
Annotations map[string]string `yaml:"annotations"`
} `yaml:"metadata"`
}

po := podLocator(t, oc.DefaultOC)
yamlString := oc.GetYaml(t, po.Namespace, "pod", po.Name)
err := yaml.Unmarshal([]byte(yamlString), &data)
if err != nil {
t.Fatalf("Failed to unmarshal YAML: %s", err)
}

annotations := data.Metadata.Annotations
annotations := oc.GetPodAnnotations(t, podLocator)
if len(annotations) == 0 {
oc.DeletePod(t, podLocator)
oc.WaitPodReady(t, podLocator)
t.Fatalf("Failed to get annotations from pod %s", po.Name)
t.Fatalf("Failed to get annotations from pod. The pod has 0 annotations")
}

return annotations
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/tests/ossm/smcp_must_gather_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func TestMustGather(t *testing.T) {
}

for webhook, kind := range webhookMap {
name := oc.GetResouceNameByLabel(t, "", kind, fmt.Sprintf("olm.webhook-description-generate-name=%s", webhook))
name := oc.GetAllResoucesNamesByLabel(t, "", kind, fmt.Sprintf("olm.webhook-description-generate-name=%s", webhook))[0]
filename := fmt.Sprintf("%s.yaml", name)
assertFilesExist(t,
dir,
Expand Down
28 changes: 26 additions & 2 deletions pkg/tests/ossm/smoke_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import (
"github.com/maistra/maistra-test-tool/pkg/util/env"
"github.com/maistra/maistra-test-tool/pkg/util/ns"
"github.com/maistra/maistra-test-tool/pkg/util/oc"
"github.com/maistra/maistra-test-tool/pkg/util/pod"
"github.com/maistra/maistra-test-tool/pkg/util/retry"
"github.com/maistra/maistra-test-tool/pkg/util/shell"
"github.com/maistra/maistra-test-tool/pkg/util/version"

. "github.com/maistra/maistra-test-tool/pkg/util/test"
Expand Down Expand Up @@ -148,6 +150,28 @@ func checkSMCP(t TestHelper, ns string) {
t.LogStep("verify proxy startup time. Expected to be less than 10 seconds")
t.Log("Jira related: https://issues.redhat.com/browse/OSSM-3586")
assertProxiesReadyInLessThan10Seconds(t, ns)

t.LogStep("Check that CNI pods for each nodes have been created")
nodesNames := oc.GetAllResoucesNames(t, "", "nodes")
cniNames := oc.GetAllResoucesNamesByLabel(t, "openshift-operators", "pods", fmt.Sprintf("k8s-app=istio-cni-node-v%d-%d", env.GetSMCPVersion().Major, env.GetSMCPVersion().Minor))
if len(nodesNames) != len(cniNames) {
t.Errorf("Number of nodes and number of CNI is not the same! Nodes: %s CNI pods: %s", nodesNames, cniNames)
}
t.LogStep("Check that CNI pods have the correct priority class name and don't have unsupported annotation")
t.Log("Jira related: https://issues.redhat.com/browse/OSSM-1162")
for _, cniPodName := range cniNames {
annotations := oc.GetPodAnnotations(t, pod.MatchingName("openshift-operators", cniPodName))
_, exists := annotations["scheduler.alpha.kubernetes.io"]
if exists {
t.Errorf("The CNI pod %s contains unsupported annotation scheduler.alpha.kubernetes.io!")
}
shell.Execute(t,
fmt.Sprintf(`oc get pod -n openshift-operators %s -o jsonpath='{.spec.priorityClassName}'`, cniPodName),
assert.OutputContains(
"system-node-critical",
fmt.Sprintf("CNI pod %s contains spec.priorityClassName: system-node-critical", cniPodName),
fmt.Sprintf("CNI pod %s doesn't contain spec.priorityClassName: system-node-critical", cniPodName)))
}
}

func assertJaegerAndTracingSettings(t TestHelper) {
Expand Down Expand Up @@ -202,9 +226,9 @@ func assertTrafficFlowsThroughProxy(t TestHelper, ns string) {

func assertProxiesReadyInLessThan10Seconds(t TestHelper, ns string) {
t.Log("Extracting proxy startup time and last transition time for all the pods in the namespace")
podsList := oc.GetJson(t, ns, "pods", "", `{.items[*].metadata.name}`)
podsNamesList := oc.GetAllResoucesNamesByLabel(t, ns, "pods", "")

for _, podName := range strings.Split(podsList, " ") {
for _, podName := range podsNamesList {
// skip sleep pod because it doesn't have a proxy
if strings.Contains(podName, "sleep") {
continue
Expand Down
18 changes: 16 additions & 2 deletions pkg/util/oc/oc.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,18 @@ func DeleteResource(t test.TestHelper, ns string, kind string, name ...string) {
DefaultOC.DeleteResource(t, ns, kind, name...)
}

func GetResouceNameByLabel(t test.TestHelper, ns string, kind string, label string) string {
// Function returns names of all resources (kind input) in the namespace (ns input) that match a particular label (label input).
// When you are looking for a global scoped resource (e.g. nodes), ns can be empty
func GetAllResoucesNamesByLabel(t test.TestHelper, ns string, kind string, label string) []string {
t.T().Helper()
return DefaultOC.GetResouceNameByLabel(t, ns, kind, label)
return DefaultOC.GetAllResoucesNames(t, ns, kind, label)
}

// Function returns names of all resources (kind input) in the namespace (ns input).
// When you are looking for a global scoped resource (e.g. nodes), ns can be empty
func GetAllResoucesNames(t test.TestHelper, ns string, kind string) []string {
t.T().Helper()
return DefaultOC.GetAllResoucesNames(t, ns, kind, "")
}

func ResourceByLabelExists(t test.TestHelper, ns string, kind string, label string) bool {
Expand Down Expand Up @@ -300,3 +309,8 @@ func WaitUntilResourceExist(t test.TestHelper, ns string, kind string, name stri
t.T().Helper()
DefaultOC.WaitUntilResourceExist(t, ns, kind, name)
}

func GetPodAnnotations(t test.TestHelper, podLocator PodLocatorFunc) map[string]string {
t.T().Helper()
return DefaultOC.GetPodAnnotations(t, podLocator)
}
15 changes: 9 additions & 6 deletions pkg/util/oc/oc_struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,18 +488,21 @@ func (o OC) ResourceExists(t test.TestHelper, ns, kind, name string) bool {
return exists
}

func (o OC) GetResouceNameByLabel(t test.TestHelper, ns, kind, label string) string {
// Function returns names of all resources (kind input) in the namespace (ns input) that match a particular label (label input).
// Label input can be an empty string, and then all resources in the namespace are returned
// When you are looking for a global scoped resource (e.g. nodes), ns can be empty
func (o OC) GetAllResoucesNames(t test.TestHelper, ns, kind, label string) []string {
t.T().Helper()
var value string
var values []string
o.withKubeconfig(t, func() {
t.T().Helper()
value = shell.Execute(t, fmt.Sprintf("oc %s get %s -l %s -o custom-columns=NAME:.metadata.name --no-headers || true", nsFlag(ns), kind, label))
value = strings.TrimSpace(value)
if value == "" {
output := shell.Execute(t, fmt.Sprintf("oc %s get %s -l '%s' -o jsonpath='{.items[*].metadata.name}' || true", nsFlag(ns), kind, label))
if output == "" {
t.Fatalf("Could not find resource %s with label %s in namespace %s", kind, label, ns)
}
values = strings.Split(output, " ")
})
return value
return values
}

func (o OC) ResourceByLabelExists(t test.TestHelper, ns, kind, label string) bool {
Expand Down
20 changes: 20 additions & 0 deletions pkg/util/oc/pod_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"strings"
"time"

"gopkg.in/yaml.v2"

"github.com/maistra/maistra-test-tool/pkg/util/check/assert"
"github.com/maistra/maistra-test-tool/pkg/util/check/common"
"github.com/maistra/maistra-test-tool/pkg/util/check/require"
Expand Down Expand Up @@ -246,3 +248,21 @@ func (o OC) WaitUntilResourceExist(t test.TestHelper, ns string, kind string, na
})
})
}

func (o OC) GetPodAnnotations(t test.TestHelper, podLocator PodLocatorFunc) map[string]string {
var data struct {
Metadata struct {
Annotations map[string]string `yaml:"annotations"`
} `yaml:"metadata"`
}

po := podLocator(t, &o)
yamlString := o.GetYaml(t, po.Namespace, "pod", po.Name)
err := yaml.Unmarshal([]byte(yamlString), &data)
if err != nil {
t.Fatalf("Failed to unmarshal YAML: %s", err)
}

annotations := data.Metadata.Annotations
return annotations
}
15 changes: 8 additions & 7 deletions pkg/util/pod/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,13 @@
package pod

import (
"strings"

ocpackage "github.com/maistra/maistra-test-tool/pkg/util/oc"
"github.com/maistra/maistra-test-tool/pkg/util/test"
)

func getPods(t test.TestHelper, oc *ocpackage.OC, selector string, ns string) []ocpackage.NamespacedName {
t.T().Helper()
output := oc.Invokef(t, "kubectl -n %s get pods -l %q -o jsonpath='{.items[*].metadata.name}'", ns, selector)
if output == "" {
t.Fatalf("no pods found using selector %s in namespace %s", selector, ns)
}
pods := strings.Split(output, " ")
pods := oc.GetAllResoucesNames(t, ns, "pods", selector)
var namespacedNames []ocpackage.NamespacedName
for _, pod := range pods {
namespacedNames = append(namespacedNames, ocpackage.NewNamespacedName(ns, pod))
Expand Down Expand Up @@ -56,3 +50,10 @@ func MatchingSelectorFirst(selector string, ns string) ocpackage.PodLocatorFunc
return pods[0]
}
}

// "placeholder", when we know the name of the pod and the namespace but we want to use a different function which takes PodLocatorFunc as an input parameter
func MatchingName(ns string, name string) ocpackage.PodLocatorFunc {
return func(t test.TestHelper, oc *ocpackage.OC) ocpackage.NamespacedName {
return ocpackage.NewNamespacedName(ns, name)
}
}

0 comments on commit 051e5cc

Please sign in to comment.