Skip to content

Commit 44944db

Browse files
committed
Migrate OCP-38271 from openshift-tests-private
Add test to verify init containers do not restart when removed from node. - Add pod-initContainer.yaml template - Add helper functions in node_utils.go - Add OCP-38271 test in node_e2e/node.go Author: minmli@redhat.com (original) Migrated-by: bgudi@redhat.com Move OCP-38271 test to separate Describe block
1 parent c77ff4a commit 44944db

File tree

4 files changed

+248
-2
lines changed

4 files changed

+248
-2
lines changed

test/extended/node/node_e2e/node.go

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import (
66

77
g "github.com/onsi/ginkgo/v2"
88
o "github.com/onsi/gomega"
9-
nodeutils "github.com/openshift/origin/test/extended/node"
10-
exutil "github.com/openshift/origin/test/extended/util"
119
"k8s.io/apimachinery/pkg/util/wait"
1210
e2e "k8s.io/kubernetes/test/e2e/framework"
11+
12+
nodeutils "github.com/openshift/origin/test/extended/node"
13+
exutil "github.com/openshift/origin/test/extended/util"
14+
"github.com/openshift/origin/test/extended/util/compat_otp"
1315
)
1416

1517
var _ = g.Describe("[sig-node] [Jira:Node/Kubelet] Kubelet, CRI-O, CPU manager", func() {
@@ -104,3 +106,52 @@ var _ = g.Describe("[sig-node] [Jira:Node/Kubelet] Kubelet, CRI-O, CPU manager",
104106
o.Expect(output).To(o.ContainSubstring("spec.cgroupMode: Unsupported value: \"v1\": supported values: \"v2\", \"\""))
105107
})
106108
})
109+
110+
var _ = g.Describe("[sig-node] [Jira:Node/Kubelet] NODE initContainer policy,volume,readines,quota", func() {
111+
defer g.GinkgoRecover()
112+
113+
var (
114+
oc = exutil.NewCLI("node-initcontainer")
115+
)
116+
117+
// Skip all tests on MicroShift clusters as MachineConfig resources are not available
118+
g.BeforeEach(func() {
119+
isMicroShift, err := exutil.IsMicroShiftCluster(oc.AdminKubeClient())
120+
o.Expect(err).NotTo(o.HaveOccurred())
121+
if isMicroShift {
122+
g.Skip("Skipping test on MicroShift cluster - MachineConfig resources are not available")
123+
}
124+
})
125+
126+
//author: bgudi@redhat.com
127+
g.It("[OTP] Init containers should not restart when the exited init container is removed from node [OCP-38271]", func() {
128+
podInitCon38271 := nodeutils.PodInitConDescription{
129+
Template: exutil.FixturePath("testdata", "node", "node_e2e", "pod-initContainer.yaml"),
130+
}
131+
132+
g.By("Test for case OCP-38271")
133+
oc.SetupProject()
134+
podInitCon38271.Name = "initcon-pod"
135+
podInitCon38271.Namespace = oc.Namespace()
136+
137+
g.By("Create a pod with init container")
138+
podInitCon38271.Create(oc)
139+
defer podInitCon38271.Delete(oc)
140+
141+
g.By("Check pod status")
142+
err := nodeutils.PodStatus(oc, podInitCon38271.Namespace, podInitCon38271.Name)
143+
compat_otp.AssertWaitPollNoErr(err, "pod is not running")
144+
145+
g.By("Check init container exit normally")
146+
err = podInitCon38271.ContainerExit(oc)
147+
compat_otp.AssertWaitPollNoErr(err, "container not exit normally")
148+
149+
g.By("Delete init container")
150+
_, err = podInitCon38271.DeleteInitContainer(oc)
151+
compat_otp.AssertWaitPollNoErr(err, "fail to delete container")
152+
153+
g.By("Check init container not restart again")
154+
err = podInitCon38271.InitContainerNotRestart(oc)
155+
compat_otp.AssertWaitPollNoErr(err, "init container restart")
156+
})
157+
})

test/extended/node/node_utils.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"math/rand"
88
"os"
9+
"regexp"
910
"strings"
1011
"time"
1112

@@ -22,6 +23,7 @@ import (
2223

2324
machineconfigclient "github.com/openshift/client-go/machineconfiguration/clientset/versioned"
2425
exutil "github.com/openshift/origin/test/extended/util"
26+
"github.com/openshift/origin/test/extended/util/compat_otp"
2527
)
2628

