169 lines
6.5 KiB
C++
169 lines
6.5 KiB
C++
/*
|
|
* AttachmentManagerTest.cpp
|
|
*
|
|
* Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License").
|
|
* You may not use this file except in compliance with the License.
|
|
* A copy of the License is located at
|
|
*
|
|
* http://aws.amazon.com/apache2.0/
|
|
*
|
|
* or in the "license" file accompanying this file. This file is distributed
|
|
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
|
* express or implied. See the License for the specific language governing
|
|
* permissions and limitations under the License.
|
|
*/
|
|
|
|
#include <chrono>
|
|
#include <memory>
|
|
#include <gtest/gtest.h>
|
|
#include <gmock/gmock.h>
|
|
#include <sstream>
|
|
#include <thread>
|
|
|
|
#include "ACL/AttachmentManager.h"
|
|
|
|
namespace alexaClientSDK {
|
|
namespace acl {
|
|
|
|
/// Time out to wait for an attachment.
|
|
static const std::chrono::milliseconds TIME_OUT_IN_MILLISECONDS(50);
|
|
/// The content ID of an attachment.
|
|
static const std::string CONTENT_ID_TEST0 = "contentId_test0";
|
|
/// The content ID of an attachment.
|
|
static const std::string CONTENT_ID_TEST1 = "contentId_test1";
|
|
|
|
using namespace ::testing;
|
|
|
|
/**
|
|
* Test fixture class that tests the @c AttachmentManager
|
|
*/
|
|
class AttachmentManagerTest: public ::testing::Test {
|
|
protected:
|
|
void SetUp() override {
|
|
m_attachmentManager = std::make_shared<AttachmentManager>();
|
|
}
|
|
/// The attachment manager used for testing.
|
|
std::shared_ptr<AttachmentManager> m_attachmentManager;
|
|
/// The condition variable to ensure certain orders of reader and writer.
|
|
std::condition_variable m_cv;
|
|
/// Mutex to protect shared data.
|
|
std::mutex m_mutex;
|
|
};
|
|
|
|
/// Test if the attachment manager has been successfully created.
|
|
TEST_F(AttachmentManagerTest, attachmentManagerCreation) {
|
|
ASSERT_TRUE(m_attachmentManager);
|
|
}
|
|
|
|
/// Test if the attachment reader has timed out.
|
|
TEST_F(AttachmentManagerTest, createAttachmentReaderTimeOut) {
|
|
auto attachmentReader = m_attachmentManager->createAttachmentReader(CONTENT_ID_TEST0);
|
|
auto status = attachmentReader.wait_for(TIME_OUT_IN_MILLISECONDS);
|
|
ASSERT_EQ(status, std::future_status::timeout);
|
|
}
|
|
|
|
/// Test getting attachment through attachment reader synchronously.
|
|
TEST_F(AttachmentManagerTest, createAttachmentReaderSynchrously) {
|
|
std::shared_ptr<std::iostream> attachment = std::make_shared<std::stringstream>();
|
|
m_attachmentManager->createAttachment(CONTENT_ID_TEST0, attachment);
|
|
|
|
auto attachmentReader = m_attachmentManager->createAttachmentReader(CONTENT_ID_TEST0);
|
|
ASSERT_TRUE(attachmentReader.get());
|
|
}
|
|
|
|
/// Test getting attachment through attachment reader asynchronously.
|
|
TEST_F(AttachmentManagerTest, gettingAttachmentAsynchrouslyWithWriterArrivesFirst) {
|
|
auto createAttachment = [this]() {
|
|
std::shared_ptr<std::iostream> attachment = std::make_shared<std::stringstream>();
|
|
m_attachmentManager->createAttachment(CONTENT_ID_TEST0, attachment);
|
|
};
|
|
|
|
std::thread writeThread(createAttachment);
|
|
auto attachmentReader = m_attachmentManager->createAttachmentReader(CONTENT_ID_TEST0);
|
|
ASSERT_TRUE(attachmentReader.get());
|
|
|
|
if (writeThread.joinable()) {
|
|
writeThread.join();
|
|
}
|
|
}
|
|
|
|
/// Test getting attachment through attachment reader asynchronously, with reader trying to read first.
|
|
TEST_F(AttachmentManagerTest, gettingAttachmentAsynchrouslyWithReaderArrivesFirst) {
|
|
bool readerIsReady = false;
|
|
|
|
auto createAttachment = [this, &readerIsReady]() {
|
|
std::shared_ptr<std::iostream> attachment = std::make_shared<std::stringstream>();
|
|
std::unique_lock<std::mutex> lock(m_mutex);
|
|
m_cv.wait(lock, [&readerIsReady]() {
|
|
return readerIsReady;
|
|
});
|
|
m_attachmentManager->createAttachment(CONTENT_ID_TEST0, attachment);
|
|
};
|
|
|
|
auto readAttachment = [this, &readerIsReady]() {
|
|
std::unique_lock<std::mutex> lock(m_mutex);
|
|
auto attachmentReader = m_attachmentManager->createAttachmentReader(CONTENT_ID_TEST0);
|
|
readerIsReady = true;
|
|
lock.unlock();
|
|
m_cv.notify_one();
|
|
ASSERT_TRUE(attachmentReader.get());
|
|
};
|
|
|
|
// Start the read thread before the write thread.
|
|
std::thread readThread(readAttachment);
|
|
std::thread writeThread(createAttachment);
|
|
|
|
if (readThread.joinable()) {
|
|
readThread.join();
|
|
}
|
|
|
|
if (writeThread.joinable()) {
|
|
writeThread.join();
|
|
}
|
|
}
|
|
|
|
/// Test release the expired attachment upon the creation of another attachment.
|
|
TEST_F(AttachmentManagerTest, releaseExpiredAttachmentOnAttachmentCreation) {
|
|
m_attachmentManager = std::make_shared<AttachmentManager>(std::chrono::minutes(0));
|
|
m_attachmentManager->createAttachment(CONTENT_ID_TEST0, std::make_shared<std::stringstream>());
|
|
m_attachmentManager->createAttachment(CONTENT_ID_TEST1, std::make_shared<std::stringstream>());
|
|
|
|
auto attachmentReader = m_attachmentManager->createAttachmentReader(CONTENT_ID_TEST0);
|
|
auto status = attachmentReader.wait_for(TIME_OUT_IN_MILLISECONDS);
|
|
ASSERT_EQ(status, std::future_status::timeout);
|
|
|
|
attachmentReader = m_attachmentManager->createAttachmentReader(CONTENT_ID_TEST1);
|
|
status = attachmentReader.wait_for(TIME_OUT_IN_MILLISECONDS);
|
|
ASSERT_EQ(status, std::future_status::timeout);
|
|
}
|
|
|
|
/// Test releasing attachment through attachment manager without any error.
|
|
TEST_F(AttachmentManagerTest, releaseAttachment) {
|
|
m_attachmentManager->createAttachment(CONTENT_ID_TEST0, std::make_shared<std::stringstream>());
|
|
|
|
m_attachmentManager->releaseAttachment(CONTENT_ID_TEST0);
|
|
// Try to release the attachment that is not created;
|
|
m_attachmentManager->releaseAttachment(CONTENT_ID_TEST1);
|
|
}
|
|
|
|
/// Test reading attachments after attachment has been released.
|
|
TEST_F(AttachmentManagerTest, readAttachmentAfterReleasing) {
|
|
m_attachmentManager->createAttachment(CONTENT_ID_TEST0, std::make_shared<std::stringstream>());
|
|
m_attachmentManager->createAttachment(CONTENT_ID_TEST1, std::make_shared<std::stringstream>());
|
|
|
|
m_attachmentManager->releaseAttachment(CONTENT_ID_TEST0);
|
|
m_attachmentManager->releaseAttachment(CONTENT_ID_TEST1);
|
|
|
|
auto attachmentReader = m_attachmentManager->createAttachmentReader(CONTENT_ID_TEST0);
|
|
auto status = attachmentReader.wait_for(TIME_OUT_IN_MILLISECONDS);
|
|
ASSERT_EQ(status, std::future_status::timeout);
|
|
|
|
attachmentReader = m_attachmentManager->createAttachmentReader(CONTENT_ID_TEST1);
|
|
status = attachmentReader.wait_for(TIME_OUT_IN_MILLISECONDS);
|
|
ASSERT_EQ(status, std::future_status::timeout);
|
|
}
|
|
|
|
} // namespace acl
|
|
} // namespace alexaClientSDK
|