Skip to content

Make recognition counts seedable so reco reports can be non-empty #3356

Description

@adamtheturtle

Follow-up to #3343, which adds POST /imagetargets/databases/{database_id}/reports/recoCounts. That report is necessarily header-only, because the mock has no way to have any recognitions to report. This issue proposes fixing that gap properly.

What the mock does today

Recognition counts exist as fields but are inert:

  • CloudDatabase has current_month_recos, previous_month_recos, total_recos and reco_threshold (src/mock_vws/database.py). They are keyword-only dataclass fields, so they can be set when constructing a database.
  • ImageTarget has current_month_recos, previous_month_recos and total_recos (src/mock_vws/target.py).
  • Nothing ever changes any of them. _query_tools.py matches targets without touching recognition counts.

There are two concrete holes in that:

  1. The database fields do not survive the Flask/Docker backend. They are absent from CloudDatabaseDict, to_dict and from_dict. A user who passes total_recos=500 to CloudDatabase gets it in-process and silently loses it through the Flask backend, so the same test gives different answers on different backends.
  2. The target fields cannot be set at all. They are absent from ImageTargetDict, to_dict and from_dict, and ImageTarget objects are only ever constructed inside add_target, so no public API reaches them. GET /summary/{target_id} and the new reco counts CSV can therefore only ever report zero per target.

Neither the database nor the target reco fields are mentioned in the class docstrings, so even the part that does work is undiscoverable.

Why not just count recognitions on query?

This is the obvious fix and it is the wrong one.

Real Vuforia's recognition counts lag by a long time — long enough that they do not move within a test run. Two tests assert this against the real service, not just the mock:

  • tests/mock_vws/test_target_summary.py::TestRecognitionCounts::test_recognition performs a query and then asserts all three target counts are still 0. It runs under verify_mock_vuforia, so it passes against real Vuforia.
  • tests/mock_vws/test_database_summary.py::TestRecos was relaxed in 2031caf ("Account for recos now being non-zero", March 2020) to assert only that the counts are integers which do not change between two quick requests, precisely because the real values are delayed.

So incrementing a counter when a query matches would make the mock less faithful for the interaction users actually write tests around: add a target, query it, read a summary. Users who assert total_recos == 0 after a query — matching real Vuforia — would start failing.

Proposal: seedable, not automatic

Let users state the recognition counts they want, and leave the mock's default behaviour exactly as it is now.

  1. Round-trip the existing CloudDatabase reco fields through CloudDatabaseDict / to_dict / from_dict, so the in-process and Flask/Docker backends agree. Add reco_threshold too, which has the same problem.
  2. Round-trip the ImageTarget reco fields through ImageTargetDict / to_dict / from_dict.
  3. Give users a way to set recognition counts on a target, which today has no entry point at all. Targets are created by API calls, so this has to be post-creation — something like a MockVWS method taking a target ID and the three counts, mirrored by a target manager route for the Flask backend (the existing PUT /cloud_databases/<name>/targets/<target_id> route is the natural home).
  4. Have the reco counts CSV report derive its rows from the per-target counts for the requested month: one row per target whose count for that month is non-zero, with target_id and reco_count. current_month_recos and previous_month_recos map onto the two months the endpoint accepts, so seeded targets produce a real report body.
  5. Document the fields in the CloudDatabase and ImageTarget docstrings and in differences-to-vws.rst, replacing the current bare "The mock does not count recognitions" with the reason (real counts are delayed past the length of a test) and the seeding recipe.

Optionally, and only if wanted: a MockVWS flag to opt into incrementing counts on matching queries, off by default. This would be for users who want to exercise "counts went up" code paths and accept that real Vuforia will not behave that way within a test. I would not do this without a user asking for it.

Acceptance criteria

  • CloudDatabase and ImageTarget recognition counts and reco_threshold round-trip through to_dict / from_dict, so the in-process and Flask/Docker backends return identical summaries for the same seeded values.
  • Recognition counts can be set on a target through a public API on both backends.
  • GET /summary, GET /summary/{target_id} and the reco counts CSV all reflect seeded values.
  • The reco counts CSV contains one row per target with a non-zero count for the requested month.
  • Default behaviour is unchanged: with nothing seeded, every count is 0 and the CSV is header-only, so the existing verified tests keep passing against real Vuforia.
  • Verified fake tests cover seeded and unseeded cases on both mock backends. The seeded cases cannot run against real Vuforia and should be marked mock-only, with the reason recorded in differences-to-vws.rst alongside the other mock-only paths.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions