11#include < gtest/gtest.h>
22#include < aws/core/Aws.h>
3+ #include < aws/core/utils/threading/PooledThreadExecutor.h>
4+ #include < aws/s3/S3Client.h>
5+ #include < aws/s3/model/GetObjectRequest.h>
6+ #include < aws/s3/model/GetObjectResult.h>
7+ #include < aws/transfer/TransferManager.h>
38#include < aws/testing/AwsTestHelpers.h>
49#include < aws/testing/MemoryTesting.h>
10+ #include < sstream>
511
612using namespace Aws ;
13+ using namespace Aws ::S3;
14+ using namespace Aws ::S3::Model;
15+ using namespace Aws ::Transfer;
16+ using namespace Aws ::Utils::Threading;
717
818const char * ALLOCATION_TAG = " TransferUnitTest" ;
919
10- // Copy the VerifyContentRange function for testing
11- // In production, this would be exposed in a header or made testable
12- static bool VerifyContentRange (const Aws::String& requestedRange, const Aws::String& responseContentRange)
13- {
14- if (requestedRange.empty () || responseContentRange.empty ())
15- {
16- return false ;
17- }
18-
19- if (requestedRange.find (" bytes=" ) != 0 )
20- {
21- return false ;
20+ class MockS3Client : public S3Client {
21+ public:
22+ MockS3Client () : S3Client(), shouldReturnWrongRange(false ) {}
23+
24+ void SetReturnWrongRange (bool wrongRange) {
25+ shouldReturnWrongRange = wrongRange;
2226 }
23- Aws::String requestRange = requestedRange.substr (6 );
2427
25- if (responseContentRange.find (" bytes " ) != 0 )
26- {
27- return false ;
28- }
29- Aws::String responseRange = responseContentRange.substr (6 );
30- size_t slashPos = responseRange.find (' /' );
31- if (slashPos != Aws::String::npos)
32- {
33- responseRange = responseRange.substr (0 , slashPos);
28+ GetObjectOutcome GetObject (const GetObjectRequest& request) const override {
29+ GetObjectResult result;
30+
31+ if (request.RangeHasBeenSet ()) {
32+ if (shouldReturnWrongRange) {
33+ // Return a different range than requested
34+ result.SetContentRange (" bytes 1024-2047/2048" );
35+ } else {
36+ // Parse the requested range and return matching ContentRange
37+ Aws::String requestRange = request.GetRange ();
38+ if (requestRange.find (" bytes=" ) == 0 ) {
39+ Aws::String range = requestRange.substr (6 ); // Remove "bytes="
40+ result.SetContentRange (" bytes " + range + " /2048" );
41+ }
42+ }
43+ }
44+
45+ // Create a raw pointer stream
46+ auto stream = Aws::New<std::stringstream>(ALLOCATION_TAG);
47+ *stream << " mock data" ;
48+ result.ReplaceBody (stream);
49+
50+ return GetObjectOutcome (std::move (result));
3451 }
3552
36- return requestRange == responseRange;
37- }
53+ private:
54+ bool shouldReturnWrongRange;
55+ };
3856
3957class TransferUnitTest : public testing ::Test {
4058protected:
59+ void SetUp () override {
60+ executor = Aws::MakeShared<PooledThreadExecutor>(ALLOCATION_TAG, 1 );
61+ mockS3Client = Aws::MakeShared<MockS3Client>(ALLOCATION_TAG);
62+ }
63+
4164 static void SetUpTestSuite () {
4265#ifdef USE_AWS_MEMORY_MANAGEMENT
4366 _testMemorySystem.reset (new ExactTestMemorySystem (1024 , 128 ));
@@ -52,16 +75,12 @@ class TransferUnitTest : public testing::Test {
5275 EXPECT_EQ (_testMemorySystem->GetCurrentOutstandingAllocations (), 0ULL );
5376 EXPECT_EQ (_testMemorySystem->GetCurrentBytesAllocated (), 0ULL );
5477 EXPECT_TRUE (_testMemorySystem->IsClean ());
55- if (_testMemorySystem->GetCurrentOutstandingAllocations () != 0ULL )
56- FAIL ();
57- if (_testMemorySystem->GetCurrentBytesAllocated () != 0ULL )
58- FAIL ();
59- if (!_testMemorySystem->IsClean ())
60- FAIL ();
6178 _testMemorySystem.reset ();
6279#endif
6380 }
6481
82+ std::shared_ptr<PooledThreadExecutor> executor;
83+ std::shared_ptr<MockS3Client> mockS3Client;
6584 static SDKOptions _options;
6685#ifdef USE_AWS_MEMORY_MANAGEMENT
6786 static std::unique_ptr<ExactTestMemorySystem> _testMemorySystem;
@@ -73,41 +92,19 @@ SDKOptions TransferUnitTest::_options;
7392std::unique_ptr<ExactTestMemorySystem> TransferUnitTest::_testMemorySystem = nullptr ;
7493#endif
7594
76- TEST_F (TransferUnitTest, VerifyContentRange_ValidRanges) {
77- // Test matching ranges
78- EXPECT_TRUE (VerifyContentRange (" bytes=0-1023" , " bytes 0-1023/2048" ));
79- EXPECT_TRUE (VerifyContentRange (" bytes=1024-2047" , " bytes 1024-2047/2048" ));
80- EXPECT_TRUE (VerifyContentRange (" bytes=0-499" , " bytes 0-499/500" ));
81-
82- // Test without total size in response
83- EXPECT_TRUE (VerifyContentRange (" bytes=0-1023" , " bytes 0-1023" ));
84- }
85-
86- TEST_F (TransferUnitTest, VerifyContentRange_InvalidRanges) {
87- // Test mismatched ranges - this is what @kai-ion wanted to test!
88- EXPECT_FALSE (VerifyContentRange (" bytes=0-1023" , " bytes 0-1022/2048" ));
89- EXPECT_FALSE (VerifyContentRange (" bytes=0-1023" , " bytes 1024-2047/2048" ));
90- EXPECT_FALSE (VerifyContentRange (" bytes=1024-2047" , " bytes 0-1023/2048" ));
95+ TEST_F (TransferUnitTest, ContentRangeVerification_Failure) {
96+ mockS3Client->SetReturnWrongRange (true );
9197
92- // Test empty inputs
93- EXPECT_FALSE (VerifyContentRange (" " , " bytes 0-1023/2048" ));
94- EXPECT_FALSE (VerifyContentRange (" bytes=0-1023" , " " ));
95- EXPECT_FALSE (VerifyContentRange (" " , " " ));
98+ TransferManagerConfiguration config (executor.get ());
99+ config.s3Client = mockS3Client;
100+ auto transferManager = TransferManager::Create (config);
96101
97- // Test invalid format
98- EXPECT_FALSE (VerifyContentRange (" 0-1023" , " bytes 0-1023/2048" ));
99- EXPECT_FALSE (VerifyContentRange (" bytes=0-1023" , " 0-1023/2048" ));
100- EXPECT_FALSE (VerifyContentRange (" range=0-1023" , " bytes 0-1023/2048" ));
101- }
102-
103- TEST_F (TransferUnitTest, VerifyContentRange_EdgeCases) {
104- // Test single byte range
105- EXPECT_TRUE (VerifyContentRange (" bytes=0-0" , " bytes 0-0/1" ));
102+ auto createStreamFn = []() {
103+ return Aws::New<std::stringstream>(ALLOCATION_TAG);
104+ };
106105
107- // Test large ranges
108- EXPECT_TRUE ( VerifyContentRange ( " bytes=0-1073741823 " , " bytes 0-1073741823/1073741824 " ) );
106+ auto handle = transferManager-> DownloadFile ( " test-bucket " , " test-key " , 0 , 1024 , createStreamFn);
107+ handle-> WaitUntilFinished ( );
109108
110- // Test ranges with different total sizes (should still match the range part)
111- EXPECT_TRUE (VerifyContentRange (" bytes=0-1023" , " bytes 0-1023/5000" ));
112- EXPECT_TRUE (VerifyContentRange (" bytes=0-1023" , " bytes 0-1023/1024" ));
109+ EXPECT_EQ (TransferStatus::FAILED, handle->GetStatus ());
113110}
0 commit comments