From 157db19885677257140a88506a14852c68b16e20 Mon Sep 17 00:00:00 2001 From: 0xG0nz0 <8682922+0xg0nz0@users.noreply.github.com> Date: Sun, 25 Feb 2024 19:48:40 +0000 Subject: [PATCH 1/4] Interim checkin with basic address and protocol classes --- .vscode/settings.json | 4 +- CMakeLists.txt | 7 +++- sdk/client.h | 35 ++-------------- sdk/net/address.cc | 34 ++++++++++++++++ sdk/net/address.h | 47 ++++++++++++++++++++++ sdk/net/iggy.cc | 25 ++++++++++++ sdk/net/iggy.h | 45 +++++++++++++++++++++ sdk/net/protocol.cc | 24 +++++++++++ sdk/net/protocol.h | 90 ++++++++++++++++++++++++++++++++++++++++++ sdk/net/quic/address.h | 1 + sdk/net/quic/conn.h | 1 + sdk/net/quic/stream.h | 1 + sdk/net/quic/tls.h | 1 + sdk/net/transport.h | 31 +++++++++++++++ vcpkg.json | 1 + 15 files changed, 314 insertions(+), 33 deletions(-) create mode 100644 sdk/net/address.cc create mode 100644 sdk/net/address.h create mode 100644 sdk/net/iggy.cc create mode 100644 sdk/net/iggy.h create mode 100644 sdk/net/protocol.cc create mode 100644 sdk/net/protocol.h create mode 100644 sdk/net/quic/address.h create mode 100644 sdk/net/quic/conn.h create mode 100644 sdk/net/quic/stream.h create mode 100644 sdk/net/quic/tls.h create mode 100644 sdk/net/transport.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 6fe6f2b..8bc4828 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -76,6 +76,8 @@ "cinttypes": "cpp", "typeinfo": "cpp", "valarray": "cpp", - "variant": "cpp" + "variant": "cpp", + "csignal": "cpp", + "source_location": "cpp" } } diff --git a/CMakeLists.txt b/CMakeLists.txt index 1976ec5..4df7d9f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,11 +10,13 @@ if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") endif() # set up library dependencies +find_package(ada CONFIG REQUIRED) find_package(libuv CONFIG REQUIRED) find_package(spdlog CONFIG REQUIRED) find_package(unofficial-sodium CONFIG REQUIRED) # these do not correctly support CMake +find_path(ADA_INCLUDE_DIR ada.h REQUIRED) find_path(SODIUM_INCLUDE_DIR sodium.h REQUIRED) # customize the builds of key networking components; WolfSSL is not @@ -59,9 +61,12 @@ add_library( sdk/client.cc sdk/model.cc sdk/serialization.cc + sdk/net/address.cc + sdk/net/protocol.cc + sdk/net/iggy.cc ) target_compile_features(iggy PRIVATE cxx_std_17) -target_include_directories(iggy PRIVATE ${SODIUM_INCLUDE_DIR} ${USOCKETS_INCLUDE_DIR}) +target_include_directories(iggy PRIVATE ${SODIUM_INCLUDE_DIR} ${ADA_INCLUDE_DIR}) if (BUILD_TESTS) add_subdirectory(tests) diff --git a/sdk/client.h b/sdk/client.h index f6513d6..68cfe1c 100644 --- a/sdk/client.h +++ b/sdk/client.h @@ -4,33 +4,10 @@ #include #include #include "model.h" +#include "net/iggy.h" +#include "net/transport.h" namespace iggy { -namespace transport { - -/** - * @enum Transport - * @brief Available network transports for the Iggy server. Not all currently supported by the C++ client. - */ -enum Transport { - /** - * @brief Modern networking protocol from Google built on top of UDP. - * - * @ref [Wikipedia](https://en.wikipedia.org/wiki/QUIC) - */ - QUIC, - - /** - * @brief Classic HTTP REST encoded as JSON. Not recommended for high performance applications. - */ - HTTP, - - /** - * @brief Binary protocol over TCP/IP. This is the default transport. - */ - TCP -}; -}; // namespace transport namespace client { /** @@ -52,10 +29,6 @@ class Credentials { ~Credentials() { sodium_memzero(&password[0], password.size()); } }; -const unsigned short DEFAULT_HTTP_PORT = 3000; -const unsigned short DEFAULT_TCP_PORT = 8090; -const unsigned short DEFAULT_QUIC_PORT = 8080; - /** * @struct Options * @brief A struct to hold various options. @@ -73,12 +46,12 @@ struct Options { /** * @brief The port the Iggy server is listening on; default depends on transport. Defaults to the DEFAULT_TCP_PORT. */ - unsigned short port = DEFAULT_TCP_PORT; + unsigned short port = iggy::net::DEFAULT_TCP_PORT; /** * @brief The network transport to use when connecting to the server. Defaults to TCP. */ - iggy::transport::Transport transport = iggy::transport::Transport::TCP; + iggy::net::transport::Transport transport = iggy::net::transport::Transport::TCP; /** * @brief The user credentials to use when connecting to the server. diff --git a/sdk/net/address.cc b/sdk/net/address.cc new file mode 100644 index 0000000..95c6241 --- /dev/null +++ b/sdk/net/address.cc @@ -0,0 +1,34 @@ +#include "address.h" + +const iggy::net::protocol::ProtocolDefinition& iggy::net::address::LogicalAddress::getProtocolDefinition() const { + return this->protocolProvider->getProtocolDefinition(this->getProtocol()); +} + +iggy::net::address::LogicalAddress::LogicalAddress(const std::string& url, const iggy::net::protocol::ProtocolProvider* protocolProvider) { + auto parse_result = ada::parse(url); + if (!parse_result) { + throw std::invalid_argument("Invalid URL: " + url); + } + auto value = parse_result.value(); + auto protocol = value.get_protocol(); + if (!protocolProvider->isSupported(protocol)) { + throw std::invalid_argument("Unsupported protocol: " + protocol); + } + this->url = value; + this->protocolProvider = protocolProvider; +} + +const unsigned short iggy::net::address::LogicalAddress::getPort() const { + if (url.get_port().empty()) { + return this->getProtocolDefinition().getDefaultPort(); + } else { + int port = std::stoi(url.get_port()); + + // this should not happen if ada::parse is working correctly + if (port < 0 || port > 65535) { + throw std::out_of_range("Port number out of range"); + } + + return port; + } +} diff --git a/sdk/net/address.h b/sdk/net/address.h new file mode 100644 index 0000000..ca24549 --- /dev/null +++ b/sdk/net/address.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include "protocol.h" +#include "transport.h" + +namespace iggy { +namespace net { +namespace address { + +/*** + * @brief Logical address used in configuration and API to specify desired transport in a compact way, e.g. iggy:quic://localhost:8080. + */ +class LogicalAddress { +private: + ada::url url; + const iggy::net::protocol::ProtocolProvider* protocolProvider; + + const iggy::net::protocol::ProtocolDefinition& getProtocolDefinition() const; +public: + /** + * @brief Construct a logical address from a URL. + * @param url URL to parse. + * @param protocolProvider Context object providing supported protocols and default ports. + * @throws std::invalid_argument if the URL is invalid or the protocol is unknown. + */ + LogicalAddress(const std::string& url, const iggy::net::protocol::ProtocolProvider* protocolProvider); + + /** + * @brief Gets the protocol; you have a guarantee that it will be one of the supported protocols from ProtocolProvider. + */ + const std::string getProtocol() const noexcept { return url.get_protocol(); } + + /** + * @brief Gets the hostname to connect to or raw IP address. + */ + const std::string getHost() const noexcept { return url.get_hostname(); } + + /** + * @brief Gets the port to connect to; protocol default port will be substituted if not specified. + */ + const unsigned short getPort() const; +}; +}; // namespace address +}; // namespace net +}; // namespace iggy diff --git a/sdk/net/iggy.cc b/sdk/net/iggy.cc new file mode 100644 index 0000000..33aa2a5 --- /dev/null +++ b/sdk/net/iggy.cc @@ -0,0 +1,25 @@ +#include "iggy.h" + +iggy::net::IggyProtocolProvider::IggyProtocolProvider() { + for (const auto& protocol : this->supportedProtocols) { + this->supportedProtocolLookup[protocol.getName()] = protocol; + } +} + +const std::vector& iggy::net::IggyProtocolProvider::getSupportedProtocols() const { + return this->supportedProtocols; +} + +const iggy::net::protocol::ProtocolDefinition& iggy::net::IggyProtocolProvider::getProtocolDefinition(const std::string& protocol) const { + auto normalizedName = iggy::net::protocol::normalizeProtocolName(protocol); + auto it = this->supportedProtocolLookup.find(normalizedName); + if (it != this->supportedProtocolLookup.end()) { + return it->second; + } else { + throw std::invalid_argument("Unsupported protocol: " + protocol); + } +} + +const bool iggy::net::IggyProtocolProvider::isSupported(const std::string& protocol) const { + return this->supportedProtocolLookup.count(iggy::net::protocol::normalizeProtocolName(protocol)) > 0; +} diff --git a/sdk/net/iggy.h b/sdk/net/iggy.h new file mode 100644 index 0000000..7dfc6a3 --- /dev/null +++ b/sdk/net/iggy.h @@ -0,0 +1,45 @@ +#pragma once +#include +#include +#include "address.h" + +namespace iggy { +namespace net { + +const unsigned short DEFAULT_HTTP_PORT = 3000; +const unsigned short DEFAULT_TCP_PORT = 8090; +const unsigned short DEFAULT_QUIC_PORT = 8080; + +const std::string QUIC_PROTOCOL = "iggy:quic"; +const std::string TCP_PROTOCOL = "iggy:tcp"; +const std::string TCP_TLS_PROTOCOL = "iggy:tcp+tls"; +const std::string HTTP_PROTOCOL = "iggy:http"; +const std::string HTTP_TLS_PROTOCOL = "iggy:http+tls"; + +using iggy::net::protocol::MessageEncoding; +using iggy::net::protocol::ProtocolDefinition; + +/** + * @brief Provider that declares support and offers defaults for all Iggy C++ supported protocols. + * + * At this time we support iggy:quic, iggy:tcp (binary messaging) and iggy:http (with JSON messaging). + */ +class IggyProtocolProvider : iggy::net::protocol::ProtocolProvider { +private: + std::vector supportedProtocols = { + ProtocolDefinition(QUIC_PROTOCOL, DEFAULT_QUIC_PORT, iggy::net::transport::QUIC, true, MessageEncoding::BINARY), + ProtocolDefinition(TCP_PROTOCOL, DEFAULT_TCP_PORT, iggy::net::transport::TCP, false, MessageEncoding::BINARY), + ProtocolDefinition(TCP_TLS_PROTOCOL, DEFAULT_TCP_PORT, iggy::net::transport::TCP, true, MessageEncoding::BINARY), + ProtocolDefinition(HTTP_PROTOCOL, DEFAULT_HTTP_PORT, iggy::net::transport::HTTP, false, MessageEncoding::TEXT), + ProtocolDefinition(HTTP_TLS_PROTOCOL, DEFAULT_HTTP_PORT, iggy::net::transport::HTTP, true, MessageEncoding::TEXT)}; + std::map supportedProtocolLookup; + +public: + IggyProtocolProvider(); + const std::vector& getSupportedProtocols() const override; + const ProtocolDefinition& getProtocolDefinition(const std::string& protocol) const override; + const bool isSupported(const std::string& protocol) const override; +}; + +}; // namespace net +}; // namespace iggy diff --git a/sdk/net/protocol.cc b/sdk/net/protocol.cc new file mode 100644 index 0000000..8a2cdfc --- /dev/null +++ b/sdk/net/protocol.cc @@ -0,0 +1,24 @@ +#include "address.h" +#include "protocol.h" + +iggy::net::address::LogicalAddress iggy::net::protocol::ProtocolProvider::createAddress(const std::string& url) const { + return iggy::net::address::LogicalAddress(url, this); +} + +const std::string iggy::net::protocol::normalizeProtocolName(const std::string& protocol) { + // convert to lowercase + std::string lowerStr = protocol; + std::transform(lowerStr.begin(), lowerStr.end(), lowerStr.begin(), ::tolower); + + // trim whitespace from the start + auto start = lowerStr.find_first_not_of(" \t\n\r\f\v"); + if (start == std::string::npos) { + throw std::invalid_argument("Protocol name cannot be empty"); + } + + // trim whitespace from the end + auto end = lowerStr.find_last_not_of(" \t\n\r\f\v"); + + // return the trimmed, lowercase string + return lowerStr.substr(start, end - start + 1); +} \ No newline at end of file diff --git a/sdk/net/protocol.h b/sdk/net/protocol.h new file mode 100644 index 0000000..b773462 --- /dev/null +++ b/sdk/net/protocol.h @@ -0,0 +1,90 @@ +#pragma once + +#include +#include +#include "transport.h" + +namespace iggy { +namespace net { +namespace address { +class LogicalAddress; +}; + +namespace protocol { + +/** + * @brief Enumerates the supported message encodings. + */ +enum MessageEncoding { BINARY = 0, TEXT = 1 }; + +/** + * @brief Normalizes the protocol name to a canonical form. + */ +const std::string normalizeProtocolName(const std::string& protocol); + + +/** + * @brief Metadata about a protocol including its default port, transport, TLS support and message encoding. + */ +class ProtocolDefinition { +private: + std::string name; + unsigned short defaultPort; + iggy::net::transport::Transport transport; + bool tlsSupported; + MessageEncoding messageEncoding; + +public: + ProtocolDefinition(const std::string& name, + unsigned short defaultPort, + iggy::net::transport::Transport transport, + bool tlsSupported, + MessageEncoding messageEncoding) + : name(iggy::net::protocol::normalizeProtocolName(name)) + , defaultPort(defaultPort) + , transport(transport) + , tlsSupported(tlsSupported) + , messageEncoding(messageEncoding) {} + + ProtocolDefinition() = default; + ProtocolDefinition(const ProtocolDefinition& other) = default; + + const std::string& getName() const { return name; } + unsigned short getDefaultPort() const { return defaultPort; } + iggy::net::transport::Transport getTransport() const { return transport; }; + bool isTlsSupported() const { return tlsSupported; } + MessageEncoding getMessageEncoding() const { return messageEncoding; } +}; + +/** + * @brief Interface to plug in library-specific information on supported protocols. + */ +class ProtocolProvider { +public: + ProtocolProvider() = default; + virtual ~ProtocolProvider() = default; + + /** + * @brief Factory method to create a logical address from a URL. + */ + iggy::net::address::LogicalAddress createAddress(const std::string& url) const; + + /** + * @brief Enumerates all the supported protocols in the provider. + */ + virtual const std::vector& getSupportedProtocols() const = 0; + + /** + * @brief Given a normalized protocol name returns the definition with protocol metadata. + */ + virtual const ProtocolDefinition& getProtocolDefinition(const std::string& protocol) const; + + /** + * @brief Tests whether the given protocol is supported by this provider. + */ + virtual const bool isSupported(const std::string& protocol) const; +}; + +}; // namespace protocol +}; // namespace net +}; // namespace iggy diff --git a/sdk/net/quic/address.h b/sdk/net/quic/address.h new file mode 100644 index 0000000..6f70f09 --- /dev/null +++ b/sdk/net/quic/address.h @@ -0,0 +1 @@ +#pragma once diff --git a/sdk/net/quic/conn.h b/sdk/net/quic/conn.h new file mode 100644 index 0000000..6f70f09 --- /dev/null +++ b/sdk/net/quic/conn.h @@ -0,0 +1 @@ +#pragma once diff --git a/sdk/net/quic/stream.h b/sdk/net/quic/stream.h new file mode 100644 index 0000000..6f70f09 --- /dev/null +++ b/sdk/net/quic/stream.h @@ -0,0 +1 @@ +#pragma once diff --git a/sdk/net/quic/tls.h b/sdk/net/quic/tls.h new file mode 100644 index 0000000..6f70f09 --- /dev/null +++ b/sdk/net/quic/tls.h @@ -0,0 +1 @@ +#pragma once diff --git a/sdk/net/transport.h b/sdk/net/transport.h new file mode 100644 index 0000000..4aca7d7 --- /dev/null +++ b/sdk/net/transport.h @@ -0,0 +1,31 @@ +#pragma once + +namespace iggy { +namespace net { +namespace transport { + +/** + * @brief Available network transports in the client library. + */ +enum Transport { + /** + * @brief Modern networking protocol from Google built on top of UDP. + * + * @ref [Wikipedia](https://en.wikipedia.org/wiki/QUIC) + */ + QUIC, + + /** + * @brief Classic HTTP REST encoded as JSON. Not recommended for high performance applications. + */ + HTTP, + + /** + * @brief Binary protocol over TCP/IP. + */ + TCP +}; + +}; // namespace net +}; // namespace transport +}; // namespace iggy diff --git a/vcpkg.json b/vcpkg.json index d0964c1..810113e 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,5 +1,6 @@ { "dependencies": [ + "ada-url", "icu", "libsodium", "libuv", From 721b4a5ea26a60cb20f06e86403f04f664fe63da Mon Sep 17 00:00:00 2001 From: 0xG0nz0 <8682922+0xg0nz0@users.noreply.github.com> Date: Mon, 26 Feb 2024 20:41:30 +0000 Subject: [PATCH 2/4] Fix missing headers and namespaces; add missing docstrings --- sdk/binary.h | 4 +++- sdk/json.h | 4 +++- sdk/net/protocol.h | 25 +++++++++++++++++++++++-- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/sdk/binary.h b/sdk/binary.h index 4c94580..f0697ac 100644 --- a/sdk/binary.h +++ b/sdk/binary.h @@ -1,5 +1,7 @@ #pragma once +#include "serialization.h" + namespace iggy { namespace serialization { /** @@ -49,7 +51,7 @@ enum CommandCode { * @class BinaryWireFormat * @brief Simple binary serialization and deserialization for Iggy's protocol. */ -class BinaryWireFormat : WireFormat { +class BinaryWireFormat : iggy::serialization::WireFormat { public: BinaryWireFormat() = default; } diff --git a/sdk/json.h b/sdk/json.h index 0a0c41a..239b309 100644 --- a/sdk/json.h +++ b/sdk/json.h @@ -1,5 +1,7 @@ #pragma once +#include "serialization.h" + namespace iggy { namespace serialization { @@ -13,7 +15,7 @@ namespace json { * @class JsonWireFormat * @brief Binary serialization and deserialization for Iggy's protocol. */ -class JsonWireFormat : WireFormat { +class JsonWireFormat : iggy::serialization::WireFormat { public: JsonWireFormat() = default; } diff --git a/sdk/net/protocol.h b/sdk/net/protocol.h index b773462..f1d3812 100644 --- a/sdk/net/protocol.h +++ b/sdk/net/protocol.h @@ -49,10 +49,29 @@ class ProtocolDefinition { ProtocolDefinition() = default; ProtocolDefinition(const ProtocolDefinition& other) = default; + /** + * @brief Get the protocol name, e.g. iggy:tcp+tls. + */ const std::string& getName() const { return name; } + + /** + * @brief Gets the default port for the protocol, e.g. 443 for https. + */ unsigned short getDefaultPort() const { return defaultPort; } + + /** + * @brief Gets the transport for the protocol, e.g. iggy::net::transport::Transport::TCP. + */ iggy::net::transport::Transport getTransport() const { return transport; }; + + /** + * @brief Tests whether the protocol supports TLS; insecure and TLS protocols should be separate. + */ bool isTlsSupported() const { return tlsSupported; } + + /** + * @brief Gets the default message encoding used by the protocol, e.g. MessageEncoding::TEXT for JSON. + */ MessageEncoding getMessageEncoding() const { return messageEncoding; } }; @@ -66,6 +85,7 @@ class ProtocolProvider { /** * @brief Factory method to create a logical address from a URL. + * @param url The URL to parse in the context of this provider and its defaults. */ iggy::net::address::LogicalAddress createAddress(const std::string& url) const; @@ -77,12 +97,13 @@ class ProtocolProvider { /** * @brief Given a normalized protocol name returns the definition with protocol metadata. */ - virtual const ProtocolDefinition& getProtocolDefinition(const std::string& protocol) const; + virtual const ProtocolDefinition& getProtocolDefinition(const std::string& protocol) const = 0; /** * @brief Tests whether the given protocol is supported by this provider. + * @param protocol The protocol name to test. */ - virtual const bool isSupported(const std::string& protocol) const; + virtual const bool isSupported(const std::string& protocol) const = 0; }; }; // namespace protocol From 17ddbd747b1e1d50552010929b32ea74327bd4b5 Mon Sep 17 00:00:00 2001 From: 0xG0nz0 <8682922+0xg0nz0@users.noreply.github.com> Date: Mon, 26 Feb 2024 23:37:56 +0000 Subject: [PATCH 3/4] Switch from GoogleTest to Catch2 --- tests/CMakeLists.txt | 23 +++++------------------ tests/e2e_testutils.cc | 8 +++++--- tests/e2e_testutils.h | 14 ++++++-------- tests/model_test.cc | 11 ++++------- tests/ping_cmd_test.cc | 6 +++++- vcpkg.json | 1 + 6 files changed, 26 insertions(+), 37 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f513ea3..fe733a1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,20 +1,8 @@ -# set up GoogleTest if(BUILD_TESTS) - include(FetchContent) - FetchContent_Declare( - googletest - URL https://github.com/google/googletest/archive/dddb219c3eb96d7f9200f09b0a381f016e6b4562.zip - ) - set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) - FetchContent_MakeAvailable(googletest) - - # for E2E tests, controlling Docker containers + find_package(catch2 CONFIG REQUIRED) find_package(reproc++ CONFIG REQUIRED) - # set up GoogleTest - enable_testing() - add_executable( iggy_cpp_test @@ -24,7 +12,8 @@ if(BUILD_TESTS) iggy_cpp_test iggy - GTest::gtest_main + Catch2::Catch2 + Catch2::Catch2WithMain libuv::uv_a reproc++ unofficial-sodium::sodium @@ -42,12 +31,10 @@ if(BUILD_TESTS) PRIVATE iggy - GTest::gtest_main + Catch2::Catch2 + Catch2::Catch2WithMain libuv::uv_a reproc++ unofficial-sodium::sodium ) - - include(GoogleTest) - gtest_discover_tests(iggy_cpp_test) endif() diff --git a/tests/e2e_testutils.cc b/tests/e2e_testutils.cc index 03049b1..943f5df 100644 --- a/tests/e2e_testutils.cc +++ b/tests/e2e_testutils.cc @@ -1,9 +1,11 @@ #include "e2e_testutils.h" #include #include +#include #include +#include -void DockerTest::SetUp() { +IggyRunner::IggyRunner() { // start the Docker process with stdout redirected to parent process std::vector arguments = {"docker", "run", "-d", "--name", "iggy_test", "iggyrs/iggy:latest"}; reproc::options options; @@ -17,7 +19,7 @@ void DockerTest::SetUp() { std::this_thread::sleep_for(std::chrono::seconds(5)); } -void DockerTest::TearDown() { +IggyRunner::~IggyRunner() { // stop the Docker process process.stop(reproc::stop_actions{{reproc::stop::terminate, reproc::milliseconds(5000)}, {reproc::stop::kill, reproc::milliseconds(2000)}, @@ -28,4 +30,4 @@ void DockerTest::TearDown() { std::vector remove_arguments = {"docker", "rm", "-f", "iggy_test"}; remove_process.start(remove_arguments); remove_process.wait(reproc::milliseconds(5000)); -} \ No newline at end of file +} diff --git a/tests/e2e_testutils.h b/tests/e2e_testutils.h index 73b4cec..97fe722 100644 --- a/tests/e2e_testutils.h +++ b/tests/e2e_testutils.h @@ -1,20 +1,18 @@ #pragma once -#include #include /** - * @class DockerTest - * @brief GoogleTest fixture that starts and stops a Docker container for each test. + * @brief Test fixture that starts and stops a Docker container for each test. * * This test fixture is meant for use in end-to-end (E2E) tests for the Iggy C++ client. * It will start up the latest Iggy server inside a Docker container, allow you to * interact with it, then stop and remove the container in the TearDown() method. */ -class DockerTest : public ::testing::Test { -protected: +class IggyRunner { +private: reproc::process process; - void SetUp() override; - - void TearDown() override; +public: + IggyRunner(); + ~IggyRunner(); }; \ No newline at end of file diff --git a/tests/model_test.cc b/tests/model_test.cc index 9b0ce56..4b3b82d 100644 --- a/tests/model_test.cc +++ b/tests/model_test.cc @@ -1,11 +1,8 @@ -#include +#define CATCH_CONFIG_MAIN +#include #include "../sdk/model.h" -TEST(ModelTest, DefaultConstructor) { - // Create a Message object using the default constructor +TEST_CASE("simple test for model objects", "[model]") { iggy::model::system::Stats stats; - - // Perform assertions to verify the expected behavior - // For example, you can check if the message object is not null - ASSERT_NE(nullptr, &stats); + REQUIRE(&stats != nullptr); } diff --git a/tests/ping_cmd_test.cc b/tests/ping_cmd_test.cc index c158eaa..767e7c8 100644 --- a/tests/ping_cmd_test.cc +++ b/tests/ping_cmd_test.cc @@ -1,7 +1,11 @@ +#include #include "e2e_testutils.h" #include "../sdk/client.h" -TEST_F(DockerTest, BinaryPing) { +TEST_CASE("E2E test for ping command", "[ping]") { + // Start the Docker container; shuts down when this object goes out of scope + IggyRunner runner; + // Create a client object with all defaults iggy::client::Options options; iggy::client::Client client(options); diff --git a/vcpkg.json b/vcpkg.json index 810113e..6d55099 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,7 @@ { "dependencies": [ "ada-url", + "catch2", "icu", "libsodium", "libuv", From f4ab039c6803592b16fe65f42d84f945fa08d0f1 Mon Sep 17 00:00:00 2001 From: 0xG0nz0 <8682922+0xg0nz0@users.noreply.github.com> Date: Mon, 26 Feb 2024 23:53:52 +0000 Subject: [PATCH 4/4] Attempt fix for Catch2 failure in CI --- tests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fe733a1..75eb82f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,6 +1,6 @@ if(BUILD_TESTS) - find_package(catch2 CONFIG REQUIRED) + find_package(Catch2 CONFIG REQUIRED) find_package(reproc++ CONFIG REQUIRED) add_executable(