Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
test: Added tests for field validations
Signed-off-by: ntkathole <nikhilkathole2683@gmail.com>
  • Loading branch information
ntkathole committed Jun 13, 2025
commit 6ace5ecd0081b5e690557912081927985a4c2fd0
169 changes: 169 additions & 0 deletions infra/feast-operator/test/api/featurestore_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func boolPtr(b bool) *bool {
return &b
}

func createFeatureStore() *feastdevv1alpha1.FeatureStore {
return &feastdevv1alpha1.FeatureStore{
ObjectMeta: metav1.ObjectMeta{
Expand Down Expand Up @@ -336,6 +340,104 @@ func registryStoreWithDBPersistenceType(dbPersistenceType string, featureStore *
return fsCopy
}

func registryWithRestAPIFalse(featureStore *feastdevv1alpha1.FeatureStore) *feastdevv1alpha1.FeatureStore {
fsCopy := featureStore.DeepCopy()
fsCopy.Spec.Services = &feastdevv1alpha1.FeatureStoreServices{
Registry: &feastdevv1alpha1.Registry{
Local: &feastdevv1alpha1.LocalRegistryConfig{
Server: &feastdevv1alpha1.RegistryServerConfigs{
RestAPI: boolPtr(false),
},
},
},
}
return fsCopy
}

func registryWithOnlyRestAPI(featureStore *feastdevv1alpha1.FeatureStore) *feastdevv1alpha1.FeatureStore {
fsCopy := featureStore.DeepCopy()
fsCopy.Spec.Services = &feastdevv1alpha1.FeatureStoreServices{
Registry: &feastdevv1alpha1.Registry{
Local: &feastdevv1alpha1.LocalRegistryConfig{
Server: &feastdevv1alpha1.RegistryServerConfigs{
RestAPI: boolPtr(true),
},
},
},
}
return fsCopy
}

func registryWithOnlyGRPC(featureStore *feastdevv1alpha1.FeatureStore) *feastdevv1alpha1.FeatureStore {
fsCopy := featureStore.DeepCopy()
fsCopy.Spec.Services = &feastdevv1alpha1.FeatureStoreServices{
Registry: &feastdevv1alpha1.Registry{
Local: &feastdevv1alpha1.LocalRegistryConfig{
Server: &feastdevv1alpha1.RegistryServerConfigs{
GRPC: boolPtr(true),
},
},
},
}
return fsCopy
}

func registryWithBothAPIs(featureStore *feastdevv1alpha1.FeatureStore) *feastdevv1alpha1.FeatureStore {
fsCopy := featureStore.DeepCopy()
fsCopy.Spec.Services = &feastdevv1alpha1.FeatureStoreServices{
Registry: &feastdevv1alpha1.Registry{
Local: &feastdevv1alpha1.LocalRegistryConfig{
Server: &feastdevv1alpha1.RegistryServerConfigs{
RestAPI: boolPtr(true),
GRPC: boolPtr(true),
},
},
},
}
return fsCopy
}

func registryWithNoAPIs(featureStore *feastdevv1alpha1.FeatureStore) *feastdevv1alpha1.FeatureStore {
fsCopy := featureStore.DeepCopy()
fsCopy.Spec.Services = &feastdevv1alpha1.FeatureStoreServices{
Registry: &feastdevv1alpha1.Registry{
Local: &feastdevv1alpha1.LocalRegistryConfig{
Server: &feastdevv1alpha1.RegistryServerConfigs{},
},
},
}
return fsCopy
}

func registryWithBothFalse(featureStore *feastdevv1alpha1.FeatureStore) *feastdevv1alpha1.FeatureStore {
fsCopy := featureStore.DeepCopy()
fsCopy.Spec.Services = &feastdevv1alpha1.FeatureStoreServices{
Registry: &feastdevv1alpha1.Registry{
Local: &feastdevv1alpha1.LocalRegistryConfig{
Server: &feastdevv1alpha1.RegistryServerConfigs{
RestAPI: boolPtr(false),
GRPC: boolPtr(false),
},
},
},
}
return fsCopy
}

func registryWithGRPCFalse(featureStore *feastdevv1alpha1.FeatureStore) *feastdevv1alpha1.FeatureStore {
fsCopy := featureStore.DeepCopy()
fsCopy.Spec.Services = &feastdevv1alpha1.FeatureStoreServices{
Registry: &feastdevv1alpha1.Registry{
Local: &feastdevv1alpha1.LocalRegistryConfig{
Server: &feastdevv1alpha1.RegistryServerConfigs{
GRPC: boolPtr(false),
},
},
},
}
return fsCopy
}

func quotedSlice(stringSlice []string) string {
quotedSlice := make([]string, len(stringSlice))

Expand Down Expand Up @@ -476,4 +578,71 @@ var _ = Describe("FeatureStore API", func() {
attemptInvalidCreationAndAsserts(ctx, authzConfigWithOidc(authzConfigWithKubernetes(featurestore)), "One selection required between kubernetes or oidc")
})
})

Context("When creating a Registry", func() {
ctx := context.Background()

BeforeEach(func() {
By("verifying the custom resource FeatureStore is not there")
resource := &feastdevv1alpha1.FeatureStore{}
err := k8sClient.Get(ctx, typeNamespacedName, resource)
Expect(err != nil && errors.IsNotFound(err)).To(BeTrue())
})
AfterEach(func() {
By("Cleaning up the test resource")
resource := &feastdevv1alpha1.FeatureStore{}
err := k8sClient.Get(ctx, typeNamespacedName, resource)
if err == nil {
Expect(k8sClient.Delete(ctx, resource)).To(Succeed())
}
err = k8sClient.Get(ctx, typeNamespacedName, resource)
Expect(err != nil && errors.IsNotFound(err)).To(BeTrue())
})

Context("with valid API configurations", func() {
It("should succeed when restAPI is false and grpc is not specified (defaults to true)", func() {
featurestore := createFeatureStore()
resource := registryWithRestAPIFalse(featurestore)
Expect(k8sClient.Create(ctx, resource)).To(Succeed())
})

It("should succeed when restAPI is true and grpc is not specified (defaults to true)", func() {
featurestore := createFeatureStore()
resource := registryWithOnlyRestAPI(featurestore)
Expect(k8sClient.Create(ctx, resource)).To(Succeed())
})

It("should succeed when only grpc is true", func() {
featurestore := createFeatureStore()
resource := registryWithOnlyGRPC(featurestore)
Expect(k8sClient.Create(ctx, resource)).To(Succeed())
})

It("should succeed when both APIs are true", func() {
featurestore := createFeatureStore()
resource := registryWithBothAPIs(featurestore)
Expect(k8sClient.Create(ctx, resource)).To(Succeed())
})

It("should succeed when no APIs are specified (grpc defaults to true)", func() {
featurestore := createFeatureStore()
resource := registryWithNoAPIs(featurestore)
Expect(k8sClient.Create(ctx, resource)).To(Succeed())
})
})

Context("with invalid API configurations", func() {
It("should fail when both APIs are explicitly false", func() {
featurestore := createFeatureStore()
resource := registryWithBothFalse(featurestore)
attemptInvalidCreationAndAsserts(ctx, resource, "At least one of restAPI or grpc must be true")
})

It("should fail when grpc is false and restAPI is not specified", func() {
featurestore := createFeatureStore()
resource := registryWithGRPCFalse(featurestore)
attemptInvalidCreationAndAsserts(ctx, resource, "At least one of restAPI or grpc must be true")
})
})
})
})