From fd143f3c6d4775b2029a7ca1fd5a1b5f5f793e4f Mon Sep 17 00:00:00 2001 From: Matthieu Dorier Date: Wed, 22 Nov 2023 11:24:20 +0000 Subject: [PATCH] Removed the admin library and made the provider manage a single resource. --- CMakeLists.txt | 2 - examples/CMakeLists.txt | 3 - examples/admin.cpp | 100 -------------- examples/bedrock-config.json | 10 +- examples/client.cpp | 7 +- examples/server.cpp | 15 +- include/alpha/Admin.hpp | 209 ---------------------------- include/alpha/Client.hpp | 3 - include/alpha/Provider.hpp | 16 +-- include/alpha/UUID.hpp | 166 ---------------------- spack.yaml | 1 - src/Admin.cpp | 88 ------------ src/AdminImpl.hpp | 42 ------ src/AsyncRequest.cpp | 2 +- src/AsyncRequestImpl.hpp | 2 +- src/Backend.cpp | 2 +- src/CMakeLists.txt | 30 +--- src/Client.cpp | 13 +- src/ClientImpl.hpp | 6 +- src/Provider.cpp | 4 - src/ProviderImpl.hpp | 259 +++++------------------------------ src/ResourceHandle.cpp | 7 +- src/ResourceHandleImpl.hpp | 15 +- src/alpha-client.pc.in | 2 +- src/alpha-config.cmake.in | 10 +- src/alpha-server.pc.in | 2 +- tests/AdminTest.cpp | 38 ----- tests/CMakeLists.txt | 8 +- tests/ClientTest.cpp | 30 ++-- tests/Ensure.hpp | 28 ++++ tests/ResourceTest.cpp | 33 ++--- 31 files changed, 145 insertions(+), 1008 deletions(-) delete mode 100644 examples/admin.cpp delete mode 100644 include/alpha/Admin.hpp delete mode 100644 include/alpha/UUID.hpp delete mode 100644 src/Admin.cpp delete mode 100644 src/AdminImpl.hpp delete mode 100644 tests/AdminTest.cpp create mode 100644 tests/Ensure.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e22625..702405d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,8 +48,6 @@ endif () find_package (PkgConfig REQUIRED) # search fo thallium find_package (thallium REQUIRED) -# search for uuid -pkg_check_modules (uuid REQUIRED IMPORTED_TARGET uuid) # search for nlohmann/json find_package (nlohmann_json REQUIRED) # search for TCLAP diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 9c36b96..3961ecf 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,8 +1,5 @@ add_executable (example-server ${CMAKE_CURRENT_SOURCE_DIR}/server.cpp) target_link_libraries (example-server fmt::fmt spdlog::spdlog alpha-server) -add_executable (example-admin ${CMAKE_CURRENT_SOURCE_DIR}/admin.cpp) -target_link_libraries (example-admin fmt::fmt spdlog::spdlog alpha-admin) - add_executable (example-client ${CMAKE_CURRENT_SOURCE_DIR}/client.cpp) target_link_libraries (example-client fmt::fmt spdlog::spdlog alpha-client) diff --git a/examples/admin.cpp b/examples/admin.cpp deleted file mode 100644 index ff17b29..0000000 --- a/examples/admin.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * (C) 2020 The University of Chicago - * - * See COPYRIGHT in top-level directory. - */ -#include -#include -#include -#include -#include - -namespace tl = thallium; - -static std::string g_address; -static std::string g_protocol; -static std::string g_resource; -static std::string g_type; -static std::string g_config; -static std::string g_token; -static std::string g_operation; -static unsigned g_provider_id; -static std::string g_log_level = "info"; - -static void parse_command_line(int argc, char** argv); - -int main(int argc, char** argv) { - parse_command_line(argc, argv); - spdlog::set_level(spdlog::level::from_str(g_log_level)); - - // Initialize the thallium server - tl::engine engine(g_protocol, THALLIUM_CLIENT_MODE); - - try { - - // Initialize an Admin - alpha::Admin admin(engine); - - if(g_operation == "create") { - auto id = admin.createResource(g_address, g_provider_id, - g_type, g_config, g_token); - spdlog::info("Created resource {}", id.to_string()); - } else if(g_operation == "open") { - auto id = admin.openResource(g_address, g_provider_id, - g_type, g_config, g_token); - spdlog::info("Opened resource {}", id.to_string()); - } else if(g_operation == "close") { - admin.closeResource(g_address, g_provider_id, - alpha::UUID::from_string(g_resource.c_str()), g_token); - spdlog::info("Closed resource {}", g_resource); - } else if(g_operation == "destroy") { - admin.destroyResource(g_address, g_provider_id, - alpha::UUID::from_string(g_resource.c_str()), g_token); - spdlog::info("Destroyed resource {}", g_resource); - } - - // Any of the above functions may throw a alpha::Exception - } catch(const alpha::Exception& ex) { - std::cerr << ex.what() << std::endl; - exit(-1); - } - - return 0; -} - -void parse_command_line(int argc, char** argv) { - try { - TCLAP::CmdLine cmd("Alpha admin", ' ', "0.1"); - TCLAP::ValueArg addressArg("a","address","Address or server", true,"","string"); - TCLAP::ValueArg providerArg("p", "provider", "Provider id to contact (default 0)", false, 0, "int"); - TCLAP::ValueArg tokenArg("s","token","Security token", false,"","string"); - TCLAP::ValueArg typeArg("t","type","Resource type", false,"dummy","string"); - TCLAP::ValueArg resourceArg("r","resource","Resource id", false, alpha::UUID().to_string(),"string"); - TCLAP::ValueArg configArg("c","config","Resource configuration", false,"","string"); - TCLAP::ValueArg logLevel("v","verbose", "Log level (trace, debug, info, warning, error, critical, off)", false, "info", "string"); - std::vector options = { "create", "open", "close", "destroy" }; - TCLAP::ValuesConstraint allowedOptions(options); - TCLAP::ValueArg operationArg("x","exec","Operation to execute",true,"create",&allowedOptions); - cmd.add(addressArg); - cmd.add(providerArg); - cmd.add(typeArg); - cmd.add(tokenArg); - cmd.add(configArg); - cmd.add(resourceArg); - cmd.add(logLevel); - cmd.add(operationArg); - cmd.parse(argc, argv); - g_address = addressArg.getValue(); - g_provider_id = providerArg.getValue(); - g_token = tokenArg.getValue(); - g_config = configArg.getValue(); - g_type = typeArg.getValue(); - g_resource = resourceArg.getValue(); - g_operation = operationArg.getValue(); - g_log_level = logLevel.getValue(); - g_protocol = g_address.substr(0, g_address.find(":")); - } catch(TCLAP::ArgException &e) { - std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; - exit(-1); - } -} diff --git a/examples/bedrock-config.json b/examples/bedrock-config.json index d846c96..dbc13de 100644 --- a/examples/bedrock-config.json +++ b/examples/bedrock-config.json @@ -8,12 +8,10 @@ "name": "my-alpha-provider", "provider_id": 42, "config": { - "resources": [ - { - "type": "dummy", - "config": {} - } - ] + "resource": { + "type": "dummy", + "config": {} + } } } ] diff --git a/examples/client.cpp b/examples/client.cpp index 811790f..9ce1884 100644 --- a/examples/client.cpp +++ b/examples/client.cpp @@ -12,7 +12,6 @@ namespace tl = thallium; static std::string g_address; static std::string g_protocol; -static std::string g_resource; static unsigned g_provider_id; static std::string g_log_level = "info"; @@ -32,8 +31,7 @@ int main(int argc, char** argv) { // Open the Resource "myresource" from provider 0 alpha::ResourceHandle resource = - client.makeResourceHandle(g_address, g_provider_id, - alpha::UUID::from_string(g_resource.c_str())); + client.makeResourceHandle(g_address, g_provider_id); int32_t result; resource.computeSum(32, 54, &result); @@ -51,16 +49,13 @@ void parse_command_line(int argc, char** argv) { TCLAP::CmdLine cmd("Alpha client", ' ', "0.1"); TCLAP::ValueArg addressArg("a","address","Address or server", true,"","string"); TCLAP::ValueArg providerArg("p", "provider", "Provider id to contact (default 0)", false, 0, "int"); - TCLAP::ValueArg resourceArg("r","resource","Resource id", true, alpha::UUID().to_string(),"string"); TCLAP::ValueArg logLevel("v","verbose", "Log level (trace, debug, info, warning, error, critical, off)", false, "info", "string"); cmd.add(addressArg); cmd.add(providerArg); - cmd.add(resourceArg); cmd.add(logLevel); cmd.parse(argc, argv); g_address = addressArg.getValue(); g_provider_id = providerArg.getValue(); - g_resource = resourceArg.getValue(); g_log_level = logLevel.getValue(); g_protocol = g_address.substr(0, g_address.find(":")); } catch(TCLAP::ArgException &e) { diff --git a/examples/server.cpp b/examples/server.cpp index f9b562a..192b755 100644 --- a/examples/server.cpp +++ b/examples/server.cpp @@ -1,6 +1,6 @@ /* * (C) 2020 The University of Chicago - * + * * See COPYRIGHT in top-level directory. */ #include @@ -10,7 +10,6 @@ #include namespace tl = thallium; -namespace snt = alpha; static std::string g_address = "na+sm"; static unsigned g_num_providers = 1; @@ -25,9 +24,17 @@ int main(int argc, char** argv) { spdlog::set_level(spdlog::level::from_str(g_log_level)); tl::engine engine(g_address, THALLIUM_SERVER_MODE, g_use_progress_thread, g_num_threads); engine.enable_remote_shutdown(); - std::vector providers; + const auto provider_config = R"( + { + "resource": { + "type": "dummy", + "config": {} + } + } + )"; + std::vector providers; for(unsigned i=0 ; i < g_num_providers; i++) { - providers.emplace_back(engine, i); + providers.emplace_back(engine, i, provider_config); } spdlog::info("Server running at address {}", (std::string)engine.self()); engine.wait_for_finalize(); diff --git a/include/alpha/Admin.hpp b/include/alpha/Admin.hpp deleted file mode 100644 index b8fc307..0000000 --- a/include/alpha/Admin.hpp +++ /dev/null @@ -1,209 +0,0 @@ -/* - * (C) 2020 The University of Chicago - * - * See COPYRIGHT in top-level directory. - */ -#ifndef __ALPHA_ADMIN_HPP -#define __ALPHA_ADMIN_HPP - -#include -#include -#include -#include -#include -#include - -namespace alpha { - -namespace tl = thallium; - -class AdminImpl; - -/** - * @brief Admin interface to a ALPHA service. Enables creating - * and destroying resources, and attaching and detaching them - * from a provider. If ALPHA providers have set up a security - * token, operations from the Admin interface will need this - * security token. - */ -class Admin { - - public: - - using json = nlohmann::json; - - /** - * @brief Default constructor. - */ - Admin(); - - /** - * @brief Constructor using a margo instance id. - * - * @param mid Margo instance id. - */ - Admin(margo_instance_id mid); - - /** - * @brief Constructor. - * - * @param engine Thallium engine. - */ - Admin(const tl::engine& engine); - - /** - * @brief Copy constructor. - */ - Admin(const Admin&); - - /** - * @brief Move constructor. - */ - Admin(Admin&&); - - /** - * @brief Copy-assignment operator. - */ - Admin& operator=(const Admin&); - - /** - * @brief Move-assignment operator. - */ - Admin& operator=(Admin&&); - - /** - * @brief Destructor. - */ - ~Admin(); - - /** - * @brief Check if the Admin instance is valid. - */ - operator bool() const; - - /** - * @brief Creates a resource on the target provider. - * The config string must be a JSON object acceptable - * by the desired backend's creation function. - * - * @param address Address of the target provider. - * @param provider_id Provider id. - * @param type Type of the resource to create. - * @param config JSON configuration for the resource. - */ - UUID createResource(const std::string& address, - uint16_t provider_id, - const std::string& type, - const std::string& config, - const std::string& token="") const; - - /** - * @brief Creates a resource on the target provider. - * The config string must be a JSON object acceptable - * by the desired backend's creation function. - * - * @param address Address of the target provider. - * @param provider_id Provider id. - * @param type Type of the resource to create. - * @param config JSON configuration for the resource. - */ - UUID createResource(const std::string& address, - uint16_t provider_id, - const std::string& type, - const char* config, - const std::string& token="") const { - return createResource(address, provider_id, type, std::string(config), token); - } - - /** - * @brief Creates a resource on the target provider. - * The config object must be a JSON object acceptable - * by the desired backend's creation function. - * - * @param address Address of the target provider. - * @param provider_id Provider id. - * @param type Type of the resource to create. - * @param config JSON configuration for the resource. - */ - UUID createResource(const std::string& address, - uint16_t provider_id, - const std::string& type, - const json& config, - const std::string& token="") const { - return createResource(address, provider_id, type, config.dump(), token); - } - - /** - * @brief Opens an existing resource in the target provider. - * The config string must be a JSON object acceptable - * by the desired backend's open function. - * - * @param address Address of the target provider. - * @param provider_id Provider id. - * @param type Type of the resource to create. - * @param config JSON configuration for the resource. - */ - UUID openResource(const std::string& address, - uint16_t provider_id, - const std::string& type, - const std::string& config, - const std::string& token="") const; - - /** - * @brief Opens an existing resource to the target provider. - * The config object must be a JSON object acceptable - * by the desired backend's open function. - * - * @param address Address of the target provider. - * @param provider_id Provider id. - * @param type Type of the resource to create. - * @param config JSON configuration for the resource. - */ - UUID openResource(const std::string& address, - uint16_t provider_id, - const std::string& type, - const json& config, - const std::string& token="") const { - return openResource(address, provider_id, type, config.dump(), token); - } - - /** - * @brief Closes an open resource in the target provider. - * - * @param address Address of the target provider. - * @param provider_id Provider id. - * @param resource_id UUID of the resource to close. - */ - void closeResource(const std::string& address, - uint16_t provider_id, - const UUID& resource_id, - const std::string& token="") const; - - /** - * @brief Destroys an open resource in the target provider. - * - * @param address Address of the target provider. - * @param provider_id Provider id. - * @param resource_id UUID of the resource to destroy. - */ - void destroyResource(const std::string& address, - uint16_t provider_id, - const UUID& resource_id, - const std::string& token="") const; - - /** - * @brief Shuts down the target server. The Thallium engine - * used by the server must have remote shutdown enabled. - * - * @param address Address of the server to shut down. - */ - void shutdownServer(const std::string& address) const; - - private: - - std::shared_ptr self; -}; - -} - -#endif diff --git a/include/alpha/Client.hpp b/include/alpha/Client.hpp index d1feac9..a8c882e 100644 --- a/include/alpha/Client.hpp +++ b/include/alpha/Client.hpp @@ -7,7 +7,6 @@ #define __ALPHA_CLIENT_HPP #include -#include #include #include @@ -82,14 +81,12 @@ class Client { * * @param address Address of the provider holding the database. * @param provider_id Provider id. - * @param resource_id Resource UUID. * @param check Checks if the Resource exists by issuing an RPC. * * @return a ResourceHandle instance. */ ResourceHandle makeResourceHandle(const std::string& address, uint16_t provider_id, - const UUID& resource_id, bool check = true) const; /** diff --git a/include/alpha/Provider.hpp b/include/alpha/Provider.hpp index adc1d9d..6525f3f 100644 --- a/include/alpha/Provider.hpp +++ b/include/alpha/Provider.hpp @@ -32,8 +32,8 @@ class Provider { * @param pool Argobots pool to use to handle RPCs. */ Provider(const tl::engine& engine, - uint16_t provider_id = 0, - const std::string& config = "", + uint16_t provider_id, + const std::string& config, const tl::pool& pool = tl::pool()); /** @@ -45,8 +45,8 @@ class Provider { * @param pool Argobots pool to use to handle RPCs. */ Provider(margo_instance_id mid, - uint16_t provider_id = 0, - const std::string& config = "", + uint16_t provider_id, + const std::string& config, const tl::pool& pool = tl::pool()); /** @@ -74,14 +74,6 @@ class Provider { */ ~Provider(); - /** - * @brief Sets a security string that should be provided - * by Admin RPCs to accept them. - * - * @param token Security token to set. - */ - void setSecurityToken(const std::string& token); - /** * @brief Return a JSON-formatted configuration of the provider. * diff --git a/include/alpha/UUID.hpp b/include/alpha/UUID.hpp deleted file mode 100644 index 61218e7..0000000 --- a/include/alpha/UUID.hpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * (C) 2020 The University of Chicago - * - * See COPYRIGHT in top-level directory. - */ -#ifndef __ALPHA_UUID_UTIL_HPP -#define __ALPHA_UUID_UTIL_HPP - -#include -#include -#include - -namespace alpha { - -/** - * @brief UUID class (Universally Unique IDentifier). - */ -struct UUID { - - uuid_t m_data; - - /** - * @brief Constructor, produces a zero-ed UUID. - */ - UUID() { - uuid_clear(m_data); - } - - /** - * @brief Copy constructor. - */ - UUID(const UUID& other) = default; - - /** - * @brief Move constructor. - */ - UUID(UUID&& other) = default; - - /** - * @brief Copy-assignment operator. - */ - UUID& operator=(const UUID& other) = default; - - /** - * @brief Move-assignment operator. - */ - UUID& operator=(UUID&& other) = default; - - /** - * @brief Converts the UUID into a string. - * - * @return a readable string representation of the UUID. - */ - std::string to_string() const { - std::string result(36, '\0'); - uuid_unparse(this->m_data, const_cast(result.data())); - return result; - } - - /** - * @brief Makes a UUID from a C-style string. - * - * @param str 33-byte null-terminate string - * - * @return the corresponding UUID. - */ - static UUID from_string(const char* str) { - UUID uuid; - int ret = uuid_parse(str, uuid.m_data); - if(ret == -1) { - throw std::invalid_argument("String argument does not represent a valid UUID"); - } - return uuid; - } - - /** - * @brief Serialization of a UUID into an archive. - * - * @tparam Archive - * @param a - * @param version - */ - template - void save(Archive& a) const { - a.write(m_data, sizeof(uuid_t)); - } - - /** - * @brief Deserialization of a UUID from an archive. - * - * @tparam Archive - * @param a - * @param version - */ - template - void load(Archive& a) { - a.read(m_data, sizeof(uuid_t)); - } - - /** - * @brief Converts the UUID into a string and pass it - * to the provided stream. - */ - template - friend T& operator<<(T& stream, const UUID& id) { - stream << id.to_string(); - return stream; - } - - /** - * @brief Generates a random UUID. - * - * @return a random UUID. - */ - static UUID generate() { - UUID uuid; - uuid_generate(uuid.m_data); - return uuid; - } - - /** - * @brief randomize the current UUID. - */ - void randomize() { - uuid_generate(m_data); - } - - /** - * @brief Compare the UUID with another UUID. - */ - bool operator==(const UUID& other) const { - return memcmp(m_data, other.m_data, 16) == 0; - } - - /** - * @brief Computes a hash of the UUID. - * - * @return a uint64_t hash value. - */ - uint64_t hash() const { - const uint64_t* a = reinterpret_cast(m_data); - const uint64_t* b = reinterpret_cast(m_data+8); - return *a ^ *b; - } -}; - -} - -namespace std { - - - /** - * @brief Specialization of std::hash for alpha::UUID - */ - template<> - struct hash - { - size_t operator()(const alpha::UUID& id) const - { - return id.hash(); - } - }; - -} - -#endif diff --git a/spack.yaml b/spack.yaml index 9172f03..20ab61b 100644 --- a/spack.yaml +++ b/spack.yaml @@ -2,7 +2,6 @@ spack: specs: - cmake - pkgconfig - - uuid - mochi-thallium ^mercury~boostsys~checksum ^libfabric fabrics=tcp,rxm - nlohmann-json - spdlog diff --git a/src/Admin.cpp b/src/Admin.cpp deleted file mode 100644 index d8f3191..0000000 --- a/src/Admin.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * (C) 2020 The University of Chicago - * - * See COPYRIGHT in top-level directory. - */ -#include "alpha/Admin.hpp" -#include "alpha/Exception.hpp" -#include "alpha/Result.hpp" - -#include "AdminImpl.hpp" - -#include - -namespace tl = thallium; - -namespace alpha { - -Admin::Admin() = default; - -Admin::Admin(const tl::engine& engine) -: self(std::make_shared(engine)) {} - -Admin::Admin(margo_instance_id mid) -: self(std::make_shared(mid)) {} - -Admin::Admin(Admin&& other) = default; - -Admin& Admin::operator=(Admin&& other) = default; - -Admin::Admin(const Admin& other) = default; - -Admin& Admin::operator=(const Admin& other) = default; - - -Admin::~Admin() = default; - -Admin::operator bool() const { - return static_cast(self); -} - -UUID Admin::createResource(const std::string& address, - uint16_t provider_id, - const std::string& resource_type, - const std::string& resource_config, - const std::string& token) const { - auto endpoint = self->m_engine.lookup(address); - auto ph = tl::provider_handle(endpoint, provider_id); - Result result = self->m_create_resource.on(ph)(token, resource_type, resource_config); - return std::move(result).valueOrThrow(); -} - -UUID Admin::openResource(const std::string& address, - uint16_t provider_id, - const std::string& resource_type, - const std::string& resource_config, - const std::string& token) const { - auto endpoint = self->m_engine.lookup(address); - auto ph = tl::provider_handle(endpoint, provider_id); - Result result = self->m_open_resource.on(ph)(token, resource_type, resource_config); - return std::move(result).valueOrThrow(); -} - -void Admin::closeResource(const std::string& address, - uint16_t provider_id, - const UUID& resource_id, - const std::string& token) const { - auto endpoint = self->m_engine.lookup(address); - auto ph = tl::provider_handle(endpoint, provider_id); - Result result = self->m_close_resource.on(ph)(token, resource_id); - result.check(); -} - -void Admin::destroyResource(const std::string& address, - uint16_t provider_id, - const UUID& resource_id, - const std::string& token) const { - auto endpoint = self->m_engine.lookup(address); - auto ph = tl::provider_handle(endpoint, provider_id); - Result result = self->m_destroy_resource.on(ph)(token, resource_id); - result.check(); -} - -void Admin::shutdownServer(const std::string& address) const { - auto ep = self->m_engine.lookup(address); - self->m_engine.shutdown_remote_engine(ep); -} - -} diff --git a/src/AdminImpl.hpp b/src/AdminImpl.hpp deleted file mode 100644 index ce0786f..0000000 --- a/src/AdminImpl.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * (C) 2020 The University of Chicago - * - * See COPYRIGHT in top-level directory. - */ -#ifndef __ALPHA_ADMIN_IMPL_H -#define __ALPHA_ADMIN_IMPL_H - -#include - -namespace alpha { - -namespace tl = thallium; - -class AdminImpl { - - public: - - tl::engine m_engine; - tl::remote_procedure m_create_resource; - tl::remote_procedure m_open_resource; - tl::remote_procedure m_close_resource; - tl::remote_procedure m_destroy_resource; - - AdminImpl(const tl::engine& engine) - : m_engine(engine) - , m_create_resource(m_engine.define("alpha_create_resource")) - , m_open_resource(m_engine.define("alpha_open_resource")) - , m_close_resource(m_engine.define("alpha_close_resource")) - , m_destroy_resource(m_engine.define("alpha_destroy_resource")) - {} - - AdminImpl(margo_instance_id mid) - : AdminImpl(tl::engine(mid)) { - } - - ~AdminImpl() {} -}; - -} - -#endif diff --git a/src/AsyncRequest.cpp b/src/AsyncRequest.cpp index ed80292..de6a0d0 100644 --- a/src/AsyncRequest.cpp +++ b/src/AsyncRequest.cpp @@ -1,6 +1,6 @@ /* * (C) 2020 The University of Chicago - * + * * See COPYRIGHT in top-level directory. */ #include "alpha/Exception.hpp" diff --git a/src/AsyncRequestImpl.hpp b/src/AsyncRequestImpl.hpp index 53b491c..c5df97e 100644 --- a/src/AsyncRequestImpl.hpp +++ b/src/AsyncRequestImpl.hpp @@ -1,6 +1,6 @@ /* * (C) 2020 The University of Chicago - * + * * See COPYRIGHT in top-level directory. */ #ifndef __ALPHA_ASYNC_REQUEST_IMPL_H diff --git a/src/Backend.cpp b/src/Backend.cpp index d5536d5..acdab44 100644 --- a/src/Backend.cpp +++ b/src/Backend.cpp @@ -1,6 +1,6 @@ /* * (C) 2020 The University of Chicago - * + * * See COPYRIGHT in top-level directory. */ #include "alpha/Backend.hpp" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 11e440a..31f39fd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,9 +8,6 @@ set (client-src-files ResourceHandle.cpp AsyncRequest.cpp) -set (admin-src-files - Admin.cpp) - set (dummy-src-files dummy/DummyBackend.cpp) @@ -28,8 +25,9 @@ set (alpha-vers "${ALPHA_VERSION_MAJOR}.${ALPHA_VERSION_MINOR}") # server library add_library (alpha-server ${server-src-files} ${dummy-src-files}) +add_library (alpha::server ALIAS alpha-server) target_link_libraries (alpha-server - PUBLIC thallium PkgConfig::uuid nlohmann_json::nlohmann_json + PUBLIC thallium nlohmann_json::nlohmann_json PRIVATE spdlog::spdlog fmt::fmt coverage_config) target_include_directories (alpha-server PUBLIC $) target_include_directories (alpha-server BEFORE PUBLIC @@ -42,8 +40,9 @@ set_target_properties (alpha-server # client library add_library (alpha-client ${client-src-files}) +add_library (alpha::client ALIAS alpha-client) target_link_libraries (alpha-client - PUBLIC thallium PkgConfig::uuid nlohmann_json::nlohmann_json + PUBLIC thallium nlohmann_json::nlohmann_json PRIVATE spdlog::spdlog fmt::fmt coverage_config) target_include_directories (alpha-client PUBLIC $) target_include_directories (alpha-client BEFORE PUBLIC @@ -54,23 +53,11 @@ set_target_properties (alpha-client PROPERTIES VERSION ${ALPHA_VERSION} SOVERSION ${ALPHA_VERSION_MAJOR}) -# admin library -add_library (alpha-admin ${admin-src-files}) -target_link_libraries (alpha-admin PUBLIC thallium PkgConfig::uuid nlohmann_json::nlohmann_json - PRIVATE spdlog::spdlog fmt::fmt coverage_config) -target_include_directories (alpha-admin PUBLIC $) -target_include_directories (alpha-admin BEFORE PUBLIC - $) -target_include_directories (alpha-admin BEFORE PUBLIC - $) -set_target_properties (alpha-admin - PROPERTIES VERSION ${ALPHA_VERSION} - SOVERSION ${ALPHA_VERSION_MAJOR}) - if (${ENABLE_BEDROCK}) # bedrock module library add_library (alpha-bedrock-module ${module-src-files}) -target_link_libraries (alpha-bedrock-module alpha-server alpha-admin alpha-client bedrock-server coverage_config) +add_library (alpha::bedrock ALIAS alpha-bedrock-module) +target_link_libraries (alpha-bedrock-module alpha-server alpha-client bedrock-server coverage_config) target_include_directories (alpha-bedrock-module PUBLIC $) target_include_directories (alpha-bedrock-module BEFORE PUBLIC $) @@ -99,16 +86,14 @@ configure_package_config_file (alpha-config.cmake.in set (DEST_DIR "${CMAKE_INSTALL_PREFIX}") set (SERVER_PRIVATE_LIBS "-lalpha-server") set (CLIENT_PRIVATE_LIBS "-lalpha-client") -set (ADMIN_PRIVATE_LIBS "-lalpha-admin") configure_file ("alpha-server.pc.in" "alpha-server.pc" @ONLY) configure_file ("alpha-client.pc.in" "alpha-client.pc" @ONLY) -configure_file ("alpha-admin.pc.in" "alpha-admin.pc" @ONLY) # configure config.h configure_file ("config.h.in" "config.h" @ONLY) # "make install" rules -install (TARGETS alpha-admin alpha-server alpha-client +install (TARGETS alpha-server alpha-client EXPORT alpha-targets ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) @@ -131,5 +116,4 @@ install (DIRECTORY ../include/alpha FILES_MATCHING PATTERN "*.h") install (FILES "${CMAKE_CURRENT_BINARY_DIR}/alpha-server.pc" "${CMAKE_CURRENT_BINARY_DIR}/alpha-client.pc" - "${CMAKE_CURRENT_BINARY_DIR}/alpha-admin.pc" DESTINATION "lib/pkgconfig/") diff --git a/src/Client.cpp b/src/Client.cpp index e5fdc36..73e76ad 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -50,18 +50,17 @@ Client::operator bool() const { ResourceHandle Client::makeResourceHandle( const std::string& address, uint16_t provider_id, - const UUID& resource_id, bool check) const { auto endpoint = self->m_engine.lookup(address); auto ph = tl::provider_handle(endpoint, provider_id); - Result result; if(check) { - result = self->m_check_resource.on(ph)(resource_id); + try { + self->m_check.on(ph)(); + } catch(const std::exception& ex) { + throw Exception{ex.what()}; + } } - return result.andThen([&]() { - auto resource_impl = std::make_shared(self, std::move(ph), resource_id); - return ResourceHandle(resource_impl); - }); + return std::make_shared(self, std::move(ph)); } std::string Client::getConfig() const { diff --git a/src/ClientImpl.hpp b/src/ClientImpl.hpp index 8ed60da..fe93554 100644 --- a/src/ClientImpl.hpp +++ b/src/ClientImpl.hpp @@ -1,6 +1,6 @@ /* * (C) 2020 The University of Chicago - * + * * See COPYRIGHT in top-level directory. */ #ifndef __ALPHA_CLIENT_IMPL_H @@ -20,12 +20,12 @@ class ClientImpl { public: tl::engine m_engine; - tl::remote_procedure m_check_resource; + tl::remote_procedure m_check; tl::remote_procedure m_compute_sum; ClientImpl(const tl::engine& engine) : m_engine(engine) - , m_check_resource(m_engine.define("alpha_check_resource")) + , m_check(m_engine.define("alpha_check")) , m_compute_sum(m_engine.define("alpha_compute_sum")) {} diff --git a/src/Provider.cpp b/src/Provider.cpp index 6b59e86..d98ec28 100644 --- a/src/Provider.cpp +++ b/src/Provider.cpp @@ -43,8 +43,4 @@ Provider::operator bool() const { return static_cast(self); } -void Provider::setSecurityToken(const std::string& token) { - if(self) self->m_token = token; -} - } diff --git a/src/ProviderImpl.hpp b/src/ProviderImpl.hpp index a883d03..ea14af1 100644 --- a/src/ProviderImpl.hpp +++ b/src/ProviderImpl.hpp @@ -7,7 +7,6 @@ #define __ALPHA_PROVIDER_IMPL_H #include "alpha/Backend.hpp" -#include "alpha/UUID.hpp" #include #include @@ -18,20 +17,6 @@ #include -#define FIND_RESOURCE(__var__) \ - std::shared_ptr __var__;\ - do {\ - std::lock_guard lock(m_backends_mtx);\ - auto it = m_backends.find(resource_id);\ - if(it == m_backends.end()) {\ - result.success() = false;\ - result.error() = "Resource with UUID "s + resource_id.to_string() + " not found";\ - error(result.error());\ - return;\ - }\ - __var__ = it->second;\ - } while(0) - namespace alpha { using namespace std::string_literals; @@ -99,29 +84,18 @@ class ProviderImpl : public tl::provider { public: tl::engine m_engine; - std::string m_token; tl::pool m_pool; - // Admin RPC - AutoDeregistering m_create_resource; - AutoDeregistering m_open_resource; - AutoDeregistering m_close_resource; - AutoDeregistering m_destroy_resource; // Client RPC - AutoDeregistering m_check_resource; + AutoDeregistering m_check; AutoDeregistering m_compute_sum; // Backends - std::unordered_map> m_backends; - tl::mutex m_backends_mtx; + std::shared_ptr m_backend; ProviderImpl(const tl::engine& engine, uint16_t provider_id, const std::string& config, const tl::pool& pool) : tl::provider(engine, provider_id) , m_engine(engine) , m_pool(pool) - , m_create_resource(define("alpha_create_resource", &ProviderImpl::createResourceRPC, pool)) - , m_open_resource(define("alpha_open_resource", &ProviderImpl::openResourceRPC, pool)) - , m_close_resource(define("alpha_close_resource", &ProviderImpl::closeResourceRPC, pool)) - , m_destroy_resource(define("alpha_destroy_resource", &ProviderImpl::destroyResourceRPC, pool)) - , m_check_resource(define("alpha_check_resource", &ProviderImpl::checkResourceRPC, pool)) + , m_check(define("alpha_check", &ProviderImpl::checkRPC, pool)) , m_compute_sum(define("alpha_compute_sum", &ProviderImpl::computeSumRPC, pool)) { trace("Registered provider with id {}", get_provider_id()); @@ -133,241 +107,70 @@ class ProviderImpl : public tl::provider { return; } if(!json_config.is_object()) return; - if(!json_config.contains("resources")) return; - auto& resources = json_config["resources"]; - if(!resources.is_array()) return; - for(auto& resource : resources) { - if(!(resource.contains("type") && resource["type"].is_string())) - continue; - const std::string& resource_type = resource["type"].get_ref(); + if(!json_config.contains("resource")) return; + auto& resource = json_config["resource"]; + if(!resource.is_object()) return; + if(resource.contains("type") && resource["type"].is_string()) { + auto& resource_type = resource["type"].get_ref(); auto resource_config = resource.contains("config") ? resource["config"] : json::object(); - createResource(resource_type, resource_config.dump()); + auto result = createResource(resource_type, resource_config); + result.check(); } } ~ProviderImpl() { trace("Deregistering provider"); + m_backend->destroy(); } std::string getConfig() const { auto config = json::object(); - config["resources"] = json::array(); - for(auto& pair : m_backends) { - auto resource_config = json::object(); - resource_config["__id__"] = pair.first.to_string(); - resource_config["type"] = pair.second->name(); - resource_config["config"] = json::parse(pair.second->getConfig()); - config["resources"].push_back(resource_config); - } + config["resource"] = json::object(); + auto resource_config = json::object(); + resource_config["type"] = m_backend->name(); + resource_config["config"] = json::parse(m_backend->getConfig()); + config["resource"] = std::move(resource_config); return config.dump(); } - Result createResource(const std::string& resource_type, - const std::string& resource_config) { - - auto resource_id = UUID::generate(); - Result result; + Result createResource(const std::string& resource_type, + const json& resource_config) { - json json_config; - try { - json_config = json::parse(resource_config); - } catch(json::parse_error& e) { - result.error() = e.what(); - result.success() = false; - error("Could not parse resource configuration for resource {}", - resource_id.to_string()); - return result; - } + Result result; - std::unique_ptr backend; try { - backend = ResourceFactory::createResource(resource_type, get_engine(), json_config); + m_backend = ResourceFactory::createResource(resource_type, get_engine(), resource_config); } catch(const std::exception& ex) { result.success() = false; result.error() = ex.what(); - error("Error when creating resource {} of type {}: {}", - resource_id.to_string(), resource_type, result.error()); + error("Error when creating resource of type {}: {}", + resource_type, result.error()); return result; } - if(not backend) { + if(not m_backend) { result.success() = false; result.error() = "Unknown resource type "s + resource_type; - error("Unknown resource type {} for resource {}", - resource_type, resource_id.to_string()); + error("Unknown resource type {}", resource_type); return result; - } else { - std::lock_guard lock(m_backends_mtx); - m_backends[resource_id] = std::move(backend); - result.value() = resource_id; } - trace("Successfully created resource {} of type {}", - resource_id.to_string(), resource_type); + trace("Successfully created resource of type {}", resource_type); return result; } - void createResourceRPC(const tl::request& req, - const std::string& token, - const std::string& resource_type, - const std::string& resource_config) { - - trace("Received createResource request", id()); - trace(" => type = {}", resource_type); - trace(" => config = {}", resource_config); - - Result result; - AutoResponse response{req, result}; - - if(m_token.size() > 0 && m_token != token) { - result.success() = false; - result.error() = "Invalid security token"; - error("Invalid security token {}", token); - return; - } - - result = createResource(resource_type, resource_config); - } - - void openResourceRPC(const tl::request& req, - const std::string& token, - const std::string& resource_type, - const std::string& resource_config) { - - trace("Received openResource request"); - trace(" => type = {}", resource_type); - trace(" => config = {}", resource_config); - - auto resource_id = UUID::generate(); - Result result; - AutoResponse response{req, result}; - - if(m_token.size() > 0 && m_token != token) { - result.success() = false; - result.error() = "Invalid security token"; - error("Invalid security token {}", token); - return; - } - - json json_config; - try { - json_config = json::parse(resource_config); - } catch(json::parse_error& e) { - result.error() = e.what(); - result.success() = false; - error("Could not parse resource configuration for resource {}", - resource_id.to_string()); - return; - } - - std::unique_ptr backend; - try { - backend = ResourceFactory::openResource(resource_type, get_engine(), json_config); - } catch(const std::exception& ex) { - result.success() = false; - result.error() = ex.what(); - error("Error when opening resource {} of type {}: {}", - resource_id.to_string(), resource_type, result.error()); - return; - } - - if(not backend) { - result.success() = false; - result.error() = "Unknown resource type "s + resource_type; - error("Unknown resource type {} for resource {}", - resource_type, resource_id.to_string()); - return; - } else { - std::lock_guard lock(m_backends_mtx); - m_backends[resource_id] = std::move(backend); - result.value() = resource_id; - } - - trace("Successfully created resource {} of type {}", - resource_id.to_string(), resource_type); - } - - void closeResourceRPC(const tl::request& req, - const std::string& token, - const UUID& resource_id) { - trace("Received closeResource request for resource {}", - resource_id.to_string()); - - Result result; - AutoResponse response{req, result}; - - if(m_token.size() > 0 && m_token != token) { - result.success() = false; - result.error() = "Invalid security token"; - error("Invalid security token {}", token); - return; - } - - { - std::lock_guard lock(m_backends_mtx); - - if(m_backends.count(resource_id) == 0) { - result.success() = false; - result.error() = "Resource "s + resource_id.to_string() + " not found"; - error(result.error()); - return; - } - - m_backends.erase(resource_id); - } - - trace("Resource {} successfully closed", resource_id.to_string()); - } - - void destroyResourceRPC(const tl::request& req, - const std::string& token, - const UUID& resource_id) { - Result result; - AutoResponse response{req, result}; - trace("Received destroyResource request for resource {}", resource_id.to_string()); - - if(m_token.size() > 0 && m_token != token) { - result.success() = false; - result.error() = "Invalid security token"; - error("Invalid security token {}", token); - return; - } - - { - std::lock_guard lock(m_backends_mtx); - - if(m_backends.count(resource_id) == 0) { - result.success() = false; - result.error() = "Resource "s + resource_id.to_string() + " not found"; - error(result.error()); - return; - } - - result = m_backends[resource_id]->destroy(); - m_backends.erase(resource_id); - } - - trace("Resource {} successfully destroyed", resource_id.to_string()); - } - - void checkResourceRPC(const tl::request& req, - const UUID& resource_id) { - trace("Received checkResource request for resource {}", resource_id.to_string()); - Result result; - AutoResponse response{req, result}; - FIND_RESOURCE(resource); - trace("Successfully check for presence of resource {}", resource_id.to_string()); + void checkRPC(const tl::request& req) { + trace("Received check request"); + req.respond(); } void computeSumRPC(const tl::request& req, - const UUID& resource_id, int32_t x, int32_t y) { - trace("Received computeSum request for resource {}", resource_id.to_string()); + trace("Received computeSum request"); Result result; AutoResponse response{req, result}; - FIND_RESOURCE(resource); - result = resource->computeSum(x, y); - trace("Successfully executed computeSum on resource {}", resource_id.to_string()); + result = m_backend->computeSum(x, y); + trace("Successfully executed computeSum"); } }; diff --git a/src/ResourceHandle.cpp b/src/ResourceHandle.cpp index f00d5a5..a4e1bbf 100644 --- a/src/ResourceHandle.cpp +++ b/src/ResourceHandle.cpp @@ -1,6 +1,6 @@ /* * (C) 2020 The University of Chicago - * + * * See COPYRIGHT in top-level directory. */ #include "alpha/ResourceHandle.hpp" @@ -47,12 +47,11 @@ void ResourceHandle::computeSum( if(not self) throw Exception("Invalid alpha::ResourceHandle object"); auto& rpc = self->m_client->m_compute_sum; auto& ph = self->m_ph; - auto& resource_id = self->m_resource_id; if(req == nullptr) { // synchronous call - Result response = rpc.on(ph)(resource_id, x, y); + Result response = rpc.on(ph)(x, y); response.andThen([sum](int32_t s) { if(sum) *sum = s; }); } else { // asynchronous call - auto async_response = rpc.on(ph).async(resource_id, x, y); + auto async_response = rpc.on(ph).async(x, y); auto async_request_impl = std::make_shared(std::move(async_response)); async_request_impl->m_wait_callback = diff --git a/src/ResourceHandleImpl.hpp b/src/ResourceHandleImpl.hpp index bad7834..2a1a3cd 100644 --- a/src/ResourceHandleImpl.hpp +++ b/src/ResourceHandleImpl.hpp @@ -1,12 +1,12 @@ /* * (C) 2020 The University of Chicago - * + * * See COPYRIGHT in top-level directory. */ #ifndef __ALPHA_RESOURCE_HANDLE_IMPL_H #define __ALPHA_RESOURCE_HANDLE_IMPL_H -#include +#include "ClientImpl.hpp" namespace alpha { @@ -14,17 +14,14 @@ class ResourceHandleImpl { public: - UUID m_resource_id; std::shared_ptr m_client; tl::provider_handle m_ph; ResourceHandleImpl() = default; - - ResourceHandleImpl(const std::shared_ptr& client, - tl::provider_handle&& ph, - const UUID& resource_id) - : m_resource_id(resource_id) - , m_client(client) + + ResourceHandleImpl(std::shared_ptr client, + tl::provider_handle&& ph) + : m_client(std::move(client)) , m_ph(std::move(ph)) {} }; diff --git a/src/alpha-client.pc.in b/src/alpha-client.pc.in index 40ac255..ff48161 100644 --- a/src/alpha-client.pc.in +++ b/src/alpha-client.pc.in @@ -7,6 +7,6 @@ Name: alpha-client Description: Version: @ALPHA_VERSION@ -Requires: thallium uuid +Requires: thallium Libs: -L${libdir} @CLIENT_PRIVATE_LIBS@ -lstdc++ Cflags: -I${includedir} diff --git a/src/alpha-config.cmake.in b/src/alpha-config.cmake.in index 114d50a..c76f6c6 100644 --- a/src/alpha-config.cmake.in +++ b/src/alpha-config.cmake.in @@ -2,19 +2,21 @@ # alpha-config.cmake.in # -set(ALPHA_VERSION @ALPHA_VERSION@) +set (ALPHA_VERSION @ALPHA_VERSION@) @PACKAGE_INIT@ -set_and_check(ALPHA_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") +set_and_check (ALPHA_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") -check_required_components(alpha) +check_required_components (alpha) include (CMakeFindDependencyMacro) find_dependency (thallium) find_dependency (PkgConfig) -pkg_check_modules (uuid REQUIRED uuid) # FIXME: add more dependencies if needed include ("${CMAKE_CURRENT_LIST_DIR}/alpha-targets.cmake") + +add_library (alpha::server ALIAS alpha-server) +add_library (alpha::client ALIAS alpha-client) diff --git a/src/alpha-server.pc.in b/src/alpha-server.pc.in index 1743825..1940dfe 100644 --- a/src/alpha-server.pc.in +++ b/src/alpha-server.pc.in @@ -7,6 +7,6 @@ Name: alpha-server Description: Version: @ALPHA_VERSION@ -Requires: thallium uuid +Requires: thallium Libs: -L${libdir} @SERVER_PRIVATE_LIBS@ -lstdc++ Cflags: -I${includedir} diff --git a/tests/AdminTest.cpp b/tests/AdminTest.cpp deleted file mode 100644 index 51e53de..0000000 --- a/tests/AdminTest.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * (C) 2020 The University of Chicago - * - * See COPYRIGHT in top-level directory. - */ -#include -#include -#include -#include - -static const std::string resource_type = "dummy"; -static constexpr const char* resource_config = "{ \"path\" : \"mydb\" }"; - -TEST_CASE("Admin tests", "[admin]") { - - auto engine = thallium::engine("na+sm", THALLIUM_SERVER_MODE); - // Initialize the provider - alpha::Provider provider(engine); - - SECTION("Create an admin") { - alpha::Admin admin(engine); - std::string addr = engine.self(); - - SECTION("Create and destroy resources") { - alpha::UUID resource_id = admin.createResource(addr, 0, resource_type, resource_config); - - REQUIRE_THROWS_AS(admin.createResource(addr, 0, "blabla", resource_config), - alpha::Exception); - - admin.destroyResource(addr, 0, resource_id); - - alpha::UUID bad_id; - REQUIRE_THROWS_AS(admin.destroyResource(addr, 0, bad_id), alpha::Exception); - } - } - // Finalize the engine - engine.finalize(); -} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 68ccc85..ff42d44 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,11 +1,7 @@ -add_executable (AdminTest AdminTest.cpp) -target_link_libraries (AdminTest PRIVATE Catch2::Catch2WithMain alpha-server alpha-admin) -add_test (NAME AdminTest COMMAND ./AdminTest) - add_executable (ClientTest ClientTest.cpp) -target_link_libraries (ClientTest PRIVATE Catch2::Catch2WithMain alpha-server alpha-client alpha-admin) +target_link_libraries (ClientTest PRIVATE Catch2::Catch2WithMain alpha::server alpha::client) add_test (NAME ClientTest COMMAND ./ClientTest) add_executable (ResourceTest ResourceTest.cpp) -target_link_libraries (ResourceTest PRIVATE Catch2::Catch2WithMain alpha-server alpha-client alpha-admin) +target_link_libraries (ResourceTest PRIVATE Catch2::Catch2WithMain alpha::server alpha::client) add_test (NAME ResourceTest COMMAND ./ResourceTest) diff --git a/tests/ClientTest.cpp b/tests/ClientTest.cpp index e6bc021..f1eff88 100644 --- a/tests/ClientTest.cpp +++ b/tests/ClientTest.cpp @@ -5,34 +5,36 @@ */ #include #include +#include "Ensure.hpp" #include #include #include -#include - -static constexpr const char* resource_config = "{ \"path\" : \"mydb\" }"; -static const std::string resource_type = "dummy"; TEST_CASE("Client test", "[client]") { auto engine = thallium::engine("na+sm", THALLIUM_SERVER_MODE); + ENSURE(engine.finalize()); // Initialize the provider - alpha::Provider provider(engine); - alpha::Admin admin(engine); - std::string addr = engine.self(); - auto resource_id = admin.createResource(addr, 0, resource_type, resource_config); + const auto provider_config = R"( + { + "resource": { + "type": "dummy", + "config": {} + } + } + )"; + + alpha::Provider provider(engine, 42, provider_config); SECTION("Open resource") { + alpha::Client client(engine); std::string addr = engine.self(); - alpha::ResourceHandle my_resource = client.makeResourceHandle(addr, 0, resource_id); + alpha::ResourceHandle my_resource = client.makeResourceHandle(addr, 42); REQUIRE(static_cast(my_resource)); - auto bad_id = alpha::UUID::generate(); - REQUIRE_THROWS_AS(client.makeResourceHandle(addr, 0, bad_id), alpha::Exception); + REQUIRE_THROWS_AS(client.makeResourceHandle(addr, 55), alpha::Exception); + REQUIRE_NOTHROW(client.makeResourceHandle(addr, 55, false)); } - - admin.destroyResource(addr, 0, resource_id); - engine.finalize(); } diff --git a/tests/Ensure.hpp b/tests/Ensure.hpp new file mode 100644 index 0000000..ad61f2d --- /dev/null +++ b/tests/Ensure.hpp @@ -0,0 +1,28 @@ +#include + +template +class deferred { + + public: + + explicit deferred(F&& function) + : m_function(std::forward(function)) {} + + ~deferred() { + m_function(); + } + + private: + + F m_function; +}; + +template +inline auto defer(F&& f) { + return deferred(std::forward(f)); +} + +#define _UTILITY_DEFERRED_LINENAME_CAT(name, line) name##line +#define _UTILITY_DEFERRED_LINENAME(name, line) _UTILITY_DEFERRED_LINENAME_CAT(name, line) +#define ENSURE(f) \ + const auto& _UTILITY_DEFERRED_LINENAME(EXIT, __LINE__) = ::defer([&]() { f; }); (void)_UTILITY_DEFERRED_LINENAME(EXIT, __LINE__) diff --git a/tests/ResourceTest.cpp b/tests/ResourceTest.cpp index d1cb272..25724d5 100644 --- a/tests/ResourceTest.cpp +++ b/tests/ResourceTest.cpp @@ -5,25 +5,28 @@ */ #include #include +#include "Ensure.hpp" #include #include -#include - -static const std::string resource_type = "dummy"; -static constexpr const char* resource_config = "{ \"path\" : \"mydb\" }"; TEST_CASE("Resource test", "[resource]") { auto engine = thallium::engine("na+sm", THALLIUM_SERVER_MODE); - alpha::Admin admin(engine); - alpha::Provider provider(engine); - std::string addr = engine.self(); - auto resource_id = admin.createResource(addr, 0, resource_type, resource_config); + ENSURE(engine.finalize()); + const auto provider_config = R"( + { + "resource": { + "type": "dummy", + "config": {} + } + } + )"; + alpha::Provider provider(engine, 42, provider_config); SECTION("Create ResourceHandle") { alpha::Client client(engine); std::string addr = engine.self(); - auto rh = client.makeResourceHandle(addr, 0, resource_id); + auto rh = client.makeResourceHandle(addr, 42); SECTION("Send Sum RPC") { int32_t result = 0; @@ -37,17 +40,5 @@ TEST_CASE("Resource test", "[resource]") { REQUIRE_NOTHROW(request.wait()); REQUIRE(result == 94); } - - auto bad_id = alpha::UUID::generate(); - REQUIRE_THROWS_AS(client.makeResourceHandle(addr, 0, bad_id), - alpha::Exception); - - REQUIRE_THROWS_AS(client.makeResourceHandle(addr, 1, resource_id), - std::exception); - REQUIRE_NOTHROW(client.makeResourceHandle(addr, 0, bad_id, false)); - REQUIRE_NOTHROW(client.makeResourceHandle(addr, 1, resource_id, false)); } - - admin.destroyResource(addr, 0, resource_id); - engine.finalize(); }