diff --git a/sdk/core/azure-core/inc/azure/core/http/body_stream.hpp b/sdk/core/azure-core/inc/azure/core/http/body_stream.hpp index 3acb26eb9..978be7cfa 100644 --- a/sdk/core/azure-core/inc/azure/core/http/body_stream.hpp +++ b/sdk/core/azure-core/inc/azure/core/http/body_stream.hpp @@ -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."); }; /** diff --git a/sdk/core/azure-core/test/ut/CMakeLists.txt b/sdk/core/azure-core/test/ut/CMakeLists.txt index 6f5342256..8134d9db6 100644 --- a/sdk/core/azure-core/test/ut/CMakeLists.txt +++ b/sdk/core/azure-core/test/ut/CMakeLists.txt @@ -30,6 +30,7 @@ include(GoogleTest) add_executable ( azure-core-test base64.cpp + bodystream.cpp context.cpp ${CURL_CONNECTION_POOL_TESTS} ${CURL_OPTIONS_TESTS} diff --git a/sdk/core/azure-core/test/ut/bodystream.cpp b/sdk/core/azure-core/test/ut/bodystream.cpp new file mode 100644 index 000000000..144a78162 --- /dev/null +++ b/sdk/core/azure-core/test/ut/bodystream.cpp @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include + +#include + +#if defined(AZ_PLATFORM_POSIX) +#include +#elif defined(AZ_PLATFORM_WINDOWS) +#if !defined(WIN32_LEAN_AND_MEAN) +#define WIN32_LEAN_AND_MEAN +#endif +#if !defined(NOMINMAX) +#define NOMINMAX +#endif +#include +#endif + +#include + +#include + +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 data = {1, 2, 3, 4}; + Azure::Core::Http::MemoryBodyStream ms(data); + EXPECT_NO_THROW(ms.Rewind()); +}