MC/DC Integration Test Suite (Redis Module)
Summary
Introduce and maintain a Python-based integration test suite for the MC/DC Redis module that runs against a real Redis server with the module loaded. The tests validate command behavior, compression logic, and the command filter layer end‑to‑end.
The suite is executed via:
This target will:
- Build the MC/DC module (
mcdc.so)
- Create / reuse a Python virtualenv (
.venv)
- Install Python test dependencies from
test/integration/requirements.txt
- Start a temporary Redis instance with MC/DC loaded
- Run
pytest on test/integration/
Scope
1. Redis test harness
test/integration/conftest.py:
- Spawns a temporary Redis instance on a random free port using
redis-server.
- Loads the MC/DC module using
--loadmodule with a test config:
MCDC_MODULE_PATH points to the built mcdc.so (defaults to ./build/mcdc.so).
- Uses
cfg=./test/integration/mcdc.conf so tests have a stable MC/DC configuration.
- Waits for Redis to become ready (via
PING).
- Provides a
redis_server session fixture that owns process lifecycle.
- Provides an
r fixture that:
- Creates a Redis client bound to the test server
- Calls
FLUSHALL before each test to isolate state.
2. String command tests (test_strings.py)
Covers both direct MC/DC commands and filter-based rewrites.
Direct MC/DC string commands
Filter rewrites for strings
Verifies that plain Redis commands are transparently rewritten by the command filter when the key is in an MC/DC namespace (e.g., mcdc: prefix):
SET key val → behaves like mcdc.set.
GET key → behaves like mcdc.get.
STRLEN key → routed to mcdc.strlen.
Tests check:
- Value equality on readback.
- Logical vs compressed size via
STRLEN vs mcdc.cstrlen.
Async string commands
mcdc.msetasync
mcdc.mgetasync
Tests:
- Use multiple keys and values (mix of small + highly compressible values).
- Assert that:
mcdc.msetasync returns an OK‑style status (non‑error).
- Subsequent
mcdc.mgetasync returns a list with values equal to what was written.
- Compression behavior still holds for large values (using
mcdc.cstrlen).
3. Hash command tests (test_hashes.py)
Covers all hash commands implemented by MC/DC and their filter rewrites.
Direct MC/DC hash commands
mcdc.hset / mcdc.hget round‑trip for:
- Small values.
- Large, compressible values.
- Compression verification:
- Uses
mcdc.hcstrlen key field to check stored size vs logical length.
Other covered commands:
mcdc.hmget / mcdc.hset with multiple fields
mcdc.hsetnx / mcdc.hgetdel
mcdc.hvals
mcdc.hgetall
mcdc.hstrlen
mcdc.hrandfield
Assertions include:
- Field presence and value equality.
- Correct length reporting via
HSTRLEN / mcdc.hcstrlen.
- For compressible values: compressed size < logical size.
Filter rewrites for hashes
Verifies that plain Redis hash commands are rewritten when the key is in an MC/DC namespace:
HSET → mcdc.hset / mcdc.hsetasync (depending on config)
HMGET → mcdc.hmget / mcdc.hmgetasync
HVALS → mcdc.hvals
HGETALL → mcdc.hgetall
HSTRLEN → mcdc.hstrlen
HGET → mcdc.hget
HRANDFIELD → mcdc.hrandfield
Tests ensure:
- Hash semantics remain identical to plain Redis behavior.
- Values are transparently compressed/decompressed.
- The filter does not interfere with non‑MC/DC keys.
Async hash commands
mcdc.hsetasync
mcdc.hmgetasync
Tests:
- Write multiple fields using
mcdc.hsetasync.
- Read them via
mcdc.hmgetasync and plain HMGET.
- Assert value equality and proper compression for large fields using
mcdc.hcstrlen.
4. Redis version–specific behavior
Where needed (e.g., commands introduced in Redis 8+ like HSETEX), tests:
- Detect Redis server version via
INFO SERVER.
- Skip tests if a feature is not available (e.g., running against Redis 7.2.5).
This keeps the suite compatible with current dev environments while still documenting behavior for newer versions.
Makefile Integration
The itest target:
- Depends on the Redis module being built:
$(TARGET).
- Ensures a Python virtualenv exists (
.venv).
- Installs dependencies from
test/integration/requirements.txt.
- Runs pytest inside the venv, pointing
MCDC_MODULE_PATH to the built module.
Example wiring:
PYTHON ?= python3
VENV_DIR ?= .venv
ITEST_DIR ?= test/integration
REQ_FILE ?= $(ITEST_DIR)/requirements.txt
PYTHON_BIN := $(VENV_DIR)/bin/python
PIP_BIN := $(VENV_DIR)/bin/pip
PYTEST_BIN := $(VENV_DIR)/bin/pytest
.PHONY: venv
venv:
@if [ ! -d "$(VENV_DIR)" ]; then \
echo "Creating Python virtualenv in $(VENV_DIR)..."; \
$(PYTHON) -m venv $(VENV_DIR); \
fi; \
echo "Upgrading pip..."; \
"$(PIP_BIN)" install --upgrade pip >/dev/null; \
if [ -f "$(REQ_FILE)" ]; then \
echo "Installing Python dependencies from $(REQ_FILE)..."; \
"$(PIP_BIN)" install -r "$(REQ_FILE)"; \
else \
echo "WARNING: $(REQ_FILE) not found; skipping dependency install."; \
fi
.PHONY: itest
itest: $(TARGET) venv
@if [ ! -x "$(PYTEST_BIN)" ]; then \
echo "ERROR: pytest not installed in $(VENV_DIR)."; \
exit 1; \
fi; \
if [ ! -d "$(ITEST_DIR)" ]; then \
echo "ERROR: integration test directory '$(ITEST_DIR)' not found."; \
exit 1; \
fi; \
echo "Running integration tests using $(PYTEST_BIN) on $(ITEST_DIR)"; \
MCDC_MODULE_PATH="$(TARGET)" "$(PYTEST_BIN)" -q "$(ITEST_DIR)"
Dependencies
test/integration/requirements.txt:
pytest>=8.0
pytest-timeout>=2.3
pytest-asyncio>=0.23
redis>=7.0
Acceptance Criteria
MC/DC Integration Test Suite (Redis Module)
Summary
Introduce and maintain a Python-based integration test suite for the MC/DC Redis module that runs against a real Redis server with the module loaded. The tests validate command behavior, compression logic, and the command filter layer end‑to‑end.
The suite is executed via:
This target will:
mcdc.so).venv)test/integration/requirements.txtpytestontest/integration/Scope
1. Redis test harness
test/integration/conftest.py:redis-server.--loadmodulewith a test config:MCDC_MODULE_PATHpoints to the builtmcdc.so(defaults to./build/mcdc.so).cfg=./test/integration/mcdc.confso tests have a stable MC/DC configuration.PING).redis_serversession fixture that owns process lifecycle.rfixture that:FLUSHALLbefore each test to isolate state.2. String command tests (
test_strings.py)Covers both direct MC/DC commands and filter-based rewrites.
Direct MC/DC string commands
mcdc.set,mcdc.getround‑trip, for:"hello")."X" * 512).Uses:
STRLEN key→ logical size.mcdc.cstrlen key→ compressed / stored size.Assertions:
cstrlen >= strlen(no compression benefit expected).cstrlen < strlen.Similar coverage for:
mcdc.setexmcdc.setnxmcdc.psetexmcdc.getexFilter rewrites for strings
Verifies that plain Redis commands are transparently rewritten by the command filter when the key is in an MC/DC namespace (e.g.,
mcdc:prefix):SET key val→ behaves likemcdc.set.GET key→ behaves likemcdc.get.STRLEN key→ routed tomcdc.strlen.Tests check:
STRLENvsmcdc.cstrlen.Async string commands
mcdc.msetasyncmcdc.mgetasyncTests:
mcdc.msetasyncreturns an OK‑style status (non‑error).mcdc.mgetasyncreturns a list with values equal to what was written.mcdc.cstrlen).3. Hash command tests (
test_hashes.py)Covers all hash commands implemented by MC/DC and their filter rewrites.
Direct MC/DC hash commands
mcdc.hset/mcdc.hgetround‑trip for:mcdc.hcstrlen key fieldto check stored size vs logical length.Other covered commands:
mcdc.hmget/mcdc.hsetwith multiple fieldsmcdc.hsetnx/mcdc.hgetdelmcdc.hvalsmcdc.hgetallmcdc.hstrlenmcdc.hrandfieldAssertions include:
HSTRLEN/mcdc.hcstrlen.Filter rewrites for hashes
Verifies that plain Redis hash commands are rewritten when the key is in an MC/DC namespace:
HSET→mcdc.hset/mcdc.hsetasync(depending on config)HMGET→mcdc.hmget/mcdc.hmgetasyncHVALS→mcdc.hvalsHGETALL→mcdc.hgetallHSTRLEN→mcdc.hstrlenHGET→mcdc.hgetHRANDFIELD→mcdc.hrandfieldTests ensure:
Async hash commands
mcdc.hsetasyncmcdc.hmgetasyncTests:
mcdc.hsetasync.mcdc.hmgetasyncand plainHMGET.mcdc.hcstrlen.4. Redis version–specific behavior
Where needed (e.g., commands introduced in Redis 8+ like
HSETEX), tests:INFO SERVER.This keeps the suite compatible with current dev environments while still documenting behavior for newer versions.
Makefile Integration
The
itesttarget:$(TARGET)..venv).test/integration/requirements.txt.MCDC_MODULE_PATHto the built module.Example wiring:
Dependencies
test/integration/requirements.txt:Acceptance Criteria
make itestbuilds the module, sets up the venv, starts Redis, and runs all tests.mcdc.cstrlen/mcdc.hcstrlen.mcdc.mgetasync,mcdc.msetasync,mcdc.hmgetasync,mcdc.hsetasync) are fully validated (values and compression), not just “no error”.