This repository is used to build Docker image providing a CI/CD-friendly plugin for triggering, monitoring, and collecting results from OpenText Enterprise Performance Engineering (formerly LoadRunner Enterprise).
The docker image is designed to run non-interactively inside CI/CD pipelines (Harness, GitHub Actions, GitLab CI, Jenkins, Kubernetes jobs, etc.) using environment variables for configuration and outputs.
- Authenticates with an OpenText Enterprise Performance Engineering server
- Triggers a performance test execution
- Allocates or reuses a timeslot (based on configuration)
- Monitors test execution until completion
- Optionally collates and analyzes results
- Writes logs and result artifacts to configured directories
- Exits with a deterministic status code suitable for pipeline gating
This behavior allows the plugin to be used as a pipeline quality gate.
WorkspaceSync action (Technology Preview) - Synchronize local workspace scripts to LRE. At runtime, the container:
- Authenticates with an OpenText Enterprise Performance Engineering server
- Scans the workspace for folders considered as supported scripts. Folders identified as scripts are:
- VuGen scripts: folders containing a .usr file
- JMeter scripts: folders containing a .jmx file
- Gatling scripts: folders containing a .scala file
- Selenium or unit test scripts: folders containing a .java file
- DevWeb scripts: folders containing both main.js AND rts.yml files
- Zips each folder identified as script and uploads it to LRE
- Failure handling:
- If 5 consecutive script uploads fail, the action is interrupted with failure
- If more than 50% of the scripts found in the workspace are uploaded successfully, the action reports success
- Otherwise, the action reports failure
- Writes logs for each upload in console and in workspace
- Exits with a deterministic status code suitable for pipeline gating
- Docker runner (local, Kubernetes, or Harness delegate)
- Network access to the OpenText Enterprise Performance Engineering server
- Valid OpenText Enterprise Performance Engineering credentials
(username/password or token) - Writable workspace and output directories (mounted volumes)
All configuration is provided exclusively via environment variables.
| Variable | Description | Relevant to action |
|---|---|---|
| PLUGIN_LRE_SERVER | Server, port (when not mentionned, default is 80 or 433 for secured) and tenant (when not mentionned, default is ?tenant=fa128c06-5436-413d-9cfa-9f04bb738df3). e.g.: myserver.mydomain.com:81/?tenant=fa128c06-5436-413d-9cfa-9f04bb738df3' | all actions |
| PLUGIN_LRE_USERNAME | Username (or ID part of token) | all actions |
| PLUGIN_LRE_PASSWORD | Password (or secret part of token) | all actions |
| PLUGIN_LRE_DOMAIN | Domain (case-sensitive) | all actions |
| PLUGIN_LRE_PROJECT | Project (case-sensitive) | all actions |
| PLUGIN_LRE_TEST | Test ID or relative path to a YAML file defining a new test | ExecuteLreTest |
* Either username/password or token authentication must be used.
| Environment Variable | Description | Default | Relevant to action |
|---|---|---|---|
| PLUGIN_LRE_ACTION | Action to execute. Currently supported: ExecuteLreTest |
ExecuteLreTest |
all actions |
| PLUGIN_LRE_DESCRIPTION | Description displayed in console logs | value of PLUGIN_LRE_ACTION | all actions |
| PLUGIN_LRE_HTTPS_PROTOCOL | Use secured protocol for connecting to the server (true / false) |
false |
all actions |
| PLUGIN_LRE_AUTHENTICATE_WITH_TOKEN | Use token authentication (required for SSO). (true / false) |
false |
all actions |
| PLUGIN_LRE_TEST_INSTANCE | AUTO or specific instance ID |
AUTO |
ExecuteLreTest |
| PLUGIN_LRE_TIMESLOT_DURATION_HOURS | Timeslot duration (hours) | 0 |
ExecuteLreTest |
| PLUGIN_LRE_TIMESLOT_DURATION_MINUTES | Timeslot duration (minutes) | 30 |
ExecuteLreTest |
| PLUGIN_LRE_POST_RUN_ACTION | Collate Results, Collate and Analyze, Do Not Collate |
Do Not Collate |
ExecuteLreTest |
| PLUGIN_LRE_VUDS_MODE | Use VUDS licenses (true / false) |
false |
ExecuteLreTest |
| PLUGIN_LRE_TREND_REPORT | ASSOCIATED - the trend report defined in the test design will be used', Valid report ID - Report ID will be used for trend, No value or not defined - no trend monitoring. |
ExecuteLreTest |
|
| PLUGIN_LRE_SEARCH_TIMESLOT | Experimental: Search for matching timeslot instead of creating a new timeslot (true / false) |
false |
ExecuteLreTest |
| PLUGIN_LRE_STATUS_BY_SLA | Report success based on SLA (true / false) |
false |
ExecuteLreTest |
| PLUGIN_LRE_PROXY_OUT_URL | Proxy URL | all actions | |
| PLUGIN_LRE_USERNAME_PROXY | Proxy username | all actions | |
| PLUGIN_LRE_PASSWORD_PROXY | Proxy password | all actions | |
| PLUGIN_LRE_ENABLE_STACKTRACE | Print stacktrace on errors (true / false) |
false |
all actions |
| PLUGIN_LRE_RUNTIME_ONLY | Scripts upload mode (Runtime files only for true, All files for false) (true / false) |
false |
WorkspaceSync |
| Path | Purpose |
|---|---|
| PLUGIN_LRE_OUTPUT_DIR | Result files and summarized outputs |
| PLUGIN_LRE_WORKSPACE_DIR | Workspace for logs, reports, and checkout |
These directories must be writable and are typically mounted volumes in CI environments.
During execution, the condole logs provides the progression (waiting for run to finish, analysis report generation, ...) After execution, the plugin writes:
- Under PLUGIN_LRE_OUTPUT_DIR path, the file
results<timestamp>.xml– summarized test results - Under PLUGIN_LRE_WORKSPACE_DIR path,
LreResult/*.*– execution logs (lre_run_test__.log) - Under PLUGIN_LRE_WORKSPACE_DIR path, optional analysis files if
PLUGIN_LRE_POST_RUN_ACTIONisCollate and Analyze(under LreResult/LreReports/HtmlReport) - Under PLUGIN_LRE_WORKSPACE_DIR path, optional trend report if PLUGIN_LRE_TREND_REPORT is set with existing trend report (and LreResult/LreReports/TrendReports)
Exit code
0indicates success; any non-zero value indicates failure.
- Non-interactive, blocking execution
- The container handles polling and status monitoring internally
- No state is preserved between runs
- Designed to be idempotent and reproducible
Assuming the operating systen can pull docker images and run them as linux container.
create a ps1 file with the following content (provide valid values to environment variables) and run it to execute a test:
$imageBase = "performancetesting/opentext-enterprise-performance-engineering-ci-plugin"
$imageVersion = "latest"
$imageName = "${imageBase}:${imageVersion}"
docker run -it --rm `
-v C:/temp/harness/output:/harness/output `
-v C:/temp/harness/workspace:/harness/workspace `
-e PLUGIN_LRE_ACTION="ExecuteLreTest" `
-e PLUGIN_LRE_DESCRIPTION="running new test" `
-e PLUGIN_LRE_SERVER="http://<Server>/?tenant=<tenant-id>" `
-e PLUGIN_LRE_USERNAME="<username>" `
-e PLUGIN_LRE_PASSWORD="<password>" `
-e PLUGIN_LRE_DOMAIN="<domain>" `
-e PLUGIN_LRE_PROJECT="<project>" `
-e PLUGIN_LRE_TEST="<testid>" `
-e PLUGIN_LRE_POST_RUN_ACTION="Collate and Analyze" `
-e PLUGIN_LRE_OUTPUT_DIR="/harness/output" `
-e PLUGIN_LRE_WORKSPACE_DIR="/harness/workspace" `
$imageNamecreate a ps1 file with the following content (provide valid values to environment variables) and run it to sync a workspace (upload folders recognized as scripts in the workspace into LRE ):
$imageBase = "performancetesting/opentext-enterprise-performance-engineering-ci-plugin"
$imageVersion = "latest"
$imageName = "${imageBase}:${imageVersion}"
docker run -it --rm `
-v C:/temp/harness/output:/harness/output `
-v C:/temp/harness/workspace:/harness/workspace `
-e PLUGIN_LRE_ACTION="WorkspaceSync" `
-e PLUGIN_LRE_DESCRIPTION="Syncing scripts from workspace to LRE" `
-e PLUGIN_LRE_SERVER="http://<Server>/?tenant=<tenant-id>" `
-e PLUGIN_LRE_USERNAME="<username>" `
-e PLUGIN_LRE_PASSWORD="<password>" `
-e PLUGIN_LRE_DOMAIN="<domain>" `
-e PLUGIN_LRE_PROJECT="<project>" `
-e PLUGIN_LRE_OUTPUT_DIR="/harness/output" `
-e PLUGIN_LRE_WORKSPACE_DIR="/harness/workspace" `
-e PLUGIN_LRE_RUNTIME_ONLY="true"
$imageNamecreate a testImage.py file with following content (provide valid values to parameters in env_vars) and run it.
import subprocess
from pathlib import Path
# -----------------------------
# Configurable environment variables
# -----------------------------
image_base = "performancetesting/opentext-enterprise-performance-engineering-ci-plugin"
image_version = "latest"
image_name = f"{image_base}:{image_version}"
# Test-specific environment variables
env_vars = {
"PLUGIN_LRE_ACTION": "ExecuteLreTest",
"PLUGIN_LRE_DESCRIPTION": "running new test",
"PLUGIN_LRE_SERVER": "http://<Server>/?tenant=<tenant-id>",
"PLUGIN_LRE_HTTPS_PROTOCOL": "false",
"PLUGIN_LRE_AUTHENTICATE_WITH_TOKEN": "false",
"PLUGIN_LRE_USERNAME": "<username>",
"PLUGIN_LRE_PASSWORD": "<password>",
"PLUGIN_LRE_DOMAIN": "<domain>",
"PLUGIN_LRE_PROJECT": "<project>",
"PLUGIN_LRE_TEST": "<testid>",
"PLUGIN_LRE_TEST_INSTANCE": "",
"PLUGIN_LRE_TIMESLOT_DURATION_HOURS": "0",
"PLUGIN_LRE_TIMESLOT_DURATION_MINUTES": "30",
"PLUGIN_LRE_POST_RUN_ACTION": "Collate and Analyze",
"PLUGIN_LRE_VUDS_MODE": "false",
"PLUGIN_LRE_TREND_REPORT": "5",
"PLUGIN_LRE_SEARCH_TIMESLOT": "false",
"PLUGIN_LRE_STATUS_BY_SLA": "false",
"PLUGIN_LRE_OUTPUT_DIR": "/harness/output",
"PLUGIN_LRE_WORKSPACE_DIR": "/harness",
"PLUGIN_LRE_ENABLE_STACKTRACE": "false",
}
def windows_path_for_docker(path: str) -> str:
"""Convert Windows path to Docker-friendly forward slash path"""
return Path(path).resolve().as_posix()
def run_test_container():
print(f"Beginning running a test using container of image {image_name} ...")
# Docker volume mappings
volumes = [
f"{windows_path_for_docker('./harness/output')}:{env_vars['PLUGIN_LRE_OUTPUT_DIR']}",
f"{windows_path_for_docker('./harness/workspace')}:{env_vars['PLUGIN_LRE_WORKSPACE_DIR']}",
]
# Build docker run command
cmd = ["docker", "run", "-it", "--rm"]
# Add volume mappings
for vol in volumes:
cmd += ["-v", vol]
# Add environment variables
for key, value in env_vars.items():
cmd += ["-e", f"{key}={value}"]
# Add image name
cmd.append(image_name)
# Run the docker command
print("> Running Docker container...")
subprocess.run(cmd, shell=True, check=True)
print(f"Finished running a test using container of image {image_name} ...")
if __name__ == "__main__":
run_test_container()create a testImage.py file with following content (provide valid values to parameters in env_vars) and run it.
import subprocess
from pathlib import Path
# -----------------------------
# Configurable environment variables
# -----------------------------
image_base = "performancetesting/opentext-enterprise-performance-engineering-ci-plugin"
image_version = "latest"
image_name = f"{image_base}:{image_version}"
# Test-specific environment variables
env_vars = {
"PLUGIN_LRE_ACTION": "WorkspaceSync",
"PLUGIN_LRE_DESCRIPTION": "Sync scripts from workspace to LRE",
"PLUGIN_LRE_SERVER": "http://<Server>/?tenant=<tenant-id>",
"PLUGIN_LRE_HTTPS_PROTOCOL": "false",
"PLUGIN_LRE_AUTHENTICATE_WITH_TOKEN": "false",
"PLUGIN_LRE_USERNAME": "<username>",
"PLUGIN_LRE_PASSWORD": "<password>",
"PLUGIN_LRE_DOMAIN": "<domain>",
"PLUGIN_LRE_PROJECT": "<project>",
"PLUGIN_LRE_OUTPUT_DIR": "/harness/output",
"PLUGIN_LRE_WORKSPACE_DIR": "/harness",
"PLUGIN_LRE_ENABLE_STACKTRACE": "false",
"PLUGIN_LRE_RUNTIME_ONLY": "true"
}
def windows_path_for_docker(path: str) -> str:
"""Convert Windows path to Docker-friendly forward slash path"""
return Path(path).resolve().as_posix()
def run_test_container():
print(f"Beginning running a test using container of image {image_name} ...")
# Docker volume mappings
volumes = [
f"{path_for_docker('./harness/output')}:{env_vars['PLUGIN_LRE_OUTPUT_DIR']}",
f"{path_for_docker('./harness/workspace')}:{env_vars['PLUGIN_LRE_WORKSPACE_DIR']}",
]
# Build docker run command
cmd = ["docker", "run", "-it", "--rm"]
# Add volume mappings
for vol in volumes:
cmd += ["-v", vol]
# Add environment variables
for key, value in env_vars.items():
cmd += ["-e", f"{key}={value}"]
# Add image name
cmd.append(image_name)
# Run the docker command
print("> Running Docker container...")
subprocess.run(cmd, shell=True, check=True)
print(f"Finished running a test using container of image {image_name} ...")
if __name__ == "__main__":
run_test_container()Harness users expect YAML as step (the value of connectorRef should be customized to your harness configuation). values can be stored as secrets in harness and referenced.
...
steps:
- step:
type: Run
name: Run_1
identifier: Run_1
spec:
connectorRef: DockerRegistry1
image: performancetesting/opentext-enterprise-performance-engineering-ci-plugin:latest
shell: Sh
envVariables:
PLUGIN_LRE_ACTION: ExecuteLreTest
PLUGIN_LRE_DESCRIPTION: running new test
PLUGIN_LRE_SERVER: <+secrets.getValue("lre_server")>
PLUGIN_LRE_HTTPS_PROTOCOL: "true"
PLUGIN_LRE_AUTHENTICATE_WITH_TOKEN: "false"
PLUGIN_LRE_USERNAME: <+secrets.getValue("lre_username")>
PLUGIN_LRE_PASSWORD: <+secrets.getValue("lre_password")>
PLUGIN_LRE_DOMAIN: <+secrets.getValue("lre_domain")>
PLUGIN_LRE_PROJECT: <+secrets.getValue("lre_project")>
PLUGIN_LRE_TEST: <+secrets.getValue("lre_test")>
PLUGIN_LRE_TIMESLOT_DURATION_HOURS: "0"
PLUGIN_LRE_TIMESLOT_DURATION_MINUTES: "30"
PLUGIN_LRE_POST_RUN_ACTION: Collate and Analyze
PLUGIN_LRE_VUDS_MODE: "false"
PLUGIN_LRE_TREND_REPORT: "5"
PLUGIN_LRE_SEARCH_TIMESLOT: "false"
PLUGIN_LRE_STATUS_BY_SLA: "false"
PLUGIN_LRE_OUTPUT_DIR: /harness/output
PLUGIN_LRE_WORKSPACE_DIR: /harness
PLUGIN_LRE_ENABLE_STACKTRACE: "false"
......
steps:
- step:
type: Run
name: Run_1
identifier: Run_1
spec:
connectorRef: DockerRegistry1
image: performancetesting/opentext-enterprise-performance-engineering-ci-plugin:latest
shell: Sh
envVariables:
PLUGIN_LRE_ACTION: WorkspaceSync
PLUGIN_LRE_DESCRIPTION: Sync scripts from workspace to LRE
PLUGIN_LRE_SERVER: <+secrets.getValue("lre_server")>
PLUGIN_LRE_HTTPS_PROTOCOL: "true"
PLUGIN_LRE_AUTHENTICATE_WITH_TOKEN: "false"
PLUGIN_LRE_USERNAME: <+secrets.getValue("lre_username")>
PLUGIN_LRE_PASSWORD: <+secrets.getValue("lre_password")>
PLUGIN_LRE_DOMAIN: <+secrets.getValue("lre_domain")>
PLUGIN_LRE_PROJECT: <+secrets.getValue("lre_project")>
PLUGIN_LRE_OUTPUT_DIR: /harness/output
PLUGIN_LRE_WORKSPACE_DIR: /harness
PLUGIN_LRE_ENABLE_STACKTRACE: "false"
PLUGIN_LRE_RUNTIME_ONLY: "true"
...All configuration is provided using environment variables.
The plugin writes execution logs and result files to:
- Output directory:
$PLUGIN_LRE_OUTPUT_DIR - Workspace directory:
$PLUGIN_LRE_WORKSPACE_DIR
These directories should be mapped to Harness workspace paths to allow artifact collection and post-processing.
Supported authentication modes:
- Username / password
- Token authentication by setting:
- PLUGIN_LRE_AUTHENTICATE_WITH_TOKEN=true
- PLUGIN_LRE_USERNAME=
- PLUGIN_LRE_PASSWORD=
- Ensure network connectivity from the container to the server
- Validate tenant ID, domain, and project values
- Verify credentials or token permissions
- Enable stack traces by setting:
PLUGIN_LRE_ENABLE_STACKTRACE=true
This plugin uses the same core logic and configuration model as:
- GitHub Action: https://github.com/MicroFocus/lre-gh-action
- GitLab CI Plugin: https://gitlab.com/loadrunner-enterprise/lre-gitlab-action