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