1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
######################################################################
#
# File: test/unit/test_exception.py
#
# Copyright 2020 Backblaze Inc. All Rights Reserved.
#
# License https://www.backblaze.com/using_b2_code.html
#
######################################################################
from __future__ import annotations
import pytest
from apiver_deps_exception import (
AlreadyFailed,
B2Error,
BadJson,
BadUploadUrl,
BucketIdNotFound,
CapExceeded,
Conflict,
DuplicateBucketName,
EmailNotVerified,
FileAlreadyHidden,
FileNotPresent,
InvalidAuthToken,
MissingPart,
NoPaymentHistory,
PartSha1Mismatch,
ServiceError,
StorageCapExceeded,
TooManyRequests,
TransactionCapExceeded,
Unauthorized,
UnknownError,
interpret_b2_error,
)
from b2sdk._internal.exception import ResourceNotFound
class TestB2Error:
def test_plain_ascii(self):
assert 'message' == str(B2Error('message'))
def test_unicode(self):
assert '\u81ea\u7531' == str(B2Error('\u81ea\u7531'))
class TestExceptions:
def test_bad_upload_url_exception(self):
try:
raise BadUploadUrl('foo')
except BadUploadUrl as e:
assert not e.should_retry_http()
assert e.should_retry_upload()
assert str(e) == 'Bad upload url: foo', str(e)
def test_already_failed_exception(self):
try:
raise AlreadyFailed('foo')
except AlreadyFailed as e:
assert str(e) == 'Already failed: foo', str(e)
@pytest.mark.apiver(to_ver=1)
def test_command_error(self):
from apiver_deps_exception import CommandError
try:
raise CommandError('foo')
except CommandError as e:
assert str(e) == 'foo', str(e)
class TestInterpretError:
def test_file_already_hidden(self):
self._check_one(FileAlreadyHidden, 400, 'already_hidden', '', {})
assert 'File already hidden: file.txt' == str(
interpret_b2_error(400, 'already_hidden', '', {}, {'fileName': 'file.txt'})
)
def test_bad_json(self):
self._check_one(BadJson, 400, 'bad_json', '', {})
def test_file_not_present(self):
self._check_one(FileNotPresent, 400, 'no_such_file', '', {})
self._check_one(FileNotPresent, 400, 'file_not_present', '', {})
self._check_one(FileNotPresent, 404, 'not_found', '', {})
assert 'File not present: file.txt' == str(
interpret_b2_error(404, 'not_found', '', {}, {'fileName': 'file.txt'})
)
assert 'File not present: 01010101' == str(
interpret_b2_error(404, 'not_found', '', {}, {'fileId': '01010101'})
)
def test_file_or_bucket_not_present(self):
self._check_one(ResourceNotFound, 404, None, None, {})
assert 'No such file, bucket, or endpoint: ' == str(interpret_b2_error(404, None, None, {}))
def test_duplicate_bucket_name(self):
self._check_one(DuplicateBucketName, 400, 'duplicate_bucket_name', '', {})
assert 'Bucket name is already in use: my-bucket' == str(
interpret_b2_error(400, 'duplicate_bucket_name', '', {}, {'bucketName': 'my-bucket'})
)
def test_missing_part(self):
self._check_one(MissingPart, 400, 'missing_part', '', {})
assert 'Part number has not been uploaded: my-file-id' == str(
interpret_b2_error(400, 'missing_part', '', {}, {'fileId': 'my-file-id'})
)
def test_part_sha1_mismatch(self):
self._check_one(PartSha1Mismatch, 400, 'part_sha1_mismatch', '', {})
assert 'Part number my-file-id has wrong SHA1' == str(
interpret_b2_error(400, 'part_sha1_mismatch', '', {}, {'fileId': 'my-file-id'})
)
def test_unauthorized(self):
self._check_one(Unauthorized, 401, '', '', {})
def test_invalid_auth_token(self):
self._check_one(InvalidAuthToken, 401, 'bad_auth_token', '', {})
self._check_one(InvalidAuthToken, 401, 'expired_auth_token', '', {})
def test_storage_cap_exceeded(self):
self._check_one((CapExceeded, StorageCapExceeded), 403, 'storage_cap_exceeded', '', {})
def test_transaction_cap_exceeded(self):
self._check_one(
(CapExceeded, TransactionCapExceeded), 403, 'transaction_cap_exceeded', '', {}
)
def test_conflict(self):
self._check_one(Conflict, 409, '', '', {})
def test_too_many_requests_with_retry_after_header(self):
retry_after = 200
error = self._check_one(
TooManyRequests,
429,
'',
'',
{'retry-after': retry_after},
)
assert error.retry_after_seconds == retry_after
def test_too_many_requests_without_retry_after_header(self):
error = self._check_one(TooManyRequests, 429, '', '', {})
assert error.retry_after_seconds is None
@pytest.mark.apiver(
from_ver=3
) # previous apivers throw this as well, but BucketIdNotFound is a different class in them
def test_bad_bucket_id(self):
error = self._check_one(
BucketIdNotFound, 400, 'bad_bucket_id', '', {}, {'bucketId': '1001'}
)
assert error.bucket_id == '1001'
def test_service_error(self):
error = interpret_b2_error(500, 'code', 'message', {})
assert isinstance(error, ServiceError)
assert '500 code message' == str(error)
def test_unknown_error(self):
error = interpret_b2_error(499, 'code', 'message', {})
assert isinstance(error, UnknownError)
assert 'Unknown error: 499 code message' == str(error)
@classmethod
def _check_one(
cls,
expected_class,
status,
code,
message,
response_headers,
post_params=None,
):
actual_exception = interpret_b2_error(status, code, message, response_headers, post_params)
assert isinstance(actual_exception, expected_class)
return actual_exception
@pytest.mark.parametrize(
'status, code, expected_exception_cls',
[
(401, 'email_not_verified', EmailNotVerified),
(401, 'no_payment_history', NoPaymentHistory),
],
)
def test_simple_error_handlers(self, status, code, expected_exception_cls):
error = interpret_b2_error(status, code, '', {})
assert isinstance(error, expected_exception_cls)
assert error.code == code
|