Skip to content

Commit 62ef83b

Browse files
committed
test : create large ca-bundle configmap in che installation namespace before running load tests
Signed-off-by: Rohan Kumar <[email protected]>
1 parent 0ef22dc commit 62ef83b

File tree

4 files changed

+309
-10
lines changed

4 files changed

+309
-10
lines changed

test/load/che-cert-bundle-utils.sh

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
log_info() { echo -e "ℹ️ $*" >&2; }
5+
log_success() { echo -e "$*" >&2; }
6+
log_error() { echo -e "$*" >&2; }
7+
8+
9+
run_che_ca_bundle_e2e() {
10+
local che_ns="$1"
11+
local dw_ns="$2"
12+
local dw_name="$3"
13+
local cert_count="${4:-500}"
14+
local bundle_file="${5:-custom-ca-certificates.pem}"
15+
16+
check_namespaces "${che_ns}" "${dw_ns}"
17+
generate_dummy_certs "${cert_count}" "${bundle_file}"
18+
create_che_ca_configmap "${che_ns}" "${bundle_file}"
19+
patch_checluster_disable_pki_mount "${che_ns}"
20+
restart_che "${che_ns}"
21+
create_devworkspace "${dw_ns}" "${dw_name}"
22+
23+
local pod
24+
pod=$(wait_for_workspace_pod "${dw_ns}" "${dw_name}")
25+
26+
verify_ca_bundle_in_workspace "${pod}" "${dw_ns}" "${cert_count}"
27+
cleanup_resources "${dw_ns}" "${dw_name}"
28+
}
29+
30+
check_namespaces() {
31+
local che_ns="$1"
32+
local dw_ns="$2"
33+
34+
log_info "Checking namespaces..."
35+
kubectl get ns "${che_ns}" >/dev/null
36+
kubectl get ns "${dw_ns}" >/dev/null
37+
}
38+
39+
generate_dummy_certs() {
40+
local cert_count="$1"
41+
local bundle_file="$2"
42+
43+
log_info "Generating ${cert_count} dummy CA certificates..."
44+
rm -f "${bundle_file}"
45+
46+
for i in $(seq 1 "${cert_count}"); do
47+
openssl req -x509 -newkey rsa:2048 -nodes -days 1 \
48+
-subj "/CN=dummy-ca-${i}" \
49+
-keyout "dummy-ca-${i}.key" \
50+
-out "dummy-ca-${i}.pem" \
51+
>/dev/null 2>&1
52+
53+
cat "dummy-ca-${i}.pem" >> "${bundle_file}"
54+
done
55+
56+
log_success "Created CA bundle: $(du -h "${bundle_file}" | cut -f1)"
57+
}
58+
59+
create_che_ca_configmap() {
60+
local che_ns="$1"
61+
local bundle_file="$2"
62+
63+
log_info "Creating Che CA bundle ConfigMap..."
64+
65+
kubectl create configmap custom-ca-certificates \
66+
--from-file=custom-ca-certificates.pem="${bundle_file}" \
67+
-n "${che_ns}" \
68+
--dry-run=client -o yaml \
69+
| kubectl apply --server-side -f -
70+
71+
kubectl label configmap custom-ca-certificates \
72+
app.kubernetes.io/component=ca-bundle \
73+
app.kubernetes.io/part-of=che.eclipse.org \
74+
-n "${che_ns}" \
75+
--overwrite
76+
}
77+
78+
patch_checluster_disable_pki_mount() {
79+
local che_ns="$1"
80+
81+
log_info "Configuring CheCluster..."
82+
local checluster
83+
checluster=$(kubectl get checluster -n "${che_ns}" -o jsonpath='{.items[0].metadata.name}')
84+
85+
kubectl patch checluster "${checluster}" \
86+
-n "${che_ns}" \
87+
--type=merge \
88+
-p '{
89+
"spec": {
90+
"devEnvironments": {
91+
"trustedCerts": {
92+
"disableWorkspaceCaBundleMount": true
93+
}
94+
}
95+
}
96+
}'
97+
}
98+
99+
restart_che() {
100+
local che_ns="$1"
101+
102+
log_info "Restarting Che..."
103+
kubectl rollout status deploy/che -n "${che_ns}" --timeout=5m
104+
kubectl wait pod -n "${che_ns}" -l app=che --for=condition=Ready --timeout=5m
105+
106+
log_success "Che restarted"
107+
}
108+
109+
create_devworkspace() {
110+
local dw_ns="$1"
111+
local dw_name="$2"
112+
113+
log_info "Creating DevWorkspace '${dw_name}'..."
114+
cat <<EOF | kubectl apply -n "${dw_ns}" -f -
115+
kind: DevWorkspace
116+
apiVersion: workspace.devfile.io/v1alpha2
117+
metadata:
118+
name: ${dw_name}
119+
annotations:
120+
che.eclipse.org/che-editor: che-incubator/che-code/latest
121+
che.eclipse.org/devfile: |
122+
schemaVersion: 2.2.0
123+
metadata:
124+
generateName: ${dw_name}
125+
che.eclipse.org/devfile-source: |
126+
url:
127+
location: https://github.com/che-samples/web-nodejs-sample.git
128+
factory:
129+
params: che-editor=che-incubator/che-code/latest
130+
spec:
131+
started: true
132+
template:
133+
projects:
134+
- name: web-nodejs-sample
135+
git:
136+
remotes:
137+
origin: "https://github.com/che-samples/web-nodejs-sample.git"
138+
components:
139+
- name: dev
140+
container:
141+
image: quay.io/devfile/universal-developer-image:latest
142+
memoryLimit: 512Mi
143+
memoryRequest: 256Mi
144+
cpuRequest: 1000m
145+
commands:
146+
- id: say-hello
147+
exec:
148+
component: dev
149+
commandLine: echo "Hello from \$(pwd)"
150+
workingDir: \${PROJECT_SOURCE}/app
151+
contributions:
152+
- name: che-code
153+
uri: https://eclipse-che.github.io/che-plugin-registry/main/v3/plugins/che-incubator/che-code/latest/devfile.yaml
154+
components:
155+
- name: che-code-runtime-description
156+
container:
157+
env:
158+
- name: CODE_HOST
159+
value: 0.0.0.0
160+
EOF
161+
162+
163+
kubectl wait devworkspace/"${dw_name}" \
164+
-n "${dw_ns}" \
165+
--for=condition=Ready \
166+
--timeout=5m
167+
}
168+
169+
wait_for_workspace_pod() {
170+
local dw_ns="$1"
171+
local dw_name="$2"
172+
local pod_name
173+
174+
log_info "Waiting for workspace pod..."
175+
176+
kubectl wait pod \
177+
-n "${dw_ns}" \
178+
-l controller.devfile.io/devworkspace_name="${dw_name}" \
179+
--for=condition=Ready \
180+
--timeout=5m \
181+
>/dev/stderr
182+
183+
pod_name=$(kubectl get pod \
184+
-n "${dw_ns}" \
185+
-l controller.devfile.io/devworkspace_name="${dw_name}" \
186+
-o jsonpath='{.items[0].metadata.name}')
187+
188+
echo "${pod_name}"
189+
}
190+
191+
verify_ca_bundle_in_workspace() {
192+
local pod_name="$1"
193+
local dw_ns="$2"
194+
local expected_count="$3"
195+
local cert_path="/public-certs/tls-ca-bundle.pem"
196+
197+
log_info "Verifying CA bundle in workspace..."
198+
199+
kubectl exec "${pod_name}" -n "${dw_ns}" -- test -f "${cert_path}"
200+
201+
local mounted_count
202+
mounted_count=$(kubectl exec "${pod_name}" -n "${dw_ns}" -- \
203+
sh -c "grep -c 'BEGIN CERTIFICATE' ${cert_path}")
204+
205+
log_info "Generated certificates : ${expected_count}"
206+
log_info "Mounted certificates : ${mounted_count}"
207+
208+
if [[ "${mounted_count}" -le "${expected_count}" ]]; then
209+
log_error "Mounted certificate count validation failed"
210+
return 1
211+
fi
212+
213+
log_success "CA bundle verification passed"
214+
}
215+
216+
cleanup_resources() {
217+
local dw_ns="$1"
218+
local dw_name="$2"
219+
220+
log_info "Cleaning up..."
221+
kubectl delete dw "${dw_name}" -n "${dw_ns}" --ignore-not-found
222+
rm -f *.pem *.key
223+
}

