Skip to content

Commit 16853ba

Browse files
committed
test: initial support for testing kubernetes support
1 parent e6d0fa4 commit 16853ba

File tree

14 files changed

+304
-14
lines changed

14 files changed

+304
-14
lines changed

.github/workflows/kind.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Kind
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
kind:
11+
runs-on: ${{ matrix.os }}
12+
13+
strategy:
14+
matrix:
15+
os: [ubuntu-latest]
16+
node-version: [16.x]
17+
profile: [keep-it-simple, ray-autoscaler]
18+
19+
steps:
20+
- uses: actions/checkout@v3
21+
22+
- name: Create k8s Kind Cluster
23+
uses: helm/[email protected]
24+
with:
25+
install_only: true
26+
27+
- name: Use Node.js ${{ matrix.node-version }}
28+
uses: actions/setup-node@v3
29+
with:
30+
node-version: ${{ matrix.node-version }}
31+
cache: 'npm'
32+
33+
- name: Setup
34+
env:
35+
TERM: xterm
36+
run: ./tests/kind/setup-ci.sh
37+
38+
- name: Run Test with profile ${{ matrix.profile }}
39+
env:
40+
EXECUTABLE_PATH: github-actions-production
41+
DEBUG_KUBERNETES: true
42+
RAY_STARTUP_PROBE_INITIAL_DELAY_SECONDS: 30
43+
run: ./tests/kind/run.sh ${{ matrix.profile }}

.github/workflows/test.yml renamed to .github/workflows/ui.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
22
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
33

4-
name: Tests
4+
name: UI
55

66
on:
77
push:
@@ -10,7 +10,7 @@ on:
1010
branches: [ main ]
1111

1212
jobs:
13-
test-with-prod-build:
13+
production:
1414
runs-on: ${{ matrix.os }}
1515

