diff -r deecbb8ad448 code/CMakeLists.txt --- a/code/CMakeLists.txt Thu Dec 02 12:52:22 2010 +0200 +++ b/code/CMakeLists.txt Fri Dec 03 03:17:09 2010 +0200 @@ -183,17 +183,19 @@ IF(BUILD_DOCUMENTATION) # a final Doxyfile CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/doc/Doxyfile.cmake.in ${CMAKE_BINARY_DIR}/doc/Doxyfile) ADD_CUSTOM_TARGET(DoxygenDoc ${DOXYGEN} ${CMAKE_BINARY_DIR}/doc/Doxyfile) ENDIF(BUILD_DOCUMENTATION) IF(WITH_NEL_TESTS) ENABLE_TESTING() - ADD_TEST(nel_unit_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nel_unit_test --html) + ADD_TEST(nel_ligo_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nel_ligo_test --html) + ADD_TEST(nel_misc_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nel_misc_test --html) + ADD_TEST(nel_net_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nel_net_test --html) IF(BUILD_DASHBOARD) INCLUDE(Dart) SET(SVNCOMMAND svn) SET(SVNSOURCEDIR http://dev.ryzom.com/svn/trunk/nel) SET(GENERATELOGS svn2cl) ENDIF(BUILD_DASHBOARD) ENDIF(WITH_NEL_TESTS) diff -r deecbb8ad448 code/nel/tools/CMakeLists.txt --- a/code/nel/tools/CMakeLists.txt Thu Dec 02 12:52:22 2010 +0200 +++ b/code/nel/tools/CMakeLists.txt Fri Dec 03 03:17:09 2010 +0200 @@ -17,12 +17,15 @@ IF(WITH_GEORGES) ADD_SUBDIRECTORY(georges) ENDIF(WITH_GEORGES) IF(WITH_SOUND) ADD_SUBDIRECTORY(sound) ENDIF(WITH_SOUND) IF(WITH_NEL_TESTS) - ADD_SUBDIRECTORY(nel_unit_test) +# ADD_SUBDIRECTORY(nel_unit_test) + ADD_SUBDIRECTORY(nel_misc_test) + ADD_SUBDIRECTORY(nel_net_test) + ADD_SUBDIRECTORY(nel_ligo_test) ENDIF(WITH_NEL_TESTS) #build_gamedata diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/#CMakeLists.txt# --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/#CMakeLists.txt# Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,13 @@ +FILE(GLOB SRC *.cpp *.h) + +ADD_EXECUTABLE(nel_ligo_test nel_ligo_test.cpp ut_ligo.h ut_ligo_primitive.h) + +INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${CPPTEST_INCLUDE_DIR}) + +TARGET_LINK_LIBRARIES(nel_ligo_test ${CPPTEST_LIBRARIES} nelligo) +NL_DEFAULT_PROPS(nel_ligo_test "Ligo Unit Tests") +NL_ADD_RUNTIME_FLAGS(nel_ligo_test) + +ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} -DNEL_UNIT_LIGO_BASE="${PROJECT_SOURCE_DIR}/tools/nel_ligo_test/") + +INSTALL(TARGETS nel_ligo_test RUNTIME DESTINATION bin) diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/CMakeLists.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/CMakeLists.txt Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,13 @@ +FILE(GLOB SRC *.cpp *.h) + +ADD_EXECUTABLE(nel_ligo_test ${SRC}) + +INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${CPPTEST_INCLUDE_DIR}) + +TARGET_LINK_LIBRARIES(nel_ligo_test ${CPPTEST_LIBRARIES} nelligo) +NL_DEFAULT_PROPS(nel_ligo_test "Ligo Unit Tests") +NL_ADD_RUNTIME_FLAGS(nel_ligo_test) + +ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} -DNEL_UNIT_LIGO_BASE="${PROJECT_SOURCE_DIR}/tools/nel_ligo_test/") + +INSTALL(TARGETS nel_ligo_test RUNTIME DESTINATION bin) diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/__copy_file_dst.foo Binary file code/nel/tools/nel_ligo_test/__copy_file_dst.foo has changed diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/__ligo_class.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/__ligo_class.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/__test_prim.primitive --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/__test_prim.primitive Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,27 @@ + + + + + + + class + test + + + name + test_root + + + + + class + alias + + + name + alias + + + + + diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/debug_cfg_with_error_main.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/debug_cfg_with_error_main.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,41 @@ +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 1 +// This config file include the config file with error then generate an error +// WARNING : is you add lines, update the code in the test + + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 1 +// In this cfg, we introduce an error in a line after define and if clause + + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 5 + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 7 + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 9 + // nothing + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 13 +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 15 + + +// Here is the offending line, at line 18 +ABadVar iable = "foo"; + +// Some additionnal garbase lines + +AGoodVar = "bar"; +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 6 + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 8 +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 9 + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 11 + // nothing + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 15 +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 17 + + +// Some additionnal garbase lines + +AGoodVar = "bar"; diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/nel_ligo_test.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/nel_ligo_test.cpp Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,142 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include + +#include +#include + +#include + +using namespace std; + +#ifdef NL_OS_WINDOWS +# define NEL_UNIT_DATA "" +#endif + +#include "ut_ligo.h" +// Add a line here when adding a new test MODULE + +#ifdef _MSC_VER + +/** A special stream buffer that output in the 'output debug string' feature of windows. + */ +class CDebugOutput : public streambuf +{ + int_type overflow(int_type c) + { + string str(pbase(), pptr()); + + if (c != traits_type::eof()) + str += c; + OutputDebugString(str.c_str() ); + + return c; + } +}; +// The instance of the streambug +ostream msvDebug(new CDebugOutput); + +#endif + +static void usage() +{ + cout << "usage: mytest [MODE]\n" + << "where MODE may be one of:\n" + << " --compiler\n" + << " --html\n" + << " --text-terse (default)\n" + << " --text-verbose\n"; + exit(0); +} + +static auto_ptr cmdline(int argc, char* argv[]) +{ + if (argc > 2) + usage(); // will not return + + Test::Output* output = 0; + + if (argc == 1) + output = new Test::TextOutput(Test::TextOutput::Verbose); + else + { + const char* arg = argv[1]; + if (strcmp(arg, "--compiler") == 0) + { +#ifdef _MSC_VER + output = new Test::CompilerOutput(Test::CompilerOutput::MSVC, msvDebug); +#elif defined(__GNUC__) + output = new Test::CompilerOutput(Test::CompilerOutput::GCC); +#else + output = new Test::CompilerOutput; +#endif + } + else if (strcmp(arg, "--html") == 0) + output = new Test::HtmlOutput; + else if (strcmp(arg, "--text-terse") == 0) + output = new Test::TextOutput(Test::TextOutput::Terse); + else if (strcmp(arg, "--text-verbose") == 0) + output = new Test::TextOutput(Test::TextOutput::Verbose); + else + { + cout << "invalid commandline argument: " << arg << endl; + usage(); // will not return + } + } + + return auto_ptr(output); +} + +// Main test program +// +int main(int argc, char *argv[]) +{ + static const char *outputFileName = "result.html"; + + // init Nel context + new NLMISC::CApplicationContext; + + bool noerrors = false; + + try + { + Test::Suite ts; + + ts.add(auto_ptr(new CUTLigo)); + // Add a line here when adding a new test MODULE + + auto_ptr output(cmdline(argc, argv)); + noerrors = ts.run(*output); + + Test::HtmlOutput* const html = dynamic_cast(output.get()); + if (html) + { + std::ofstream fout(outputFileName); + html->generate(fout, true, "NeLTest"); + } + } + catch (...) + { + cout << "unexpected exception encountered"; + return EXIT_FAILURE; + } + if(noerrors) + nlinfo("No errors during ligo unit testing"); + else + nlwarning("Errors during ligo unit testing"); + return noerrors?EXIT_SUCCESS:EXIT_FAILURE; +} diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/nel_ligo_test.sln --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/nel_ligo_test.sln Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,60 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nel_unit_test", "nel_unit_test.vcproj", "{F89D1853-2E47-4CE5-8EC8-188A805887EE}" + ProjectSection(ProjectDependencies) = postProject + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516} = {44B21233-EFCC-4825-B5E5-3A3BD6CC5516} + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9} = {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9} + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C} = {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "misc", "..\..\src\misc.vcproj", "{44B21233-EFCC-4825-B5E5-3A3BD6CC5516}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "net", "..\..\src\net.vcproj", "{67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ligo", "..\..\src\ligo.vcproj", "{1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Debug|Win32.ActiveCfg = Debug|Win32 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Debug|Win32.Build.0 = Debug|Win32 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Debug|x64.ActiveCfg = Debug|x64 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Debug|x64.Build.0 = Debug|x64 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Release|Win32.ActiveCfg = Release|Win32 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Release|Win32.Build.0 = Release|Win32 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Release|x64.ActiveCfg = Release|x64 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Release|x64.Build.0 = Release|x64 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Debug|Win32.ActiveCfg = Debug|Win32 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Debug|Win32.Build.0 = Debug|Win32 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Debug|x64.ActiveCfg = Debug|x64 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Debug|x64.Build.0 = Debug|x64 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Release|Win32.ActiveCfg = Release|Win32 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Release|Win32.Build.0 = Release|Win32 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Release|x64.ActiveCfg = Release|x64 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Release|x64.Build.0 = Release|x64 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Debug|Win32.ActiveCfg = Debug|Win32 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Debug|Win32.Build.0 = Debug|Win32 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Debug|x64.ActiveCfg = Debug|x64 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Debug|x64.Build.0 = Debug|x64 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Release|Win32.ActiveCfg = Release|Win32 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Release|Win32.Build.0 = Release|Win32 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Release|x64.ActiveCfg = Release|x64 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Release|x64.Build.0 = Release|x64 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Debug|Win32.ActiveCfg = Debug|Win32 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Debug|Win32.Build.0 = Debug|Win32 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Debug|x64.ActiveCfg = Debug|x64 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Debug|x64.Build.0 = Debug|x64 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Release|Win32.ActiveCfg = Release|Win32 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Release|Win32.Build.0 = Release|Win32 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Release|x64.ActiveCfg = Release|x64 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/nel_ligo_test.vcproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/nel_ligo_test.vcproj Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/result.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/result.html Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,820 @@ + + + + + + + NeLTest Unit Tests Results + + + + + + +

NeLTest Unit Tests Results

+ +
+Designed by CppTest +
+
+ +

Summary

+ + + + + + + + + + + + + +
TestsErrorsSuccessTime (s)
66198%35.265000
+
+ +

Test suites

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTestsErrorsSuccessTime (s)
CUTMiscCoTask20100%0.000000
CUTMiscCommand50100%0.015000
CUTMiscConfigFile60100%0.032000
CUTMiscDebug20100%0.000000
CUTMiscDynLibLoad 10100%0.000000
CUTMiscFile40100%0.859000
CUTMiscPackFile110100%0.016000
CUTMiscSingleton20100%0.000000
CUTMiscSString10100%0.000000
CUTMiscStream40100%0.000000
CUTMiscVariable 10100%0.000000
CUTMiscTypes110%0.000000
CUTNetLayer310100%2.312000
CUTNetMessage30100%0.000000
CUTNetModule210100%32.031000
CUTLigoPrimitive10100%0.000000
+
+ +

Suite: CUTMiscCoTask

+ + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
runTasks0true0.000000
tasksAndThreads0true0.000000
+

Back to top +

+

Suite: CUTMiscCommand

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
createOneInstance0true0.015000
createAnotherInstance0true0.000000
deleteOneInstance0true0.000000
derivedClass0true0.000000
derivedClassAndBaseCall0true0.000000
+

Back to top +

+

Suite: CUTMiscConfigFile

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
configWithInclude0true0.016000
configWithOptional0true0.000000
configWithDefine0true0.000000
configWithBadTest0true0.000000
configIncludeAndOptional0true0.000000
reportErrorInSubFiles0true0.016000
+

Back to top +

+

Suite: CUTMiscDebug

+ + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
testInstanceCounter0true0.000000
testInstanceCounterOutput0true0.000000
+

Back to top +

+

Suite: CUTMiscDynLibLoad

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
libraryNameDecoration0true0.000000
+

Back to top +

+

Suite: CUTMiscFile

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
copyOneBigFile0true0.187000
copyDifferentFileSize0true0.203000
moveOneBigFile0true0.203000
moveDifferentFileSize0true0.266000
+

Back to top +

+

Suite: CUTMiscPackFile

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
addBnp0true0.000000
loadFromBnp0true0.000000
addXmlpack0true0.016000
loadFromXmlpack0true0.000000
compressMemory0true0.000000
loadFromBnpCompressed0true0.000000
loadFromXmlpackCompressed0true0.000000
decompressMemory0true0.000000
loadFromBnpUncompressed0true0.000000
loadFromXmlpackUncompressed0true0.000000
loadXmlpackWithSameName0true0.000000
+

Back to top +

+

Suite: CUTMiscSingleton

+ + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
createSingleton0true0.000000
accessSingleton0true0.000000
+

Back to top +

+

Suite: CUTMiscSString

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
testStrtok0true0.000000
+

Back to top +

+

Suite: CUTMiscStream

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
constAndStream0true0.000000
memStreamSwap0true0.000000
copyOnWrite0true0.000000
preallocatedBitStream0true0.000000
+

Back to top +

+

Suite: CUTMiscVariable

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
declareVar0true0.000000
+

Back to top +

+

Suite: CUTMiscTypes

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
basicTypes1false0.000000
+

Back to top +

+

Suite: CUTNetLayer3

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
sendReceiveUpdate0true2.312000
+

Back to top +

+

Suite: CUTNetMessage

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
messageSwap0true0.000000
lockSubMEssage0true0.000000
lockSubMEssageWithLongName0true0.000000
+

Back to top +

+

Suite: CUTNetModule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
testModuleInitInfoParsing0true0.000000
testModuleInitInfoQuering0true0.000000
testModuleInitInfoBadParsing0true0.000000
localModuleFactory0true0.016000
failedInit0true0.000000
createLocalGateway0true0.000000
plugLocalGateway0true0.000000
gatewayTransportManagement0true1.219000
connectGateways0true0.828000
moduleDisclosure0true1.328000
moduleMessaging0true1.625000
localMessageQueing0true0.609000
uniqueNameGenerator0true0.000000
gwPlugUnplug0true0.000000
peerInvisible0true3.453000
firewalling0true3.438000
distanceAndConnectionLoop0true6.109000
securityPlugin0true5.094000
synchronousMessaging0true1.031000
layer3Autoconnect0true6.672000
interceptorTest0true0.609000
+

Back to top +

+

Suite: CUTLigoPrimitive

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
testAliasGenerator0true0.000000
+

Back to top +

+
+ +

Test results

+

CUTMiscTypes::basicTypes

+ + + + + + + + + + + + + +
TestCUTMiscTypes::basicTypes
Filed:\ryzom\nel\tools\nel_unit_test\ut_misc_types.h:31
Messagesizeof(time_t) == sizeof(uint32)
+

Back to CUTMiscTypes +

+
+ + +

+ + Valid XHTML 1.0 Strict + +

+ + diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/run_test.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/run_test.bat Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,2 @@ +nel_unit_test.exe --html +start result.html diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_ligo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_ligo.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,34 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_LIGO +#define UT_LIGO + +#include + +#include "ut_ligo_primitive.h" +// Add a line here when adding a new test CLASS + +struct CUTLigo : public Test::Suite +{ + CUTLigo() + { + add(auto_ptr(new CUTLigoPrimitive)); + // Add a line here when adding a new test CLASS + } +}; + +#endif diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_ligo_primitive.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_ligo_primitive.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,171 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_LIGO_PRIMITIVE +#define UT_LIGO_PRIMITIVE + +#include +#include + +class CUTLigoPrimitive : public Test::Suite +{ +public: + CUTLigoPrimitive() + { + TEST_ADD(CUTLigoPrimitive::testAliasGenerator) + } + +private: + + string _RestorePath; + string _WorkingPath; + string _RefPrimFileName; + void setup() + { + _RestorePath = NLMISC::CPath::getCurrentPath(); + NLMISC::CPath::setCurrentPath(_WorkingPath.c_str()); + + _RefPrimFileName = "__test_prim.primitive"; + + // register ligo class factory + NLLIGO::Register(); + + // create a primitive config file + nlinfo("Building a default ligo class file"); + + const char *CLASS_FILE_NAME = "__ligo_class.xml"; + + string classfile; + classfile = string() + + "\n" + + "\n" + + " \n" + + " \n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n" + + " \n" + + " \n" + + " \n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + FILE *fp = fopen(CLASS_FILE_NAME, "wt"); + nlassert(fp != NULL); + size_t s = fwrite(classfile.data(), 1, classfile.size(), fp); + nlassert(s == classfile.size()); + fclose(fp); + + // init ligo + NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig = &_LigoConfig; + _LigoConfig.readPrimitiveClass(CLASS_FILE_NAME, false); + + // create a reference primitive + if (NLMISC::CFile::isExists(_RefPrimFileName)) + { + NLMISC::CFile::deleteFile(_RefPrimFileName); + } + NLLIGO::CPrimitives primDoc; + nlassert(primDoc.RootNode != NULL); + + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = &primDoc; + + NLLIGO::IPrimitive *p = dynamic_cast (NLMISC::CClassRegistry::create ("CPrimNode")); + p->addPropertyByName("class", new NLLIGO::CPropertyString("test")); + p->addPropertyByName("name", new NLLIGO::CPropertyString("test_root")); + primDoc.RootNode->insertChild(p); + + NLLIGO::CPrimAlias *pa = dynamic_cast (NLMISC::CClassRegistry::create ("CPrimAlias")); + pa->addPropertyByName("class", new NLLIGO::CPropertyString("alias")); + pa->addPropertyByName("name", new NLLIGO::CPropertyString("alias")); + p->insertChild(pa); + + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; + + // save the file + saveXmlPrimitiveFile(primDoc, _RefPrimFileName); + } + + void tear_down() + { + NLMISC::CPath::setCurrentPath(_RestorePath.c_str()); + } + + void testAliasGenerator() + { + //Known bug : is we load/save a primitive and replacing a primitive node with itself (conserving the alias), the + // 'last generated alias' counter is incremented. + uint32 lastGeneratedAlias; + + // First, load then save the doc + { + NLLIGO::CPrimitives primDoc; + + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = &primDoc; + loadXmlPrimitiveFile(primDoc, _RefPrimFileName, _LigoConfig); + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; + + lastGeneratedAlias = primDoc.getLastGeneratedAlias(); + + // get a copy of the primitive + NLLIGO::IPrimitive *prim = NULL; + NLLIGO::IPrimitive *primCopy = NULL; + TEST_ASSERT(primDoc.RootNode->getChild(prim, 0)); + if (prim) + { + primCopy = prim->copy(); + TEST_ASSERT(primCopy != NULL); + if (primCopy) + { + // remove the primitive + primDoc.RootNode->removeChild(prim); + + // insert the copy + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = &primDoc; + primDoc.RootNode->insertChild(primCopy); + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; + } + } + + // save the file + saveXmlPrimitiveFile(primDoc, _RefPrimFileName); + } + + // second, reload the file and check the last generated alias + { + NLLIGO::CPrimitives primDoc; + + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = &primDoc; + loadXmlPrimitiveFile(primDoc, _RefPrimFileName, _LigoConfig); + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; + + TEST_ASSERT(lastGeneratedAlias == primDoc.getLastGeneratedAlias()); + } + } + + NLLIGO::CLigoConfig _LigoConfig; +}; + +#endif diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/cfg_with_bad_test.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/cfg_with_bad_test.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,23 @@ + +// insert a var just to prove we can't read it +ASimpleVar = "hello"; + +// A bad preprocessor command +# UnknowCommand + +// a closing endif without matching ifdef +#endif + +// a series of invalid command +#include blop // missing quote +#include "blop // missing closing quote +#optional blop +#optional "blop +#define *1234 // invalid label +#ifdef *1234 // still invalid label + + +// a opening ifdef not closed +#ifdef FOO + +// NB : do not close the #ifdef \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/cfg_with_define.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/cfg_with_define.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,34 @@ + +#define FOO +# define BAR + +#ifdef FOOBAR + this is an invalid content that should be ignored by parser +#endif + + # ifdef FOOBAR + this is another invalid content that should be + ignored by parser with some free alignement + +CfgNotToBeFound="iCan'tBeThere"; + # endif + +#ifdef FOO + // A simple var in a valid bloc +CfgReadableVar="You can see me"; +#endif + +// Multi test imbrication +#ifdef FOO // ok +# ifdef FOOBAR // not ok +# ifdef BAR // ok, but in a not ok scope +CfgInvisible = "You can't see me !"; +# endif +# endif +#endif + +#ifndef FOOBAR + // this one must exist + CfgMustExist="hello world"; +#endif + diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/cfg_with_error.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/cfg_with_error.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,22 @@ +// In this cfg, we introduce an error in a line after define and if clause + + +#define FOO + +#define BAR + +#ifdef FOO + // nothing +#endif + +#ifndef BAR + // nothing +#endif + + +// Here is the offending line, at line 18 +ABadVar iable = "foo"; + +// Some additionnal garbase lines + +AGoodVar = "bar"; diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/cfg_with_error_main.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/cfg_with_error_main.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,21 @@ +// This config file include the config file with error then generate an error +// WARNING : is you add lines, update the code in the test + + +#include "cfg_with_error.cfg" + +#define FOO +#define BAR + +#ifdef FOO + // nothing +#endif + +#ifndef BAR + // nothing +#endif + + +// Some additionnal garbase lines + +AGoodVar = "bar"; diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/cfg_with_include.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/cfg_with_include.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,10 @@ + + +#include "included_cfg.cfg" + +// #include "not_found_file.cfg" this include should not work +//#include "not_found_file.cfg" this include should not work +// not a valid include #include "not_found_file.cfg + + +CfgWithInclude = "ok"; diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/cfg_with_include_and_optional.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/cfg_with_include_and_optional.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,5 @@ +// include of a missing file, should generate a warning +#include "a_missing_file.cfg" + +// optional include a a missing file, just issue an info log +#optional "a_missing_file.cfg" diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/cfg_with_optional.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/cfg_with_optional.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,10 @@ + + +#optional "included_cfg.cfg" + +// #include "not_found_file.cfg" this include should not work +//#include "not_found_file.cfg" this include should not work +// not a valid include #include "not_found_file.cfg + + +CfgWithInclude = "ok"; diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/file1_in_bnp.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/file1_in_bnp.txt Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ +The content of the first file \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/file2_in_bnp.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/file2_in_bnp.txt Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ +Another content but for the second file \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/files.bnp Binary file code/nel/tools/nel_ligo_test/ut_misc_files/files.bnp has changed diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/files.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/files.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,11 @@ + + +The content of the first file + + +Another content but for the second file + + +The content of the first fileAnother content but for the second file + + diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/.xml_pack_index --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/.xml_pack_index Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,2 @@ +file1_in_sub_1.xml +file2_in_sub_1.xml diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/file1_in_sub_1.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/file1_in_sub_1.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/file2_in_sub_1.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/file2_in_sub_1.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/samename.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/samename.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,8 @@ + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/.xml_pack_index --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/.xml_pack_index Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,2 @@ +file1_in_sub_2.xml +file2_in_sub_2.xml diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/file1_in_sub_2.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/file1_in_sub_2.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/file2_in_sub_2.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/file2_in_sub_2.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/samename.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/samename.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,8 @@ + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/included_cfg.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/included_cfg.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,3 @@ + +IncludedCfg = "ok"; + diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/xml_files/file1_in_xml_pack.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/xml_files/file1_in_xml_pack.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/xml_files/file2_in_xml_pack.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/xml_files/file2_in_xml_pack.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/xml_files/same_subfolder_1/samename/samename.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/xml_files/same_subfolder_1/samename/samename.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,8 @@ + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/xml_files/same_subfolder_2/samename/samename.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/xml_files/same_subfolder_2/samename/samename.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,8 @@ + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_ligo_test/ut_misc_files/xml_files/xml_files.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_ligo_test/ut_misc_files/xml_files/xml_files.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,8 @@ + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_misc_test/CMakeLists.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/CMakeLists.txt Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,13 @@ +FILE(GLOB SRC *.cpp *.h) + +ADD_EXECUTABLE(nel_misc_test ${SRC}) + +INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${CPPTEST_INCLUDE_DIR}) + +TARGET_LINK_LIBRARIES(nel_misc_test ${CPPTEST_LIBRARIES} nelmisc) +NL_DEFAULT_PROPS(nel_misc_test "Misc Unit Tests") +NL_ADD_RUNTIME_FLAGS(nel_misc_test) + +ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} -DNEL_UNIT_BASE="${PROJECT_SOURCE_DIR}/tools/nel_misc_test/") + +INSTALL(TARGETS nel_misc_test RUNTIME DESTINATION bin) diff -r deecbb8ad448 code/nel/tools/nel_misc_test/__copy_file_dst.foo Binary file code/nel/tools/nel_misc_test/__copy_file_dst.foo has changed diff -r deecbb8ad448 code/nel/tools/nel_misc_test/__ligo_class.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/__ligo_class.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_misc_test/__test_prim.primitive --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/__test_prim.primitive Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,27 @@ + + + + + + + class + test + + + name + test_root + + + + + class + alias + + + name + alias + + + + + diff -r deecbb8ad448 code/nel/tools/nel_misc_test/debug_cfg_with_error_main.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/debug_cfg_with_error_main.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,41 @@ +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 1 +// This config file include the config file with error then generate an error +// WARNING : is you add lines, update the code in the test + + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 1 +// In this cfg, we introduce an error in a line after define and if clause + + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 5 + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 7 + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 9 + // nothing + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 13 +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 15 + + +// Here is the offending line, at line 18 +ABadVar iable = "foo"; + +// Some additionnal garbase lines + +AGoodVar = "bar"; +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 6 + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 8 +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 9 + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 11 + // nothing + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 15 +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 17 + + +// Some additionnal garbase lines + +AGoodVar = "bar"; diff -r deecbb8ad448 code/nel/tools/nel_misc_test/nel_misc_test.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/nel_misc_test.cpp Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,146 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include + +#include +#include + +#include + +using namespace std; + +#ifdef NL_OS_WINDOWS +# define NEL_UNIT_DATA "" +#endif + +#include "ut_misc.h" +//#include "ut_net.h" +//#include "ut_ligo.h" +// Add a line here when adding a new test MODULE + +#ifdef _MSC_VER + +/** A special stream buffer that output in the 'output debug string' feature of windows. + */ +class CDebugOutput : public streambuf +{ + int_type overflow(int_type c) + { + string str(pbase(), pptr()); + + if (c != traits_type::eof()) + str += c; + OutputDebugString(str.c_str() ); + + return c; + } +}; +// The instance of the streambug +ostream msvDebug(new CDebugOutput); + +#endif + +static void usage() +{ + cout << "usage: mytest [MODE]\n" + << "where MODE may be one of:\n" + << " --compiler\n" + << " --html\n" + << " --text-terse (default)\n" + << " --text-verbose\n"; + exit(0); +} + +static auto_ptr cmdline(int argc, char* argv[]) +{ + if (argc > 2) + usage(); // will not return + + Test::Output* output = 0; + + if (argc == 1) + output = new Test::TextOutput(Test::TextOutput::Verbose); + else + { + const char* arg = argv[1]; + if (strcmp(arg, "--compiler") == 0) + { +#ifdef _MSC_VER + output = new Test::CompilerOutput(Test::CompilerOutput::MSVC, msvDebug); +#elif defined(__GNUC__) + output = new Test::CompilerOutput(Test::CompilerOutput::GCC); +#else + output = new Test::CompilerOutput; +#endif + } + else if (strcmp(arg, "--html") == 0) + output = new Test::HtmlOutput; + else if (strcmp(arg, "--text-terse") == 0) + output = new Test::TextOutput(Test::TextOutput::Terse); + else if (strcmp(arg, "--text-verbose") == 0) + output = new Test::TextOutput(Test::TextOutput::Verbose); + else + { + cout << "invalid commandline argument: " << arg << endl; + usage(); // will not return + } + } + + return auto_ptr(output); +} + +// Main test program +// +int main(int argc, char *argv[]) +{ + static const char *outputFileName = "result.html"; + + // init Nel context + new NLMISC::CApplicationContext; + + bool noerrors = false; + + try + { + Test::Suite ts; + + ts.add(auto_ptr(new CUTMisc)); + // ts.add(auto_ptr(new CUTNet)); + //ts.add(auto_ptr(new CUTLigo)); + // Add a line here when adding a new test MODULE + + auto_ptr output(cmdline(argc, argv)); + noerrors = ts.run(*output); + + Test::HtmlOutput* const html = dynamic_cast(output.get()); + if (html) + { + std::ofstream fout(outputFileName); + html->generate(fout, true, "NeLTest"); + } + } + catch (...) + { + cout << "unexpected exception encountered"; + return EXIT_FAILURE; + } + if(noerrors) + nlinfo("No errors during unit testing"); + else + nlwarning("Errors during unit testing"); + return noerrors?EXIT_SUCCESS:EXIT_FAILURE; +} diff -r deecbb8ad448 code/nel/tools/nel_misc_test/nel_misc_test.sln --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/nel_misc_test.sln Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,60 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nel_unit_test", "nel_unit_test.vcproj", "{F89D1853-2E47-4CE5-8EC8-188A805887EE}" + ProjectSection(ProjectDependencies) = postProject + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516} = {44B21233-EFCC-4825-B5E5-3A3BD6CC5516} + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9} = {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9} + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C} = {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "misc", "..\..\src\misc.vcproj", "{44B21233-EFCC-4825-B5E5-3A3BD6CC5516}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "net", "..\..\src\net.vcproj", "{67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ligo", "..\..\src\ligo.vcproj", "{1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Debug|Win32.ActiveCfg = Debug|Win32 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Debug|Win32.Build.0 = Debug|Win32 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Debug|x64.ActiveCfg = Debug|x64 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Debug|x64.Build.0 = Debug|x64 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Release|Win32.ActiveCfg = Release|Win32 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Release|Win32.Build.0 = Release|Win32 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Release|x64.ActiveCfg = Release|x64 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Release|x64.Build.0 = Release|x64 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Debug|Win32.ActiveCfg = Debug|Win32 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Debug|Win32.Build.0 = Debug|Win32 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Debug|x64.ActiveCfg = Debug|x64 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Debug|x64.Build.0 = Debug|x64 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Release|Win32.ActiveCfg = Release|Win32 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Release|Win32.Build.0 = Release|Win32 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Release|x64.ActiveCfg = Release|x64 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Release|x64.Build.0 = Release|x64 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Debug|Win32.ActiveCfg = Debug|Win32 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Debug|Win32.Build.0 = Debug|Win32 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Debug|x64.ActiveCfg = Debug|x64 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Debug|x64.Build.0 = Debug|x64 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Release|Win32.ActiveCfg = Release|Win32 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Release|Win32.Build.0 = Release|Win32 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Release|x64.ActiveCfg = Release|x64 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Release|x64.Build.0 = Release|x64 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Debug|Win32.ActiveCfg = Debug|Win32 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Debug|Win32.Build.0 = Debug|Win32 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Debug|x64.ActiveCfg = Debug|x64 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Debug|x64.Build.0 = Debug|x64 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Release|Win32.ActiveCfg = Release|Win32 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Release|Win32.Build.0 = Release|Win32 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Release|x64.ActiveCfg = Release|x64 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff -r deecbb8ad448 code/nel/tools/nel_misc_test/nel_misc_test.vcproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/nel_misc_test.vcproj Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_misc_test/result.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/result.html Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,820 @@ + + + + + + + NeLTest Unit Tests Results + + + + + + +

NeLTest Unit Tests Results

+ +
+Designed by CppTest +
+
+ +

Summary

+ + + + + + + + + + + + + +
TestsErrorsSuccessTime (s)
66198%35.265000
+
+ +

Test suites

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTestsErrorsSuccessTime (s)
CUTMiscCoTask20100%0.000000
CUTMiscCommand50100%0.015000
CUTMiscConfigFile60100%0.032000
CUTMiscDebug20100%0.000000
CUTMiscDynLibLoad 10100%0.000000
CUTMiscFile40100%0.859000
CUTMiscPackFile110100%0.016000
CUTMiscSingleton20100%0.000000
CUTMiscSString10100%0.000000
CUTMiscStream40100%0.000000
CUTMiscVariable 10100%0.000000
CUTMiscTypes110%0.000000
CUTNetLayer310100%2.312000
CUTNetMessage30100%0.000000
CUTNetModule210100%32.031000
CUTLigoPrimitive10100%0.000000
+
+ +

Suite: CUTMiscCoTask

+ + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
runTasks0true0.000000
tasksAndThreads0true0.000000
+

Back to top +

+

Suite: CUTMiscCommand

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
createOneInstance0true0.015000
createAnotherInstance0true0.000000
deleteOneInstance0true0.000000
derivedClass0true0.000000
derivedClassAndBaseCall0true0.000000
+

Back to top +

+

Suite: CUTMiscConfigFile

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
configWithInclude0true0.016000
configWithOptional0true0.000000
configWithDefine0true0.000000
configWithBadTest0true0.000000
configIncludeAndOptional0true0.000000
reportErrorInSubFiles0true0.016000
+

Back to top +

+

Suite: CUTMiscDebug

+ + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
testInstanceCounter0true0.000000
testInstanceCounterOutput0true0.000000
+

Back to top +

+

Suite: CUTMiscDynLibLoad

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
libraryNameDecoration0true0.000000
+

Back to top +

+

Suite: CUTMiscFile

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
copyOneBigFile0true0.187000
copyDifferentFileSize0true0.203000
moveOneBigFile0true0.203000
moveDifferentFileSize0true0.266000
+

Back to top +

+

Suite: CUTMiscPackFile

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
addBnp0true0.000000
loadFromBnp0true0.000000
addXmlpack0true0.016000
loadFromXmlpack0true0.000000
compressMemory0true0.000000
loadFromBnpCompressed0true0.000000
loadFromXmlpackCompressed0true0.000000
decompressMemory0true0.000000
loadFromBnpUncompressed0true0.000000
loadFromXmlpackUncompressed0true0.000000
loadXmlpackWithSameName0true0.000000
+

Back to top +

+

Suite: CUTMiscSingleton

+ + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
createSingleton0true0.000000
accessSingleton0true0.000000
+

Back to top +

+

Suite: CUTMiscSString

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
testStrtok0true0.000000
+

Back to top +

+

Suite: CUTMiscStream

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
constAndStream0true0.000000
memStreamSwap0true0.000000
copyOnWrite0true0.000000
preallocatedBitStream0true0.000000
+

Back to top +

+

Suite: CUTMiscVariable

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
declareVar0true0.000000
+

Back to top +

+

Suite: CUTMiscTypes

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
basicTypes1false0.000000
+

Back to top +

+

Suite: CUTNetLayer3

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
sendReceiveUpdate0true2.312000
+

Back to top +

+

Suite: CUTNetMessage

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
messageSwap0true0.000000
lockSubMEssage0true0.000000
lockSubMEssageWithLongName0true0.000000
+

Back to top +

+

Suite: CUTNetModule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
testModuleInitInfoParsing0true0.000000
testModuleInitInfoQuering0true0.000000
testModuleInitInfoBadParsing0true0.000000
localModuleFactory0true0.016000
failedInit0true0.000000
createLocalGateway0true0.000000
plugLocalGateway0true0.000000
gatewayTransportManagement0true1.219000
connectGateways0true0.828000
moduleDisclosure0true1.328000
moduleMessaging0true1.625000
localMessageQueing0true0.609000
uniqueNameGenerator0true0.000000
gwPlugUnplug0true0.000000
peerInvisible0true3.453000
firewalling0true3.438000
distanceAndConnectionLoop0true6.109000
securityPlugin0true5.094000
synchronousMessaging0true1.031000
layer3Autoconnect0true6.672000
interceptorTest0true0.609000
+

Back to top +

+

Suite: CUTLigoPrimitive

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
testAliasGenerator0true0.000000
+

Back to top +

+
+ +

Test results

+

CUTMiscTypes::basicTypes

+ + + + + + + + + + + + + +
TestCUTMiscTypes::basicTypes
Filed:\ryzom\nel\tools\nel_unit_test\ut_misc_types.h:31
Messagesizeof(time_t) == sizeof(uint32)
+

Back to CUTMiscTypes +

+
+ + +

+ + Valid XHTML 1.0 Strict + +

