Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 77 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,81 @@
# Changelog

## [2.0.4] - 2026-07-26

Kubernetes is no longer required. Benchmarks can run as local containers under
podman or docker, and HammerDB moves to 6.0.

### Added
- Container backend: set `backend: podman` or `backend: docker` to run one
HammerDB container per target on a single host, with no cluster, Helm or
kubectl. Verified equivalent to Kubernetes on throughput across SQL Server,
Oracle and PostgreSQL at 1, 4 and 8 targets.
- PostgreSQL support, including TPC-C and TPC-H scripts and schema build.
- Transaction response times in the scorecard. HammerDB 6.0 reports per
transaction percentiles from reservoir sampling, so p50/p95/p99 and max are
exact rather than bucket approximations. `time_profile` now defaults on; the
overhead measured smaller than run-to-run variance.
- `validate --from-cluster` checks database reachability from where the
workers actually run, which is not always reachable from your workstation.
- Credentials pass through a Kubernetes Secret by default, so they are not
readable via `kubectl describe job`.
- Pod securityContext compatible with the restricted Pod Security Standard.
- `resources.limits` applies to the container backend as `--memory`/`--cpus`.
- `-c` and `--config` accepted as aliases for `--file`.

### Changed
- HammerDB 6.0. Existing 5.0-built schemas are read without rebuilding, and
the published `latest` images now contain 6.0. Verified that an unmodified
2.0.3 install still runs against them.
- `init` asks where to run the workers and emits only the relevant backend
block, instead of always asking for a Kubernetes namespace.
- README leads with the container path; Kubernetes is documented as the option
for people who already have a cluster.
- The repo-root chart paths are symlinks into the packaged chart rather than a
second copy, which had already drifted.

### Fixed
- `total_iterations` rendered in scientific notation (`1e+07`) in the Helm
template, which TCL cannot parse.
- `find_test_ids` returned a stale build run ahead of the completed run, so
`results` reported no metrics after a successful benchmark.
- Container runs carried no deployment-name label, so two configs sharing a
host saw each other's test IDs.
- The base image was missing `libpq5`, so PostgreSQL could never load its
driver despite being advertised as supported.
- `securityContext` and `use_secrets` opt-outs were inert, because Go's
`default true` treats an explicit `false` as absent.
- `validate --from-cluster` probed every non-Oracle target on the SQL Server
port, reporting healthy PostgreSQL fleets as unreachable.
- The `:z` SELinux mount relabel was applied unconditionally, which breaks
Docker Desktop. It is now gated on the host actually enforcing SELinux.
- `init` produced SQL Server ODBC settings when PostgreSQL was selected.
- `VERSION` reported `2.0.2` in the 2.0.3 release; it now reads from
`pyproject.toml`.

### Known limitations
- Oracle requires Oracle Instant Client, which Oracle publishes for linux.x64
only, so Oracle benchmarks cannot run on Apple Silicon.
- Oracle ships as a separate image you build yourself, because Oracle's licence
does not permit redistributing Instant Client.
- The container backend drives from a single host. Spreading workers across
hosts requires the Kubernetes backend.
- Verified on Linux with podman. The docker, macOS and WSL2 paths are
implemented and unit tested but have not been exercised end to end.

## [2.0.3] - 2026-07-11

### Fixed
- Test ID resolution now filters by deployment name, so `results` and `report`
act on the intended run.

## [2.0.2] - 2026-07-10

### Fixed
- Run hash generation mis-parsed YAML values in scientific notation.
- Helm chart version aligned with the CLI release.
- LICENSE badge link corrected for PyPI rendering.

## [2.0.1] - 2026-03-05

### Added
Expand All @@ -11,7 +87,7 @@
- Input validation and Ctrl+C handling

### Fixed
- README.md documentation links broken on PyPI relative paths like `docs/CONFIGURATION.md` resolved against `pypi.org` instead of GitHub. Converted all links to absolute GitHub URLs.
- README.md documentation links broken on PyPI: relative paths like `docs/CONFIGURATION.md` resolved against `pypi.org` instead of GitHub. Converted all links to absolute GitHub URLs.

## [2.0.0] - 2026-03-01

Expand Down
60 changes: 60 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# CLAUDE.md — HammerDB-Scale

## Communication style

Andrew is the director on this project. Communicate at that level.

- Write in proper prose with correct punctuation. Full sentences, not fragments.
- Do not use em dashes. Use commas, colons, semicolons, or separate sentences instead.
- Lead with the answer or the recommendation, then supply the reasoning. Do not build up to a conclusion.
- Do not dump raw information. Synthesise it. If there are five findings, say which two matter and why.
- Give a clear recommendation when asked a decision question. Do not present a neutral menu of options and leave the choice hanging.
- Quantify effort and risk in concrete terms (days of work, files touched, what breaks) rather than vague labels.
- Flag genuine trade-offs and things that will bite later, but keep it brief and do not editorialise.
- Skip filler openings and closings. No "Great question", no "Let me know if you need anything else".
- Avoid heavy bold-and-bullet formatting where a short paragraph reads better.

## Project overview

HammerDB-Scale orchestrates parallel HammerDB database benchmarks across multiple
database instances at once. It is used mainly for storage platform validation:
proving how a Pure Storage FlashArray behaves when serving N database workloads
concurrently.

Current shape: a Python CLI (`hammerdb_scale`) that generates Helm values, deploys
one Kubernetes Job per database target, then collects and parses the job logs into
aggregated results and a self-contained HTML scorecard.

- `src/hammerdb_scale/` — the CLI package (see MEMORY.md for the module map)
- `src/hammerdb_scale/chart/` — the bundled Helm chart, the single source of truth
- `templates/`, `scripts/`, `Chart.yaml`, `values.yaml` — symlinks into the chart above
- `src/hammerdb_scale/runtime/` — execution backends (Kubernetes and container)
- `entrypoint.sh` — the in-container dispatcher that selects and runs a TCL script
- `Dockerfile`, `Dockerfile.oracle` — base image and Oracle Instant Client extension
- `hack/build-images.sh` — builds and verifies both images

### Things worth knowing

- The repo-root chart paths are symlinks, not copies. They used to be duplicates and
had already drifted; `get_chart_path()` prefers the packaged copy, so a fix applied
only at the repo root would never reach anyone installing from PyPI.
- The HammerDB version lives in `ARG HAMMERDB_VERSION` and flows through
`HAMMERDB_HOME`. `entrypoint.sh` *searches* for its mounted scripts rather than
requiring the chart's mountPath to match the image, because those are set by
different artifacts and can always disagree.
- `DEFAULT_HAMMERDB_VERSION` is what this repo builds; `PUBLISHED_HAMMERDB_VERSION`
is what the published images contain and drives the chart default. Move the latter
only after pushing new images.
- Database support is gated in five places: the `DatabaseType` enum in
`config/schema.py`, the `case` blocks in `entrypoint.sh`, the parser registry in
`results/parsers.py`, the per-database TCL script directories, and the per-database
ConfigMap template in the chart.
- The base image needs `libpq5` for PostgreSQL: HammerDB bundles Pgtcl but links the
system libpq at runtime.
- Credentials go through a Kubernetes Secret by default (`kubernetes.use_secrets`),
so they are not readable via `kubectl describe job`.

## Working preferences

- Do not use `sed` or shell scripts to edit config files. Use the Edit tool per file.
- Run `pytest tests/ -q` before declaring work done. The suite is fast (under a second).
19 changes: 0 additions & 19 deletions Chart.yaml

This file was deleted.

1 change: 1 addition & 0 deletions Chart.yaml
99 changes: 99 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# HammerDB Scale - Base Image
#
# Verified working: SQL Server and PostgreSQL.
# Oracle needs the extension image (Dockerfile.oracle) because Oracle Instant
# Client cannot be redistributed.
#
# ARCHITECTURE: x86_64. HammerDB 6.0 does publish ARM64 tarballs and this image
# would build for ARM, but the Oracle extension cannot (Instant Client is
# x86_64-only), so the pair is kept uniformly x86_64 to avoid shipping a base
# image that works on ARM alongside an Oracle image that does not.
#
# BUILD:
# docker build -t sillidata/hammerdb-scale:6.0 .
#
# To build a different HammerDB version:
# docker build --build-arg HAMMERDB_VERSION=5.0 -t sillidata/hammerdb-scale:5.0 .
#
# Prefer hack/build-images.sh, which builds this and the Oracle
# image in the right order and verifies both.