1616
strategy:

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
"pty:electron": "npm run pty:rebuild electron",
1919
"pty:nodejs": "npm run pty:rebuild node",
2020
"prepare": "cross-env husky install",
21-
"build:docker:cli": "npm run build:docker1 && docker build -f deploy/cli/Dockerfile -t ghcr.io/project-codeflare/codeflare-cli .",
22-
"build:docker:logs": "npm run build:docker1 && docker build -f deploy/log-aggregator/Dockerfile -t ghcr.io/project-codeflare/codeflare-log-aggregator .",
23-
"build:docker1": "if [ ! -n \"$FAST\" ]; then npm run build:docker0; fi",
24-
"build:docker0": "CLIENT_HOME=$PWD webpack-cli --mode=${MODE-production} --config node_modules/@kui-shell/webpack/headless-webpack.config.js",
21+
"build:docker:cli": "npm run build:headless-maybe && docker build -f deploy/cli/Dockerfile -t ghcr.io/project-codeflare/codeflare-cli .",
22+
"build:docker:logs": "npm run build:headless-maybe && docker build -f deploy/log-aggregator/Dockerfile -t ghcr.io/project-codeflare/codeflare-log-aggregator .",
23+
"build:headless-maybe": "if [ ! -n \"$FAST\" ]; then npm run build:headless; fi",
24+
"build:headless": "CLIENT_HOME=$PWD webpack-cli --mode=${MODE-production} --config node_modules/@kui-shell/webpack/headless-webpack.config.js",
2525
"docker:debug": "ENTRYPOINT=bash ./bin/codeflare -d",
2626
"build:electron:mac:amd64": "KUI_HEADLESS_WEBPACK=true KUI_LAUNCHER=$PWD/bin/codeflare PLATFORM=mac ARCH=x64 kui-build-electron",
2727
"build:electron:mac:arm64": "KUI_HEADLESS_WEBPACK=true KUI_LAUNCHER=$PWD/bin/codeflare PLATFORM=mac ARCH=arm64 kui-build-electron",
@@ -112,7 +112,7 @@
112112
"typescript": "4.7.4"
113113
},
114114
"dependencies": {
115-
"@guidebooks/store": "^0.0.1",
115+
"@guidebooks/store": "^0.1.1",
116116
"@kui-shell/client": "file:./plugins/plugin-client-default",
117117
"@kui-shell/core": "11.5.0-dev-20220807-191654",
118118
"@kui-shell/plugin-bash-like": "11.5.0-dev-20220807-191654",

tests/kind/config.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
kind: Cluster
2+
apiVersion: kind.x-k8s.io/v1alpha4
3+
nodes:
4+
- role: control-plane
5+
- role: worker

tests/kind/inputs/qiskit/main.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import ray
2+
import numpy as np
3+
4+
from qiskit.opflow import Z, I, X
5+
from qiskit.providers.basicaer import QasmSimulatorPy
6+
from qiskit.utils import QuantumInstance
7+
from qiskit.algorithms import VQE
8+
from qiskit.circuit.library import TwoLocal
9+
from qiskit.algorithms.optimizers import SLSQP
10+
from qiskit.providers import Backend
11+
12+
13+
@ray.remote
14+
def prep_problem():
15+
"""Prepare demo problem."""
16+
op = (
17+
(-1.052373245772859 * I ^ I)
18+
+ (0.39793742484318045 * I ^ Z)
19+
+ (-0.39793742484318045 * Z ^ I)
20+
+ (-0.01128010425623538 * Z ^ Z)
21+
+ (0.18093119978423156 * X ^ X)
22+
)
23+
initial_state = np.random.random(8)
24+
var_form = TwoLocal(
25+
rotation_blocks="ry",
26+
entanglement_blocks="cz"
27+
)
28+
29+
return (op, var_form, initial_state)
30+
31+
@ray.remote
32+
def optimize(problem):
33+
"""Optimization demo routine."""
34+
backend = QasmSimulatorPy()
35+
36+
op, var_form, init_point = problem
37+
38+
qi = QuantumInstance(backend, seed_transpiler=42, seed_simulator=42)
39+
ansatz = TwoLocal(rotation_blocks="ry", entanglement_blocks="cz")
40+
slsqp = SLSQP(maxiter=100)
41+
42+
vqe = VQE(
43+
var_form,
44+
optimizer=slsqp,
45+
quantum_instance=qi,
46+
initial_point=init_point
47+
)
48+
result = vqe.compute_minimum_eigenvalue(op)
49+
50+
print(f"Optimization result:")
51+
print(f" - eigenvalue: {result.eigenvalue}")
52+
print(f" - optimal value: {result.optimal_value}")
53+
print(f" - optinal parameters: {result.optimal_parameters}")
54+
55+
return result
56+
57+
@ray.remote
58+
def analyze(results):
59+
"""Analyzing demo results."""
60+
return min(results, key=lambda r: r.eigenvalue.real)
61+
62+
63+
if __name__ == "__main__":
64+
with ray.init():
65+
number_of_trials = 30
66+
67+
workflow_graph = analyze.remote(
68+
results=ray.get([
69+
optimize.remote(
70+
problem=prep_problem.remote()
71+
)
72+
for _ in range(number_of_trials)
73+
])
74+
)
75+
76+
result = ray.get(workflow_graph)
77+
print(f"Final result:")
78+
print(f" - eigenvalue: {result.eigenvalue}")
79+
print(f" - optimal value: {result.optimal_value}")
80+
print(f" - optinal parameters: {result.optimal_parameters}")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
qiskit==0.37.0

tests/kind/profiles/keep-it-simple

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "keep-it-simple",
3+
"creationTime": 1660657756574,
4+
"lastModifiedTime": 1660658307175,
5+
"lastUsedTime": 1660742079201,
6+
"choices": {
7+
"madwizard/apriori/use-gpu": "don't use gpus",
8+
"madwizard/apriori/arch": "x64",
9+
"madwizard/apriori/platform": "darwin",
10+
"madwizard/apriori/mac-installer": "Homebrew",
11+
"madwizard/apriori/in-terminal": "HTML",
12+
"Start a new Run####Connect Dashboard to an existing Run####Boot up a Cloud Computer####Shut down a Cloud Computer": "Start a new Run",
13+
"Training Demos####Fine Tuning Demos####Bring Your Own Code": "Bring Your Own Code",
14+
"BERT####MLFlow Demo####Tensorboard Demo": "MLFlow Demo",
15+
"Location of your working directory": "{\"Location of your working directory\":\"tests/kind/inputs/qiskit\"}",
16+
"Provide custom base image, if any": "{\"Provide custom base image, if any\":\"rayproject/ray:1.13.1-py37\"}",
17+
"AWS####IBM####My data is not stored in S3": "My data is not stored in S3",
18+
"Run Locally####Run on a Kubernetes Cluster": "Run on a Kubernetes Cluster",
19+
"expand(kubectl config get-contexts -o name, Kubernetes contexts)": "kind-codeflare-test",
20+
"expand([ -z ${KUBE_CONTEXT} ] && exit 1 || X=$(kubectl ${KUBE_CONTEXT_ARG} get ns -o name || oc ${KUBE_CONTEXT_ARG} get projects -o name); echo \"$X\" | sed -E 's#(namespace|project.project.openshift.io)/##' | grep -Ev 'openshift|kube-', Kubernetes namespaces)####Create a namespace": "default",
21+
"Number of CPUs####Number of GPUs####Minimum Workers####Maximum Workers####Worker Memory####Head Memory": "{\"Number of CPUs\":\"500m\",\"Number of GPUs\":\"0\",\"Minimum Workers\":\"1\",\"Maximum Workers\":\"1\",\"Worker Memory\":\"1Gi\",\"Head Memory\":\"1Gi\"}",
22+
"Keep It Simple####Use the Ray Autoscaler####Use the Multi-user Enhanced Kubernetes Scheduler": "Keep It Simple"
23+
}
24+
}

