Skip to content

Assert explain hash fields through assertProperties - #732

Open
samafarc wants to merge 1 commit into
documentdb:mainfrom
samafarc:fix-explain-hash-assert
Open

samafarc wants to merge 1 commit into
documentdb:mainfrom
samafarc:fix-explain-hash-assert

Conversation

@samafarc

Copy link
Copy Markdown
Contributor

Assert explain hash fields through assertProperties

Problem

The explain hash tests (test_explain_queryhash_shape.py, test_explain_queryhash_pipeline.py) read planCacheShapeHash / queryShapeHash with local helpers that raise RuntimeError when explain fails or the field is missing. The error fires before any assertion runs. On an engine that doesn't report these hashes, all 168 cases fail with a helper error instead of an assertion failure.

Changes

  • New system/diagnostic/utils/explain_hash.py with assert_hash_relation(result_a, result_b, paths, same, msg). In one assertProperties call it checks:
    • both hashes are non-empty strings
    • the hashes are equal (same=True) or different (same=False)
  • A failed explain result goes to assertProperties, which reports the server error as an assertion failure.
  • The four get_* / _get_* helpers are replaced by explain_find / _explain_aggregate, which return the raw explain result.
  • The $out / $merge layout (stages.0.$cursor.queryPlanner.planCacheShapeHash) is kept as a second candidate path.

Expectations are unchanged. One check is stricter: a Ne comparison no longer passes when a hash is missing.

Testing

  • MongoDB 8.2.4: 168/168 pass before and after.
  • Amazon DocumentDB 8.0: every case now fails inside assertProperties, with the same signature across two runs, instead of raising RuntimeError.
  • Helper negative cases checked: mismatch, a missing hash on either side, $out/$merge path, explain error.
  • Framework unit tests: 48/48. black, isort, flake8, mypy clean.

Example failure on an engine without the field:

The explain queryShapeHash / planCacheShapeHash tests pulled the hash
out of the explain result in local helpers and raised RuntimeError when
the field was missing or explain failed. That failure happened before
any assertion helper ran, so an engine that does not report these
fields failed every case with an exception instead of an assertion
result.

Replace the four helpers with explain_find / _explain_aggregate, which
only return the raw explain result, and a shared assert_hash_relation
helper in diagnostic/utils/explain_hash.py. It checks in a single
assertProperties call that both hashes are non-empty strings and that
they are equal (same shape) or different (different shape). An explain
error is passed to assertProperties and fails there with the server
error.

Behavior change: a different-shape test now fails when the second
explain has no hash, where before Ne passed on a missing field. Test
expectations are otherwise unchanged; 168/168 still pass on MongoDB
8.2.4.

Signed-off-by: Samar Farooqi <samafarc@amazon.com>
@samafarc
samafarc requested a review from a team as a code owner October 21, 2026 21:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant