Squash TM¶
Squash TM (Test Management) is the open source ALM used by PerfShop for managing requirements, test cases, campaigns, and executions. It is shipped by the Squashtest vendor and actively maintained.
Source of truth
This page is drawn from the perfshop-squash-db, perfshop-testmgmt, and perfshop-squash-seed blocks of the compose files, the configuration bind mounts (squash-seed/start-plugins.cfg, squash-seed/squash.tm.cfg.properties), and the squash-seed/seed.py script.
Dedicated PostgreSQL database¶
Squash TM is deliberately coupled to PostgreSQL 16 — not MySQL, not the perfshop-db database. This is the choice made by the official Squashtest stack for the most stable support, and PerfShop sticks to it:
perfshop-squash-db:
image: postgres:16
container_name: perfshop-squash-db
environment:
- POSTGRES_DB=squashtm
- POSTGRES_USER=squashtm
- POSTGRES_PASSWORD=${SQUASH_DB_PASSWORD:-squashtm}
volumes:
- squash-db-data:/var/lib/postgresql/data
ports:
- "${SQUASH_DB_PORT:-5433}:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U squashtm -d squashtm"]
interval: 10s
timeout: 5s
retries: 5
| Aspect | Value |
|---|---|
| Image | postgres:16 |
| Database | squashtm |
| User | squashtm (default, overridable through SQUASH_DB_PASSWORD) |
| Named volume | squash-db-data → /var/lib/postgresql/data |
| Default host port | 5433 (to avoid a conflict with a possible local PostgreSQL) |
| Healthcheck | pg_isready |
The coexistence of MySQL 8 (for perfshop-app) and PostgreSQL 16 (for Squash TM) in the same stack is pedagogically useful: students see two DBMSes side by side, each with its official image and its own healthcheck.
The Squash TM service¶
perfshop-testmgmt:
image: squashtest/squash-tm:latest
container_name: perfshop-testmgmt
depends_on:
perfshop-squash-db:
condition: service_healthy
environment:
- DATABASE_URL=jdbc:postgresql://perfshop-squash-db:5432/squashtm
- DATABASE_USER=squashtm
- DATABASE_PASSWORD=${SQUASH_DB_PASSWORD:-squashtm}
- SQUASH_JWT_SECRET=${SQUASH_JWT_SECRET}
- SQUASH_ADMIN_LOGIN=${SQUASH_ADMIN_LOGIN:-admin}
- SQUASH_ADMIN_PASSWORD=${SQUASH_ADMIN_PASSWORD:-Squash2026*}
ports:
- "${SQUASH_HTTP_PORT:-8088}:8080"
volumes:
- ./squash-seed/start-plugins.cfg:/opt/squash-tm/conf/start-plugins.cfg:ro
- ./squash-seed/squash.tm.cfg.properties:/opt/squash-tm/conf/squash.tm.cfg.properties:ro
- ./squash-seed/trusted_key.pub:/opt/squash-tm/conf/trusted_key.pub:ro
healthcheck:
test: ["CMD-SHELL", "curl -sf http://localhost:8080/squash/isSquashAlive || exit 1"]
interval: 15s
timeout: 10s
retries: 20
start_period: 120s
Key points¶
| Aspect | Value |
|---|---|
| Image | squashtest/squash-tm:latest (the vendor's official image) |
| JDBC URL | jdbc:postgresql://perfshop-squash-db:5432/squashtm |
| Internal port | 8080 |
| Default host port | 8088 |
| Healthcheck endpoint | http://localhost:8080/squash/isSquashAlive (public Squash TM endpoint, no authentication required) |
start_period |
120 seconds — Squash TM starts slowly (Spring Boot + PostgreSQL init + plugins) |
Critical variables¶
| Variable | Role |
|---|---|
SQUASH_JWT_SECRET |
Base64 secret used to sign JWT tokens that Squash TM sends to Squash Orchestrator. This is the key that authenticates execution jobs submitted to the orchestrator. Must be random and stable. |
SQUASH_ADMIN_LOGIN / _PASSWORD |
Squash TM superadmin account (default admin / Squash2026*) |
DATABASE_URL |
Always jdbc:postgresql://perfshop-squash-db:5432/squashtm |
The JWT secret is shared with the orchestrator
The same SQUASH_JWT_SECRET variable is used by perfshop-testmgmt (for signing) and by perfshop-orchestrator (for verification). Changing it without restarting both will cause jobs to be rejected by the orchestrator with a JWT error. See squash-orchestrator.md.
Configuration by bind mount¶
Three files are mounted read-only into the Squash TM container:
start-plugins.cfg¶
Controls which Squash TM plugins are loaded at startup. PerfShop enables at least:
- The Git SCM connector (
squash-tm-scm-git) — to poll the Forgejo repository and discover scripts - The Squash Orchestrator connector — to submit execution jobs to the orchestrator
squash.tm.cfg.properties¶
Spring properties file that overrides the Squash TM defaults:
- Public URL (
squash.tm.url) - JDBC connection pool configuration
- SCM integration options (polling interval, timeout)
- JWT secret used consistently with the environment variable
trusted_key.pub¶
RSA public key that certifies Squash TM to Squash Orchestrator. The matching private key (trusted_key.pem) is stored on the orchestrator side. This key pair lets the orchestrator verify that submitted jobs indeed come from a legitimate Squash TM, independently of the JWT secret.
The squash-seed seed¶
The perfshop-squash-seed service is a one-shot Python container:
perfshop-squash-seed:
image: python:3.11-slim
depends_on:
perfshop-testmgmt:
condition: service_healthy
perfshop-forgejo-seed:
condition: service_completed_successfully
volumes:
- ./squash-seed/seed.py:/app/seed.py:ro
- forgejo-token-data:/token:ro
command: >
sh -c "pip install --no-cache-dir requests==2.31.0 &&
python /app/seed.py"
restart: "no"
Double dependency¶
The Squash TM seed depends on two conditions:
perfshop-testmgmt: service_healthy— Squash TM must respond on/squash/isSquashAliveperfshop-forgejo-seed: service_completed_successfully— the Forgejo seed must have finished successfully, meaning the Forgejo CI account is created and the API token for Squash TM is stored in the named volumeforgejo-token-data
This double dependency is one of the most tightly constrained startup chains in the entire PerfShop stack.
What the seed does¶
sequenceDiagram
autonumber
participant S as squash-seed
participant STM as perfshop-testmgmt
participant FG as perfshop-forgejo
S->>STM: POST /squash/login<br/>(admin / Squash2026*)
STM-->>S: Session cookie
S->>STM: GET /squash/api/rest/projects<br/>(looks for "PerfShop QA")
alt Project missing
S->>STM: POST /squash/api/rest/projects<br/>{name:"PerfShop QA", ...}
STM-->>S: 201 Created
else Project exists
STM-->>S: 200 (already there)
end
S->>S: Reads /token/forgejo_token (volume)
S->>STM: POST /squash/api/rest/scm-servers<br/>{kind:"git", url:"http://perfshop-forgejo:3000", token:...}
STM-->>S: 201 (or update)
S->>STM: POST /squash/api/rest/scm-repositories<br/>{server:..., name:"perfshop-tests", ...}
STM-->>S: 201
Note over S,STM: Exits with code 0
The main steps:
- Authentication as Squash TM admin
- Creation of the
PerfShop QAproject if it does not already exist (idempotent) - Reading the Forgejo token from the
forgejo-token-datanamed volume (mounted read-only) - Creation of the Git SCM server pointing to
perfshop-forgejo:3000with the authentication token - Creation of the SCM repository
perfshop-testsin the project
Minimalistic seed
The Squash TM seed is intentionally minimalistic: it does not create test cases, campaigns, or requirements. This is deliberate — discovering how to create these artifacts in the web UI is one of the pedagogical objectives. Only what is needed to make SCM polling work is bootstrapped.
Healthcheck and public endpoint¶
The http://perfshop-testmgmt:8080/squash/isSquashAlive endpoint is public (no authentication) and returns 200 OK with a simple body when Squash TM is ready to serve. It is the target of the Docker healthcheck (start_period: 120s) and of the seed polling.
Once healthy, Squash TM exposes its full UI at http://localhost:8088/squash/ (default host port).
Communication with other services¶
flowchart LR
STM["perfshop-testmgmt"]
STM -->|"JDBC :5432"| SQDB[("perfshop-squash-db<br/>PostgreSQL 16")]
STM -->|"Git clone/pull :3000<br/>(CI token)"| FG[("perfshop-forgejo")]
STM -->|"POST /jobs (JWT RS512)"| ORCH["perfshop-orchestrator"]
ORCH -.->|"results"| STM
USER["Instructor<br/>(browser)"] -->|"HTTP :8088/squash/"| STM
Three outbound channels:
- To PostgreSQL: all business data (projects, tests, campaigns, executions)
- To Forgejo: regular SCM polling to discover Robot Framework scripts
- To the orchestrator: JWT-signed submission of execution jobs
Volumes¶
| Volume | Mount point | Content |
|---|---|---|
squash-db-data (named) |
/var/lib/postgresql/data |
PostgreSQL data |
./squash-seed/start-plugins.cfg (bind RO) |
/opt/squash-tm/conf/start-plugins.cfg |
List of enabled plugins |
./squash-seed/squash.tm.cfg.properties (bind RO) |
/opt/squash-tm/conf/squash.tm.cfg.properties |
Squash TM Spring properties |
./squash-seed/trusted_key.pub (bind RO) |
/opt/squash-tm/conf/trusted_key.pub |
RSA public key for the orchestrator |
forgejo-token-data (named, RO) |
/token:ro (for the seed) |
Forgejo CI token read by the seed |
Ports¶
| Service | Host port | Container port | Environment variable |
|---|---|---|---|
perfshop-squash-db |
5433 | 5432 | SQUASH_DB_PORT |
perfshop-testmgmt |
8088 | 8080 | SQUASH_HTTP_PORT |
Going further¶
- QA Stack — Overview — complete end-to-end workflow
- Squash Orchestrator — the recipient of JWT jobs
- Forgejo — the SCM polled by Squash TM
- Test Runner — the final target of execution jobs