tests/kind/profiles/ray-autoscaler

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "ray-autoscaler",
3+
"creationTime": 1660657756574,
4+
"lastModifiedTime": 1660675440396,
5+
"lastUsedTime": 1660743373674,
6+
"choices": {
7+
"madwizard/apriori/use-gpu": "don't use gpus",
8+
"madwizard/apriori/arch": "x64",
9+
"madwizard/apriori/platform": "darwin",
10+
"madwizard/apriori/mac-installer": "Homebrew",
11+
"madwizard/apriori/in-terminal": "HTML",
12+
"Start a new Run####Connect Dashboard to an existing Run####Boot up a Cloud Computer####Shut down a Cloud Computer": "Start a new Run",
13+
"Training Demos####Fine Tuning Demos####Bring Your Own Code": "Bring Your Own Code",
14+
"BERT####MLFlow Demo####Tensorboard Demo": "MLFlow Demo",
15+
"Location of your working directory": "{\"Location of your working directory\":\"tests/kind/inputs/qiskit\"}",
16+
"Provide custom base image, if any": "{\"Provide custom base image, if any\":\"rayproject/ray:1.13.1-py37\"}",
17+
"AWS####IBM####My data is not stored in S3": "My data is not stored in S3",
18+
"Run Locally####Run on a Kubernetes Cluster": "Run on a Kubernetes Cluster",
19+
"expand(kubectl config get-contexts -o name, Kubernetes contexts)": "kind-codeflare-test",
20+
"expand([ -z ${KUBE_CONTEXT} ] && exit 1 || X=$(kubectl ${KUBE_CONTEXT_ARG} get ns -o name || oc ${KUBE_CONTEXT_ARG} get projects -o name); echo \"$X\" | sed -E 's#(namespace|project.project.openshift.io)/##' | grep -Ev 'openshift|kube-', Kubernetes namespaces)####Create a namespace": "default",
21+
"Number of CPUs####Number of GPUs####Minimum Workers####Maximum Workers####Worker Memory####Head Memory": "{\"Number of CPUs\":\"350m\",\"Number of GPUs\":\"0\",\"Minimum Workers\":\"1\",\"Maximum Workers\":\"1\",\"Worker Memory\":\"1Gi\",\"Head Memory\":\"1Gi\"}",
22+
"Keep It Simple####Use the Ray Autoscaler####Use the Multi-user Enhanced Kubernetes Scheduler": "Use the Ray Autoscaler"
23+
}
24+
}

tests/kind/run.sh

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/usr/bin/env bash
2+
3+
SCRIPTDIR=$(cd $(dirname "$0") && pwd)
4+
. "$SCRIPTDIR"/values.sh
5+
6+
export KUBECONFIG=$("$SCRIPTDIR"/setup.sh)
7+
echo "Using KUBECONFIG=$KUBECONFIG"
8+
9+
echo "================NODE INFO================="
10+
kubectl get node -o custom-columns=CAPACITY:.status.capacity
11+
echo "=========================================="
12+
13+
while getopts "ab:f:s:" opt
14+
do
15+
case $opt in
16+
a) FORCE_ALL=true; continue;;
17+
f) FORCE=$OPTARG; continue;;
18+
s) export GUIDEBOOK_STORE=$OPTARG; continue;;
19+
b) GUIDEBOOK=$OPTARG; continue;;
20+
*) continue;;
21+
esac
22+
done
23+
shift $((OPTIND-1))
24+
25+
mkdir -p "$MWPROFILES_PATH"
26+
27+
function run {
28+
local profile=$1
29+
local guidebook=${2-$GUIDEBOOK}
30+
local yes=$([ -z "$FORCE_ALL" ] && [ "$FORCE" != "$profile" ] && [ -f "$MWPROFILES_PATH/$profile" ] && echo "--yes" || echo "")
31+
32+
echo "Running with profile $profile"
33+
"$ROOT"/bin/codeflare -p $profile $yes $guidebook
34+
}
35+
36+
function logpoller {
37+
local type=$1
38+
39+
sleep 10
40+
while true; do
41+
kubectl logs -l ray-node-type=$type -f
42+
sleep 3
43+
done
44+
}
45+
46+
if [ -n "$DEBUG_KUBERNETES" ]; then
47+
logpoller head &
48+
HEAD_POLLER_PID=$!
49+
50+
logpoller worker &
51+
WORKER_POLLER_PID=$!
52+
fi
53+
54+
if [ -n "$1" ]; then
55+
OUTPUT=$(mktemp)
56+
run "$1" | tee $OUTPUT
57+
grep succeeded $OUTPUT
58+
else
59+
idx=1
60+
for i in "$SCRIPTDIR"/profiles/*; do
61+
profile=$(basename $i)
62+
63+
if [ $idx -gt 1 ]; then
64+
echo "Tearing down previous setup"
65+
run $profile ml/ray/stop/kubernetes
66+
fi
67+
68+
OUTPUT=$(mktemp)
69+
run $profile | tee $OUTPUT
70+
grep succeeded $OUTPUT
71+
idx=$((idx + 1))
72+
done
73+
fi
74+
75+
if [ -n "$HEAD_POLLER_PID" ]; then
76+
kill $HEAD_POLLER_PID
77+
fi
78+
if [ -n "$WORKER_POLLER_PID" ]; then
79+
kill $WORKER_POLLER_PID
80+
fi

0 commit comments

Comments
 (0)