forked from rook/rook
following the design from here: https://github.com/rook/rook/blob/master/design/ceph/object/ceph-bucket-notification-crd.md Closes: https://github.com/rook/rook/issues/5313 Signed-off-by: Yuval Lifshitz <ylifshit@redhat.com>
294 lines
12 KiB
Go
294 lines
12 KiB
Go
/*
|
|
Copyright 2021 The Rook Authors. All rights reserved.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package cluster
|
|
|
|
import (
|
|
"testing"
|
|
|
|
cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
|
|
"github.com/rook/rook/pkg/clusterd"
|
|
"github.com/stretchr/testify/assert"
|
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
|
|
)
|
|
|
|
func TestCephClusterDependents(t *testing.T) {
|
|
scheme := runtime.NewScheme()
|
|
assert.NoError(t, cephv1.AddToScheme(scheme))
|
|
|
|
ns := "test-ceph-cluster-dependents"
|
|
|
|
var c *clusterd.Context
|
|
|
|
newClusterdCtx := func(objects ...client.Object) *clusterd.Context {
|
|
return &clusterd.Context{
|
|
Client: fakeclient.NewClientBuilder().WithScheme(scheme).WithObjects(objects...).Build(),
|
|
}
|
|
}
|
|
|
|
// Create objectmeta with the given name in our test namespace
|
|
meta := func(name string) v1.ObjectMeta {
|
|
return v1.ObjectMeta{
|
|
Name: name,
|
|
Namespace: ns,
|
|
}
|
|
}
|
|
|
|
t.Run("CephBlockPools", func(t *testing.T) {
|
|
c = newClusterdCtx(
|
|
&cephv1.CephBlockPool{ObjectMeta: meta("block-pool-1")},
|
|
&cephv1.CephBlockPool{ObjectMeta: meta("block-pool-2")},
|
|
)
|
|
deps, err := CephClusterDependents(c, ns)
|
|
assert.NoError(t, err)
|
|
assert.False(t, deps.Empty())
|
|
assert.ElementsMatch(t, []string{"CephBlockPool"}, deps.PluralKinds())
|
|
assert.ElementsMatch(t, []string{"block-pool-1", "block-pool-2"}, deps.OfKind("CephBlockPool"))
|
|
})
|
|
|
|
t.Run("CephRBDMirrors", func(t *testing.T) {
|
|
c = newClusterdCtx(
|
|
&cephv1.CephRBDMirror{ObjectMeta: meta("rbdmirror")},
|
|
)
|
|
deps, err := CephClusterDependents(c, ns)
|
|
assert.NoError(t, err)
|
|
assert.False(t, deps.Empty())
|
|
assert.ElementsMatch(t, []string{"CephRBDMirror"}, deps.PluralKinds())
|
|
assert.ElementsMatch(t, []string{"rbdmirror"}, deps.OfKind("CephRBDMirror"))
|
|
})
|
|
|
|
t.Run("CephFilesystems", func(t *testing.T) {
|
|
c = newClusterdCtx(
|
|
&cephv1.CephFilesystem{ObjectMeta: meta("filesystem-1")},
|
|
&cephv1.CephFilesystem{ObjectMeta: meta("filesystem-2")},
|
|
&cephv1.CephFilesystem{ObjectMeta: meta("filesystem-3")},
|
|
)
|
|
deps, err := CephClusterDependents(c, ns)
|
|
assert.NoError(t, err)
|
|
assert.False(t, deps.Empty())
|
|
assert.ElementsMatch(t, []string{"CephFilesystem"}, deps.PluralKinds())
|
|
assert.ElementsMatch(t, []string{"filesystem-1", "filesystem-2", "filesystem-3"}, deps.OfKind("CephFilesystem"))
|
|
})
|
|
|
|
t.Run("CephFilesystemMirrors", func(t *testing.T) {
|
|
c = newClusterdCtx(
|
|
&cephv1.CephFilesystemMirror{ObjectMeta: meta("fsmirror")},
|
|
)
|
|
deps, err := CephClusterDependents(c, ns)
|
|
assert.NoError(t, err)
|
|
assert.False(t, deps.Empty())
|
|
assert.ElementsMatch(t, []string{"CephFilesystemMirror"}, deps.PluralKinds())
|
|
assert.ElementsMatch(t, []string{"fsmirror"}, deps.OfKind("CephFilesystemMirror"))
|
|
})
|
|
|
|
t.Run("CephObjectStores", func(t *testing.T) {
|
|
c = newClusterdCtx(
|
|
&cephv1.CephObjectStore{ObjectMeta: meta("objectstore-1")},
|
|
&cephv1.CephObjectStore{ObjectMeta: meta("objectstore-2")},
|
|
)
|
|
deps, err := CephClusterDependents(c, ns)
|
|
assert.NoError(t, err)
|
|
assert.False(t, deps.Empty())
|
|
assert.ElementsMatch(t, []string{"CephObjectStore"}, deps.PluralKinds())
|
|
assert.ElementsMatch(t, []string{"objectstore-1", "objectstore-2"}, deps.OfKind("CephObjectStore"))
|
|
})
|
|
|
|
t.Run("CephObjectStoreUsers", func(t *testing.T) {
|
|
c = newClusterdCtx(
|
|
&cephv1.CephObjectStoreUser{ObjectMeta: meta("u1")},
|
|
&cephv1.CephObjectStoreUser{ObjectMeta: meta("u2")},
|
|
&cephv1.CephObjectStoreUser{ObjectMeta: meta("u3")},
|
|
&cephv1.CephObjectStoreUser{ObjectMeta: meta("u4")},
|
|
&cephv1.CephObjectStoreUser{ObjectMeta: meta("u5")},
|
|
)
|
|
deps, err := CephClusterDependents(c, ns)
|
|
assert.NoError(t, err)
|
|
assert.False(t, deps.Empty())
|
|
assert.ElementsMatch(t, []string{"CephObjectStoreUser"}, deps.PluralKinds())
|
|
assert.ElementsMatch(t, []string{"u1", "u2", "u3", "u4", "u5"}, deps.OfKind("CephObjectStoreUser"))
|
|
})
|
|
|
|
t.Run("CephObjectZones", func(t *testing.T) {
|
|
c = newClusterdCtx(
|
|
&cephv1.CephObjectZone{ObjectMeta: meta("zone-1")},
|
|
&cephv1.CephObjectZone{ObjectMeta: meta("zone-2")},
|
|
)
|
|
deps, err := CephClusterDependents(c, ns)
|
|
assert.NoError(t, err)
|
|
assert.False(t, deps.Empty())
|
|
assert.ElementsMatch(t, []string{"CephObjectZone"}, deps.PluralKinds())
|
|
assert.ElementsMatch(t, []string{"zone-1", "zone-2"}, deps.OfKind("CephObjectZone"))
|
|
})
|
|
|
|
t.Run("CephObjectZoneGroups", func(t *testing.T) {
|
|
c = newClusterdCtx(
|
|
&cephv1.CephObjectZoneGroup{ObjectMeta: meta("group-1")},
|
|
&cephv1.CephObjectZoneGroup{ObjectMeta: meta("group-2")},
|
|
)
|
|
deps, err := CephClusterDependents(c, ns)
|
|
assert.NoError(t, err)
|
|
assert.False(t, deps.Empty())
|
|
assert.ElementsMatch(t, []string{"CephObjectZoneGroup"}, deps.PluralKinds())
|
|
assert.ElementsMatch(t, []string{"group-1", "group-2"}, deps.OfKind("CephObjectZoneGroup"))
|
|
})
|
|
|
|
t.Run("CephObjectRealms", func(t *testing.T) {
|
|
c = newClusterdCtx(
|
|
&cephv1.CephObjectRealm{ObjectMeta: meta("realm-1")},
|
|
&cephv1.CephObjectRealm{ObjectMeta: meta("realm-2")},
|
|
)
|
|
deps, err := CephClusterDependents(c, ns)
|
|
assert.NoError(t, err)
|
|
assert.False(t, deps.Empty())
|
|
assert.ElementsMatch(t, []string{"CephObjectRealm"}, deps.PluralKinds())
|
|
assert.ElementsMatch(t, []string{"realm-1", "realm-2"}, deps.OfKind("CephObjectRealm"))
|
|
})
|
|
|
|
t.Run("CephNFSes", func(t *testing.T) {
|
|
c = newClusterdCtx(
|
|
&cephv1.CephNFS{ObjectMeta: meta("nfs-1")},
|
|
&cephv1.CephNFS{ObjectMeta: meta("nfs-2")},
|
|
)
|
|
deps, err := CephClusterDependents(c, ns)
|
|
assert.NoError(t, err)
|
|
assert.False(t, deps.Empty())
|
|
assert.ElementsMatch(t, []string{"CephNFS"}, deps.PluralKinds())
|
|
assert.ElementsMatch(t, []string{"nfs-1", "nfs-2"}, deps.OfKind("CephNFS"))
|
|
})
|
|
|
|
t.Run("CephClients", func(t *testing.T) {
|
|
c = newClusterdCtx(
|
|
&cephv1.CephClient{ObjectMeta: meta("client-1")},
|
|
&cephv1.CephClient{ObjectMeta: meta("client-2")},
|
|
&cephv1.CephClient{ObjectMeta: meta("client-3")},
|
|
)
|
|
deps, err := CephClusterDependents(c, ns)
|
|
assert.NoError(t, err)
|
|
assert.False(t, deps.Empty())
|
|
assert.ElementsMatch(t, []string{"CephClient"}, deps.PluralKinds())
|
|
assert.ElementsMatch(t, []string{"client-1", "client-2", "client-3"}, deps.OfKind("CephClient"))
|
|
})
|
|
|
|
t.Run("CephBucketTopics", func(t *testing.T) {
|
|
c = newClusterdCtx(
|
|
&cephv1.CephBucketTopic{ObjectMeta: meta("topic-1")},
|
|
&cephv1.CephBucketTopic{ObjectMeta: meta("topic-2")},
|
|
&cephv1.CephBucketTopic{ObjectMeta: meta("topic-3")},
|
|
)
|
|
deps, err := CephClusterDependents(c, ns)
|
|
assert.NoError(t, err)
|
|
assert.False(t, deps.Empty())
|
|
assert.ElementsMatch(t, []string{"CephBucketTopic"}, deps.PluralKinds())
|
|
assert.ElementsMatch(t, []string{"topic-1", "topic-2", "topic-3"}, deps.OfKind("CephBucketTopic"))
|
|
})
|
|
|
|
t.Run("CephBucketNotifications", func(t *testing.T) {
|
|
c = newClusterdCtx(
|
|
&cephv1.CephBucketNotification{ObjectMeta: meta("notif-1")},
|
|
&cephv1.CephBucketNotification{ObjectMeta: meta("notif-2")},
|
|
&cephv1.CephBucketNotification{ObjectMeta: meta("notif-3")},
|
|
)
|
|
deps, err := CephClusterDependents(c, ns)
|
|
assert.NoError(t, err)
|
|
assert.False(t, deps.Empty())
|
|
assert.ElementsMatch(t, []string{"CephBucketNotification"}, deps.PluralKinds())
|
|
assert.ElementsMatch(t, []string{"notif-1", "notif-2", "notif-3"}, deps.OfKind("CephBucketNotification"))
|
|
})
|
|
|
|
t.Run("All", func(t *testing.T) {
|
|
c = newClusterdCtx(
|
|
&cephv1.CephBlockPool{ObjectMeta: meta("pool-1")},
|
|
&cephv1.CephRBDMirror{ObjectMeta: meta("rbdmirror-1")},
|
|
&cephv1.CephRBDMirror{ObjectMeta: meta("rbdmirror-2")},
|
|
&cephv1.CephFilesystem{ObjectMeta: meta("filesystem-1")},
|
|
&cephv1.CephFilesystemMirror{ObjectMeta: meta("fsmirror-1")},
|
|
&cephv1.CephFilesystemMirror{ObjectMeta: meta("fsmirror-2")},
|
|
&cephv1.CephObjectStore{ObjectMeta: meta("objectstore-1")},
|
|
&cephv1.CephObjectStoreUser{ObjectMeta: meta("u1")},
|
|
&cephv1.CephObjectZone{ObjectMeta: meta("zone-1")},
|
|
&cephv1.CephObjectZoneGroup{ObjectMeta: meta("group-1")},
|
|
&cephv1.CephObjectRealm{ObjectMeta: meta("realm-1")},
|
|
&cephv1.CephNFS{ObjectMeta: meta("nfs-1")},
|
|
&cephv1.CephClient{ObjectMeta: meta("client-1")},
|
|
&cephv1.CephBucketTopic{ObjectMeta: meta("topic-1")},
|
|
&cephv1.CephBucketNotification{ObjectMeta: meta("notif-1")},
|
|
)
|
|
deps, err := CephClusterDependents(c, ns)
|
|
assert.NoError(t, err)
|
|
assert.False(t, deps.Empty())
|
|
assert.ElementsMatch(t, []string{"CephBlockPool", "CephRBDMirror", "CephFilesystem",
|
|
"CephFilesystemMirror", "CephObjectStore", "CephObjectStoreUser", "CephObjectZone",
|
|
"CephObjectZoneGroup", "CephObjectRealm", "CephNFS", "CephClient", "CephBucketTopic", "CephBucketNotification"}, deps.PluralKinds())
|
|
assert.ElementsMatch(t, []string{"pool-1"}, deps.OfKind("CephBlockPool"))
|
|
assert.ElementsMatch(t, []string{"rbdmirror-1", "rbdmirror-2"}, deps.OfKind("CephRBDMirror"))
|
|
assert.ElementsMatch(t, []string{"filesystem-1"}, deps.OfKind("CephFilesystem"))
|
|
assert.ElementsMatch(t, []string{"fsmirror-1", "fsmirror-2"}, deps.OfKind("CephFilesystemMirror"))
|
|
assert.ElementsMatch(t, []string{"objectstore-1"}, deps.OfKind("CephObjectStore"))
|
|
assert.ElementsMatch(t, []string{"u1"}, deps.OfKind("CephObjectStoreUser"))
|
|
assert.ElementsMatch(t, []string{"zone-1"}, deps.OfKind("CephObjectZone"))
|
|
assert.ElementsMatch(t, []string{"group-1"}, deps.OfKind("CephObjectZoneGroup"))
|
|
assert.ElementsMatch(t, []string{"realm-1"}, deps.OfKind("CephObjectRealm"))
|
|
assert.ElementsMatch(t, []string{"nfs-1"}, deps.OfKind("CephNFS"))
|
|
assert.ElementsMatch(t, []string{"client-1"}, deps.OfKind("CephClient"))
|
|
assert.ElementsMatch(t, []string{"topic-1"}, deps.OfKind("CephBucketTopic"))
|
|
assert.ElementsMatch(t, []string{"notif-1"}, deps.OfKind("CephBucketNotification"))
|
|
|
|
t.Run("and no dependencies in another namespace", func(t *testing.T) {
|
|
deps, err := CephClusterDependents(c, "other-namespace")
|
|
assert.NoError(t, err)
|
|
assert.True(t, deps.Empty())
|
|
})
|
|
})
|
|
|
|
// TODO: how do we get this to return errors without a reactor? Do we need to add reactors
|
|
// to controller-runtime?
|
|
// Keep the below test commented-out until we can check off the above TODO. For now we will have
|
|
// to assume the errors are handled properly.
|
|
// t.Run("With errors", func(t *testing.T) {
|
|
// // // add reactor to cause failures when listing block and nfs (but not object, fs, or any others)
|
|
// // var listReactor k8stesting.ReactionFunc = func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {
|
|
// // r := action.GetResource().Resource
|
|
// // if r == "cephblockpools" || r == "cephnfses" {
|
|
// // return true, nil, errors.Errorf("fake error listing %q", r)
|
|
// // }
|
|
// // return false, nil, nil
|
|
// // }
|
|
// // dynInt.PrependReactor("list", "*", listReactor)
|
|
|
|
// client := fakeclient.NewClientBuilder().WithScheme(scheme).WithObjects(
|
|
// &cephv1.CephBlockPool{ObjectMeta: meta("pool-1")},
|
|
// &cephv1.CephFilesystem{ObjectMeta: meta("filesystem-1")},
|
|
// &cephv1.CephObjectStore{ObjectMeta: meta("objectstore-1")},
|
|
// ).Build()
|
|
|
|
// c := &clusterd.Context{
|
|
// Client: client,
|
|
// }
|
|
|
|
// deps, err := CephClusterDependents(c, ns)
|
|
// assert.Error(t, err)
|
|
// assert.Contains(t, err.Error(), "CephBlockPool")
|
|
// assert.Contains(t, err.Error(), "CephNFS")
|
|
// assert.False(t, deps.Empty())
|
|
// assert.ElementsMatch(t, []string{"CephFilesystem", "CephObjectStore"}, deps.PluralKinds())
|
|
// assert.ElementsMatch(t, []string{"filesystem-1"}, deps.OfKind("CephFilesystem"))
|
|
// assert.ElementsMatch(t, []string{"objectstore-1"}, deps.OfKind("CephObjectStore"))
|
|
// })
|
|
}
|