async def test__write_to_stream_with_hash_check_fail(self, checksum): stream = io.BytesIO() download = download_mod.Download( sync_test.EXAMPLE_URL, stream=stream, checksum=checksum ) chunk1 = b"first chunk, count starting at 0. " chunk2 = b"second chunk, or chunk 1, which is better? " chunk3 = b"ordinals and numerals and stuff." bad_checksum = u"d3JvbmcgbiBtYWRlIHVwIQ==" header_value = u"crc32c={bad},md5={bad}".format(bad=bad_checksum) headers = {_helpers._HASH_HEADER: header_value} response = _mock_response(chunks=[chunk1, chunk2, chunk3], headers=headers) with pytest.raises(common.DataCorruption) as exc_info: await download._write_to_stream(response) assert not download.finished error = exc_info.value assert error.response is response assert len(error.args) == 1 if checksum == u"md5": good_checksum = u"fPAJHnnoi/+NadyNxT2c2w==" else: good_checksum = u"qmNCyg==" msg = download_mod._CHECKSUM_MISMATCH.format( sync_test.EXAMPLE_URL, bad_checksum, good_checksum, checksum_type=checksum.upper(), ) assert error.args[0] == msg
async def test__write_to_stream_no_hash_check(self): stream = io.BytesIO() download = download_mod.Download(sync_test.EXAMPLE_URL, stream=stream) chunk1 = b"right now, " chunk2 = b"but a little later" response = _mock_response(chunks=[chunk1, chunk2], headers={}) ret_val = await download._write_to_stream(response) assert ret_val is None assert stream.getvalue() == chunk1 + chunk2
async def test__write_to_stream_with_hash_check_success(self, checksum): stream = io.BytesIO() download = download_mod.Download( sync_test.EXAMPLE_URL, stream=stream, checksum=checksum ) chunk1 = b"first chunk, count starting at 0. " chunk2 = b"second chunk, or chunk 1, which is better? " chunk3 = b"ordinals and numerals and stuff." header_value = u"crc32c=qmNCyg==,md5=fPAJHnnoi/+NadyNxT2c2w==" headers = {_helpers._HASH_HEADER: header_value} response = _mock_response(chunks=[chunk1, chunk2, chunk3], headers=headers) ret_val = await download._write_to_stream(response) assert ret_val is None assert stream.getvalue() == chunk1 + chunk2 + chunk3
async def test_consume_with_stream_hash_check_fail(self, checksum): stream = io.BytesIO() download = download_mod.Download( sync_test.EXAMPLE_URL, stream=stream, checksum=checksum ) chunks = (b"zero zero", b"niner tango") bad_checksum = u"anVzdCBub3QgdGhpcyAxLA==" header_value = u"crc32c={bad},md5={bad}".format(bad=bad_checksum) headers = {_helpers._HASH_HEADER: header_value} transport = mock.AsyncMock(spec=["request"]) mockResponse = _mock_response(chunks=chunks, headers=headers) transport.request = mock.AsyncMock(spec=["__call__"], return_value=mockResponse) assert not download.finished with pytest.raises(common.DataCorruption) as exc_info: await download.consume(transport) assert stream.getvalue() == b"".join(chunks) assert download.finished assert download._headers == {} error = exc_info.value assert error.response is transport.request.return_value assert len(error.args) == 1 if checksum == u"md5": good_checksum = u"1A/dxEpys717C6FH7FIWDw==" else: good_checksum = u"GvNZlg==" msg = download_mod._CHECKSUM_MISMATCH.format( sync_test.EXAMPLE_URL, bad_checksum, good_checksum, checksum_type=checksum.upper(), ) assert error.args[0] == msg # Check mocks. transport.request.assert_called_once_with( u"GET", sync_test.EXAMPLE_URL, data=None, headers={}, stream=True, timeout=EXPECTED_TIMEOUT, )
async def _consume_helper( self, stream=None, end=65536, headers=None, chunks=(), response_headers=None, checksum="md5", timeout=None, ): download = download_mod.Download( sync_test.EXAMPLE_URL, stream=stream, end=end, headers=headers ) transport = mock.AsyncMock(spec=["request"]) mockResponse = _mock_response(chunks=chunks, headers=response_headers) transport.request = mock.AsyncMock(spec=["__call__"], return_value=mockResponse) assert not download.finished if timeout is not None: ret_val = await download.consume(transport, timeout=timeout) else: ret_val = await download.consume(transport) assert ret_val is transport.request.return_value called_kwargs = { u"data": None, u"headers": download._headers, u"timeout": EXPECTED_TIMEOUT if timeout is None else timeout, } if chunks: assert stream is not None called_kwargs[u"stream"] = True transport.request.assert_called_once_with( u"GET", sync_test.EXAMPLE_URL, **called_kwargs ) range_bytes = u"bytes={:d}-{:d}".format(0, end) assert download._headers[u"range"] == range_bytes assert download.finished return transport
async def test__write_to_stream_with_invalid_checksum_type(self): BAD_CHECKSUM_TYPE = "badsum" stream = io.BytesIO() download = download_mod.Download( sync_test.EXAMPLE_URL, stream=stream, checksum=BAD_CHECKSUM_TYPE ) chunk1 = b"first chunk, count starting at 0. " chunk2 = b"second chunk, or chunk 1, which is better? " chunk3 = b"ordinals and numerals and stuff." bad_checksum = u"d3JvbmcgbiBtYWRlIHVwIQ==" header_value = u"crc32c={bad},md5={bad}".format(bad=bad_checksum) headers = {_helpers._HASH_HEADER: header_value} response = _mock_response(chunks=[chunk1, chunk2, chunk3], headers=headers) with pytest.raises(ValueError) as exc_info: await download._write_to_stream(response) assert not download.finished error = exc_info.value assert error.args[0] == "checksum must be ``'md5'``, ``'crc32c'`` or ``None``"