Skip to content

Validators run on every request and re-derive their own applicability #3371

Description

@adamtheturtle

What happens

run_services_validators in src/mock_vws/_services_validators/__init__.py calls around thirty validators in sequence on every request, regardless of which endpoint was hit. Each validator then works out for itself whether it applies, by re-reading the body or by re-checking the path and method.

Two consequences.

The same work is repeated. For a single POST /targets, the request body is json.loadsed by validate_keys, the metadata validators, the active flag validator, the name validators, the width validator and each of the image validators. The image is base64-decoded and opened with PIL separately by validate_image_integrity, validate_image_format, validate_image_color_space and validate_image_size — four decodes and four Image.open calls of the same bytes, each with its own if not request_body: return and if image is None: return preamble.

The route table is rebuilt per request. validate_keys constructs eleven _Route objects on every call, at src/mock_vws/_services_validators/key_validators.py:57 onwards, then linearly matches the request against them.

Why it matters

Correctness first: Vuforia's error precedence — which of several simultaneous problems with a request is the one reported — is currently encoded implicitly as the order of the calls in this one function. That ordering is the product of a lot of verification against real Vuforia, and nothing states it or protects it. Reordering two lines silently changes which result code the mock returns, and only a test which sends a request that is wrong in two ways at once would notice.

Second, this is a mock whose whole point is to be faster than the real service, and the redundant decoding is on the hot path of the most commonly exercised endpoint.

Suggested resolution

Build the validator chains once, per route, at module level, so that each endpoint declares the validators which apply to it in the order they apply. That makes the precedence explicit and reviewable, removes the per-validator applicability guards, and stops validators which cannot apply from running at all.

Parsing the body once and passing the parsed form down the chain would remove the repeated decoding, but is a separate step and need not be done at the same time.

The route table in key_validators.py is a third copy of information already held in _requests_mock_server/mock_web_services_api.py and _flask_server/vws.py; a shared table would fall out of #3370.

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