Skip to content

Commit d1bf58f

Browse files
authored
test: Added upgrade tests (feast-dev#5072)
Added upgrade tests Signed-off-by: Theodor Mihalache <[email protected]>
1 parent e25ca4f commit d1bf58f

11 files changed

+682
-428
lines changed

.github/workflows/operator-e2e-integration-tests.yml

+25-3
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,30 @@ jobs:
5656
cd infra/feast-operator/
5757
make test-e2e
5858
59+
- name: Clean up docker images
60+
if: always()
61+
run: |
62+
docker images --format '{{.Repository}}:{{.Tag}}' | grep 'feast' | xargs -r docker rmi -f
63+
docker system prune -a -f
64+
65+
- name: Run Previous version tests
66+
run: |
67+
# Run the previous version tests
68+
cd infra/feast-operator/
69+
make test-previous-version
70+
71+
- name: Clean up docker images
72+
if: always()
73+
run: |
74+
docker images --format '{{.Repository}}:{{.Tag}}' | grep 'feast' | xargs -r docker rmi -f
75+
docker system prune -a -f
76+
77+
- name: Run Upgrade tests
78+
run: |
79+
# Run the upgrade tests
80+
cd infra/feast-operator/
81+
make test-upgrade
82+
5983
- name: Debug KIND Cluster when there is a failure
6084
if: failure()
6185
run: |
@@ -66,6 +90,4 @@ jobs:
6690
if: always()
6791
run: |
6892
# Delete the KIND cluster after tests
69-
kind delete cluster --name kind-$KIND_CLUSTER
70-
71-
93+
kind delete cluster --name kind-$KIND_CLUSTER

infra/feast-operator/.golangci.yml

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ issues:
1919
- path: "test/*"
2020
linters:
2121
- lll
22+
- path: "upgrade/*"
23+
linters:
24+
- lll
25+
- path: "previous-version/*"
26+
linters:
27+
- lll
2228
linters:
2329
disable-all: true
2430
enable:

infra/feast-operator/Makefile

+10-2
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,20 @@ vet: ## Run go vet against code.
113113

114114
.PHONY: test
115115
test: build-installer vet lint envtest ## Run tests.
116-
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v test/e2e | grep -v test/data-source-types) -coverprofile cover.out
116+
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v test/e2e | grep -v test/data-source-types | grep -v test/upgrade | grep -v test/previous-version) -coverprofile cover.out
117117

118118
# Utilize Kind or modify the e2e tests to load the image locally, enabling compatibility with other vendors.
119119
.PHONY: test-e2e # Run the e2e tests against a Kind k8s instance that is spun up.
120120
test-e2e:
121-
go test -timeout 30m ./test/e2e/ -v -ginkgo.v
121+
go test -timeout 60m ./test/e2e/ -v -ginkgo.v
122+
123+
.PHONY: test-upgrade # Run the upgrade tests against a Kind k8s instance that is spun up.
124+
test-upgrade:
125+
go test -timeout 60m ./test/upgrade/ -v -ginkgo.v
126+
127+
.PHONY: test-previous-version # Run e2e tests against previous version in a Kind k8s instance that is spun up.
128+
test-previous-version:
129+
go test -timeout 60m ./test/previous-version/ -v -ginkgo.v
122130

123131
# Requires python3
124132
.PHONY: test-datasources

infra/feast-operator/test/e2e/e2e_test.go

+20-199
Original file line numberDiff line numberDiff line change
@@ -17,217 +17,38 @@ limitations under the License.
1717
package e2e
1818

1919
import (
20-
"fmt"
21-
"os"
22-
"os/exec"
23-
"time"
24-
25-
. "github.com/onsi/ginkgo/v2"
26-
. "github.com/onsi/gomega"
27-
2820
"github.com/feast-dev/feast/infra/feast-operator/test/utils"
29-
)
30-
31-
const (
32-
feastControllerNamespace = "feast-operator-system"
33-
timeout = 2 * time.Minute
34-
controllerDeploymentName = "feast-operator-controller-manager"
35-
feastPrefix = "feast-"
21+
. "github.com/onsi/ginkgo/v2"
3622
)
3723

3824
var _ = Describe("controller", Ordered, func() {
39-
BeforeAll(func() {
40-
_, isRunOnOpenShiftCI := os.LookupEnv("RUN_ON_OPENSHIFT_CI")
41-
if !isRunOnOpenShiftCI {
42-
By("creating manager namespace")
43-
cmd := exec.Command("kubectl", "create", "ns", feastControllerNamespace)
44-
_, _ = utils.Run(cmd)
45-
46-
var err error
47-
// projectimage stores the name of the image used in the example
48-
var projectimage = "localhost/feast-operator:v0.0.1"
49-
50-
By("building the manager(Operator) image")
51-
cmd = exec.Command("make", "docker-build", fmt.Sprintf("IMG=%s", projectimage))
52-
_, err = utils.Run(cmd)
53-
ExpectWithOffset(1, err).NotTo(HaveOccurred())
54-
55-
By("loading the the manager(Operator) image on Kind")
56-
err = utils.LoadImageToKindClusterWithName(projectimage)
57-
ExpectWithOffset(1, err).NotTo(HaveOccurred())
58-
59-
// this image will be built in above make target.
60-
var feastImage = "feastdev/feature-server:dev"
61-
var feastLocalImage = "localhost/feastdev/feature-server:dev"
62-
63-
By("building the feast image")
64-
cmd = exec.Command("make", "feast-ci-dev-docker-img")
65-
_, err = utils.Run(cmd)
66-
ExpectWithOffset(1, err).NotTo(HaveOccurred())
67-
68-
By("Tag the local feast image for the integration tests")
69-
cmd = exec.Command("docker", "image", "tag", feastImage, feastLocalImage)
70-
_, err = utils.Run(cmd)
71-
ExpectWithOffset(1, err).NotTo(HaveOccurred())
72-
73-
By("loading the the feast image on Kind cluster")
74-
err = utils.LoadImageToKindClusterWithName(feastLocalImage)
75-
ExpectWithOffset(1, err).NotTo(HaveOccurred())
25+
featureStoreName := "simple-feast-setup"
26+
feastResourceName := utils.FeastPrefix + featureStoreName
27+
feastK8sResourceNames := []string{
28+
feastResourceName + "-online",
29+
feastResourceName + "-offline",
30+
feastResourceName + "-ui",
31+
}
7632

77-
By("installing CRDs")
78-
cmd = exec.Command("make", "install")
79-
_, err = utils.Run(cmd)
80-
ExpectWithOffset(1, err).NotTo(HaveOccurred())
33+
runTestDeploySimpleCRFunc := utils.GetTestDeploySimpleCRFunc("/test/e2e",
34+
"test/testdata/feast_integration_test_crs/v1alpha1_default_featurestore.yaml",
35+
featureStoreName, feastResourceName, feastK8sResourceNames)
8136

82-
By("deploying the controller-manager")
83-
cmd = exec.Command("make", "deploy", fmt.Sprintf("IMG=%s", projectimage), fmt.Sprintf("FS_IMG=%s", feastLocalImage))
84-
_, err = utils.Run(cmd)
85-
ExpectWithOffset(1, err).NotTo(HaveOccurred())
37+
runTestWithRemoteRegistryFunction := utils.GetTestWithRemoteRegistryFunc("/test/e2e",
38+
"test/testdata/feast_integration_test_crs/v1alpha1_default_featurestore.yaml",
39+
"test/testdata/feast_integration_test_crs/v1alpha1_remote_registry_featurestore.yaml",
40+
featureStoreName, feastResourceName, feastK8sResourceNames)
8641

87-
By("Validating that the controller-manager deployment is in available state")
88-
err = checkIfDeploymentExistsAndAvailable(feastControllerNamespace, controllerDeploymentName, timeout)
89-
Expect(err).ToNot(HaveOccurred(), fmt.Sprintf(
90-
"Deployment %s is not available but expected to be available. \nError: %v\n",
91-
controllerDeploymentName, err,
92-
))
93-
fmt.Printf("Feast Control Manager Deployment %s is available\n", controllerDeploymentName)
94-
}
42+
BeforeAll(func() {
43+
utils.DeployOperatorFromCode("/test/e2e")
9544
})
9645

9746
AfterAll(func() {
98-
// Add any post clean up code here.
99-
_, isRunOnOpenShiftCI := os.LookupEnv("RUN_ON_OPENSHIFT_CI")
100-
if !isRunOnOpenShiftCI {
101-
By("Uninstalling the feast CRD")
102-
cmd := exec.Command("kubectl", "delete", "deployment", controllerDeploymentName, "-n", feastControllerNamespace)
103-
_, err := utils.Run(cmd)
104-
ExpectWithOffset(1, err).NotTo(HaveOccurred())
105-
}
47+
utils.DeleteOperatorDeployment("/test/e2e")
10648
})
10749

10850
Context("Operator E2E Tests", func() {
109-
It("Should be able to deploy and run a default feature store CR successfully", func() {
110-
By("deploying the Simple Feast Custom Resource to Kubernetes")
111-
namespace := "default"
112-
113-
cmd := exec.Command("kubectl", "apply", "-f",
114-
"test/testdata/feast_integration_test_crs/v1alpha1_default_featurestore.yaml", "-n", namespace)
115-
_, cmdOutputerr := utils.Run(cmd)
116-
ExpectWithOffset(1, cmdOutputerr).NotTo(HaveOccurred())
117-
118-
featureStoreName := "simple-feast-setup"
119-
validateTheFeatureStoreCustomResource(namespace, featureStoreName, timeout)
120-
121-
By("deleting the feast deployment")
122-
cmd = exec.Command("kubectl", "delete", "-f",
123-
"test/testdata/feast_integration_test_crs/v1alpha1_default_featurestore.yaml")
124-
_, cmdOutputerr = utils.Run(cmd)
125-
ExpectWithOffset(1, cmdOutputerr).NotTo(HaveOccurred())
126-
})
127-
128-
It("Should be able to deploy and run a feature store with remote registry CR successfully", func() {
129-
By("deploying the Simple Feast Custom Resource to Kubernetes")
130-
namespace := "default"
131-
cmd := exec.Command("kubectl", "apply", "-f",
132-
"test/testdata/feast_integration_test_crs/v1alpha1_default_featurestore.yaml", "-n", namespace)
133-
_, cmdOutputErr := utils.Run(cmd)
134-
ExpectWithOffset(1, cmdOutputErr).NotTo(HaveOccurred())
135-
136-
featureStoreName := "simple-feast-setup"
137-
validateTheFeatureStoreCustomResource(namespace, featureStoreName, timeout)
138-
139-
var remoteRegistryNs = "remote-registry"
140-
By(fmt.Sprintf("Creating the remote registry namespace=%s", remoteRegistryNs))
141-
cmd = exec.Command("kubectl", "create", "ns", remoteRegistryNs)
142-
_, _ = utils.Run(cmd)
143-
144-
By("deploying the Simple Feast remote registry Custom Resource on Kubernetes")
145-
cmd = exec.Command("kubectl", "apply", "-f",
146-
"test/testdata/feast_integration_test_crs/v1alpha1_remote_registry_featurestore.yaml", "-n", remoteRegistryNs)
147-
_, cmdOutputErr = utils.Run(cmd)
148-
ExpectWithOffset(1, cmdOutputErr).NotTo(HaveOccurred())
149-
150-
remoteFeatureStoreName := "simple-feast-remote-setup"
151-
152-
validateTheFeatureStoreCustomResource(remoteRegistryNs, remoteFeatureStoreName, timeout)
153-
154-
By("deleting the feast remote registry deployment")
155-
cmd = exec.Command("kubectl", "delete", "-f",
156-
"test/testdata/feast_integration_test_crs/v1alpha1_remote_registry_featurestore.yaml", "-n", remoteRegistryNs)
157-
_, cmdOutputErr = utils.Run(cmd)
158-
ExpectWithOffset(1, cmdOutputErr).NotTo(HaveOccurred())
159-
160-
By("deleting the feast deployment")
161-
cmd = exec.Command("kubectl", "delete", "-f",
162-
"test/testdata/feast_integration_test_crs/v1alpha1_default_featurestore.yaml", "-n", namespace)
163-
_, cmdOutputErr = utils.Run(cmd)
164-
ExpectWithOffset(1, cmdOutputErr).NotTo(HaveOccurred())
165-
})
51+
It("Should be able to deploy and run a default feature store CR successfully", runTestDeploySimpleCRFunc)
52+
It("Should be able to deploy and run a feature store with remote registry CR successfully", runTestWithRemoteRegistryFunction)
16653
})
16754
})
168-
169-
func validateTheFeatureStoreCustomResource(namespace string, featureStoreName string, timeout time.Duration) {
170-
hasRemoteRegistry, err := isFeatureStoreHavingRemoteRegistry(namespace, featureStoreName)
171-
Expect(err).ToNot(HaveOccurred(), fmt.Sprintf(
172-
"Error occurred while checking FeatureStore %s is having remote registry or not. \nError: %v\n",
173-
featureStoreName, err))
174-
175-
feastResourceName := feastPrefix + featureStoreName
176-
k8sResourceNames := []string{feastResourceName}
177-
feastK8sResourceNames := []string{
178-
feastResourceName + "-online",
179-
feastResourceName + "-offline",
180-
feastResourceName + "-ui",
181-
}
182-
183-
if !hasRemoteRegistry {
184-
feastK8sResourceNames = append(feastK8sResourceNames, feastResourceName+"-registry")
185-
}
186-
187-
for _, deploymentName := range k8sResourceNames {
188-
By(fmt.Sprintf("validate the feast deployment: %s is up and in availability state.", deploymentName))
189-
err = checkIfDeploymentExistsAndAvailable(namespace, deploymentName, timeout)
190-
Expect(err).ToNot(HaveOccurred(), fmt.Sprintf(
191-
"Deployment %s is not available but expected to be available. \nError: %v\n",
192-
deploymentName, err,
193-
))
194-
fmt.Printf("Feast Deployment %s is available\n", deploymentName)
195-
}
196-
197-
By("Check if the feast client - kubernetes config map exists.")
198-
configMapName := feastResourceName + "-client"
199-
err = checkIfConfigMapExists(namespace, configMapName)
200-
Expect(err).ToNot(HaveOccurred(), fmt.Sprintf(
201-
"config map %s is not available but expected to be available. \nError: %v\n",
202-
configMapName, err,
203-
))
204-
fmt.Printf("Feast Deployment client config map %s is available\n", configMapName)
205-
206-
for _, serviceAccountName := range k8sResourceNames {
207-
By(fmt.Sprintf("validate the feast service account: %s is available.", serviceAccountName))
208-
err = checkIfServiceAccountExists(namespace, serviceAccountName)
209-
Expect(err).ToNot(HaveOccurred(), fmt.Sprintf(
210-
"Service account %s does not exist in namespace %s. Error: %v",
211-
serviceAccountName, namespace, err,
212-
))
213-
fmt.Printf("Service account %s exists in namespace %s\n", serviceAccountName, namespace)
214-
}
215-
216-
for _, serviceName := range feastK8sResourceNames {
217-
By(fmt.Sprintf("validate the kubernetes service name: %s is available.", serviceName))
218-
err = checkIfKubernetesServiceExists(namespace, serviceName)
219-
Expect(err).ToNot(HaveOccurred(), fmt.Sprintf(
220-
"kubernetes service %s is not available but expected to be available. \nError: %v\n",
221-
serviceName, err,
222-
))
223-
fmt.Printf("kubernetes service %s is available\n", serviceName)
224-
}
225-
226-
By(fmt.Sprintf("Checking FeatureStore customer resource: %s is in Ready Status.", featureStoreName))
227-
err = checkIfFeatureStoreCustomResourceConditionsInReady(featureStoreName, namespace)
228-
Expect(err).ToNot(HaveOccurred(), fmt.Sprintf(
229-
"FeatureStore custom resource %s all conditions are not in ready state. \nError: %v\n",
230-
featureStoreName, err,
231-
))
232-
fmt.Printf("FeatureStore custom resource %s conditions are in Ready State\n", featureStoreName)
233-
}

0 commit comments

Comments
 (0)