Skip to content

Unit Testing Phase 2.3: Query_Cache Unit Tests #5475

@renecannao

Description

@renecannao

Parent Issue

Part of #5472 — Unit Testing Framework: Milestone 2

Depends On

Why Query Cache

Query_Cache has a clean, well-defined interface (set/get/flush/purgeHash) and an interesting internal design (32 KV_BtreeArray hash buckets with rwlocks). Its correctness is critical for performance — a cache bug can cause stale results or memory leaks that are very hard to catch via E2E tests.

Key challenge: The constructor registers Prometheus counters via GloVars.prometheus_registry. This must be handled in the test harness (provide a real registry or guard with nullptr check).

Scope

Test File

test/tap/tests/unit/query_cache_unit-t.cpp

Test Cases

Basic operations:

  • set() a query result → get() with same key returns matching data
  • get() on nonexistent key returns nullptr/empty
  • set() with same key twice → second value replaces first
  • flush() removes all entries, returns correct count

TTL and eviction:

  • set() with TTL → entry accessible before expiration
  • Entry expires after TTL → get() returns empty
  • purgeHash(max_memory) → entries evicted when total size exceeds budget
  • Purge prioritizes oldest/largest entries (verify eviction policy)

Memory accounting:

  • get_data_size() grows after set() operations
  • get_data_size() shrinks after purgeHash() or flush()
  • get_data_size() reflects actual data stored (not just overhead)

Stats counters:

  • Glo_cntSet increments on each set()
  • Glo_cntGet increments on each get() (hit or miss)
  • Glo_cntGetOK increments only on cache hits
  • Glo_dataIN tracks bytes inserted
  • Glo_dataOUT tracks bytes retrieved on hits
  • Glo_cntPurge increments on purge operations

Concurrency (stress tests):

  • Multiple threads doing concurrent set() operations on different keys
  • Multiple threads doing concurrent get() operations
  • Mixed set()/get()/purgeHash() under contention
  • Verify no deadlocks or data corruption (rwlock correctness across 32 buckets)

Edge cases:

  • cache_empty_result behavior — caching queries that return 0 rows
  • Very large cache entries
  • Very high number of entries (verify hash distribution across 32 buckets)
  • set() after flush() works correctly (cache is reusable)

PgSQL equivalents:

  • Mirror key test cases for PgSQL_Query_Cache

Acceptance Criteria

  • All test cases pass without a running ProxySQL instance
  • Tests complete in under 5 seconds (concurrency tests may take longer)
  • No memory leaks under ASAN
  • Stats counters are verified to be accurate
  • Concurrency tests run with at least 4 threads
  • Tests cover both MySQL_Query_Cache and PgSQL_Query_Cache

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions