Skip to content

Commit 7542316

Browse files
Merge pull request #1045 from adamtheturtle/test-request-time-too-skewed
Test request time too skewed
2 parents ec94f5a + 8e44ac9 commit 7542316

File tree

6 files changed

+65
-0
lines changed

6 files changed

+65
-0
lines changed

dev-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ dulwich==0.19.11
77
flake8-commas==2.0.0 # Require silicon valley commas
88
flake8-quotes==2.0.1 # Require single quotes
99
flake8==3.7.8 # Lint
10+
freezegun==0.3.12
1011
isort==4.3.21 # Lint imports
1112
mypy==0.720 # Type checking
1213
pip_check_reqs==2.0.3

src/vws/_result_codes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
ImageTooLarge,
1212
MetadataTooLarge,
1313
ProjectInactive,
14+
RequestTimeTooSkewed,
1415
TargetNameExist,
1516
TargetStatusNotSuccess,
1617
TargetStatusProcessing,
@@ -43,6 +44,7 @@ def raise_for_result_code(
4344
'InactiveProject': ProjectInactive,
4445
'MetadataTooLarge': MetadataTooLarge,
4546
'ProjectInactive': ProjectInactive,
47+
'RequestTimeTooSkewed': RequestTimeTooSkewed,
4648
'TargetNameExist': TargetNameExist,
4749
'TargetStatusNotSuccess': TargetStatusNotSuccess,
4850
'TargetStatusProcessing': TargetStatusProcessing,

src/vws/exceptions.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,21 @@ def response(self) -> Response:
203203
return self._response
204204

205205

206+
class RequestTimeTooSkewed(Exception):
207+
"""
208+
Exception raised when Vuforia returns a response with a result code
209+
'RequestTimeTooSkewed'.
210+
"""
211+
212+
def __init__(self, response: Response) -> None:
213+
"""
214+
Args:
215+
response: The response to a request to Vuforia.
216+
"""
217+
super().__init__()
218+
self.response = response
219+
220+
206221
class TargetNameExist(Exception):
207222
"""
208223
Exception raised when Vuforia returns a response with a result code

src/vws/query.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,11 @@ def query(
6060
none (return no target_data), all (for all matched targets)".
6161
6262
Raises:
63+
~vws.exceptions.AuthenticationFailure: The client access key pair
64+
is not correct.
6365
~vws.exceptions.MaxNumResultsOutOfRange: `max_num_results`` is not
6466
within the range (1, 50).
67+
~vws.exceptions.ProjectInactive: The project is inactive.
6568
6669
Returns:
6770
An ordered list of target details of matching targets.

src/vws/vws.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ def add_target(
176176
~vws.exceptions.TargetNameExist: A target with the given ``name``
177177
already exists.
178178
~vws.exceptions.ProjectInactive: The project is inactive.
179+
~vws.exceptions.RequestTimeTooSkewed: There is an error with the
180+
time sent to Vuforia.
179181
"""
180182
image_data = image.getvalue()
181183
image_data_encoded = base64.b64encode(image_data).decode('ascii')
@@ -224,6 +226,8 @@ def get_target_record(self, target_id: str) -> Dict[str, Union[str, int]]:
224226
example, the given access key does not match a known database.
225227
~vws.exceptions.UnknownTarget: The given target ID does not match a
226228
target in the database.
229+
~vws.exceptions.RequestTimeTooSkewed: There is an error with the
230+
time sent to Vuforia.
227231
"""
228232
response = self._make_request(
229233
method='GET',
@@ -256,6 +260,8 @@ def _wait_for_target_processed(
256260
than five minutes.
257261
~vws.exceptions.UnknownTarget: The given target ID does not match a
258262
target in the database.
263+
~vws.exceptions.RequestTimeTooSkewed: There is an error with the
264+
time sent to Vuforia.
259265
"""
260266
while True:
261267
report = self.get_target_summary_report(target_id=target_id)
@@ -294,6 +300,8 @@ def wait_for_target_processed(
294300
processing stage for more than ``timeout_seconds`` seconds.
295301
~vws.exceptions.UnknownTarget: The given target ID does not match a
296302
target in the database.
303+
~vws.exceptions.RequestTimeTooSkewed: There is an error with the
304+
time sent to Vuforia.
297305
"""
298306

299307
@timeout(
@@ -323,6 +331,8 @@ def list_targets(self) -> List[str]:
323331
correct.
324332
~vws.exceptions.Fail: There was an error with the request. For
325333
example, the given access key does not match a known database.
334+
~vws.exceptions.RequestTimeTooSkewed: There is an error with the
335+
time sent to Vuforia.
326336
"""
327337
response = self._make_request(
328338
method='GET',
@@ -356,6 +366,8 @@ def get_target_summary_report(
356366
example, the given access key does not match a known database.
357367
~vws.exceptions.UnknownTarget: The given target ID does not match a
358368
target in the database.
369+
~vws.exceptions.RequestTimeTooSkewed: There is an error with the
370+
time sent to Vuforia.
359371
"""
360372
response = self._make_request(
361373
method='GET',
@@ -381,6 +393,8 @@ def get_database_summary_report(self) -> Dict[str, Union[str, int]]:
381393
correct.
382394
~vws.exceptions.Fail: There was an error with the request. For
383395
example, the given access key does not match a known database.
396+
~vws.exceptions.RequestTimeTooSkewed: There is an error with the
397+
time sent to Vuforia.
384398
"""
385399
response = self._make_request(
386400
method='GET',
@@ -410,6 +424,8 @@ def delete_target(self, target_id: str) -> None:
410424
target in the database.
411425
~vws.exceptions.TargetStatusProcessing: The given target is in the
412426
processing state.
427+
~vws.exceptions.RequestTimeTooSkewed: There is an error with the
428+
time sent to Vuforia.
413429
"""
414430
self._make_request(
415431
method='DELETE',
@@ -439,6 +455,8 @@ def get_duplicate_targets(self, target_id: str) -> List[str]:
439455
~vws.exceptions.UnknownTarget: The given target ID does not match a
440456
target in the database.
441457
~vws.exceptions.ProjectInactive: The project is inactive.
458+
~vws.exceptions.RequestTimeTooSkewed: There is an error with the
459+
time sent to Vuforia.
442460
"""
443461
response = self._make_request(
444462
method='GET',
@@ -489,6 +507,8 @@ def update_target(
489507
~vws.exceptions.TargetNameExist: A target with the given ``name``
490508
already exists.
491509
~vws.exceptions.ProjectInactive: The project is inactive.
510+
~vws.exceptions.RequestTimeTooSkewed: There is an error with the
511+
time sent to Vuforia.
492512
"""
493513
data: Dict[str, Union[str, bool, float, int]] = {}
494514

tests/test_exceptions.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import random
77

88
import pytest
9+
from freezegun import freeze_time
910
from mock_vws import MockVWS
1011
from mock_vws.database import VuforiaDatabase
1112
from mock_vws.states import States
@@ -21,6 +22,7 @@
2122
MatchProcessing,
2223
MetadataTooLarge,
2324
ProjectInactive,
25+
RequestTimeTooSkewed,
2426
TargetNameExist,
2527
TargetStatusNotSuccess,
2628
TargetStatusProcessing,
@@ -219,6 +221,28 @@ def test_metadata_too_large(
219221
assert exc.value.response.status_code == codes.UNPROCESSABLE_ENTITY
220222

221223

224+
def test_request_time_too_skewed(vws_client: VWS) -> None:
225+
"""
226+
A ``RequestTimeTooSkewed`` exception is raised when the request time is
227+
more than five minutes different from the server time.
228+
"""
229+
vws_max_time_skew = 60 * 5
230+
leeway = 10
231+
time_difference_from_now = vws_max_time_skew + leeway
232+
233+
# We use a custom tick because we expect the following:
234+
#
235+
# * At least one time check when creating the request
236+
# * At least one time check when processing the request
237+
#
238+
# >= 1 ticks are acceptable.
239+
with freeze_time(auto_tick_seconds=time_difference_from_now):
240+
with pytest.raises(RequestTimeTooSkewed) as exc:
241+
vws_client.get_target_record(target_id='a')
242+
243+
assert exc.value.response.status_code == codes.FORBIDDEN
244+
245+
222246
def test_authentication_failure(high_quality_image: io.BytesIO) -> None:
223247
"""
224248
An ``AuthenticationFailure`` exception is raised when the server access key

0 commit comments

Comments
 (0)