What happens
Targets are held in a set, so every endpoint which returns a list of targets iterates in hash order. Because target IDs are random hex and str hashing is salted per process, that order is not stable across runs.
Affected:
src/mock_vws/_query_tools.py:72 — Query API matchessrc/mock_vws/_requests_mock_server/mock_web_services_api.py:722 — GET /targetssrc/mock_vws/_requests_mock_server/mock_web_services_api.py:848 — GET /duplicates/{target_id}
and the corresponding handlers in src/mock_vws/_flask_server/vws.py.
Four runs of the same script, adding the same four fixed target IDs to a database and printing the iteration order:
['ddd', 'bbb', 'ccc', 'aaa']
['ddd', 'bbb', 'aaa', 'ccc']
['bbb', 'aaa', 'ddd', 'ccc']
['bbb', 'ddd', 'aaa', 'ccc']
Why it matters
For GET /targets and GET /duplicates the order is cosmetic, since callers treat the result as a set.
For the Query API it is not. _query_tools.py builds the full result list first and only then truncates:
results=results[: int(max_num_results)]
src/mock_vws/_query_tools.py:129. So a query which matches three targets with max_num_results=1 returns an arbitrary one of the three, and a different one on a different run. The same applies to include_target_data=top at src/mock_vws/_query_tools.py:116, which attaches target data to whichever result happened to sort first rather than to the best match.
That is a flakiness source in the test suites of anything which uses the mock, and it is the kind of flake which is hard to attribute, because the same test passes and fails with no change to the code under test.
Real Vuforia orders query results by match score, best first.
Suggested resolution
The mock has no match score, so it cannot reproduce Vuforia's order. It can at least be deterministic. Sorting by upload_date and then by target_id would make repeated runs agree with each other, which is what removes the flake.
differences-to-vws.rst should then record that the mock's query result order is deterministic but is not Vuforia's score order, so callers should not read the mock's order as a ranking. It currently says nothing about result ordering.
What happens
Targets are held in a
set, so every endpoint which returns a list of targets iterates in hash order. Because target IDs are random hex andstrhashing is salted per process, that order is not stable across runs.Affected:
src/mock_vws/_query_tools.py:72— Query API matchessrc/mock_vws/_requests_mock_server/mock_web_services_api.py:722—GET /targetssrc/mock_vws/_requests_mock_server/mock_web_services_api.py:848—GET /duplicates/{target_id}and the corresponding handlers in
src/mock_vws/_flask_server/vws.py.Four runs of the same script, adding the same four fixed target IDs to a database and printing the iteration order:
Why it matters
For
GET /targetsandGET /duplicatesthe order is cosmetic, since callers treat the result as a set.For the Query API it is not.
_query_tools.pybuilds the full result list first and only then truncates:src/mock_vws/_query_tools.py:129. So a query which matches three targets withmax_num_results=1returns an arbitrary one of the three, and a different one on a different run. The same applies toinclude_target_data=topatsrc/mock_vws/_query_tools.py:116, which attaches target data to whichever result happened to sort first rather than to the best match.That is a flakiness source in the test suites of anything which uses the mock, and it is the kind of flake which is hard to attribute, because the same test passes and fails with no change to the code under test.
Real Vuforia orders query results by match score, best first.
Suggested resolution
The mock has no match score, so it cannot reproduce Vuforia's order. It can at least be deterministic. Sorting by
upload_dateand then bytarget_idwould make repeated runs agree with each other, which is what removes the flake.differences-to-vws.rstshould then record that the mock's query result order is deterministic but is not Vuforia's score order, so callers should not read the mock's order as a ranking. It currently says nothing about result ordering.