From 0b9b54764ba0c5963a66d0a66140abbc49990f32 Mon Sep 17 00:00:00 2001 From: Simone Basso Date: Mon, 7 Jan 2019 13:43:25 +0100 Subject: [PATCH] Second attempt at reaching 100% of coverage --- mkmmdb.hpp | 55 ++++++++++++++++++++++++++++++++------------------ unit-tests.cpp | 10 +++++++++ 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/mkmmdb.hpp b/mkmmdb.hpp index 8cf3e98..c979fff 100644 --- a/mkmmdb.hpp +++ b/mkmmdb.hpp @@ -100,6 +100,11 @@ struct MMDB_s_deleter { // MMDB_s_uptr is a unique pointer to MMDB_s. using MMDB_s_uptr = std::unique_ptr; +// MKMMDB_NOEXCEPT allows to remove the noexcept specifier in unit tests. +#ifndef MKMMDB_NOEXCEPT +#define MKMMDB_NOEXCEPT noexcept +#endif + // Handle::Impl contains Handle's internals. class Handle::Impl { public: @@ -119,21 +124,21 @@ class Handle::Impl { // the country code. @param logs is where to store logs. Returns true on // success and false on failure. bool finish_lookup_cc(MMDB_entry_s *entry, std::string &cc, - std::vector &logs) noexcept; + std::vector &logs) MKMMDB_NOEXCEPT; // finish_lookup_asn finishes a ASN lookup. @param entry is the entry that // should contain the results. @param asn is the place where we'll write // the ASN string. @param logs is where to store logs. Returns true on // success and false on failure. bool finish_lookup_asn(MMDB_entry_s *entry, std::string &asn, - std::vector &logs) noexcept; + std::vector &logs) MKMMDB_NOEXCEPT; // finish_lookup_org finishes a ORG lookup. @param entry is the entry that // should contain the results. @param org is the place where we'll write // the ORG string. @param logs is where to store logs. Returns true on // success and false on failure. bool finish_lookup_org(MMDB_entry_s *entry, std::string &org, - std::vector &logs) noexcept; + std::vector &logs) MKMMDB_NOEXCEPT; }; Handle::Handle() noexcept { impl.reset(new Handle::Impl); } @@ -208,16 +213,28 @@ static bool MMDB_get_value_check( return true; } -bool Handle::Impl::finish_lookup_cc(MMDB_entry_s *entry, std::string &cc, - std::vector &logs) noexcept { - if (!entry) { - abort(); - } +// MKMMDB_ABORT allows to check in unit tests that we would abort. +#ifndef MKMMDB_ABORT +#define MKMMDB_ABORT abort() +#endif + +// MKMMDB_ABORT_IF_NULLPTR calls abort if @p Pointer is nullptr. +#define MKMMDB_ABORT_IF_NULLPTR(Pointer) \ + do { \ + if (Pointer == nullptr) { \ + MKMMDB_ABORT; \ + } \ + } while (0) + +bool Handle::Impl::finish_lookup_cc( + MMDB_entry_s *entry, std::string &cc, + std::vector &logs) MKMMDB_NOEXCEPT { + MKMMDB_ABORT_IF_NULLPTR(entry); MMDB_entry_data_s data{}; auto mmdb_error = MMDB_get_value( entry, &data, "registered_country", "iso_code", nullptr); auto ok = MMDB_get_value_check( - mmdb_error, data, MMDB_DATA_TYPE_UTF8_STRING, logs); + mmdb_error, data, MMDB_DATA_TYPE_UTF8_STRING, logs); MKMOCK_HOOK(finish_lookup_cc_check, ok); if (!ok) { return false; @@ -234,11 +251,10 @@ bool Handle::lookup_cc(const std::string &ip, std::string &cc, }); } -bool Handle::Impl::finish_lookup_asn(MMDB_entry_s *entry, std::string &asn, - std::vector &logs) noexcept { - if (!entry) { - abort(); - } +bool Handle::Impl::finish_lookup_asn( + MMDB_entry_s *entry, std::string &asn, + std::vector &logs) MKMMDB_NOEXCEPT { + MKMMDB_ABORT_IF_NULLPTR(entry); MMDB_entry_data_s data{}; auto mmdb_error = MMDB_get_value( entry, &data, "autonomous_system_number", nullptr); @@ -259,16 +275,15 @@ bool Handle::lookup_asn(const std::string &ip, std::string &asn, }); } -bool Handle::Impl::finish_lookup_org(MMDB_entry_s *entry, std::string &org, - std::vector &logs) noexcept { - if (!entry) { - abort(); - } +bool Handle::Impl::finish_lookup_org( + MMDB_entry_s *entry, std::string &org, + std::vector &logs) MKMMDB_NOEXCEPT { + MKMMDB_ABORT_IF_NULLPTR(entry); MMDB_entry_data_s data{}; auto mmdb_error = MMDB_get_value( entry, &data, "autonomous_system_organization", nullptr); auto ok = MMDB_get_value_check( - mmdb_error, data, MMDB_DATA_TYPE_UTF8_STRING, logs); + mmdb_error, data, MMDB_DATA_TYPE_UTF8_STRING, logs); MKMOCK_HOOK(finish_lookup_org_check, ok); if (!ok) { return false; diff --git a/unit-tests.cpp b/unit-tests.cpp index 67bb8ae..833800a 100644 --- a/unit-tests.cpp +++ b/unit-tests.cpp @@ -13,6 +13,12 @@ MKMOCK_DEFINE_HOOK(finish_lookup_cc_check, bool); MKMOCK_DEFINE_HOOK(finish_lookup_asn_check, bool); MKMOCK_DEFINE_HOOK(finish_lookup_org_check, bool); +// Override MKMMDB_ABORT so we can actually verify we would abort +#define MKMMDB_ABORT throw std::exception() + +// Disable noexcept specifier for functions that may MKMMDB_ABORT +#define MKMMDB_NOEXCEPT // Nothing + // Include mkmmdb implementation // ----------------------------- @@ -90,3 +96,7 @@ TEST_CASE("When lookup_org fails because MMDB provides us a bad value") { REQUIRE(handle.lookup_org("8.8.8.8", org, logs) == false); }); } + +TEST_CASE("MKMMDB_ABORT_IF_NULLPTR works as expected") { + REQUIRE_THROWS([]() { MKMMDB_ABORT_IF_NULLPTR(nullptr); }()); +}