test/load/devworkspace_load_test.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,6 @@ export const options = {
5050
iterations: maxDevWorkspaces,
5151
maxDuration: '3h',
5252
},
53-
final_cleanup: {
54-
executor: 'per-vu-iterations',
55-
vus: 1,
56-
iterations: 1,
57-
exec: 'final_cleanup',
58-
startTime: '0s',
59-
maxDuration: '3h',
60-
},
6153
}, thresholds: {
6254
'checks': ['rate>0.95'],
6355
'devworkspace_create_duration': ['p(95)<15000'],
@@ -203,6 +195,11 @@ export function handleSummary(data) {
203195
return loadTestSummaryReport;
204196
}
205197

198+
export function teardown(data) {
199+
console.log("Running final cleanup after all DevWorkspace creation finished...");
200+
final_cleanup();
201+
}
202+
206203
function createNewDevWorkspace(namespace, vuId, iteration) {
207204
const baseUrl = `${apiServer}/apis/workspace.devfile.io/v1alpha2/namespaces/${namespace}/devworkspaces`;
208205

@@ -259,6 +256,13 @@ function waitUntilDevWorkspaceIsReady(vuId, crName, namespace) {
259256
attempts++;
260257
}
261258

259+
if (!isReady && attempts >= maxAttempts) {
260+
console.error(
261+
`GET [VU ${vuId}] Timed out waiting for DevWorkspace '${crName}' in namespace '${namespace}' ` +
262+
`after ${attempts} attempts (${devWorkspaceReadyTimeout}s). Last known phase: '${lastPhase}'`
263+
);
264+
}
265+
262266
if (res.status === 200) {
263267
if (isReady) {
264268
devworkspaceReady.add(1);
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
provision_che_workspace_namespace() {
2+
local LOAD_TEST_NAMESPACE="$1"
3+
local CHE_NAMESPACE="$2"
4+
local CHE_CLUSTER_NAME="$3"
5+
6+
if [[ -z "${LOAD_TEST_NAMESPACE}" ]]; then
7+
echo "ERROR: LOAD_TEST_NAMESPACE argument is required"
8+
echo "Usage: provision_che_workspace_namespace <namespace>"
9+
return 1
10+
fi
11+
12+
if ! command -v oc >/dev/null 2>&1; then
13+
echo "ERROR: oc CLI not found"
14+
return 1
15+
fi
16+
17+
local USERNAME
18+
USERNAME="$(oc whoami)"
19+
20+
echo "Provisioning Che workspace namespace"
21+
echo " User : ${USERNAME}"
22+
echo " Namespace : ${LOAD_TEST_NAMESPACE}"
23+
24+
oc patch checluster "${CHE_CLUSTER_NAME}" \
25+
-n "${CHE_NAMESPACE}" \
26+
--type=merge \
27+
-p '{
28+
"spec": {
29+
"devEnvironments": {
30+
"defaultNamespace": {
31+
"autoProvision": false
32+
}
33+
}
34+
}
35+
}' >/dev/null
36+
37+
cat <<EOF | oc apply -f -
38+
apiVersion: v1
39+
kind: Namespace
40+
metadata:
41+
name: ${LOAD_TEST_NAMESPACE}
42+
labels:
43+
app.kubernetes.io/part-of: che.eclipse.org
44+
app.kubernetes.io/component: workspaces-namespace
45+
annotations:
46+
che.eclipse.org/username: ${USERNAME}
47+
EOF
48+
49+
oc get namespace "${LOAD_TEST_NAMESPACE}" >/dev/null
50+
51+
echo "✔ Namespace '${LOAD_TEST_NAMESPACE}' provisioned for user '${USERNAME}'"
52+
}

test/load/runk6.sh

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/bin/bash
22

3-
#!/bin/bash
3+
source test/load/provision-che-workspace-namespace.sh
4+
source test/load/che-cert-bundle-utils.sh
5+
46

57
MODE="binary" # or 'operator'
68
LOAD_TEST_NAMESPACE="loadtest-devworkspaces"
@@ -19,17 +21,26 @@ SEPARATE_NAMESPACES="false"
1921
DELETE_DEVWORKSPACE_AFTER_READY="true"
2022
MAX_DEVWORKSPACES="-1"
2123
CREATE_AUTOMOUNT_RESOURCES="false"
24+
RUN_WITH_ECLIPSE_CHE="false"
2225
LOGS_DIR="logs"
2326
TEST_DURATION_IN_MINUTES="25"
2427
MIN_KUBECTL_VERSION="1.24.0"
2528
MIN_CURL_VERSION="7.0.0"
2629
MIN_K6_VERSION="1.1.0"
30+
CHE_NAMESPACE="eclipse-che"
31+
CHE_CLUSTER_NAME="eclipse-che"
32+
TEST_CERTIFICATES_COUNT="500"
2733

2834
# ----------- Main Execution Flow -----------
2935
main() {
3036
parse_arguments "$@"
3137
check_prerequisites
32-
create_namespace
38+
if [[ "$RUN_WITH_ECLIPSE_CHE" == "false" ]]; then
39+
create_namespace
40+
else
41+
provision_che_workspace_namespace "$LOAD_TEST_NAMESPACE" "$CHE_NAMESPACE" "$CHE_CLUSTER_NAME"
42+
run_che_ca_bundle_e2e "$CHE_NAMESPACE" "$LOAD_TEST_NAMESPACE" "test-devworkspace" "$TEST_CERTIFICATES_COUNT"
43+
fi
3344
create_rbac
3445
start_background_watchers
3546

@@ -68,6 +79,9 @@ Options:
6879
--dwo-namespace <string> DevWorkspace Operator namespace (default: loadtest-devworkspaces)
6980
--logs-dir <string> Directory name where DevWorkspace and event logs would be dumped
7081
--test-duration-minutes <int> Duration in minutes for which to run load tests (default: 25 minutes)
82+
--run-with-eclipse-che <true|false> Whether these tests are supposed to be run with Eclipse Che (If yes additional certificates are mounted)
83+
--che-cluster-name <string> Applicable if running on Eclipse Che, defaults to 'eclipse-che'
84+
--che-namespace <string> Applicable if running on Eclipse Che, defaults to 'eclipse-che'
7185
-h, --help Show this help message
7286
EOF
7387
}
@@ -97,6 +111,12 @@ parse_arguments() {
97111
LOGS_DIR="$2"; shift 2;;
98112
--test-duration-minutes)
99113
TEST_DURATION_IN_MINUTES="$2"; shift 2;;
114+
--run-with-eclipse-che)
115+
RUN_WITH_ECLIPSE_CHE="$2"; shift 2;;
116+
--che-cluster-name)
117+
CHE_CLUSTER_NAME="$2"; shift 2;;
118+
--che-namespace)
119+
CHE_NAMESPACE="$2"; shift 2;;
100120
-h|--help)
101121
print_help; exit 0;;
102122
*)

0 commit comments

Comments
 (0)