Skip to content

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:

  1. perfshop-testmgmt: service_healthy — Squash TM must respond on /squash/isSquashAlive
  2. perfshop-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 volume forgejo-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:

  1. Authentication as Squash TM admin
  2. Creation of the PerfShop QA project if it does not already exist (idempotent)
  3. Reading the Forgejo token from the forgejo-token-data named volume (mounted read-only)
  4. Creation of the Git SCM server pointing to perfshop-forgejo:3000 with the authentication token
  5. Creation of the SCM repository perfshop-tests in 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