Переглянути джерело

Added event admin performance unit test.

Sascha Zelzer 12 роки тому
батько
коміт
7702bc013a

+ 2 - 0
Libs/PluginFramework/Testing/CMakeLists.txt

@@ -24,6 +24,8 @@ add_subdirectory(org.commontk.pluginfwtest)
 add_subdirectory(FrameworkTestPlugins)
 
 add_subdirectory(org.commontk.pluginfwtest.perf)
+add_subdirectory(org.commontk.eventadmintest.perf)
+
 add_subdirectory(org.commontk.configadmintest)
 add_subdirectory(org.commontk.eventadmintest)
 

+ 42 - 0
Libs/PluginFramework/Testing/org.commontk.eventadmintest.perf/CMakeLists.txt

@@ -0,0 +1,42 @@
+project(org_commontk_eventadmintest_perf)
+
+set(PLUGIN_export_directive "org_commontk_eventadmintest_perf_EXPORT")
+
+set(PLUGIN_SRCS
+  ctkEventAdminTestPerfActivator_p.h
+  ctkEventAdminTestPerfActivator.cpp
+  ctkEventAdminPerfTestSuite_p.h
+  ctkEventAdminPerfTestSuite.cpp
+)
+
+set(PLUGIN_MOC_SRCS
+  ctkEventAdminTestPerfActivator_p.h
+  ctkEventAdminPerfTestSuite_p.h
+)
+
+set(PLUGIN_UI_FORMS
+
+)
+
+set(PLUGIN_resources
+
+)
+
+ctkFunctionGetTargetLibraries(PLUGIN_target_libraries)
+
+if(UNIX)
+  list(APPEND PLUGIN_target_libraries rt)
+endif()
+
+ctkMacroBuildPlugin(
+  NAME ${PROJECT_NAME}
+  EXPORT_DIRECTIVE ${PLUGIN_export_directive}
+  SRCS ${PLUGIN_SRCS}
+  MOC_SRCS ${PLUGIN_MOC_SRCS}
+  UI_FORMS ${PLUGIN_UI_FORMS}
+  RESOURCES ${PLUGIN_resources}
+  TARGET_LIBRARIES ${PLUGIN_target_libraries}
+  TEST_PLUGIN
+)
+
+set(eventadmin_perftest ${PROJECT_NAME} CACHE INTERNAL "Target name for the plugin containing performance tests for EventAdmin implementations")

+ 187 - 0
Libs/PluginFramework/Testing/org.commontk.eventadmintest.perf/ctkEventAdminPerfTestSuite.cpp

