TN3270 terminal emulation support for k6 load testing.
This extension allows you to perform load testing against IBM mainframe applications that use the TN3270 protocol.
- TN3270/TN3270E protocol support via s3270
- Standard 3270 operations (PF/PA keys, Enter, Tab, Clear)
- Screen content reading and text search
- Screenshot capture for debugging
- Concurrent VU support with per-VU subprocess isolation
-
s3270 - The 3270 terminal emulator engine
# macOS brew install x3270 # Ubuntu/Debian apt-get install x3270 # RHEL/CentOS yum install x3270-x11
-
xk6 - k6 extension builder
go install go.k6.io/xk6/cmd/xk6@latest
Build k6 with the xk6-tn3270 extension:
xk6 build --with github.com/msradam/xk6-tn3270Or build from local source:
git clone https://github.com/msradam/xk6-tn3270.git
cd xk6-tn3270
make buildBuilding k6 with this extension on z/OS USS requires specific environment configuration:
# Required environment variables
export SSL_CERT_FILE=$ZOPEN_CA # CA certificates for HTTPS
export GOCACHE=/tmp/CB8A/go-cache # Use /tmp for build cache (more space)
export GOMODCACHE=/tmp/CB8A/go-mod # Use /tmp for module cache
export LIBPATH=/usr/lib:$LIBPATH # Include system libraries for linker
export GOMAXPROCS=2 # Limit parallelism to avoid OOM
# Build with afero compatibility fix (required for z/OS)
xk6 build \
--with xk6-tn3270=/path/to/xk6-tn3270 \
--replace github.com/spf13/afero=github.com/spf13/afero@v1.11.0 \
--output ./k6Key z/OS build requirements:
- SSL certificates: Set
SSL_CERT_FILEto a valid CA bundle (e.g.,$ZOPEN_CAfrom z/Open) - Disk space: Use
/tmpfor Go caches - home directories often have limited space - Linker libraries: Add
/usr/libtoLIBPATHforiewbndd6.so - afero replace: The default afero v1.1.2 is incompatible with z/OS - use v1.11.0+
- Memory: Limit
GOMAXPROCSif builds get killed (OOM)
Full build script example:
#!/bin/bash
source ~/.profile
export SSL_CERT_FILE=$ZOPEN_CA
export GOCACHE=/tmp/$USER/go-cache
export GOMODCACHE=/tmp/$USER/go-mod
export LIBPATH=/usr/lib:$LIBPATH
export GOMAXPROCS=2
mkdir -p $GOCACHE $GOMODCACHE
xk6 build \
--with xk6-tn3270=. \
--replace github.com/spf13/afero=github.com/spf13/afero@v1.11.0 \
--output ./k6import { TN3270 } from 'k6/x/tn3270';
export default function() {
const tn = TN3270();
// Connect to mainframe
tn.connect('mainframe.example.com', 23);
tn.waitForField();
// Login
tn.type('USERID');
tn.tab();
tn.type('PASSWORD');
tn.enter();
tn.waitForField();
// Navigate using PF keys
tn.pf(3); // PF3 to go back
tn.waitForField();
// Get screen content
const screen = tn.getScreenText();
console.log(screen);
// Take a screenshot for debugging
tn.screenshot('screenshots/login-screen.txt');
// Disconnect
tn.disconnect();
}| Method | Description |
|---|---|
connect(host, port, timeout?) |
Establish TN3270 connection. Timeout in seconds (default: 30, max: 300) |
disconnect() |
Clean shutdown of connection |
isConnected() |
Returns true if currently connected |
| Method | Description |
|---|---|
type(text) |
Type text at current cursor position (max 1920 chars) |
string(text) |
Alias for type() |
enter() |
Send Enter key |
tab() |
Send Tab key |
clear() |
Send Clear key |
| Method | Description |
|---|---|
pf(key) |
Send PF key (1-24) |
pa(key) |
Send PA key (1-3) |
| Method | Description |
|---|---|
waitForField(timeout?) |
Wait for screen to be ready for input. Timeout in seconds (default: 30) |
waitForText(text, timeout?) |
Wait until text appears on screen |
getScreenText() |
Return current screen contents as text |
ascii() |
Alias for getScreenText() |
| Method | Description |
|---|---|
sendCommand(command, wait?) |
Type text + Enter + optional wait for field (default: true) |
sendPF(key, wait?) |
Send PF key + optional wait for field (default: true) |
| Method | Description |
|---|---|
screenshot(path) |
Save current screen to a text file (similar to k6 browser's screenshot) |
printScreen() |
Return formatted screen with line numbers and border for console output |
See examples/simbank-test.js for a smoke test against Galasa SimBank.
# Run unit tests
go test -v ./...
# Start Galasa SimBank for E2E testing
git clone https://github.com/galasa-dev/simplatform.git
cd simplatform && ./build-locally.sh && ./run-locally.sh --server
# Run smoke test against SimBank (port 2023)
make test-simbankThis extension uses s3270, the scripting version of the x3270 terminal emulator, as the underlying TN3270 engine. Each k6 VU (Virtual User) spawns its own s3270 subprocess, allowing for concurrent connections to mainframe systems.
The architecture follows the pattern used by other k6 extensions like xk6-browser:
k6 VU → xk6-tn3270 (Go) → s3270 subprocess → Mainframe
MIT License - see LICENSE file.