avs-device-sdk/CapabilitiesDelegate/test/Storage/SQLiteCapabilitiesDelegateS...

290 lines
9.1 KiB
C++

/*
* Copyright 2019 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 <fstream>
#include <string>
#include <unordered_map>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <AVSCommon/Utils/Configuration/ConfigurationNode.h>
#include <CapabilitiesDelegate/Storage/SQLiteCapabilitiesDelegateStorage.h>
namespace alexaClientSDK {
namespace capabilitiesDelegate {
namespace storage {
namespace test {
using namespace avsCommon::utils::configuration;
using namespace ::testing;
/// Test database file name.
static const std::string TEST_DATABASE_FILE_NAME = "SQLiteCapabilitiesDelegateStorageTest.db";
// clang-format off
static const std::string CAPABILITIES_DELEGATE_JSON = R"(
{
"capabilitiesDelegate" : {
"databaseFilePath":")" + TEST_DATABASE_FILE_NAME + R"("
}
}
)";
// clang-format on
/// Test endpoint ID.
static const std::string TEST_ENDPOINT_ID_1 = "EndpointID1";
/// Test endpoint ID.
static const std::string TEST_ENDPOINT_ID_2 = "EndpointID2";
/// Test endpoint configuration.
static const std::string TEST_ENDPOINT_CONFIG_1 = "EndpointConfig1";
/// Test endpoint configuration.
static const std::string TEST_ENDPOINT_CONFIG_2 = "EndpointConfig2";
/**
* Checks whether a file exists in the file system.
*
* @param file The file name.
* @return Whether the file exists.
*/
static bool fileExists(const std::string& file) {
std::ifstream dbFile(file);
return dbFile.good();
}
/**
* Test harness for @c SQLiteCapabilitiesDelegateStorage.
*/
class SQLiteCapabilitiesDelegateStorageTest : public Test {
public:
/// Setup before each test case.
void SetUp() override;
/// Teardown after each test case.
void TearDown() override;
protected:
/// Cleanup function to close.
void closeAndDeleteDB();
/// The database instance used for the tests.
std::unique_ptr<SQLiteCapabilitiesDelegateStorage> m_db;
};
void SQLiteCapabilitiesDelegateStorageTest::closeAndDeleteDB() {
if (m_db) {
m_db->close();
}
m_db.reset();
if (fileExists(TEST_DATABASE_FILE_NAME)) {
remove(TEST_DATABASE_FILE_NAME.c_str());
}
}
void SQLiteCapabilitiesDelegateStorageTest::SetUp() {
/// Initialize Global ConfigurationNode with valid value.
auto json = std::shared_ptr<std::stringstream>(new std::stringstream());
*json << CAPABILITIES_DELEGATE_JSON;
std::vector<std::shared_ptr<std::istream>> jsonStream;
jsonStream.push_back(json);
ASSERT_TRUE(ConfigurationNode::initialize(jsonStream));
m_db = SQLiteCapabilitiesDelegateStorage::create(ConfigurationNode::getRoot());
ASSERT_THAT(m_db, NotNull());
ASSERT_TRUE(m_db->createDatabase());
}
void SQLiteCapabilitiesDelegateStorageTest::TearDown() {
ConfigurationNode::uninitialize();
closeAndDeleteDB();
}
/**
* Tests create method with invalid @c ConfigurationNode.
*/
TEST_F(SQLiteCapabilitiesDelegateStorageTest, test_createInvalidConfigurationRoot) {
ConfigurationNode::uninitialize();
std::vector<std::shared_ptr<std::istream>> empty;
ConfigurationNode::initialize(empty);
ASSERT_THAT(SQLiteCapabilitiesDelegateStorage::create(ConfigurationNode::getRoot()), IsNull());
}
/**
* Tests create method with valid @c ConfigurationNode.
*/
TEST_F(SQLiteCapabilitiesDelegateStorageTest, test_createValidConfigurationRoot) {
ASSERT_THAT(SQLiteCapabilitiesDelegateStorage::create(ConfigurationNode::getRoot()), NotNull());
}
/**
* Tests if create existing database fails.
*/
TEST_F(SQLiteCapabilitiesDelegateStorageTest, test_createExistingDatabaseFails) {
ASSERT_FALSE(m_db->createDatabase());
}
/**
* Tests if the open existing database succeeds.
*/
TEST_F(SQLiteCapabilitiesDelegateStorageTest, test_openExistingDatabaseSucceeds) {
m_db->close();
ASSERT_TRUE(m_db->open());
}
/**
* Tests if the store method works with a single endpoint.
*/
TEST_F(SQLiteCapabilitiesDelegateStorageTest, test_storeForEndpointWorks) {
ASSERT_TRUE(m_db->store(TEST_ENDPOINT_ID_1, TEST_ENDPOINT_CONFIG_1));
std::string testString;
ASSERT_TRUE(m_db->load(TEST_ENDPOINT_ID_1, &testString));
ASSERT_EQ(testString, TEST_ENDPOINT_CONFIG_1);
}
/**
* Tests if the store method works with an endpoint map.
*/
TEST_F(SQLiteCapabilitiesDelegateStorageTest, test_storeForEndpointMapWorks) {
std::unordered_map<std::string, std::string> storeMap;
storeMap.insert({TEST_ENDPOINT_ID_1, TEST_ENDPOINT_CONFIG_1});
storeMap.insert({TEST_ENDPOINT_ID_2, TEST_ENDPOINT_CONFIG_2});
ASSERT_TRUE(m_db->store(storeMap));
std::unordered_map<std::string, std::string> loadMap;
ASSERT_TRUE(m_db->load(&loadMap));
ASSERT_THAT(loadMap.size(), Eq(2U));
auto it1 = loadMap.find(TEST_ENDPOINT_ID_1);
ASSERT_NE(it1, loadMap.end());
ASSERT_EQ(it1->second, TEST_ENDPOINT_CONFIG_1);
auto it2 = loadMap.find(TEST_ENDPOINT_ID_2);
ASSERT_NE(it2, loadMap.end());
ASSERT_EQ(it2->second, TEST_ENDPOINT_CONFIG_2);
}
/**
* Test if storing an existing entry in to the database replaces the previous value.
*/
TEST_F(SQLiteCapabilitiesDelegateStorageTest, test_storeForExistingEntry) {
std::string storedValue;
std::unordered_map<std::string, std::string> storeMap;
storeMap.insert({TEST_ENDPOINT_ID_1, TEST_ENDPOINT_CONFIG_1});
storeMap.insert({TEST_ENDPOINT_ID_2, TEST_ENDPOINT_CONFIG_2});
ASSERT_TRUE(m_db->store(storeMap));
ASSERT_TRUE(m_db->load(TEST_ENDPOINT_ID_1, &storedValue));
std::string TEST_CONFIG = "TEST_CONFIG";
ASSERT_TRUE(m_db->store(TEST_ENDPOINT_ID_1, TEST_CONFIG));
ASSERT_TRUE(m_db->load(TEST_ENDPOINT_ID_1, &storedValue));
ASSERT_EQ(storedValue, TEST_CONFIG);
}
/**
* Test if the load method with endpointId input works.
*/
TEST_F(SQLiteCapabilitiesDelegateStorageTest, test_loadForEndpointWorks) {
std::unordered_map<std::string, std::string> storeMap;
storeMap.insert({TEST_ENDPOINT_ID_1, TEST_ENDPOINT_CONFIG_1});
storeMap.insert({TEST_ENDPOINT_ID_2, TEST_ENDPOINT_CONFIG_2});
ASSERT_TRUE(m_db->store(storeMap));
std::string endpointConfig1, endpointConfig2;
ASSERT_TRUE(m_db->load(TEST_ENDPOINT_ID_1, &endpointConfig1));
ASSERT_TRUE(m_db->load(TEST_ENDPOINT_ID_2, &endpointConfig2));
ASSERT_EQ(endpointConfig1, TEST_ENDPOINT_CONFIG_1);
ASSERT_EQ(endpointConfig2, TEST_ENDPOINT_CONFIG_2);
}
/**
* Test if the load method with endpointId input works.
*/
TEST_F(SQLiteCapabilitiesDelegateStorageTest, test_loadForNonExistingEndpoint) {
std::unordered_map<std::string, std::string> storeMap;
storeMap.insert({TEST_ENDPOINT_ID_2, TEST_ENDPOINT_CONFIG_2});
ASSERT_TRUE(m_db->store(storeMap));
std::string endpointConfig1, endpointConfig2;
ASSERT_TRUE(m_db->load(TEST_ENDPOINT_ID_1, &endpointConfig1));
}
/**
* Test if the erase method works for a given endpointId.
*/
TEST_F(SQLiteCapabilitiesDelegateStorageTest, test_eraseWorks) {
std::unordered_map<std::string, std::string> storeMap;
storeMap.insert({TEST_ENDPOINT_ID_1, TEST_ENDPOINT_CONFIG_1});
storeMap.insert({TEST_ENDPOINT_ID_2, TEST_ENDPOINT_CONFIG_2});
ASSERT_TRUE(m_db->store(storeMap));
ASSERT_TRUE(m_db->erase(TEST_ENDPOINT_ID_1));
std::unordered_map<std::string, std::string> loadMap;
ASSERT_TRUE(m_db->load(&loadMap));
ASSERT_THAT(loadMap.size(), Eq(1U));
auto it = loadMap.find(TEST_ENDPOINT_ID_1);
ASSERT_EQ(it, loadMap.end());
it = loadMap.find(TEST_ENDPOINT_ID_2);
ASSERT_NE(it, loadMap.end());
ASSERT_EQ(it->second, TEST_ENDPOINT_CONFIG_2);
}
TEST_F(SQLiteCapabilitiesDelegateStorageTest, test_clearDatabaseWorks) {
/// Store one item in the database.
std::unordered_map<std::string, std::string> testMap;
ASSERT_TRUE(m_db->store(TEST_ENDPOINT_ID_1, TEST_ENDPOINT_CONFIG_1));
ASSERT_TRUE(m_db->load(&testMap));
ASSERT_THAT(testMap.size(), Eq(1U));
/// Validate after clearing the database.
ASSERT_TRUE(m_db->clearDatabase());
testMap.clear();
ASSERT_TRUE(m_db->load(&testMap));
ASSERT_TRUE(testMap.empty());
/// Store two items in the database.
ASSERT_TRUE(m_db->store(TEST_ENDPOINT_ID_1, TEST_ENDPOINT_CONFIG_1));
ASSERT_TRUE(m_db->store(TEST_ENDPOINT_ID_2, TEST_ENDPOINT_CONFIG_2));
ASSERT_TRUE(m_db->load(&testMap));
ASSERT_THAT(testMap.size(), Eq(2U));
/// Validate after clearing the database.
ASSERT_TRUE(m_db->clearDatabase());
testMap.clear();
ASSERT_TRUE(m_db->load(&testMap));
ASSERT_TRUE(testMap.empty());
/// Test clearing empty database.
testMap.clear();
ASSERT_TRUE(m_db->load(&testMap));
ASSERT_TRUE(testMap.empty());
ASSERT_TRUE(m_db->clearDatabase());
}
} // namespace test
} // namespace storage
} // namespace capabilitiesDelegate
} // namespace alexaClientSDK