@@ -0,0 +1,187 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+
+#include "ctkEventAdminPerfTestSuite_p.h"
+
+#include <ctkPluginContext.h>
+#include <ctkServiceEvent.h>
+
+#include <service/event/ctkEventAdmin.h>
+#include <service/event/ctkEventConstants.h>
+
+#include <QTest>
+#include <QDebug>
+
+
+//----------------------------------------------------------------------------
+TestEventHandler::TestEventHandler(int& counter)
+  : counter(counter)
+{}
+
+//----------------------------------------------------------------------------
+void TestEventHandler::handleEvent(const ctkEvent& )
+{
+  counter++;
+}
+
+//----------------------------------------------------------------------------
+ctkEventAdminPerfTestSuite::ctkEventAdminPerfTestSuite(ctkPluginContext *context, int pluginId)
+  : pc(context)
+  , pluginId(pluginId)
+  , nSendEvents(400)
+  , nHandlers(40)
+  , nEvent1Handled(0)
+  , nEvent2Handled(0)
+  , eventAdmin(0)
+{
+}
+
+//----------------------------------------------------------------------------
+void ctkEventAdminPerfTestSuite::addHandlers()
+{
+  qDebug() << "Adding" << nHandlers << "event handlers";
+  for (int i = 0; i < nHandlers; ++i)
+  {
+    TestEventHandler* h1 = new TestEventHandler(nEvent1Handled);
+    handlers.push_back(h1);
+    ctkDictionary props1;
+    props1.insert(ctkEventConstants::EVENT_TOPIC, "org/bla/1");
+    handlerRegistrations.push_back(pc->registerService<ctkEventHandler>(h1, props1));
+
+
+    TestEventHandler* h2 = new TestEventHandler(nEvent2Handled);
+    handlers.push_back(h2);
+    ctkDictionary props2;
+    props2.insert(ctkEventConstants::EVENT_TOPIC, "org/bla/*");
+    handlerRegistrations.push_back(pc->registerService<ctkEventHandler>(h2, props2));
+
+    TestEventHandler* h3 = new TestEventHandler(nEvent2Handled);
+    handlers.push_back(h3);
+    ctkDictionary props3;
+    props3.insert(ctkEventConstants::EVENT_TOPIC, "org/bla/*");
+    props3.insert(ctkEventConstants::EVENT_FILTER, "(name=bla)");
+    handlerRegistrations.push_back(pc->registerService<ctkEventHandler>(h3, props3));
+  }
+}
+
+//----------------------------------------------------------------------------
+void ctkEventAdminPerfTestSuite::removeHandlers()
+{
+  foreach(ctkServiceRegistration sr, handlerRegistrations)
+  {
+    sr.unregister();
+  }
+  handlerRegistrations.clear();
+  qDeleteAll(handlers);
+  handlers.clear();
+}
+
+//----------------------------------------------------------------------------
+void ctkEventAdminPerfTestSuite::sendEvents()
+{
+  ctkEvent event1("org/bla/1");
+  for (int i = 0; i < nSendEvents; ++i)
+  {
+    eventAdmin->sendEvent(event1);
+  }
+
+  for (int i = 0; i < nSendEvents; ++i)
+  {
+    ctkDictionary props;
+    props.insert("name", "bla");
+    props.insert("level", i);
+    ctkEvent event2("org/bla/2", props);
+    eventAdmin->sendEvent(event2);
+  }
+}
+
+//----------------------------------------------------------------------------
+void ctkEventAdminPerfTestSuite::postEvents()
+{
+  ctkEvent event1("org/bla/1");
+  for (int i = 0; i < nSendEvents; ++i)
+  {
+    eventAdmin->postEvent(event1);
+  }
+
+  for (int i = 0; i < nSendEvents; ++i)
+  {
+    ctkDictionary props;
+    props.insert("name", "bla");
+    props.insert("level", i);
+    ctkEvent event2("org/bla/2", props);
+    eventAdmin->postEvent(event2);
+  }
+}
+
+//----------------------------------------------------------------------------
+void ctkEventAdminPerfTestSuite::initTestCase()
+{
+  nEvent1Handled = 0;
+  nEvent2Handled = 0;
+
+  pc->getPlugin(pluginId)->start();
+  ctkServiceReference reference = pc->getServiceReference<ctkEventAdmin>();
+  QVERIFY(reference);
+  eventAdmin = pc->getService<ctkEventAdmin>(reference);
+  QVERIFY(eventAdmin);
+
+  addHandlers();
+}
+
+//----------------------------------------------------------------------------
+void ctkEventAdminPerfTestSuite::testSendEvents()
+{
+  QTime t;
+  t.start();
+  sendEvents();
+  int ms = t.elapsed();
+  QCOMPARE(nEvent1Handled, nSendEvents * nHandlers);
+  QCOMPARE(nEvent2Handled, nSendEvents * nHandlers * 3);
+  qDebug() << "Sending" << 2*nSendEvents << "synchronous events took" << ms << "ms";
+}
+
+//----------------------------------------------------------------------------
+void ctkEventAdminPerfTestSuite::testPostEvents()
+{
+  QTime t;
+  t.start();
+  postEvents();
+  int ms = t.elapsed();
+  qDebug() << "Sending" << 2*nSendEvents << "asynchronous events took" << ms << "ms";
+  // wait a little for the asynchronous handling of events
+  QTest::qWait(10000);
+}
+
+//----------------------------------------------------------------------------
+void ctkEventAdminPerfTestSuite::cleanupTestCase()
+{
+  try
+  {
+    removeHandlers();
+    pc->getPlugin(pluginId)->stop();
+  }
+  catch (const ctkInvalidArgumentException&)
+  {
+    qDebug() << "NOooooo!!!";
+  }
+}

+ 87 - 0
Libs/PluginFramework/Testing/org.commontk.eventadmintest.perf/ctkEventAdminPerfTestSuite_p.h

