Skip to content

Commit 83576ec

Browse files
Merge pull request #882 from VWS-Python/fix-max-file-size
Fix max file size test failure
2 parents c0447b0 + d6aa76a commit 83576ec

File tree

9 files changed

+115
-17
lines changed

9 files changed

+115
-17
lines changed

src/mock_vws/_query_validators/exceptions.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,42 @@ def __init__(self) -> None:
621621
}
622622

623623

624+
class RequestEntityTooLarge(ValidatorException):
625+
"""
626+
Exception raised when the given image file size is too large.
627+
"""
628+
629+
def __init__(self) -> None:
630+
"""
631+
Attributes:
632+
status_code: The status code to use in a response if this is
633+
raised.
634+
response_text: The response text to use in a response if this is
635+
raised.
636+
"""
637+
super().__init__()
638+
self.status_code = HTTPStatus.REQUEST_ENTITY_TOO_LARGE
639+
self.response_text = textwrap.dedent(
640+
"""\
641+
<html>\r
642+
<head><title>413 Request Entity Too Large</title></head>\r
643+
<body bgcolor="white">\r
644+
<center><h1>413 Request Entity Too Large</h1></center>\r
645+
<hr><center>nginx</center>\r
646+
</body>\r
647+
</html>\r
648+
""",
649+
)
650+
date = email.utils.formatdate(None, localtime=False, usegmt=True)
651+
self.headers = {
652+
'Connection': 'Close',
653+
'Date': date,
654+
'Server': 'nginx',
655+
'Content-Type': 'text/html',
656+
'Content-Length': str(len(self.response_text)),
657+
}
658+
659+
624660
class MatchProcessing(ValidatorException):
625661
"""
626662
Exception raised a target is matched which is processing or recently

src/mock_vws/_query_validators/image_validators.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
import io
77
from typing import Dict
88

9-
import requests
109
from PIL import Image
1110

12-
from mock_vws._query_validators.exceptions import BadImage, ImageNotGiven
11+
from mock_vws._query_validators.exceptions import (
12+
BadImage,
13+
ImageNotGiven,
14+
RequestEntityTooLarge,
15+
)
1316

1417

1518
def validate_image_field_given(
@@ -54,7 +57,7 @@ def validate_image_file_size(
5457
request_body: The body of the request.
5558
5659
Raises:
57-
requests.exceptions.ConnectionError: The image file size is too large.
60+
RequestEntityTooLarge: The image file size is too large.
5861
"""
5962
body_file = io.BytesIO(request_body)
6063

@@ -74,7 +77,7 @@ def validate_image_file_size(
7477
# files.
7578
max_bytes = 2 * 1024 * 1024
7679
if len(image) > max_bytes:
77-
raise requests.exceptions.ConnectionError
80+
raise RequestEntityTooLarge
7881

7982

8083
def validate_image_dimensions(

tests/mock_vws/test_authorization_header.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def test_missing(self, endpoint: Endpoint) -> None:
6262
content_type='text/plain;charset=iso-8859-1',
6363
cache_control=None,
6464
www_authenticate='VWS',
65+
connection='keep-alive',
6566
)
6667
assert response.text == 'Authorization header missing.'
6768
return
@@ -114,6 +115,7 @@ def test_one_part(
114115
content_type='text/plain;charset=iso-8859-1',
115116
cache_control=None,
116117
www_authenticate='VWS',
118+
connection='keep-alive',
117119
)
118120
assert response.text == 'Malformed authorization header.'
119121
return
@@ -161,6 +163,7 @@ def test_missing_signature(
161163
content_type='text/html;charset=iso-8859-1',
162164
cache_control='must-revalidate,no-cache,no-store',
163165
www_authenticate=None,
166+
connection='keep-alive',
164167
)
165168
content_filename = 'jetty_error_array_out_of_bounds.html'
166169
content_filename_2 = 'jetty_error_array_out_of_bounds_2.html'
@@ -227,6 +230,7 @@ def test_bad_access_key_query(
227230
content_type='application/json',
228231
cache_control=None,
229232
www_authenticate='VWS',
233+
connection='keep-alive',
230234
)
231235

232236
assert response.json().keys() == {'transaction_id', 'result_code'}
@@ -285,6 +289,7 @@ def test_bad_secret_key_query(
285289
content_type='application/json',
286290
cache_control=None,
287291
www_authenticate='VWS',
292+
connection='keep-alive',
288293
)
289294

290295
assert response.json().keys() == {'transaction_id', 'result_code'}

tests/mock_vws/test_content_length.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ def test_too_small(self, endpoint: Endpoint) -> None:
9797
content_type='application/json',
9898
cache_control=None,
9999
www_authenticate='VWS',
100+
connection='keep-alive',
100101
)
101102
return
102103

tests/mock_vws/test_date_header.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ def test_no_date_header(
7575
content_type=expected_content_type,
7676
cache_control=None,
7777
www_authenticate=None,
78+
connection='keep-alive',
7879
)
7980
return
8081

@@ -141,6 +142,7 @@ def test_incorrect_date_format(
141142
content_type='text/plain;charset=iso-8859-1',
142143
cache_control=None,
143144
www_authenticate='VWS',
145+
connection='keep-alive',
144146
)
145147
return
146148

tests/mock_vws/test_invalid_json.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ def test_invalid_json(
9999
content_type='application/json',
100100
cache_control=None,
101101
www_authenticate=None,
102+
connection='keep-alive',
102103
)
103104
expected_text = 'No image.'
104105
assert response.text == expected_text

tests/mock_vws/test_query.py

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,17 @@
6262
""", # noqa: E501
6363
)
6464

65+
_NGINX_REQUEST_ENTITY_TOO_LARGE_ERROR = textwrap.dedent(
66+
"""\
67+
<html>\r
68+
<head><title>413 Request Entity Too Large</title></head>\r
69+
<body bgcolor="white">\r
70+
<center><h1>413 Request Entity Too Large</h1></center>\r
71+
<hr><center>nginx</center>\r
72+
</body>\r
73+
</html>\r
74+
""",
75+
)
6576

6677
_JETTY_ERROR_DELETION_NOT_COMPLETE_START_PATH = (
6778
Path(__file__).parent / 'jetty_error_deletion_not_complete.html'
@@ -228,6 +239,7 @@ def test_incorrect_no_boundary(
228239
content_type=resp_content_type,
229240
cache_control=resp_cache_control,
230241
www_authenticate=None,
242+
connection='keep-alive',
231243
)
232244

233245
def test_incorrect_with_boundary(
@@ -284,6 +296,7 @@ def test_incorrect_with_boundary(
284296
content_type=None,
285297
cache_control=None,
286298
www_authenticate=None,
299+
connection='keep-alive',
287300
)
288301

289302
@pytest.mark.parametrize(
@@ -347,6 +360,7 @@ def test_no_boundary(
347360
content_type='text/html;charset=utf-8',
348361
cache_control=None,
349362
www_authenticate=None,
363+
connection='keep-alive',
350364
)
351365

352366
def test_bogus_boundary(
@@ -398,6 +412,7 @@ def test_bogus_boundary(
398412
content_type='application/json',
399413
cache_control=None,
400414
www_authenticate=None,
415+
connection='keep-alive',
401416
)
402417

403418
def test_extra_section(
@@ -590,6 +605,7 @@ def test_missing_image(
590605
content_type='application/json',
591606
cache_control=None,
592607
www_authenticate=None,
608+
connection='keep-alive',
593609
)
594610

595611
def test_extra_fields(
@@ -615,6 +631,7 @@ def test_extra_fields(
615631
status_code=HTTPStatus.BAD_REQUEST,
616632
cache_control=None,
617633
www_authenticate=None,
634+
connection='keep-alive',
618635
)
619636

620637
def test_missing_image_and_extra_fields(
@@ -640,6 +657,7 @@ def test_missing_image_and_extra_fields(
640657
status_code=HTTPStatus.BAD_REQUEST,
641658
cache_control=None,
642659
www_authenticate=None,
660+
connection='keep-alive',
643661
)
644662

645663

@@ -778,6 +796,7 @@ def test_out_of_range(
778796
status_code=HTTPStatus.BAD_REQUEST,
779797
cache_control=None,
780798
www_authenticate=None,
799+
connection='keep-alive',
781800
)
782801

783802
@pytest.mark.parametrize(
@@ -816,6 +835,7 @@ def test_invalid_type(
816835
status_code=HTTPStatus.BAD_REQUEST,
817836
cache_control=None,
818837
www_authenticate=None,
838+
connection='keep-alive',
819839
)
820840

821841

@@ -999,6 +1019,7 @@ def test_invalid_value(
9991019
content_type='application/json',
10001020
cache_control=None,
10011021
www_authenticate=None,
1022+
connection='keep-alive',
10021023
)
10031024

10041025

@@ -1111,6 +1132,7 @@ def test_invalid(
11111132
content_type=None,
11121133
cache_control=None,
11131134
www_authenticate=None,
1135+
connection='keep-alive',
11141136
)
11151137

11161138

@@ -1189,6 +1211,7 @@ def test_not_image(
11891211
content_type='application/json',
11901212
cache_control=None,
11911213
www_authenticate=None,
1214+
connection='keep-alive',
11921215
)
11931216
assert response.json().keys() == {'transaction_id', 'result_code'}
11941217
assert_valid_transaction_id(response=response)
@@ -1221,7 +1244,7 @@ def test_png(
12211244
https://library.vuforia.com/articles/Solution/How-To-Perform-an-Image-Recognition-Query.
12221245
the maximum file size is "2MiB for PNG".
12231246
1224-
Above this limit, a ``ConnectionError`` is raised.
1247+
Above this limit, a ``REQUEST_ENTITY_TOO_LARGE`` response is returned.
12251248
We do not test exactly at this limit, but that may be beneficial in the
12261249
future.
12271250
"""
@@ -1271,11 +1294,20 @@ def test_png(
12711294
assert image_content_size > max_bytes
12721295
assert (image_content_size * 0.95) < max_bytes
12731296

1274-
with pytest.raises(requests.exceptions.ConnectionError):
1275-
query(
1276-
vuforia_database=vuforia_database,
1277-
body=body,
1278-
)
1297+
response = query(
1298+
vuforia_database=vuforia_database,
1299+
body=body,
1300+
)
1301+
1302+
assert_vwq_failure(
1303+
response=response,
1304+
status_code=HTTPStatus.REQUEST_ENTITY_TOO_LARGE,
1305+
content_type='text/html',
1306+
cache_control=None,
1307+
www_authenticate=None,
1308+
connection='Close',
1309+
)
1310+
assert response.text == _NGINX_REQUEST_ENTITY_TOO_LARGE_ERROR
12791311

12801312
def test_jpeg(
12811313
self,
@@ -1287,7 +1319,7 @@ def test_jpeg(
12871319
the maximum file size is "512 KiB for JPEG".
12881320
However, this test shows that the maximum size for JPEG is 2 MiB.
12891321
1290-
Above this limit, a ``ConnectionError`` is raised.
1322+
Above this limit, a ``REQUEST_ENTITY_TOO_LARGE`` response is returned.
12911323
We do not test exactly at this limit, but that may be beneficial in the
12921324
future.
12931325
"""
@@ -1336,11 +1368,21 @@ def test_jpeg(
13361368
assert image_content_size > max_bytes
13371369
assert (image_content_size * 0.95) < max_bytes
13381370

1339-
with pytest.raises(requests.exceptions.ConnectionError):
1340-
query(
1341-
vuforia_database=vuforia_database,
1342-
body=body,
1343-
)
1371+
response = query(
1372+
vuforia_database=vuforia_database,
1373+
body=body,
1374+
)
1375+
1376+
assert_vwq_failure(
1377+
response=response,
1378+
status_code=HTTPStatus.REQUEST_ENTITY_TOO_LARGE,
1379+
content_type='text/html',
1380+
cache_control=None,
1381+
www_authenticate=None,
1382+
connection='Close',
1383+
)
1384+
1385+
assert response.text == _NGINX_REQUEST_ENTITY_TOO_LARGE_ERROR
13441386

13451387

13461388
@pytest.mark.usefixtures('verify_mock_vuforia')
@@ -1391,6 +1433,7 @@ def test_max_height(self, vuforia_database: VuforiaDatabase) -> None:
13911433
content_type='application/json',
13921434
cache_control=None,
13931435
www_authenticate=None,
1436+
connection='keep-alive',
13941437
)
13951438
assert response.json().keys() == {'transaction_id', 'result_code'}
13961439
assert_valid_transaction_id(response=response)
@@ -1449,6 +1492,7 @@ def test_max_width(self, vuforia_database: VuforiaDatabase) -> None:
14491492
content_type='application/json',
14501493
cache_control=None,
14511494
www_authenticate=None,
1495+
connection='keep-alive',
14521496
)
14531497
assert response.json().keys() == {'transaction_id', 'result_code'}
14541498
assert_valid_transaction_id(response=response)
@@ -1518,6 +1562,7 @@ def test_unsupported(
15181562
content_type='application/json',
15191563
cache_control=None,
15201564
www_authenticate=None,
1565+
connection='keep-alive',
15211566
)
15221567
assert response.json().keys() == {'transaction_id', 'result_code'}
15231568
assert_valid_transaction_id(response=response)
@@ -1716,6 +1761,7 @@ def test_deleted(
17161761
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
17171762
cache_control='must-revalidate,no-cache,no-store',
17181763
www_authenticate=None,
1764+
connection='keep-alive',
17191765
)
17201766

17211767
return
@@ -1955,6 +2001,7 @@ def test_inactive_project(
19552001
content_type='application/json',
19562002
cache_control=None,
19572003
www_authenticate=None,
2004+
connection='keep-alive',
19582005
)
19592006
assert response.json().keys() == {'transaction_id', 'result_code'}
19602007
assert_valid_transaction_id(response=response)

tests/mock_vws/test_unexpected_json.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ def test_does_not_take_data(
7777
content_type=None,
7878
cache_control=None,
7979
www_authenticate=None,
80+
connection='keep-alive',
8081
)
8182
return
8283

0 commit comments

Comments
 (0)