+ + diff -r deecbb8ad448 code/nel/tools/nel_misc_test/run_test.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/run_test.bat Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,2 @@ +nel_unit_test.exe --html +start result.html diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,56 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_MISC +#define UT_MISC + +#include "ut_misc_co_task.h" +#include "ut_misc_command.h" +#include "ut_misc_config_file.h" +#include "ut_misc_debug.h" +#include "ut_misc_dynlibload.h" +#include "ut_misc_file.h" +#include "ut_misc_pack_file.h" +#include "ut_misc_singleton.h" +#include "ut_misc_sstring.h" +#include "ut_misc_stream.h" +#include "ut_misc_variable.h" +#include "ut_misc_types.h" +#include "ut_misc_string_common.h" +// Add a line here when adding a new test CLASS + +struct CUTMisc : public Test::Suite +{ + CUTMisc() + { + add(auto_ptr(new CUTMiscCoTask)); + add(auto_ptr(new CUTMiscCommand)); + add(auto_ptr(new CUTMiscConfigFile)); + add(auto_ptr(new CUTMiscDebug)); + add(auto_ptr(new CUTMiscDynLibLoad)); + add(auto_ptr(new CUTMiscFile)); + add(auto_ptr(new CUTMiscPackFile)); + add(auto_ptr(new CUTMiscSingleton)); + add(auto_ptr(new CUTMiscSString)); + add(auto_ptr(new CUTMiscStream)); + add(auto_ptr(new CUTMiscVariable)); + add(auto_ptr(new CUTMiscTypes)); + add(auto_ptr(new CUTMiscStringCommon)); + // Add a line here when adding a new test CLASS + } +}; + +#endif diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_co_task.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_co_task.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,244 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_MISC_CO_TASK +#define UT_MISC_CO_TASK + +#include +#include + +const char *referenceResult[] = +{ + "Task1 : 0", + "Task2 : 0", + "Main : 0", + + "Task1 : 1", + "Task2 : 1", + "Main : 1", + + "Task1 : 2", + "Task2 : 2", + + "Task1 : 3", + "Task2 : 3", + + "Task1 : 4", + "Task2 : 4", + + "Task2 : 5", + + "Task2 : 6", +}; + +const char *referenceResultThread1[] = +{ + "Task1 : 0", + "Thread : 0", + + "Task1 : 1", + "Thread : 1", + + "Task1 : 2", + "Thread : 2", + + "Task1 : 3", + "Thread : 3", + + "Task1 : 4", + "Thread : 4", +}; + +const char *referenceResultThread2[] = +{ + "Task2 : 0", + "Main : 0", + + "Task2 : 1", + "Main : 1", + + "Task2 : 2", + + "Task2 : 3", + + "Task2 : 4", +}; + +vector result; +vector result2; + +// a simple task +class CTask1 : public NLMISC::CCoTask +{ + vector &Output; +public: + CTask1(vector &output = result) + : Output(output) + {} + + void run() + { + for (uint i=0; i<5; ++i) + { + string s = NLMISC::toString("Task1 : %u", i); + Output.push_back(s); + yield(); + } + } +}; + +// another simple task +class CTask2 : public NLMISC::CCoTask +{ + vector &Output; + +public: + CTask2(vector &output = result) + : Output(output) + {} + + void run() + { + for (uint i=0; i<7; ++i) + { + string s = NLMISC::toString("Task2 : %u", i); + Output.push_back(s); + yield(); + } + } +}; + +// a thread runnable class +class CTaskThread : public NLMISC::IRunnable +{ + void run() + { + CTask1 t1(result2); + + for (uint i=0; i<5; ++i) + { + t1.resume(); + string s = NLMISC::toString("Thread : %u", i); + result2.push_back(s); + NLMISC::nlSleep(0); + } + } +}; + +// Test suite for coroutine task +class CUTMiscCoTask: public Test::Suite +{ +public: + CUTMiscCoTask() + { + TEST_ADD(CUTMiscCoTask::runTasks); + TEST_ADD(CUTMiscCoTask::tasksAndThreads); + + } + + void tasksAndThreads() + { + // test running task in two separate thread (this stress the + // multithreading support of task). CoTask API ;ake use of + // thread local storage API to store by thread current task info. + + result.clear(); + result2.clear(); + + CTaskThread tt; + NLMISC::IThread *th = NLMISC::IThread::create(&tt); + + CTask2 t2; + + // start the thread + th->start(); + + for (uint i=0; i<2; ++i) + { + t2.resume(); + string s = NLMISC::toString("Main : %u", i); + result.push_back(s); + NLMISC::nlSleep(0); + } + + // wait task completion + t2.wait(); + + // wait thread completion + th->wait(); + + delete th; + + // test result + for (uint i=0; i +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_MISC_COMMAND +#define UT_MISC_COMMAND + +#include + +vector callList; + +class TTest : public NLMISC::ICommandsHandler +{ +protected: + std::string _Name; +public: + const std::string &getCommandHandlerName() const + { + return _Name; + } + + void setName(const std::string &name) + { + nlassert(_Name.empty()); + _Name = name; + + registerCommandsHandler(); + } + + NLMISC_COMMAND_HANDLER_TABLE_BEGIN(TTest) + NLMISC_COMMAND_HANDLER_ADD(TTest, theCommand1, "help", "args") + NLMISC_COMMAND_HANDLER_ADD(TTest, theCommand2, "other help", "other args") + NLMISC_COMMAND_HANDLER_TABLE_END + + + NLMISC_CLASS_COMMAND_DECL(theCommand1) + { + callList.push_back(_Name+".theCommand1"); + return true; + } + + NLMISC_CLASS_COMMAND_DECL(theCommand2) + { + callList.push_back(_Name+".theCommand2"); + return true; + } + +}; + +class TTestDerived : public TTest +{ +public: + NLMISC_COMMAND_HANDLER_TABLE_EXTEND_BEGIN(TTestDerived, TTest) + NLMISC_COMMAND_HANDLER_ADD(TTestDerived, derivedCommand, "help", "args") + NLMISC_COMMAND_HANDLER_ADD(TTestDerived, commandToOverride, "help", "args") + NLMISC_COMMAND_HANDLER_TABLE_END + + NLMISC_CLASS_COMMAND_DECL(derivedCommand) + { + callList.push_back(_Name+".derivedCommand"); + return true; + } + + NLMISC_CLASS_COMMAND_DECL(commandToOverride) + { + callList.push_back(_Name+".commandToOverride"); + return true; + } + +}; + +class TTestDerived2 : public TTestDerived +{ +public: + NLMISC_COMMAND_HANDLER_TABLE_EXTEND_BEGIN(TTestDerived2, TTestDerived) + NLMISC_COMMAND_HANDLER_ADD(TTestDerived2, derivedCommand2, "help", "args") + NLMISC_COMMAND_HANDLER_ADD(TTestDerived2, commandToOverride, "help", "args") + NLMISC_COMMAND_HANDLER_TABLE_END + + NLMISC_CLASS_COMMAND_DECL(derivedCommand2) + { + callList.push_back(_Name+".derivedCommand2"); + return true; + } + + NLMISC_CLASS_COMMAND_DECL(commandToOverride) + { + callList.push_back(_Name+".command Overidden"); + return true; + } + +}; + +class TTestDerived3 : public TTestDerived2 +{ + // empty class +}; + +class TTestDerived4 : public TTestDerived3 +{ +public: + NLMISC_COMMAND_HANDLER_TABLE_EXTEND_BEGIN(TTestDerived4, TTestDerived3) + NLMISC_COMMAND_HANDLER_ADD(TTestDerived4, derivedCommand4, "help", "args") + NLMISC_COMMAND_HANDLER_ADD(TTestDerived4, theCommand1, "help", "args") + NLMISC_COMMAND_HANDLER_TABLE_END + + NLMISC_CLASS_COMMAND_DECL(derivedCommand4) + { + callList.push_back(_Name+".derivedCommand4"); + return true; + } + + NLMISC_CLASS_COMMAND_DECL(theCommand1) + { + callList.push_back(_Name+".recallBase"); + NLMISC_CLASS_COMMAND_CALL_BASE(TTestDerived3, theCommand1); + return true; + } +}; + +class CUTMiscCommand : public Test::Suite +{ + TTest *t1; + TTest *t2; +public: + CUTMiscCommand() + { + TEST_ADD(CUTMiscCommand::createOneInstance); + TEST_ADD(CUTMiscCommand::createAnotherInstance); + TEST_ADD(CUTMiscCommand::deleteOneInstance); + TEST_ADD(CUTMiscCommand::derivedClass); + TEST_ADD(CUTMiscCommand::derivedClassAndBaseCall); + } + + void derivedClassAndBaseCall() + { + TTestDerived4 t4; + t4.setName("T4"); + + callList.clear(); + + NLMISC::ICommand::execute("T4.derivedCommand4", *NLMISC::InfoLog); + TEST_ASSERT(callList.size() == 1); + TEST_ASSERT(callList[0] == "T4.derivedCommand4"); + + NLMISC::ICommand::execute("T4.theCommand1", *NLMISC::InfoLog); + TEST_ASSERT(callList.size() == 3); + TEST_ASSERT(callList[1] == "T4.recallBase"); + TEST_ASSERT(callList[2] == "T4.theCommand1"); + } + + void derivedClass() + { + TTestDerived t1; + t1.setName("T1"); + TTestDerived2 t2; + t2.setName("T2"); + + callList.clear(); + + NLMISC::ICommand::execute("T1.theCommand1", *NLMISC::InfoLog); + TEST_ASSERT(callList.size() == 1); + TEST_ASSERT(callList[0] == "T1.theCommand1"); + + NLMISC::ICommand::execute("T1.derivedCommand", *NLMISC::InfoLog); + TEST_ASSERT(callList.size() == 2); + TEST_ASSERT(callList[1] == "T1.derivedCommand"); + + NLMISC::ICommand::execute("T1.commandToOverride", *NLMISC::InfoLog); + TEST_ASSERT(callList.size() == 3); + TEST_ASSERT(callList[2] == "T1.commandToOverride"); + + + NLMISC::ICommand::execute("T2.theCommand1", *NLMISC::InfoLog); + TEST_ASSERT(callList.size() == 4); + TEST_ASSERT(callList[3] == "T2.theCommand1"); + + NLMISC::ICommand::execute("T2.derivedCommand", *NLMISC::InfoLog); + TEST_ASSERT(callList.size() == 5); + TEST_ASSERT(callList[4] == "T2.derivedCommand"); + + NLMISC::ICommand::execute("T2.commandToOverride", *NLMISC::InfoLog); + TEST_ASSERT(callList.size() == 6); + TEST_ASSERT(callList[5] == "T2.command Overidden"); + } + + + void createOneInstance() + { + t1 = new TTest; + t1->setName("inst1"); + + TEST_ASSERT(callList.empty()); + + NLMISC::ICommand::execute("inst1.theCommand1", *NLMISC::InfoLog); + TEST_ASSERT(callList.size() == 1); + TEST_ASSERT(callList[0] == "inst1.theCommand1"); + + NLMISC::ICommand::execute("inst1.theCommand2", *NLMISC::InfoLog); + TEST_ASSERT(callList.size() == 2); + TEST_ASSERT(callList[0] == "inst1.theCommand1"); + TEST_ASSERT(callList[1] == "inst1.theCommand2"); + } + + void createAnotherInstance() + { + t2 = new TTest; + t2->setName("inst2"); + + TEST_ASSERT(callList.size() == 2); + + NLMISC::ICommand::execute("inst2.theCommand1", *NLMISC::InfoLog); + TEST_ASSERT(callList.size() == 3); + TEST_ASSERT(callList[0] == "inst1.theCommand1"); + TEST_ASSERT(callList[1] == "inst1.theCommand2"); + TEST_ASSERT(callList[2] == "inst2.theCommand1"); + + NLMISC::ICommand::execute("inst2.theCommand2", *NLMISC::InfoLog); + TEST_ASSERT(callList.size() == 4); + TEST_ASSERT(callList[0] == "inst1.theCommand1"); + TEST_ASSERT(callList[1] == "inst1.theCommand2"); + TEST_ASSERT(callList[2] == "inst2.theCommand1"); + TEST_ASSERT(callList[3] == "inst2.theCommand2"); + } + + void deleteOneInstance() + { + delete t1; + + NLMISC::ICommand::execute("inst1.theCommand2", *NLMISC::InfoLog); + TEST_ASSERT(callList.size() == 4); + TEST_ASSERT(callList[0] == "inst1.theCommand1"); + TEST_ASSERT(callList[1] == "inst1.theCommand2"); + TEST_ASSERT(callList[2] == "inst2.theCommand1"); + TEST_ASSERT(callList[3] == "inst2.theCommand2"); + + } + +}; + +#endif diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_config_file.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_config_file.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,180 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_MISC_CONFIG_FILE +#define UT_MISC_CONFIG_FILE + +#include + +#ifndef NEL_UNIT_BASE +#define NEL_UNIT_BASE "" +#endif // NEL_UNIT_BASE + +// Test suite for CConfigFile class +class CUTMiscConfigFile : public Test::Suite +{ + string _WorkingPath; + string _OldPath; +public: + CUTMiscConfigFile () + { + TEST_ADD(CUTMiscConfigFile::configWithInclude); + TEST_ADD(CUTMiscConfigFile::configWithOptional); + TEST_ADD(CUTMiscConfigFile::configWithDefine); + TEST_ADD(CUTMiscConfigFile::configWithBadTest); + TEST_ADD(CUTMiscConfigFile::configIncludeAndOptional); + TEST_ADD(CUTMiscConfigFile::reportErrorInSubFiles); + } + + void setup() + { + _OldPath = NLMISC::CPath::getCurrentPath(); + NLMISC::CPath::setCurrentPath(_WorkingPath.c_str()); + } + + void tear_down() + { + NLMISC::CPath::setCurrentPath(_OldPath.c_str()); + } + + void configWithInclude() + { + NLMISC::CConfigFile configFile; + + TEST_THROWS_NOTHING(configFile.load(NEL_UNIT_BASE "ut_misc_files/cfg_with_include.cfg")); + + TEST_ASSERT(configFile.loaded()); + TEST_ASSERT(configFile.getVarPtr("CfgWithInclude") != NULL); + TEST_ASSERT(configFile.getVar("CfgWithInclude").asString(0) == "ok"); + TEST_ASSERT(configFile.getVarPtr("IncludedCfg") != NULL); + TEST_ASSERT(configFile.getVar("IncludedCfg").asString(0) == "ok"); + } + + void configWithOptional() + { + NLMISC::CConfigFile configFile; + + TEST_THROWS_NOTHING(configFile.load(NEL_UNIT_BASE "ut_misc_files/cfg_with_optional.cfg")); + + TEST_ASSERT(configFile.loaded()); + TEST_ASSERT(configFile.getVarPtr("CfgWithInclude") != NULL); + TEST_ASSERT(configFile.getVar("CfgWithInclude").asString(0) == "ok"); + TEST_ASSERT(configFile.getVarPtr("IncludedCfg") != NULL); + TEST_ASSERT(configFile.getVar("IncludedCfg").asString(0) == "ok"); + } + + + void configWithDefine() + { + NLMISC::CConfigFile configFile; + + TEST_THROWS_NOTHING(configFile.load(NEL_UNIT_BASE "ut_misc_files/cfg_with_define.cfg")); + + TEST_ASSERT(configFile.loaded()); + TEST_ASSERT(configFile.getVarPtr("CfgReadableVar") != NULL); + TEST_ASSERT(configFile.getVarPtr("CfgNotToBeFound") == NULL); + TEST_ASSERT(configFile.getVarPtr("CfgInvisible") == NULL); + TEST_ASSERT(configFile.getVarPtr("CfgMustExist") != NULL); + } + + class CMyDisplayer : public NLMISC::IDisplayer + { + public: + vector Lines; + + virtual void doDisplay( const NLMISC::CLog::TDisplayInfo& args, const char *message) + { + Lines.push_back(message); + } + }; + + void configWithBadTest() + { + // override the warning channel to get the error on unclosed if + CMyDisplayer 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); + + TEST_THROWS_NOTHING(configFile.load(NEL_UNIT_BASE "ut_misc_files/cfg_with_bad_test.cfg")); + + TEST_ASSERT(configFile.getVarPtr("ASimpleVar") != NULL); + + // check that we have the warnings + TEST_ASSERT(warnings.Lines.size() == 13); + TEST_ASSERT(warnings.Lines[0].find(string("Preprocess: In file ")+fullName+"(6) : Error unrecognized preprocessor command") != string::npos); + TEST_ASSERT(warnings.Lines[1].find(string("Preprocess: In file ")+fullName+"(9) : Error found '#endif' without matching #if") != string::npos); + + // skip the I18N warning from parseMarkedString + TEST_ASSERT(warnings.Lines[3].find(string("Preprocess: In file ")+fullName+"(12) : Error parsing include file command") != string::npos); + // skip the I18N warning from parseMarkedString + TEST_ASSERT(warnings.Lines[5].find(string("Preprocess: In file ")+fullName+"(13) : Error parsing include file command") != string::npos); + // skip the I18N warning from parseMarkedString + TEST_ASSERT(warnings.Lines[7].find(string("Preprocess: In file ")+fullName+"(14) : Error parsing optional file command") != string::npos); + // skip the I18N warning from parseMarkedString + TEST_ASSERT(warnings.Lines[9].find(string("Preprocess: In file ")+fullName+"(15) : Error parsing optional file command") != string::npos); + TEST_ASSERT(warnings.Lines[10].find(string("Preprocess: In file ")+fullName+"(16) : Error parsing #define command") != string::npos); + TEST_ASSERT(warnings.Lines[11].find(string("Preprocess: In file ")+fullName+"(17) : Error parsing #ifdef command") != string::npos); + + TEST_ASSERT(warnings.Lines[12].find("Preprocess: Missing 1 closing #endif after parsing") != string::npos); + } + + void configIncludeAndOptional() + { + CMyDisplayer 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); + + + TEST_THROWS_NOTHING(configFile.load(NEL_UNIT_BASE "ut_misc_files/cfg_with_include_and_optional.cfg")); + + // check that we have the warnings only for the 'include' command + TEST_ASSERT(warnings.Lines.size() == 1); + TEST_ASSERT(warnings.Lines[0].find(string("Preprocess: In file ")+fullName+"(2) : Cannot include file 'a_missing_file.cfg'") != string::npos); + } + + void reportErrorInSubFiles() + { + CMyDisplayer 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); + + + TEST_THROWS(configFile.load(NEL_UNIT_BASE "ut_misc_files/cfg_with_error_main.cfg"), NLMISC::EParseError); + + // check that we have error report with correct filename and line number + TEST_ASSERT(warnings.Lines.size() == 1); + // the first error is in the subfile + TEST_ASSERT(warnings.Lines[0].find(string("CF: Parsing error in file ")+subfullName+" line 18") != string::npos); + } +}; + +#endif diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_debug.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_debug.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,234 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_MISC_DEBUG +#define UT_MISC_DEBUG + +#include +#include + +class CMiscUnitTestNelLibrary : public NLMISC::INelLibrary { + void onLibraryLoaded(bool firstTime) { } + void onLibraryUnloaded(bool lastTime) { } +}; +NLMISC_DECL_PURE_LIB(CMiscUnitTestNelLibrary); + +// Test suite for CInstanceCounter +class CFoo1 +{ +public: + NL_INSTANCE_COUNTER_DECL(CFoo1); +}; +NL_INSTANCE_COUNTER_IMPL(CFoo1); + +class CFoo2 +{ +public: + NL_INSTANCE_COUNTER_DECL(CFoo2); +}; + +NL_INSTANCE_COUNTER_IMPL(CFoo2); + +class CFoo3 : public CFoo2 +{ +public: + NL_INSTANCE_COUNTER_DECL(CFoo3); +}; + +NL_INSTANCE_COUNTER_IMPL(CFoo3); + + +class CUTMiscDebug : public Test::Suite +{ +public: + CUTMiscDebug() + { + TEST_ADD(CUTMiscDebug::testInstanceCounter) + TEST_ADD(CUTMiscDebug::testInstanceCounterOutput) + } + +private: + void testInstanceCounter() + { + sint32 n; + { + CFoo1 foo1; + + sint32 n = NL_GET_INSTANCE_COUNTER(CFoo1); + TEST_ASSERT(n == 1); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo1); + TEST_ASSERT(n == 1); + + NLMISC::CInstanceCounterManager::getInstance().resetDeltaCounter(); + + n = NL_GET_INSTANCE_COUNTER(CFoo1); + TEST_ASSERT(n == 1); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo1); + TEST_ASSERT(n == 0); + } + n = NL_GET_INSTANCE_COUNTER(CFoo1); + TEST_ASSERT(n == 0); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo1); + TEST_ASSERT(n == -1); + + { + CFoo1 foo1; + CFoo1 other(foo1); + + sint32 n = NL_GET_INSTANCE_COUNTER(CFoo1); + TEST_ASSERT(n == 2); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo1); + TEST_ASSERT(n == 1); + + NLMISC::CInstanceCounterManager::getInstance().resetDeltaCounter(); + + n = NL_GET_INSTANCE_COUNTER(CFoo1); + TEST_ASSERT(n == 2); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo1); + TEST_ASSERT(n == 0); + } + n = NL_GET_INSTANCE_COUNTER(CFoo1); + TEST_ASSERT(n == 0); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo1); + TEST_ASSERT(n == -2); + + { + CFoo1 foo1; + CFoo1 other; + + foo1 = other; + + sint32 n = NL_GET_INSTANCE_COUNTER(CFoo1); + TEST_ASSERT(n == 2); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo1); + TEST_ASSERT(n == 0); + + NLMISC::CInstanceCounterManager::getInstance().resetDeltaCounter(); + + n = NL_GET_INSTANCE_COUNTER(CFoo1); + TEST_ASSERT(n == 2); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo1); + TEST_ASSERT(n == 0); + } + n = NL_GET_INSTANCE_COUNTER(CFoo1); + TEST_ASSERT(n == 0); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo1); + TEST_ASSERT(n == -2); + + CFoo1 *foo1s[10]; + CFoo2 *foo2s[10]; + CFoo3 *foo3s[10]; + for (uint i=0; i<10; ++i) + { + foo1s[i] = new CFoo1; + foo2s[i] = new CFoo2; + foo3s[i] = new CFoo3; + + } + n = NL_GET_INSTANCE_COUNTER(CFoo1); + TEST_ASSERT(n == 10); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo1); + TEST_ASSERT(n == 8); + n = NL_GET_INSTANCE_COUNTER(CFoo2); + TEST_ASSERT(n == 20); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo2); + TEST_ASSERT(n == 20); + n = NL_GET_INSTANCE_COUNTER(CFoo3); + TEST_ASSERT(n == 10); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo3); + TEST_ASSERT(n == 10); + + NLMISC::CInstanceCounterManager::getInstance().resetDeltaCounter(); + n = NL_GET_INSTANCE_COUNTER(CFoo1); + TEST_ASSERT(n == 10); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo1); + TEST_ASSERT(n == 0); + n = NL_GET_INSTANCE_COUNTER(CFoo2); + TEST_ASSERT(n == 20); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo2); + TEST_ASSERT(n == 0); + n = NL_GET_INSTANCE_COUNTER(CFoo3); + TEST_ASSERT(n == 10); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo3); + TEST_ASSERT(n == 0); + + for (uint i=0; i<5; ++i) + { + delete foo1s[i]; + delete foo2s[i]; + delete foo3s[i]; + } + n = NL_GET_INSTANCE_COUNTER(CFoo1); + TEST_ASSERT(n == 5); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo1); + TEST_ASSERT(n == -5); + n = NL_GET_INSTANCE_COUNTER(CFoo2); + TEST_ASSERT(n == 10); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo2); + TEST_ASSERT(n == -10); + n = NL_GET_INSTANCE_COUNTER(CFoo3); + TEST_ASSERT(n == 5); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo3); + TEST_ASSERT(n == -5); + for (uint i=5; i<10; ++i) + { + delete foo1s[i]; + delete foo2s[i]; + delete foo3s[i]; + } + n = NL_GET_INSTANCE_COUNTER(CFoo1); + TEST_ASSERT(n == 0); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo1); + TEST_ASSERT(n == -10); + n = NL_GET_INSTANCE_COUNTER(CFoo2); + TEST_ASSERT(n == 0); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo2); + TEST_ASSERT(n == -20); + n = NL_GET_INSTANCE_COUNTER(CFoo3); + TEST_ASSERT(n == 0); + n = NL_GET_INSTANCE_COUNTER_DELTA(CFoo3); + TEST_ASSERT(n == -10); + } + + void testInstanceCounterOutput() + { + NLMISC::CInstanceCounterManager::getInstance().resetDeltaCounter(); + + CFoo1 *foo1s[10]; + CFoo2 *foo2s[10]; + CFoo3 *foo3s[10]; + for (uint i=0; i<10; ++i) + { + foo1s[i] = new CFoo1; + foo2s[i] = new CFoo2; + foo3s[i] = new CFoo3; + + } + + string ref = "Listing 3 Instance counters :\n" + " Class 'CFoo1 ', \t 10 instances, \t 10 delta\n" + " Class 'CFoo2 ', \t 20 instances, \t 20 delta\n" + " Class 'CFoo3 ', \t 10 instances, \t 10 delta\n"; + + string ret = NLMISC::CInstanceCounterManager::getInstance().displayCounters(); + + nlinfo("%s", ref.c_str()); + nlinfo("%s", ret.c_str()); + TEST_ASSERT(ref == ret); + } +}; + +#endif diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_dynlibload.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_dynlibload.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,40 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_MISC_DYNLIBLOAD +#define UT_MISC_DYNLIBLOAD + +#include + +class CUTMiscDynLibLoad : public Test::Suite +{ +public: + CUTMiscDynLibLoad () + { + TEST_ADD(CUTMiscDynLibLoad ::libraryNameDecoration) + } + + void libraryNameDecoration() + { + string libName = "libmylib_with_dll_so_some_very_bad_rd_df_tag_inside_df"; + string fileName = "some/path/to/add/difficulties/"+NLMISC::CLibrary::makeLibName(libName); + string cleanedName = NLMISC::CLibrary::cleanLibName(fileName); + + TEST_ASSERT(cleanedName == libName); + } +}; + +#endif diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_file.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_file.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,181 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_MISC_FILE +#define UT_MISC_FILE + +#include +#include + +// Test suite for NLMISC::CFile behavior +struct CUTMiscFile : public Test::Suite +{ + CUTMiscFile() + { + TEST_ADD(CUTMiscFile::copyOneBigFile); + TEST_ADD(CUTMiscFile::copyDifferentFileSize); + TEST_ADD(CUTMiscFile::moveOneBigFile); + TEST_ADD(CUTMiscFile::moveDifferentFileSize); + // Add a line here when adding a new test METHOD + } + +private: + string _SrcFile; + string _DstFile; + + void setup() + { + _SrcFile = "__copy_file_src.foo"; + _DstFile = "__copy_file_dst.foo"; + } + + void tear_down() + { + } + + void copyFileSize(uint fileSize) + { + // create a source file (using standard c code) + FILE *fp = fopen(_SrcFile.c_str(), "wb"); + nlverify(fp != NULL); + + for (uint i=0; i + +The content of the first file + + +Another content but for the second file + + +The content of the first fileAnother content but for the second file + + diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/.xml_pack_index --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/.xml_pack_index Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,2 @@ +file1_in_sub_1.xml +file2_in_sub_1.xml diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/file1_in_sub_1.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/file1_in_sub_1.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/file2_in_sub_1.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/file2_in_sub_1.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/samename.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/samename.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,8 @@ + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/.xml_pack_index --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/.xml_pack_index Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,2 @@ +file1_in_sub_2.xml +file2_in_sub_2.xml diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/file1_in_sub_2.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/file1_in_sub_2.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/file2_in_sub_2.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/file2_in_sub_2.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/samename.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/samename.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,8 @@ + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_files/included_cfg.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_files/included_cfg.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,3 @@ + +IncludedCfg = "ok"; + diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_files/xml_files/file1_in_xml_pack.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_files/xml_files/file1_in_xml_pack.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_files/xml_files/file2_in_xml_pack.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_files/xml_files/file2_in_xml_pack.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_files/xml_files/same_subfolder_1/samename/samename.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_files/xml_files/same_subfolder_1/samename/samename.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,8 @@ + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_files/xml_files/same_subfolder_2/samename/samename.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_files/xml_files/same_subfolder_2/samename/samename.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,8 @@ + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_files/xml_files/xml_files.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_files/xml_files/xml_files.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,8 @@ + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_pack_file.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_pack_file.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,245 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_MISC_PACK_FILE +#define UT_MISC_PACK_FILE + + +// Commenting out the ifdef since the files are authored on Windows +// and therefore always have a Windows-style newline. +//#ifdef NL_OS_WINDOWS +const string NewLine("\r\n"); +//#elif defined(NL_OS_UNIX) +//const string NewLine("\n"); +//#else +//#error "Specify the new line format for text file"; +//#endif + +#ifndef NEL_UNIT_BASE +#define NEL_UNIT_BASE "" +#endif // NEL_UNIT_BASE + +// Test suite for bnp and xml pack files +class CUTMiscPackFile : public Test::Suite +{ + string _WorkingPath; + string _OldPath; +public: + CUTMiscPackFile () + { + TEST_ADD(CUTMiscPackFile::addBnp); + TEST_ADD(CUTMiscPackFile::loadFromBnp); + TEST_ADD(CUTMiscPackFile::addXmlpack); + TEST_ADD(CUTMiscPackFile::loadFromXmlpack); + TEST_ADD(CUTMiscPackFile::compressMemory); + TEST_ADD(CUTMiscPackFile::loadFromBnpCompressed); + TEST_ADD(CUTMiscPackFile::loadFromXmlpackCompressed); + TEST_ADD(CUTMiscPackFile::decompressMemory); + TEST_ADD(CUTMiscPackFile::loadFromBnpUncompressed); + TEST_ADD(CUTMiscPackFile::loadFromXmlpackUncompressed); + TEST_ADD(CUTMiscPackFile::loadXmlpackWithSameName); + } + + void setup() + { + _OldPath = NLMISC::CPath::getCurrentPath(); + NLMISC::CPath::setCurrentPath(_WorkingPath.c_str()); + string pathAfter = NLMISC::CPath::getCurrentPath(); + } + + void tear_down() + { + NLMISC::CPath::setCurrentPath(_OldPath.c_str()); + } + + void addBnp() + { + // add bnp file in the path and access to file inside + NLMISC::CPath::addSearchBigFile(NEL_UNIT_BASE "ut_misc_files/files.bnp", false, false); + } + + void loadFromBnp() + { + // lookup for the file + string filename = NLMISC::CPath::lookup("file1_in_bnp.txt", true, true, false); + TEST_ASSERT(filename == "files.bnp@file1_in_bnp.txt"); + + // read the first file content + { + NLMISC::CIFile file1(filename); + string content1; + content1.resize(file1.getFileSize()); + file1.serialBuffer((uint8*)content1.data(), file1.getFileSize()); + + // check the file content + TEST_ASSERT(content1 == "The content of the first file"); + } + + // lookup for the 2nd file + filename = NLMISC::CPath::lookup("file2_in_bnp.txt", true, true, false); + TEST_ASSERT(filename == "files.bnp@file2_in_bnp.txt"); + + { + // read the second file content + NLMISC::CIFile file2(filename); + string content2; + content2.resize(file2.getFileSize()); + file2.serialBuffer((uint8*)content2.data(), file2.getFileSize()); + + // check the file content + TEST_ASSERT(content2 == "Another content but for the second file"); + } + } + + void addXmlpack() + { + // add xml_pack file in the path and access to file inside + NLMISC::CPath::addSearchXmlpackFile(NEL_UNIT_BASE "ut_misc_files/xml_files/xml_files.xml_pack", false, false); + } + + void loadFromXmlpack() + { + // lookup for the file + string filename = NLMISC::CPath::lookup("file1_in_xml_pack.xml", true, true, false); + TEST_ASSERT(filename == NEL_UNIT_BASE "ut_misc_files/xml_files/xml_files.xml_pack@@file1_in_xml_pack.xml"); + + // read the first file content + { + NLMISC::CIFile file1(filename); + string content1; + content1.resize(file1.getFileSize()); + file1.serialBuffer((uint8*)content1.data(), file1.getFileSize()); + + // check the file content + string refText = ""+NewLine; + TEST_ASSERT(content1 == refText); + } + + // lookup for the 2nd file + filename = NLMISC::CPath::lookup("file2_in_xml_pack.xml", true, true, false); + TEST_ASSERT(filename == NEL_UNIT_BASE "ut_misc_files/xml_files/xml_files.xml_pack@@file2_in_xml_pack.xml"); + + { + // read the second file content + NLMISC::CIFile file2(filename); + string content2; + content2.resize(file2.getFileSize()); + file2.serialBuffer((uint8*)content2.data(), file2.getFileSize()); + + // check the file content + string refText=""+NewLine; + TEST_ASSERT(content2 == refText); + } + } + + void compressMemory() + { +//#ifdef WIN32 +//_CrtCheckMemory(); +//#endif + NLMISC::CPath::memoryCompress(); +//#ifdef WIN32 +//_CrtCheckMemory(); +//#endif + } + + void loadFromBnpCompressed() + { + // simply recall loadFromBnp + loadFromBnp(); + } + + void loadFromXmlpackCompressed() + { + // simply recall loadFromXmlpack + loadFromXmlpack(); + } + + void decompressMemory() + { + NLMISC::CPath::memoryUncompress(); + } + + void loadFromBnpUncompressed() + { + // simply recall loadFromBnp + loadFromBnp(); + } + + void loadFromXmlpackUncompressed() + { + // simply recall loadFromXmlpack + loadFromXmlpack(); + } + + void loadXmlpackWithSameName() + { + // we support xml_pack file in subfolder that have the same name + // but the 'addSearchPath' or add xml pack must be done + // at a higher discriminant directory + +// NLMISC::CPath::addSearchXmlpackFile(NEL_UNIT_BASE "ut_misc_files/xml_files/same_subfolder_1/samename/samename.xml_pack", true, false, NULL); +// NLMISC::CPath::addSearchXmlpackFile(NEL_UNIT_BASE "ut_misc_files/xml_files/same_subfolder_2/samename/samename.xml_pack", true, false, NULL); + NLMISC::CPath::addSearchPath(NEL_UNIT_BASE "ut_misc_files/xml_files", true, false); + + // lookup for the files in first subdirectory + string filename = NLMISC::CPath::lookup("file1_in_sub_1.xml", true, true, false); + TEST_ASSERT(filename == NEL_UNIT_BASE "ut_misc_files/xml_files/same_subfolder_1/samename/samename.xml_pack@@file1_in_sub_1.xml"); + filename = NLMISC::CPath::lookup("file2_in_sub_1.xml", true, true, false); + TEST_ASSERT(filename == NEL_UNIT_BASE "ut_misc_files/xml_files/same_subfolder_1/samename/samename.xml_pack@@file2_in_sub_1.xml"); + + // lookup for the files in the second subdirectory + filename = NLMISC::CPath::lookup("file1_in_sub_2.xml", true, true, false); + TEST_ASSERT(filename == NEL_UNIT_BASE "ut_misc_files/xml_files/same_subfolder_2/samename/samename.xml_pack@@file1_in_sub_2.xml"); + filename = NLMISC::CPath::lookup("file2_in_sub_2.xml", true, true, false); + TEST_ASSERT(filename == NEL_UNIT_BASE "ut_misc_files/xml_files/same_subfolder_2/samename/samename.xml_pack@@file2_in_sub_2.xml"); + + // read the file content of the first file in first pack + filename = NLMISC::CPath::lookup("file1_in_sub_1.xml", true, true, false); + + // check that we can read the file modif date + uint32 d = NLMISC::CFile::getFileModificationDate(filename); + TEST_ASSERT(d != 0); + { + NLMISC::CIFile file1(filename); + string content1; + content1.resize(file1.getFileSize()); + file1.serialBuffer((uint8*)content1.data(), file1.getFileSize()); + + // check the file content + string refText = ""+NewLine; + TEST_ASSERT(content1 == refText); + } + + // read the file content of the second file in the second pack + filename = NLMISC::CPath::lookup("file2_in_sub_2.xml", true, true, false); + { + // read the second file content + NLMISC::CIFile file2(filename); + string content2; + content2.resize(file2.getFileSize()); + file2.serialBuffer((uint8*)content2.data(), file2.getFileSize()); + + // check the file content + string refText=""+NewLine; + TEST_ASSERT(content2 == refText); + } + + } + +}; + +#endif diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_singleton.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_singleton.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,139 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_MISC_SINGLETON +#define UT_MISC_SINGLETON + +#include + +class CSafeSingleton +{ + NL_INSTANCE_COUNTER_DECL(CSafeSingleton); + NLMISC_SAFE_SINGLETON_DECL(CSafeSingleton); + CSafeSingleton() {} +}; + +NL_INSTANCE_COUNTER_IMPL(CSafeSingleton); +NLMISC_SAFE_SINGLETON_IMPL(CSafeSingleton); + + +class CUnsafeSingleton +{ + NL_INSTANCE_COUNTER_DECL(CUnsafeSingleton); + + static CUnsafeSingleton *_Instance; + + CUnsafeSingleton() {} + CUnsafeSingleton(const CUnsafeSingleton &other) {} + +public: + + static CUnsafeSingleton &getInstance() + { + if (_Instance == NULL) + _Instance = new CUnsafeSingleton; + return *_Instance; + } +}; + +NL_INSTANCE_COUNTER_IMPL(CUnsafeSingleton); +CUnsafeSingleton *CUnsafeSingleton::_Instance = NULL; + + +// Test suite for Singleton behavior +class CUTMiscSingleton : public Test::Suite +{ + std::string WorkingPath; + std::string OldPath; +public: + CUTMiscSingleton() + { + TEST_ADD(CUTMiscSingleton::createSingleton); + TEST_ADD(CUTMiscSingleton::accessSingleton); + //TEST_ADD(CUTMiscSingleton::multiDllSingleton); + } + + void setup() + { + OldPath = NLMISC::CPath::getCurrentPath(); + + NLMISC::CPath::setCurrentPath(WorkingPath.c_str()); + } + + void tear_down() + { + NLMISC::CPath::setCurrentPath(OldPath.c_str()); + } + + void createSingleton() + { + TEST_ASSERT(NLMISC::CInstanceCounterManager::getInstance().getInstanceCounter("CSafeSingleton") == 0); + CSafeSingleton &ss = CSafeSingleton::getInstance(); + + TEST_ASSERT(NL_GET_INSTANCE_COUNTER(CSafeSingleton) == 1); + + TEST_ASSERT(NL_GET_INSTANCE_COUNTER(CUnsafeSingleton) == 0); + CUnsafeSingleton &us = CUnsafeSingleton::getInstance(); + + TEST_ASSERT(NL_GET_INSTANCE_COUNTER(CUnsafeSingleton) == 1); + } + + void accessSingleton() + { + TEST_ASSERT(NL_GET_INSTANCE_COUNTER(CSafeSingleton) == 1); + CSafeSingleton &ss = CSafeSingleton::getInstance(); + + TEST_ASSERT(NL_GET_INSTANCE_COUNTER(CSafeSingleton) == 1); + + TEST_ASSERT(NL_GET_INSTANCE_COUNTER(CUnsafeSingleton) == 1); + CUnsafeSingleton &us = CUnsafeSingleton::getInstance(); + + TEST_ASSERT(NL_GET_INSTANCE_COUNTER(CUnsafeSingleton) == 1); + } + + /*void multiDllSingleton() + { + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().exists("aDynLibCommand") == false); + + CLibrary lib; + if (lib.loadLibrary("dyn_lib_test", true, true, true) != true) + { + TEST_ASSERT_MSG(false, "failed to reload the dll for testing singletons across dlls"); + return; + } + + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().isCommand("aDynLibCommand") == true); + + IDynLibTest *libTest = dynamic_cast(lib.getNelLibraryInterface()); + TEST_ASSERT(libTest != NULL); + + libTest->testSingleton(this); + }*/ + + void assertmentWrapper(Test::Source src) + { + assertment(src); + } + + bool continue_after_failureWrapper() + { + return continue_after_failure(); + } + + friend class CDynLibTest; +}; + +#endif diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_sstring.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_sstring.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,57 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_MISC_SSTRING +#define UT_MISC_SSTRING + +#include + +struct CUTMiscSString : public Test::Suite +{ + CUTMiscSString() + { + TEST_ADD(CUTMiscSString::testStrtok); + // Add a line here when adding a new test METHOD + } + + void testStrtok() + { + NLMISC::CSString testLine(" a=b c (a=e b=c) \t\t c(a=e b=c) toto(bimbo(foo(bar(a=b))))"); + + NLMISC::CSString part; + part = testLine.strtok(" \t", true, false); + TEST_ASSERT(part == "a=b"); + part = testLine.strtok(" \t", true, false); + TEST_ASSERT(part == "c"); + part = testLine.strtok(" \t", true, false); + TEST_ASSERT(part == "(a=e b=c)"); + part = testLine.strtok(" \t", true, false); + TEST_ASSERT(part == "c"); + part = testLine.strtok(" \t=", true, false); + TEST_ASSERT(part == "(a=e b=c)"); + part = testLine.strtok(" \t=", true, false); + TEST_ASSERT(part == "toto"); + part = testLine.strtok(" \t=", true, false); + TEST_ASSERT(part == "(bimbo(foo(bar(a=b))))"); + part = part.stripBlockDelimiters(); + NLMISC::CSString part2 = part.strtok(" \t=", true, false); + TEST_ASSERT(part2 == "bimbo"); + part2 = part.strtok(" \t=", true, false); + TEST_ASSERT(part2 == "(foo(bar(a=b)))"); + } +}; + +#endif diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_stream.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_stream.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,187 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_MISC_STREAM +#define UT_MISC_STREAM + +#include +#include + +// The following line is known to crash in a Ryzom service +NLMISC::CBitMemStream globalBms( false, 2048 ); // global to avoid reallocation + +// Test suite for stream based classes +// ! not complete at all at time of writing ! +class CUTMiscStream: public Test::Suite +{ +public: + CUTMiscStream () + { + TEST_ADD(CUTMiscStream::constAndStream); + TEST_ADD(CUTMiscStream::memStreamSwap); + TEST_ADD(CUTMiscStream::copyOnWrite); + TEST_ADD(CUTMiscStream::preallocatedBitStream); + } + + void preallocatedBitStream() + { + NLMISC::CBitMemStream localBms( false, 2048 ); // global to avoid reallocation + } + + + void copyOnWrite() + { + // test the copy on write strategy in the mem stream (and derived) class. + // The point is to be able to copy a mem stream (e.g a NLNET::CMessage) + // but to do not copy the stream buffer. + // If more than one stream use the same buffer, any attempt to + // modifye the buffer content while lead to a buffer duplication + + NLMISC::CMemStream s1; + NLMISC::CMemStream s2; + NLMISC::CMemStream s3; + + + uint32 i = 1; + s1.serial(i); + + s2 = s1; + s3 = s2; + + TEST_ASSERT(s1.buffer() == s2.buffer()); + TEST_ASSERT(s1.buffer() == s3.buffer()); + + // change s1 + s1.serial(i); + TEST_ASSERT(s1.buffer() != s2.buffer()); + TEST_ASSERT(s2.buffer() == s3.buffer()); + + s2.invert(); + s3 = s2; + + TEST_ASSERT(s2.buffer() == s3.buffer()); + + s2.serial(i); + + TEST_ASSERT(s2.buffer() == s3.buffer()); + + + } + + enum TEnum + { + e_a, + e_b, + e_c, + e_d + }; + + void constAndStream() + { + // check that we can serialize with const stream or const object + + + NLMISC::CMemStream s1; + NLMISC::IStream &is1 = s1; + + const string str("toto"); + const uint32 i(1234546); + const TEnum e(e_a); + string str2("titi"); + uint32 i2(123456); + TEnum e2(e_b); + + // no need for const cast any more + nlWriteSerial(s1, str); + nlWriteSerial(s1, i); + nlWrite(s1, serialEnum, e); + nlWriteSerial(is1, str); + nlWriteSerial(is1, i); + nlWrite(is1, serialEnum, i); + // this work as well + s1.serial(str2); + s1.serial(i2); + s1.serialEnum(e2); + + is1.serial(str2); + is1.serial(i2); + is1.serialEnum(e2); + + const NLMISC::CMemStream &s2 = s1; + const NLMISC::IStream &is2 = s2; + + string str3; + uint32 i3; + TEnum e3(e_c); + // cant write in a const stream + TEST_THROWS(nlReadSerial(s2, str3), NLMISC::ENotInputStream); + TEST_THROWS(nlReadSerial(s2, i3), NLMISC::ENotInputStream); + TEST_THROWS(nlRead(s2, serialEnum, e3), NLMISC::ENotInputStream); + TEST_THROWS(nlReadSerial(is2, str3), NLMISC::ENotInputStream); + TEST_THROWS(nlReadSerial(is2, i3), NLMISC::ENotInputStream); + TEST_THROWS(nlRead(is2, serialEnum, e3), NLMISC::ENotInputStream); + + + s1.invert(); + + nlReadSerial(s2, str3); + nlReadSerial(s2, i3); + nlRead(s2, serialEnum, e3); + nlReadSerial(is2, str3); + nlReadSerial(is2, i3); + nlRead(is2, serialEnum, e3); + + + // cant read a const value + TEST_THROWS(nlWriteSerial(s1, str), NLMISC::ENotOutputStream); + TEST_THROWS(nlWriteSerial(s1, i), NLMISC::ENotOutputStream); + TEST_THROWS(nlWrite(s1, serialEnum, e), NLMISC::ENotOutputStream); + TEST_THROWS(nlWriteSerial(is1, str), NLMISC::ENotOutputStream); + TEST_THROWS(nlWriteSerial(is1, i), NLMISC::ENotOutputStream); + TEST_THROWS(nlWrite(is1, serialEnum, e), NLMISC::ENotOutputStream); + + } + + void memStreamSwap() + { + NLMISC::CMemStream ms2; + + string s; + { + NLMISC::CMemStream ms1; + + s = "foo1"; + ms1.serial(s); + s = "foo2"; + ms1.serial(s); + s = ""; + + ms2.swap(ms1); + + // check that ms1 is empty now + TEST_ASSERT(ms1.length() == 0); + } + + TEST_ASSERT(!ms2.isReading()); + ms2.invert(); + ms2.serial(s); + TEST_ASSERT(s == "foo1"); + ms2.serial(s); + TEST_ASSERT(s == "foo2"); + } +}; + +#endif diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_string_common.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_string_common.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,408 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_MISC_STRING_COMMON +#define UT_MISC_STRING_COMMON + +#include + +struct CUTMiscStringCommon : public Test::Suite +{ + CUTMiscStringCommon() + { + TEST_ADD(CUTMiscStringCommon::fromStringSint8); + TEST_ADD(CUTMiscStringCommon::fromStringUint8); + TEST_ADD(CUTMiscStringCommon::fromStringSint16); + TEST_ADD(CUTMiscStringCommon::fromStringUint16); + TEST_ADD(CUTMiscStringCommon::fromStringSint32); + TEST_ADD(CUTMiscStringCommon::fromStringUint32); + // Add a line here when adding a new test METHOD + } + + void fromStringSint8() + { + bool ret; + + // tests for sint8 + sint8 val; + + // positive value + ret = NLMISC::fromString("1", val); + TEST_ASSERT(ret && val == 1); + + // negative value + ret = NLMISC::fromString("-1", val); + TEST_ASSERT(ret && val == -1); + + // bad character + ret = NLMISC::fromString("a", val); + TEST_ASSERT(!ret && val == 0); + + // right character and bad character + ret = NLMISC::fromString("1a", val); + TEST_ASSERT(ret && val == 1); + + // min limit + ret = NLMISC::fromString("-128", val); + TEST_ASSERT(ret && val == -128); + + // max limit + ret = NLMISC::fromString("127", val); + TEST_ASSERT(ret && val == 127); + + // min limit -1 + ret = NLMISC::fromString("-129", val); + TEST_ASSERT(!ret && val == 0); + + // max limit +1 + ret = NLMISC::fromString("128", val); + TEST_ASSERT(!ret && val == 0); + + // with period + ret = NLMISC::fromString("1.2", val); + TEST_ASSERT(ret && val == 1); + + // with coma + ret = NLMISC::fromString("1,2", val); + TEST_ASSERT(ret && val == 1); + + // with spaces before + ret = NLMISC::fromString(" 10", val); + TEST_ASSERT(ret && val == 10); + + // with spaces after + ret = NLMISC::fromString("10 ", val); + TEST_ASSERT(ret && val == 10); + + // with 0s before + ret = NLMISC::fromString("001", val); + TEST_ASSERT(ret && val == 1); + + // with + before + ret = NLMISC::fromString("+1", val); + TEST_ASSERT(ret && val == 1); + } + + void fromStringUint8() + { + bool ret; + + // tests for uint8 + uint8 val; + + // positive value + ret = NLMISC::fromString("1", val); + TEST_ASSERT(ret && val == 1); + + // bad character + ret = NLMISC::fromString("a", val); + TEST_ASSERT(!ret && val == 0); + + // right character and bad character + ret = NLMISC::fromString("1a", val); + TEST_ASSERT(ret && val == 1); + + // min limit + ret = NLMISC::fromString("0", val); + TEST_ASSERT(ret && val == 0); + + // max limit + ret = NLMISC::fromString("255", val); + TEST_ASSERT(ret && val == 255); + + // min limit -1 + ret = NLMISC::fromString("-1", val); + TEST_ASSERT(!ret && val == 0); + + // max limit +1 + ret = NLMISC::fromString("256", val); + TEST_ASSERT(!ret && val == 0); + + // with period + ret = NLMISC::fromString("1.2", val); + TEST_ASSERT(ret && val == 1); + + // with coma + ret = NLMISC::fromString("1,2", val); + TEST_ASSERT(ret && val == 1); + + // with spaces before + ret = NLMISC::fromString(" 10", val); + TEST_ASSERT(ret && val == 10); + + // with spaces after + ret = NLMISC::fromString("10 ", val); + TEST_ASSERT(ret && val == 10); + + // with 0s before + ret = NLMISC::fromString("001", val); + TEST_ASSERT(ret && val == 1); + + // with + before + ret = NLMISC::fromString("+1", val); + TEST_ASSERT(ret && val == 1); + } + + void fromStringSint16() + { + bool ret; + + // tests for sint16 + sint16 val; + + // positive value + ret = NLMISC::fromString("1", val); + TEST_ASSERT(ret && val == 1); + + // negative value + ret = NLMISC::fromString("-1", val); + TEST_ASSERT(ret && val == -1); + + // bad character + ret = NLMISC::fromString("a", val); + TEST_ASSERT(!ret && val == 0); + + // right character and bad character + ret = NLMISC::fromString("1a", val); + TEST_ASSERT(ret && val == 1); + + // min limit + ret = NLMISC::fromString("-32768", val); + TEST_ASSERT(ret && val == -32768); + + // max limit + ret = NLMISC::fromString("32767", val); + TEST_ASSERT(ret && val == 32767); + + // min limit -1 + ret = NLMISC::fromString("-32769", val); + TEST_ASSERT(!ret && val == 0); + + // max limit +1 + ret = NLMISC::fromString("32768", val); + TEST_ASSERT(!ret && val == 0); + + // with period + ret = NLMISC::fromString("1.2", val); + TEST_ASSERT(ret && val == 1); + + // with coma + ret = NLMISC::fromString("1,2", val); + TEST_ASSERT(ret && val == 1); + + // with spaces before + ret = NLMISC::fromString(" 10", val); + TEST_ASSERT(ret && val == 10); + + // with spaces after + ret = NLMISC::fromString("10 ", val); + TEST_ASSERT(ret && val == 10); + + // with 0s before + ret = NLMISC::fromString("001", val); + TEST_ASSERT(ret && val == 1); + + // with + before + ret = NLMISC::fromString("+1", val); + TEST_ASSERT(ret && val == 1); + } + + void fromStringUint16() + { + bool ret; + + // tests for uint16 + uint16 val; + + // positive value + ret = NLMISC::fromString("1", val); + TEST_ASSERT(ret && val == 1); + + // bad character + ret = NLMISC::fromString("a", val); + TEST_ASSERT(!ret && val == 0); + + // right character and bad character + ret = NLMISC::fromString("1a", val); + TEST_ASSERT(ret && val == 1); + + // min limit + ret = NLMISC::fromString("0", val); + TEST_ASSERT(ret && val == 0); + + // max limit + ret = NLMISC::fromString("65535", val); + TEST_ASSERT(ret && val == 65535); + + // min limit -1 + ret = NLMISC::fromString("-1", val); + TEST_ASSERT(!ret && val == 0); + + // max limit +1 + ret = NLMISC::fromString("65536", val); + TEST_ASSERT(!ret && val == 0); + + // with period + ret = NLMISC::fromString("1.2", val); + TEST_ASSERT(ret && val == 1); + + // with coma + ret = NLMISC::fromString("1,2", val); + TEST_ASSERT(ret && val == 1); + + // with spaces before + ret = NLMISC::fromString(" 10", val); + TEST_ASSERT(ret && val == 10); + + // with spaces after + ret = NLMISC::fromString("10 ", val); + TEST_ASSERT(ret && val == 10); + + // with 0s before + ret = NLMISC::fromString("001", val); + TEST_ASSERT(ret && val == 1); + + // with + before + ret = NLMISC::fromString("+1", val); + TEST_ASSERT(ret && val == 1); + } + + void fromStringSint32() + { + bool ret; + + // tests for sint32 + sint32 val; + + // positive value + ret = NLMISC::fromString("1", val); + TEST_ASSERT(ret && val == 1); + + // negative value + ret = NLMISC::fromString("-1", val); + TEST_ASSERT(ret && val == -1); + + // bad character + ret = NLMISC::fromString("a", val); + TEST_ASSERT(!ret && val == 0); + + // right character and bad character + ret = NLMISC::fromString("1a", val); + TEST_ASSERT(ret && val == 1); + + // min limit + ret = NLMISC::fromString("-2147483648", val); + TEST_ASSERT(ret && val == INT_MIN); + + // max limit + ret = NLMISC::fromString("2147483647", val); + TEST_ASSERT(ret && val == INT_MAX); + + // min limit -1 + ret = NLMISC::fromString("-2147483649", val); + TEST_ASSERT(!ret && val == 0); + + // max limit +1 + ret = NLMISC::fromString("2147483648", val); + TEST_ASSERT(!ret && val == 0); + + // with period + ret = NLMISC::fromString("1.2", val); + TEST_ASSERT(ret && val == 1); + + // with coma + ret = NLMISC::fromString("1,2", val); + TEST_ASSERT(ret && val == 1); + + // with spaces before + ret = NLMISC::fromString(" 10", val); + TEST_ASSERT(ret && val == 10); + + // with spaces after + ret = NLMISC::fromString("10 ", val); + TEST_ASSERT(ret && val == 10); + + // with 0s before + ret = NLMISC::fromString("001", val); + TEST_ASSERT(ret && val == 1); + + // with + before + ret = NLMISC::fromString("+1", val); + TEST_ASSERT(ret && val == 1); + } + + void fromStringUint32() + { + bool ret; + + // tests for uint32 + uint32 val; + + // positive value + ret = NLMISC::fromString("1", val); + TEST_ASSERT(ret && val == 1); + + // bad character + ret = NLMISC::fromString("a", val); + TEST_ASSERT(!ret && val == 0); + + // right character and bad character + ret = NLMISC::fromString("1a", val); + TEST_ASSERT(ret && val == 1); + + // min limit + ret = NLMISC::fromString("0", val); + TEST_ASSERT(ret && val == 0); + + // max limit + ret = NLMISC::fromString("4294967295", val); + TEST_ASSERT(ret && val == 4294967295); + + // min limit -1 + ret = NLMISC::fromString("-1", val); + TEST_ASSERT(!ret && val == 0); + + // max limit +1 + ret = NLMISC::fromString("4294967296", val); + TEST_ASSERT(!ret && val == 0); + + // with period + ret = NLMISC::fromString("1.2", val); + TEST_ASSERT(ret && val == 1); + + // with coma + ret = NLMISC::fromString("1,2", val); + TEST_ASSERT(ret && val == 1); + + // with spaces before + ret = NLMISC::fromString(" 10", val); + TEST_ASSERT(ret && val == 10); + + // with spaces after + ret = NLMISC::fromString("10 ", val); + TEST_ASSERT(ret && val == 10); + + // with 0s before + ret = NLMISC::fromString("001", val); + TEST_ASSERT(ret && val == 1); + + // with + before + ret = NLMISC::fromString("+1", val); + TEST_ASSERT(ret && val == 1); + } +}; + +#endif diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_types.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,49 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_MISC_TYPES +#define UT_MISC_TYPES + +#include + +class CUTMiscTypes: public Test::Suite +{ +public: + CUTMiscTypes () + { + TEST_ADD(CUTMiscTypes::basicTypes) + } + + void basicTypes() + { + // this doesn't work on 64bit architectures + //Test_ASSERT(sizeof(uint) == sizeof(void*)); + + TEST_ASSERT(sizeof(sint8) == 1); + TEST_ASSERT(sizeof(uint8) == 1); + TEST_ASSERT(sizeof(sint16) == 2); + TEST_ASSERT(sizeof(uint16) == 2); + TEST_ASSERT(sizeof(sint32) == 4); + TEST_ASSERT(sizeof(uint32) == 4); + TEST_ASSERT(sizeof(sint64) == 8); + TEST_ASSERT(sizeof(uint64) == 8); + + TEST_ASSERT(sizeof(sint) >= 4); + TEST_ASSERT(sizeof(uint) >= 4); + } +}; + +#endif diff -r deecbb8ad448 code/nel/tools/nel_misc_test/ut_misc_variable.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_misc_test/ut_misc_variable.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,44 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_MISC_VARIABLE +#define UT_MISC_VARIABLE + +#include + +class CUTMiscVariable : public Test::Suite +{ +public: + CUTMiscVariable () + { + TEST_ADD(CUTMiscVariable ::declareVar) + } + + void declareVar() + { + { + NLMISC::CVariable myLocalVar("test", "myLocalVar", "no help", ""); + + TEST_ASSERT(myLocalVar.get() == string("")); + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute("myLocalVar foo", (*NLMISC::InfoLog))); + TEST_ASSERT(myLocalVar.get() == string("foo")); + } + + TEST_ASSERT(!NLMISC::CCommandRegistry::getInstance().execute("myLocalVar foo", (*NLMISC::InfoLog))); + } +}; + +#endif diff -r deecbb8ad448 code/nel/tools/nel_net_test/CMakeLists.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/CMakeLists.txt Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,13 @@ +FILE(GLOB SRC *.cpp *.h) + +ADD_EXECUTABLE(nel_net_test ${SRC}) + +INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${CPPTEST_INCLUDE_DIR}) + +TARGET_LINK_LIBRARIES(nel_net_test ${CPPTEST_LIBRARIES} nelnet) +NL_DEFAULT_PROPS(nel_net_test "Net Unit Tests") +NL_ADD_RUNTIME_FLAGS(nel_net_test) + +ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} -DNEL_UNIT_NET_BASE="${PROJECT_SOURCE_DIR}/tools/nel_net_test/") + +INSTALL(TARGETS nel_net_test RUNTIME DESTINATION bin) diff -r deecbb8ad448 code/nel/tools/nel_net_test/__copy_file_dst.foo Binary file code/nel/tools/nel_net_test/__copy_file_dst.foo has changed diff -r deecbb8ad448 code/nel/tools/nel_net_test/__ligo_class.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/__ligo_class.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_net_test/__test_prim.primitive --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/__test_prim.primitive Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,27 @@ + + + + + + + class + test + + + name + test_root + + + + + class + alias + + + name + alias + + + + + diff -r deecbb8ad448 code/nel/tools/nel_net_test/debug_cfg_with_error_main.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/debug_cfg_with_error_main.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,41 @@ +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 1 +// This config file include the config file with error then generate an error +// WARNING : is you add lines, update the code in the test + + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 1 +// In this cfg, we introduce an error in a line after define and if clause + + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 5 + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 7 + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 9 + // nothing + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 13 +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error.cfg" 15 + + +// Here is the offending line, at line 18 +ABadVar iable = "foo"; + +// Some additionnal garbase lines + +AGoodVar = "bar"; +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 6 + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 8 +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 9 + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 11 + // nothing + +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 15 +#fileline "r:/code/nel/tools/nel_unit_test/ut_misc_files/cfg_with_error_main.cfg" 17 + + +// Some additionnal garbase lines + +AGoodVar = "bar"; diff -r deecbb8ad448 code/nel/tools/nel_net_test/nel_net_test.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/nel_net_test.cpp Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,146 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include + +#include +#include + +#include + +using namespace std; + +#ifdef NL_OS_WINDOWS +# define NEL_UNIT_DATA "" +#endif + + +#include "ut_net.h" + +// Add a line here when adding a new test MODULE + +#ifdef _MSC_VER + +/** A special stream buffer that output in the 'output debug string' feature of windows. + */ +class CDebugOutput : public streambuf +{ + int_type overflow(int_type c) + { + string str(pbase(), pptr()); + + if (c != traits_type::eof()) + str += c; + OutputDebugString(str.c_str() ); + + return c; + } +}; +// The instance of the streambug +ostream msvDebug(new CDebugOutput); + +#endif + +static void usage() +{ + cout << "usage: mytest [MODE]\n" + << "where MODE may be one of:\n" + << " --compiler\n" + << " --html\n" + << " --text-terse (default)\n" + << " --text-verbose\n"; + exit(0); +} + +static auto_ptr cmdline(int argc, char* argv[]) +{ + if (argc > 2) + usage(); // will not return + + Test::Output* output = 0; + + if (argc == 1) + output = new Test::TextOutput(Test::TextOutput::Verbose); + else + { + const char* arg = argv[1]; + if (strcmp(arg, "--compiler") == 0) + { +#ifdef _MSC_VER + output = new Test::CompilerOutput(Test::CompilerOutput::MSVC, msvDebug); +#elif defined(__GNUC__) + output = new Test::CompilerOutput(Test::CompilerOutput::GCC); +#else + output = new Test::CompilerOutput; +#endif + } + else if (strcmp(arg, "--html") == 0) + output = new Test::HtmlOutput; + else if (strcmp(arg, "--text-terse") == 0) + output = new Test::TextOutput(Test::TextOutput::Terse); + else if (strcmp(arg, "--text-verbose") == 0) + output = new Test::TextOutput(Test::TextOutput::Verbose); + else + { + cout << "invalid commandline argument: " << arg << endl; + usage(); // will not return + } + } + + return auto_ptr(output); +} + +// Main test program +// +int main(int argc, char *argv[]) +{ + static const char *outputFileName = "result.html"; + + // init Nel context + new NLMISC::CApplicationContext; + + bool noerrors = false; + + try + { + Test::Suite ts; + + + ts.add(auto_ptr(new CUTNet)); + + // Add a line here when adding a new test MODULE + + auto_ptr output(cmdline(argc, argv)); + noerrors = ts.run(*output); + + Test::HtmlOutput* const html = dynamic_cast(output.get()); + if (html) + { + std::ofstream fout(outputFileName); + html->generate(fout, true, "NeLTest"); + } + } + catch (...) + { + cout << "unexpected exception encountered"; + return EXIT_FAILURE; + } + if(noerrors) + nlinfo("No errors during net unit testing"); + else + nlwarning("Errors during net unit testing"); + return noerrors?EXIT_SUCCESS:EXIT_FAILURE; +} diff -r deecbb8ad448 code/nel/tools/nel_net_test/nel_net_test.sln --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/nel_net_test.sln Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,60 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nel_unit_test", "nel_unit_test.vcproj", "{F89D1853-2E47-4CE5-8EC8-188A805887EE}" + ProjectSection(ProjectDependencies) = postProject + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516} = {44B21233-EFCC-4825-B5E5-3A3BD6CC5516} + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9} = {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9} + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C} = {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "misc", "..\..\src\misc.vcproj", "{44B21233-EFCC-4825-B5E5-3A3BD6CC5516}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "net", "..\..\src\net.vcproj", "{67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ligo", "..\..\src\ligo.vcproj", "{1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Debug|Win32.ActiveCfg = Debug|Win32 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Debug|Win32.Build.0 = Debug|Win32 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Debug|x64.ActiveCfg = Debug|x64 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Debug|x64.Build.0 = Debug|x64 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Release|Win32.ActiveCfg = Release|Win32 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Release|Win32.Build.0 = Release|Win32 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Release|x64.ActiveCfg = Release|x64 + {F89D1853-2E47-4CE5-8EC8-188A805887EE}.Release|x64.Build.0 = Release|x64 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Debug|Win32.ActiveCfg = Debug|Win32 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Debug|Win32.Build.0 = Debug|Win32 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Debug|x64.ActiveCfg = Debug|x64 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Debug|x64.Build.0 = Debug|x64 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Release|Win32.ActiveCfg = Release|Win32 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Release|Win32.Build.0 = Release|Win32 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Release|x64.ActiveCfg = Release|x64 + {44B21233-EFCC-4825-B5E5-3A3BD6CC5516}.Release|x64.Build.0 = Release|x64 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Debug|Win32.ActiveCfg = Debug|Win32 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Debug|Win32.Build.0 = Debug|Win32 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Debug|x64.ActiveCfg = Debug|x64 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Debug|x64.Build.0 = Debug|x64 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Release|Win32.ActiveCfg = Release|Win32 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Release|Win32.Build.0 = Release|Win32 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Release|x64.ActiveCfg = Release|x64 + {67AF56A4-A228-4BFB-BDA8-026CBEDE8BF9}.Release|x64.Build.0 = Release|x64 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Debug|Win32.ActiveCfg = Debug|Win32 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Debug|Win32.Build.0 = Debug|Win32 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Debug|x64.ActiveCfg = Debug|x64 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Debug|x64.Build.0 = Debug|x64 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Release|Win32.ActiveCfg = Release|Win32 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Release|Win32.Build.0 = Release|Win32 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Release|x64.ActiveCfg = Release|x64 + {1DDC11C7-AF79-40F3-A6D4-F84BA8644B5C}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff -r deecbb8ad448 code/nel/tools/nel_net_test/nel_net_test.vcproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/nel_net_test.vcproj Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_net_test/result.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/result.html Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,820 @@ + + + + + + + NeLTest Unit Tests Results + + + + + + +

NeLTest Unit Tests Results

+ +
+Designed by CppTest +
+
+ +

Summary

+ + + + + + + + + + + + + +
TestsErrorsSuccessTime (s)
66198%35.265000
+
+ +

Test suites

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTestsErrorsSuccessTime (s)
CUTMiscCoTask20100%0.000000
CUTMiscCommand50100%0.015000
CUTMiscConfigFile60100%0.032000
CUTMiscDebug20100%0.000000
CUTMiscDynLibLoad 10100%0.000000
CUTMiscFile40100%0.859000
CUTMiscPackFile110100%0.016000
CUTMiscSingleton20100%0.000000
CUTMiscSString10100%0.000000
CUTMiscStream40100%0.000000
CUTMiscVariable 10100%0.000000
CUTMiscTypes110%0.000000
CUTNetLayer310100%2.312000
CUTNetMessage30100%0.000000
CUTNetModule210100%32.031000
CUTLigoPrimitive10100%0.000000
+
+ +

Suite: CUTMiscCoTask

+ + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
runTasks0true0.000000
tasksAndThreads0true0.000000
+

Back to top +

+

Suite: CUTMiscCommand

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
createOneInstance0true0.015000
createAnotherInstance0true0.000000
deleteOneInstance0true0.000000
derivedClass0true0.000000
derivedClassAndBaseCall0true0.000000
+

Back to top +

+

Suite: CUTMiscConfigFile

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
configWithInclude0true0.016000
configWithOptional0true0.000000
configWithDefine0true0.000000
configWithBadTest0true0.000000
configIncludeAndOptional0true0.000000
reportErrorInSubFiles0true0.016000
+

Back to top +

+

Suite: CUTMiscDebug

+ + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
testInstanceCounter0true0.000000
testInstanceCounterOutput0true0.000000
+

Back to top +

+

Suite: CUTMiscDynLibLoad

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
libraryNameDecoration0true0.000000
+

Back to top +

+

Suite: CUTMiscFile

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
copyOneBigFile0true0.187000
copyDifferentFileSize0true0.203000
moveOneBigFile0true0.203000
moveDifferentFileSize0true0.266000
+

Back to top +

+

Suite: CUTMiscPackFile

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
addBnp0true0.000000
loadFromBnp0true0.000000
addXmlpack0true0.016000
loadFromXmlpack0true0.000000
compressMemory0true0.000000
loadFromBnpCompressed0true0.000000
loadFromXmlpackCompressed0true0.000000
decompressMemory0true0.000000
loadFromBnpUncompressed0true0.000000
loadFromXmlpackUncompressed0true0.000000
loadXmlpackWithSameName0true0.000000
+

Back to top +

+

Suite: CUTMiscSingleton

+ + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
createSingleton0true0.000000
accessSingleton0true0.000000
+

Back to top +

+

Suite: CUTMiscSString

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
testStrtok0true0.000000
+

Back to top +

+

Suite: CUTMiscStream

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
constAndStream0true0.000000
memStreamSwap0true0.000000
copyOnWrite0true0.000000
preallocatedBitStream0true0.000000
+

Back to top +

+

Suite: CUTMiscVariable

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
declareVar0true0.000000
+

Back to top +

+

Suite: CUTMiscTypes

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
basicTypes1false0.000000
+

Back to top +

+

Suite: CUTNetLayer3

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
sendReceiveUpdate0true2.312000
+

Back to top +

+

Suite: CUTNetMessage

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
messageSwap0true0.000000
lockSubMEssage0true0.000000
lockSubMEssageWithLongName0true0.000000
+

Back to top +

+

Suite: CUTNetModule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
testModuleInitInfoParsing0true0.000000
testModuleInitInfoQuering0true0.000000
testModuleInitInfoBadParsing0true0.000000
localModuleFactory0true0.016000
failedInit0true0.000000
createLocalGateway0true0.000000
plugLocalGateway0true0.000000
gatewayTransportManagement0true1.219000
connectGateways0true0.828000
moduleDisclosure0true1.328000
moduleMessaging0true1.625000
localMessageQueing0true0.609000
uniqueNameGenerator0true0.000000
gwPlugUnplug0true0.000000
peerInvisible0true3.453000
firewalling0true3.438000
distanceAndConnectionLoop0true6.109000
securityPlugin0true5.094000
synchronousMessaging0true1.031000
layer3Autoconnect0true6.672000
interceptorTest0true0.609000
+

Back to top +

+

Suite: CUTLigoPrimitive

+ + + + + + + + + + + + + +
NameErrorsSuccessTime (s)
testAliasGenerator0true0.000000
+

Back to top +

+
+ +

Test results

+

CUTMiscTypes::basicTypes

+ + + + + + + + + + + + + +
TestCUTMiscTypes::basicTypes
Filed:\ryzom\nel\tools\nel_unit_test\ut_misc_types.h:31
Messagesizeof(time_t) == sizeof(uint32)
+

Back to CUTMiscTypes +

+
+ + +

+ + Valid XHTML 1.0 Strict + +