@@ -0,0 +1,87 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+
+#ifndef CTKEAPERFTESTSUITE_P_H
+#define CTKEAPERFTESTSUITE_P_H
+
+#include "ctkTestSuiteInterface.h"
+
+#include <service/event/ctkEventHandler.h>
+#include <ctkServiceRegistration.h>
+
+#include <QDebug>
+
+struct ctkEventAdmin;
+
+class ctkEventAdminPerfTestSuite : public QObject, public ctkTestSuiteInterface
+{
+  Q_OBJECT
+  Q_INTERFACES(ctkTestSuiteInterface)
+
+private:
+
+  ctkPluginContext* pc;
+  int pluginId;
+
+  int nSendEvents;
+  int nHandlers;
+
+  int nEvent1Handled;
+  int nEvent2Handled;
+
+  ctkEventAdmin* eventAdmin;
+
+  QList<ctkEventHandler*> handlers;
+  QList<ctkServiceRegistration> handlerRegistrations;
+
+public:
+
+  ctkEventAdminPerfTestSuite(ctkPluginContext* context, int pluginId);
+
+private:
+
+  void addHandlers();
+  void removeHandlers();
+
+  void sendEvents();
+  void postEvents();
+
+private Q_SLOTS:
+
+  void initTestCase();
+  void testSendEvents();
+  void testPostEvents();
+  void cleanupTestCase();
+};
+
+class TestEventHandler : public QObject, public ctkEventHandler
+{
+  Q_OBJECT
+  Q_INTERFACES(ctkEventHandler)
+private:
+  int& counter;
+public:
+  TestEventHandler(int& counter);
+  void handleEvent(const ctkEvent& );
+};
+
+#endif // CTKEAPERFTESTSUITE_P_H

+ 82 - 0
Libs/PluginFramework/Testing/org.commontk.eventadmintest.perf/ctkEventAdminTestPerfActivator.cpp

@@ -0,0 +1,82 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+#include "ctkEventAdminTestPerfActivator_p.h"
+
+#include "ctkEventAdminPerfTestSuite_p.h"
+
+#include <QtPlugin>
+
+
+//----------------------------------------------------------------------------
+ctkEventAdminTestPerfActivator::ctkEventAdminTestPerfActivator()
+  : perfTestSuite(0)
+{
+
+}
+
+//----------------------------------------------------------------------------
+ctkEventAdminTestPerfActivator::~ctkEventAdminTestPerfActivator()
+{
+  delete perfTestSuite;
+}
+
+//----------------------------------------------------------------------------
+void ctkEventAdminTestPerfActivator::start(ctkPluginContext* context)
+{
+  QString symbolicName = context->getProperty("event.impl").toString();
+  if (symbolicName.isEmpty())
+  {
+    throw ctkRuntimeException("Framework property 'event.impl' containing the symbolic "
+                              "name of the EventAdmin implementation not found!");
+  }
+
+  long eventPluginId = -1;
+  foreach(QSharedPointer<ctkPlugin> p, context->getPlugins())
+  {
+    if (p->getSymbolicName() == symbolicName)
+    {
+      eventPluginId = p->getPluginId();
+      break;
+    }
+  }
+
+  if (eventPluginId < 0)
+  {
+    QString msg = QString("The EventAdmin implementation '%1' is not installed.")
+        .arg(symbolicName);
+    throw ctkRuntimeException(msg);
+  }
+
+  perfTestSuite = new ctkEventAdminPerfTestSuite(context, eventPluginId);
+  context->registerService<ctkTestSuiteInterface>(perfTestSuite);
+}
+
+//----------------------------------------------------------------------------
+void ctkEventAdminTestPerfActivator::stop(ctkPluginContext* context)
+{
+  Q_UNUSED(context);
+
+  delete perfTestSuite;
+  perfTestSuite = 0;
+}
+
+Q_EXPORT_PLUGIN2(org_commontk_eventadmintest_perf, ctkEventAdminTestPerfActivator)

+ 48 - 0
Libs/PluginFramework/Testing/org.commontk.eventadmintest.perf/ctkEventAdminTestPerfActivator_p.h

@@ -0,0 +1,48 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+
+#ifndef CTKEVENTADMINTESTPERFACTIVATOR_H
+#define CTKEVENTADMINTESTPERFACTIVATOR_H
+
+#include <ctkPluginActivator.h>
+
+
+class ctkEventAdminTestPerfActivator : public QObject,
+    public ctkPluginActivator
+{
+  Q_OBJECT
+  Q_INTERFACES(ctkPluginActivator)
+
+public:
+
+  ctkEventAdminTestPerfActivator();
+  ~ctkEventAdminTestPerfActivator();
+
+  void start(ctkPluginContext* context);
+  void stop(ctkPluginContext* context);
+
+private:
+
+  QObject* perfTestSuite;
+};
+
+#endif // CTKEVENTADMINTESTPERFACTIVATOR_H

+ 10 - 0
Libs/PluginFramework/Testing/org.commontk.eventadmintest.perf/manifest_headers.cmake

