Verified Commit 2b0bd8cc authored by Tunahan Kaya's avatar Tunahan Kaya Committed by Marc Vef
Browse files

added unit tests (for db.cpp) and changed CMake to include new unit tests

parent be470cc7
Loading
Loading
Loading
Loading
+57 −3
Original line number Diff line number Diff line
@@ -29,16 +29,70 @@ target_link_libraries(catch2_main
    Catch2::Catch2
)

# needed for filesystem header
set(CMAKE_CXX_STANDARD 17)

# define executables for tests and make them depend on the convenience 
# library (and Catch2 transitively) and fmt
add_executable(tests

# test source files
set(test_src
        test_example_00.cpp
        test_example_01.cpp
        db_test.cpp
        )

# needed headers
set(test_headers
        ../../src/global/rpc/rpc_utils.cpp
        ../../src/global/path_util.cpp
        ../../src/daemon/ops/metadentry.cpp
        ../../src/daemon/classes/fs_data.cpp
        ../../src/daemon/handler/h_preload.cpp
        ../../src/global/metadata.cpp
        ../../include/global/metadata.hpp
        ../../include/daemon/classes/fs_data.hpp
        ../../include/daemon/main.hpp
        ../../include/version.hpp
        ../../include/global/configure.hpp
        ../../include/global/global_defs.hpp
        ../../include/global/rpc/rpc_types.hpp
        ../../include/global/rpc/rpc_utils.hpp
        ../../include/global/path_util.hpp
        ../../include/daemon/main.hpp
        ../../include/daemon/ops/metadentry.hpp
        ../../include/daemon/classes/fs_data.hpp
        ../../include/daemon/classes/rpc_data.hpp
        ../../include/daemon/handler/rpc_defs.hpp
        )

add_executable(tests
        ${test_src}
        ${test_headers}
        )

# probably dont need all yet
target_link_libraries(tests
    catch2_main
    fmt::fmt
    metadata
    metadata_db
    storage
    distributor
    log_util
    env_util
    spdlog
    hermes
    # margo libs
    ${ABT_LIBRARIES}
    mercury
    ${MARGO_LIBRARIES}
    # others
    Boost::boost # needed for tokenizer header
    Boost::program_options
    Boost::filesystem
    Threads::Threads
    pthread
)

# Catch2's contrib folder includes some helper functions

tests/unit/db_test.cpp

0 → 100644
+270 −0
Original line number Diff line number Diff line
//
// Created by tunahan on 10.02.20.
//

#include <catch2/catch.hpp>
#include <daemon/backend/metadata/db.hpp>
#include <daemon/main.hpp>
#include <daemon/classes/fs_data.hpp>
#include <global/path_util.hpp>
#include <random>
#include <pthread.h>
#include <thread>
#include <fmt/format.h>
#include <set>
#include <filesystem>
#include <string>


// BDD STYLE
SCENARIO("Test Db functionality"){

    GIVEN("Open a db") {
        int i = 0;
        // when open db
        std::string metadata_path = "/tmp/db_test" + std::to_string(i);
        MetadataDB db = MetadataDB(metadata_path);
        i++;
        WHEN("Try to input key") {
            std::string key = "/a";
            std::string val = "453|123|";

            db.put(key, val);
            THEN("Key and value in DB") {
                auto res = db.get(key);
                REQUIRE(res == val);
            }
        }
        system( (std::string("rm -rf ") + metadata_path).data());
        metadata_path = "/tmp/db_test" + std::to_string(i);
        db = MetadataDB(metadata_path);
        i++;
        WHEN("RocksDB 1 key two values - returns first value"){
            std::string key = "/a";
            std::string val = "453|123|";
            std::string val2 = "453|124|";

            THEN("First value returns for key"){

                db.put(key, val);
                db.put(key, val2);

                auto res = db.get(key);
                REQUIRE(res == val);
            }
        }

        system( (std::string("rm -rf ") + metadata_path).data());

    }

}

// Regular test case style
TEST_CASE("RocksDB single input"){
    std::string metadata_path = "/home/tunahan/rocksdb";
    std::string key = "/a";
    std::string val = "453|123|";
    try {
        MetadataDB db = MetadataDB(metadata_path);
        db.put(key, val);

        auto res = db.get(key);
        REQUIRE(res == val);

    } catch (const std::exception & e) {
    throw;
    }
}
TEST_CASE("RocksDB 1 key two values - returns first value"){
    std::string metadata_path = "/home/tunahan/rocksdb";

    std::string key = "/a";
    std::string val = "453|123|";
    std::string val2 = "453|124|";

    try {
        MetadataDB db = MetadataDB(metadata_path);
        db.put(key, val);
        db.put(key, val2);
        auto res = db.get(key);
        REQUIRE(res == val);

    } catch (const std::exception & e) {
        throw;
    }
}

TEST_CASE("RocksDB delete inserted key"){
    std::string metadata_path = "/home/tunahan/rocksdb";

    std::string key = "/";
    std::string val = "453|123|";

    try {
        MetadataDB db = MetadataDB(metadata_path);
        db.put(key, val);
        db.remove(key);

    } catch (const std::exception & e) {
        throw;
    }
}


TEST_CASE("RocksDB get deleted key"){
    std::string metadata_path = "/home/tunahan/rocksdb";

    std::string key = "/";
    std::string val = "453|123|";

    try {
        MetadataDB db = MetadataDB(metadata_path);
        db.put(key, val);
        db.remove(key);
        REQUIRE_THROWS(db.get(key), "Not Found: ");

    } catch (const std::exception & e) {
        throw;
    }
}


TEST_CASE("RocksDB update key"){
    std::string metadata_path = "/home/tunahan/rocksdb";

    std::string key = "/";
    std::string key2 = "/a";
    std::string val = "453|123|";
    std::string val2 = "453|151|";

    try {
        MetadataDB db = MetadataDB(metadata_path);
        db.put(key, val);
        db.update(key, key2, val2);
        auto res2 = db.get(key2);
        REQUIRE_THROWS(db.get(key), "Not Found: ");
        REQUIRE(res2 == val2);
    } catch (const std::exception & e) {
        throw;
    }
}

std::string gen_random(const int len, bool key) {
    std::string s;
    s.resize(len);
    static const char alphanum[] =
            "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
            "abcdefghijklmnopqrstuvwxyz";

    static const char numbers[] =  "123456789";
    if (key) {
        s[0] = '/';
        for (int i = 1; i < len; ++i) {
            s[i] = alphanum[std::rand() % (sizeof(alphanum) - 1)];
        }
        s[len] = '\0';
    }else{
        if(len < 6) return s;
        for (int i = 0; i < len-5; ++i) {
            s[i] = numbers[std::rand() % (sizeof(numbers) - 1)];
        }
        s[len-5] = '|';
        for (int i = len-4; i < len; ++i) {
            s[i] = numbers[std::rand() % (sizeof(numbers) - 1)];
        }

        s[len-1] = '|';
    }
    return s;
}

TEST_CASE("Bulk Insert/Get - single core"){
    std::string metadata_path = "/home/tunahan/rocksdb";

    const int number_Entries = 100;
    const int len_strings = 10;
    std::set<std::string> keyList;
    std::vector<std::string> valList;
    for(int i = 0; i < number_Entries; i++){
        std::string temp;
        temp = gen_random(len_strings, false);
        valList.push_back(temp);
        //std::cout << temp << "\n";
        temp = gen_random(len_strings, true);
        keyList.insert(temp);
        //std::cout << temp << "\n";
    }

    try {
        MetadataDB db = MetadataDB(metadata_path);
        auto keys = keyList.begin();
        for(int i = 0; i<number_Entries; i++) {
            auto key = *(keys++);
            db.put( key, valList[i]);
            auto res = db.get(key);
            REQUIRE(res == valList[i]);
        }
    } catch (const std::exception & e) {
        throw;
    }
}
#define NUM_THREADS 5




TEST_CASE("Multithreaded Bulk Insert and Get"){

    const int number_Entries = 1000;


    std::string metadata_path = "/home/tunahan/rocksdb2";
    MetadataDB db = MetadataDB(metadata_path);



    std::vector<std::thread> threads;

    for (int i = 0; i < 8; ++i) {
        threads.emplace_back([&](){
            const int len_strings = 10;
            std::set<std::string> keyList;
            std::vector<std::string> valList;
            for(int i = 0; i < number_Entries; i++){
                std::string temp;
                temp = gen_random(len_strings, false);
                valList.push_back(temp);
                temp = gen_random(len_strings, true);
                keyList.insert(temp);
            }
            auto keys = keyList.begin();
            for(int i = 0; i<number_Entries; i++) {
                auto key = *(keys++);
                db.put( key, valList[i]);
                auto res = db.get(key);
                REQUIRE(res == valList[i]);
            }
        });
    }

    for(auto& t : threads){t.join();}

}

TEST_CASE("Merge Operation"){
    std::string metadata_path = "/home/tunahan/rocksdb3";
    std::string key = "/a";
    std::string val = "4523|123|";

    try {
        MetadataDB db = MetadataDB(metadata_path);
        db.put(key, val);
        db.increase_size(key, 10, true);



    } catch (const std::exception & e) {
        throw;
    }
}