Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: migrate kubeflow-pipeline-e2e-test to GitHub Actions #10887

Merged
merged 2 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
81 changes: 81 additions & 0 deletions .github/workflows/e2e-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: KFP e2e tests

on:
push:
branches: [master]

pull_request:
paths:
- '.github/workflows/e2e-test.yaml'
- 'scripts/deploy/github/**'
- 'go.mod'
- 'go.sum'
- 'backend/**'
- 'frontend/**'
- 'proxy/**'
- 'manifests/kustomize/**'
- 'test/**'

jobs:
integration-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Create k8s Kind Cluster
uses: container-tools/kind-action@v2
with:
cluster_name: kfp
kubectl_version: v1.29.2
version: v0.22.0
node_image: kindest/node:v1.29.2

- name: Build images
run: ./scripts/deploy/github/build-images.sh

- name: Deploy KFP
run: ./scripts/deploy/github/deploy-kfp.sh

- name: Forward API port
run: ./scripts/deploy/github/forward-port.sh "kubeflow" "ml-pipeline" 8888 8888

- name: Initialization tests v1
working-directory: ./backend/test/initialization
run: go test -v ./... -namespace kubeflow -args -runIntegrationTests=true

- name: Initialization tests v2
working-directory: ./backend/test/v2/initialization
run: go test -v ./... -namespace kubeflow -args -runIntegrationTests=true

- name: API integration tests v1
working-directory: ./backend/test/integration
run: go test -v ./... -namespace ${NAMESPACE} -args -runIntegrationTests=true

- name: API integration tests v2
working-directory: ./backend/test/v2/integration
run: go test -v ./... -namespace ${NAMESPACE} -args -runIntegrationTests=true

- name: Forward Frontend port
run: ./scripts/deploy/github/forward-port.sh "kubeflow" "ml-pipeline-ui" 3000 3000

- name: Build frontend integration tests image
working-directory: ./test/frontend-integration-test
run: docker build . -t kfp-frontend-integration-test:local

- name: Frontend integration tests
run: docker run --net=host kfp-frontend-integration-test:local --remote-run true

- name: Basic sample tests - sequential
run: pip3 install -r ./test/sample-test/requirements.txt && pip3 install kfp~=2.0 && python3 ./test/sample-test/sample_test_launcher.py sample_test run_test --namespace kubeflow --test-name sequential --results-gcs-dir output

# Disabled while https://github.com/kubeflow/pipelines/issues/10885 is not resolved
# - name: Basic sample tests - exit_handler
# run: pip3 install -r ./test/sample-test/requirements.txt && pip3 install kfp~=2.0 && python3 ./test/sample-test/sample_test_launcher.py sample_test run_test --namespace kubeflow --test-name exit_handler --results-gcs-dir output

- name: Collect test results
if: always()
uses: actions/upload-artifact@v4
with:
name: kfp-backend-artifacts
path: /tmp/tmp.*/*
2 changes: 1 addition & 1 deletion backend/test/initialization/initialization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (s *InitializationTest) SetupTest() {
return
}

err := test.WaitForReady(*namespace, *initializeTimeout)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we keep the namespace parameter? While it always defaults to "kubeflow" in case of KFP standalone deployment, it would be useful in testing multi-tenancy in full kubeflow deployment (though we don't have automated test for it yet).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, WaitForReady does no longer depend on any namespace since now it invokes localhost:8888.

err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion backend/test/integration/experiment_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (s *ExperimentApiTest) SetupTest() {
}

if !*isDevMode {
err := test.WaitForReady(*namespace, *initializeTimeout)
err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion backend/test/integration/healthz_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (s *HealthzApiTest) SetupTest() {
}

if !*isDevMode {
err := test.WaitForReady(*namespace, *initializeTimeout)
err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion backend/test/integration/job_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func (s *JobApiTestSuite) SetupTest() {
}

if !*isDevMode {
err := test.WaitForReady(*namespace, *initializeTimeout)
err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %s", err.Error())
}
Expand Down
2 changes: 1 addition & 1 deletion backend/test/integration/pipeline_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (s *PipelineApiTest) SetupTest() {
}

if !*isDevMode {
err := test.WaitForReady(*namespace, *initializeTimeout)
err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %s", err.Error())
}
Expand Down
2 changes: 1 addition & 1 deletion backend/test/integration/pipeline_version_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (s *PipelineVersionApiTest) SetupTest() {
}

if !*isDevMode {
err := test.WaitForReady(*namespace, *initializeTimeout)
err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %s", err.Error())
}
Expand Down
2 changes: 1 addition & 1 deletion backend/test/integration/run_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (s *RunApiTestSuite) SetupTest() {
}

if !*isDevMode {
err := test.WaitForReady(*namespace, *initializeTimeout)
err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %s", err.Error())
}
Expand Down
2 changes: 1 addition & 1 deletion backend/test/integration/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func (s *UpgradeTests) SetupSuite() {
}

if !*isDevMode {
err := test.WaitForReady(*namespace, *initializeTimeout)
err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion backend/test/integration/visualization_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (s *VisualizationApiTest) SetupTest() {
}

if !*isDevMode {
err := test.WaitForReady(*namespace, *initializeTimeout)
err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %v", err)
}
Expand Down
5 changes: 2 additions & 3 deletions backend/test/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package test

import (
"fmt"
"net/http"
"os"
"testing"
Expand All @@ -39,9 +38,9 @@ import (
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
)

func WaitForReady(namespace string, initializeTimeout time.Duration) error {
func WaitForReady(initializeTimeout time.Duration) error {
operation := func() error {
response, err := http.Get(fmt.Sprintf("http://ml-pipeline.%s.svc.cluster.local:8888/apis/v1beta1/healthz", namespace))
response, err := http.Get("http://localhost:8888/apis/v1beta1/healthz")
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion backend/test/v2/initialization/initialization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (s *InitializationTest) SetupTest() {
return
}

err := test.WaitForReady(*namespace, *initializeTimeout)
err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion backend/test/v2/integration/experiment_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (s *ExperimentApiTest) SetupTest() {
}

if !*isDevMode {
err := test.WaitForReady(*namespace, *initializeTimeout)
err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion backend/test/v2/integration/healthz_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (s *HealthzApiTest) SetupTest() {
}

if !*isDevMode {
err := test.WaitForReady(*namespace, *initializeTimeout)
err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion backend/test/v2/integration/pipeline_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (s *PipelineApiTest) SetupTest() {
}

if !*isDevMode {
err := test.WaitForReady(*namespace, *initializeTimeout)
err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %s", err.Error())
}
Expand Down
2 changes: 1 addition & 1 deletion backend/test/v2/integration/pipeline_version_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (s *PipelineVersionApiTest) SetupTest() {
}

if !*isDevMode {
err := test.WaitForReady(*namespace, *initializeTimeout)
err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %s", err.Error())
}
Expand Down
2 changes: 1 addition & 1 deletion backend/test/v2/integration/recurring_run_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (s *RecurringRunApiTestSuite) SetupTest() {
}

if !*isDevMode {
err := test.WaitForReady(*namespace, *initializeTimeout)
err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %s", err.Error())
}
Expand Down
2 changes: 1 addition & 1 deletion backend/test/v2/integration/run_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (s *RunApiTestSuite) SetupTest() {
}

if !*isDevMode {
err := test.WaitForReady(*namespace, *initializeTimeout)
err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %s", err.Error())
}
Expand Down
2 changes: 1 addition & 1 deletion backend/test/v2/integration/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (s *UpgradeTests) SetupSuite() {
}

if !*isDevMode {
err := test.WaitForReady(*namespace, *initializeTimeout)
err := test.WaitForReady(*initializeTimeout)
if err != nil {
glog.Exitf("Failed to initialize test. Error: %v", err)
}
Expand Down
5 changes: 2 additions & 3 deletions backend/test/v2/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package test

import (
"fmt"
"net/http"
"os"
"testing"
Expand All @@ -37,9 +36,9 @@ import (
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
)

func WaitForReady(namespace string, initializeTimeout time.Duration) error {
func WaitForReady(initializeTimeout time.Duration) error {
operation := func() error {
response, err := http.Get(fmt.Sprintf("http://ml-pipeline.%s.svc.cluster.local:8888/apis/v2beta1/healthz", namespace))
response, err := http.Get("http://localhost:8888/apis/v2beta1/healthz")
if err != nil {
return err
}
Expand Down
35 changes: 35 additions & 0 deletions scripts/deploy/github/forward-port.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env bash

usage() {
echo "Usage: $0 [-q] <KUBEFLOW_NS> <APP_NAME> <LOCAL_PORT> <REMOTE_PORT>"
exit 1
}

QUIET=0
while getopts "q" opt; do
case $opt in
q) QUIET=1 ;;
*) usage ;;
esac
done
shift $((OPTIND -1))

if [ $# -ne 4 ]; then
usage
fi

KUBEFLOW_NS=$1
APP_NAME=$2
LOCAL_PORT=$3
REMOTE_PORT=$4

POD_NAME=$(kubectl get pods -n "$KUBEFLOW_NS" -l "app=$APP_NAME" -o jsonpath='{.items[0].metadata.name}')

if [ $QUIET -eq 1 ]; then
kubectl port-forward -n "$KUBEFLOW_NS" "$POD_NAME" "$LOCAL_PORT:$REMOTE_PORT" > /dev/null 2>&1 &
else
kubectl port-forward -n "$KUBEFLOW_NS" "$POD_NAME" "$LOCAL_PORT:$REMOTE_PORT" &
fi

# wait for the port-forward
sleep 5
18 changes: 0 additions & 18 deletions test/api-integration-test/Dockerfile

This file was deleted.

4 changes: 0 additions & 4 deletions test/api-integration-test/OWNERS

This file was deleted.

Loading
Loading