Skip to content

test(python): migrate ten test files off the 0.7 call forms - #227

Merged
gouyt13 merged 2 commits into
mainfrom
test/migrate-tests-off-07-forms
Nov 12, 2026
Merged

gouyt13 merged 2 commits into
mainfrom
test/migrate-tests-off-07-forms

Conversation

@gouyt13

@gouyt13 gouyt13 commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

Summary

Migrate ten Python test files off the deprecated 0.7 call forms, so they pass under -W error::DeprecationWarning and keep working after #213 removes those forms in 0.9:

test_array_alignment.py, test_build_cluster_ids.py, test_concurrent_indexes.py, test_index_repr.py, test_kmeans_sampling.py, test_large_dimensions.py, test_persistence_paths.py, test_quantization_factors.py, test_remove_arrays.py, test_thread_counts.py

Related to #214 and #216. These are the remaining files from that issue that #222 does not touch. The other seven (test_hnsw, test_import, test_input_boundaries, test_ivf, test_ivf_initializers, test_portable_indexes, test_symqg) follow separately, to avoid conflicts with #222.

Changes

Most changes replace one call form with another and keep the same thread counts, nbits, seeds and ef_construction:

  • 0.7 constructors become 0.8 keyword constructors. HNSW passes num_clusters=len(centroids) so that set_centroids accepts the centroids, and SymphonyQG uses nbits=32 instead of quantization_bits=0.
  • build() becomes set_centroids() + add(cluster_ids=..., num_threads=1), or add(num_threads=...) for SymphonyQG.
  • search_batch() becomes search(), and is_built becomes len().

Three files needed more than a direct replacement:

  • test_concurrent_indexes.py used build() as a mutation that can run more than once, and 0.8 has no equivalent. Active searches and mutations are now checked to reject add, train and set_centroids with BUSY. No other test checked train or set_centroids for BUSY. These calls raise a different error when the index is idle, so a broken guard still fails the test. To show that SymphonyQG released its access, the test expects the "does not support incremental addition" error from a second add, which takes write access before it rejects the existing graph.
  • test_array_alignment.py: IVF reproduces its rotation with seed=42, as HNSW already did. It no longer rebuilds a loaded reference, because 0.8 rejects set_centroids on an index that stores points. Aligned and unaligned inputs still save identical bytes.
  • test_index_repr.py expects 0.8 capacities: IVF starts at 0, and HNSW calls resize(96) to keep a preallocated capacity. HNSW now fixes num_clusters=1 at construction, so the test no longer checks that the summary changes from the default 16 to 1.

#216 fixes in the two graph tests

CI on this branch failed twice. Each failure was a graph build that left one point unreachable, a case #216 already lists: first the qg alignment case, then test_thread_counts[18446744073709551615-l2-hnsw], where point 4's nearest result was 69. Both tests are in this PR, so the second commit applies the fixes proposed in #216:

  • test_array_alignment.py: SymphonyQG now builds with seed=42 and one thread, like IVF and HNSW. Aligned and unaligned inputs must save identical bytes and return identical k=5 results; the qg case did not compare bytes before. The k=len(data) search, which required every point to be reachable, is removed. The exact-distance check now runs on the k=5 reference results.
  • test_thread_counts.py: IVF still requires every point to find itself. HNSW and SymphonyQG require a self-recall@1 of at least 95%, so up to 4 of the 96 points may miss. Searches on the same graph must still agree across thread counts. The threshold is a judgment call: the only miss observed was the one in CI. Locally, 6,000 graph builds on 96 CPUs and 8,000 parallel builds restricted to 4 CPUs had no misses.

The migration did not change how the HNSW graph is built: add on an empty index runs the same link_exact as the old build (through construct), with the same seed, nbits, M and ef_construction.

Testing

Run with the package built from main; this PR changes only tests.

  • ./scripts/check-python.sh and git diff --check pass.
  • The ten files pass with -W error::DeprecationWarning: 191 passed.
  • Full Python suite: 1146 passed, 2 skipped, the same as before the change.
  • With -W error::DeprecationWarning on the full suite, only the seven files listed above still fail.
  • test_concurrent_indexes.py passed 200 repeated runs, and test_array_alignment.py with test_thread_counts.py passed 200 repeated runs after the Make graph-index tests independent of graph connectivity #216 fixes.
  • Before those fixes, the qg alignment case failed in about 0.2% of runs, on main as well (2 of 400 runs); details are in Make graph-index tests independent of graph connectivity #216.

Rewrite index setup in ten Python test files with the 0.8 API, so they
pass under -W error::DeprecationWarning and keep working after the 0.7
forms are removed in 0.9 (#213):

- constructors take num_clusters, nbits and seed by keyword, and
  SymphonyQG takes ef_construction and nbits=32 for raw vectors;
- build() becomes set_centroids() and add(), or add() for SymphonyQG,
  with num_threads=1 where build() used its single-thread default;
- search_batch() becomes search(), and is_built becomes len().

test_concurrent_indexes used build() as a repeatable mutation, which
0.8 does not have. Active operations are now checked to reject add,
train and set_centroids, and SymphonyQG's released access is checked
through a second add, which takes write access before it rejects the
existing graph. No other test checked train or set_centroids for BUSY.

test_array_alignment reproduces the IVF rotation with seed= instead of
rebuilding a loaded reference, since 0.8 rejects set_centroids on an
index that stores points. test_index_repr expects 0.8 capacities and
fixes the HNSW num_clusters at construction.

Related to #214.
@github-actions github-actions Bot added the release:maintenance Release category managed from the PR title label Nov 12, 2026
Apply the #216 fixes to the two migrated tests that failed in CI on this
branch, each time on a graph build that left one point unreachable:

- test_array_alignment builds SymphonyQG with seed=42 and one thread, as
  the IVF and HNSW cases already do. It compares the saved bytes and the
  k=5 results of aligned and unaligned inputs, and drops the k=len(data)
  search that required every point to be reachable. The exact-distance
  check now runs on the k=5 reference results.
- test_thread_counts keeps exact self-matches for IVF, but requires a
  self-recall of at least 95% for HNSW and SymphonyQG, whose parallel or
  unseeded builds can leave a point unreachable. Searches on the same
  graph must still agree across thread counts.

Related to #216.
@gouyt13
gouyt13 merged commit ffc76f7 into main Nov 12, 2026
40 checks passed
@gouyt13
gouyt13 deleted the test/migrate-tests-off-07-forms branch November 12, 2026 06:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:maintenance Release category managed from the PR title

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant