diff --git a/CMakeLists.txt b/CMakeLists.txt index 52bf070..b2bce3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,7 @@ add_library(webfused-static STATIC src/webfused/daemon.c src/webfused/config/config.c src/webfused/config/factory.c + src/webfused/config/builder.c src/webfused/log/logger.c ) @@ -105,6 +106,7 @@ include(GoogleTest) pkg_check_modules(GMOCK gmock) add_executable(alltests + test/mock_config_builder.cc test/mock_logger.cc test/test_config.cc test/test_log.cc diff --git a/src/webfused/config/builder.c b/src/webfused/config/builder.c new file mode 100644 index 0000000..7d1c6c1 --- /dev/null +++ b/src/webfused/config/builder.c @@ -0,0 +1,42 @@ +#include "webfused/config/builder.h" + +void +wfd_config_builder_set_server_vhostname( + struct wfd_config_builder builder, + char const * vhost_name) +{ + builder.vtable->set_server_vhostname(builder.data, vhost_name); +} + +void +wfd_config_builder_set_server_port( + struct wfd_config_builder builder, + int port) +{ + builder.vtable->set_server_port(builder.data, port); +} + +void +wfd_config_builder_set_server_key( + struct wfd_config_builder builder, + char const * key_path) +{ + builder.vtable->set_server_key(builder.data, key_path); +} + +void +wfd_config_builder_set_server_cert( + struct wfd_config_builder builder, + char const * cert_path) +{ + builder.vtable->set_server_cert(builder.data, cert_path); +} + +void +wfd_config_builder_set_server_document_root( + struct wfd_config_builder builder, + char const * document_root) +{ + builder.vtable->set_server_document_root(builder.data, document_root); +} + diff --git a/src/webfused/config/builder.h b/src/webfused/config/builder.h new file mode 100644 index 0000000..0dbc753 --- /dev/null +++ b/src/webfused/config/builder.h @@ -0,0 +1,79 @@ +#ifndef WFD_CONFIG_BUILDER_H +#define WFD_CONFIG_BUILDER_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef void +wfd_config_builder_set_server_vhostname_fn( + void * data, + char const * vhost_name); + +typedef void +wfd_config_builder_set_server_port_fn( + void * data, + int port); + +typedef void +wfd_config_builder_set_server_key_fn( + void * data, + char const * key_path); + +typedef void +wfd_config_builder_set_server_cert_fn( + void * data, + char const * cert_path); + +typedef void +wfd_config_builder_set_server_document_root_fn( + void * data, + char const * document_root); + +struct wfd_config_builder_vtable +{ + wfd_config_builder_set_server_vhostname_fn * set_server_vhostname; + wfd_config_builder_set_server_port_fn * set_server_port; + wfd_config_builder_set_server_key_fn * set_server_key; + wfd_config_builder_set_server_cert_fn * set_server_cert; + wfd_config_builder_set_server_document_root_fn * set_server_document_root; +}; + +struct wfd_config_builder +{ + struct wfd_config_builder_vtable const * vtable; + void * data; +}; + +extern void +wfd_config_builder_set_server_vhostname( + struct wfd_config_builder builder, + char const * vhost_name); + +extern void +wfd_config_builder_set_server_port( + struct wfd_config_builder builder, + int port); + +extern void +wfd_config_builder_set_server_key( + struct wfd_config_builder builder, + char const * key_path); + +extern void +wfd_config_builder_set_server_cert( + struct wfd_config_builder builder, + char const * cert_path); + +extern void +wfd_config_builder_set_server_document_root( + struct wfd_config_builder builder, + char const * document_root); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/webfused/config/factory.c b/src/webfused/config/factory.c index 11b1ff7..36096a1 100644 --- a/src/webfused/config/factory.c +++ b/src/webfused/config/factory.c @@ -1,6 +1,4 @@ #include "webfused/config/factory.h" -#include "webfused/config/config_intern.h" -#include "webfused/config/config.h" #include "webfused/log/log.h" #include @@ -59,76 +57,72 @@ wfd_config_check_version( static bool wfd_config_read_server( config_t * config, - struct wfd_config * result) + struct wfd_config_builder builder) { char const * vhost_name; int rc = config_lookup_string(config, "server.vhost_name", &vhost_name); if (CONFIG_TRUE == rc) { - wfd_config_set_server_vhostname(result, vhost_name); + wfd_config_builder_set_server_vhostname(builder, vhost_name); } int port; rc = config_lookup_int(config, "server.port", &port); if (CONFIG_TRUE == rc) { - wfd_config_set_server_port(result, port); + wfd_config_builder_set_server_port(builder, port); } char const * cert; rc = config_lookup_string(config, "server.tls.certificate", &cert); if (CONFIG_TRUE == rc) { - wfd_config_set_server_cert(result, cert); + wfd_config_builder_set_server_cert(builder, cert); } char const * key; rc = config_lookup_string(config, "server.tls.key", &key); if (CONFIG_TRUE == rc) { - wfd_config_set_server_key(result, key); + wfd_config_builder_set_server_key(builder, key); } char const * doc_root; rc = config_lookup_string(config, "server.document_root", &doc_root); if (CONFIG_TRUE == rc) { - wfd_config_set_server_document_root(result, doc_root); + wfd_config_builder_set_server_document_root(builder, doc_root); } return true; } -static struct wfd_config * -wfd_config_load(config_t * config) +static bool +wfd_config_load( + struct wfd_config_builder builder, + config_t * config) { - struct wfd_config * result = wfd_config_create(); - bool success = wfd_config_check_version(config) - && wfd_config_read_server(config, result) + bool result = wfd_config_check_version(config) + && wfd_config_read_server(config, builder) ; - if (!success) - { - wfd_config_dispose(result); - result = NULL; - } - return result; } -struct wfd_config * +bool wfd_config_load_file( + struct wfd_config_builder builder, char const * filename) { - struct wfd_config * result = NULL; + bool result = false; config_t config; config_init(&config); int rc = config_read_file(&config, filename); if (CONFIG_TRUE == rc) { - result = wfd_config_load(&config); + result = wfd_config_load(builder, &config); } else { @@ -143,18 +137,19 @@ wfd_config_load_file( return result; } -struct wfd_config * +bool wfd_config_load_string( + struct wfd_config_builder builder, char const * contents) { - struct wfd_config * result = NULL; + bool result = false; config_t config; config_init(&config); int rc = config_read_string(&config, contents); if (CONFIG_TRUE == rc) { - result = wfd_config_load(&config); + result = wfd_config_load(builder, &config); } else { diff --git a/src/webfused/config/factory.h b/src/webfused/config/factory.h index f058b4c..f2dcd5d 100644 --- a/src/webfused/config/factory.h +++ b/src/webfused/config/factory.h @@ -1,17 +1,25 @@ #ifndef WFD_CONFIG_FACTORY_H #define WFD_CONFIG_FACTORY_H +#ifndef __cplusplus +#include +#endif + +#include "webfused/config/builder.h" + #ifdef __cplusplus extern "C" { #endif -extern struct wfd_config * +extern bool wfd_config_load_file( + struct wfd_config_builder builder, char const * filename); -extern struct wfd_config * +extern bool wfd_config_load_string( + struct wfd_config_builder builder, char const * contents); #ifdef __cplusplus diff --git a/test/mock_config_builder.cc b/test/mock_config_builder.cc new file mode 100644 index 0000000..90334b7 --- /dev/null +++ b/test/mock_config_builder.cc @@ -0,0 +1,76 @@ +#include "mock_config_builder.hpp" + +extern "C" +{ +using webfused_test::IConfigBuilder; + +static void +wfd_MockConifigBuilder_set_server_vhostname( + void * data, + char const * vhost_name) +{ + auto * builder = reinterpret_cast(data); + builder->setServerVhostname(vhost_name); +} + +static void +wfd_MockConifigBuilder_set_server_port( + void * data, + int port) +{ + auto * builder = reinterpret_cast(data); + builder->setServerPort(port); +} + +static void +wfd_MockConifigBuilder_set_server_key( + void * data, + char const * key_path) +{ + auto * builder = reinterpret_cast(data); + builder->setServerKey(key_path); +} + +static void +wfd_MockConifigBuilder_set_server_cert( + void * data, + char const * cert_path) +{ + auto * builder = reinterpret_cast(data); + builder->setServerCert(cert_path); +} + +static void +wfd_MockConifigBuilder_set_server_document_root( + void * data, + char const * document_root) +{ + auto * builder = reinterpret_cast(data); + builder->setServerDocumentRoot(document_root); +} + +static const wfd_config_builder_vtable wfd_MockConfigBuilder_vtable = +{ + &wfd_MockConifigBuilder_set_server_vhostname, + &wfd_MockConifigBuilder_set_server_port, + &wfd_MockConifigBuilder_set_server_key, + &wfd_MockConifigBuilder_set_server_cert, + &wfd_MockConifigBuilder_set_server_document_root +}; + +} + +namespace webfused_test +{ + struct wfd_config_builder MockConfigBuilder::getBuilder() + { + IConfigBuilder * config_builder = this; + + wfd_config_builder builder = { + &wfd_MockConfigBuilder_vtable, + reinterpret_cast(config_builder) + }; + + return builder; + } +} \ No newline at end of file diff --git a/test/mock_config_builder.hpp b/test/mock_config_builder.hpp new file mode 100644 index 0000000..4620bf0 --- /dev/null +++ b/test/mock_config_builder.hpp @@ -0,0 +1,36 @@ +#ifndef WFD_MOCK_CONFIG_BUILDER_HPP +#define WFD_MOCK_CONFIG_BUILDER_HPP + +#include +#include "webfused/config/builder.h" + +namespace webfused_test +{ + +class IConfigBuilder +{ +public: + virtual ~IConfigBuilder() = default; + virtual void setServerVhostname(char const * vhostname) = 0; + virtual void setServerPort(int port) = 0; + virtual void setServerKey(char const * key_path) = 0; + virtual void setServerCert(char const * cert_path) = 0; + virtual void setServerDocumentRoot(char const * document_root) = 0; +}; + +class MockConfigBuilder: public IConfigBuilder +{ +public: + ~MockConfigBuilder() override = default; + MOCK_METHOD1(setServerVhostname, void (char const * vhostname)); + MOCK_METHOD1(setServerPort, void (int port)); + MOCK_METHOD1(setServerKey, void (char const * key_path)); + MOCK_METHOD1(setServerCert, void (char const * cert_path)); + MOCK_METHOD1(setServerDocumentRoot, void (char const * document_root)); + + struct wfd_config_builder getBuilder(); +}; + +} + +#endif diff --git a/test/test_config.cc b/test/test_config.cc index 59bdf63..c0179b1 100644 --- a/test/test_config.cc +++ b/test/test_config.cc @@ -1,21 +1,26 @@ #include #include "webfused/config/factory.h" -#include "webfused/config/config.h" #include "webfused/log/logger.h" #include "webfused/log/log.h" #include "mock_logger.hpp" +#include "mock_config_builder.hpp" using ::testing::_; +using ::testing::StrictMock; +using ::testing::StrEq; using ::webfused_test::MockLogger; +using ::webfused_test::MockConfigBuilder; TEST(config, is_loadable) { - struct wfd_config * config = wfd_config_load_file("webfused.conf"); - ASSERT_NE(nullptr, config); + StrictMock builder; + EXPECT_CALL(builder, setServerVhostname(StrEq("localhost"))).Times(1); + EXPECT_CALL(builder, setServerPort(8080)).Times(1); - wfd_config_dispose(config); + bool result = wfd_config_load_file(builder.getBuilder(), "webfused.conf"); + ASSERT_TRUE(result); } TEST(config, minimal_config) @@ -24,11 +29,11 @@ TEST(config, minimal_config) EXPECT_CALL(logger, log(_, _, _)).Times(0); EXPECT_CALL(logger, onclose()).Times(1); - char const minimal[] = "version = { major = 1, minor = 0 }\n"; - struct wfd_config * config = wfd_config_load_string(minimal); - ASSERT_NE(nullptr, config); + StrictMock builder; - wfd_config_dispose(config); + char const minimal[] = "version = { major = 1, minor = 0 }\n"; + bool result = wfd_config_load_string(builder.getBuilder(), minimal); + ASSERT_TRUE(result); } TEST(config, invalid_config) @@ -37,10 +42,12 @@ TEST(config, invalid_config) EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1); EXPECT_CALL(logger, onclose()).Times(1); + StrictMock builder; + char const syntax_error[] = "version.major = 1\n"; - struct wfd_config * config = wfd_config_load_string(syntax_error); - ASSERT_EQ(nullptr, config); + bool result = wfd_config_load_string(builder.getBuilder(), syntax_error); + ASSERT_FALSE(result); } TEST(config, invalid_major_version_too_low) @@ -49,10 +56,12 @@ TEST(config, invalid_major_version_too_low) EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1); EXPECT_CALL(logger, onclose()).Times(1); + StrictMock builder; + char const too_low[] = "version = { major = 0, minor = 0 }\n"; - struct wfd_config * config = wfd_config_load_string(too_low); - ASSERT_EQ(nullptr, config); + bool result = wfd_config_load_string(builder.getBuilder(), too_low); + ASSERT_FALSE(result); } TEST(config, invalid_major_version_too_high) @@ -61,10 +70,12 @@ TEST(config, invalid_major_version_too_high) EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1); EXPECT_CALL(logger, onclose()).Times(1); + StrictMock builder; + char const too_high[] = "version = { major = 2, minor = 0 }\n"; - struct wfd_config * config = wfd_config_load_string(too_high); - ASSERT_EQ(nullptr, config); + bool result = wfd_config_load_string(builder.getBuilder(), too_high); + ASSERT_FALSE(result); } TEST(config, invalid_missing_major_version) @@ -73,10 +84,12 @@ TEST(config, invalid_missing_major_version) EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1); EXPECT_CALL(logger, onclose()).Times(1); + StrictMock builder; + char const too_high[] = "version = { minor = 0 }\n"; - struct wfd_config * config = wfd_config_load_string(too_high); - ASSERT_EQ(nullptr, config); + bool result = wfd_config_load_string(builder.getBuilder(), too_high); + ASSERT_FALSE(result); } TEST(config, invalid_missing_minor_version) @@ -85,10 +98,12 @@ TEST(config, invalid_missing_minor_version) EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1); EXPECT_CALL(logger, onclose()).Times(1); + StrictMock builder; + char const too_high[] = "version = { major = 1 }\n"; - struct wfd_config * config = wfd_config_load_string(too_high); - ASSERT_EQ(nullptr, config); + bool result = wfd_config_load_string(builder.getBuilder(), too_high); + ASSERT_FALSE(result); } TEST(config, valid_older_minor) @@ -97,12 +112,12 @@ TEST(config, valid_older_minor) EXPECT_CALL(logger, log(WFD_LOGLEVEL_INFO, _, _)).Times(1); EXPECT_CALL(logger, onclose()).Times(1); - char const valid[] = "version = { major = 1, minor = -1 }\n"; + StrictMock builder; - struct wfd_config * config = wfd_config_load_string(valid); - ASSERT_NE(nullptr, config); + char const valid[] = "version = { major = 1, minor = -1 }\n"; - wfd_config_dispose(config); + bool result = wfd_config_load_string(builder.getBuilder(), valid); + ASSERT_TRUE(result); } TEST(config, valid_newer_minor) @@ -111,31 +126,12 @@ TEST(config, valid_newer_minor) EXPECT_CALL(logger, log(WFD_LOGLEVEL_WARN, _, _)).Times(1); EXPECT_CALL(logger, onclose()).Times(1); - char const valid[] = "version = { major = 1, minor = 1 }\n"; - - struct wfd_config * config = wfd_config_load_string(valid); - ASSERT_NE(nullptr, config); - - wfd_config_dispose(config); -} - -TEST(config, default_values) -{ - MockLogger logger; - EXPECT_CALL(logger, log(_, _, _)).Times(0); - EXPECT_CALL(logger, onclose()).Times(1); - - char const minimal[] = "version = { major = 1, minor = 0 }\n"; - struct wfd_config * config = wfd_config_load_string(minimal); - ASSERT_NE(nullptr, config); + StrictMock builder; - ASSERT_EQ(8080, wfd_config_get_server_port(config)); - ASSERT_STREQ("localhost", wfd_config_get_server_vhostname(config)); - ASSERT_EQ(nullptr, wfd_config_get_server_cert(config)); - ASSERT_EQ(nullptr, wfd_config_get_server_key(config)); - ASSERT_EQ(nullptr, wfd_config_get_server_document_root(config)); + char const valid[] = "version = { major = 1, minor = 1 }\n"; - wfd_config_dispose(config); + bool result = wfd_config_load_string(builder.getBuilder(), valid); + ASSERT_TRUE(result); } TEST(config, vhost_name) @@ -144,6 +140,9 @@ TEST(config, vhost_name) EXPECT_CALL(logger, log(_, _, _)).Times(0); EXPECT_CALL(logger, onclose()).Times(1); + StrictMock builder; + EXPECT_CALL(builder, setServerVhostname(StrEq("some.host"))).Times(1); + char const config_text[] = "version = { major = 1, minor = 0 }\n" "server:\n" @@ -151,12 +150,8 @@ TEST(config, vhost_name) " vhost_name = \"some.host\"\n" "}\n" ; - struct wfd_config * config = wfd_config_load_string(config_text); - ASSERT_NE(nullptr, config); - - ASSERT_STREQ("some.host", wfd_config_get_server_vhostname(config)); - - wfd_config_dispose(config); + bool result = wfd_config_load_string(builder.getBuilder(), config_text); + ASSERT_TRUE(result); } TEST(config, port) @@ -165,46 +160,18 @@ TEST(config, port) EXPECT_CALL(logger, log(_, _, _)).Times(0); EXPECT_CALL(logger, onclose()).Times(1); - char const config_text[] = - "version = { major = 1, minor = 0 }\n" - "server:\n" - "{\n" - " port = 54321\n" - "}\n" - ; - struct wfd_config * config = wfd_config_load_string(config_text); - ASSERT_NE(nullptr, config); - - ASSERT_EQ(54321, wfd_config_get_server_port(config)); - - wfd_config_dispose(config); -} - -TEST(config, tls) -{ - MockLogger logger; - EXPECT_CALL(logger, log(_, _, _)).Times(0); - EXPECT_CALL(logger, onclose()).Times(1); + StrictMock builder; + EXPECT_CALL(builder, setServerPort(54321)).Times(1); char const config_text[] = "version = { major = 1, minor = 0 }\n" "server:\n" "{\n" - " tls:\n" - " {\n" - " certificate = \"/path/to/cert.pem\"\n" - " key = \"/path/to/key.pem\"\n" - " }\n" + " port = 54321\n" "}\n" ; - struct wfd_config * config = wfd_config_load_string(config_text); - ASSERT_NE(nullptr, config); - - ASSERT_TRUE(wfd_config_is_server_tls_enabled(config)); - ASSERT_STREQ("/path/to/cert.pem", wfd_config_get_server_cert(config)); - ASSERT_STREQ("/path/to/key.pem", wfd_config_get_server_key(config)); - - wfd_config_dispose(config); + bool result = wfd_config_load_string(builder.getBuilder(), config_text); + ASSERT_TRUE(result); } TEST(config, tls_certificate) @@ -213,6 +180,9 @@ TEST(config, tls_certificate) EXPECT_CALL(logger, log(_, _, _)).Times(0); EXPECT_CALL(logger, onclose()).Times(1); + StrictMock builder; + EXPECT_CALL(builder, setServerCert(StrEq("/path/to/cert.pem"))).Times(1); + char const config_text[] = "version = { major = 1, minor = 0 }\n" "server:\n" @@ -223,14 +193,8 @@ TEST(config, tls_certificate) " }\n" "}\n" ; - struct wfd_config * config = wfd_config_load_string(config_text); - ASSERT_NE(nullptr, config); - - ASSERT_FALSE(wfd_config_is_server_tls_enabled(config)); - ASSERT_STREQ("/path/to/cert.pem", wfd_config_get_server_cert(config)); - ASSERT_EQ(nullptr, wfd_config_get_server_key(config)); - - wfd_config_dispose(config); + bool result = wfd_config_load_string(builder.getBuilder(), config_text); + ASSERT_TRUE(result); } TEST(config, tls_key) @@ -239,6 +203,9 @@ TEST(config, tls_key) EXPECT_CALL(logger, log(_, _, _)).Times(0); EXPECT_CALL(logger, onclose()).Times(1); + StrictMock builder; + EXPECT_CALL(builder, setServerKey(StrEq("/path/to/key.pem"))).Times(1); + char const config_text[] = "version = { major = 1, minor = 0 }\n" "server:\n" @@ -249,14 +216,8 @@ TEST(config, tls_key) " }\n" "}\n" ; - struct wfd_config * config = wfd_config_load_string(config_text); - ASSERT_NE(nullptr, config); - - ASSERT_FALSE(wfd_config_is_server_tls_enabled(config)); - ASSERT_EQ(nullptr, wfd_config_get_server_cert(config)); - ASSERT_STREQ("/path/to/key.pem", wfd_config_get_server_key(config)); - - wfd_config_dispose(config); + bool result = wfd_config_load_string(builder.getBuilder(), config_text); + ASSERT_TRUE(result); } TEST(config, document_root) @@ -265,6 +226,9 @@ TEST(config, document_root) EXPECT_CALL(logger, log(_, _, _)).Times(0); EXPECT_CALL(logger, onclose()).Times(1); + StrictMock builder; + EXPECT_CALL(builder, setServerDocumentRoot(StrEq("/var/www"))).Times(1); + char const config_text[] = "version = { major = 1, minor = 0 }\n" "server:\n" @@ -272,10 +236,6 @@ TEST(config, document_root) " document_root = \"/var/www\"\n" "}\n" ; - struct wfd_config * config = wfd_config_load_string(config_text); - ASSERT_NE(nullptr, config); - - ASSERT_STREQ("/var/www", wfd_config_get_server_document_root(config)); - - wfd_config_dispose(config); + bool result = wfd_config_load_string(builder.getBuilder(), config_text); + ASSERT_TRUE(result); }