From 8e52af5cfbf2a79f1d69dcc6bf9f527c84d680df Mon Sep 17 00:00:00 2001 From: raaizik Date: Wed, 22 Jul 2026 14:59:22 +0300 Subject: [PATCH] nfs: add unit tests for custom NFS port Add coverage for GetPort defaults and custom values, Service and probe port wiring, Ganesha NFS_Port config, and create-or-update when spec.server.port changes on an existing Service. Signed-off-by: raaizik (cherry picked from commit b97296c47c338ea1af243df57442e9efa8796984) --- pkg/apis/ceph.rook.io/v1/nfs_test.go | 8 ++ pkg/operator/ceph/nfs/spec_test.go | 126 +++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) diff --git a/pkg/apis/ceph.rook.io/v1/nfs_test.go b/pkg/apis/ceph.rook.io/v1/nfs_test.go index a5a2a6d7c..9c8b24af7 100644 --- a/pkg/apis/ceph.rook.io/v1/nfs_test.go +++ b/pkg/apis/ceph.rook.io/v1/nfs_test.go @@ -23,6 +23,14 @@ import ( v1 "k8s.io/api/core/v1" ) +func TestCephNFS_GetPort(t *testing.T) { + nfs := &CephNFS{} + assert.Equal(t, DefaultNFSPort, nfs.GetPort()) + + nfs.Spec.Server.Port = 12049 + assert.Equal(t, int32(12049), nfs.GetPort()) +} + func TestNFSSecuritySpec_Validate(t *testing.T) { isFailing := true isOkay := false diff --git a/pkg/operator/ceph/nfs/spec_test.go b/pkg/operator/ceph/nfs/spec_test.go index 439280a25..7ff01287b 100644 --- a/pkg/operator/ceph/nfs/spec_test.go +++ b/pkg/operator/ceph/nfs/spec_test.go @@ -17,6 +17,7 @@ limitations under the License. package nfs import ( + "context" "testing" cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" @@ -34,6 +35,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/client/fake" ) @@ -456,4 +458,128 @@ func TestDeploymentSpec(t *testing.T) { assert.Equal(t, ganeshaCont.LivenessProbe.FailureThreshold, int32(10)) assert.GreaterOrEqual(t, ganeshaCont.LivenessProbe.TimeoutSeconds, int32(5)) }) + + t.Run("custom nfs port", func(t *testing.T) { + customPort := int32(12049) + nfs := &cephv1.CephNFS{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-nfs", + Namespace: "rook-ceph-test-ns", + }, + Spec: cephv1.NFSGaneshaSpec{ + Server: cephv1.GaneshaServerSpec{ + Active: 1, + Port: customPort, + }, + }, + } + + r, cfg := newDeploymentSpecTest(t) + d, err := r.makeDeployment(nfs, cfg) + assert.NoError(t, err) + + var ganeshaCont *v1.Container + for i := range d.Spec.Template.Spec.Containers { + if d.Spec.Template.Spec.Containers[i].Name == "nfs-ganesha" { + ganeshaCont = &d.Spec.Template.Spec.Containers[i] + break + } + } + assert.NotNil(t, ganeshaCont) + assert.NotNil(t, ganeshaCont.LivenessProbe) + assert.NotNil(t, ganeshaCont.LivenessProbe.Exec) + // rpcinfo encodes the port in network byte order as 127.0.0.1.. + assert.Contains(t, ganeshaCont.LivenessProbe.Exec.Command, "127.0.0.1.47.17") + + svc := r.generateCephNFSService(nfs, cfg) + assert.Equal(t, customPort, svc.Spec.Ports[0].Port) + assert.Equal(t, intstr.FromInt(int(customPort)), svc.Spec.Ports[0].TargetPort) + assert.Empty(t, svc.Spec.ClusterIP) + }) + + t.Run("hostNetwork keeps headless service with custom port", func(t *testing.T) { + hostNetwork := true + customPort := int32(12049) + nfs := &cephv1.CephNFS{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-nfs", + Namespace: "rook-ceph-test-ns", + }, + Spec: cephv1.NFSGaneshaSpec{ + Server: cephv1.GaneshaServerSpec{ + Active: 1, + Port: customPort, + HostNetwork: &hostNetwork, + }, + }, + } + + r, cfg := newDeploymentSpecTest(t) + svc := r.generateCephNFSService(nfs, cfg) + assert.Equal(t, v1.ClusterIPNone, svc.Spec.ClusterIP) + assert.Equal(t, customPort, svc.Spec.Ports[0].Port) + assert.Equal(t, intstr.FromInt(int(customPort)), svc.Spec.Ports[0].TargetPort) + }) +} + +func TestCreateOrUpdateCephNFSServicePort(t *testing.T) { + nfs := &cephv1.CephNFS{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-nfs", + Namespace: "rook-ceph-test-ns", + }, + TypeMeta: controllerTypeMeta, + Spec: cephv1.NFSGaneshaSpec{ + Server: cephv1.GaneshaServerSpec{ + Active: 1, + }, + }, + } + + r, cfg := newDeploymentSpecTest(t) + + err := r.createCephNFSService(nfs, cfg) + assert.NoError(t, err) + + svc, err := r.context.Clientset.CoreV1().Services(nfs.Namespace).Get(context.TODO(), instanceName(nfs, cfg.ID), metav1.GetOptions{}) + assert.NoError(t, err) + assert.Equal(t, cephv1.DefaultNFSPort, svc.Spec.Ports[0].Port) + + expected := svc.DeepCopy() + expected.Spec.Ports[0].Port = 12049 + expected.Spec.Ports[0].TargetPort = intstr.FromInt(12049) + + nfs.Spec.Server.Port = 12049 + err = r.createCephNFSService(nfs, cfg) + assert.NoError(t, err) + + svc, err = r.context.Clientset.CoreV1().Services(nfs.Namespace).Get(context.TODO(), instanceName(nfs, cfg.ID), metav1.GetOptions{}) + assert.NoError(t, err) + assert.Equal(t, expected.Labels, svc.Labels) + assert.Equal(t, expected.Spec, svc.Spec) +} + +func TestGetGaneshaConfigNFSPort(t *testing.T) { + nfs := &cephv1.CephNFS{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-nfs", + Namespace: "rook-ceph", + }, + Spec: cephv1.NFSGaneshaSpec{ + RADOS: cephv1.GaneshaRADOSSpec{ + Pool: ".nfs", + Namespace: "my-nfs", + }, + Server: cephv1.GaneshaServerSpec{ + Active: 1, + }, + }, + } + + cfg := getGaneshaConfig(nfs, cephver.Squid, "a") + assert.Contains(t, cfg, "NFS_Port = 2049;") + + nfs.Spec.Server.Port = 12049 + cfg = getGaneshaConfig(nfs, cephver.Squid, "a") + assert.Contains(t, cfg, "NFS_Port = 12049;") }