Throw a logic error when calling Rewind on unsupported BodyStreams and update the exception message to be actionable. (#1713)

* Throw a runtime error when calling Rewind on unsupported BodyStreams and update the exception message.

* Add rewind test for bodystream.

* Change exception type from runtime to logic.

* Add necessary platform specific headers.
This commit is contained in:
Ahson Khan 2021-02-22 12:26:51 -08:00 committed by GitHub
parent 97b0ccf79b
commit 0dfe2f498d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 4 deletions

View File

@ -68,10 +68,10 @@ namespace Azure { namespace Core { namespace Http {
*/
virtual void Rewind()
{
// Exception is not meant to be caught. This is rather an indication of a bad program that
// needs to be updated. This is the reason of using `throw` alone.
throw "The upload BodyStream doesn't support Rewind which is required to guarantee fault "
"tolerance when retrying the operation.";
throw std::logic_error(
"The specified BodyStream doesn't support Rewind which is required to guarantee fault "
"tolerance when retrying any operation. Consider creating a MemoryBodyStream or "
"FileBodyStream, which are rewindable.");
};
/**

View File

@ -30,6 +30,7 @@ include(GoogleTest)
add_executable (
azure-core-test
base64.cpp
bodystream.cpp
context.cpp
${CURL_CONNECTION_POOL_TESTS}
${CURL_OPTIONS_TESTS}

View File

@ -0,0 +1,63 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
#include <azure/core/platform.hpp>
#include <iostream>
#if defined(AZ_PLATFORM_POSIX)
#include <fcntl.h>
#elif defined(AZ_PLATFORM_WINDOWS)
#if !defined(WIN32_LEAN_AND_MEAN)
#define WIN32_LEAN_AND_MEAN
#endif
#if !defined(NOMINMAX)
#define NOMINMAX
#endif
#include <windows.h>
#endif
#include <gtest/gtest.h>
#include <azure/core/http/body_stream.hpp>
using namespace Azure::Core;
// Used to test virtual, default behavior of BodyStream.
class TestBodyStream : public Http::BodyStream {
int64_t OnRead(Context const& context, uint8_t* buffer, int64_t count) override { return 0; }
int64_t Length() const override { return 0; }
};
TEST(BodyStream, Rewind)
{
TestBodyStream tb;
EXPECT_THROW(tb.Rewind(), std::logic_error);
std::string testDataPath(AZURE_TEST_DATA_PATH);
#if defined(AZ_PLATFORM_POSIX)
testDataPath.append("/fileData");
int f = open(testDataPath.data(), O_RDONLY);
EXPECT_GE(f, 0);
#elif defined(AZ_PLATFORM_WINDOWS)
testDataPath.append("\\fileData");
HANDLE f = CreateFile(
testDataPath.data(),
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
EXPECT_NE(f, INVALID_HANDLE_VALUE);
#else
#error "Unknown platform"
#endif
auto fileBodyStream = Azure::Core::Http::FileBodyStream(f, 0, 0);
EXPECT_NO_THROW(fileBodyStream.Rewind());
std::vector<uint8_t> data = {1, 2, 3, 4};
Azure::Core::Http::MemoryBodyStream ms(data);
EXPECT_NO_THROW(ms.Rewind());
}