Skip to content

Commit 07758fe

Browse files
committed
add options for --max-devworkspaces and --delete-devworkspace-after-ready
Signed-off-by: Rohan Kumar <[email protected]>
1 parent 8f433fb commit 07758fe

File tree

3 files changed

+76
-4
lines changed

3 files changed

+76
-4
lines changed

.ci/openshift_e2e.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,6 @@ export CLEAN_UP_AFTER_SUITE="false"
7373
make test_e2e
7474
bumpLogs
7575

76-
make test_load ARGS="--mode operator --max-vus 250 --separate-namespaces false --test-duration-minutes 25 --dwo-namespace devworkspace-controller --logs-dir ${ARTIFACT_DIR}/load-testing-logs"
77-
make uninstall
76+
make test_load ARGS="--max-vus 500 --max-devworkspaces 1500 --delete-devworkspace-after-ready false --separate-namespaces false --test-duration-minutes 25 --dwo-namespace devworkspace-controller --logs-dir ${ARTIFACT_DIR}/load-testing-logs"
77+
78+
#make uninstall

test/load/devworkspace_load_test.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ const inCluster = __ENV.IN_CLUSTER === 'true';
2323
const apiServer = inCluster ? `https://kubernetes.default.svc` : __ENV.KUBE_API;
2424
const token = inCluster ? open('/var/run/secrets/kubernetes.io/serviceaccount/token') : __ENV.KUBE_TOKEN;
2525
const useSeparateNamespaces = __ENV.SEPARATE_NAMESPACES === "true";
26+
const deleteDevWorkspaceAfterReady = __ENV.DELETE_DEVWORKSPACE_AFTER_READY === "true";
2627
const operatorNamespace = __ENV.DWO_NAMESPACE || 'openshift-operators';
2728
const externalDevWorkspaceLink = __ENV.DEVWORKSPACE_LINK || '';
2829
const shouldCreateAutomountResources = (__ENV.CREATE_AUTOMOUNT_RESOURCES || 'false') === 'true';
2930
const maxVUs = Number(__ENV.MAX_VUS || 50);
31+
const maxDevWorkspaces = Number(__ENV.MAX_DEVWORKSPACES || -1);
3032
const devWorkspaceReadyTimeout = Number(__ENV.DEV_WORKSPACE_READY_TIMEOUT_IN_SECONDS || 600);
3133
const autoMountConfigMapName = 'dwo-load-test-automount-configmap';
3234
const autoMountSecretName = 'dwo-load-test-automount-secret';
@@ -87,6 +89,12 @@ export function setup() {
8789
}
8890

