From d6260b31ed6880f6ab7b0aa71214bbb7a9d7b7e7 Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Mon, 22 Jun 2026 11:30:48 +0300 Subject: [PATCH 01/15] Add Performance workflow benchmarking OpenDJ vs OpenLDAP Adds .github/workflows/performance.yml plus supporting assets under .github/performance/ to run an automated LDAP benchmark comparing the latest OpenDJ and OpenLDAP Docker images. - Triggers: manual (workflow_dispatch) and after the Release workflow (workflow_run). Image tags and load profile (threads/duration/rampup/ jmeter_version) are configurable inputs, defaulting to latest images and the original 256-thread/600s profile. - Benchmarks OpenLDAP (osixia/openldap) first, then OpenDJ (openidentityplatform/opendj), sequentially so only one server is under load at a time. - JMeter plan (benchmark.jmx): the admin bind is cached once per thread (Once Only Controller, labelled ADMIN_CONNECT and excluded from metrics); ADD/SEARCH/COMPARE/MODIFY/DELETE/ADD WITHOUT DELETE run on that admin connection; the measured BIND is a single bind/unbind (test=sbind, own connection) as the per-thread user with the password MODIFY sets, so real password-hash verification is exercised. - Captures versions via shipped tools (OpenLDAP slapd -VV, OpenDJ rootDSE fullVendorVersion) and writes versions, a per-operation comparison table and two comparative Mermaid xychart-beta charts to GITHUB_STEP_SUMMARY; full JMeter HTML dashboards are uploaded as the jmeter-reports artifact. --- .github/performance/benchmark.jmx | 332 ++++++++++++++++++++++++++++++ .github/performance/people.ldif | 17 ++ .github/performance/summary.sh | 144 +++++++++++++ .github/workflows/performance.yml | 208 +++++++++++++++++++ 4 files changed, 701 insertions(+) create mode 100644 .github/performance/benchmark.jmx create mode 100644 .github/performance/people.ldif create mode 100644 .github/performance/summary.sh create mode 100644 .github/workflows/performance.yml diff --git a/.github/performance/benchmark.jmx b/.github/performance/benchmark.jmx new file mode 100644 index 0000000000..a20b94a64b --- /dev/null +++ b/.github/performance/benchmark.jmx @@ -0,0 +1,332 @@ + + + + + + Parametrized LDAP benchmark. Admin bind is cached once per thread (Once Only Controller, labelled ADMIN_CONNECT, excluded from metrics). Data ops (ADD/SEARCH/COMPARE/MODIFY/DELETE/ADD WITHOUT DELETE) reuse the cached admin connection. The measured user authentication is a single bind/unbind (test=sbind, own connection) after MODIFY has set the userPassword. + false + true + false + + + + + + + + continue + + false + -1 + + ${__P(threads,256)} + ${__P(rampup,0)} + true + ${__P(duration,600)} + + + + + + + + ${__P(host,localhost)} + ${__P(port,1389)} + ou=People,${__P(basedn,dc=example,dc=com)} + 2 + + + + false + false + 60000 + false + false + ${__P(adminbinddn,cn=Directory Manager)} + ${__P(adminbindpw,password)} + + + + + bind + + + + + + + + + + 2 + + + + false + false + + false + false + + + + + + + add + cn=user_${__threadNum} + + + + sn + user_${__threadNum} + = + + + mail + user_${__threadNum}@test.com + = + + + objectClass + top + = + + + objectClass + inetOrgPerson + = + + + objectClass + organizationalPerson + = + + + objectClass + person + = + + + + + + + + + + + + 2 + 0 + 0 + cn:dn:objectClass + false + false + + false + false + + + + + + + search + + (sn=user_${__threadNum}) + + + + + + + + + 2 + + + + false + false + + false + false + + + cn=user_${__threadNum} + mail=user_${__threadNum}@test.com + + + compare + + + + + + + + + 2 + + + + false + false + + false + false + + + + + + + modify + cn=user_${__threadNum} + + + + sn + rename_${__threadNum} + replace + = + + + userPassword + ${__P(benchpw,benchPass1)} + replace + = + + + + + + + + + ${__P(host,localhost)} + ${__P(port,1389)} + ou=People,${__P(basedn,dc=example,dc=com)} + 2 + + + + false + false + 60000 + false + false + cn=user_${__threadNum},ou=People,${__P(basedn,dc=example,dc=com)} + ${__P(benchpw,benchPass1)} + + + + + sbind + + + + + + + + + 2 + + + + false + false + + false + false + + + + + + + delete + cn=user_${__threadNum} + + + + + + + + + 2 + + + + false + false + + false + false + + + + + + + add + cn=user_${__threadNum}_${__UUID} + + + + sn + user_${__threadNum} + = + + + mail + user_${__threadNum}@test.com + = + + + objectClass + top + = + + + objectClass + inetOrgPerson + = + + + objectClass + organizationalPerson + = + + + objectClass + person + = + + + + + + + + + diff --git a/.github/performance/people.ldif b/.github/performance/people.ldif new file mode 100644 index 0000000000..d6a350093e --- /dev/null +++ b/.github/performance/people.ldif @@ -0,0 +1,17 @@ +# The contents of this file are subject to the terms of the Common Development and +# Distribution License (the License). You may not use this file except in compliance with the +# License. +# +# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the +# specific language governing permission and limitations under the License. +# +# When distributing Covered Software, include this CDDL Header Notice in each file and include +# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL +# Header, with the fields enclosed by brackets [] replaced by your own identifying +# information: "Portions copyright [year] [name of copyright owner]". +# +# Copyright 2026 3A Systems, LLC. +dn: ou=People,dc=example,dc=com +objectClass: top +objectClass: organizationalUnit +ou: People diff --git a/.github/performance/summary.sh b/.github/performance/summary.sh new file mode 100644 index 0000000000..ecac86c8de --- /dev/null +++ b/.github/performance/summary.sh @@ -0,0 +1,144 @@ +#!/usr/bin/env bash +# The contents of this file are subject to the terms of the Common Development and +# Distribution License (the License). You may not use this file except in compliance with the +# License. +# +# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the +# specific language governing permission and limitations under the License. +# +# When distributing Covered Software, include this CDDL Header Notice in each file and include +# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL +# Header, with the fields enclosed by brackets [] replaced by your own identifying +# information: "Portions copyright [year] [name of copyright owner]". +# +# Copyright 2026 3A Systems, LLC. +# +# Render an OpenDJ-vs-OpenLDAP LDAP benchmark report (versions + comparison table + +# comparative Mermaid charts) to stdout โ€” intended to be appended to $GITHUB_STEP_SUMMARY. +# +# Usage: +# summary.sh \ +# [openldap_image] [opendj_image] +# +# The admin connection bind is labelled ADMIN_CONNECT in the plan and is intentionally +# skipped here, so it never pollutes the per-operation comparison. +set -euo pipefail + +OL_JSON="${1:?openldap statistics.json required}" +DJ_JSON="${2:?opendj statistics.json required}" +OL_VER="${3:-unknown}" +DJ_VER="${4:-unknown}" +OL_IMG="${5:-}" +DJ_IMG="${6:-}" + +# Operations to compare, in workflow order. ADMIN_CONNECT and Total are excluded. +OPS=("ADD" "SEARCH" "COMPARE" "MODIFY" "BIND" "DELETE" "ADD WITHOUT DELETE") + +# m