Skip to content

Commit f22e3cd

Browse files
Merge pull request #2554 from VWS-Python/fix-tests
Corrupted images now get an error
2 parents 0ee953e + 46e4317 commit f22e3cd

File tree

7 files changed

+75
-36
lines changed

7 files changed

+75
-36
lines changed

src/mock_vws/_services_validators/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
validate_image_data_type,
3030
validate_image_encoding,
3131
validate_image_format,
32+
validate_image_integrity,
3233
validate_image_is_image,
3334
validate_image_size,
3435
)
@@ -122,6 +123,7 @@ def run_services_validators(
122123
validate_image_format(request_body=request_body)
123124
validate_image_color_space(request_body=request_body)
124125
validate_image_size(request_body=request_body)
126+
validate_image_integrity(request_body=request_body)
125127

126128
validate_name_type(request_body=request_body)
127129
validate_name_length(request_body=request_body)

src/mock_vws/_services_validators/image_validators.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,36 @@
2121
_LOGGER = logging.getLogger(name=__name__)
2222

2323

24+
@beartype
25+
def validate_image_integrity(*, request_body: bytes) -> None:
26+
"""Validate the integrity of the image given to a VWS endpoint.
27+
28+
Args:
29+
request_body: The body of the request.
30+
31+
Raises:
32+
BadImageError: The image is given and is not a valid image file.
33+
"""
34+
if not request_body:
35+
return
36+
37+
request_text = request_body.decode()
38+
image = json.loads(s=request_text).get("image")
39+
if image is None:
40+
return
41+
42+
decoded = decode_base64(encoded_data=image)
43+
44+
image_file = io.BytesIO(initial_bytes=decoded)
45+
pil_image = Image.open(fp=image_file)
46+
47+
try:
48+
pil_image.verify()
49+
except SyntaxError as exc:
50+
_LOGGER.warning(msg="The image is not a valid image file.")
51+
raise BadImageError from exc
52+
53+
2454
@beartype
2555
def validate_image_format(*, request_body: bytes) -> None:
2656
"""Validate the format of the image given to a VWS endpoint.

tests/mock_vws/test_add_target.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -478,14 +478,21 @@ def test_corrupted(
478478
vws_client: VWS,
479479
) -> None:
480480
"""
481-
No error is returned when the given image is corrupted.
481+
An error is returned when the given image is corrupted.
482482
"""
483-
vws_client.add_target(
484-
name="example_name",
485-
width=1,
486-
image=corrupted_image_file,
487-
application_metadata=None,
488-
active_flag=True,
483+
with pytest.raises(expected_exception=BadImageError) as exc:
484+
vws_client.add_target(
485+
name="example_name",
486+
width=1,
487+
image=corrupted_image_file,
488+
application_metadata=None,
489+
active_flag=True,
490+
)
491+
492+
assert_vws_failure(
493+
response=exc.value.response,
494+
status_code=HTTPStatus.UNPROCESSABLE_ENTITY,
495+
result_code=ResultCodes.BAD_IMAGE,
489496
)
490497

491498
@staticmethod

tests/mock_vws/test_flask_app_usage.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ class TestTargetRaters:
455455

456456
@staticmethod
457457
def test_default(
458-
corrupted_image_file: io.BytesIO,
458+
image_file_success_state_low_rating: io.BytesIO,
459459
high_quality_image: io.BytesIO,
460460
) -> None:
461461
"""
@@ -470,10 +470,10 @@ def test_default(
470470
server_secret_key=database.server_secret_key,
471471
)
472472

473-
corrupted_image_target_id = vws_client.add_target(
473+
low_rating_image_target_id = vws_client.add_target(
474474
name=uuid.uuid4().hex,
475475
width=1,
476-
image=corrupted_image_file,
476+
image=image_file_success_state_low_rating,
477477
application_metadata=None,
478478
active_flag=True,
479479
)
@@ -487,27 +487,26 @@ def test_default(
487487
)
488488

489489
for target_id in (
490-
corrupted_image_target_id,
490+
low_rating_image_target_id,
491491
high_quality_image_target_id,
492492
):
493493
vws_client.wait_for_target_processed(target_id=target_id)
494494

495-
corrupted_image_rating = vws_client.get_target_record(
496-
target_id=corrupted_image_target_id,
495+
low_rated_image_rating = vws_client.get_target_record(
496+
target_id=low_rating_image_target_id,
497497
).target_record.tracking_rating
498498

499499
high_quality_image_rating = vws_client.get_target_record(
500500
target_id=high_quality_image_target_id,
501501
).target_record.tracking_rating
502502

503-
# In the real Vuforia, this image may rate as -2.
504-
assert corrupted_image_rating <= 0
503+
assert low_rated_image_rating <= 0
505504
assert high_quality_image_rating > 1
506505

507506
@staticmethod
508507
def test_brisque(
509508
monkeypatch: pytest.MonkeyPatch,
510-
corrupted_image_file: io.BytesIO,
509+
image_file_success_state_low_rating: io.BytesIO,
511510
high_quality_image: io.BytesIO,
512511
) -> None:
513512
"""
@@ -524,10 +523,10 @@ def test_brisque(
524523
server_secret_key=database.server_secret_key,
525524
)
526525

527-
corrupted_image_target_id = vws_client.add_target(
526+
low_rating_image_target_id = vws_client.add_target(
528527
name=uuid.uuid4().hex,
529528
width=1,
530-
image=corrupted_image_file,
529+
image=image_file_success_state_low_rating,
531530
application_metadata=None,
532531
active_flag=True,
533532
)
@@ -541,21 +540,20 @@ def test_brisque(
541540
)
542541

543542
for target_id in (
544-
corrupted_image_target_id,
543+
low_rating_image_target_id,
545544
high_quality_image_target_id,
546545
):
547546
vws_client.wait_for_target_processed(target_id=target_id)
548547

549-
corrupted_image_rating = vws_client.get_target_record(
550-
target_id=corrupted_image_target_id,
548+
low_rated_image_rating = vws_client.get_target_record(
549+
target_id=low_rating_image_target_id,
551550
).target_record.tracking_rating
552551

553552
high_quality_image_rating = vws_client.get_target_record(
554553
target_id=high_quality_image_target_id,
555554
).target_record.tracking_rating
556555

557-
# In the real Vuforia, this image may rate as -2.
558-
assert corrupted_image_rating <= 0
556+
assert low_rated_image_rating <= 0
559557
assert high_quality_image_rating > 1
560558

561559
@staticmethod

tests/mock_vws/test_get_target.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ def test_target_quality(
146146
vws_client: VWS,
147147
high_quality_image: io.BytesIO,
148148
image_file_success_state_low_rating: io.BytesIO,
149-
corrupted_image_file: io.BytesIO,
150149
) -> None:
151150
"""
152151
The target tracking rating is as expected.
@@ -159,14 +158,9 @@ def test_target_quality(
159158
vws_client=vws_client,
160159
image_file=image_file_success_state_low_rating,
161160
)
162-
corrupted_image_file_tracking_rating = _get_target_tracking_rating(
163-
vws_client=vws_client,
164-
image_file=corrupted_image_file,
165-
)
166161
assert (
167162
high_quality_image_tracking_rating
168163
> low_quality_image_tracking_rating
169-
>= corrupted_image_file_tracking_rating
170164
)
171165

172166

tests/mock_vws/test_target_raters.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,15 @@ class TestBrisqueTargetTrackingRater:
5050
"""
5151

5252
@staticmethod
53-
def test_low_quality_image(corrupted_image_file: io.BytesIO) -> None:
53+
def test_low_quality_image(
54+
image_file_success_state_low_rating: io.BytesIO,
55+
) -> None:
5456
"""
5557
Test that a low quality image returns a low rating.
5658
"""
5759
rater = BrisqueTargetTrackingRater()
58-
image_content = corrupted_image_file.getvalue()
60+
image_content = image_file_success_state_low_rating.getvalue()
5961
rating = rater(image_content=image_content)
60-
# In the real Vuforia, this image may rate as -2.
6162
assert rating == 0
6263

6364
@staticmethod

tests/mock_vws/test_update_target.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -670,12 +670,19 @@ def test_corrupted(
670670
target_id: str,
671671
) -> None:
672672
"""
673-
No error is returned when the given image is corrupted.
673+
An error is returned when the given image is corrupted.
674674
"""
675675
vws_client.wait_for_target_processed(target_id=target_id)
676-
vws_client.update_target(
677-
target_id=target_id,
678-
image=corrupted_image_file,
676+
with pytest.raises(expected_exception=BadImageError) as exc:
677+
vws_client.update_target(
678+
target_id=target_id,
679+
image=corrupted_image_file,
680+
)
681+
682+
assert_vws_failure(
683+
response=exc.value.response,
684+
status_code=HTTPStatus.UNPROCESSABLE_ENTITY,
685+
result_code=ResultCodes.BAD_IMAGE,
679686
)
680687

681688
@staticmethod

0 commit comments

Comments
 (0)