github.com/kotalco/kotal@v0.3.0/controllers/aptos/node_controller_test.go (about) 1 package controllers 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 "time" 8 9 aptosv1alpha1 "github.com/kotalco/kotal/apis/aptos/v1alpha1" 10 "github.com/kotalco/kotal/controllers/shared" 11 . "github.com/onsi/ginkgo/v2" 12 . "github.com/onsi/gomega" 13 "github.com/onsi/gomega/gstruct" 14 appsv1 "k8s.io/api/apps/v1" 15 corev1 "k8s.io/api/core/v1" 16 "k8s.io/apimachinery/pkg/api/resource" 17 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 18 "k8s.io/apimachinery/pkg/types" 19 "k8s.io/apimachinery/pkg/util/intstr" 20 ) 21 22 var _ = Describe("aptos node controller", func() { 23 ns := &corev1.Namespace{ 24 ObjectMeta: metav1.ObjectMeta{ 25 Name: "aptos", 26 }, 27 } 28 29 key := types.NamespacedName{ 30 Name: "aptos-node", 31 Namespace: ns.Name, 32 } 33 34 testImage := "kotalco/aptos:controller-test" 35 36 spec := aptosv1alpha1.NodeSpec{ 37 Image: testImage, 38 Network: "testnet", 39 API: true, 40 APIPort: 4321, 41 P2PPort: 5432, 42 MetricsPort: 9099, 43 } 44 45 toCreate := &aptosv1alpha1.Node{ 46 ObjectMeta: metav1.ObjectMeta{ 47 Name: key.Name, 48 Namespace: key.Namespace, 49 }, 50 Spec: spec, 51 } 52 53 t := true 54 55 nodeOwnerReference := metav1.OwnerReference{ 56 APIVersion: "aptos.kotal.io/v1alpha1", 57 Kind: "Node", 58 Name: toCreate.Name, 59 Controller: &t, 60 BlockOwnerDeletion: &t, 61 } 62 63 It(fmt.Sprintf("Should create %s namespace", ns.Name), func() { 64 Expect(k8sClient.Create(context.TODO(), ns)).To(Succeed()) 65 }) 66 67 It("should create aptos node", func() { 68 if os.Getenv(shared.EnvUseExistingCluster) != "true" { 69 toCreate.Default() 70 } 71 Expect(k8sClient.Create(context.Background(), toCreate)).Should(Succeed()) 72 }) 73 74 It("Should get aptos node", func() { 75 fetched := &aptosv1alpha1.Node{} 76 Expect(k8sClient.Get(context.Background(), key, fetched)).To(Succeed()) 77 Expect(fetched.Spec).To(Equal(toCreate.Spec)) 78 nodeOwnerReference.UID = fetched.UID 79 time.Sleep(5 * time.Second) 80 }) 81 82 It("Should create node statefulset", func() { 83 fetched := &appsv1.StatefulSet{} 84 Expect(k8sClient.Get(context.Background(), key, fetched)).To(Succeed()) 85 Expect(fetched.OwnerReferences).To(ContainElements(nodeOwnerReference)) 86 Expect(*fetched.Spec.Template.Spec.SecurityContext).To(gstruct.MatchFields(gstruct.IgnoreExtras, gstruct.Fields{ 87 "RunAsUser": gstruct.PointTo(Equal(int64(1000))), 88 "RunAsGroup": gstruct.PointTo(Equal(int64(3000))), 89 "FSGroup": gstruct.PointTo(Equal(int64(2000))), 90 "RunAsNonRoot": gstruct.PointTo(Equal(true)), 91 })) 92 Expect(fetched.Spec.Template.Spec.Containers[0].Image).To(Equal(testImage)) 93 }) 94 95 It("Should create allocate correct resources to node statefulset", func() { 96 fetched := &appsv1.StatefulSet{} 97 expectedResources := corev1.ResourceRequirements{ 98 Requests: corev1.ResourceList{ 99 corev1.ResourceCPU: resource.MustParse(aptosv1alpha1.DefaultNodeCPURequest), 100 corev1.ResourceMemory: resource.MustParse(aptosv1alpha1.DefaultNodeMemoryRequest), 101 }, 102 Limits: corev1.ResourceList{ 103 corev1.ResourceCPU: resource.MustParse(aptosv1alpha1.DefaultNodeCPULimit), 104 corev1.ResourceMemory: resource.MustParse(aptosv1alpha1.DefaultNodeMemoryLimit), 105 }, 106 } 107 Expect(k8sClient.Get(context.Background(), key, fetched)).To(Succeed()) 108 Expect(fetched.Spec.Template.Spec.Containers[0].Resources).To(Equal(expectedResources)) 109 }) 110 111 It("Should create node configmap", func() { 112 fetched := &corev1.ConfigMap{} 113 Expect(k8sClient.Get(context.Background(), key, fetched)).To(Succeed()) 114 Expect(fetched.OwnerReferences).To(ContainElements(nodeOwnerReference)) 115 Expect(fetched.Data).To(HaveKey("config.yaml")) 116 117 }) 118 119 It("Should create node data persistent volume with correct resources", func() { 120 fetched := &corev1.PersistentVolumeClaim{} 121 Expect(k8sClient.Get(context.Background(), key, fetched)).To(Succeed()) 122 Expect(fetched.OwnerReferences).To(ContainElements(nodeOwnerReference)) 123 expectedResources := corev1.VolumeResourceRequirements{ 124 Requests: corev1.ResourceList{ 125 corev1.ResourceStorage: resource.MustParse(aptosv1alpha1.DefaultNodeStorageRequest), 126 }, 127 } 128 Expect(fetched.Spec.Resources).To(Equal(expectedResources)) 129 }) 130 131 It("Should create node service", func() { 132 fetched := &corev1.Service{} 133 Expect(k8sClient.Get(context.Background(), key, fetched)).To(Succeed()) 134 Expect(fetched.OwnerReferences).To(ContainElements(nodeOwnerReference)) 135 Expect(fetched.Spec.Ports).To(ContainElements( 136 []corev1.ServicePort{ 137 { 138 Name: "p2p", 139 Port: int32(spec.P2PPort), 140 TargetPort: intstr.FromString("p2p"), 141 Protocol: corev1.ProtocolTCP, 142 }, 143 { 144 Name: "metrics", 145 Port: int32(spec.MetricsPort), 146 TargetPort: intstr.FromString("metrics"), 147 Protocol: corev1.ProtocolTCP, 148 }, 149 { 150 Name: "api", 151 Port: int32(spec.APIPort), 152 TargetPort: intstr.FromString("api"), 153 Protocol: corev1.ProtocolTCP, 154 }, 155 }, 156 )) 157 }) 158 159 It(fmt.Sprintf("Should delete %s namespace", ns.Name), func() { 160 Expect(k8sClient.Delete(context.Background(), ns)).To(Succeed()) 161 }) 162 163 })