8991
export default function () {
92+
if (maxDevWorkspaces > 0) {
93+
const totalDevWorkspaces = getDevWorkspacesFromApiServer().length;
94+
if (totalDevWorkspaces > maxDevWorkspaces) {
95+
return;
96+
}
97+
}
9098
const vuId = __VU;
9199
const iteration = __ITER;
92100
const crName = `dw-test-${vuId}-${iteration}`;
@@ -104,7 +112,9 @@ export default function () {
104112
const devWorkspaceCreated = createNewDevWorkspace(namespace, vuId, iteration);
105113
if (devWorkspaceCreated) {
106114
waitUntilDevWorkspaceIsReady(vuId, crName, namespace);
107-
deleteDevWorkspace(crName, namespace);
115+
if (deleteDevWorkspaceAfterReady) {
116+
deleteDevWorkspace(crName, namespace);
117+
}
108118
}
109119
} catch (error) {
110120
console.error(`Load test for ${vuId}-${iteration} failed:`, error.message);
@@ -434,6 +444,23 @@ function downloadAndParseExternalWorkspace(externalDevWorkspaceLink) {
434444
return manifest;
435445
}
436446

447+
function getDevWorkspacesFromApiServer() {
448+
const basePath = useSeparateNamespaces
449+
? `${apiServer}/apis/workspace.devfile.io/v1alpha2/devworkspaces`
450+
: `${apiServer}/apis/workspace.devfile.io/v1alpha2/namespaces/${loadTestNamespace}/devworkspaces`;
451+
452+
const url = `${basePath}?labelSelector=${labelKey}%3D${labelType}`;
453+
const res = http.get(url, { headers });
454+
455+
if (res.status !== 200) {
456+
console.error(`Failed to fetch DevWorkspaces: ${res.status} ${res.body}`);
457+
return [];
458+
}
459+
460+
const body = JSON.parse(res.body);
461+
return body.items.map((dw) => dw.metadata.name);
462+
}
463+
437464
function generateDevWorkspaceToCreate(vuId, iteration, namespace) {
438465
const name = `dw-test-${vuId}-${iteration}`;
439466
let devWorkspace = {};

test/load/runk6.sh

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ DEVWORKSPACE_LINK="https://gist.githubusercontent.com/rohanKanojia/ecf625afaf3fe
1616
MAX_VUS="100"
1717
DEV_WORKSPACE_READY_TIMEOUT_IN_SECONDS="1200"
1818
SEPARATE_NAMESPACES="false"
19+
DELETE_DEVWORKSPACE_AFTER_READY="true"
20+
MAX_DEVWORKSPACES="-1"
1921
CREATE_AUTOMOUNT_RESOURCES="false"
2022
LOGS_DIR="logs"
2123
TEST_DURATION_IN_MINUTES="25"
@@ -57,7 +59,9 @@ Usage: $0 [options]
5759
Options:
5860
--mode <operator|binary> Mode to run the script (default: operator)
5961
--max-vus <int> Number of virtual users for k6 (default: 100)
62+
--max-devworkspaces <int> Maximum number of DevWorkspaces to create (by default, it's not specified)
6063
--separate-namespaces <true|false> Use separate namespaces for workspaces (default: false)
64+
--delete-devworkspace-after-ready Delete DevWorkspace once it becomes Ready (default: true)
6165
--devworkspace-ready-timeout-seconds <int> Timeout in seconds for workspace to become ready (default: 1200)
6266
--devworkspace-link <string> DevWorkspace link (default: empty, opinionated DevWorkspace is created)
6367
--create-automount-resources <true|false> Whether to create automount resources (default: false)
@@ -77,6 +81,10 @@ parse_arguments() {
7781
MAX_VUS="$2"; shift 2;;
7882
--separate-namespaces)
7983
SEPARATE_NAMESPACES="$2"; shift 2;;
84+
--max-devworkspaces)
85+
MAX_DEVWORKSPACES="$2"; shift 2;;
86+
--delete-devworkspace-after-ready)
87+
DELETE_DEVWORKSPACE_AFTER_READY="$2"; shift 2;;
8088
--devworkspace-ready-timeout-seconds)
8189
DEV_WORKSPACE_READY_TIMEOUT_IN_SECONDS="$2"; shift 2;;
8290
--devworkspace-link)
@@ -173,11 +181,40 @@ start_background_watchers() {
173181
kubectl get dw --watch --all-namespaces \
174182
>> "${LOGS_DIR}/${TIMESTAMP}_dw_watch.log" 2>&1 &
175183
PID_DW_WATCH=$!
184+
185+
log_failed_devworkspaces &
186+
PID_FAILED_DW_POLL=$!
187+
}
188+
189+
log_failed_devworkspaces() {
190+
echo "📄 Starting periodic failed DevWorkspaces report (every 10s)..."
191+
192+
POLL_INTERVAL=10 # in seconds
193+
ITERATIONS=$(((TEST_DURATION_IN_MINUTES * 60) / POLL_INTERVAL))
194+
195+
for ((i = 0; i < ITERATIONS; i++)); do
196+
OUTPUT=$(kubectl get devworkspaces --all-namespaces -o json | jq -r '
197+
.items[]
198+
| select(.status.phase == "Failed")
199+
| [
200+
.metadata.namespace,
201+
.metadata.name,
202+
.status.phase,
203+
(.status.message // "No message")
204+
]
205+
| @csv')
206+
207+
if [ -n "$OUTPUT" ]; then
208+
echo "$OUTPUT" > "${LOGS_DIR}/dw_failure_report.csv"
209+
fi
210+
211+
sleep "$POLL_INTERVAL"
212+
done
176213
}
177214

178215
stop_background_watchers() {
179216
echo "🛑 Stopping background watchers..."
180-
kill "$PID_EVENTS_WATCH" "$PID_DW_WATCH" 2>/dev/null || true
217+
kill "$PID_EVENTS_WATCH" "$PID_DW_WATCH" "$PID_FAILED_DW_POLL" 2>/dev/null || true
181218
}
182219

183220
install_k6_operator() {
@@ -235,6 +272,10 @@ spec:
235272
value: '${TEST_DURATION_IN_MINUTES}'
236273
- name: DEV_WORKSPACE_READY_TIMEOUT_IN_SECONDS
237274
value: '${DEV_WORKSPACE_READY_TIMEOUT_IN_SECONDS}'
275+
- name: DELETE_DEVWORKSPACE_AFTER_READY
276+
value: '${DELETE_DEVWORKSPACE_AFTER_READY}'
277+
- name: MAX_DEVWORKSPACES
278+
value: '${MAX_DEVWORKSPACES}'
238279
EOF
239280
}
240281

@@ -330,6 +371,8 @@ run_k6_binary_test() {
330371
MAX_VUS="${MAX_VUS}" \
331372
TEST_DURATION_IN_MINUTES="${TEST_DURATION_IN_MINUTES}" \
332373
DEV_WORKSPACE_READY_TIMEOUT_IN_SECONDS="${DEV_WORKSPACE_READY_TIMEOUT_IN_SECONDS}" \
374+
DELETE_DEVWORKSPACE_AFTER_READY="${DELETE_DEVWORKSPACE_AFTER_READY}" \
375+
MAX_DEVWORKSPACES="${MAX_DEVWORKSPACES}" \
333376
k6 run "${K6_SCRIPT}"
334377
exit_code=$?
335378
if [ $exit_code -ne 0 ]; then
@@ -338,4 +381,5 @@ run_k6_binary_test() {
338381
return 0
339382
}
340383

384+
trap stop_background_watchers EXIT
341385
main "$@"

0 commit comments

Comments
 (0)