@@ -0,0 +1,10 @@
+set(Plugin-ActivationPolicy "eager")
+set(Plugin-Name "Event Admin Performance Test Suite")
+set(Plugin-Version "0.9")
+set(Plugin-Description "Test the performance of the event admin")
+set(Plugin-Vendor "CommonTK")
+set(Plugin-DocURL "http://www.commontk.org")
+set(Plugin-ContactAddress "http://www.commontk.org")
+set(Plugin-Category "test")
+set(Plugin-Copyright "German Cancer Research Center, Division of Medical and Biological Informatics")
+set(Plugin-License "http://www.apache.org/licenses/LICENSE-2.0.html")

+ 9 - 0
Libs/PluginFramework/Testing/org.commontk.eventadmintest.perf/target_libraries.cmake

@@ -0,0 +1,9 @@
+#
+# See CMake/ctkFunctionGetTargetLibraries.cmake
+# 
+# This file should list the libraries required to build the current CTK plugin.
+# 
+
+set(target_libraries
+  CTKPluginFramework
+  )

+ 18 - 1
Plugins/org.commontk.eventadmin/Testing/Cpp/CMakeLists.txt

@@ -8,9 +8,11 @@ set(MY_MOC_CXX )
 
 #QT4_WRAP_CPP(MY_MOC_CXX ${MOC_SRCS})
 
+# Create a test for this EventAdmin implementation
+
 set(test_executable ${PROJECT_NAME}CppTests)
 
-add_executable(${test_executable} ${SRCS} ${MY_MOC_CXX})
+add_executable(${test_executable} ctkEventAdminImplTestMain.cpp)
 target_link_libraries(${test_executable}
   ${fw_lib}
   ${fwtestutil_lib}
@@ -20,3 +22,18 @@ add_dependencies(${test_executable} ${PROJECT_NAME} ${eventadmin_test})
 
 add_test(${PROJECT_NAME}Tests ${CPP_TEST_PATH}/${test_executable})
 set_property(TEST ${PROJECT_NAME}Tests PROPERTY LABELS ${PROJECT_NAME})
+
+# Create a performance test for this EventAdmin implementation
+
+set(test_executable ${PROJECT_NAME}PerfTests)
+
+add_executable(${test_executable} ctkEventAdminImplPerfTestMain.cpp)
+target_link_libraries(${test_executable}
+  ${fw_lib}
+  ${fwtestutil_lib}
+)
+
+add_dependencies(${test_executable} ${PROJECT_NAME} ${eventadmin_perftest})
+
+add_test(${PROJECT_NAME}PerfTests ${CPP_TEST_PATH}/${test_executable})
+set_property(TEST ${PROJECT_NAME}PerfTests PROPERTY LABELS ${PROJECT_NAME})

+ 70 - 0
Plugins/org.commontk.eventadmin/Testing/Cpp/ctkEventAdminImplPerfTestMain.cpp

@@ -0,0 +1,70 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+
+#include <QCoreApplication>
+
+#include <ctkConfig.h>
+#include <ctkPluginConstants.h>
+
+#include <Testing/Cpp/ctkPluginFrameworkTestRunner.h>
+
+
+int main(int argc, char** argv)
+{
+  QCoreApplication app(argc, argv);
+
+  ctkPluginFrameworkTestRunner testRunner;
+
+  app.setOrganizationName("CTK");
+  app.setOrganizationDomain("commontk.org");
+  app.setApplicationName("ctkEventAdminImplCppTests");
+
+  QString pluginDir;
+#ifdef CMAKE_INTDIR
+  pluginDir = CTK_PLUGIN_DIR CMAKE_INTDIR "/";
+#else
+  pluginDir = CTK_PLUGIN_DIR;
+#endif
+
+  QString testpluginDir;
+#ifdef CMAKE_INTDIR
+  testpluginDir = qApp->applicationDirPath() + "/../test_plugins/" CMAKE_INTDIR "/";
+#else
+  testpluginDir = qApp->applicationDirPath() + "/test_plugins/";
+#endif
+
+  testRunner.addPluginPath(pluginDir, false);
+  testRunner.addPlugin(testpluginDir, "org_commontk_eventadmintest_perf");
+  testRunner.addPlugin(pluginDir, "org_commontk_eventadmin");
+  testRunner.addPlugin(pluginDir, "org_commontk_log");
+  testRunner.startPluginOnRun("org.commontk.eventadmintest.perf");
+
+  ctkProperties fwProps;
+  fwProps.insert(ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN, ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);
+  fwProps.insert("pluginfw.testDir", testpluginDir);
+  fwProps.insert("event.impl", "org.commontk.eventadmin");
+
+  fwProps.insert("org.commontk.eventadmin.ThreadPoolSize", 10);
+
+  testRunner.init(fwProps);
+  return testRunner.run(argc, argv);
+}