Skip to content

Commit

Permalink
feat: Adding first feast operator e2e test. (#4791)
Browse files Browse the repository at this point in the history
* Abstracted the code to reuse the validations across different test cases. Incorporated the code review comments.

Signed-off-by: lrangine <19699092+lokeshrangineni@users.noreply.github.com>

* Abstracted the code to reuse the validations across different test cases. Incorporated the code review comments.

Signed-off-by: lrangine <19699092+lokeshrangineni@users.noreply.github.com>

* Abstracted the code to reuse the validations across different test cases. Incorporated the code review comments.

Signed-off-by: lrangine <19699092+lokeshrangineni@users.noreply.github.com>

* adding the validations to check featurestore conditions are in ready state.

Signed-off-by: lrangine <19699092+lokeshrangineni@users.noreply.github.com>

* Fixing the integration tests on the PR by updating the make target as per updated code.

Signed-off-by: lrangine <19699092+lokeshrangineni@users.noreply.github.com>

* Fixing lint errors with line length

Signed-off-by: lrangine <19699092+lokeshrangineni@users.noreply.github.com>

* changing the feast operator image name to localhost to incorporate code review comment.

Signed-off-by: lrangine <19699092+lokeshrangineni@users.noreply.github.com>

---------

Signed-off-by: lrangine <19699092+lokeshrangineni@users.noreply.github.com>
  • Loading branch information
lokeshrangineni authored Dec 5, 2024
1 parent dc9f825 commit 8339f8d
Show file tree
Hide file tree
Showing 5 changed files with 326 additions and 61 deletions.
6 changes: 3 additions & 3 deletions infra/feast-operator/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ docker-build: ## Build docker image with the manager.
$(CONTAINER_TOOL) build -t ${IMG} .

## Build feast docker image.
.PHONY: feast-docker-build
feast-image-build:
cd ./../.. && VERSION=operator.v0 REGISTRY=example.com make build-feature-transformation-server-docker
.PHONY: feast-ci-dev-docker-img
feast-ci-dev-docker-img:
cd ./../.. && make build-feature-server-dev


.PHONY: docker-push
Expand Down
25 changes: 25 additions & 0 deletions infra/feast-operator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,28 @@ 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.



## Running End-to-End integration tests on local(dev) environment
You need a kind cluster to run the e2e tests on local(dev) environment.

```shell
# Default kind cluster configuration is not enough to run all the pods. In my case i was using docker with colima. kind uses the cpi and memory assigned to docker.
# below memory configuration worked well but if you are using other docker runtime then please increase the cpu and memory.
colima start --cpu 10 --memory 15 --disk 100

# create the kind cluster
kind create cluster

# set kubernetes context to the recently created kind cluster
kubectl cluster-info --context kind-kind

# run the command from operator directory to run e2e tests.
make test-e2e

# delete cluster once you are done.
kind delete cluster
```



156 changes: 98 additions & 58 deletions infra/feast-operator/test/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,40 +27,26 @@ import (
"github.com/feast-dev/feast/infra/feast-operator/test/utils"
)

const namespace = "feast-operator-system"
const feastControllerNamespace = "feast-operator-system"

var _ = Describe("controller", Ordered, func() {
BeforeAll(func() {
By("installing prometheus operator")
Expect(utils.InstallPrometheusOperator()).To(Succeed())

By("installing the cert-manager")
Expect(utils.InstallCertManager()).To(Succeed())

By("creating manager namespace")
cmd := exec.Command("kubectl", "create", "ns", namespace)
cmd := exec.Command("kubectl", "create", "ns", feastControllerNamespace)
_, _ = utils.Run(cmd)
})

AfterAll(func() {
By("uninstalling the Prometheus manager bundle")
utils.UninstallPrometheusOperator()

By("uninstalling the cert-manager bundle")
utils.UninstallCertManager()

By("removing manager namespace")
cmd := exec.Command("kubectl", "delete", "ns", namespace)
_, _ = utils.Run(cmd)
//Add any post clean up code here.
})

Context("Operator", func() {
It("should run successfully", func() {
var controllerPodName string
It("Should be able to deploy and run a default feature store CR successfully", func() {
//var controllerPodName string
var err error

// projectimage stores the name of the image used in the example
var projectimage = "example.com/feast-operator:v0.0.1"
var projectimage = "localhost/feast-operator:v0.0.1"

By("building the manager(Operator) image")
cmd := exec.Command("make", "docker-build", fmt.Sprintf("IMG=%s", projectimage))
Expand All @@ -72,13 +58,20 @@ var _ = Describe("controller", Ordered, func() {
ExpectWithOffset(1, err).NotTo(HaveOccurred())

By("building the feast image")
cmd = exec.Command("make", "feast-image-build")
cmd = exec.Command("make", "feast-ci-dev-docker-img")
_, err = utils.Run(cmd)
ExpectWithOffset(1, err).NotTo(HaveOccurred())
// this image will be built in above make target.
var feastImage = "feastdev/feature-server:dev"
var feastLocalImage = "localhost/feastdev/feature-server:dev"

By("Tag the local feast image for the integration tests")
cmd = exec.Command("docker", "image", "tag", feastImage, feastLocalImage)
_, err = utils.Run(cmd)
ExpectWithOffset(1, err).NotTo(HaveOccurred())

var feastImage = "example.com/feature-transformation-server:operator.v0"
By("loading the the feast image on Kind")
err = utils.LoadImageToKindClusterWithName(feastImage)
By("loading the the feast image on Kind cluster")
err = utils.LoadImageToKindClusterWithName(feastLocalImage)
ExpectWithOffset(1, err).NotTo(HaveOccurred())

By("installing CRDs")
Expand All @@ -91,41 +84,88 @@ var _ = Describe("controller", Ordered, func() {
_, err = utils.Run(cmd)
ExpectWithOffset(1, err).NotTo(HaveOccurred())

By("validating that the controller-manager pod is running as expected")
verifyControllerUp := func() error {
// Get pod name

cmd = exec.Command("kubectl", "get",
"pods", "-l", "control-plane=controller-manager",
"-o", "go-template={{ range .items }}"+
"{{ if not .metadata.deletionTimestamp }}"+
"{{ .metadata.name }}"+
"{{ \"\\n\" }}{{ end }}{{ end }}",
"-n", namespace,
)

podOutput, err := utils.Run(cmd)
ExpectWithOffset(2, err).NotTo(HaveOccurred())
podNames := utils.GetNonEmptyLines(string(podOutput))
if len(podNames) != 1 {
return fmt.Errorf("expect 1 controller pods running, but got %d", len(podNames))
}
controllerPodName = podNames[0]
ExpectWithOffset(2, controllerPodName).Should(ContainSubstring("controller-manager"))

// Validate pod status
cmd = exec.Command("kubectl", "get",
"pods", controllerPodName, "-o", "jsonpath={.status.phase}",
"-n", namespace,
)
status, err := utils.Run(cmd)
ExpectWithOffset(2, err).NotTo(HaveOccurred())
if string(status) != "Running" {
return fmt.Errorf("controller pod in %s status", status)
}
return nil
timeout := 2 * time.Minute

controllerDeploymentName := "feast-operator-controller-manager"
By("Validating that the controller-manager deployment is in available state")
err = checkIfDeploymentExistsAndAvailable(feastControllerNamespace, controllerDeploymentName, timeout)
Expect(err).To(BeNil(), fmt.Sprintf(
"Deployment %s is not available but expected to be available. \nError: %v\n",
controllerDeploymentName, err,
))
fmt.Printf("Feast Control Manager Deployment %s is available\n", controllerDeploymentName)

By("deploying the Simple Feast Custom Resource to Kubernetes")
cmd = exec.Command("kubectl", "apply", "-f",
"test/testdata/feast_integration_test_crs/v1alpha1_default_featurestore.yaml")
_, cmdOutputerr := utils.Run(cmd)
ExpectWithOffset(1, cmdOutputerr).NotTo(HaveOccurred())

namespace := "default"

deploymentNames := [3]string{"feast-simple-feast-setup-registry", "feast-simple-feast-setup-online",
"feast-simple-feast-setup-offline"}
for _, deploymentName := range deploymentNames {
By(fmt.Sprintf("validate the feast deployment: %s is up and in availability state.", deploymentName))
err = checkIfDeploymentExistsAndAvailable(namespace, deploymentName, timeout)
Expect(err).To(BeNil(), fmt.Sprintf(
"Deployment %s is not available but expected to be available. \nError: %v\n",
deploymentName, err,
))
fmt.Printf("Feast Deployment %s is available\n", deploymentName)
}
EventuallyWithOffset(1, verifyControllerUp, time.Minute, time.Second).Should(Succeed())

By("Check if the feast client - kubernetes config map exists.")
configMapName := "feast-simple-feast-setup-client"
err = checkIfConfigMapExists(namespace, configMapName)
Expect(err).To(BeNil(), fmt.Sprintf(
"config map %s is not available but expected to be available. \nError: %v\n",
configMapName, err,
))
fmt.Printf("Feast Deployment %s is available\n", configMapName)

serviceAccountNames := [3]string{"feast-simple-feast-setup-registry", "feast-simple-feast-setup-online",
"feast-simple-feast-setup-offline"}
for _, serviceAccountName := range serviceAccountNames {
By(fmt.Sprintf("validate the feast service account: %s is available.", serviceAccountName))
err = checkIfServiceAccountExists(namespace, serviceAccountName)
Expect(err).To(BeNil(), fmt.Sprintf(
"Service account %s does not exist in namespace %s. Error: %v",
serviceAccountName, namespace, err,
))
fmt.Printf("Service account %s exists in namespace %s\n", serviceAccountName, namespace)
}

serviceNames := [3]string{"feast-simple-feast-setup-registry", "feast-simple-feast-setup-online",
"feast-simple-feast-setup-offline"}
for _, serviceName := range serviceNames {
By(fmt.Sprintf("validate the kubernetes service name: %s is available.", serviceName))
err = checkIfKubernetesServiceExists(namespace, serviceName)
Expect(err).To(BeNil(), fmt.Sprintf(
"kubernetes service %s is not available but expected to be available. \nError: %v\n",
serviceName, err,
))
fmt.Printf("kubernetes service %s is available\n", serviceName)
}

By(fmt.Sprintf("Checking FeatureStore customer resource: %s is in Ready Status.", "simple-feast-setup"))
err = checkIfFeatureStoreCustomResourceConditionsInReady("simple-feast-setup", namespace)
Expect(err).To(BeNil(), fmt.Sprintf(
"FeatureStore custom resource %s all conditions are not in ready state. \nError: %v\n",
"simple-feast-setup", err,
))
fmt.Printf("FeatureStore customer resource %s conditions are in Ready State\n", "simple-feast-setup")

By("deleting the feast deployment")
cmd = exec.Command("kubectl", "delete", "-f",
"test/testdata/feast_integration_test_crs/v1alpha1_default_featurestore.yaml")
_, cmdOutputerr = utils.Run(cmd)
ExpectWithOffset(1, cmdOutputerr).NotTo(HaveOccurred())

By("Uninstalling the feast CRD")
cmd = exec.Command("kubectl", "delete", "deployment", controllerDeploymentName, "-n", feastControllerNamespace)
_, err = utils.Run(cmd)
ExpectWithOffset(1, err).NotTo(HaveOccurred())

})
})
Expand Down
Loading

0 comments on commit 8339f8d

Please sign in to comment.