package couchctl import ( "fmt" "testing" "github.com/stretchr/testify/require" "gotest.tools/v3/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" "edge-infra.dev/pkg/edge/constants/api/cluster" "edge-infra.dev/pkg/edge/constants/api/fleet" dsapi "edge-infra.dev/pkg/edge/datasync/apis/v1alpha1" "edge-infra.dev/pkg/edge/datasync/couchdb" "edge-infra.dev/test/f2" "edge-infra.dev/test/f2/x/ktest" ) func TestCouchUserReconciler(t *testing.T) { fin := f2.NewFeature("CouchUserReconciler"). WithLabel(_fleetType, fleet.Store, fleet.CouchDB). WithLabel(_clusterType, cluster.Generic, cluster.DSDS, cluster.GKE). Setup("CouchDBUser Created", func(ctx f2.Context, t *testing.T) f2.Context { k := ktest.FromContextT(ctx, t) k.WaitOn(t, k.ObjExists(couchDBServer)) assert.NilError(t, client.IgnoreAlreadyExists(k.Client.Create(ctx, couchDBDUser))) return ctx }). Test("CouchDBServer Ready", testReady(couchDBServer)). Test("CouchDBUser Ready", testReady(couchDBDUser)). Test("K8 Secret Created", func(ctx f2.Context, t *testing.T) f2.Context { k := ktest.FromContextT(ctx, t) user := &couchdb.UserCredentials{} secret, err := user.FromSecret(ctx, k.Client, couchDBDUser.SecretNamespacedName()) require.NoError(t, err) require.NotNil(t, secret) assert.Assert(t, len(user.Username) != 0) assert.Assert(t, len(user.Password) != 0) assert.Assert(t, len(user.URI) != 0) return ctx }). Test("Couchdb User Created", func(ctx f2.Context, t *testing.T) f2.Context { k := ktest.FromContextT(ctx, t) cc, err := couchdbServerClient(ctx, k.Client, couchDBServer) require.NoError(t, err) exists, err := cc.CheckUserAndRolesExists(ctx, couchDBDUser.Spec.User.Name, couchDBDUser.Spec.User.Roles) require.NoError(t, err) require.True(t, exists, "user: %s, ", couchDBDUser.Spec.User.Name) return ctx }). Test("Couchdb User Security Exist In DB", func(ctx f2.Context, t *testing.T) f2.Context { if couchDBServer.IsCloud() { return ctx } k := ktest.FromContextT(ctx, t) cc, err := couchdbServerClient(ctx, k.Client, couchDBServer) require.NoError(t, err) replSet := &dsapi.ReplicationSet{} err = cc.GetReplicationSetDoc(ctx, couchCtlConfig.ReplicationDB(), replSet) require.NoError(t, err) security := userToSecurity(couchDBDUser, couchDBDUser.Spec.User.Name) for _, d := range replSet.Datasets { exists, err := cc.CheckDBUsersAndRoles(ctx, security, d.Name) require.NoError(t, err) require.True(t, exists) } return ctx }). Test("ServerURL Checks", func(ctx f2.Context, t *testing.T) f2.Context { if couchDBServer.IsCloud() { return ctx } couchDBUserURL := getCouchDBUserURL(couchCtlConfig, couchDBServer) serverURL := getServerURL(couchCtlConfig, couchDBServer) name := "data-sync-couchdb" if couchCtlConfig.IsDSDS() { name = "data-sync-couchdb-lane" } require.Equal(t, couchDBUserURL, fmt.Sprintf("%s.data-sync-couchdb.svc.cluster.local", name)) require.Equal(t, serverURL, fmt.Sprintf("http://%s:%s", couchDBServer.Spec.URI, couchCtlConfig.CouchDBPort)) return ctx }). Feature() f.Test(t, fin) } func newCouchDBUser(name, userName string, server *dsapi.CouchDBServer) *dsapi.CouchDBUser { return &dsapi.CouchDBUser{ TypeMeta: metav1.TypeMeta{ APIVersion: dsapi.GroupVersion.String(), Kind: "CouchDBUser", }, ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: server.Namespace, }, Spec: dsapi.CouchDBUserSpec{ Type: dsapi.UserCredentials, ServerRef: server.ServerRef(), User: dsapi.User{ Name: userName, Roles: []string{couchdb.ReadOnlyUser}, }, Provider: &dsapi.Provider{Name: fmt.Sprintf("%s-provider", userName)}, }, } }