booblik
Wikici

The Smoke Test

Generated page

Model gemma-mtp, commit ef58254ca7be, 2026-08-16, sources: 6. Edit the code or the hand-written documentation instead.

What this module is responsible for

The Smoke Test module ensures that the built distribution and the resulting Docker image are actually functional in a real-world runtime environment. While unit tests verify logic, the smoke tests verify delivery: they ensure that configuration is correctly read, the main method doesn't die at startup, and the containerized environment preserves the intended runtime profile and security constraints.

Diagram

The Distribution Lifecycle

The smoke test starts by building the full distribution using the Gradle installDist task (smoke.sh:31). Once built, it launches the broker as a background process and waits for the "booblik listening" log entry to confirm it has successfully bound to the network (smoke.sh:41). The lifecycle concludes by killing the broker and starting a second instance to ensure the system can transition from a stopped to a running state without losing data (smoke.sh:131).

The Wire Protocol and CRC32C Verification

To ensure the implementation hasn't drifted from the specification, a Python script is used to communicate over a raw socket (smoke.sh:47). This script is intentionally written in a language that shares no code with the Kotlin implementation, acting as an independent validator of the binary format (smoke.sh:51). It performs the following checks:

FieldTypeDescription
lengthint32Size of the body
apiKeyint16Request type
apiVersionint16Protocol version
correlationIdint32Request/Response matching
crc32cint32Per-record checksum (Castagnoli)

The client manually calculates the CRC32C for each record and asserts that the broker's returned checksum matches the expected value (smoke.sh:125).

The Log Recovery and Restart Mechanism

The tests verify that the append-only log is durable across process restarts. After the first broker instance is killed, a new instance is started using the same properties file (smoke.sh:133). The test then verifies that the log segment is recovered by checking that the broker reports the correct offset range for the "smoke" topic (smoke.sh:139).

The Docker Runtime Profile

The ci/docker-smoke.sh script validates that the Docker image preserves the specific resource constraints required for the broker's performance profile. It extracts the jvm: line from the container logs and verifies that all six mandatory flags are present (docker-smoke.sh:75). These flags include:

FlagPurpose
-XX:+UseSerialGCGarbage Collection strategy
-XX:ReservedCodeCacheSize=32MCode cache limit
-XX:MaxDirectMemorySize=32MDirect memory limit
-Xss256kThread stack size
-XX:MaxMetaspaceSize=80MMetaspace limit
-Xmx64MHeap memory limit

Additionally, it ensures the process does not run as root by checking the id -un output (docker-smoke.sh:95).

Sparse Segment Materialization

To optimize disk usage, the broker uses sparse files for its segments. The smoke test executes a command inside the container to locate the latest .log segment and uses stat to check its apparent size versus its actual disk occupation (docker-smoke.sh:102). It asserts that the actual blocks occupied are significantly less than the apparent size, confirming that the segment is indeed sparse (docker-smoke.sh:104).

The Health Check and METADATA Interface

The health check mechanism is tested to ensure it provides meaningful status. It validates that the booblik-health tool correctly identifies a live broker via the METADATA interface (docker-smoke.sh:87). Crucially, it also verifies that the health check does not report a "healthy" status if it is attempting to connect to a port that is not actually listening (docker-smoke.sh:88).

Key files

FileLinesWhat is there
ci/smoke.sh47-128Python-based independent wire protocol validator
ci/docker-smoke.sh75-83JVM flag profile verification logic
ci/docker-smoke.sh94-95Non-root user identity check
ci/docker-smoke.sh102-104Sparse file/segment verification

Behaviour that surprises

  • The transferTo method in the transport layer only provides zero-copy performance when the target is a SocketChannel (README.md:211).
  • The booblik-app start script is responsible for baking the JVM profile into the distribution, but this can be silently overridden by a JAVA_OPTS line in a Dockerfile (README.md:80).
  • The booblik-client is a "shared codec" that is used by both the client and the server to ensure the wire format remains consistent (README.md:222).

On this page