|
7 | 7 | #include <aws/crt/auth/Credentials.h> |
8 | 8 | #include <aws/testing/AwsCppSdkGTestSuite.h> |
9 | 9 |
|
| 10 | +#include <atomic> |
| 11 | +#include <chrono> |
| 12 | +#include <memory> |
| 13 | +#include <thread> |
| 14 | + |
10 | 15 | namespace { |
11 | 16 | const char* CRT_CREDS_TEST_LOG = "CrtCredentialsProviderTest"; |
12 | 17 | } |
@@ -56,8 +61,65 @@ class MockedCredsProvider : public Aws::Auth::CrtCredentialsProvider { |
56 | 61 | std::shared_ptr<MockCrtCredentialsProvider> m_provider; |
57 | 62 | }; |
58 | 63 |
|
| 64 | +class AsyncMockCrtCredentialsProvider : public Aws::Crt::Auth::ICredentialsProvider { |
| 65 | + public: |
| 66 | + explicit AsyncMockCrtCredentialsProvider(std::chrono::milliseconds callbackDelay, |
| 67 | + std::shared_ptr<Aws::Crt::Auth::Credentials> credentials) |
| 68 | + : m_callbackDelay{callbackDelay}, m_credentials{std::move(credentials)} {} |
| 69 | + |
| 70 | + ~AsyncMockCrtCredentialsProvider() override { |
| 71 | + if (m_worker.joinable()) { |
| 72 | + m_worker.join(); |
| 73 | + } |
| 74 | + } |
| 75 | + |
| 76 | + bool GetCredentials(const Aws::Crt::Auth::OnCredentialsResolved& onCredentialsResolved) const override { |
| 77 | + const std::chrono::milliseconds delay = m_callbackDelay; |
| 78 | + const std::shared_ptr<Aws::Crt::Auth::Credentials> creds = m_credentials; |
| 79 | + m_worker = std::thread([delay, creds, onCredentialsResolved]() { |
| 80 | + std::this_thread::sleep_for(delay); |
| 81 | + onCredentialsResolved(creds, AWS_OP_SUCCESS); |
| 82 | + }); |
| 83 | + return true; |
| 84 | + } |
| 85 | + |
| 86 | + aws_credentials_provider* GetUnderlyingHandle() const noexcept override { return nullptr; } |
| 87 | + bool IsValid() const noexcept override { return true; } |
| 88 | + |
| 89 | + private: |
| 90 | + std::chrono::milliseconds m_callbackDelay; |
| 91 | + std::shared_ptr<Aws::Crt::Auth::Credentials> m_credentials; |
| 92 | + mutable std::thread m_worker; |
| 93 | +}; |
| 94 | + |
| 95 | +class AsyncMockedCredsProvider : public Aws::Auth::CrtCredentialsProvider { |
| 96 | + public: |
| 97 | + AsyncMockedCredsProvider(std::shared_ptr<AsyncMockCrtCredentialsProvider> provider, std::chrono::milliseconds timeout) |
| 98 | + : Aws::Auth::CrtCredentialsProvider([provider]() -> std::shared_ptr<Aws::Crt::Auth::ICredentialsProvider> { return provider; }, |
| 99 | + timeout, Aws::Client::UserAgentFeature::CREDENTIALS_LOGIN, "AsyncMockedCredsProvider"), |
| 100 | + m_provider{provider} {} |
| 101 | + |
| 102 | + private: |
| 103 | + std::shared_ptr<AsyncMockCrtCredentialsProvider> m_provider; |
| 104 | +}; |
| 105 | + |
59 | 106 | class CrtCredentialsProviderTest : public Aws::Testing::AwsCppSdkGTestSuite {}; |
60 | 107 |
|
| 108 | +TEST_F(CrtCredentialsProviderTest, ShouldNotUseFreedStateWhenRefreshOutlivesTimeout) { |
| 109 | + auto crtCreds = Aws::MakeShared<Aws::Crt::Auth::Credentials>( |
| 110 | + CRT_CREDS_TEST_LOG, Aws::Crt::ByteCursorFromCString("access"), Aws::Crt::ByteCursorFromCString("secret"), |
| 111 | + Aws::Crt::ByteCursorFromCString("token"), static_cast<uint64_t>((Aws::Utils::DateTime::Now() + std::chrono::minutes(100)).Seconds())); |
| 112 | + |
| 113 | + auto underlying_mock = Aws::MakeShared<AsyncMockCrtCredentialsProvider>(CRT_CREDS_TEST_LOG, std::chrono::milliseconds(300), crtCreds); |
| 114 | + |
| 115 | + { |
| 116 | + AsyncMockedCredsProvider provider(underlying_mock, std::chrono::milliseconds(50)); |
| 117 | + EXPECT_TRUE(provider.GetAWSCredentials().IsExpiredOrEmpty()); |
| 118 | + } |
| 119 | + |
| 120 | + std::this_thread::sleep_for(std::chrono::milliseconds(400)); |
| 121 | +} |
| 122 | + |
61 | 123 | TEST_F(CrtCredentialsProviderTest, ShouldCache) { |
62 | 124 | auto underlying_mock = Aws::MakeShared<MockCrtCredentialsProvider>(CRT_CREDS_TEST_LOG); |
63 | 125 | underlying_mock->AddCredentialForReturn(Aws::MakeShared<Aws::Crt::Auth::Credentials>( |
|
0 commit comments