Skip to content

Commit 0fdc1b5

Browse files
committed
Add integration test for Pod delete
1 parent 366cfc1 commit 0fdc1b5

File tree

2 files changed

+190
-0
lines changed

2 files changed

+190
-0
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package manifest
2+
3+
import (
4+
"github.com/aws/aws-sdk-go-v2/aws"
5+
appsv1 "k8s.io/api/apps/v1"
6+
corev1 "k8s.io/api/core/v1"
7+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
8+
)
9+
10+
type StatefulSetBuilder struct {
11+
namespace string
12+
name string
13+
serviceName string
14+
replicas int32
15+
labels map[string]string
16+
container corev1.Container
17+
nodeSelector map[string]string
18+
terminationGracePeriod int64
19+
}
20+
21+
func NewDefaultStatefulSetBuilder() *StatefulSetBuilder {
22+
return &StatefulSetBuilder{
23+
namespace: "default",
24+
name: "statefulset",
25+
serviceName: "statefulset",
26+
replicas: 2,
27+
labels: map[string]string{},
28+
container: NewBusyBoxContainerBuilder().Build(),
29+
nodeSelector: map[string]string{"kubernetes.io/os": "linux"},
30+
terminationGracePeriod: 0,
31+
}
32+
}
33+
34+
func (s *StatefulSetBuilder) Namespace(namespace string) *StatefulSetBuilder {
35+
s.namespace = namespace
36+
return s
37+
}
38+
39+
func (s *StatefulSetBuilder) Name(name string) *StatefulSetBuilder {
40+
s.name = name
41+
s.serviceName = name // typically same as name
42+
return s
43+
}
44+
45+
func (s *StatefulSetBuilder) ServiceName(serviceName string) *StatefulSetBuilder {
46+
s.serviceName = serviceName
47+
return s
48+
}
49+
50+
func (s *StatefulSetBuilder) Replicas(replicas int32) *StatefulSetBuilder {
51+
s.replicas = replicas
52+
return s
53+
}
54+
55+
func (s *StatefulSetBuilder) PodLabel(key, value string) *StatefulSetBuilder {
56+
s.labels[key] = value
57+
return s
58+
}
59+
60+
func (s *StatefulSetBuilder) Container(container corev1.Container) *StatefulSetBuilder {
61+
s.container = container
62+
return s
63+
}
64+
65+
func (s *StatefulSetBuilder) Build() *appsv1.StatefulSet {
66+
return &appsv1.StatefulSet{
67+
ObjectMeta: metav1.ObjectMeta{
68+
Name: s.name,
69+
Namespace: s.namespace,
70+
},
71+
Spec: appsv1.StatefulSetSpec{
72+
ServiceName: s.serviceName,
73+
Replicas: aws.Int32(s.replicas),
74+
Selector: &metav1.LabelSelector{
75+
MatchLabels: s.labels,
76+
},
77+
Template: corev1.PodTemplateSpec{
78+
ObjectMeta: metav1.ObjectMeta{
79+
Labels: s.labels,
80+
},
81+
Spec: corev1.PodSpec{
82+
Containers: []corev1.Container{s.container},
83+
NodeSelector: s.nodeSelector,
84+
TerminationGracePeriodSeconds: aws.Int64(s.terminationGracePeriod),
85+
},
86+
},
87+
},
88+
}
89+
}

test/integration/perpodsg/perpodsg_test.go

100644100755
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
sgpWrapper "github.com/aws/amazon-vpc-resource-controller-k8s/test/framework/resource/k8s/sgp"
2929
"github.com/aws/amazon-vpc-resource-controller-k8s/test/framework/utils"
3030
"github.com/samber/lo"
31+
"sigs.k8s.io/controller-runtime/pkg/client"
3132

3233
. "github.com/onsi/ginkgo/v2"
3334
. "github.com/onsi/gomega"
@@ -513,8 +514,108 @@ var _ = Describe("Branch ENI Pods", func() {
513514
})
514515
})
515516
})
517+
518+
Describe("Test Network Connectivity on Delete and Recreation of Pod", func() {
519+
Context("creating statefulset with network connectivity", func() {
520+
var resourceMap map[v1.ResourceName]resource.Quantity
521+
var statefulSet *appsv1.StatefulSet
522+
var container v1.Container
523+
524+
BeforeEach(func() {
525+
resourceMap = map[v1.ResourceName]resource.Quantity{
526+
config.ResourceNamePodENI: resource.MustParse("1"),
527+
}
528+
})
529+
530+
JustBeforeEach(func() {
531+
container = manifest.NewBusyBoxContainerBuilder().
532+
Resources(v1.ResourceRequirements{
533+
Limits: resourceMap,
534+
Requests: resourceMap,
535+
}).
536+
Command([]string{ "/bin/sh", "-c",
537+
"while true; do if ping -c 1 google.com; then echo 'Successfully pinged google.com'; else echo 'Failed to ping google.com'; exit 1; fi; sleep 30; done",
538+
}).
539+
Name("network-test").
540+
Image("busybox").
541+
Build()
542+
543+
statefulSet = manifest.NewDefaultStatefulSetBuilder().
544+
Namespace(namespace).
545+
Name("network-test").
546+
PodLabel(podLabelKey, podLabelValue).
547+
Container(container).
548+
Build()
549+
})
550+
551+
JustAfterEach(func() {
552+
By("deleting the statefulset")
553+
err = frameWork.K8sClient.Delete(ctx, statefulSet)
554+
Expect(err).ToNot(HaveOccurred())
555+
})
556+
557+
Context("when statefulset is created with network connectivity requirements", func() {
558+
It("should have all pods running with network access", func() {
559+
By("creating security group policy")
560+
sgpWrapper.CreateSecurityGroupPolicy(frameWork.K8sClient, ctx, securityGroupPolicy)
561+
562+
By("creating statefulset")
563+
err = frameWork.K8sClient.Create(ctx, statefulSet)
564+
Expect(err).ToNot(HaveOccurred())
565+
566+
By("waiting for statefulset pods to be ready")
567+
Eventually(func() bool {
568+
err := frameWork.K8sClient.Get(ctx, client.ObjectKey{
569+
Namespace: namespace,
570+
Name: statefulSet.Name,
571+
}, statefulSet)
572+
if err != nil {
573+
return false
574+
}
575+
return statefulSet.Status.ReadyReplicas == *statefulSet.Spec.Replicas
576+
}, 300*time.Second, 5*time.Second).Should(BeTrue())
577+
578+
By("verifying network connectivity of all pods")
579+
verify.VerifyNetworkingOfAllPodUsingENI(namespace, podLabelKey, podLabelValue,
580+
securityGroups)
581+
582+
By("force deleting one pod to verify recreation")
583+
pods := &v1.PodList{}
584+
err = frameWork.K8sClient.List(ctx, pods, client.InNamespace(namespace),
585+
client.MatchingLabels(map[string]string{podLabelKey: podLabelValue}))
586+
Expect(err).ToNot(HaveOccurred())
587+
Expect(pods.Items).ToNot(BeEmpty())
588+
589+
// Force delete the first pod
590+
err = frameWork.K8sClient.Delete(ctx, &pods.Items[0], client.GracePeriodSeconds(0))
591+
Expect(err).ToNot(HaveOccurred())
592+
593+
By("waiting for pod to be recreated")
594+
Eventually(func() bool {
595+
err := frameWork.K8sClient.Get(ctx, client.ObjectKey{
596+
Namespace: namespace,
597+
Name: statefulSet.Name,
598+
}, statefulSet)
599+
if err != nil {
600+
return false
601+
}
602+
return statefulSet.Status.ReadyReplicas == *statefulSet.Spec.Replicas
603+
}, 300*time.Second, 5*time.Second).Should(BeTrue())
604+
605+
By("verifying network connectivity after pod recreation")
606+
verify.VerifyNetworkingOfAllPodUsingENI(namespace, podLabelKey, podLabelValue,
607+
securityGroups)
608+
})
609+
})
610+
})
611+
})
516612
})
517613

614+
// Helper functions
615+
func int32Ptr(i int32) *int32 {
616+
return &i
617+
}
618+
518619
func CreateServiceAccount(serviceAccount *v1.ServiceAccount) {
519620
By("create a service account")
520621
err := frameWork.K8sClient.Create(ctx, serviceAccount)

0 commit comments

Comments
 (0)