We value your privacy

This site uses cookies to improve your browsing experience, analyze site traffic, and show personalized content. See our Privacy Policy.

  1. MooseStack
  2. Testing Utilities

Testing Utilities

MooseTip:

Testing utilities are currently available for TypeScript only.

The testing utilities provide purpose-built tools for benchmarking, validating, and diagnosing MooseStack applications against ClickHouse. They are shipped as a separate subpath import so they are never bundled into production code.

import {  profileBenchmark,  explain,  tableStats,  createTestReporter,} from "@514labs/moose-lib/testing";

Query Profiling

Profile query execution by reading ClickHouse's system.query_log. The profiling workflow batches multiple runs, flushes logs once, and resolves all results in a single lookup.

profileBenchmark

Run a query N times and return server-side profiling data with percentile summaries.

benchmark.test.ts
import { getMooseUtils } from "@514labs/moose-lib";import { profileBenchmark } from "@514labs/moose-lib/testing"; const { client, sql } = await getMooseUtils({ readonly: true });const query = sql`SELECT count() FROM MyTable WHERE status = 'active'`; const { profiles, p50, p95 } = await profileBenchmark(client.query, query, 12); console.log(`p50: ${p50}ms, p95: ${p95}ms`);// Each profile contains: queryId, durationMs, readRows, readBytes,// memoryUsage, resultRows, diskReadUs, osReadBytes

Queries are executed sequentially to measure individual query performance, not contention.

profileQuery / resolveProfiles

For finer control, execute queries individually and batch-resolve profiles later.

manual-profile.test.ts
import { profileQuery, resolveProfiles } from "@514labs/moose-lib/testing"; // Run several queries, collecting query IDsconst ids: string[] = [];ids.push(await profileQuery(client.query, queryA));ids.push(await profileQuery(client.query, queryB)); // Flush logs once and resolve all profiles in one batchconst profiles = await resolveProfiles(client.query, ids);

BenchmarkResult

PropertyTypeDescription
profilesreadonly ProfileResult[]Per-run profiling data
p50number50th percentile of server-side duration (ms)
p95number95th percentile of server-side duration (ms)

ProfileResult

PropertyTypeDescription
queryIdstringClickHouse query ID
durationMsnumberServer-side query duration (ms)
readRowsnumberRows read from storage
readBytesnumberBytes read from storage
memoryUsagenumberPeak memory usage (bytes)
resultRowsnumberRows in result set
diskReadUsnumberDisk read time (microseconds)
osReadBytesnumberOS-level bytes read

EXPLAIN Analysis

explain

Run EXPLAIN indexes=1 on a query and extract index condition and granule pruning statistics.

explain.test.ts
import { explain } from "@514labs/moose-lib/testing"; const plan = await explain(client.query, query); console.log(`Index: ${plan.indexCondition}`);console.log(`Granules: ${plan.selectedGranules}/${plan.totalGranules} (skip ${plan.granuleSkipPct}%)`);

ExplainResult

PropertyTypeDescription
indexConditionstringThe index condition extracted from the EXPLAIN plan
selectedGranulesnumberNumber of granules selected for reading
totalGranulesnumberTotal granules in the table
granuleSkipPctnumberPercentage of granules skipped (0–100)
rawPlanstringFull EXPLAIN output

Table Diagnostics

tableStats

Get row count, part count, and disk size for a single table.

table-stats.test.ts
import { tableStats } from "@514labs/moose-lib/testing"; const stats = await tableStats(client.query, "MyTable");console.log(`${stats.rows} rows, ${stats.parts} parts, ${stats.diskSize}`);

Supports database.table notation. Table names are validated and quoted to prevent injection.

TableStats

PropertyTypeDescription
tablestringTable name as provided
rowsnumberTotal row count
partsnumberActive part count
diskSizestringHuman-readable disk size (e.g. "1.23 GiB")

Test Reporting

Accumulate test results and flush them to a timestamped JSON file.

createTestReporter

reporter.test.ts
import { createTestReporter } from "@514labs/moose-lib/testing"; const { results, flush } = createTestReporter({  prefix: "benchmark-details",  outputDir: new URL("../reports", import.meta.url).pathname,}); // Record results during testsresults.tests["baseline"] = { p50: 12, p95: 45 };results.tests["variant-A"] = { p50: 10, p95: 38 }; // Write to disk (returns the filepath)const filepath = await flush();

The output JSON includes a timestamp, target (ClickHouse host and database), and all recorded tests.

TestReporterOptions

PropertyTypeRequiredDescription
prefixstringYesFilename prefix (e.g. "benchmark-details")
outputDirstringYesDirectory to write report files
targetTestReportTargetNoClickHouse host and database. Defaults to MOOSE_CLICKHOUSE_CONFIG__HOST and MOOSE_CLICKHOUSE_CONFIG__DB_NAME env vars.

Utility Functions

percentile

Calculate the Nth percentile from an array of numbers.

import { percentile } from "@514labs/moose-lib/testing"; percentile([10, 20, 30, 40, 50], 95); // 50

On this page

Query ProfilingprofileBenchmarkprofileQuery / resolveProfilesBenchmarkResultProfileResultEXPLAIN AnalysisexplainExplainResultTable DiagnosticstableStatsTableStatsTest ReportingcreateTestReporterTestReporterOptionsUtility Functionspercentile
Edit this page
FiveonefourFiveonefour
Fiveonefour Docs
MooseStackHostingTemplatesGuides
Release Notes
Source559
  • Overview
Build a New App
  • 5 Minute Quickstart
  • Browse Templates
  • Existing ClickHouse
Add to Existing App
  • Next.js
  • Fastify
Fundamentals
  • Moose Runtime
  • MooseDev MCP
  • Language Server
  • Data Modeling
Moose Modules
  • Moose OLAP
  • Moose Streaming
  • Moose Workflows
  • Moose APIs & Web Apps
Deployment & Lifecycle
  • Moose Dev
  • Moose Migrate
  • Moose Deploy
Reference
  • API Reference
  • Query Layer
  • Testing Utilities
  • Data Types
  • Table Engines
  • CLI
  • Configuration
  • Observability Metrics
  • Help
  • Release Notes
Contribution
  • Documentation
  • Framework