From b82c9e435a22e36fe396eca395c3362aec3ca149 Mon Sep 17 00:00:00 2001 From: Griffin Sullivan <48397354+Griffin-Sullivan@users.noreply.github.com> Date: Mon, 18 Nov 2024 08:10:23 -0500 Subject: [PATCH 1/6] Add BFF dev mode for local K8s testing (#560) Signed-off-by: Griffin-Sullivan --- clients/ui/bff/Makefile | 4 +++- clients/ui/bff/cmd/main.go | 7 +++++-- clients/ui/bff/docs/dev-guide.md | 13 ++++++++++++- clients/ui/bff/internal/api/middleware.go | 14 +++++++++++--- clients/ui/bff/internal/config/environment.go | 2 ++ 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/clients/ui/bff/Makefile b/clients/ui/bff/Makefile index dec0984d3..b8e6ccdd3 100644 --- a/clients/ui/bff/Makefile +++ b/clients/ui/bff/Makefile @@ -3,6 +3,8 @@ IMG ?= model-registry-bff:latest PORT ?= 4000 MOCK_K8S_CLIENT ?= false MOCK_MR_CLIENT ?= false +DEV_MODE ?= false +DEV_MODE_PORT ?= 8080 # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. ENVTEST_K8S_VERSION = 1.29.0 @@ -45,7 +47,7 @@ build: fmt vet test .PHONY: run run: fmt vet envtest ENVTEST_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" \ - go run ./cmd/main.go --port=$(PORT) --mock-k8s-client=$(MOCK_K8S_CLIENT) --mock-mr-client=$(MOCK_MR_CLIENT) + go run ./cmd/main.go --port=$(PORT) --mock-k8s-client=$(MOCK_K8S_CLIENT) --mock-mr-client=$(MOCK_MR_CLIENT) --dev-mode=$(DEV_MODE) --dev-mode-port=$(DEV_MODE_PORT) .PHONY: docker-build docker-build: diff --git a/clients/ui/bff/cmd/main.go b/clients/ui/bff/cmd/main.go index 25c367c3f..eb719229d 100644 --- a/clients/ui/bff/cmd/main.go +++ b/clients/ui/bff/cmd/main.go @@ -4,11 +4,12 @@ import ( "context" "flag" "fmt" - "github.com/kubeflow/model-registry/ui/bff/internal/api" - "github.com/kubeflow/model-registry/ui/bff/internal/config" "os/signal" "syscall" + "github.com/kubeflow/model-registry/ui/bff/internal/api" + "github.com/kubeflow/model-registry/ui/bff/internal/config" + "log/slog" "net/http" "os" @@ -21,6 +22,8 @@ func main() { flag.IntVar(&cfg.Port, "port", getEnvAsInt("PORT", 4000), "API server port") flag.BoolVar(&cfg.MockK8Client, "mock-k8s-client", false, "Use mock Kubernetes client") flag.BoolVar(&cfg.MockMRClient, "mock-mr-client", false, "Use mock Model Registry client") + flag.BoolVar(&cfg.DevMode, "dev-mode", false, "Use development mode for access to local K8s cluster") + flag.IntVar(&cfg.DevModePort, "dev-mode-port", getEnvAsInt("DEV_MODE_PORT", 8080), "Use port when in development mode") flag.Parse() logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) diff --git a/clients/ui/bff/docs/dev-guide.md b/clients/ui/bff/docs/dev-guide.md index 01e5fab92..582c72896 100644 --- a/clients/ui/bff/docs/dev-guide.md +++ b/clients/ui/bff/docs/dev-guide.md @@ -82,4 +82,15 @@ curl http://localhost:8080/api/model_registry/v1alpha3/registered_models You should receive a 200 response if everything is working correctly, the body should look like: ```json {"items":[],"nextPageToken":"","pageSize":0,"size":0} -``` \ No newline at end of file +``` + +#### 6. Run BFF locally in Dev Mode +To access your local kind cluster when running the BFF locally, you can use the `DEV_MODE` option. This is useful for when +you want to test live changes on real cluster. To do so, simply run: +```shell +make run DEV_MODE=true +``` +You can also specify the port you are forwarding to if it is something other than 8080: +```shell +make run DEV_MODE=true DEV_MODE_PORT=8081 +``` diff --git a/clients/ui/bff/internal/api/middleware.go b/clients/ui/bff/internal/api/middleware.go index 743cd2567..64c5e5958 100644 --- a/clients/ui/bff/internal/api/middleware.go +++ b/clients/ui/bff/internal/api/middleware.go @@ -3,9 +3,11 @@ package api import ( "context" "fmt" + "net/http" + "github.com/julienschmidt/httprouter" + "github.com/kubeflow/model-registry/ui/bff/internal/config" "github.com/kubeflow/model-registry/ui/bff/internal/integrations" - "net/http" ) type contextKey string @@ -41,7 +43,7 @@ func (app *App) AttachRESTClient(handler func(http.ResponseWriter, *http.Request modelRegistryID := ps.ByName(ModelRegistryId) - modelRegistryBaseURL, err := resolveModelRegistryURL(modelRegistryID, app.kubernetesClient) + modelRegistryBaseURL, err := resolveModelRegistryURL(modelRegistryID, app.kubernetesClient, app.config) if err != nil { app.serverErrorResponse(w, r, fmt.Errorf("failed to resolve model registry base URL): %v", err)) return @@ -83,11 +85,17 @@ func resolveBearerToken(k8s integrations.KubernetesClientInterface, header http. return bearerToken, nil } -func resolveModelRegistryURL(id string, client integrations.KubernetesClientInterface) (string, error) { +func resolveModelRegistryURL(id string, client integrations.KubernetesClientInterface, config config.EnvConfig) (string, error) { serviceDetails, err := client.GetServiceDetailsByName(id) if err != nil { return "", err } + + if config.DevMode { + serviceDetails.ClusterIP = "localhost" + serviceDetails.HTTPPort = int32(config.DevModePort) + } + url := fmt.Sprintf("http://%s:%d/api/model_registry/v1alpha3", serviceDetails.ClusterIP, serviceDetails.HTTPPort) return url, nil } diff --git a/clients/ui/bff/internal/config/environment.go b/clients/ui/bff/internal/config/environment.go index f7b10bf63..f63dcce83 100644 --- a/clients/ui/bff/internal/config/environment.go +++ b/clients/ui/bff/internal/config/environment.go @@ -4,4 +4,6 @@ type EnvConfig struct { Port int MockK8Client bool MockMRClient bool + DevMode bool + DevModePort int } From 3eec9420663e7c9dee1651049f32c19341a5afbb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 13:11:23 +0000 Subject: [PATCH 2/6] build(deps): bump dompurify from 3.1.7 to 3.2.0 in /clients/ui/frontend (#568) Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.1.7 to 3.2.0. - [Release notes](https://github.com/cure53/DOMPurify/releases) - [Commits](https://github.com/cure53/DOMPurify/compare/3.1.7...3.2.0) --- updated-dependencies: - dependency-name: dompurify dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/ui/frontend/package-lock.json | 9 ++++----- clients/ui/frontend/package.json | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/clients/ui/frontend/package-lock.json b/clients/ui/frontend/package-lock.json index 1f020b0c5..edc8e29e7 100644 --- a/clients/ui/frontend/package-lock.json +++ b/clients/ui/frontend/package-lock.json @@ -17,7 +17,7 @@ "@patternfly/react-table": "6.0.0", "@patternfly/react-templates": "6.0.0", "classnames": "^2.2.6", - "dompurify": "^3.1.7", + "dompurify": "^3.2.0", "lodash-es": "^4.17.15", "npm-run-all": "^4.1.5", "react": "^18", @@ -8243,10 +8243,9 @@ } }, "node_modules/dompurify": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.7.tgz", - "integrity": "sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==", - "license": "(MPL-2.0 OR Apache-2.0)" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.0.tgz", + "integrity": "sha512-AMdOzK44oFWqHEi0wpOqix/fUNY707OmoeFDnbi3Q5I8uOpy21ufUA5cDJPr0bosxrflOVD/H2DMSvuGKJGfmQ==" }, "node_modules/domutils": { "version": "2.8.0", diff --git a/clients/ui/frontend/package.json b/clients/ui/frontend/package.json index 12f6ffe55..d7588b9e3 100644 --- a/clients/ui/frontend/package.json +++ b/clients/ui/frontend/package.json @@ -107,7 +107,7 @@ "react-dom": "^18", "react-router": "^6.26.2", "sass": "^1.78.0", - "dompurify": "^3.1.7", + "dompurify": "^3.2.0", "showdown": "^2.1.0", "classnames": "^2.2.6" }, From 2659cf72180bb7059a44e33efcbfb92390831329 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 13:18:23 +0000 Subject: [PATCH 3/6] build(deps-dev): bump postcss from 8.4.48 to 8.4.49 in /clients/ui/frontend (#565) Bumps [postcss](https://github.com/postcss/postcss) from 8.4.48 to 8.4.49. - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.4.48...8.4.49) --- updated-dependencies: - dependency-name: postcss dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/ui/frontend/package-lock.json | 8 ++++---- clients/ui/frontend/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clients/ui/frontend/package-lock.json b/clients/ui/frontend/package-lock.json index edc8e29e7..eb9b889c3 100644 --- a/clients/ui/frontend/package-lock.json +++ b/clients/ui/frontend/package-lock.json @@ -65,7 +65,7 @@ "jest-environment-jsdom": "^29.7.0", "junit-report-merger": "^7.0.0", "mini-css-extract-plugin": "^2.9.0", - "postcss": "^8.4.48", + "postcss": "^8.4.49", "prettier": "^3.3.3", "prop-types": "^15.8.1", "raw-loader": "^4.0.2", @@ -15931,9 +15931,9 @@ } }, "node_modules/postcss": { - "version": "8.4.48", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.48.tgz", - "integrity": "sha512-GCRK8F6+Dl7xYniR5a4FYbpBzU8XnZVeowqsQFYdcXuSbChgiks7qybSkbvnaeqv0G0B+dd9/jJgH8kkLDQeEA==", + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "dev": true, "funding": [ { diff --git a/clients/ui/frontend/package.json b/clients/ui/frontend/package.json index d7588b9e3..c73fd521c 100644 --- a/clients/ui/frontend/package.json +++ b/clients/ui/frontend/package.json @@ -69,7 +69,7 @@ "jest-environment-jsdom": "^29.7.0", "junit-report-merger": "^7.0.0", "mini-css-extract-plugin": "^2.9.0", - "postcss": "^8.4.48", + "postcss": "^8.4.49", "prettier": "^3.3.3", "prop-types": "^15.8.1", "raw-loader": "^4.0.2", From 5a8af71cd44c5ed809e12efc0c7ceb0ceeba5cc8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 13:19:22 +0000 Subject: [PATCH 4/6] build(deps-dev): bump @mui/material from 6.1.6 to 6.1.7 in /clients/ui/frontend (#566) Bumps [@mui/material](https://github.com/mui/material-ui/tree/HEAD/packages/mui-material) from 6.1.6 to 6.1.7. - [Release notes](https://github.com/mui/material-ui/releases) - [Changelog](https://github.com/mui/material-ui/blob/master/CHANGELOG.md) - [Commits](https://github.com/mui/material-ui/commits/v6.1.7/packages/mui-material) --- updated-dependencies: - dependency-name: "@mui/material" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/ui/frontend/package-lock.json | 61 ++++++++++++--------------- clients/ui/frontend/package.json | 2 +- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/clients/ui/frontend/package-lock.json b/clients/ui/frontend/package-lock.json index eb9b889c3..512a7cc9b 100644 --- a/clients/ui/frontend/package-lock.json +++ b/clients/ui/frontend/package-lock.json @@ -32,7 +32,7 @@ "@babel/preset-typescript": "^7.21.5", "@cypress/code-coverage": "^3.13.5", "@mui/icons-material": "^6.1.5", - "@mui/material": "^6.1.3", + "@mui/material": "^6.1.7", "@mui/types": "^7.2.17", "@testing-library/cypress": "^10.0.1", "@testing-library/dom": "^10.4.0", @@ -3125,11 +3125,10 @@ "license": "MIT" }, "node_modules/@mui/core-downloads-tracker": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.6.tgz", - "integrity": "sha512-nz1SlR9TdBYYPz4qKoNasMPRiGb4PaIHFkzLzhju0YVYS5QSuFF2+n7CsiHMIDcHv3piPu/xDWI53ruhOqvZwQ==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.7.tgz", + "integrity": "sha512-POuIBi80BZBogQkG4PQKIGwy4QFwB+kOr+OI4k7Znh7LqMAIhwB9OC00l6M+w1GrZJYj3T8R5WX8G6QAIvoVEw==", "dev": true, - "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" @@ -3163,17 +3162,16 @@ } }, "node_modules/@mui/material": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.6.tgz", - "integrity": "sha512-1yvejiQ/601l5AK3uIdUlAVElyCxoqKnl7QA+2oFB/2qYPWfRwDgavW/MoywS5Y2gZEslcJKhe0s2F3IthgFgw==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.7.tgz", + "integrity": "sha512-KsjujQL/A2hLd1PV3QboF+W6SSL5QqH6ZlSuQoeYz9r69+TnyBFIevbYLxdjJcJmGBjigL5pfpn7hTGop+vhSg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/core-downloads-tracker": "^6.1.6", - "@mui/system": "^6.1.6", + "@mui/core-downloads-tracker": "^6.1.7", + "@mui/system": "^6.1.7", "@mui/types": "^7.2.19", - "@mui/utils": "^6.1.6", + "@mui/utils": "^6.1.7", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.11", "clsx": "^2.1.1", @@ -3192,7 +3190,7 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@mui/material-pigment-css": "^6.1.6", + "@mui/material-pigment-css": "^6.1.7", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -3213,14 +3211,13 @@ } }, "node_modules/@mui/private-theming": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.6.tgz", - "integrity": "sha512-ioAiFckaD/fJSnTrUMWgjl9HYBWt7ixCh7zZw7gDZ+Tae7NuprNV6QJK95EidDT7K0GetR2rU3kAeIR61Myttw==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.7.tgz", + "integrity": "sha512-uLbfUSsug5K0LVkv0PI6Flste3le8+6WSL2omdTiYde93P89Qr7pKr8TA6d2yXfr+Bm+SvD8/fGnkaRwFkryuQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/utils": "^6.1.6", + "@mui/utils": "^6.1.7", "prop-types": "^15.8.1" }, "engines": { @@ -3241,11 +3238,10 @@ } }, "node_modules/@mui/styled-engine": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.6.tgz", - "integrity": "sha512-I+yS1cSuSvHnZDBO7e7VHxTWpj+R7XlSZvTC4lS/OIbUNJOMMSd3UDP6V2sfwzAdmdDNBi7NGCRv2SZ6O9hGDA==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.7.tgz", + "integrity": "sha512-Ou4CxN7MQmwrfG1Pu6EYjPgPChQXxPDJrwgizLXlRPOad5qAq4gYXRuzrGQ2DfGjjwmJhjI8T6A0SeapAZPGig==", "dev": true, - "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", "@emotion/cache": "^11.13.1", @@ -3276,17 +3272,16 @@ } }, "node_modules/@mui/system": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.6.tgz", - "integrity": "sha512-qOf1VUE9wK8syiB0BBCp82oNBAVPYdj4Trh+G1s+L+ImYiKlubWhhqlnvWt3xqMevR+D2h1CXzA1vhX2FvA+VQ==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.7.tgz", + "integrity": "sha512-qbMGgcC/FodpuRSfjXlEDdbNQaW++eATh0vNBcPUv2/YXSpReoOpoT9FhogxEBNks+aQViDXBRZKh6HX2fVmwg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/private-theming": "^6.1.6", - "@mui/styled-engine": "^6.1.6", + "@mui/private-theming": "^6.1.7", + "@mui/styled-engine": "^6.1.7", "@mui/types": "^7.2.19", - "@mui/utils": "^6.1.6", + "@mui/utils": "^6.1.7", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -3332,11 +3327,10 @@ } }, "node_modules/@mui/utils": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.6.tgz", - "integrity": "sha512-sBS6D9mJECtELASLM+18WUcXF6RH3zNxBRFeyCRg8wad6NbyNrdxLuwK+Ikvc38sTZwBzAz691HmSofLqHd9sQ==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.7.tgz", + "integrity": "sha512-Gr7cRZxBoZ0BIa3Xqf/2YaUrBLyNPJvXPQH3OsD9WMZukI/TutibbQBVqLYpgqJn8pKSjbD50Yq2auG0wI1xOw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", "@mui/types": "^7.2.19", @@ -6840,7 +6834,6 @@ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } diff --git a/clients/ui/frontend/package.json b/clients/ui/frontend/package.json index c73fd521c..e29e9d7df 100644 --- a/clients/ui/frontend/package.json +++ b/clients/ui/frontend/package.json @@ -35,7 +35,7 @@ "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.21.5", "@cypress/code-coverage": "^3.13.5", - "@mui/material": "^6.1.3", + "@mui/material": "^6.1.7", "@mui/icons-material": "^6.1.5", "@mui/types": "^7.2.17", "@testing-library/cypress": "^10.0.1", From aeb637bac30f1836408fa63b2474eb87471c88b3 Mon Sep 17 00:00:00 2001 From: Alex Creasy Date: Tue, 19 Nov 2024 16:26:23 +0000 Subject: [PATCH 5/6] Improves 'make help' documentation (#573) Signed-off-by: Alex Creasy --- clients/ui/bff/Makefile | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/clients/ui/bff/Makefile b/clients/ui/bff/Makefile index b8e6ccdd3..103d914de 100644 --- a/clients/ui/bff/Makefile +++ b/clients/ui/bff/Makefile @@ -16,41 +16,41 @@ help: ## Display this help. @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) .PHONY: fmt -fmt: +fmt: ## Applies the correct code style to source files using go fmt. go fmt ./... -.PHONY: clean +.PHONY: clean ## Deletes previously built binaries. clean: rm -Rf ./bin .PHONY: lint -lint: golangci-lint ## Run golangci-lint linter +lint: golangci-lint ## Run golangci-lint to automatically check source code for programmatic and stylistic errors. $(GOLANGCI_LINT) run .PHONY: lint-fix -lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes +lint-fix: golangci-lint ## Run golangci-lint to automatically check source code for programmatic and stylistic errors and, additionally perform fixes where possible. $(GOLANGCI_LINT) run --fix .PHONY: vet -vet: . +vet: . ## Runs static analysis tools on source files and reports suspicious constructs that could be bugs or syntactical errors. go vet ./... .PHONY: test -test: fmt vet envtest +test: fmt vet envtest ## Runs the full test suite. ENVTEST_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" \ go test ./... .PHONY: build -build: fmt vet test +build: fmt vet test ## Builds the project to produce a binary executable. go build -o bin/bff cmd/main.go .PHONY: run -run: fmt vet envtest +run: fmt vet envtest ## Runs the project. ENVTEST_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" \ go run ./cmd/main.go --port=$(PORT) --mock-k8s-client=$(MOCK_K8S_CLIENT) --mock-mr-client=$(MOCK_MR_CLIENT) --dev-mode=$(DEV_MODE) --dev-mode-port=$(DEV_MODE_PORT) .PHONY: docker-build -docker-build: +docker-build: ## Builds a container for the project. $(CONTAINER_TOOL) build -t ${IMG} . ##@ Dependencies From eba7ef23dd543e2586bca5ab19c20880c5fb22c9 Mon Sep 17 00:00:00 2001 From: Griffin Sullivan <48397354+Griffin-Sullivan@users.noreply.github.com> Date: Tue, 19 Nov 2024 15:45:24 -0500 Subject: [PATCH 6/6] Limit use of mockBFFResponse in mock tests (#575) Signed-off-by: Griffin-Sullivan --- .../frontend/src/__mocks__/mockBFFResponse.ts | 5 -- .../cypress/cypress/support/commands/api.ts | 20 ++--- .../mocked/modelRegistry/modelRegistry.cy.ts | 7 +- .../modelRegistrySettings.cy.ts | 3 +- .../tests/mocked/modelVersionArchive.cy.ts | 28 +++--- .../tests/mocked/modelVersionDetails.cy.ts | 85 +++++++++---------- .../cypress/tests/mocked/modelVersions.cy.ts | 11 ++- .../tests/mocked/registeredModelArchive.cy.ts | 24 +++--- 8 files changed, 80 insertions(+), 103 deletions(-) delete mode 100644 clients/ui/frontend/src/__mocks__/mockBFFResponse.ts diff --git a/clients/ui/frontend/src/__mocks__/mockBFFResponse.ts b/clients/ui/frontend/src/__mocks__/mockBFFResponse.ts deleted file mode 100644 index f1599462b..000000000 --- a/clients/ui/frontend/src/__mocks__/mockBFFResponse.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ModelRegistryBody } from '~/app/types'; - -export const mockBFFResponse = (data: T): ModelRegistryBody => ({ - data, -}); diff --git a/clients/ui/frontend/src/__tests__/cypress/cypress/support/commands/api.ts b/clients/ui/frontend/src/__tests__/cypress/cypress/support/commands/api.ts index 019f4520e..08423f51f 100644 --- a/clients/ui/frontend/src/__tests__/cypress/cypress/support/commands/api.ts +++ b/clients/ui/frontend/src/__tests__/cypress/cypress/support/commands/api.ts @@ -1,9 +1,9 @@ import type { GenericStaticResponse, RouteHandlerController } from 'cypress/types/net-stubbing'; +import { mockBFFResponse } from '~/__mocks__/utils'; import type { ModelArtifact, ModelArtifactList, ModelRegistry, - ModelRegistryBody, ModelVersion, ModelVersionList, RegisteredModel, @@ -35,7 +35,7 @@ declare global { interceptApi: (( type: 'GET /api/:apiVersion/model_registry/:modelRegistryName/registered_models', options: { path: { modelRegistryName: string; apiVersion: string } }, - response: ApiResponse>, + response: ApiResponse, ) => Cypress.Chainable) & (( type: 'POST /api/:apiVersion/model_registry/:modelRegistryName/registered_models', @@ -47,7 +47,7 @@ declare global { options: { path: { modelRegistryName: string; apiVersion: string; registeredModelId: number }; }, - response: ApiResponse>, + response: ApiResponse, ) => Cypress.Chainable) & (( type: 'POST /api/:apiVersion/model_registry/:modelRegistryName/registered_models/:registeredModelId/versions', @@ -61,28 +61,28 @@ declare global { options: { path: { modelRegistryName: string; apiVersion: string; registeredModelId: number }; }, - response: ApiResponse>, + response: ApiResponse, ) => Cypress.Chainable) & (( type: 'PATCH /api/:apiVersion/model_registry/:modelRegistryName/registered_models/:registeredModelId', options: { path: { modelRegistryName: string; apiVersion: string; registeredModelId: number }; }, - response: ApiResponse>, + response: ApiResponse, ) => Cypress.Chainable) & (( type: 'GET /api/:apiVersion/model_registry/:modelRegistryName/model_versions/:modelVersionId', options: { path: { modelRegistryName: string; apiVersion: string; modelVersionId: number }; }, - response: ApiResponse>, + response: ApiResponse, ) => Cypress.Chainable) & (( type: 'GET /api/:apiVersion/model_registry/:modelRegistryName/model_versions/:modelVersionId/artifacts', options: { path: { modelRegistryName: string; apiVersion: string; modelVersionId: number }; }, - response: ApiResponse>, + response: ApiResponse, ) => Cypress.Chainable) & (( type: 'POST /api/:apiVersion/model_registry/:modelRegistryName/model_versions/:modelVersionId/artifacts', @@ -96,12 +96,12 @@ declare global { options: { path: { modelRegistryName: string; apiVersion: string; modelVersionId: number }; }, - response: ApiResponse>, + response: ApiResponse, ) => Cypress.Chainable) & (( type: 'GET /api/:apiVersion/model_registry', options: { path: { apiVersion: string } }, - response: ApiResponse>, + response: ApiResponse, ) => Cypress.Chainable); } } @@ -136,7 +136,7 @@ Cypress.Commands.add( } return cy.intercept( { method, pathname, query: options?.query, ...(options?.times && { times: options.times }) }, - response, + mockBFFResponse(response), ); }, ); diff --git a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelRegistry.cy.ts b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelRegistry.cy.ts index e6cb531c3..897b01148 100644 --- a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelRegistry.cy.ts +++ b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelRegistry.cy.ts @@ -5,7 +5,6 @@ import { mockModelVersionList } from '~/__mocks__/mockModelVersionList'; import { mockRegisteredModel } from '~/__mocks__/mockRegisteredModel'; import { mockRegisteredModelList } from '~/__mocks__/mockRegisteredModelsList'; import { labelModal, modelRegistry } from '~/__tests__/cypress/cypress/pages/modelRegistry'; -import { mockBFFResponse } from '~/__mocks__/mockBFFResponse'; import type { ModelRegistry, ModelVersion, RegisteredModel } from '~/app/types'; import { be } from '~/__tests__/cypress/cypress/utils/should'; import { MODEL_REGISTRY_API_VERSION } from '~/__tests__/cypress/cypress/support/commands/api'; @@ -69,7 +68,7 @@ const initIntercepts = ({ { path: { apiVersion: MODEL_REGISTRY_API_VERSION }, }, - mockBFFResponse(modelRegistries), + modelRegistries, ); cy.interceptApi( @@ -77,7 +76,7 @@ const initIntercepts = ({ { path: { modelRegistryName: 'modelregistry-sample', apiVersion: MODEL_REGISTRY_API_VERSION }, }, - mockBFFResponse(mockRegisteredModelList({ items: registeredModels })), + mockRegisteredModelList({ items: registeredModels }), ); cy.interceptApi( @@ -89,7 +88,7 @@ const initIntercepts = ({ registeredModelId: 1, }, }, - mockBFFResponse(mockModelVersionList({ items: modelVersions })), + mockModelVersionList({ items: modelVersions }), ); }; diff --git a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistrySettings/modelRegistrySettings.cy.ts b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistrySettings/modelRegistrySettings.cy.ts index 22ed09af7..9a28f6e3d 100644 --- a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistrySettings/modelRegistrySettings.cy.ts +++ b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistrySettings/modelRegistrySettings.cy.ts @@ -1,6 +1,5 @@ import { mockModelRegistry } from '~/__mocks__/mockModelRegistry'; import type { ModelRegistry } from '~/app/types'; -import { mockBFFResponse } from '~/__mocks__/mockBFFResponse'; import { modelRegistrySettings } from '~/__tests__/cypress/cypress/pages/modelRegistrySettings'; type HandlersProps = { @@ -28,7 +27,7 @@ const initIntercepts = ({ { path: { apiVersion: MODEL_REGISTRY_API_VERSION }, }, - mockBFFResponse(modelRegistries), + modelRegistries, ); }; diff --git a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelVersionArchive.cy.ts b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelVersionArchive.cy.ts index f52bdc37b..291250583 100644 --- a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelVersionArchive.cy.ts +++ b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelVersionArchive.cy.ts @@ -63,7 +63,7 @@ const initIntercepts = ({ { path: { apiVersion: MODEL_REGISTRY_API_VERSION }, }, - mockBFFResponse(modelRegistries), + modelRegistries, ); cy.interceptApi( @@ -71,7 +71,7 @@ const initIntercepts = ({ { path: { modelRegistryName: 'modelregistry-sample', apiVersion: MODEL_REGISTRY_API_VERSION }, }, - mockBFFResponse(mockRegisteredModelList({ size: registeredModelsSize })), + mockRegisteredModelList({ size: registeredModelsSize }), ); cy.interceptApi( @@ -83,11 +83,9 @@ const initIntercepts = ({ registeredModelId: 1, }, }, - mockBFFResponse( - mockModelVersionList({ - items: modelVersions, - }), - ), + mockModelVersionList({ + items: modelVersions, + }), ); cy.interceptApi( @@ -99,7 +97,7 @@ const initIntercepts = ({ registeredModelId: 1, }, }, - mockBFFResponse(mockRegisteredModel({ name: 'test-1' })), + mockRegisteredModel({ name: 'test-1' }), ); cy.interceptApi( @@ -111,9 +109,7 @@ const initIntercepts = ({ modelVersionId: 2, }, }, - mockBFFResponse( - mockModelVersion({ id: '2', name: 'model version 2', state: ModelState.ARCHIVED }), - ), + mockModelVersion({ id: '2', name: 'model version 2', state: ModelState.ARCHIVED }), ); cy.interceptApi( @@ -125,7 +121,7 @@ const initIntercepts = ({ modelVersionId: 3, }, }, - mockBFFResponse(mockModelVersion({ id: '3', name: 'model version 3', state: ModelState.LIVE })), + mockModelVersion({ id: '3', name: 'model version 3', state: ModelState.LIVE }), ); }; @@ -199,7 +195,7 @@ describe('Restoring archive version', () => { modelVersionId: 2, }, }, - mockBFFResponse(mockModelVersion({})), + mockModelVersion({}), ).as('versionRestored'); initIntercepts({}); @@ -228,7 +224,7 @@ describe('Restoring archive version', () => { modelVersionId: 2, }, }, - mockBFFResponse(mockModelVersion({})), + mockModelVersion({}), ).as('versionRestored'); initIntercepts({}); @@ -257,7 +253,7 @@ describe('Archiving version', () => { modelVersionId: 3, }, }, - mockBFFResponse(mockModelVersion({})), + mockModelVersion({}), ).as('versionArchived'); initIntercepts({}); @@ -287,7 +283,7 @@ describe('Archiving version', () => { modelVersionId: 3, }, }, - mockBFFResponse(mockModelVersion({})), + mockModelVersion({}), ).as('versionArchived'); initIntercepts({}); diff --git a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelVersionDetails.cy.ts b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelVersionDetails.cy.ts index 3bcf9ece1..c07827db9 100644 --- a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelVersionDetails.cy.ts +++ b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelVersionDetails.cy.ts @@ -1,7 +1,6 @@ /* eslint-disable camelcase */ import { verifyRelativeURL } from '~/__tests__/cypress/cypress/utils/url'; import { mockModelRegistry } from '~/__mocks__/mockModelRegistry'; -import { mockBFFResponse } from '~/__mocks__/utils'; import { mockRegisteredModel } from '~/__mocks__/mockRegisteredModel'; import { mockModelVersionList } from '~/__mocks__/mockModelVersionList'; import { mockModelVersion } from '~/__mocks__/mockModelVersion'; @@ -34,7 +33,7 @@ const initIntercepts = ({ { path: { apiVersion: MODEL_REGISTRY_API_VERSION }, }, - mockBFFResponse(modelRegistries), + modelRegistries, ); cy.interceptApi( @@ -46,7 +45,7 @@ const initIntercepts = ({ registeredModelId: 1, }, }, - mockBFFResponse(mockRegisteredModel({})), + mockRegisteredModel({}), ); cy.interceptApi( @@ -58,19 +57,17 @@ const initIntercepts = ({ registeredModelId: 1, }, }, - mockBFFResponse( - mockModelVersionList({ - items: [ - mockModelVersion({ name: 'Version 1', author: 'Author 1', registeredModelId: '1' }), - mockModelVersion({ - author: 'Author 2', - registeredModelId: '1', - id: '2', - name: 'Version 2', - }), - ], - }), - ), + mockModelVersionList({ + items: [ + mockModelVersion({ name: 'Version 1', author: 'Author 1', registeredModelId: '1' }), + mockModelVersion({ + author: 'Author 2', + registeredModelId: '1', + id: '2', + name: 'Version 2', + }), + ], + }), ); cy.interceptApi( @@ -82,23 +79,21 @@ const initIntercepts = ({ modelVersionId: 1, }, }, - mockBFFResponse( - mockModelVersion({ - id: '1', - name: 'Version 1', - labels: [ - 'Testing label', - 'Financial data', - 'Fraud detection', - 'Long label data to be truncated abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc', - 'Machine learning', - 'Next data to be overflow', - 'Label x', - 'Label y', - 'Label z', - ], - }), - ), + mockModelVersion({ + id: '1', + name: 'Version 1', + labels: [ + 'Testing label', + 'Financial data', + 'Fraud detection', + 'Long label data to be truncated abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc', + 'Machine learning', + 'Next data to be overflow', + 'Label x', + 'Label y', + 'Label z', + ], + }), ); cy.interceptApi( @@ -110,7 +105,7 @@ const initIntercepts = ({ modelVersionId: 2, }, }, - mockBFFResponse(mockModelVersion({ id: '2', name: 'Version 2' })), + mockModelVersion({ id: '2', name: 'Version 2' }), ); cy.interceptApi( @@ -122,18 +117,16 @@ const initIntercepts = ({ modelVersionId: 1, }, }, - mockBFFResponse( - mockModelArtifactList({ - items: [ - mockModelArtifact({}), - mockModelArtifact({ - author: 'Author 2', - id: '2', - name: 'Artifact 2', - }), - ], - }), - ), + mockModelArtifactList({ + items: [ + mockModelArtifact({}), + mockModelArtifact({ + author: 'Author 2', + id: '2', + name: 'Artifact 2', + }), + ], + }), ); }; diff --git a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelVersions.cy.ts b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelVersions.cy.ts index c3fd860e2..7ad00d4a0 100644 --- a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelVersions.cy.ts +++ b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelVersions.cy.ts @@ -8,7 +8,6 @@ import type { ModelRegistry, ModelVersion } from '~/app/types'; import { verifyRelativeURL } from '~/__tests__/cypress/cypress/utils/url'; import { mockModelRegistry } from '~/__mocks__/mockModelRegistry'; import { mockModelVersion } from '~/__mocks__/mockModelVersion'; -import { mockBFFResponse } from '~/__mocks__/utils'; import { MODEL_REGISTRY_API_VERSION } from '~/__tests__/cypress/cypress/support/commands/api'; type HandlersProps = { @@ -54,7 +53,7 @@ const initIntercepts = ({ { path: { apiVersion: MODEL_REGISTRY_API_VERSION }, }, - mockBFFResponse(modelRegistries), + modelRegistries, ); cy.interceptApi( @@ -62,7 +61,7 @@ const initIntercepts = ({ { path: { modelRegistryName: 'modelregistry-sample', apiVersion: MODEL_REGISTRY_API_VERSION }, }, - mockBFFResponse(mockRegisteredModelList({ size: registeredModelsSize })), + mockRegisteredModelList({ size: registeredModelsSize }), ); cy.interceptApi( @@ -74,7 +73,7 @@ const initIntercepts = ({ registeredModelId: 1, }, }, - mockBFFResponse(mockModelVersionList({ items: modelVersions })), + mockModelVersionList({ items: modelVersions }), ); cy.interceptApi( @@ -86,7 +85,7 @@ const initIntercepts = ({ registeredModelId: 1, }, }, - mockBFFResponse(mockRegisteredModel({})), + mockRegisteredModel({}), ); cy.interceptApi( @@ -98,7 +97,7 @@ const initIntercepts = ({ modelVersionId: 1, }, }, - mockBFFResponse(mockModelVersion({ id: '1', name: 'model version' })), + mockModelVersion({ id: '1', name: 'model version' }), ); }; diff --git a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/registeredModelArchive.cy.ts b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/registeredModelArchive.cy.ts index 451b5a7cb..d07c89a1e 100644 --- a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/registeredModelArchive.cy.ts +++ b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/registeredModelArchive.cy.ts @@ -67,7 +67,7 @@ const initIntercepts = ({ { path: { apiVersion: MODEL_REGISTRY_API_VERSION }, }, - mockBFFResponse(modelRegistries), + modelRegistries, ); cy.interceptApi( @@ -75,7 +75,7 @@ const initIntercepts = ({ { path: { modelRegistryName: 'modelregistry-sample', apiVersion: MODEL_REGISTRY_API_VERSION }, }, - mockBFFResponse(mockRegisteredModelList({ items: registeredModels })), + mockRegisteredModelList({ items: registeredModels }), ); cy.interceptApi( @@ -87,7 +87,7 @@ const initIntercepts = ({ modelVersionId: 1, }, }, - mockBFFResponse(mockModelVersion({ id: '1', name: 'Version 2' })), + mockModelVersion({ id: '1', name: 'Version 2' }), ); cy.interceptApi( @@ -99,7 +99,7 @@ const initIntercepts = ({ registeredModelId: 2, }, }, - mockBFFResponse(mockModelVersionList({ items: modelVersions })), + mockModelVersionList({ items: modelVersions }), ); cy.interceptApi( @@ -111,7 +111,7 @@ const initIntercepts = ({ registeredModelId: 2, }, }, - mockBFFResponse(mockRegisteredModel({ id: '2', name: 'model 2', state: ModelState.ARCHIVED })), + mockRegisteredModel({ id: '2', name: 'model 2', state: ModelState.ARCHIVED }), ); cy.interceptApi( @@ -123,7 +123,7 @@ const initIntercepts = ({ registeredModelId: 3, }, }, - mockBFFResponse(mockRegisteredModel({ id: '3', name: 'model 3' })), + mockRegisteredModel({ id: '3', name: 'model 3' }), ); }; @@ -249,7 +249,7 @@ describe('Restoring archive model', () => { registeredModelId: 2, }, }, - mockBFFResponse(mockRegisteredModel({ id: '2', name: 'model 2', state: ModelState.LIVE })), + mockRegisteredModel({ id: '2', name: 'model 2', state: ModelState.LIVE }), ).as('modelRestored'); initIntercepts({}); @@ -278,7 +278,7 @@ describe('Restoring archive model', () => { registeredModelId: 2, }, }, - mockBFFResponse(mockRegisteredModel({ id: '2', name: 'model 2', state: ModelState.LIVE })), + mockRegisteredModel({ id: '2', name: 'model 2', state: ModelState.LIVE }), ).as('modelRestored'); initIntercepts({}); @@ -307,9 +307,7 @@ describe('Archiving model', () => { registeredModelId: 3, }, }, - mockBFFResponse( - mockRegisteredModel({ id: '3', name: 'model 3', state: ModelState.ARCHIVED }), - ), + mockRegisteredModel({ id: '3', name: 'model 3', state: ModelState.ARCHIVED }), ).as('modelArchived'); initIntercepts({}); @@ -339,9 +337,7 @@ describe('Archiving model', () => { registeredModelId: 3, }, }, - mockBFFResponse( - mockRegisteredModel({ id: '3', name: 'model 3', state: ModelState.ARCHIVED }), - ), + mockRegisteredModel({ id: '3', name: 'model 3', state: ModelState.ARCHIVED }), ).as('modelArchived'); initIntercepts({});