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