+ + diff -r deecbb8ad448 code/nel/tools/nel_net_test/run_test.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/run_test.bat Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,2 @@ +nel_unit_test.exe --html +start result.html diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/cfg_with_bad_test.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/cfg_with_bad_test.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,23 @@ + +// insert a var just to prove we can't read it +ASimpleVar = "hello"; + +// A bad preprocessor command +# UnknowCommand + +// a closing endif without matching ifdef +#endif + +// a series of invalid command +#include blop // missing quote +#include "blop // missing closing quote +#optional blop +#optional "blop +#define *1234 // invalid label +#ifdef *1234 // still invalid label + + +// a opening ifdef not closed +#ifdef FOO + +// NB : do not close the #ifdef \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/cfg_with_define.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/cfg_with_define.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,34 @@ + +#define FOO +# define BAR + +#ifdef FOOBAR + this is an invalid content that should be ignored by parser +#endif + + # ifdef FOOBAR + this is another invalid content that should be + ignored by parser with some free alignement + +CfgNotToBeFound="iCan'tBeThere"; + # endif + +#ifdef FOO + // A simple var in a valid bloc +CfgReadableVar="You can see me"; +#endif + +// Multi test imbrication +#ifdef FOO // ok +# ifdef FOOBAR // not ok +# ifdef BAR // ok, but in a not ok scope +CfgInvisible = "You can't see me !"; +# endif +# endif +#endif + +#ifndef FOOBAR + // this one must exist + CfgMustExist="hello world"; +#endif + diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/cfg_with_error.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/cfg_with_error.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,22 @@ +// In this cfg, we introduce an error in a line after define and if clause + + +#define FOO + +#define BAR + +#ifdef FOO + // nothing +#endif + +#ifndef BAR + // nothing +#endif + + +// Here is the offending line, at line 18 +ABadVar iable = "foo"; + +// Some additionnal garbase lines + +AGoodVar = "bar"; diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/cfg_with_error_main.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/cfg_with_error_main.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,21 @@ +// This config file include the config file with error then generate an error +// WARNING : is you add lines, update the code in the test + + +#include "cfg_with_error.cfg" + +#define FOO +#define BAR + +#ifdef FOO + // nothing +#endif + +#ifndef BAR + // nothing +#endif + + +// Some additionnal garbase lines + +AGoodVar = "bar"; diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/cfg_with_include.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/cfg_with_include.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,10 @@ + + +#include "included_cfg.cfg" + +// #include "not_found_file.cfg" this include should not work +//#include "not_found_file.cfg" this include should not work +// not a valid include #include "not_found_file.cfg + + +CfgWithInclude = "ok"; diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/cfg_with_include_and_optional.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/cfg_with_include_and_optional.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,5 @@ +// include of a missing file, should generate a warning +#include "a_missing_file.cfg" + +// optional include a a missing file, just issue an info log +#optional "a_missing_file.cfg" diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/cfg_with_optional.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/cfg_with_optional.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,10 @@ + + +#optional "included_cfg.cfg" + +// #include "not_found_file.cfg" this include should not work +//#include "not_found_file.cfg" this include should not work +// not a valid include #include "not_found_file.cfg + + +CfgWithInclude = "ok"; diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/file1_in_bnp.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/file1_in_bnp.txt Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ +The content of the first file \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/file2_in_bnp.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/file2_in_bnp.txt Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ +Another content but for the second file \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/files.bnp Binary file code/nel/tools/nel_net_test/ut_misc_files/files.bnp has changed diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/files.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/files.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,11 @@ + + +The content of the first file + + +Another content but for the second file + + +The content of the first fileAnother content but for the second file + + diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/.xml_pack_index --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/.xml_pack_index Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,2 @@ +file1_in_sub_1.xml +file2_in_sub_1.xml diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/file1_in_sub_1.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/file1_in_sub_1.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/file2_in_sub_1.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/file2_in_sub_1.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/samename.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/files_for_xml_subpack/same_subfolder_1/samename/samename.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,8 @@ + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/.xml_pack_index --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/.xml_pack_index Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,2 @@ +file1_in_sub_2.xml +file2_in_sub_2.xml diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/file1_in_sub_2.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/file1_in_sub_2.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/file2_in_sub_2.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/file2_in_sub_2.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/samename.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/files_for_xml_subpack/same_subfolder_2/samename/samename.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,8 @@ + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/included_cfg.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/included_cfg.cfg Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,3 @@ + +IncludedCfg = "ok"; + diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/xml_files/file1_in_xml_pack.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/xml_files/file1_in_xml_pack.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/xml_files/file2_in_xml_pack.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/xml_files/file2_in_xml_pack.xml Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/xml_files/same_subfolder_1/samename/samename.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/xml_files/same_subfolder_1/samename/samename.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,8 @@ + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/xml_files/same_subfolder_2/samename/samename.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/xml_files/same_subfolder_2/samename/samename.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,8 @@ + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_misc_files/xml_files/xml_files.xml_pack --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_misc_files/xml_files/xml_files.xml_pack Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,8 @@ + + + + + + + + diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_net.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_net.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,38 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_NET +#define UT_NET + +#include + +#include "ut_net_layer3.h" +#include "ut_net_message.h" +#include "ut_net_module.h" +// Add a line here when adding a new test CLASS + +struct CUTNet : public Test::Suite +{ + CUTNet() + { + add(auto_ptr(new CUTNetLayer3)); + add(auto_ptr(new CUTNetMessage)); + add(auto_ptr(new CUTNetModule)); + // Add a line here when adding a new test CLASS + } +}; + +#endif diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_net_layer3.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_net_layer3.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,207 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_NET_LAYER3 +#define UT_NET_LAYER3 + +#include +#include + +uint16 TestPort1 = 56000; + +uint NbTestReceived = 0; + +NLNET::CMessage msgoutExpectingAnswer0, msgoutSimple0, msgoutSimple50; + +// Data structure for messages +struct TData +{ + string PayloadString; + bool ExpectingAnswer; + + // Constructor + TData() : ExpectingAnswer(false) {} + + // Serial + void serial( NLMISC::IStream& s ) + { + s.serial( PayloadString ); + s.serial( ExpectingAnswer ); + } +}; + +// This callback must not take more than 10 ms +void cbTest( NLNET::CMessage &msgin, NLNET::TSockId from, NLNET::CCallbackNetBase &netbase ) +{ + NLMISC::TTime before = NLMISC::CTime::getLocalTime(); + + // Read data from the message + TData data; + msgin.serial( data ); + if ( data.PayloadString == "Payload" ) + ++NbTestReceived; + + // Send the answer if required + if ( data.ExpectingAnswer ) + netbase.send( msgoutSimple0, from ); + + // Check that the duration is compatible with our timeout tests + NLMISC::TTime maxDuration; + if ( msgin.getName() == "TEST_50" ) + { + while ( NLMISC::CTime::getLocalTime() - before < 49 ); // wait + maxDuration = 70; + } + else + maxDuration = 10; + NLMISC::TTime actualDuration = NLMISC::CTime::getLocalTime() - before; + if ( actualDuration > maxDuration ) + nlerror( "The callback cbTest takes too long (%u) for %s, please fix the test", (uint)actualDuration, msgin.getName().c_str() ); +} + + +static NLNET::TCallbackItem CallbackArray[] = +{ + { "TEST_0", cbTest }, + { "TEST_50", cbTest } +}; + + +// Test suite for layer 3 +class CUTNetLayer3: public Test::Suite +{ +public: + + // + CUTNetLayer3 () + { + _Server = NULL; + _Client = NULL; + TEST_ADD(CUTNetLayer3::sendReceiveUpdate); + + } + + // + ~CUTNetLayer3 () + { + if ( _Server ) + delete _Server; + _Server = NULL; + if ( _Client ) + delete _Client; + _Client = NULL; + } + + // + void sendReceiveUpdate() + { + // Prepare messages for tests + TData data; + data.PayloadString = "Payload"; + data.ExpectingAnswer = true; + msgoutExpectingAnswer0.clear(); // optional + msgoutExpectingAnswer0.setType( "TEST_0" ); // could be passed to the constructor + msgoutExpectingAnswer0.serial( data ); + data.ExpectingAnswer = false; + msgoutSimple0.clear(); // optional + msgoutSimple0.setType( "TEST_0" ); // could be passed to the constructor + msgoutSimple0.serial( data ); + msgoutSimple50.clear(); // optional + msgoutSimple50.setType( "TEST_50" ); // could be passed to the constructor + msgoutSimple50.serial( data ); + + // Init connections + _Server = new NLNET::CCallbackServer(); + _Server->init( TestPort1 ); + _Server->addCallbackArray( CallbackArray, sizeof(CallbackArray)/sizeof(NLNET::TCallbackItem) ); + _Client = new NLNET::CCallbackClient(); + _Client->connect( NLNET::CInetAddress( "localhost", TestPort1 ) ); + _Client->addCallbackArray( CallbackArray, sizeof(CallbackArray)/sizeof(NLNET::TCallbackItem) ); + + // TEST: Simple message transmission + NbTestReceived = 0; + _Client->send( msgoutExpectingAnswer0 ); + for ( uint i=0; i!=10; ++i ) // give some time to receive + { + _Client->update(); + _Server->update(); // legacy version + NLMISC::nlSleep( 50 ); + } + TEST_ASSERT( NbTestReceived == 2 ); // answer and reply + + // TEST: ONE-SHOT update mode on the receiver + NbTestReceived = 0; + for ( uint i=0; i!=20; ++i ) // send 20 messages + _Client->send( msgoutSimple0 ); + while ( NbTestReceived < 20 ) + { + _Client->update2(); + uint prevNbTestReceived = NbTestReceived; + _Server->update2( 0 ); // shortest time-out = ONE-SHOT mode + TEST_ASSERT( (NbTestReceived == prevNbTestReceived) || + (NbTestReceived == prevNbTestReceived + 1) ); + NLMISC::nlSleep( 10 ); + } + + // TEST: GREEDY update mode on the receiver + NbTestReceived = 0; + for ( uint i=0; i!=20; ++i ) // send 20 messages + _Client->send( msgoutSimple0 ); + for ( uint i=0; i!=10; ++i ) // make sure all messages are flushed + { + _Client->update2(); + NLMISC::nlSleep( 10 ); + } + _Server->update2( -1 ); // receive all + TEST_ASSERT( NbTestReceived == 20 ); + + // TEST: CONSTRAINED update mode on the receiver + NbTestReceived = 0; + for ( uint i=0; i!=20; ++i ) // send 20 messages that will trigger a time-consuming callback + _Client->send( msgoutSimple50 ); + for ( uint i=0; i!=10; ++i ) // make sure all messages are flushed + { + _Client->update2(); + NLMISC::nlSleep( 10 ); + } + while ( NbTestReceived < 20 ) + { + uint prevNbTestReceived = NbTestReceived; + _Server->update2( 80 ); // no more time than two callback executions + TEST_ASSERT( NbTestReceived <= prevNbTestReceived + 2 ); + } + + // TEST: CONSTRAINED with minTime update mode on the receiver + NbTestReceived = 0; + while ( NbTestReceived < 20 ) + { + _Client->send( msgoutSimple0 ); + _Client->send( msgoutSimple0 ); // send 2 messages at a time + _Client->update2(); + NLMISC::TTime before = NLMISC::CTime::getLocalTime(); + _Server->update2( -1, 30 ); + NLMISC::TTime duration = NLMISC::CTime::getLocalTime() - before; + TEST_ASSERT( duration >= 30 ); + } + } + +private: + NLNET::CCallbackServer *_Server; + NLNET::CCallbackClient *_Client; + +}; + +#endif diff -r deecbb8ad448 code/nel/tools/nel_net_test/ut_net_message.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code/nel/tools/nel_net_test/ut_net_message.h Fri Dec 03 03:17:09 2010 +0200 @@ -0,0 +1,301 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_NET_MESSAGE +#define UT_NET_MESSAGE + +class CUTNetMessage: public Test::Suite +{ +public: + CUTNetMessage () + { + TEST_ADD(CUTNetMessage::messageSwap); + TEST_ADD(CUTNetMessage::lockSubMEssage); + TEST_ADD(CUTNetMessage::lockSubMEssageWithLongName); + + } + + void lockSubMEssageWithLongName() + { + NLNET::CMessage master("BIG"); + + // serial some stuff + for (uint8 i=0; i<10; ++i) + { + master.serial(i); + } + + uint32 sizes[4]; + + // serial 4 sub messages + for (uint i=0; i<4; ++i) + { + NLNET::CMessage sub(NLMISC::toString("A_VERY_LONG_SUB_MESSAGE_NAME_%u", i)); + + for (uint8 j=0; j +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef UT_NET_MODULE +#define UT_NET_MODULE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class CModuleType0 : public NLNET::CModuleBase +{ +public: + + uint PingCount; + uint ResponseReceived; + + set ModuleType0; + + uint32 ModuleUpCalled; + uint32 ModuleDownCalled; + uint32 ProcessMessageCalled; + uint32 SecurityUpdateCalled; + + + CModuleType0() + : PingCount(0), + ResponseReceived(0) + { + ModuleUpCalled = 0; + ModuleDownCalled = 0; + ProcessMessageCalled = 0; + SecurityUpdateCalled = 0; + } + + std::string buildModuleManifest() const + { + return "CModuleType0"; + } + + bool initModule(const NLNET::TParsedCommandLine ¶m) + { + bool ret = CModuleBase::initModule(param); + if (param.getParam("FAIL") != NULL) + return false; + + return ret; + } + + void onServiceUp(const std::string &serviceName, NLNET::TServiceId serviceId) + { + } + /// A nel layer 5 service has stopped. + void onServiceDown(const std::string &serviceName, NLNET::TServiceId serviceId) + { + } + void onModuleUpdate() + { + } + /** The service main loop is terminating it job', all module will be + * disconnected and removed after this callback. + */ + void onApplicationExit() + { + } + + void onModuleUp(NLNET::IModuleProxy *moduleProxy) + { + ModuleUpCalled++; + + if (moduleProxy->getModuleClassName() == getModuleClassName()) + ModuleType0.insert(moduleProxy); + } + /** Called by a socket to inform this module that another + * module has been deleted OR has been no more accessible (due to + * some gateway disconnection). + */ + void onModuleDown(NLNET::IModuleProxy *moduleProxy) + { + ModuleDownCalled++; + + if (moduleProxy->getModuleClassName() == getModuleClassName()) + ModuleType0.erase(moduleProxy); + } + + bool onProcessModuleMessage(NLNET::IModuleProxy *senderModuleProxy, const NLNET::CMessage &message) + { + ProcessMessageCalled++; + + if (message.getName() == "DEBUG_MOD_PING") + { + PingCount++; + return true; + } + else if (message.getName() == "HELLO") + { + NLNET::CMessage ping("DEBUG_MOD_PING"); + senderModuleProxy->sendModuleMessage(this, NLNET::CMessage(ping)); + senderModuleProxy->sendModuleMessage(this, NLNET::CMessage(ping)); + { + NLNET::CMessage resp; + resp.setType("HELLO_RESP", NLNET::CMessage::Response); + + senderModuleProxy->sendModuleMessage(this, resp); + } + senderModuleProxy->sendModuleMessage(this, NLNET::CMessage(ping)); + senderModuleProxy->sendModuleMessage(this, NLNET::CMessage(ping)); + return true; + } + else if (message.getName() == "HELLO2") + { + // the response for the life, the universe and all other things... + throw 42; + + return true; + } + + return false; + } + + void onModuleSecurityChange(NLNET::IModuleProxy *moduleProxy) + { + SecurityUpdateCalled++; + } + + void onModuleSocketEvent(NLNET::IModuleSocket *moduleSocket, IModule::TModuleSocketEvent eventType) + { + } + + void startTaskA() + { + // start a task on module + NLNET_START_MODULE_TASK(CModuleType0, taskA); + } + + // test task A + void taskA() + { + // use the first like me in the list + nlassert(!ModuleType0.empty()); + + NLNET::TModuleProxyPtr proxy = *ModuleType0.begin(); + + NLNET::CMessage msg; + msg.setType("HELLO", NLNET::CMessage::Request); + NLNET::CMessage resp; + invokeModuleOperation(proxy, msg, resp); + + nlassert(resp.getName() == "HELLO_RESP"); + + ResponseReceived++; + } + + void startTaskB() + { + // start a task on module + NLNET_START_MODULE_TASK(CModuleType0, taskB); + } + + // test task B + void taskB() + { + // use the first like me in the list + nlassert(!ModuleType0.empty()); + + NLNET::TModuleProxyPtr proxy = *ModuleType0.begin(); + + NLNET::CMessage msg; + msg.setType("HELLO2", NLNET::CMessage::Request); + NLNET::CMessage resp; + + try + { + invokeModuleOperation(proxy, msg, resp); + } + catch(IModule::EInvokeFailed) + { + ResponseReceived++; + } + } + +}; + +NLNET_REGISTER_MODULE_FACTORY(CModuleType0, "ModuleType0"); + +// A module that doesn't support immediate dispatching +class CModuleAsync : public CModuleType0 +{ +public: + + bool isImmediateDispatchingSupported() const + { + return false; + } +}; + +NLNET_REGISTER_MODULE_FACTORY(CModuleAsync, "ModuleAsync"); + +enum TTestSecurityTypes +{ + tst_type1, + tst_type2, + tst_type3, + tst_type4, +}; + +// security type 1 data : contains host gateway name +struct TSecurityType1 : public NLNET::TSecurityData +{ + string SecurityGatewayName; + + TSecurityType1(const TCtorParam ¶m) + : NLNET::TSecurityData(param) + { + } + + void serial(NLMISC::CMemStream &s) + { + s.serial(SecurityGatewayName); + } + +}; + +NLMISC_REGISTER_OBJECT(NLNET::TSecurityData, TSecurityType1, uint8, tst_type1); + + +// security type 2 data : contains host gateway name and a predefined integer value +struct TSecurityType2 : public NLNET::TSecurityData +{ + string SecurityGatewayName; + uint32 IntegerValue; + + TSecurityType2(const TCtorParam ¶m) + : NLNET::TSecurityData(param) + { + IntegerValue = 0x12345678; + } + + void serial(NLMISC::CMemStream &s) + { + s.serial(SecurityGatewayName); + s.serial(IntegerValue); + } +}; + +NLMISC_REGISTER_OBJECT(NLNET::TSecurityData, TSecurityType2, uint8, tst_type2); + + +// security type 3 data, same as type 1 +struct TSecurityType3 : public NLNET::TSecurityData +{ + string SecurityGatewayName; + + TSecurityType3(const TCtorParam ¶m) + : NLNET::TSecurityData(param) + { + } + + void serial(NLMISC::CMemStream &s) + { + s.serial(SecurityGatewayName); + } + +}; +NLMISC_REGISTER_OBJECT(NLNET::TSecurityData, TSecurityType3, uint8, tst_type3); + +// security type 4 data, same as type 1 but not registered +struct TSecurityType4 : public NLNET::TSecurityData +{ + string SecurityGatewayName; + + TSecurityType4(const TCtorParam ¶m) + : NLNET::TSecurityData(param) + { + } + + void serial(NLMISC::CMemStream &s) + { + s.serial(SecurityGatewayName); + } +}; + +/** a sample security plug-in that add type 1 security data to local modules, + * type 2 security to foreign module, + * and that remove received type 1 security from foreign module + */ +class CTestSecurity1 : public NLNET::CGatewaySecurity +{ +public: + CTestSecurity1(const TCtorParam ¶ms) + : NLNET::CGatewaySecurity(params) + {} + + virtual void onNewProxy(NLNET::IModuleProxy *proxy) + { + if (proxy->getGatewayRoute() == NULL) + { + // add a type 1 security + TSecurityType1 *st1 = new TSecurityType1(NLNET::TSecurityData::TCtorParam(tst_type1)); + st1->SecurityGatewayName = _Gateway->getFullyQualifiedGatewayName(); + + setSecurityData(proxy, st1); + } + else + { + // remove any type 1 data and set a type 2 data + removeSecurityData(proxy, tst_type1); + TSecurityType2 *st2 = new TSecurityType2(NLNET::TSecurityData::TCtorParam(tst_type2)); + st2->SecurityGatewayName = _Gateway->getFullyQualifiedGatewayName(); + + setSecurityData(proxy, st2); + } + + forceSecurityUpdate(proxy); + } + + void onNewSecurityData(NLNET::CGatewayRoute *from, NLNET::IModuleProxy *proxy, NLNET::TSecurityData *firstSecurityData) + { + // replace the complete security set + replaceAllSecurityDatas(proxy, firstSecurityData); + // remove any type 1 data and set a type 2 data + removeSecurityData(proxy, tst_type1); + TSecurityType2 *st2 = new TSecurityType2(NLNET::TSecurityData::TCtorParam(tst_type2)); + st2->SecurityGatewayName = _Gateway->getFullyQualifiedGatewayName(); + + setSecurityData(proxy, st2); + + // we don't need to update in this case (update is always done by gateway) + } + + virtual void onDelete() + { + vector proxies; + _Gateway->getModuleProxyList(proxies); + + // remove any security data managed by this plug-in + for (uint i=0; igetFirstSecurityData() != NULL) + { + bool update = false; + update |= removeSecurityData(proxy, tst_type1); + update |= removeSecurityData(proxy, tst_type2); + if (update) + forceSecurityUpdate(proxy); + } + } + } + +}; +NLMISC_REGISTER_OBJECT(NLNET::CGatewaySecurity, CTestSecurity1, std::string, "TestSecurity1"); + +/** a sample security plug-in that add type 3 and type 4 security data to local modules, + */ +class CTestSecurity2 : public NLNET::CGatewaySecurity +{ +public: + CTestSecurity2(const TCtorParam ¶ms) + : NLNET::CGatewaySecurity(params) + {} + + virtual void onNewProxy(NLNET::IModuleProxy *proxy) + { + if (proxy->getGatewayRoute() == NULL) + { + // add a type 3 security + TSecurityType3 *st3 = new TSecurityType3(NLNET::TSecurityData::TCtorParam(tst_type3)); + st3->SecurityGatewayName = _Gateway->getFullyQualifiedGatewayName(); + setSecurityData(proxy, st3); + // add a type 4 security + TSecurityType4 *st4 = new TSecurityType4(NLNET::TSecurityData::TCtorParam(tst_type4)); + st4->SecurityGatewayName = _Gateway->getFullyQualifiedGatewayName(); + setSecurityData(proxy, st4); + forceSecurityUpdate(proxy); + } + } + + void onNewSecurityData(NLNET::CGatewayRoute *from, NLNET::IModuleProxy *proxy, NLNET::TSecurityData *firstSecurityData) + { + // replace the complete security set + replaceAllSecurityDatas(proxy, firstSecurityData); + } + + virtual void onDelete() + { + vector proxies; + _Gateway->getModuleProxyList(proxies); + + // remove any security data managed by this plug-in + for (uint i=0; igetGatewayRoute() == NULL) + { + removeSecurityData(proxy, tst_type3); + removeSecurityData(proxy, tst_type4); + forceSecurityUpdate(proxy); + } + } + } +}; +NLMISC_REGISTER_OBJECT(NLNET::CGatewaySecurity, CTestSecurity2, std::string, "TestSecurity2"); + + +// A module interceptor +class CInterceptor : public NLNET::IModuleInterceptable +{ +public: + string Name; + uint32 ModuleUpCalled; + uint32 ModuleDownCalled; + uint32 ProcessMessageCalled; + uint32 SecurityUpdateCalled; + + CInterceptor(NLNET::IInterceptorRegistrar *registrar, const string &name) + : Name(name) + { + NLNET::IModuleInterceptable::registerInterceptor(registrar), + ModuleUpCalled = 0; + ModuleDownCalled = 0; + ProcessMessageCalled = 0; + SecurityUpdateCalled = 0; + } + + virtual std::string buildModuleManifest() const + { + return Name; + } + + virtual void onModuleUp(NLNET::IModuleProxy *moduleProxy) + { + ModuleUpCalled++; + } + + virtual void onModuleDown(NLNET::IModuleProxy *moduleProxy) + { + ModuleDownCalled++; + } + + virtual bool onProcessModuleMessage(NLNET::IModuleProxy *senderModuleProxy, const NLNET::CMessage &message) + { + ProcessMessageCalled++; + return false; + } + + virtual void onModuleSecurityChange(NLNET::IModuleProxy *moduleProxy) + { + SecurityUpdateCalled++; + } +}; + +// Test suite for Modules class +class CUTNetModule : public Test::Suite +{ + string _WorkingPath; + string _RestorePath; + +public: + // utility to look for a specified proxy in a vector of proxy + // return true if the proxy if found + bool lookForModuleProxy(const vector proxList, const std::string &modName) + { + for (uint i=0; igetModuleName().find(modName) == (proxList[i]->getModuleName().size() - modName.size())) + return true; + } + + return false; + } + + NLNET::IModuleProxy *retrieveModuleProxy(NLNET::IModuleGateway *gw, const std::string &modName) + { + vector proxList; + gw->getModuleProxyList(proxList); + + for (uint i=0; igetModuleName().find(modName) == (proxList[i]->getModuleName().size() - modName.size())) + return proxList[i]; + } + + return NULL; + } + + void setup() + { + _RestorePath = NLMISC::CPath::getCurrentPath(); + + NLMISC::CPath::setCurrentPath(_WorkingPath.c_str()); + } + + void tear_down() + { + NLMISC::CPath::setCurrentPath(_RestorePath.c_str()); + } + + CUTNetModule () + { + TEST_ADD(CUTNetModule::testModuleInitInfoParsing); + TEST_ADD(CUTNetModule::testModuleInitInfoQuering); + TEST_ADD(CUTNetModule::testModuleInitInfoBadParsing); + TEST_ADD(CUTNetModule::localModuleFactory); + //TEST_ADD(CUTNetModule::loadModuleLib); + //TEST_ADD(CUTNetModule::createModule); + //TEST_ADD(CUTNetModule::deleteModule); + TEST_ADD(CUTNetModule::failedInit); + //TEST_ADD(CUTNetModule::unloadModuleLib); + TEST_ADD(CUTNetModule::createLocalGateway); + TEST_ADD(CUTNetModule::plugLocalGateway); + //TEST_ADD(CUTNetModule::moduleManagerCommands); + TEST_ADD(CUTNetModule::gatewayTransportManagement); + TEST_ADD(CUTNetModule::connectGateways); + TEST_ADD(CUTNetModule::moduleDisclosure); + TEST_ADD(CUTNetModule::moduleMessaging); + TEST_ADD(CUTNetModule::localMessageQueing); + TEST_ADD(CUTNetModule::uniqueNameGenerator); + TEST_ADD(CUTNetModule::gwPlugUnplug); + TEST_ADD(CUTNetModule::peerInvisible); + TEST_ADD(CUTNetModule::firewalling); + TEST_ADD(CUTNetModule::distanceAndConnectionLoop); + TEST_ADD(CUTNetModule::securityPlugin); + TEST_ADD(CUTNetModule::synchronousMessaging); + TEST_ADD(CUTNetModule::layer3Autoconnect); + TEST_ADD(CUTNetModule::interceptorTest); + } + + void interceptorTest() + { + // Check that the interceptor system. + + // TODO : right now, there is no test of the security update call + + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + NLMISC::CCommandRegistry &cr = NLMISC::CCommandRegistry::getInstance(); + + // create the modules + NLNET::IModule *gw = mm.createModule("StandardGateway", "gw", ""); + NLNET::IModule *mod = mm.createModule("ModuleType0", "mod", ""); + NLNET::IModuleGateway *gGw = dynamic_cast(gw); + CModuleType0 *mod0 = dynamic_cast(mod); + + TEST_ASSERT(gGw != NULL); + TEST_ASSERT(mod0 != NULL); + + // create the interceptors and attach it to the mod0 + CInterceptor *inter0 = new CInterceptor(mod, "Inter0"); + CInterceptor *inter1 = new CInterceptor(mod, "Inter1"); + + // plug the modules + cr.execute("gw.plug gw", NLMISC::InfoLog()); + cr.execute("mod.plug gw", NLMISC::InfoLog()); + + // update the network + for (uint i=0; i<5; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(40); + } + + // send a message to the module fro; the gateway + NLNET::CMessage msg("foo"); + NLNET::IModuleProxy *modProx = retrieveModuleProxy(gGw, "mod"); + TEST_ASSERT(modProx != NULL); + modProx->sendModuleMessage(gw, msg); + + // update the network + for (uint i=0; i<5; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(40); + } + + // check the module manifest + TEST_ASSERT(modProx->getModuleManifest() == "CModuleType0 Inter0 Inter1"); + + // unplug the modules + cr.execute("gw.unplug gw", NLMISC::InfoLog()); + cr.execute("mod.unplug gw", NLMISC::InfoLog()); + + // update the network + for (uint i=0; i<5; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(40); + } + + // now check that all methods have been called in that + // module and in the two interceptors, + // also check the manifest string content. + TEST_ASSERT(mod0->ModuleUpCalled == 1); + TEST_ASSERT(mod0->ModuleDownCalled == 1); + TEST_ASSERT(mod0->ProcessMessageCalled == 1); +// TEST_ASSERT(mod0->SecurityUpdateCalled); + + TEST_ASSERT(inter0->ModuleUpCalled == 1); + TEST_ASSERT(inter0->ModuleDownCalled == 1); + TEST_ASSERT(inter0->ProcessMessageCalled == 1); +// TEST_ASSERT(inter0->SecurityUpdateCalled); + + TEST_ASSERT(inter1->ModuleUpCalled == 1); + TEST_ASSERT(inter1->ModuleDownCalled == 1); + TEST_ASSERT(inter1->ProcessMessageCalled == 1); +// TEST_ASSERT(inter1->SecurityUpdateCalled); + + + // delete the modules + mm.deleteModule(gw); + mm.deleteModule(mod); + + // delete the interceptors + delete inter0; + delete inter1; + } + + void layer3Autoconnect() + { + // Check that layer 3 client can automatically reconnect in case of server + // down/up + // + // We create two gateway, gw1 and gw2, plugged in themselves, then we create + // a layer 3 client on gw1, update the network, then we create the layer 3 server + // on gw2, update the network then check that module are connected. + // + // Then we close the L3 server on gw2, update the network, check that module + // are diconnected and reopen the L3 server and recheck that module are connected. + // + // + + + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + NLMISC::CCommandRegistry &cr = NLMISC::CCommandRegistry::getInstance(); + + // create the modules + NLNET::IModule *gw1 = mm.createModule("StandardGateway", "gw1", ""); + NLNET::IModule *gw2 = mm.createModule("StandardGateway", "gw2", ""); + NLNET::IModuleGateway *gGw1 = dynamic_cast(gw1); + NLNET::IModuleGateway *gGw2 = dynamic_cast(gw2); + + // plug gateway in themselves + cr.execute("gw1.plug gw1", NLMISC::InfoLog()); + cr.execute("gw2.plug gw2", NLMISC::InfoLog()); + + // create the client transport + cr.execute("gw1.transportAdd L3Client l3c", NLMISC::InfoLog()); + cr.execute("gw1.transportCmd l3c(retryInterval=1)", NLMISC::InfoLog()); + cr.execute("gw1.transportCmd l3c(connect addr=localhost:8062)", NLMISC::InfoLog()); + + // update the network + for (uint i=0; i<5; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(40); + } + + TEST_ASSERT(retrieveModuleProxy(gGw1, "gw2") == NULL); + TEST_ASSERT(retrieveModuleProxy(gGw1, "gw2") == NULL); + + // open the server + cr.execute("gw2.transportAdd L3Server l3s", NLMISC::InfoLog()); + cr.execute("gw2.transportCmd l3s(open port=8062)", NLMISC::InfoLog()); + + // update the network (give more time because we must cover the Layer3 client reconnection timer) + for (uint i=0; i<40; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(50); + } + + // check module connectivity + TEST_ASSERT(retrieveModuleProxy(gGw1, "gw2") != NULL); + TEST_ASSERT(retrieveModuleProxy(gGw1, "gw2") != NULL); + + // exchange some message + cr.execute("gw1.sendPing "+gw2->getModuleFullyQualifiedName(), NLMISC::InfoLog()); + cr.execute("gw2.sendPing "+gw1->getModuleFullyQualifiedName(), NLMISC::InfoLog()); + + // update the network + for (uint i=0; i<5; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(40); + } + + // check the ping counter + TEST_ASSERT(gGw1->getReceivedPingCount() == 1); + TEST_ASSERT(gGw2->getReceivedPingCount() == 1); + + // flood a little with ping + for (uint i=0; i<100; ++i) + cr.execute("gw1.sendPing "+gw2->getModuleFullyQualifiedName(), NLMISC::InfoLog()); + + // close the server + cr.execute("gw2.transportCmd l3s(close)", NLMISC::InfoLog()); + + // update the network + for (uint i=0; i<5; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(40); + } + + // test no connectivity + TEST_ASSERT(retrieveModuleProxy(gGw1, "gw2") == NULL); + TEST_ASSERT(retrieveModuleProxy(gGw2, "gw1") == NULL); + + // re-open the server + cr.execute("gw2.transportCmd l3s(open port=8062)", NLMISC::InfoLog()); + + // update the network (give more time because we must cover the Layer3 client reconnection timer) + for (uint i=0; i<40; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(50); + } + + // check module connectivity + TEST_ASSERT(retrieveModuleProxy(gGw1, "gw2") != NULL); + TEST_ASSERT(retrieveModuleProxy(gGw2, "gw1") != NULL); + + // exchange some message + cr.execute("gw1.sendPing "+gw2->getModuleFullyQualifiedName(), NLMISC::InfoLog()); + cr.execute("gw2.sendPing "+gw1->getModuleFullyQualifiedName(), NLMISC::InfoLog()); + + // update the network + for (uint i=0; i<5; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(40); + } + + // check the ping counter + TEST_ASSERT(gGw1->getReceivedPingCount() == 2); + TEST_ASSERT(gGw2->getReceivedPingCount() == 2); + + // cleanup modules + mm.deleteModule(gw1); + mm.deleteModule(gw2); + } + + void synchronousMessaging() + { + // check that the synchronous messaging is working + // by using module task + + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + NLMISC::CCommandRegistry &cr = NLMISC::CCommandRegistry::getInstance(); + + + // create the modules + NLNET::IModule *gw = mm.createModule("StandardGateway", "gw", ""); + NLNET::IModule *m1 = mm.createModule("ModuleType0", "m1", ""); + NLNET::IModule *m2 = mm.createModule("ModuleType0", "m2", ""); + + // plug the two modules in the gateway + cr.execute("m1.plug gw", NLMISC::InfoLog()); + cr.execute("m2.plug gw", NLMISC::InfoLog()); + + // update the network + for (uint i=0; i<15; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(40); + } + + CModuleType0 *mod1 = dynamic_cast(m1); + + // start a task on module 1 + mod1->startTaskA(); + + // update the network + for (uint i=0; i<5; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(40); + } + + + TEST_ASSERT(mod1->PingCount == 4); + TEST_ASSERT(mod1->ResponseReceived == 1); + + // start a task on module 1 + mod1->startTaskB(); + + // update the network + for (uint i=0; i<5; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(40); + } + + + TEST_ASSERT(mod1->PingCount == 4); + TEST_ASSERT(mod1->ResponseReceived == 2); + mm.deleteModule(m1); + mm.deleteModule(m2); + mm.deleteModule(gw); + } + + void securityPlugin() + { + // Check that security plug-in work well. + // + // We connect three gateway in series with the central gateway + // using a security module that adds security data to + // proxies : + // For local proxies, it adds type 1 security data + // For foreign proxies, it adds type 2 security data + // for foreign proxies, it removes any type 1 security data found + // + // gw1 (l3c) -------- (l3s) gw2 (l3c) ------ (l3s) gw3 + // ^ ^ + // | | + // SecurityPlugin2 SecurityPlugin1 + // + // After connecting and plugging-in each gateway into themselves, + // we check the presence and content of the security datas. + // then we remove the securityPlugin1 and check that all + // security data have been removed, + // Then, we re create the securityPlugin1 and recheck + // then one again, we remove it and recheck. + // + // For the second part of the check, we create a security + // plug-in 2 on gw1 that add 'type3' security data on + // local plug-in. + // We also plug the security plug-in 1 and then we check that + // we have the correct security data + + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + NLMISC::CCommandRegistry &cr = NLMISC::CCommandRegistry::getInstance(); + + NLNET::IModule *gw1, *gw2, *gw3; + + // create the modules + gw1 = mm.createModule("StandardGateway", "gw1", ""); + gw2 = mm.createModule("StandardGateway", "gw2", ""); + gw3 = mm.createModule("StandardGateway", "gw3", ""); + + TEST_ASSERT(gw1 != NULL); + TEST_ASSERT(gw2 != NULL); + TEST_ASSERT(gw3 != NULL); + + // plug gateway in themselves + NLNET::IModuleSocket *sGw1, *sGw2, *sGw3; + sGw1 = mm.getModuleSocket("gw1"); + sGw2 = mm.getModuleSocket("gw2"); + sGw3 = mm.getModuleSocket("gw3"); + + TEST_ASSERT(sGw1 != NULL); + TEST_ASSERT(sGw2 != NULL); + TEST_ASSERT(sGw3 != NULL); + + gw1->plugModule(sGw1); + gw2->plugModule(sGw2); + gw3->plugModule(sGw3); + + string cmd; + // create security plug-in + cmd = "gw2.securityCreate TestSecurity1"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // create the transports + cmd = "gw1.transportAdd L3Client l3c"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw2.transportAdd L3Client l3c"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw2.transportAdd L3Server l3s"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw3.transportAdd L3Server l3s"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // connect transport + cmd = "gw2.transportCmd l3s(open port=8062)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw3.transportCmd l3s(open port=8063)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw1.transportCmd l3c(connect addr=localhost:8062)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw2.transportCmd l3c(connect addr=localhost:8063)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + + for (uint retry = 0; retry < 2; ++retry) + { + if (retry > 0) + { + // recreate the security plug-in + cmd = "gw2.securityCreate TestSecurity1"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + } + // update the network + for (uint i=0; i<15; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(40); + } + NLNET::IModuleGateway *gGw1, *gGw2, *gGw3; + gGw1 = dynamic_cast(gw1); + TEST_ASSERT(gGw1 != NULL); + gGw2 = dynamic_cast(gw2); + TEST_ASSERT(gGw2 != NULL); + gGw3 = dynamic_cast(gw3); + TEST_ASSERT(gGw3 != NULL); + + + // check security data + NLNET::IModuleProxy *proxGw1_1, *proxGw2_1, *proxGw3_1; + NLNET::IModuleProxy *proxGw1_2, *proxGw2_2, *proxGw3_2; + NLNET::IModuleProxy *proxGw1_3, *proxGw2_3, *proxGw3_3; + + proxGw1_1 = retrieveModuleProxy(gGw1, "gw1"); + proxGw2_1 = retrieveModuleProxy(gGw1, "gw2"); + proxGw3_1 = retrieveModuleProxy(gGw1, "gw3"); + proxGw1_2 = retrieveModuleProxy(gGw2, "gw1"); + proxGw2_2 = retrieveModuleProxy(gGw2, "gw2"); + proxGw3_2 = retrieveModuleProxy(gGw2, "gw3"); + proxGw1_3 = retrieveModuleProxy(gGw3, "gw1"); + proxGw2_3 = retrieveModuleProxy(gGw3, "gw2"); + proxGw3_3 = retrieveModuleProxy(gGw3, "gw3"); + + TEST_ASSERT(proxGw1_1 != NULL); + TEST_ASSERT(proxGw2_1 != NULL); + TEST_ASSERT(proxGw3_1 != NULL); + TEST_ASSERT(proxGw1_2 != NULL); + TEST_ASSERT(proxGw2_2 != NULL); + TEST_ASSERT(proxGw3_2 != NULL); + TEST_ASSERT(proxGw1_3 != NULL); + TEST_ASSERT(proxGw2_3 != NULL); + TEST_ASSERT(proxGw3_3 != NULL); + + const NLNET::TSecurityData *ms; + const TSecurityType1 *st1; + const TSecurityType2 *st2; + + ms = proxGw1_1->getFirstSecurityData(); + TEST_ASSERT(ms == NULL); + + ms = proxGw1_2->getFirstSecurityData(); + TEST_ASSERT(ms != NULL); + TEST_ASSERT(ms->DataTag == tst_type2); + st2 = dynamic_cast(ms); + TEST_ASSERT(st2 != NULL); + TEST_ASSERT(st2->SecurityGatewayName == gw2->getModuleFullyQualifiedName()); + TEST_ASSERT(st2->IntegerValue == 0x12345678); + TEST_ASSERT(st2->NextItem == NULL); + + ms = proxGw1_3->getFirstSecurityData(); + TEST_ASSERT(ms != NULL); + TEST_ASSERT(ms->DataTag == tst_type2); + st2 = dynamic_cast(ms); + TEST_ASSERT(st2 != NULL); + TEST_ASSERT(st2->SecurityGatewayName == gw2->getModuleFullyQualifiedName()); + TEST_ASSERT(st2->IntegerValue == 0x12345678); + TEST_ASSERT(st2->NextItem == NULL); + + ms = proxGw2_1->getFirstSecurityData(); + TEST_ASSERT(ms != NULL); + TEST_ASSERT(ms->DataTag == tst_type1); + st1 = dynamic_cast(ms); + TEST_ASSERT(st1 != NULL); + TEST_ASSERT(st1->SecurityGatewayName == gw2->getModuleFullyQualifiedName()); + TEST_ASSERT(st1->NextItem == NULL); + + ms = proxGw2_2->getFirstSecurityData(); + TEST_ASSERT(ms != NULL); + TEST_ASSERT(ms->DataTag == tst_type1); + st1 = dynamic_cast(ms); + TEST_ASSERT(st1 != NULL); + TEST_ASSERT(st1->SecurityGatewayName == gw2->getModuleFullyQualifiedName()); + TEST_ASSERT(st1->NextItem == NULL); + + ms = proxGw2_3->getFirstSecurityData(); + TEST_ASSERT(ms != NULL); + TEST_ASSERT(ms->DataTag == tst_type1); + st1 = dynamic_cast(ms); + TEST_ASSERT(st1 != NULL); + TEST_ASSERT(st1->SecurityGatewayName == gw2->getModuleFullyQualifiedName()); + TEST_ASSERT(st1->NextItem == NULL); + + ms = proxGw3_1->getFirstSecurityData(); + TEST_ASSERT(ms != NULL); + TEST_ASSERT(ms->DataTag == tst_type2); + st2 = dynamic_cast(ms); + TEST_ASSERT(st2 != NULL); + TEST_ASSERT(st2->SecurityGatewayName == gw2->getModuleFullyQualifiedName()); + TEST_ASSERT(st2->IntegerValue == 0x12345678); + TEST_ASSERT(st2->NextItem == NULL); + + ms = proxGw3_2->getFirstSecurityData(); + TEST_ASSERT(ms != NULL); + TEST_ASSERT(ms->DataTag == tst_type2); + st2 = dynamic_cast(ms); + TEST_ASSERT(st2 != NULL); + TEST_ASSERT(st2->SecurityGatewayName == gw2->getModuleFullyQualifiedName()); + TEST_ASSERT(st2->IntegerValue == 0x12345678); + TEST_ASSERT(st2->NextItem == NULL); + + ms = proxGw3_3->getFirstSecurityData(); + TEST_ASSERT(ms == NULL); + + // remove the security plug-in + // create security plug-in + cmd = "gw2.securityRemove"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // update the network + for (uint i=0; i<15; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(40); + } + + ms = proxGw1_1->getFirstSecurityData(); + TEST_ASSERT(ms == NULL); + ms = proxGw1_2->getFirstSecurityData(); + TEST_ASSERT(ms == NULL); + ms = proxGw1_3->getFirstSecurityData(); + TEST_ASSERT(ms == NULL); + ms = proxGw2_1->getFirstSecurityData(); + TEST_ASSERT(ms == NULL); + ms = proxGw2_2->getFirstSecurityData(); + TEST_ASSERT(ms == NULL); + ms = proxGw2_3->getFirstSecurityData(); + TEST_ASSERT(ms == NULL); + ms = proxGw3_1->getFirstSecurityData(); + TEST_ASSERT(ms == NULL); + ms = proxGw3_2->getFirstSecurityData(); + TEST_ASSERT(ms == NULL); + ms = proxGw3_3->getFirstSecurityData(); + TEST_ASSERT(ms == NULL); + } + + // part 2 + // create the security plug-in + cmd = "gw2.securityCreate TestSecurity1"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw1.securityCreate TestSecurity2"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // update the network + for (uint i=0; i<15; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(40); + } + + NLNET::IModuleGateway *gGw1, *gGw2, *gGw3; + gGw1 = dynamic_cast(gw1); + TEST_ASSERT(gGw1 != NULL); + gGw2 = dynamic_cast(gw2); + TEST_ASSERT(gGw2 != NULL); + gGw3 = dynamic_cast(gw3); + TEST_ASSERT(gGw3 != NULL); + + + // check security data + NLNET::IModuleProxy *proxGw1_1, *proxGw2_1, *proxGw3_1; + NLNET::IModuleProxy *proxGw1_2, *proxGw2_2, *proxGw3_2; + NLNET::IModuleProxy *proxGw1_3, *proxGw2_3, *proxGw3_3; + + proxGw1_1 = retrieveModuleProxy(gGw1, "gw1"); + proxGw2_1 = retrieveModuleProxy(gGw1, "gw2"); + proxGw3_1 = retrieveModuleProxy(gGw1, "gw3"); + proxGw1_2 = retrieveModuleProxy(gGw2, "gw1"); + proxGw2_2 = retrieveModuleProxy(gGw2, "gw2"); + proxGw3_2 = retrieveModuleProxy(gGw2, "gw3"); + proxGw1_3 = retrieveModuleProxy(gGw3, "gw1"); + proxGw2_3 = retrieveModuleProxy(gGw3, "gw2"); + proxGw3_3 = retrieveModuleProxy(gGw3, "gw3"); + + TEST_ASSERT(proxGw1_1 != NULL); + TEST_ASSERT(proxGw2_1 != NULL); + TEST_ASSERT(proxGw3_1 != NULL); + TEST_ASSERT(proxGw1_2 != NULL); + TEST_ASSERT(proxGw2_2 != NULL); + TEST_ASSERT(proxGw3_2 != NULL); + TEST_ASSERT(proxGw1_3 != NULL); + TEST_ASSERT(proxGw2_3 != NULL); + TEST_ASSERT(proxGw3_3 != NULL); + + const NLNET::TSecurityData *ms; +// const TSecurityType1 *st1; +// const TSecurityType2 *st2; + + ms = proxGw1_1->findSecurityData(tst_type1); + TEST_ASSERT(ms == NULL); + ms = proxGw1_1->findSecurityData(tst_type2); + TEST_ASSERT(ms == NULL); + ms = proxGw1_1->findSecurityData(tst_type3); + TEST_ASSERT(ms != NULL); + ms = proxGw1_1->findSecurityData(tst_type4); + TEST_ASSERT(ms != NULL); + TEST_ASSERT(dynamic_cast(ms) != NULL); + + ms = proxGw1_2->findSecurityData(tst_type1); + TEST_ASSERT(ms == NULL); + ms = proxGw1_2->findSecurityData(tst_type2); + TEST_ASSERT(ms != NULL); + ms = proxGw1_2->findSecurityData(tst_type3); + TEST_ASSERT(ms != NULL); + ms = proxGw1_2->findSecurityData(0xff); + TEST_ASSERT(ms != NULL); + TEST_ASSERT(dynamic_cast(ms) != NULL); + + ms = proxGw1_3->findSecurityData(tst_type1); + TEST_ASSERT(ms == NULL); + ms = proxGw1_3->findSecurityData(tst_type2); + TEST_ASSERT(ms != NULL); + ms = proxGw1_3->findSecurityData(tst_type3); + TEST_ASSERT(ms != NULL); + ms = proxGw1_3->findSecurityData(0xff); + TEST_ASSERT(ms != NULL); + TEST_ASSERT(dynamic_cast(ms) != NULL); + + + ms = proxGw2_1->findSecurityData(tst_type1); + TEST_ASSERT(ms != NULL); + ms = proxGw2_1->findSecurityData(tst_type2); + TEST_ASSERT(ms == NULL); + ms = proxGw2_1->findSecurityData(tst_type3); + TEST_ASSERT(ms == NULL); + ms = proxGw2_1->findSecurityData(tst_type4); + TEST_ASSERT(ms == NULL); + + ms = proxGw2_2->findSecurityData(tst_type1); + TEST_ASSERT(ms != NULL); + ms = proxGw2_2->findSecurityData(tst_type2); + TEST_ASSERT(ms == NULL); + ms = proxGw2_2->findSecurityData(tst_type3); + TEST_ASSERT(ms == NULL); + ms = proxGw2_2->findSecurityData(tst_type4); + TEST_ASSERT(ms == NULL); + + ms = proxGw2_3->findSecurityData(tst_type1); + TEST_ASSERT(ms != NULL); + ms = proxGw2_3->findSecurityData(tst_type2); + TEST_ASSERT(ms == NULL); + ms = proxGw2_3->findSecurityData(tst_type3); + TEST_ASSERT(ms == NULL); + ms = proxGw2_3->findSecurityData(tst_type4); + TEST_ASSERT(ms == NULL); + + + ms = proxGw3_1->findSecurityData(tst_type1); + TEST_ASSERT(ms == NULL); + ms = proxGw3_1->findSecurityData(tst_type2); + TEST_ASSERT(ms != NULL); + ms = proxGw3_1->findSecurityData(tst_type3); + TEST_ASSERT(ms == NULL); + ms = proxGw3_1->findSecurityData(tst_type4); + TEST_ASSERT(ms == NULL); + + ms = proxGw3_2->findSecurityData(tst_type1); + TEST_ASSERT(ms == NULL); + ms = proxGw3_2->findSecurityData(tst_type2); + TEST_ASSERT(ms != NULL); + ms = proxGw3_2->findSecurityData(tst_type3); + TEST_ASSERT(ms == NULL); + ms = proxGw3_2->findSecurityData(tst_type4); + TEST_ASSERT(ms == NULL); + + ms = proxGw3_3->findSecurityData(tst_type1); + TEST_ASSERT(ms == NULL); + ms = proxGw3_3->findSecurityData(tst_type2); + TEST_ASSERT(ms == NULL); + ms = proxGw3_3->findSecurityData(tst_type3); + TEST_ASSERT(ms == NULL); + ms = proxGw3_3->findSecurityData(tst_type4); + TEST_ASSERT(ms == NULL); + + // remove the security plug-in + // create security plug-in + cmd = "gw1.securityRemove"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // update the network + for (uint i=0; i<15; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(40); + } + + ms = proxGw1_1->findSecurityData(tst_type1); + TEST_ASSERT(ms == NULL); + ms = proxGw1_1->findSecurityData(tst_type2); + TEST_ASSERT(ms == NULL); + ms = proxGw1_1->findSecurityData(tst_type3); + TEST_ASSERT(ms == NULL); + ms = proxGw1_1->findSecurityData(tst_type4); + TEST_ASSERT(ms == NULL); + + ms = proxGw1_2->findSecurityData(tst_type1); + TEST_ASSERT(ms == NULL); + ms = proxGw1_2->findSecurityData(tst_type2); + TEST_ASSERT(ms != NULL); + ms = proxGw1_2->findSecurityData(tst_type3); + TEST_ASSERT(ms == NULL); + ms = proxGw1_2->findSecurityData(tst_type4); + TEST_ASSERT(ms == NULL); + + ms = proxGw1_3->findSecurityData(tst_type1); + TEST_ASSERT(ms == NULL); + ms = proxGw1_3->findSecurityData(tst_type2); + TEST_ASSERT(ms != NULL); + ms = proxGw1_3->findSecurityData(tst_type3); + TEST_ASSERT(ms == NULL); + ms = proxGw1_3->findSecurityData(tst_type4); + TEST_ASSERT(ms == NULL); + + + ms = proxGw2_1->findSecurityData(tst_type1); + TEST_ASSERT(ms != NULL); + ms = proxGw2_1->findSecurityData(tst_type2); + TEST_ASSERT(ms == NULL); + ms = proxGw2_1->findSecurityData(tst_type3); + TEST_ASSERT(ms == NULL); + ms = proxGw2_1->findSecurityData(tst_type4); + TEST_ASSERT(ms == NULL); + + ms = proxGw2_2->findSecurityData(tst_type1); + TEST_ASSERT(ms != NULL); + ms = proxGw2_2->findSecurityData(tst_type2); + TEST_ASSERT(ms == NULL); + ms = proxGw2_2->findSecurityData(tst_type3); + TEST_ASSERT(ms == NULL); + ms = proxGw2_2->findSecurityData(tst_type4); + TEST_ASSERT(ms == NULL); + + ms = proxGw2_3->findSecurityData(tst_type1); + TEST_ASSERT(ms != NULL); + ms = proxGw2_3->findSecurityData(tst_type2); + TEST_ASSERT(ms == NULL); + ms = proxGw2_3->findSecurityData(tst_type3); + TEST_ASSERT(ms == NULL); + ms = proxGw2_3->findSecurityData(tst_type4); + TEST_ASSERT(ms == NULL); + + + ms = proxGw3_1->findSecurityData(tst_type1); + TEST_ASSERT(ms == NULL); + ms = proxGw3_1->findSecurityData(tst_type2); + TEST_ASSERT(ms != NULL); + ms = proxGw3_1->findSecurityData(tst_type3); + TEST_ASSERT(ms == NULL); + ms = proxGw3_1->findSecurityData(tst_type4); + TEST_ASSERT(ms == NULL); + + ms = proxGw3_2->findSecurityData(tst_type1); + TEST_ASSERT(ms == NULL); + ms = proxGw3_2->findSecurityData(tst_type2); + TEST_ASSERT(ms != NULL); + ms = proxGw3_2->findSecurityData(tst_type3); + TEST_ASSERT(ms == NULL); + ms = proxGw3_2->findSecurityData(tst_type4); + TEST_ASSERT(ms == NULL); + + ms = proxGw3_3->findSecurityData(tst_type1); + TEST_ASSERT(ms == NULL); + ms = proxGw3_3->findSecurityData(tst_type2); + TEST_ASSERT(ms == NULL); + ms = proxGw3_3->findSecurityData(tst_type3); + TEST_ASSERT(ms == NULL); + ms = proxGw3_3->findSecurityData(tst_type4); + TEST_ASSERT(ms == NULL); + + // cleanup + mm.deleteModule(gw1); + mm.deleteModule(gw2); + mm.deleteModule(gw3); + } + + void distanceAndConnectionLoop() + { + // Check that we support a closed loop or multi connection + // of gateway and that the gateway chooses the best + // route to reach a module when more than one is possible + // and that the distance is updated + // + // For this test, we use the following context: + // three gateway (gw1, gw2, gw3), each having a layer 3 + // server and client transport. + // one gateway (gw4) having just a layer3 server + // gw1 connects on gw2, gw2 connects on gw3, gw3 connects on gw4. + // we check the module list and distance, then gw3 connects to gw1, closing + // the loop. + // we recheck module list and distance. + // We then disconnect gw3 from gw1 and recheck module list and distance. + // + // Finally, we create a second connection from gw1 to gw2 and + // recheck module list and distances + // + // /------\ + // (l3s) gw1 (l3c) (l3s) gw2 (l3c) ------ (l3s) gw3 (l3c) ------ (l3s) gw4 + // | \----------------/ | + // | | + // | | + // \-----------------------------------------------------/ + // + + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + NLMISC::CCommandRegistry &cr = NLMISC::CCommandRegistry::getInstance(); + + NLNET::IModule *gw1, *gw2, *gw3, *gw4; + + // create the modules + gw1 = mm.createModule("StandardGateway", "gw1", ""); + gw2 = mm.createModule("StandardGateway", "gw2", ""); + gw3 = mm.createModule("StandardGateway", "gw3", ""); + gw4 = mm.createModule("StandardGateway", "gw4", ""); + + TEST_ASSERT(gw1 != NULL); + TEST_ASSERT(gw2 != NULL); + TEST_ASSERT(gw3 != NULL); + TEST_ASSERT(gw4 != NULL); + + // plug gateway into themselves + NLNET::IModuleSocket *sGw1, *sGw2, *sGw3, *sGw4; + sGw1 = mm.getModuleSocket("gw1"); + sGw2 = mm.getModuleSocket("gw2"); + sGw3 = mm.getModuleSocket("gw3"); + sGw4 = mm.getModuleSocket("gw4"); + + TEST_ASSERT(sGw1 != NULL); + TEST_ASSERT(sGw2 != NULL); + TEST_ASSERT(sGw3 != NULL); + TEST_ASSERT(sGw4 != NULL); + + gw1->plugModule(sGw1); + gw2->plugModule(sGw2); + gw3->plugModule(sGw3); + gw4->plugModule(sGw4); + + string cmd; + // create the transports + cmd = "gw1.transportAdd L3Client l3c"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw1.transportAdd L3Server l3s"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw2.transportAdd L3Client l3c"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw2.transportAdd L3Server l3s"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw3.transportAdd L3Client l3c"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw3.transportAdd L3Server l3s"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw4.transportAdd L3Server l3s"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // connect transport + cmd = "gw1.transportCmd l3s(open port=8061)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw2.transportCmd l3s(open port=8062)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw3.transportCmd l3s(open port=8063)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw4.transportCmd l3s(open port=8064)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw1.transportCmd l3c(connect addr=localhost:8062)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw2.transportCmd l3c(connect addr=localhost:8063)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gw3.transportCmd l3c(connect addr=localhost:8064)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // update the network + for (uint i=0; i<15; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(40); + } + + // check the modules list + // ok, now, check that each gateways know the gateway it must know + NLNET::IModuleGateway *gGw1, *gGw2, *gGw3, *gGw4; + gGw1 = dynamic_cast(gw1); + TEST_ASSERT(gGw1 != NULL); + gGw2 = dynamic_cast(gw2); + TEST_ASSERT(gGw2 != NULL); + gGw3 = dynamic_cast(gw3); + TEST_ASSERT(gGw3 != NULL); + gGw4 = dynamic_cast(gw4); + TEST_ASSERT(gGw4 != NULL); + + vector proxList; + gGw1->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + proxList.clear(); + gGw2->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + proxList.clear(); + gGw3->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + proxList.clear(); + gGw4->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + + // check the distance + NLNET::IModuleProxy *gw1_1Prox, *gw1_2Prox, *gw1_3Prox, *gw1_4Prox; + NLNET::IModuleProxy *gw2_1Prox, *gw2_2Prox, *gw2_3Prox, *gw2_4Prox; + NLNET::IModuleProxy *gw3_1Prox, *gw3_2Prox, *gw3_3Prox, *gw3_4Prox; + NLNET::IModuleProxy *gw4_1Prox, *gw4_2Prox, *gw4_3Prox, *gw4_4Prox; + + gw1_1Prox = retrieveModuleProxy(gGw1, "gw1"); + TEST_ASSERT(gw1_1Prox != NULL); + TEST_ASSERT(gw1_1Prox->getModuleDistance() == 0); + gw1_2Prox = retrieveModuleProxy(gGw2, "gw1"); + TEST_ASSERT(gw1_2Prox != NULL); + TEST_ASSERT(gw1_2Prox->getModuleDistance() == 1); + gw1_3Prox = retrieveModuleProxy(gGw3, "gw1"); + TEST_ASSERT(gw1_3Prox != NULL); + TEST_ASSERT(gw1_3Prox->getModuleDistance() == 2); + gw1_4Prox = retrieveModuleProxy(gGw4, "gw1"); + TEST_ASSERT(gw1_4Prox != NULL); + TEST_ASSERT(gw1_4Prox->getModuleDistance() == 3); + + gw2_1Prox = retrieveModuleProxy(gGw1, "gw2"); + TEST_ASSERT(gw2_1Prox != NULL); + TEST_ASSERT(gw2_1Prox->getModuleDistance() == 1); + gw2_2Prox = retrieveModuleProxy(gGw2, "gw2"); + TEST_ASSERT(gw2_2Prox != NULL); + TEST_ASSERT(gw2_2Prox->getModuleDistance() == 0); + gw2_3Prox = retrieveModuleProxy(gGw3, "gw2"); + TEST_ASSERT(gw2_3Prox != NULL); + TEST_ASSERT(gw2_3Prox->getModuleDistance() == 1); + gw2_4Prox = retrieveModuleProxy(gGw4, "gw2"); + TEST_ASSERT(gw2_4Prox != NULL); + TEST_ASSERT(gw2_4Prox->getModuleDistance() == 2); + + gw3_1Prox = retrieveModuleProxy(gGw1, "gw3"); + TEST_ASSERT(gw3_1Prox != NULL); + TEST_ASSERT(gw3_1Prox->getModuleDistance() == 2); + gw3_2Prox = retrieveModuleProxy(gGw2, "gw3"); + TEST_ASSERT(gw3_2Prox != NULL); + TEST_ASSERT(gw3_2Prox->getModuleDistance() == 1); + gw3_3Prox = retrieveModuleProxy(gGw3, "gw3"); + TEST_ASSERT(gw3_3Prox != NULL); + TEST_ASSERT(gw3_3Prox->getModuleDistance() == 0); + gw3_4Prox = retrieveModuleProxy(gGw4, "gw3"); + TEST_ASSERT(gw3_4Prox != NULL); + TEST_ASSERT(gw3_4Prox->getModuleDistance() == 1); + + gw4_1Prox = retrieveModuleProxy(gGw1, "gw4"); + TEST_ASSERT(gw4_1Prox != NULL); + TEST_ASSERT(gw4_1Prox->getModuleDistance() == 3); + gw4_2Prox = retrieveModuleProxy(gGw2, "gw4"); + TEST_ASSERT(gw4_2Prox != NULL); + TEST_ASSERT(gw4_2Prox->getModuleDistance() == 2); + gw4_3Prox = retrieveModuleProxy(gGw3, "gw4"); + TEST_ASSERT(gw4_3Prox != NULL); + TEST_ASSERT(gw4_3Prox->getModuleDistance() == 1); + gw4_4Prox = retrieveModuleProxy(gGw4, "gw4"); + TEST_ASSERT(gw4_4Prox != NULL); + TEST_ASSERT(gw4_4Prox->getModuleDistance() == 0); + + // now, connect gw3 to gw1 + cmd = "gw3.transportCmd l3c(connect addr=localhost:8061)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // update the network + for (uint i=0; i<7; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(100); + } + + // check module list + proxList.clear(); + gGw1->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + proxList.clear(); + gGw2->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + proxList.clear(); + gGw3->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + proxList.clear(); + gGw4->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + + // check the distances + gw1_1Prox = retrieveModuleProxy(gGw1, "gw1"); + TEST_ASSERT(gw1_1Prox != NULL); + TEST_ASSERT(gw1_1Prox->getModuleDistance() == 0); + gw1_2Prox = retrieveModuleProxy(gGw2, "gw1"); + TEST_ASSERT(gw1_2Prox != NULL); + TEST_ASSERT(gw1_2Prox->getModuleDistance() == 1); + gw1_3Prox = retrieveModuleProxy(gGw3, "gw1"); + TEST_ASSERT(gw1_3Prox != NULL); + TEST_ASSERT(gw1_3Prox->getModuleDistance() == 1); + gw1_4Prox = retrieveModuleProxy(gGw4, "gw1"); + TEST_ASSERT(gw1_4Prox != NULL); + TEST_ASSERT(gw1_4Prox->getModuleDistance() == 2); + + gw2_1Prox = retrieveModuleProxy(gGw1, "gw2"); + TEST_ASSERT(gw2_1Prox != NULL); + TEST_ASSERT(gw2_1Prox->getModuleDistance() == 1); + gw2_2Prox = retrieveModuleProxy(gGw2, "gw2"); + TEST_ASSERT(gw2_2Prox != NULL); + TEST_ASSERT(gw2_2Prox->getModuleDistance() == 0); + gw2_3Prox = retrieveModuleProxy(gGw3, "gw2"); + TEST_ASSERT(gw2_3Prox != NULL); + TEST_ASSERT(gw2_3Prox->getModuleDistance() == 1); + gw2_4Prox = retrieveModuleProxy(gGw4, "gw2"); + TEST_ASSERT(gw2_4Prox != NULL); + TEST_ASSERT(gw2_4Prox->getModuleDistance() == 2); + + gw3_1Prox = retrieveModuleProxy(gGw1, "gw3"); + TEST_ASSERT(gw3_1Prox != NULL); + TEST_ASSERT(gw3_1Prox->getModuleDistance() == 1); + gw3_2Prox = retrieveModuleProxy(gGw2, "gw3"); + TEST_ASSERT(gw3_2Prox != NULL); + TEST_ASSERT(gw3_2Prox->getModuleDistance() == 1); + gw3_3Prox = retrieveModuleProxy(gGw3, "gw3"); + TEST_ASSERT(gw3_3Prox != NULL); + TEST_ASSERT(gw3_3Prox->getModuleDistance() == 0); + gw3_4Prox = retrieveModuleProxy(gGw4, "gw3"); + TEST_ASSERT(gw3_4Prox != NULL); + TEST_ASSERT(gw3_4Prox->getModuleDistance() == 1); + + gw4_1Prox = retrieveModuleProxy(gGw1, "gw4"); + TEST_ASSERT(gw4_1Prox != NULL); + TEST_ASSERT(gw4_1Prox->getModuleDistance() == 2); + gw4_2Prox = retrieveModuleProxy(gGw2, "gw4"); + TEST_ASSERT(gw4_2Prox != NULL); + TEST_ASSERT(gw4_2Prox->getModuleDistance() == 2); + gw4_3Prox = retrieveModuleProxy(gGw3, "gw4"); + TEST_ASSERT(gw4_3Prox != NULL); + TEST_ASSERT(gw4_3Prox->getModuleDistance() == 1); + gw4_4Prox = retrieveModuleProxy(gGw4, "gw4"); + TEST_ASSERT(gw4_4Prox != NULL); + TEST_ASSERT(gw4_4Prox->getModuleDistance() == 0); + + // close gw3 to gw1 + cmd = "gw3.transportCmd l3c(close connId=1)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // update the network + for (uint i=0; i<7; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(100); + } + + // check module list + proxList.clear(); + gGw1->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + proxList.clear(); + gGw2->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + proxList.clear(); + gGw3->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + proxList.clear(); + gGw4->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + + // check the distances + gw1_1Prox = retrieveModuleProxy(gGw1, "gw1"); + TEST_ASSERT(gw1_1Prox != NULL); + TEST_ASSERT(gw1_1Prox->getModuleDistance() == 0); + gw1_2Prox = retrieveModuleProxy(gGw2, "gw1"); + TEST_ASSERT(gw1_2Prox != NULL); + TEST_ASSERT(gw1_2Prox->getModuleDistance() == 1); + gw1_3Prox = retrieveModuleProxy(gGw3, "gw1"); + TEST_ASSERT(gw1_3Prox != NULL); + TEST_ASSERT(gw1_3Prox->getModuleDistance() == 2); + gw1_4Prox = retrieveModuleProxy(gGw4, "gw1"); + TEST_ASSERT(gw1_4Prox != NULL); + TEST_ASSERT(gw1_4Prox->getModuleDistance() == 3); + + gw2_1Prox = retrieveModuleProxy(gGw1, "gw2"); + TEST_ASSERT(gw2_1Prox != NULL); + TEST_ASSERT(gw2_1Prox->getModuleDistance() == 1); + gw2_2Prox = retrieveModuleProxy(gGw2, "gw2"); + TEST_ASSERT(gw2_2Prox != NULL); + TEST_ASSERT(gw2_2Prox->getModuleDistance() == 0); + gw2_3Prox = retrieveModuleProxy(gGw3, "gw2"); + TEST_ASSERT(gw2_3Prox != NULL); + TEST_ASSERT(gw2_3Prox->getModuleDistance() == 1); + gw2_4Prox = retrieveModuleProxy(gGw4, "gw2"); + TEST_ASSERT(gw2_4Prox != NULL); + TEST_ASSERT(gw2_4Prox->getModuleDistance() == 2); + + gw3_1Prox = retrieveModuleProxy(gGw1, "gw3"); + TEST_ASSERT(gw3_1Prox != NULL); + TEST_ASSERT(gw3_1Prox->getModuleDistance() == 2); + gw3_2Prox = retrieveModuleProxy(gGw2, "gw3"); + TEST_ASSERT(gw3_2Prox != NULL); + TEST_ASSERT(gw3_2Prox->getModuleDistance() == 1); + gw3_3Prox = retrieveModuleProxy(gGw3, "gw3"); + TEST_ASSERT(gw3_3Prox != NULL); + TEST_ASSERT(gw3_3Prox->getModuleDistance() == 0); + gw3_4Prox = retrieveModuleProxy(gGw4, "gw3"); + TEST_ASSERT(gw3_4Prox != NULL); + TEST_ASSERT(gw3_4Prox->getModuleDistance() == 1); + + gw4_1Prox = retrieveModuleProxy(gGw1, "gw4"); + TEST_ASSERT(gw4_1Prox != NULL); + TEST_ASSERT(gw4_1Prox->getModuleDistance() == 3); + gw4_2Prox = retrieveModuleProxy(gGw2, "gw4"); + TEST_ASSERT(gw4_2Prox != NULL); + TEST_ASSERT(gw4_2Prox->getModuleDistance() == 2); + gw4_3Prox = retrieveModuleProxy(gGw3, "gw4"); + TEST_ASSERT(gw4_3Prox != NULL); + TEST_ASSERT(gw4_3Prox->getModuleDistance() == 1); + gw4_4Prox = retrieveModuleProxy(gGw4, "gw4"); + TEST_ASSERT(gw4_4Prox != NULL); + TEST_ASSERT(gw4_4Prox->getModuleDistance() == 0); + + // make a double connection from gw1 to gw2 + cmd = "gw1.transportCmd l3c(connect addr=localhost:8062)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // update the network + for (uint i=0; i<7; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(100); + } + + // check module list + proxList.clear(); + gGw1->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + proxList.clear(); + gGw2->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + proxList.clear(); + gGw3->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + proxList.clear(); + gGw4->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + + // check the distances + gw1_1Prox = retrieveModuleProxy(gGw1, "gw1"); + TEST_ASSERT(gw1_1Prox != NULL); + TEST_ASSERT(gw1_1Prox->getModuleDistance() == 0); + gw1_2Prox = retrieveModuleProxy(gGw2, "gw1"); + TEST_ASSERT(gw1_2Prox != NULL); + TEST_ASSERT(gw1_2Prox->getModuleDistance() == 1); + gw1_3Prox = retrieveModuleProxy(gGw3, "gw1"); + TEST_ASSERT(gw1_3Prox != NULL); + TEST_ASSERT(gw1_3Prox->getModuleDistance() == 2); + gw1_4Prox = retrieveModuleProxy(gGw4, "gw1"); + TEST_ASSERT(gw1_4Prox != NULL); + TEST_ASSERT(gw1_4Prox->getModuleDistance() == 3); + + gw2_1Prox = retrieveModuleProxy(gGw1, "gw2"); + TEST_ASSERT(gw2_1Prox != NULL); + TEST_ASSERT(gw2_1Prox->getModuleDistance() == 1); + gw2_2Prox = retrieveModuleProxy(gGw2, "gw2"); + TEST_ASSERT(gw2_2Prox != NULL); + TEST_ASSERT(gw2_2Prox->getModuleDistance() == 0); + gw2_3Prox = retrieveModuleProxy(gGw3, "gw2"); + TEST_ASSERT(gw2_3Prox != NULL); + TEST_ASSERT(gw2_3Prox->getModuleDistance() == 1); + gw2_4Prox = retrieveModuleProxy(gGw4, "gw2"); + TEST_ASSERT(gw2_4Prox != NULL); + TEST_ASSERT(gw2_4Prox->getModuleDistance() == 2); + + gw3_1Prox = retrieveModuleProxy(gGw1, "gw3"); + TEST_ASSERT(gw3_1Prox != NULL); + TEST_ASSERT(gw3_1Prox->getModuleDistance() == 2); + gw3_2Prox = retrieveModuleProxy(gGw2, "gw3"); + TEST_ASSERT(gw3_2Prox != NULL); + TEST_ASSERT(gw3_2Prox->getModuleDistance() == 1); + gw3_3Prox = retrieveModuleProxy(gGw3, "gw3"); + TEST_ASSERT(gw3_3Prox != NULL); + TEST_ASSERT(gw3_3Prox->getModuleDistance() == 0); + gw3_4Prox = retrieveModuleProxy(gGw4, "gw3"); + TEST_ASSERT(gw3_4Prox != NULL); + TEST_ASSERT(gw3_4Prox->getModuleDistance() == 1); + + gw4_1Prox = retrieveModuleProxy(gGw1, "gw4"); + TEST_ASSERT(gw4_1Prox != NULL); + TEST_ASSERT(gw4_1Prox->getModuleDistance() == 3); + gw4_2Prox = retrieveModuleProxy(gGw2, "gw4"); + TEST_ASSERT(gw4_2Prox != NULL); + TEST_ASSERT(gw4_2Prox->getModuleDistance() == 2); + gw4_3Prox = retrieveModuleProxy(gGw3, "gw4"); + TEST_ASSERT(gw4_3Prox != NULL); + TEST_ASSERT(gw4_3Prox->getModuleDistance() == 1); + gw4_4Prox = retrieveModuleProxy(gGw4, "gw4"); + TEST_ASSERT(gw4_4Prox != NULL); + TEST_ASSERT(gw4_4Prox->getModuleDistance() == 0); + + // release modules + mm.deleteModule(gw1); + mm.deleteModule(gw2); + mm.deleteModule(gw3); + mm.deleteModule(gw4); + } + + void firewalling() + { + // check that, with firewall mode enabled, unsafe root can only see protected + // modules if they initiate the dialog first (i.e only a protected module can send + // a message to an unsafe module). + // + // for this test, we have the following context : + // 'master' : a gateway that accesses connection on two transports, one 'firewalled', the other one normal + // 'peer1' : gateway connected to gateway 'master' on a firewalled transport + // 'peer2' : gateway connected to gateway 'master' on a firewalled transport + // 'other' : gateway connected to gateway 'master' on a classic transport + // + // peer1 (l3c)-----\ + // >-|<- (l3s1/Firewalled) master (l3s2) ----- (l3c) other + // peer2 (l3c)-----/ + // + // 'peer1' and 'peer2' must not see any module except modules that try to communicate with them + // 'master' and 'other' must see 'peer1', 'peer2', 'master' and 'other' + // + // Switching OFF the firewall should disclose all modules, + // switching ON then must throw an exception + + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + NLMISC::CCommandRegistry &cr = NLMISC::CCommandRegistry::getInstance(); + + NLNET::IModule *peer1, *peer2, *master, *other; + + // create the modules + peer1 = mm.createModule("StandardGateway", "peer1", ""); + peer2 = mm.createModule("StandardGateway", "peer2", ""); + master = mm.createModule("StandardGateway", "master", ""); + other = mm.createModule("StandardGateway", "other", ""); + + TEST_ASSERT(peer1 != NULL); + TEST_ASSERT(peer2 != NULL); + TEST_ASSERT(master != NULL); + TEST_ASSERT(other != NULL); + + // plug gateway in themselves + NLNET::IModuleSocket *sPeer1, *sPeer2, *sMaster, *sOther; + sPeer1 = mm.getModuleSocket("peer1"); + sPeer2 = mm.getModuleSocket("peer2"); + sMaster = mm.getModuleSocket("master"); + sOther = mm.getModuleSocket("other"); + + TEST_ASSERT(sPeer1 != NULL); + TEST_ASSERT(sPeer2 != NULL); + TEST_ASSERT(sMaster != NULL); + TEST_ASSERT(sOther != NULL); + + peer1->plugModule(sPeer1); + peer2->plugModule(sPeer2); + master->plugModule(sMaster); + other->plugModule(sOther); + + string cmd; + // create the transports + cmd = "peer1.transportAdd L3Client l3c"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "peer2.transportAdd L3Client l3c"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "master.transportAdd L3Server l3s1"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "master.transportAdd L3Server l3s2"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "other.transportAdd L3Client l3c"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // Set option and connect transport + cmd = "master.transportOptions l3s1(Firewalled)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "master.transportCmd l3s1(open port=8060)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "master.transportCmd l3s2(open port=8061)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "peer1.transportCmd l3c(connect addr=localhost:8060)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "peer2.transportCmd l3c(connect addr=localhost:8060)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "other.transportCmd l3c(connect addr=localhost:8061)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // d'ho ! all done, now let's run some loop of update + for (uint i=0; i<7; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(100); + } + + // ok, now, check that each gateway only knows the gateway it must know + NLNET::IModuleGateway *gPeer1, *gPeer2, *gMaster, *gOther; + gPeer1 = dynamic_cast(peer1); + TEST_ASSERT(gPeer1 != NULL); + gPeer2 = dynamic_cast(peer2); + TEST_ASSERT(gPeer2 != NULL); + gMaster = dynamic_cast(master); + TEST_ASSERT(gMaster != NULL); + gOther = dynamic_cast(other); + TEST_ASSERT(gOther != NULL); + + vector proxList; + gPeer1->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 1); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + + proxList.clear(); + gPeer2->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 1); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + + proxList.clear(); + gMaster->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + + proxList.clear(); + gOther->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + + + // now send the debug 'PING' message from 'other' to 'peer1', and a message from 'master' to 'peer2' + { + NLNET::CMessage ping("DEBUG_MOD_PING"); + + // retrieve peer1 proxy from other + NLNET::IModuleProxy *peer1Prox = retrieveModuleProxy(gMaster, "peer1"); + TEST_ASSERT(peer1Prox != NULL); + peer1Prox->sendModuleMessage(master, ping); + } + { + NLNET::CMessage ping("DEBUG_MOD_PING"); + + // retrieve peer1 proxy from other + NLNET::IModuleProxy *peer2Prox = retrieveModuleProxy(gOther, "peer2"); + TEST_ASSERT(peer2Prox != NULL); + peer2Prox->sendModuleMessage(other, ping); + } + + // update the network + for (uint i=0; i<7; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(100); + } + + // check new proxy table and ping counter + TEST_ASSERT(gPeer1->getReceivedPingCount() == 1); + proxList.clear(); + gPeer1->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 2); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + + TEST_ASSERT(gPeer2->getReceivedPingCount() == 1); + proxList.clear(); + gPeer2->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 2); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + + proxList.clear(); + gMaster->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + + proxList.clear(); + gOther->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + + // now, remove firewall mode + cmd = "master.transportOptions l3s1()"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // update the network + for (uint i=0; i<7; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(100); + } + + // check new proxy table and ping counter + proxList.clear(); + gPeer1->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + + TEST_ASSERT(gPeer2->getReceivedPingCount() == 1); + proxList.clear(); + gPeer2->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + + proxList.clear(); + gMaster->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + + proxList.clear(); + gOther->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + + // no try reactivate firewall mode with active route + cmd = "master.transportOptions l3s1(Firewalled)"; + TEST_THROWS(cr.execute(cmd, NLMISC::InfoLog()), NLNET::IModuleGateway::EGatewayFirewallBreak); + + + // cleanup + mm.deleteModule(peer1); + mm.deleteModule(peer2); + mm.deleteModule(master); + mm.deleteModule(other); + + } + + void peerInvisible() + { + // check that, with peer invisible enable, the peer modules are effectively invisible, + // and, also, check that other modules, on other route are visible. + // for this test, we have the following context : + // 'master' : a gateway that acces connection on to transport, on 'peer invisible', the other normal + // 'peer1' : gateway connected to gateway 'master' on a peer invisible transport + // 'peer2' : gateway connected to gateway 'master' on a peer invisible transport + // 'other' : gateway connected to gateway 'master' on a classic transport + // + // peer1 (l3c)-----\ + // >-- (l3s1/PeerInvisible) master (l3s2) ----- (l3c) other + // peer2 (l3c)-----/ + // + // 'peer1' must see 'master' and 'other' + // 'peer2' must see 'master' and 'other' + // 'master' must see 'peer1', 'peer2' and 'other' + // 'other' must see 'peer1', 'peer2' and 'master' + // + // When switching the PeerInvisible option to OFF, peer1 and peer2 must see each other + + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + NLMISC::CCommandRegistry &cr = NLMISC::CCommandRegistry::getInstance(); + + NLNET::IModule *peer1, *peer2, *master, *other; + + // create the modules + peer1 = mm.createModule("StandardGateway", "peer1", ""); + peer2 = mm.createModule("StandardGateway", "peer2", ""); + master = mm.createModule("StandardGateway", "master", ""); + other = mm.createModule("StandardGateway", "other", ""); + + TEST_ASSERT(peer1 != NULL); + TEST_ASSERT(peer2 != NULL); + TEST_ASSERT(master != NULL); + TEST_ASSERT(other != NULL); + + // plug gateway in themselves + NLNET::IModuleSocket *sPeer1, *sPeer2, *sMaster, *sOther; + sPeer1 = mm.getModuleSocket("peer1"); + sPeer2 = mm.getModuleSocket("peer2"); + sMaster = mm.getModuleSocket("master"); + sOther = mm.getModuleSocket("other"); + + TEST_ASSERT(sPeer1 != NULL); + TEST_ASSERT(sPeer2 != NULL); + TEST_ASSERT(sMaster != NULL); + TEST_ASSERT(sOther != NULL); + + peer1->plugModule(sPeer1); + peer2->plugModule(sPeer2); + master->plugModule(sMaster); + other->plugModule(sOther); + + string cmd; + // create the transports + cmd = "peer1.transportAdd L3Client l3c"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "peer2.transportAdd L3Client l3c"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "master.transportAdd L3Server l3s1"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "master.transportAdd L3Server l3s2"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "other.transportAdd L3Client l3c"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // Set option and connect transport + cmd = "master.transportOptions l3s1(PeerInvisible)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "master.transportCmd l3s1(open port=8060)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "master.transportCmd l3s2(open port=8061)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "peer1.transportCmd l3c(connect addr=localhost:8060)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "peer2.transportCmd l3c(connect addr=localhost:8060)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "other.transportCmd l3c(connect addr=localhost:8061)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // d'ho ! all done, now let's run some loop of update + for (uint i=0; i<7; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(100); + } + + // ok, now, check that each gateway only knows the gateway it must know + NLNET::IModuleGateway *gPeer1, *gPeer2, *gMaster, *gOther; + gPeer1 = dynamic_cast(peer1); + TEST_ASSERT(gPeer1 != NULL); + gPeer2 = dynamic_cast(peer2); + TEST_ASSERT(gPeer2 != NULL); + gMaster = dynamic_cast(master); + TEST_ASSERT(gMaster != NULL); + gOther = dynamic_cast(other); + TEST_ASSERT(gOther != NULL); + + vector proxList; + gPeer1->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 3); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + + proxList.clear(); + gPeer2->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 3); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + + proxList.clear(); + gMaster->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + + proxList.clear(); + gOther->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + + // now, remove the 'PeerInvisible' options + cmd = "master.transportOptions l3s1()"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // update the network + for (uint i=0; i<7; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(100); + } + + // check new proxy table + proxList.clear(); + gPeer1->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + + proxList.clear(); + gPeer2->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + + proxList.clear(); + gMaster->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + + proxList.clear(); + gOther->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + + // now, re set the 'PeerInvisible' options + cmd = "master.transportOptions l3s1(PeerInvisible)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // update the network + for (uint i=0; i<7; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(100); + } + + // check new proxy table + proxList.clear(); + gPeer1->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 3); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + + proxList.clear(); + gPeer2->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 3); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + + proxList.clear(); + gMaster->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + + proxList.clear(); + gOther->getModuleProxyList(proxList); + TEST_ASSERT(proxList.size() == 4); + TEST_ASSERT(lookForModuleProxy(proxList, "other")); + TEST_ASSERT(lookForModuleProxy(proxList, "master")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer1")); + TEST_ASSERT(lookForModuleProxy(proxList, "peer2")); + // cleanup + mm.deleteModule(peer1); + mm.deleteModule(peer2); + mm.deleteModule(master); + mm.deleteModule(other); + + } + + void gwPlugUnplug() + { + // check that multiple plug/unplug operations work well + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + NLMISC::CCommandRegistry &cr = NLMISC::CCommandRegistry::getInstance(); + + NLNET::IModule *mod = mm.createModule("StandardGateway", "gw", ""); + TEST_ASSERT(mod != NULL); + + NLNET::IModuleSocket *socket = mm.getModuleSocket("gw"); + TEST_ASSERT(socket != NULL); + mod->plugModule(socket); + mod->unplugModule(socket); + mod->plugModule(socket); + mod->unplugModule(socket); + mod->plugModule(socket); + + std::vector result; + socket->getModuleList(result); + TEST_ASSERT(result.size() == 1); + + mod->unplugModule(socket); + + mm.deleteModule(mod); + } + + void uniqueNameGenerator() + { + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + NLMISC::CCommandRegistry &cr = NLMISC::CCommandRegistry::getInstance(); + + mm.setUniqueNameRoot("foo"); + + // create a simple module + NLNET::IModule *mod = mm.createModule("ModuleType0", "mod", ""); + TEST_ASSERT(mod != NULL); + TEST_ASSERT(mod->getModuleFullyQualifiedName() == "foo:mod"); + mm.deleteModule(mod); + + // reset the unique name to normal value + mm.setUniqueNameRoot(string()); + + mod = mm.createModule("ModuleType0", "mod", ""); + TEST_ASSERT(mod != NULL); + TEST_ASSERT(mod->getModuleFullyQualifiedName() != "foo:mod"); + + mm.deleteModule(mod); + } + + void localMessageQueing() + { + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + NLMISC::CCommandRegistry &cr = NLMISC::CCommandRegistry::getInstance(); + + NLNET::IModule *mods = mm.createModule("StandardGateway", "gws", ""); + TEST_ASSERT(mods != NULL); + NLNET::IModuleGateway *gws = dynamic_cast(mods); + TEST_ASSERT(gws != NULL); + + // get the socket interface of the gateway + NLNET::IModuleSocket *socketGws = mm.getModuleSocket("gws"); + TEST_ASSERT(socketGws != NULL); + + // create two modules that will communicate localy + NLNET::IModule *m1= mm.createModule("ModuleType0", "m1", ""); + TEST_ASSERT(m1!= NULL); + NLNET::IModule *m2= mm.createModule("ModuleAsync", "m2", ""); + TEST_ASSERT(m2!= NULL); + + m1->plugModule(socketGws); + m2->plugModule(socketGws); + + // update the networks + for (uint i=0; i<4; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(50); + } + + // retrieve module proxy and send one ping to each other + vector proxiesC; + gws->getModuleProxyList(proxiesC); + TEST_ASSERT(proxiesC.size() == 2); + TEST_ASSERT(lookForModuleProxy(proxiesC, "m2")); + NLNET::IModuleProxy *pm2 = retrieveModuleProxy(gws, "m2"); + TEST_ASSERT(pm2 != NULL); + NLNET::CMessage aMessage("DEBUG_MOD_PING"); + pm2->sendModuleMessage(m1, aMessage); + + proxiesC.clear(); + gws->getModuleProxyList(proxiesC); + TEST_ASSERT(proxiesC.size() == 2); + TEST_ASSERT(lookForModuleProxy(proxiesC, "m1")); + NLNET::IModuleProxy *pm1 = retrieveModuleProxy(gws, "m1"); + TEST_ASSERT(pm1 != NULL); + aMessage = NLNET::CMessage("DEBUG_MOD_PING"); + pm1->sendModuleMessage(m2, aMessage); + + // check received ping count + CModuleType0 *mod1 = dynamic_cast(m1); + TEST_ASSERT(mod1 != NULL); + TEST_ASSERT(mod1->PingCount == 1); + CModuleType0 *mod2 = dynamic_cast(m2); + TEST_ASSERT(mod2 != NULL); + TEST_ASSERT(mod2->PingCount == 0); + + // update the networks + for (uint i=0; i<4; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(50); + } + + // check received ping count + TEST_ASSERT(mod1->PingCount == 1); + TEST_ASSERT(mod2->PingCount == 1); + + // update the networks + for (uint i=0; i<4; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(50); + } + + // check received ping count + TEST_ASSERT(mod1->PingCount == 1); + TEST_ASSERT(mod2->PingCount == 1); + + + // cleanup + mm.deleteModule(m1); + mm.deleteModule(m2); + mm.deleteModule(mods); + } + + void moduleMessaging() + { + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + NLMISC::CCommandRegistry &cr = NLMISC::CCommandRegistry::getInstance(); + + // create two gateway an connect them, plug the gateway on themselves and send a message + NLNET::IModule *mods = mm.createModule("StandardGateway", "gws", ""); + TEST_ASSERT(mods != NULL); + NLNET::IModuleGateway *gws = dynamic_cast(mods); + TEST_ASSERT(gws != NULL); + + // plug the module in itself before opening connection + NLNET::IModuleSocket *socketGws = mm.getModuleSocket("gws"); + TEST_ASSERT(socketGws != NULL); + mods->plugModule(socketGws); + + // add transport for server mode + string cmd = "gws.transportAdd L3Server l3s"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gws.transportCmd l3s(open port=6185)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + NLNET::IModule *modc = mm.createModule("StandardGateway", "gwc", ""); + TEST_ASSERT(modc != NULL); + NLNET::IModuleGateway *gwc = dynamic_cast(modc); + TEST_ASSERT(gwc != NULL); + // add transport for client mode + cmd = "gwc.transportAdd L3Client l3c"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gwc.transportCmd l3c(connect addr=localhost:6185)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // plug the module in itself before opening connection + NLNET::IModuleSocket *socketGwc = mm.getModuleSocket("gwc"); + TEST_ASSERT(socketGwc != NULL); + modc->plugModule(socketGwc); + + // update the gateways... + for (uint i=0; i<4; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(100); + } + + // send a message from gws to gwc using the proxy + // First, get the proxy for the client (must be the second one) + vector proxiesS; + gws->getModuleProxyList(proxiesS); + TEST_ASSERT(proxiesS.size() == 2); + TEST_ASSERT(lookForModuleProxy(proxiesS, "gwc")); + NLNET::CMessage aMessage("DEBUG_MOD_PING"); + proxiesS[1]->sendModuleMessage(mods, aMessage); + + // update the gateways... + for (uint i=0; i<4; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(100); + } + + // check that the ping has been received + TEST_ASSERT(gwc->getReceivedPingCount() == 1); + + // send two crossing messages simultaneously + vector proxiesC; + gwc->getModuleProxyList(proxiesC); + TEST_ASSERT(proxiesC.size() == 2); + TEST_ASSERT(lookForModuleProxy(proxiesC, "gws")); + proxiesS[1]->sendModuleMessage(mods, aMessage); + proxiesC[1]->sendModuleMessage(modc, aMessage); + + // update the gateways... + for (uint i=0; i<4; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(100); + } + // check that the ping has been received + TEST_ASSERT(gwc->getReceivedPingCount() == 2); + TEST_ASSERT(gws->getReceivedPingCount() == 1); + + + // send with ISocket + socketGws->sendModuleMessage(mods, proxiesS[1]->getModuleProxyId(), aMessage); + // update the gateways... + for (uint i=0; i<4; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(100); + } + // check that the ping has been received + TEST_ASSERT(gwc->getReceivedPingCount() == 3); + TEST_ASSERT(gws->getReceivedPingCount() == 1); + + // cleanup modules + mm.deleteModule(mods); + TEST_ASSERT(mm.getLocalModule("gws") == NULL); + mm.deleteModule(modc); + TEST_ASSERT(mm.getLocalModule("gwc") == NULL); + } + + void moduleDisclosure() + { + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + NLMISC::CCommandRegistry &cr = NLMISC::CCommandRegistry::getInstance(); + + NLNET::IModule *mods = mm.createModule("StandardGateway", "gws", ""); + TEST_ASSERT(mods != NULL); + NLNET::IModuleGateway *gws = dynamic_cast(mods); + TEST_ASSERT(gws != NULL); + + TEST_ASSERT(gws->getProxyCount() == 0); + + // plug the module in itself before opening connection + NLNET::IModuleSocket *socketGws = mm.getModuleSocket("gws"); + TEST_ASSERT(socketGws != NULL); + mods->plugModule(socketGws); + + // now, there must be one proxy in the gateway + TEST_ASSERT(gws->getProxyCount() == 1); + vector proxies; + gws->getModuleProxyList(proxies); + TEST_ASSERT(proxies.size() == 1); + TEST_ASSERT(proxies[0]->getGatewayRoute() == NULL); + TEST_ASSERT(proxies[0]->getForeignModuleId() == mods->getModuleId()); + + // add transport for server mode + string cmd = "gws.transportAdd L3Server l3s"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gws.transportCmd l3s(open port=6185)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + NLNET::IModule *modc = mm.createModule("StandardGateway", "gwc", ""); + TEST_ASSERT(modc != NULL); + NLNET::IModuleGateway *gwc = dynamic_cast(modc); + TEST_ASSERT(gwc != NULL); + // add transport for client mode + cmd = "gwc.transportAdd L3Client l3c"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gwc.transportCmd l3c(connect addr=localhost:6185)"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + for (uint i=0; i<5; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(100); + } + + // The server must have not changed + TEST_ASSERT(gws->getProxyCount() == 1); + + // The client must have one proxy + TEST_ASSERT(gwc->getProxyCount() == 1); + proxies.clear(); + gwc->getModuleProxyList(proxies); + TEST_ASSERT(proxies.size() == 1); + TEST_ASSERT(proxies[0]->getGatewayRoute() != NULL); + TEST_ASSERT(proxies[0]->getModuleName().find("gws") == proxies[0]->getModuleName().size() - 3); + + // plug the client module in itself after opening connection + NLNET::IModuleSocket *socketGwc = mm.getModuleSocket("gwc"); + TEST_ASSERT(socketGwc != NULL); + modc->plugModule(socketGwc); + + + for (uint i=0; i<4; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(100); + } + + // The server must have now the two modules + TEST_ASSERT(gws->getProxyCount() == 2); + proxies.clear(); + gws->getModuleProxyList(proxies); + TEST_ASSERT(proxies.size() == 2); + TEST_ASSERT(proxies[0]->getGatewayRoute() == NULL); + TEST_ASSERT(proxies[0]->getForeignModuleId() == mods->getModuleId()); + TEST_ASSERT(proxies[1]->getGatewayRoute() != NULL); + TEST_ASSERT(proxies[1]->getModuleName().find("gwc") == proxies[1]->getModuleName().size() - 3); + + // The client must have two module also + TEST_ASSERT(gwc->getProxyCount() == 2); + proxies.clear(); + gwc->getModuleProxyList(proxies); + TEST_ASSERT(proxies.size() == 2); + TEST_ASSERT(proxies[0]->getGatewayRoute() != NULL); + TEST_ASSERT(proxies[0]->getModuleName().find("gws") == proxies[1]->getModuleName().size() - 3); + TEST_ASSERT(proxies[1]->getGatewayRoute() == NULL); + TEST_ASSERT(proxies[1]->getForeignModuleId() == modc->getModuleId()); + + + // unplug the client module in itself after opening connection + mods->unplugModule(socketGws); + + for (uint i=0; i<4; ++i) + { + NLMISC::nlSleep(100); + mm.updateModules(); + } + + // The server must have one module left + TEST_ASSERT(gws->getProxyCount() == 1); + proxies.clear(); + gws->getModuleProxyList(proxies); + TEST_ASSERT(proxies.size() == 1); + TEST_ASSERT(proxies[0]->getGatewayRoute() != NULL); + TEST_ASSERT(proxies[0]->getModuleName().find("gwc") == proxies[0]->getModuleName().size() - 3); + + // The client must have one module left + TEST_ASSERT(gwc->getProxyCount() == 1); + proxies.clear(); + gwc->getModuleProxyList(proxies); + TEST_ASSERT(proxies.size() == 1); + TEST_ASSERT(proxies[0]->getGatewayRoute() == NULL); + TEST_ASSERT(proxies[0]->getForeignModuleId() == modc->getModuleId()); + + // Dump the module state + cmd = "gws.dump"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + cmd = "gwc.dump"; + TEST_ASSERT(cr.execute(cmd, NLMISC::InfoLog())); + + // cleanup modules + mm.deleteModule(mods); + TEST_ASSERT(mm.getLocalModule("gws") == NULL); + mm.deleteModule(modc); + TEST_ASSERT(mm.getLocalModule("gwc") == NULL); + } + + void connectGateways() + { + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + + NLNET::IModule *mods = mm.createModule("StandardGateway", "gws", ""); + TEST_ASSERT(mods != NULL); + NLNET::IModuleGateway *gws = dynamic_cast(mods); + TEST_ASSERT(gws != NULL); + // add transport for server mode + string cmd = "gws.transportAdd L3Server l3s"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + cmd = "gws.transportCmd l3s(open port=6185)"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + + NLNET::IModule *modc1 = mm.createModule("StandardGateway", "gwc1", ""); + TEST_ASSERT(modc1 != NULL); + NLNET::IModuleGateway *gwc1 = dynamic_cast(modc1); + TEST_ASSERT(gwc1 != NULL); + // add transport for client mode + cmd = "gwc1.transportAdd L3Client l3c"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + cmd = "gwc1.transportCmd l3c(connect addr=localhost:6185)"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + + for (uint i=0; i<4; ++i) + { + mm.updateModules(); + NLMISC::nlSleep(100); + } + + TEST_ASSERT(gws->getRouteCount() == 1); + TEST_ASSERT(gwc1->getRouteCount() == 1); + + // do a second connect to the server for stress + // add transport for client mode + cmd = "gwc1.transportCmd l3c(connect addr=localhost:6185)"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + + // create third gateway + NLNET::IModule *modc2 = mm.createModule("StandardGateway", "gwc2", ""); + TEST_ASSERT(modc2 != NULL); + NLNET::IModuleGateway *gwc2 = dynamic_cast(modc2); + TEST_ASSERT(gwc2 != NULL); + // add transport for client mode + cmd = "gwc2.transportAdd L3Client l3c"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + cmd = "gwc2.transportCmd l3c(connect addr=localhost:6185)"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + + // update the module to update the network callback client and server + for (uint i=0; i<4; ++i) + { + // give some time to the listen and receiver thread to do there jobs + NLMISC::nlSleep(100); + mm.updateModules(); + } + + TEST_ASSERT(gws->getRouteCount() == 3); + TEST_ASSERT(gwc1->getRouteCount() == 2); + TEST_ASSERT(gwc2->getRouteCount() == 1); + + // dump the gateways state + cmd = "gws.dump"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + cmd = "gwc1.dump"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + cmd = "gwc2.dump"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + + // cleanup the modules + mm.deleteModule(mods); + TEST_ASSERT(mm.getLocalModule("gws") == NULL); + mm.deleteModule(modc1); + TEST_ASSERT(mm.getLocalModule("gwc1") == NULL); + mm.deleteModule(modc2); + TEST_ASSERT(mm.getLocalModule("gwc2") == NULL); + } + + void gatewayTransportManagement() + { + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + + // create a gateway module + NLNET::IModule *mod = mm.createModule("StandardGateway", "gw", ""); + TEST_ASSERT(mod != NULL); + NLNET::IModuleGateway *gw = dynamic_cast(mod); + TEST_ASSERT(gw != NULL); + + // Create a layer 3 server transport + // send a transport creation command + string cmd = "gw.transportAdd L3Server l3s"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + NLNET::IGatewayTransport *transportL3s = gw->getGatewayTransport("l3s"); + TEST_ASSERT(transportL3s != NULL); + + // send a transport command + cmd = "gw.transportCmd l3s(open port=6185)"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + + // Create a layer 3 client transport + // send a transport creation command + cmd = "gw.transportAdd L3Client l3c"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + NLNET::IGatewayTransport *transportL3c = gw->getGatewayTransport("l3c"); + TEST_ASSERT(transportL3c != NULL); + + // send a transport command + cmd = "gw.transportCmd l3c(connect addr=localhost:6185)"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + + // update the module to update the network callback client and server + for (uint i=0; i<4; ++i) + { + // give some time to the listen and receiver thread to do there jobs + mm.updateModules(); + NLMISC::nlSleep(100); + } + + TEST_ASSERT(transportL3s->getRouteCount() == 1); + TEST_ASSERT(transportL3c->getRouteCount() == 1); + TEST_ASSERT(gw->getRouteCount() == 2); + + // dump the gateways state + cmd = "gw.dump"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + + + // close all connections + cmd = "gw.transportCmd l3s(close)"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + + cmd = "gw.transportCmd l3c(close connId=0)"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + + // update the module to update the network callback client and server + for (uint i=0; i<4; ++i) + { + // give some time to the listen and receiver thread to do there jobs + mm.updateModules(); + NLMISC::nlSleep(100); + } + + TEST_ASSERT(transportL3s->getRouteCount() == 0); + TEST_ASSERT(transportL3c->getRouteCount() == 0); + TEST_ASSERT(gw->getRouteCount() == 0); + + // Remove transports + cmd = "gw.transportRemove l3s"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + cmd = "gw.transportRemove l3c"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + + TEST_ASSERT(gw->getGatewayTransport("l3c") == NULL); + TEST_ASSERT(gw->getGatewayTransport("l3s") == NULL); + TEST_ASSERT(gw->getTransportCount() == 0); + + // update the module to update the network callback client and server + for (uint i=0; i<4; ++i) + { + // give some time to the listen and receiver thread to do there jobs + mm.updateModules(); + NLMISC::nlSleep(100); + } + + // cleanup the modules + mm.deleteModule(mod); + TEST_ASSERT(mm.getLocalModule("gw") == NULL); + } + +/* void moduleManagerCommands() + { + string cmd; + // load a library + cmd = "moduleManager.loadLibrary net_module_lib_test/net_module_lib_test"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + + // dump the module state + cmd = "moduleManager.dump"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + + // create a module + cmd = "moduleManager.createModule ModuleType1 AModuleName"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + + // dump the module state + cmd = "moduleManager.dump"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + + // delete the module + cmd = "moduleManager.deleteModule AModuleName"; + TEST_ASSERT(NLMISC::CCommandRegistry::getInstance().execute(cmd, NLMISC::InfoLog())); + }*/ + + void plugLocalGateway() + { + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + + NLNET::IModule *gateway1 = mm.createModule("LocalGateway", "g1", ""); + TEST_ASSERT(gateway1 != NULL); + NLNET::IModule *gateway2 = mm.createModule("LocalGateway", "g2", ""); + TEST_ASSERT(gateway2 != NULL); + + NLNET::IModuleSocket *socket1 = mm.getModuleSocket("g1"); + TEST_ASSERT(socket1 != NULL); + NLNET::IModuleSocket *socket2 = mm.getModuleSocket("g2"); + TEST_ASSERT(socket2 != NULL); + gateway1->plugModule(socket1); + gateway1->plugModule(socket2); + gateway2->plugModule(socket1); + gateway2->plugModule(socket2); + + mm.deleteModule(gateway1); + TEST_ASSERT(mm.getLocalModule("g1") == NULL); + mm.deleteModule(gateway2); + TEST_ASSERT(mm.getLocalModule("g2") == NULL); + } + + void createLocalGateway() + { + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + + NLNET::IModule *gateway = mm.createModule("LocalGateway", "localGateway", ""); + TEST_ASSERT(gateway != NULL); + + NLNET::IModule *mod1 = mm.createModule("ModuleType0", "plugged1", ""); + TEST_ASSERT(mod1 != NULL); + NLNET::IModule *mod2 = mm.createModule("ModuleType0", "plugged2", ""); + TEST_ASSERT(mod2 != NULL); + + NLNET::IModuleSocket *socket = mm.getModuleSocket("localGateway"); + TEST_ASSERT(socket != NULL); + mod1->plugModule(socket); + mod2->plugModule(socket); + + mm.deleteModule(mod1); + TEST_ASSERT(mm.getLocalModule("plugged1") == NULL); + mm.deleteModule(mod2); + TEST_ASSERT(mm.getLocalModule("plugged2") == NULL); + + mm.deleteModule(gateway); + TEST_ASSERT(mm.getLocalModule("localGateway") == NULL); + } + +/* void unloadModuleLib() + { + IModuleManager &mm = IModuleManager::getInstance(); + + CRefPtr module1 = mm.createModule("ModuleType1", "TheModule2", "the args"); + TEST_ASSERT(module1 != NULL); + + TEST_ASSERT(mm.unloadModuleLibrary("net_module_lib_test")); + + // the module must have been deleted + TEST_ASSERT(module1 == NULL); + + TModulePtr module2 = mm.createModule("ModuleType1", "TheModuleThatCantBeCreated", "the args"); + TEST_ASSERT(module2 == NULL); + }*/ + + void failedInit() + { + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + + NLNET::IModule *module = mm.createModule("ModuleType0", "FailingInit", "FAIL"); + TEST_ASSERT(module == NULL); + } + +/* void deleteModule() + { + IModuleManager &mm = IModuleManager::getInstance(); + + IModule *module = mm.createModule("ModuleType1", "TheModuleToDelete", "the args"); + TEST_ASSERT(module != NULL); + + CRefPtr checkPtr(module); + + mm.deleteModule(module); + TEST_ASSERT(checkPtr == NULL); + }*/ + +/* void createModule() + { + IModuleManager &mm = IModuleManager::getInstance(); + + TModulePtr module = mm.createModule("ModuleType1", "TheModule", "the args"); + TEST_ASSERT(module != NULL); + + TEST_ASSERT(module->getModuleClassName() == "ModuleType1"); + TEST_ASSERT(module->getModuleName() == "TheModule"); + + string lh; + if (IService::isServiceInitialized()) + lh = IService::getInstance()->getHostName(); + else + lh = ::NLNET::CInetAddress::localHost().hostName(); + string fqmn = lh+":"+toString(getpid())+":TheModule"; + + TEST_ASSERT(module->getModuleFullyQualifiedName() == fqmn); + }*/ + +/* void loadModuleLib() + { + string moduleLibName = "net_module_lib_test/net_module_lib_test"; + + IModuleManager &mm = IModuleManager::getInstance(); + TEST_ASSERT(mm.loadModuleLibrary(moduleLibName)); + + vector moduleList; + mm.getAvailableModuleClassList(moduleList); + + TEST_ASSERT(moduleList.size() == 6); + TEST_ASSERT(moduleList[0] == "LocalGateway"); + TEST_ASSERT(moduleList[1] == "ModuleAsync"); + TEST_ASSERT(moduleList[2] == "ModuleType0"); + TEST_ASSERT(moduleList[3] == "ModuleType1"); + TEST_ASSERT(moduleList[4] == "ModuleType2"); + TEST_ASSERT(moduleList[5] == "StandardGateway"); + }*/ + + void localModuleFactory() + { + NLNET::IModuleManager &mm = NLNET::IModuleManager::getInstance(); + + vector moduleList; + mm.getAvailableModuleClassList(moduleList); + + TEST_ASSERT(moduleList.size() == 4); + TEST_ASSERT(moduleList[0] == "LocalGateway"); + TEST_ASSERT(moduleList[1] == "ModuleAsync"); + TEST_ASSERT(moduleList[2] == "ModuleType0"); + TEST_ASSERT(moduleList[3] == "StandardGateway"); + } + + void testModuleInitInfoBadParsing() + { + NLNET::TParsedCommandLine mif; + + string paramString = " a=1 b=2 ( b=1) "; + TEST_ASSERT(!mif.parseParamList(paramString)); + + paramString = " lswkd ,fpqoj(( çruq fzemfwijf ujr wmozejifp_zujf woijpç_u ' "; + TEST_ASSERT(!mif.parseParamList(paramString)); + + paramString = "a ( b=2"; + TEST_ASSERT(!mif.parseParamList(paramString)); + + paramString = "a b=2)"; + TEST_ASSERT(!mif.parseParamList(paramString)); + + paramString = "a b=2\"toto\""; + TEST_ASSERT(!mif.parseParamList(paramString)); + + paramString = "=a"; + TEST_ASSERT(!mif.parseParamList(paramString)); + + paramString = "a(=b)"; + TEST_ASSERT(!mif.parseParamList(paramString)); + } + + void testModuleInitInfoQuering() + { + NLNET::TParsedCommandLine mif; + + string paramString = " a=1 b=2 sub ( y=22 zzzz=12 subsub (g=\"bean in box\" z=2) ) "; + + TEST_ASSERT(mif.parseParamList(paramString)); + + TEST_ASSERT(mif.getParam("a") != NULL); + TEST_ASSERT(mif.getParam("a") == mif.SubParams[0]); + + TEST_ASSERT(mif.getParam("sub") != NULL); + TEST_ASSERT(mif.getParam("sub") == mif.SubParams[2]); + + TEST_ASSERT(mif.getParam("foo") == NULL); + + TEST_ASSERT(mif.getParam("sub.subsub.g") != NULL); + TEST_ASSERT(mif.getParam("sub.subsub.g") == mif.SubParams[2]->SubParams[2]->SubParams[0]); + } + + void testModuleInitInfoParsing() + { + NLNET::TParsedCommandLine mif; + + string paramString = "a"; + TEST_ASSERT(mif.parseParamList(paramString)); + paramString = "a=1"; + TEST_ASSERT(mif.parseParamList(paramString)); + paramString = "a(b=1)"; + TEST_ASSERT(mif.parseParamList(paramString)); + paramString = "a a a a"; + TEST_ASSERT(mif.parseParamList(paramString)); + TEST_ASSERT(mif.SubParams.size() == 4); + paramString = " a ( b=1 )"; + TEST_ASSERT(mif.parseParamList(paramString)); + + paramString = " a=1 b=2 sub ( y=22 zzzz=12 subsub (g=\"bean in box\" z=2) ) "; + + TEST_ASSERT(mif.parseParamList(paramString)); + + TEST_ASSERT(mif.SubParams.size() == 3); + + TEST_ASSERT(mif.SubParams[0]->SubParams.size() == 0); + TEST_ASSERT(mif.SubParams[0]->ParamName == "a"); + TEST_ASSERT(mif.SubParams[0]->ParamValue == "1"); + + TEST_ASSERT(mif.SubParams[1]->SubParams.size() == 0); + TEST_ASSERT(mif.SubParams[1]->ParamName == "b"); + TEST_ASSERT(mif.SubParams[1]->ParamValue == "2"); + + TEST_ASSERT(mif.SubParams[2]->SubParams.size() == 3); + TEST_ASSERT(mif.SubParams[2]->ParamName == "sub"); + TEST_ASSERT(mif.SubParams[2]->ParamValue.empty()); + + TEST_ASSERT(mif.SubParams[2]->SubParams[0]->SubParams.size() == 0); + TEST_ASSERT(mif.SubParams[2]->SubParams[0]->ParamName == "y"); + TEST_ASSERT(mif.SubParams[2]->SubParams[0]->ParamValue == "22"); + + TEST_ASSERT(mif.SubParams[2]->SubParams[1]->SubParams.size() == 0); + TEST_ASSERT(mif.SubParams[2]->SubParams[1]->ParamName == "zzzz"); + TEST_ASSERT(mif.SubParams[2]->SubParams[1]->ParamValue == "12"); + + TEST_ASSERT(mif.SubParams[2]->SubParams[2]->SubParams.size() == 2); + TEST_ASSERT(mif.SubParams[2]->SubParams[2]->ParamName == "subsub"); + TEST_ASSERT(mif.SubParams[2]->SubParams[2]->ParamValue.empty()); + + TEST_ASSERT(mif.SubParams[2]->SubParams[2]->SubParams[0]->SubParams.size() == 0); + TEST_ASSERT(mif.SubParams[2]->SubParams[2]->SubParams[0]->ParamName == "g"); + TEST_ASSERT(mif.SubParams[2]->SubParams[2]->SubParams[0]->ParamValue == "bean in box"); + + TEST_ASSERT(mif.SubParams[2]->SubParams[2]->SubParams[1]->SubParams.size() == 0); + TEST_ASSERT(mif.SubParams[2]->SubParams[2]->SubParams[1]->ParamName == "z"); + TEST_ASSERT(mif.SubParams[2]->SubParams[2]->SubParams[1]->ParamValue == "2"); + } +}; + +#endif