khanat-opennel-code/code/nel/tools/nel_unit_test/ut_net_module.h
2013-06-05 23:04:46 -07:00

2981 lines
94 KiB
C++

// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// 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 <http://www.gnu.org/licenses/>.
#ifndef UT_NET_MODULE
#define UT_NET_MODULE
#include <nel/misc/dynloadlib.h>
#include <nel/misc/command.h>
#include <nel/misc/path.h>
#include <nel/net/module_common.h>
#include <nel/net/module_manager.h>
#include <nel/net/module.h>
#include <nel/net/inet_address.h>
#include <nel/net/module_socket.h>
#include <nel/net/module_gateway.h>
#include <nel/net/service.h>
class CModuleType0 : public NLNET::CModuleBase
{
public:
uint PingCount;
uint ResponseReceived;
set<NLNET::TModuleProxyPtr> 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 &param)
{
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(const 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 &param)
: 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 &param)
: 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 &param)
: 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 &param)
: 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 &params)
: 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<NLNET::IModuleProxy*> proxies;
_Gateway->getModuleProxyList(proxies);
// remove any security data managed by this plug-in
for (uint i=0; i<proxies.size(); ++i)
{
NLNET::IModuleProxy *proxy = proxies[i];
if (proxy->getFirstSecurityData() != 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 &params)
: 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<NLNET::IModuleProxy*> proxies;
_Gateway->getModuleProxyList(proxies);
// remove any security data managed by this plug-in
for (uint i=0; i<proxies.size(); ++i)
{
NLNET::IModuleProxy *proxy = proxies[i];
if (proxy->getGatewayRoute() == 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<NLNET::IModuleProxy*> proxList, const std::string &modName)
{
for (uint i=0; i<proxList.size(); ++i)
{
if (proxList[i]->getModuleName().find(modName) == (proxList[i]->getModuleName().size() - modName.size()))
return true;
}
return false;
}
NLNET::IModuleProxy *retrieveModuleProxy(NLNET::IModuleGateway *gw, const std::string &modName)
{
vector<NLNET::IModuleProxy*> proxList;
gw->getModuleProxyList(proxList);
for (uint i=0; i<proxList.size(); ++i)
{
if (proxList[i]->getModuleName().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<NLNET::IModuleGateway *>(gw);
CModuleType0 *mod0 = dynamic_cast<CModuleType0*>(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<NLNET::IModuleGateway *>(gw1);
NLNET::IModuleGateway *gGw2 = dynamic_cast<NLNET::IModuleGateway *>(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<CModuleType0 *>(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<NLNET::IModuleGateway *>(gw1);
TEST_ASSERT(gGw1 != NULL);
gGw2 = dynamic_cast<NLNET::IModuleGateway *>(gw2);
TEST_ASSERT(gGw2 != NULL);
gGw3 = dynamic_cast<NLNET::IModuleGateway *>(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<const TSecurityType2 *>(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<const TSecurityType2 *>(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<const TSecurityType1 *>(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<const TSecurityType1 *>(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<const TSecurityType1 *>(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<const TSecurityType2 *>(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<const TSecurityType2 *>(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<NLNET::IModuleGateway *>(gw1);
TEST_ASSERT(gGw1 != NULL);
gGw2 = dynamic_cast<NLNET::IModuleGateway *>(gw2);
TEST_ASSERT(gGw2 != NULL);
gGw3 = dynamic_cast<NLNET::IModuleGateway *>(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<const TSecurityType4*>(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<const NLNET::TUnknownSecurityData*>(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<const NLNET::TUnknownSecurityData*>(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
//
// /---<optional>---\
// (l3s) gw1 (l3c) (l3s) gw2 (l3c) ------ (l3s) gw3 (l3c) ------ (l3s) gw4
// | \----------------/ |
// | |
// | |
// \------------------<optional>-----------------------------------/
//
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<NLNET::IModuleGateway *>(gw1);
TEST_ASSERT(gGw1 != NULL);
gGw2 = dynamic_cast<NLNET::IModuleGateway *>(gw2);
TEST_ASSERT(gGw2 != NULL);
gGw3 = dynamic_cast<NLNET::IModuleGateway *>(gw3);
TEST_ASSERT(gGw3 != NULL);
gGw4 = dynamic_cast<NLNET::IModuleGateway *>(gw4);
TEST_ASSERT(gGw4 != NULL);
vector<NLNET::IModuleProxy*> 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<NLNET::IModuleGateway *>(peer1);
TEST_ASSERT(gPeer1 != NULL);
gPeer2 = dynamic_cast<NLNET::IModuleGateway *>(peer2);
TEST_ASSERT(gPeer2 != NULL);
gMaster = dynamic_cast<NLNET::IModuleGateway *>(master);
TEST_ASSERT(gMaster != NULL);
gOther = dynamic_cast<NLNET::IModuleGateway *>(other);
TEST_ASSERT(gOther != NULL);
vector<NLNET::IModuleProxy*> 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<NLNET::IModuleGateway *>(peer1);
TEST_ASSERT(gPeer1 != NULL);
gPeer2 = dynamic_cast<NLNET::IModuleGateway *>(peer2);
TEST_ASSERT(gPeer2 != NULL);
gMaster = dynamic_cast<NLNET::IModuleGateway *>(master);
TEST_ASSERT(gMaster != NULL);
gOther = dynamic_cast<NLNET::IModuleGateway *>(other);
TEST_ASSERT(gOther != NULL);
vector<NLNET::IModuleProxy*> 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<NLNET::IModuleProxy*> 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<NLNET::IModuleGateway*>(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<NLNET::IModuleProxy*> 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<CModuleType0*>(m1);
TEST_ASSERT(mod1 != NULL);
TEST_ASSERT(mod1->PingCount == 1);
CModuleType0 *mod2 = dynamic_cast<CModuleType0*>(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<NLNET::IModuleGateway*>(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<NLNET::IModuleGateway*>(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<NLNET::IModuleProxy*> 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<NLNET::IModuleProxy*> 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<NLNET::IModuleGateway*>(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<NLNET::IModuleProxy*> 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<NLNET::IModuleGateway*>(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<NLNET::IModuleGateway*>(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<NLNET::IModuleGateway*>(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<NLNET::IModuleGateway*>(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<NLNET::IModuleGateway*>(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<IModule> 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<IModule> 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<string> 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<string> 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(( cruq fzemfwijf ujr wmozejifp_zujf woijpc_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