Commit af53bd02 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum

[ADD] - basic unit test for WModule,WModuleConnector and WModuleIn/OutputConnector.

parent e90450d1
......@@ -5,13 +5,15 @@ ADD_SUBDIRECTORY( exceptions )
FILE( GLOB KERNEL_EXCEPTIONS_SRC "exceptions/*.cpp" )
ADD_LIBRARY( kernel SHARED ${KERNEL_SRC} ${MODULES_SRC} ${KERNEL_EXCEPTIONS_SRC} )
TARGET_LINK_LIBRARIES( kernel common ge ${OPENSCENEGRAPH_LIBRARIES} )
TARGET_LINK_LIBRARIES( kernel dataHandler gui common ge ${OPENSCENEGRAPH_LIBRARIES} )
# Unit tests
IF( CXXTEST_FOUND )
SET( testLibs guiqt4 )
CXXTEST_ADD_TESTS_FROM_LIST( "${KERNEL_SRC}"
"" # no libs for linking required
${testLibs}
"WKernel.cpp"
"WModule.cpp"
"../modules/navigationSlices/WNavigationSliceModule.cpp"
......
......@@ -24,6 +24,7 @@
#include <set>
#include <string>
#include <sstream>
#include <boost/shared_ptr.hpp>
......@@ -31,12 +32,14 @@
#include "WModuleOutputConnector.h"
#include "WModuleConnectorSignals.h"
#include "exceptions/WModuleSignalUnknown.h"
#include "exceptions/WModuleConnectorInitFailed.h"
#include "WModule.h"
WModule::WModule():
WThreadedRunner()
{
// initialize members
m_Initialized=false;
}
......@@ -78,9 +81,25 @@ void WModule::removeConnectors()
m_OutputConnectors.clear();
}
void WModule::connectors()
{
}
void WModule::initializeConnectors()
{
// doing it twice is not allowed
if ( isInitialized() )
{
// TODO(ebaum): is this really needed?
std::ostringstream s;
s << "Could not initialize connectors for Module " << getName() << ". Reason: already initialized.";
throw WModuleConnectorInitFailed( s.str() );
}
m_Initialized=true;
connectors();
}
const std::set<boost::shared_ptr<WModuleInputConnector> >& WModule::getInputConnectors() const
......@@ -98,11 +117,11 @@ const t_GenericSignalHandlerType WModule::getSignalHandler( MODULE_CONNECTOR_SIG
switch ( signal )
{
case CONNECTION_ESTABLISHED:
return boost::bind( &WModule::notifyConnectionEstablished, this, _1, _2 );
return boost::bind( &WModule::notifyConnectionEstablished, this, _1, _2 );
case CONNECTION_CLOSED:
return boost::bind( &WModule::notifyConnectionClosed, this, _1, _2 );
return boost::bind( &WModule::notifyConnectionClosed, this, _1, _2 );
case DATA_CHANGED:
return boost::bind( &WModule::notifyDataChange, this, _1, _2 );
return boost::bind( &WModule::notifyDataChange, this, _1, _2 );
default:
throw new WModuleSignalUnknown( "Could not subscribe to unknown signal. You need to implement this signal type\
explicitly in your module." );
......
......@@ -106,9 +106,17 @@ protected:
// **************************************************************************************************************************
/**
* Initialize connectors in this function. It is pure virtual to enforce its implementation.
* Initialize connectors in this function. This function must not be called multiple times for one module instance.
* The module container manages calling those functions -> so just implement it.
*/
virtual void initializeConnectors();
virtual void connectors();
/**
* Manages connector initialization. Gets called by module container.
*
* \throw WModuleConnectorInitFailed if called multiple times.
*/
void initializeConnectors();
/**
* Set of input connectors associated with this module.
......
......@@ -152,7 +152,7 @@ boost::signals2::connection WModuleConnector::subscribeSignal( MODULE_CONNECTOR_
const t_GenericSignalHandlerType WModuleConnector::getSignalHandler( MODULE_CONNECTOR_SIGNAL signal )
{
// the module instance knows that
m_Module->getSignalHandler( signal );
return m_Module->getSignalHandler( signal );
}
void WModuleConnector::disconnect( boost::shared_ptr<WModuleConnector> con, bool removeFromOwnList )
......
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <string>
#include "WModuleConnectorInitFailed.h"
WModuleConnectorInitFailed::WModuleConnectorInitFailed( const std::string& msg ): WModuleException( msg )
{
// initialize members
}
WModuleConnectorInitFailed::~WModuleConnectorInitFailed() throw()
{
// cleanup
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WMODULECONNECTORINITFAILED_H
#define WMODULECONNECTORINITFAILED_H
#include <string>
#include "WModuleException.h"
/**
* General purpose exception and therefore base class for all kernel related exceptions.
* \ingroup ge
*/
class WModuleConnectorInitFailed: public WModuleException
{
public:
/**
* Default constructor.
* \param msg the exception message.
*/
explicit WModuleConnectorInitFailed( const std::string& msg = "Module connectors could not be initialized." );
/**
* Destructor.
*/
virtual ~WModuleConnectorInitFailed() throw();
protected:
private:
};
#endif // WMODULECONNECTORINITFAILED_H
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WMODULECONNECTOR_TEST_H
#define WMODULECONNECTOR_TEST_H
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <cxxtest/TestSuite.h>
#include "../WModuleConnector.h"
#include "../WModuleOutputConnector.h"
#include "../WModuleInputConnector.h"
#include "../WModule.h"
#include "../../common/WSegmentationFault.h"
#include "../exceptions/WModuleConnectorInitFailed.h"
/**
* Class implementing a simple mod // required since pure virtualule, since proper testing of WModuleConnector itself is not usable.
*/
class WModuleImpl: public WModule
{
friend class WModuleConnectorTest;
public:
WModuleImpl(): WModule()
{
}
virtual ~WModuleImpl()
{
}
// required since pure virtual
virtual const std::string getName() const
{
return "testmodule";
}
// required since pure virtual
virtual const std::string getDescription() const
{
return "testdesc";
}
virtual void initializeConnectors()
{
m_Input= boost::shared_ptr<WModuleInputConnector>(
new WModuleInputConnector( shared_from_this(), "in1", "desc1" )
);
// add it to the list of connectors. Please note, that a connector NOT added via addConnector will not work as expected.
addConnector( m_Input );
m_Output= boost::shared_ptr<WModuleOutputConnector>(
new WModuleOutputConnector( shared_from_this(), "out1", "desc2" )
);
// add it to the list of connectors. Please note, that a connector NOT added via addConnector will not work as expected.
addConnector( m_Output );
WModule::initializeConnectors();
}
protected:
virtual void threadMain()
{
// Since the modules run in a separate thread: such loops are possible
while ( !m_FinishRequested )
{
// do fancy stuff
sleep( 1 );
}
}
virtual void notifyConnectionEstablished( boost::shared_ptr<WModuleConnector> /*here*/,
boost::shared_ptr<WModuleConnector> /*there*/ )
{
std::cout << "hallo est" << std::endl;
}
virtual void notifyConnectionClosed( boost::shared_ptr<WModuleConnector> /*here*/,
boost::shared_ptr<WModuleConnector> /*there*/ )
{
std::cout << "hallo clo" << std::endl;
}
virtual void notifyDataChange( boost::shared_ptr<WModuleConnector> /*input*/,
boost::shared_ptr<WModuleConnector> /*output*/ )
{
std::cout << "hallo change" << std::endl;
}
private:
boost::shared_ptr<WModuleInputConnector> m_Input;
boost::shared_ptr<WModuleOutputConnector> m_Output;
};
/**
* Tests the WModuleConnector class. We use WModuleConnector's direct derived classes WModuleInputConnector and
* WModuleOutputConnector to test their common functionality implemented in WModuleConnector (which has pure virtual members -> so
* can't be instantiated directly).
*/
class WModuleConnectorTest : public CxxTest::TestSuite
{
public:
/**
* Tests the signal handler management.
*/
void testModuleConnectors( void )
{
// install signal handler as early as possible
//WSegmentationFault::installSignalHandler();
// init 2 separate test modules
boost::shared_ptr<WModuleImpl> m1 = boost::shared_ptr<WModuleImpl>( new WModuleImpl() );
boost::shared_ptr<WModuleImpl> m2 = boost::shared_ptr<WModuleImpl>( new WModuleImpl() );
// check whether there are NO connectors.
// The constructor should now create connectors since shared_ptr are needed -> init in constructor leads to exception
TS_ASSERT( m1->m_InputConnectors.size() == 0 );
TS_ASSERT( m1->m_OutputConnectors.size() == 0 );
TS_ASSERT( m2->m_InputConnectors.size() == 0 );
TS_ASSERT( m2->m_OutputConnectors.size() == 0 );
// init connectors
// TODO(ebaum): replace this with the module container, since the module container should manage this
// well actually this also tests the WModule::addConnector method and instantiation of WModuleInputConnector and
// WModuleOutputConnector.
TS_ASSERT_THROWS_NOTHING( m1->initializeConnectors() );
TS_ASSERT_THROWS_NOTHING( m2->initializeConnectors() );
// now there should be 1 everywhere
TS_ASSERT( m1->m_InputConnectors.size() == 1 );
TS_ASSERT( m1->m_OutputConnectors.size() == 1 );
TS_ASSERT( m2->m_InputConnectors.size() == 1 );
TS_ASSERT( m2->m_OutputConnectors.size() == 1 );
// try initializing twice
TS_ASSERT_THROWS( m1->initializeConnectors(), WModuleConnectorInitFailed );
// now we have 2 properly initialized modules?
TS_ASSERT( m1->isInitialized() );
TS_ASSERT( m2->isInitialized() );
// initialize connector
}
/**
* Test proper subscription to signals.
*/
void testSignalSubscription( void )
{
TS_ASSERT( true );
}
/**
* Connect/Disconnect Modules.
*/
void testConnection( void )
{
TS_ASSERT( true );
}
/**
* Tests disconnection of multiple connections.
*/
void testDisconnectAll( void )
{
TS_ASSERT( true );
}
};
#endif // WMODULECONNECTOR_TEST_H
......@@ -64,7 +64,7 @@ const std::string WNavigationSliceModule::getDescription() const
return "This module shows 3 orthogonal navigation slices.";
}
void WNavigationSliceModule::initializeConnectors()
void WNavigationSliceModule::connectors()
{
// initialize connectors
// XXX to add a new connector and to offer it, these simple steps need to be done
......@@ -72,11 +72,12 @@ void WNavigationSliceModule::initializeConnectors()
m_Input= boost::shared_ptr<WModuleInputConnector>(
new WModuleInputConnector( shared_from_this(), "in1", "Dataset to show on the slices." )
);
// add it to the list of connectors. Please note, that a connector NOT added via addConnector will not work as expected.
addConnector( m_Input );
// call WModules initialization
WModule::initializeConnectors();
WModule::connectors();
}
void WNavigationSliceModule::notifyDataChange( boost::shared_ptr<WModuleConnector> input,
......
......@@ -79,7 +79,7 @@ protected:
/**
* Initialize the connectors this module is using.
*/
virtual void initializeConnectors();
virtual void connectors();
/**
* Receive DATA_CHANGE notifications.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment