|
14 | 14 | from unittest import mock
|
15 | 15 |
|
16 | 16 | import pytest
|
17 |
| -from botocore.httpchecksum import ( |
18 |
| - AwsChunkedWrapperError, |
19 |
| - Crc32Checksum, |
20 |
| - FlexibleChecksumError, |
21 |
| -) |
| 17 | +from botocore.exceptions import AwsChunkedWrapperError, FlexibleChecksumError |
| 18 | +from botocore.httpchecksum import Crc32Checksum |
22 | 19 | from botocore.model import OperationModel, StringShape, StructureShape
|
23 | 20 |
|
24 | 21 | from aiobotocore.awsrequest import AioAWSResponse
|
25 | 22 | from aiobotocore.config import AioConfig
|
26 | 23 | from aiobotocore.httpchecksum import (
|
27 | 24 | AioAwsChunkedWrapper,
|
| 25 | + StreamingChecksumBody, |
28 | 26 | apply_request_checksum,
|
29 | 27 | handle_checksum_body,
|
30 | 28 | )
|
@@ -523,3 +521,66 @@ def test_wrapper_can_only_seek_to_start(self):
|
523 | 521 | wrapper.seek(0, whence=1)
|
524 | 522 | with pytest.raises(AwsChunkedWrapperError):
|
525 | 523 | wrapper.seek(1, whence=2)
|
| 524 | + |
| 525 | + |
| 526 | +class TestStreamingChecksumBody: |
| 527 | + @pytest.fixture(scope="session") |
| 528 | + def raw_bytes(self): |
| 529 | + return b"hello world" |
| 530 | + |
| 531 | + @pytest.fixture |
| 532 | + def fake_body(self, raw_bytes): |
| 533 | + return AsyncBytesIO(raw_bytes) |
| 534 | + |
| 535 | + @pytest.fixture |
| 536 | + def make_wrapper(self, fake_body): |
| 537 | + def make_wrapper(checksum): |
| 538 | + return StreamingChecksumBody( |
| 539 | + fake_body, |
| 540 | + None, |
| 541 | + Crc32Checksum(), |
| 542 | + checksum, |
| 543 | + ) |
| 544 | + |
| 545 | + return make_wrapper |
| 546 | + |
| 547 | + @pytest.fixture |
| 548 | + def wrapper(self, make_wrapper): |
| 549 | + return make_wrapper("DUoRhQ==") |
| 550 | + |
| 551 | + async def test_basic_read_good(self, raw_bytes, wrapper): |
| 552 | + actual = await wrapper.read() |
| 553 | + assert actual == raw_bytes |
| 554 | + |
| 555 | + async def test_many_reads_good(self, raw_bytes, wrapper): |
| 556 | + actual = b"" |
| 557 | + actual += await wrapper.read(5) |
| 558 | + actual += await wrapper.read(5) |
| 559 | + actual += await wrapper.read(1) |
| 560 | + assert actual == raw_bytes |
| 561 | + |
| 562 | + async def test_basic_read_bad(self, make_wrapper): |
| 563 | + wrapper = make_wrapper("duorhq==") |
| 564 | + with pytest.raises(FlexibleChecksumError): |
| 565 | + await wrapper.read() |
| 566 | + |
| 567 | + async def test_many_reads_bad(self, make_wrapper): |
| 568 | + wrapper = make_wrapper("duorhq==") |
| 569 | + await wrapper.read(5) |
| 570 | + await wrapper.read(6) |
| 571 | + # Whole body has been read, next read signals the end of the stream and |
| 572 | + # validates the checksum of the body contents read |
| 573 | + with pytest.raises(FlexibleChecksumError): |
| 574 | + await wrapper.read(1) |
| 575 | + |
| 576 | + async def test_handles_variable_padding(self, raw_bytes, make_wrapper): |
| 577 | + # This digest is equivalent but with more padding |
| 578 | + wrapper = make_wrapper("DUoRhQ=====") |
| 579 | + actual = await wrapper.read() |
| 580 | + assert actual == raw_bytes |
| 581 | + |
| 582 | + async def test_iter_raises_error(self, make_wrapper): |
| 583 | + wrapper = make_wrapper("duorhq==") |
| 584 | + with pytest.raises(FlexibleChecksumError): |
| 585 | + async for chunk in wrapper: |
| 586 | + pass |
0 commit comments