Files
my-rook-config/pkg/operator/ceph/object/cosi/controller_test.go
T
Jiffin Tony Thottan 5b5e1c0292 object: add check specific to name and namespace for ceph cosi driver
The name for cephcosi driver should be ceph-cosi-driver and namespace
should same as the rook operator. Otherwise request need to be failed.

Fixes: #13025
Signed-off-by: Jiffin Tony Thottan <thottanjiffin@gmail.com>
2024-01-31 11:32:47 +05:30

315 lines
10 KiB
Go

package cosi
import (
"context"
"os"
"testing"
"github.com/coreos/pkg/capnslog"
cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
rookfake "github.com/rook/rook/pkg/client/clientset/versioned/fake"
"github.com/rook/rook/pkg/client/clientset/versioned/scheme"
"github.com/rook/rook/pkg/clusterd"
"github.com/rook/rook/pkg/operator/test"
exectest "github.com/rook/rook/pkg/util/exec/test"
"github.com/stretchr/testify/assert"
appsv1 "k8s.io/api/apps/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/record"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)
const (
cephObjectStoreName = "my-store"
namespace = "rook-ceph"
)
func TestCephCOSIDriverController(t *testing.T) {
ctx := context.TODO()
capnslog.SetGlobalLogLevel(capnslog.DEBUG)
os.Setenv("ROOK_LOG_LEVEL", "DEBUG")
os.Setenv("POD_NAMESPACE", namespace)
setupNewEnvironment := func(objects ...runtime.Object) *ReconcileCephCOSIDriver {
executor := &exectest.MockExecutor{
MockExecuteCommandWithOutput: func(command string, args ...string) (string, error) {
if args[0] == "status" {
return `{"fsid":"c47cac40-9bee-4d52-823b-ccd803ba5bfe","health":{"checks":{},"status":"HEALTH_ERR"},"pgmap":{"num_pgs":100,"pgs_by_state":[{"state_name":"active+clean","count":100}]}}`, nil
}
return "", nil
},
}
clientset := test.New(t, 3)
c := &clusterd.Context{
Executor: executor,
RookClientset: rookfake.NewSimpleClientset(),
Clientset: clientset,
}
// Register operator types with the runtime scheme.
s := scheme.Scheme
err := appsv1.AddToScheme(s)
if err != nil {
assert.Fail(t, "failed to build scheme")
}
s.AddKnownTypes(cephv1.SchemeGroupVersion, &cephv1.CephObjectStore{})
s.AddKnownTypes(cephv1.SchemeGroupVersion, &cephv1.CephCOSIDriver{})
s.AddKnownTypes(cephv1.SchemeGroupVersion, &cephv1.CephObjectStoreList{})
// Create a fake client to mock API calls.
cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objects...).Build()
return &ReconcileCephCOSIDriver{
client: cl,
scheme: s,
context: c,
recorder: &record.FakeRecorder{},
opManagerContext: ctx,
}
}
req := reconcile.Request{
NamespacedName: types.NamespacedName{
Name: CephCOSIDriverName,
Namespace: namespace,
},
}
t.Run("no requeue no object store or cosi driver exists", func(t *testing.T) {
r := setupNewEnvironment()
res, err := r.Reconcile(ctx, req)
assert.NoError(t, err)
assert.Equal(t, false, res.Requeue)
})
t.Run("object store exists", func(t *testing.T) {
objectStore := &cephv1.CephObjectStore{
ObjectMeta: metav1.ObjectMeta{
Name: cephObjectStoreName,
Namespace: namespace,
},
}
r := setupNewEnvironment(objectStore)
res, err := r.Reconcile(ctx, req)
assert.NoError(t, err)
assert.Equal(t, false, res.Requeue)
cephCOSIDriverDeployment := &appsv1.Deployment{}
err = r.client.Get(ctx, types.NamespacedName{Name: CephCOSIDriverName, Namespace: namespace}, cephCOSIDriverDeployment)
assert.True(t, kerrors.IsNotFound(err))
})
t.Run("ceph cosi driver CRD with disabled mode without any object stores", func(t *testing.T) {
cephCOSIDriver := &cephv1.CephCOSIDriver{
ObjectMeta: metav1.ObjectMeta{
Name: CephCOSIDriverName,
Namespace: namespace,
},
Spec: cephv1.CephCOSIDriverSpec{
DeploymentStrategy: cephv1.COSIDeploymentStrategyNever,
},
}
r := setupNewEnvironment(cephCOSIDriver)
res, err := r.Reconcile(ctx, req)
assert.NoError(t, err)
assert.Equal(t, false, res.Requeue)
cephCOSIDriverDeployment := &appsv1.Deployment{}
err = r.client.Get(ctx, types.NamespacedName{Name: cephCOSIDriver.Name, Namespace: cephCOSIDriver.Namespace}, cephCOSIDriverDeployment)
assert.Error(t, err)
})
t.Run("ceph cosi driver CRD with disabled mode with object stores", func(t *testing.T) {
cephCOSIDriver := &cephv1.CephCOSIDriver{
ObjectMeta: metav1.ObjectMeta{
Name: CephCOSIDriverName,
Namespace: namespace,
},
Spec: cephv1.CephCOSIDriverSpec{
DeploymentStrategy: cephv1.COSIDeploymentStrategyNever,
},
}
objectStore := &cephv1.CephObjectStore{
ObjectMeta: metav1.ObjectMeta{
Name: cephObjectStoreName,
Namespace: namespace,
},
}
r := setupNewEnvironment(cephCOSIDriver, objectStore)
res, err := r.Reconcile(ctx, req)
assert.NoError(t, err)
assert.Equal(t, false, res.Requeue)
cephCOSIDriverDeployment := &appsv1.Deployment{}
err = r.client.Get(ctx, types.NamespacedName{Name: cephCOSIDriver.Name, Namespace: cephCOSIDriver.Namespace}, cephCOSIDriverDeployment)
assert.Error(t, err)
})
t.Run("ceph cosi driver CRD with enforced mode without any object stores", func(t *testing.T) {
cephCOSIDriver := &cephv1.CephCOSIDriver{
ObjectMeta: metav1.ObjectMeta{
Name: CephCOSIDriverName,
Namespace: namespace,
},
Spec: cephv1.CephCOSIDriverSpec{
DeploymentStrategy: cephv1.COSIDeploymentStrategyAlways,
},
}
r := setupNewEnvironment(cephCOSIDriver)
res, err := r.Reconcile(ctx, req)
assert.NoError(t, err)
assert.Equal(t, false, res.Requeue)
cephCOSIDriverDeployment := &appsv1.Deployment{}
err = r.client.Get(ctx, types.NamespacedName{Name: cephCOSIDriver.Name, Namespace: cephCOSIDriver.Namespace}, cephCOSIDriverDeployment)
assert.NoError(t, err)
})
t.Run("ceph cosi driver CRD with auto mode without object stores", func(t *testing.T) {
cephCOSIDriver := &cephv1.CephCOSIDriver{
ObjectMeta: metav1.ObjectMeta{
Name: CephCOSIDriverName,
Namespace: namespace,
},
Spec: cephv1.CephCOSIDriverSpec{
DeploymentStrategy: cephv1.COSIDeploymentStrategyAuto,
},
}
r := setupNewEnvironment(cephCOSIDriver)
res, err := r.Reconcile(ctx, req)
assert.NoError(t, err)
assert.Equal(t, true, res.Requeue)
cephCOSIDriverDeployment := &appsv1.Deployment{}
err = r.client.Get(ctx, types.NamespacedName{Name: cephCOSIDriver.Name, Namespace: cephCOSIDriver.Namespace}, cephCOSIDriverDeployment)
assert.Error(t, err)
})
t.Run("ceph cosi driver CRD with auto mode with object stores", func(t *testing.T) {
cephCOSIDriver := &cephv1.CephCOSIDriver{
ObjectMeta: metav1.ObjectMeta{
Name: CephCOSIDriverName,
Namespace: namespace,
},
Spec: cephv1.CephCOSIDriverSpec{
DeploymentStrategy: cephv1.COSIDeploymentStrategyAuto,
},
}
objectStore := &cephv1.CephObjectStore{
ObjectMeta: metav1.ObjectMeta{
Name: cephObjectStoreName,
Namespace: namespace,
},
}
r := setupNewEnvironment(cephCOSIDriver, objectStore)
res, err := r.Reconcile(ctx, req)
assert.NoError(t, err)
assert.Equal(t, false, res.Requeue)
cephCOSIDriverDeployment := &appsv1.Deployment{}
err = r.client.Get(ctx, types.NamespacedName{Name: cephCOSIDriver.Name, Namespace: cephCOSIDriver.Namespace}, cephCOSIDriverDeployment)
assert.NoError(t, err)
})
t.Run("ceph cosi driver CRD with custom values and no object stores", func(t *testing.T) {
cephCOSIDriver := &cephv1.CephCOSIDriver{
ObjectMeta: metav1.ObjectMeta{
Name: CephCOSIDriverName,
Namespace: namespace,
},
Spec: cephv1.CephCOSIDriverSpec{
Image: "quay.io/ceph/cosi:custom",
DeploymentStrategy: cephv1.COSIDeploymentStrategyAuto,
},
}
r := setupNewEnvironment(cephCOSIDriver)
res, err := r.Reconcile(ctx, req)
assert.NoError(t, err)
assert.Equal(t, true, res.Requeue)
cephCOSIDriverDeployment := &appsv1.Deployment{}
err = r.client.Get(ctx, types.NamespacedName{Name: cephCOSIDriver.Name, Namespace: cephCOSIDriver.Namespace}, cephCOSIDriverDeployment)
assert.Error(t, err)
})
t.Run("ceph cosi driver CRD with custom values and object stores", func(t *testing.T) {
cephCOSIDriver := &cephv1.CephCOSIDriver{
ObjectMeta: metav1.ObjectMeta{
Name: CephCOSIDriverName,
Namespace: namespace,
},
Spec: cephv1.CephCOSIDriverSpec{
Image: "quay.io/ceph/cosi:custom",
DeploymentStrategy: cephv1.COSIDeploymentStrategyAuto,
},
}
objectStore := &cephv1.CephObjectStore{
ObjectMeta: metav1.ObjectMeta{
Name: cephObjectStoreName,
Namespace: namespace,
},
}
r := setupNewEnvironment(cephCOSIDriver, objectStore)
res, err := r.Reconcile(ctx, req)
assert.NoError(t, err)
assert.Equal(t, false, res.Requeue)
cephCOSIDriverDeployment := &appsv1.Deployment{}
err = r.client.Get(ctx, types.NamespacedName{Name: cephCOSIDriver.Name, Namespace: cephCOSIDriver.Namespace}, cephCOSIDriverDeployment)
assert.NoError(t, err)
assert.Equal(t, "quay.io/ceph/cosi:custom", cephCOSIDriverDeployment.Spec.Template.Spec.Containers[0].Image)
})
t.Run("ceph cosi driver CRD with custom namespace", func(t *testing.T) {
cephCOSIDriver := &cephv1.CephCOSIDriver{
ObjectMeta: metav1.ObjectMeta{
Name: CephCOSIDriverName,
Namespace: "custom-namespace",
},
Spec: cephv1.CephCOSIDriverSpec{
Image: "quay.io/ceph/cosi:custom",
DeploymentStrategy: cephv1.COSIDeploymentStrategyAuto,
},
}
r := setupNewEnvironment(cephCOSIDriver)
req := reconcile.Request{
NamespacedName: types.NamespacedName{
Name: CephCOSIDriverName,
Namespace: "custom-namespace",
},
}
res, err := r.Reconcile(ctx, req)
assert.Error(t, err)
assert.Equal(t, false, res.Requeue)
})
t.Run("multiple ceph cosi driver CRDs", func(t *testing.T) {
cephCOSIDriver1 := &cephv1.CephCOSIDriver{
ObjectMeta: metav1.ObjectMeta{
Name: "ceph-cosi-driver-1",
Namespace: namespace,
},
Spec: cephv1.CephCOSIDriverSpec{
Image: "quay.io/ceph/cosi:custom",
DeploymentStrategy: cephv1.COSIDeploymentStrategyAuto,
},
}
cephCOSIDriver2 := &cephv1.CephCOSIDriver{
ObjectMeta: metav1.ObjectMeta{
Name: "ceph-cosi-driver-2",
Namespace: namespace,
},
Spec: cephv1.CephCOSIDriverSpec{
Image: "quay.io/ceph/cosi:custom",
DeploymentStrategy: cephv1.COSIDeploymentStrategyAuto,
},
}
r := setupNewEnvironment(cephCOSIDriver1, cephCOSIDriver2)
req := reconcile.Request{
NamespacedName: types.NamespacedName{
Name: "ceph-cosi-driver-1",
Namespace: namespace,
},
}
res, err := r.Reconcile(ctx, req)
assert.Error(t, err)
assert.Equal(t, false, res.Requeue)
})
}