| name | mz-limits-test |
| description | Add/modify/debug limits test. Trigger: "limits test", "Generator subclass", "many objects", "scaling test", or stress-test Materialize with many objects (tables, views, sources, indexes). Also edits in test/limits/mzcompose.py.
|
Limits Test Framework
The limits test stresses Materialize with large numbers of objects, complex queries, and large ingestions. It catches regressions via fixpoint panics, stack overflows, CI timeouts (O(N^M) with N~1000), and OOM panics (2GB memory limit).
Where It Lives
- Main file:
test/limits/mzcompose.py
- All Generator subclasses live in that single file
- Auto-discovery: Subclasses of
Generator are found automatically via all_subclasses(Generator) from materialize.util - no registration needed
Generator Base Class
class Generator:
COUNT: int = 1000
VERSION: str = "1.0.0"
MAX_COUNT: int | None = None
@classmethod
def body(cls) -> None:
"""Override this. Print testdrive commands to stdout."""
raise NotImplementedError
@classmethod
def all(cls) -> range:
@classmethod
def no_first(cls) -> range:
@classmethod
def no_last(cls) -> range:
@classmethod
def store_explain_and_run(cls, query: str) -> str | None:
"""Records EXPLAIN query for timing and prints `> {query}`."""
header() is inherited - it resets the public schema and grants privileges. footer() prints a blank line. generate() calls header() → body() → footer().
How to Add a New Limits Test
- Add a new class in
test/limits/mzcompose.py that extends Generator.
- Implement the
body() classmethod. It must print() testdrive commands.
- Optionally override
COUNT and MAX_COUNT, only if it's causing issues in CI.
Minimal Template
class MyNewFeature(Generator):
COUNT = min(Generator.COUNT, 100)
MAX_COUNT = 800
@classmethod
def body(cls) -> None:
print("$ postgres-execute connection=mz_system")
print(f"ALTER SYSTEM SET max_tables = {cls.COUNT * 10};")
print("$ postgres-execute connection=mz_system")
print(f"ALTER SYSTEM SET max_objects_per_schema = {cls.COUNT * 10};")
for i in cls.all():
print(f"> CREATE TABLE t{i} (f1 INTEGER);")
print(f"> INSERT INTO t{i} VALUES ({i});")
for i in cls.all():
cls.store_explain_and_run(f"SELECT * FROM t{i}")
print(f"{i}")
You can run it locally with bin/mzcompose --find limits down && bin/mzcompose --find limits run main --scenario=MyNewFeature, add --find-limit for the Release Qualification mode.