2729
// getNodesByLabel returns nodes matching the specified label selector
@@ -671,3 +673,84 @@ func ensureDropInDirectoryExists(ctx context.Context, oc *exutil.CLI, dirPath st
671673

672674
return nil
673675
}
676+
677+
// ============================================================================
678+
// Helper functions for testcases migrated from openshift-tests-private
679+
// ============================================================================
680+
681+
// PodInitConDescription describes a pod with init container for testing
682+
type PodInitConDescription struct {
683+
Name string
684+
Namespace string
685+
Template string
686+
}
687+
688+
func (p *PodInitConDescription) Create(oc *exutil.CLI) {
689+
configFile := compat_otp.ProcessTemplate(oc, "--ignore-unknown-parameters=true", "-f", p.Template, "-p", "NAME="+p.Name, "NAMESPACE="+p.Namespace)
690+
err := oc.AsAdmin().Run("create").Args("-f", configFile).Execute()
691+
o.Expect(err).NotTo(o.HaveOccurred())
692+
}
693+
694+
func (p *PodInitConDescription) Delete(oc *exutil.CLI) {
695+
err := oc.AsAdmin().Run("delete").Args("-n", p.Namespace, "pod", p.Name).Execute()
696+
o.Expect(err).NotTo(o.HaveOccurred())
697+
}
698+
699+
func (p *PodInitConDescription) ContainerExit(oc *exutil.CLI) error {
700+
return wait.Poll(2*time.Second, 2*time.Minute, func() (bool, error) {
701+
initConStatus, err := oc.AsAdmin().Run("get").Args("pod", "-o=jsonpath={.items[0].status.initContainerStatuses[0].state.terminated.reason}", "-n", p.Namespace).Output()
702+
framework.Logf("The initContainer status is %v", initConStatus)
703+
o.Expect(err).NotTo(o.HaveOccurred())
704+
if strings.Contains(initConStatus, "Completed") {
705+
framework.Logf("The initContainer exit normally")
706+
return true, nil
707+
}
708+
framework.Logf("The initContainer not exit!")
709+
return false, nil
710+
})
711+
}
712+
713+
func (p *PodInitConDescription) DeleteInitContainer(oc *exutil.CLI) (string, error) {
714+
nodename, err := oc.AsAdmin().Run("get").Args("pod", "-o=jsonpath={.items[0].spec.nodeName}", "-n", p.Namespace).Output()
715+
o.Expect(err).NotTo(o.HaveOccurred())
716+
containerID, err := oc.AsAdmin().Run("get").Args("pod", "-o=jsonpath={.items[0].status.initContainerStatuses[0].containerID}", "-n", p.Namespace).Output()
717+
o.Expect(err).NotTo(o.HaveOccurred())
718+
framework.Logf("The containerID is %v", containerID)
719+
initContainerID := string(containerID)[8:]
720+
framework.Logf("The initContainerID is %s", initContainerID)
721+
return compat_otp.DebugNodeWithChroot(oc, fmt.Sprintf("%s", nodename), "crictl", "rm", initContainerID)
722+
}
723+
724+
func (p *PodInitConDescription) InitContainerNotRestart(oc *exutil.CLI) error {
725+
return wait.Poll(3*time.Minute, 6*time.Minute, func() (bool, error) {
726+
re := regexp.MustCompile("running")
727+
podname, err := oc.AsAdmin().Run("get").Args("pod", "-o=jsonpath={.items[0].metadata.name}", "-n", p.Namespace).Output()
728+
o.Expect(err).NotTo(o.HaveOccurred())
729+
output, err := oc.AsAdmin().Run("exec").Args(string(podname), "-n", p.Namespace, "--", "cat", "/mnt/data/test").Output()
730+
framework.Logf("The /mnt/data/test: %s", output)
731+
o.Expect(err).NotTo(o.HaveOccurred())
732+
found := re.FindAllString(output, -1)
733+
if lenStr := len(found); lenStr > 1 {
734+
framework.Logf("initContainer restart %d times.", (lenStr - 1))
735+
return false, nil
736+
} else if lenStr == 1 {
737+
framework.Logf("initContainer not restart")
738+
return true, nil
739+
}
740+
return false, nil
741+
})
742+
}
743+
744+
// PodStatus checks if pod is in Ready state
745+
func PodStatus(oc *exutil.CLI, namespace string, podName string) error {
746+
framework.Logf("check if pod is available")
747+
return wait.Poll(5*time.Second, 3*time.Minute, func() (bool, error) {
748+
status, err := oc.AsAdmin().Run("get").Args("pod", podName, "-o=jsonpath={.status.conditions[?(@.type=='Ready')].status}", "-n", namespace).Output()
749+
o.Expect(err).NotTo(o.HaveOccurred())
750+
if strings.Contains(status, "True") {
751+
framework.Logf("Pod is running and container is Ready!")
752+
return true, nil
753+
}
754+
return false, nil
755+
})
756+
}

test/extended/testdata/bindata.go

Lines changed: 67 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
apiVersion: template.openshift.io/v1
2+
kind: Template
3+
metadata:
4+
name: pod-initcontainer
5+
objects:
6+
- kind: Pod
7+
apiVersion: v1
8+
metadata:
9+
name: "${NAME}"
10+
namespace: "${NAMESPACE}"
11+
spec:
12+
securityContext:
13+
runAsNonRoot: true
14+
seccompProfile:
15+
type: RuntimeDefault
16+
initContainers:
17+
- name: inittest
18+
image: "quay.io/openshifttest/hello-openshift@sha256:4200f438cf2e9446f6bcff9d67ceea1f69ed07a2f83363b7fb52529f7ddd8a83"
19+
securityContext:
20+
allowPrivilegeEscalation: false
21+
capabilities:
22+
drop:
23+
- ALL
24+
command: ["bin/sh", "-ec", "echo running >> /mnt/data/test"]
25+
volumeMounts:
26+
- name: my-volume
27+
mountPath: /mnt/data
28+
containers:
29+
- name: my-container
30+
image: "quay.io/openshifttest/hello-openshift@sha256:4200f438cf2e9446f6bcff9d67ceea1f69ed07a2f83363b7fb52529f7ddd8a83"
31+
securityContext:
32+
allowPrivilegeEscalation: false
33+
capabilities:
34+
drop:
35+
- ALL
36+
command: ["/bin/sh", "-ec", "ls /mnt/data; sleep 999999"]
37+
volumeMounts:
38+
- mountPath: /mnt/data
39+
name: my-volume
40+
volumes:
41+
- name: my-volume
42+
emptyDir: {}
43+
parameters:
44+
- name: NAME
45+
- name: NAMESPACE

0 commit comments

Comments
 (0)