FROM ubuntu:24.04

# The HammerDB version is defined once here and flows into the install path,
# HAMMERDB_HOME and the image label. entrypoint.sh reads HAMMERDB_HOME rather
# than hardcoding a path, so a version bump is this one argument.
ARG HAMMERDB_VERSION=6.0

# Provenance. Populated by the release script; harmless when built by hand.
ARG VCS_REF=unknown
ARG BUILD_DATE=unknown
ARG IMAGE_VERSION=dev

LABEL maintainer="hammerdb-scale"
LABEL description="HammerDB Scale Test Runner - Multi-Database Performance Testing"
LABEL hammerdb.version="${HAMMERDB_VERSION}"
LABEL database.support="mssql,postgresql (oracle via extension image)"
LABEL org.opencontainers.image.title="hammerdb-scale"
LABEL org.opencontainers.image.description="HammerDB Scale Test Runner - Multi-Database Performance Testing"
LABEL org.opencontainers.image.source="https://github.com/PureStorage-OpenConnect/hammerdb-scale"
LABEL org.opencontainers.image.licenses="Apache-2.0"
LABEL org.opencontainers.image.version="${IMAGE_VERSION}"
LABEL org.opencontainers.image.revision="${VCS_REF}"
LABEL org.opencontainers.image.created="${BUILD_DATE}"

# Set environment variables
ENV DEBIAN_FRONTEND=noninteractive
ENV HAMMERDB_HOME=/opt/HammerDB-${HAMMERDB_VERSION}

# Install base packages and SQL Server drivers (Microsoft - permissive license)
RUN apt-get update && \
apt-get install -y \
apt-transport-https \
curl \
gnupg2 \
wget \
python3 \
python3-pip \
vim && \
# Add Microsoft repository for SQL Server tools
curl -sSL -O https://packages.microsoft.com/config/ubuntu/24.04/packages-microsoft-prod.deb && \
dpkg -i packages-microsoft-prod.deb && \
rm packages-microsoft-prod.deb && \
apt-get update && \
ACCEPT_EULA=Y apt-get install -y mssql-tools18 msodbcsql18 unixodbc unixodbc-dev && \
# HammerDB bundles Pgtcl but links against the system libpq at runtime;
# without libpq5 the PostgreSQL driver fails with
# "Failed to load Pgtcl - libpq.so.5: cannot open shared object file".
# postgresql-client provides psql for diagnostics.
apt-get install -y libpq5 postgresql-client && \
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /var/apt/cache/* /tmp/* /var/tmp/*

# Install Python dependencies for Pure Storage metrics collection
RUN python3 -m pip install --no-cache-dir --break-system-packages requests urllib3

# Install HammerDB
WORKDIR /opt
RUN wget "https://github.com/TPC-Council/HammerDB/releases/download/v${HAMMERDB_VERSION}/HammerDB-${HAMMERDB_VERSION}-Prod-Lin-UBU24.tar.gz" && \
tar -xzf "HammerDB-${HAMMERDB_VERSION}-Prod-Lin-UBU24.tar.gz" && \
rm "HammerDB-${HAMMERDB_VERSION}-Prod-Lin-UBU24.tar.gz" && \
echo 'export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/:$LD_LIBRARY_PATH' >> ~/.bashrc

# Configure HammerDB
RUN chmod +x "${HAMMERDB_HOME}/hammerdbcli" && \
ln -sf /opt/mssql-tools18/bin/bcp "${HAMMERDB_HOME}/bcp" && \
ln -sf /opt/mssql-tools18/bin/bcp /usr/local/bin/bcp

# Add entrypoint script
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh

# Add Pure Storage metrics collection script
COPY scripts/collect_pure_metrics.py ${HAMMERDB_HOME}/scripts/collect_pure_metrics.py
RUN chmod +x "${HAMMERDB_HOME}/scripts/collect_pure_metrics.py"

WORKDIR ${HAMMERDB_HOME}

ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
Loading
Loading