Skip to content

Commit

Permalink
migrate config file test to gtest to prevent segfault if file can not…
Browse files Browse the repository at this point in the history
… be loaded and get some test output so the error can be identified
  • Loading branch information
zerotacg committed Jul 8, 2024
1 parent 840e0e1 commit 5c94f27
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 18 deletions.
32 changes: 16 additions & 16 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -324,23 +324,23 @@ IF(WITH_MSQUIC)
FIND_PACKAGE(msquic REQUIRED)
ENDIF()

IF(WITH_NEL)
IF(WITH_NEL_TESTS)
FIND_PACKAGE(CppTest)

ENABLE_TESTING()
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/a7f443b80b105f940225332ed3c31f2790092f47.zip
EXCLUDE_FROM_ALL
)
SET(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
include(GoogleTest)
include(cmake/add_test_executable.cmake)
ENDIF()
IF(WITH_NEL_TESTS)
FIND_PACKAGE(CppTest)

ENABLE_TESTING()
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/a7f443b80b105f940225332ed3c31f2790092f47.zip
EXCLUDE_FROM_ALL
)
SET(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
include(GoogleTest)
include(cmake/add_test_executable.cmake)
ENDIF()

IF(WITH_NEL)
IF(HUNTER_ENABLED)
IF(WITH_GUI)
HUNTER_ADD_PACKAGE(luabind)
Expand Down
21 changes: 19 additions & 2 deletions nel/tools/nel_unit_test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
FILE(GLOB SRC *.cpp *.h)

ADD_EXECUTABLE(nel_unit_test ${SRC})
ADD_EXECUTABLE(nel_unit_test
nel_unit_test.cpp
)

INCLUDE_DIRECTORIES(${CPPTEST_INCLUDE_DIR})

TARGET_LINK_LIBRARIES(nel_unit_test ${CPPTEST_LIBRARIES} nelmisc nelnet nelligo)
NL_DEFAULT_PROPS(nel_unit_test "Unit Tests")
NL_ADD_RUNTIME_FLAGS(nel_unit_test)

ADD_DEFINITIONS(-DNEL_UNIT_BASE="${PROJECT_SOURCE_DIR}/tools/nel_unit_test/")
target_compile_definitions(nel_unit_test
PUBLIC
NEL_UNIT_BASE="${PROJECT_SOURCE_DIR}/tools/nel_unit_test/"
)

INSTALL(TARGETS nel_unit_test RUNTIME DESTINATION ${NL_BIN_PREFIX})


add_test_executable(nel_misc_config_file_test
ut_misc_config_file.test.cpp
)
target_link_libraries(nel_misc_config_file_test
nelmisc
)
target_compile_definitions(nel_misc_config_file_test
PUBLIC
NEL_UNIT_BASE="${CMAKE_CURRENT_SOURCE_DIR}/"
)
140 changes: 140 additions & 0 deletions nel/tools/nel_unit_test/ut_misc_config_file.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <string>

#include <nel/misc/config_file.h>
#include <nel/misc/path.h>
#include <nel/misc/mem_displayer.h>

#ifndef NEL_UNIT_BASE
#define NEL_UNIT_BASE ""
#endif // NEL_UNIT_BASE

using std::string;

using ::testing::IsFalse;
using ::testing::IsNull;
using ::testing::IsTrue;
using ::testing::NotNull;
using ::testing::StartsWith;
using ::testing::StrEq;

class CUTMiscConfigFileTest : public testing::Test
{
protected:
NLMISC::CApplicationContext context;

void SetUp() override
{
context = NLMISC::CApplicationContext();

NLMISC::createDebug(NULL);
}

void TearDown() override
{
}
};

TEST_F(CUTMiscConfigFileTest, configWithInclude)
{
NLMISC::CConfigFile configFile;

ASSERT_NO_THROW({ configFile.load(NEL_UNIT_BASE "ut_misc_files/cfg_with_include.cfg"); });

ASSERT_THAT(configFile.loaded(), IsTrue());
EXPECT_THAT(configFile.getVarPtr("CfgWithInclude"), NotNull());
EXPECT_THAT(configFile.getVar("CfgWithInclude").asString(0), StrEq("ok"));
EXPECT_THAT(configFile.getVarPtr("IncludedCfg"), NotNull());
EXPECT_THAT(configFile.getVar("IncludedCfg").asString(0), StrEq("ok"));
}

TEST_F(CUTMiscConfigFileTest, configWithOptional)
{
NLMISC::CConfigFile configFile;

ASSERT_NO_THROW({ configFile.load(NEL_UNIT_BASE "ut_misc_files/cfg_with_optional.cfg"); });

ASSERT_THAT(configFile.loaded(), IsTrue());
EXPECT_THAT(configFile.getVarPtr("CfgWithInclude"), NotNull());
EXPECT_THAT(configFile.getVar("CfgWithInclude").asString(0), StrEq("ok"));
EXPECT_THAT(configFile.getVarPtr("IncludedCfg"), NotNull());
EXPECT_THAT(configFile.getVar("IncludedCfg").asString(0), StrEq("ok"));
}

TEST_F(CUTMiscConfigFileTest, configWithDefine)
{
NLMISC::CConfigFile configFile;

ASSERT_NO_THROW({ configFile.load(NEL_UNIT_BASE "ut_misc_files/cfg_with_define.cfg"); });

ASSERT_THAT(configFile.loaded(), IsTrue());
EXPECT_THAT(configFile.getVarPtr("CfgReadableVar"), NotNull());
EXPECT_THAT(configFile.getVarPtr("CfgNotToBeFound"), IsNull());
EXPECT_THAT(configFile.getVarPtr("CfgInvisible"), IsNull());
EXPECT_THAT(configFile.getVarPtr("CfgMustExist"), NotNull());
}

TEST_F(CUTMiscConfigFileTest, configWithBadTest)
{
NLMISC::CLightMemDisplayer warnings;
NLMISC::CLog logger;
logger.addDisplayer(&warnings);
NLMISC::CNLWarningOverride override(&logger);

NLMISC::CConfigFile configFile;

string fullName = NLMISC::CPath::getFullPath(NEL_UNIT_BASE "ut_misc_files/cfg_with_bad_test.cfg", false);

ASSERT_NO_THROW({ configFile.load(fullName); });

EXPECT_THAT(configFile.getVarPtr("ASimpleVar"), NotNull());

auto &warningLogs = warnings.lockStrings();
EXPECT_THAT(warningLogs, Contains(StrEq(string("Preprocess: In file ") + fullName + "(6) : Error unrecognized preprocessor command\n")));
EXPECT_THAT(warningLogs, Contains(StrEq(string("Preprocess: In file ") + fullName + "(9) : Error found '#endif' without matching #if\n")));
EXPECT_THAT(warningLogs, Contains(StrEq(string("Preprocess: In file ") + fullName + "(12) : Error parsing include file command\n")));
EXPECT_THAT(warningLogs, Contains(StrEq(string("Preprocess: In file ") + fullName + "(13) : Error parsing include file command\n")));
EXPECT_THAT(warningLogs, Contains(StrEq(string("Preprocess: In file ") + fullName + "(14) : Error parsing optional file command\n")));
EXPECT_THAT(warningLogs, Contains(StrEq(string("Preprocess: In file ") + fullName + "(15) : Error parsing optional file command\n")));
EXPECT_THAT(warningLogs, Contains(StrEq(string("Preprocess: In file ") + fullName + "(16) : Error parsing #define command\n")));
EXPECT_THAT(warningLogs, Contains(StrEq(string("Preprocess: In file ") + fullName + "(17) : Error parsing #ifdef command\n")));
EXPECT_THAT(warningLogs, Contains(StartsWith("Preprocess: Missing 1 closing #endif after parsing")));
}

TEST_F(CUTMiscConfigFileTest, configIncludeAndOptional)
{
NLMISC::CLightMemDisplayer warnings;
NLMISC::CLog logger;
logger.addDisplayer(&warnings);
NLMISC::CNLWarningOverride override(&logger);

NLMISC::CConfigFile configFile;

string fullName = NLMISC::CPath::getFullPath(NEL_UNIT_BASE "ut_misc_files/cfg_with_include_and_optional.cfg", false);

ASSERT_NO_THROW({ configFile.load(fullName); });

auto &warningLogs = warnings.lockStrings();
EXPECT_THAT(warningLogs, Contains(StrEq(string("Preprocess: In file ") + fullName + "(2) : Cannot include file 'a_missing_file.cfg'\n")));
}

TEST_F(CUTMiscConfigFileTest, reportErrorInSubFiles)
{
NLMISC::CLightMemDisplayer warnings;
NLMISC::CLog logger;
logger.addDisplayer(&warnings);
NLMISC::CNLWarningOverride override(&logger);

NLMISC::CConfigFile configFile;

string fullName = NLMISC::CPath::getFullPath(NEL_UNIT_BASE "ut_misc_files/cfg_with_error_main.cfg", false);
string subfullName = NLMISC::CPath::getFullPath(NEL_UNIT_BASE "ut_misc_files/cfg_with_error.cfg", false);

EXPECT_THROW({ configFile.load(fullName); }, NLMISC::EParseError);

// check that we have error report with correct filename and line number
auto &warningLogs = warnings.lockStrings();
EXPECT_THAT(warningLogs, Contains(StrEq(string("CF: Parsing error in file ") + subfullName + " line 18, look in 'debug_cfg_with_error_main.cfg' for a preprocessed version of the config file\n")));
}

0 comments on commit 5c94f27

Please sign in to comment.