--- /dev/null
+
+#include <iostream>
+#include <dlfcn.h>
+#include <boost/test/included/unit_test.hpp>
+#include "schedule_module_control.h"
+#include "schedule_module_control_test.h"
+#include "logger.h"
+#include "parameter.h"
+
+using namespace l7vs;
+using namespace boost::unit_test;
+
+std::vector<l7vs::schedule_module_base*> test1_vec;
+std::vector<l7vs::schedule_module_base*> test2_vec;
+#define THREAD_LOOP_COUNT 100
+void thread1(){
+ BOOST_TEST_MESSAGE( "thread1 start" );
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ test1_vec.clear();
+ l7vs::schedule_module_base* schedule1 = NULL;
+ for( int i = 0; i < THREAD_LOOP_COUNT; i++ ){
+ try{
+ schedule1 = control.load_module( PM1 );
+ }
+ catch(...){
+ BOOST_ERROR( "exception : load_module thread1" );
+ }
+ test1_vec.push_back(schedule1);
+ }
+ BOOST_CHECK_EQUAL( test1_vec.size(), (size_t)THREAD_LOOP_COUNT );
+
+ std::vector<l7vs::schedule_module_base*>::iterator test1_it = test1_vec.begin();
+ for( int i = 0; i < THREAD_LOOP_COUNT; i++ ){
+ control.unload_module(*test1_it);
+ test1_it = test1_vec.erase(test1_it);
+ test1_it = test1_vec.begin();
+ }
+ BOOST_CHECK_EQUAL( test1_vec.size(), (size_t)0 );
+ BOOST_TEST_MESSAGE( "thread1 stop" );
+}
+
+void thread2(){
+ BOOST_TEST_MESSAGE( "thread2 start" );
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ test2_vec.clear();
+ l7vs::schedule_module_base* schedule2 = NULL;
+ for( int i = 0; i < THREAD_LOOP_COUNT; i++ ){
+ try{
+ schedule2 = control.load_module( PM2 );
+ }
+ catch(...){
+ BOOST_ERROR( "exception : load_module thread2" );
+ }
+ test2_vec.push_back(schedule2);
+ }
+ BOOST_CHECK_EQUAL( test2_vec.size(), (size_t)THREAD_LOOP_COUNT );
+
+ std::vector<l7vs::schedule_module_base*>::iterator test2_it = test2_vec.begin();
+ for( int i = 0; i < THREAD_LOOP_COUNT; i++ ){
+ control.unload_module(*test2_it);
+ test2_it = test2_vec.erase(test2_it);
+ test2_it = test2_vec.begin();
+ }
+ BOOST_CHECK_EQUAL( test2_vec.size(), (size_t)0 );
+ BOOST_TEST_MESSAGE( "thread2 stop" );
+}
+
+void thread3(){
+ BOOST_TEST_MESSAGE( "thread3 start" );
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ test1_vec.clear();
+ l7vs::schedule_module_base* schedule1 = NULL;
+ for( int i = 0; i < THREAD_LOOP_COUNT; i++ ){
+ try{
+ schedule1 = control.load_module( PM1 );
+ }
+ catch(...){
+ BOOST_ERROR( "exception : load_module thread3" );
+ }
+ test1_vec.push_back(schedule1);
+ }
+ BOOST_CHECK_EQUAL( test1_vec.size(), (size_t)THREAD_LOOP_COUNT );
+ BOOST_TEST_MESSAGE( "thread3 stop" );
+}
+
+void thread4(){
+ BOOST_TEST_MESSAGE( "thread4 start" );
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ test2_vec.clear();
+ l7vs::schedule_module_base* schedule2 = NULL;
+ for( int i = 0; i < THREAD_LOOP_COUNT; i++ ){
+ try{
+ schedule2 = control.load_module( PM1 );
+ }
+ catch(...){
+ BOOST_ERROR( "exception : load_module thread4" );
+ }
+ test2_vec.push_back(schedule2);
+ }
+ BOOST_CHECK_EQUAL( test2_vec.size(), (size_t)THREAD_LOOP_COUNT );
+ BOOST_TEST_MESSAGE( "thread4 stop" );
+}
+
+void thread5(){
+ BOOST_TEST_MESSAGE( "thread5 start" );
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ BOOST_CHECK_EQUAL( test1_vec.size(), (size_t)THREAD_LOOP_COUNT );
+ std::vector<l7vs::schedule_module_base*>::iterator test1_it = test1_vec.begin();
+#if 1
+ for( int i = 0; i < THREAD_LOOP_COUNT; i++ ){
+ control.unload_module(*test1_it);
+ test1_vec.erase(test1_it);
+ test1_it = test1_vec.begin();
+ }
+#else
+ for( test1_it = test1_vec.begin(); test1_it != test1_vec.end(); test1_it++ ){
+ control.unload_module(*test1_it);
+ }
+ test1_vec.clear();
+#endif
+ BOOST_TEST_MESSAGE( "thread5 stop" );
+}
+
+void thread6(){
+ BOOST_TEST_MESSAGE( "thread6 start" );
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ BOOST_CHECK_EQUAL( test2_vec.size(), (size_t)THREAD_LOOP_COUNT );
+ std::vector<l7vs::schedule_module_base*>::iterator test2_it = test2_vec.begin();
+#if 1
+ for( int i = 0; i < THREAD_LOOP_COUNT; i++ ){
+ control.unload_module(*test2_it);
+ test2_vec.erase(test2_it);
+ test2_it = test2_vec.begin();
+ }
+#else
+ for( test2_it = test2_vec.begin(); test2_it != test2_vec.end(); test2_it++ ){
+ control.unload_module(*test2_it);
+ }
+ test2_vec.clear();
+#endif
+ BOOST_TEST_MESSAGE( "thread6 stop" );
+}
+
+void thread7(){
+ BOOST_TEST_MESSAGE( "thread7 start" );
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ test1_vec.clear();
+ l7vs::schedule_module_base* schedule1 = NULL;
+ for( int i = 0; i < THREAD_LOOP_COUNT; i++ ){
+ try{
+ schedule1 = control.load_module( PM1 );
+ }
+ catch(...){
+ BOOST_ERROR( "exception : load_module thread7" );
+ }
+ test1_vec.push_back(schedule1);
+ }
+ BOOST_CHECK_EQUAL( test1_vec.size(), (size_t)THREAD_LOOP_COUNT );
+
+ std::vector<l7vs::schedule_module_base*>::iterator test1_it = test1_vec.begin();
+ for( int i = 0; i < THREAD_LOOP_COUNT; i++ ){
+ control.unload_module(*test1_it);
+ test1_it = test1_vec.erase(test1_it);
+ test1_it = test1_vec.begin();
+ }
+ BOOST_CHECK_EQUAL( test1_vec.size(), (size_t)0 );
+ BOOST_TEST_MESSAGE( "thread7 stop" );
+}
+
+void thread8(){
+ BOOST_TEST_MESSAGE( "thread8 start" );
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ test2_vec.clear();
+ l7vs::schedule_module_base* schedule2 = NULL;
+ for( int i = 0; i < THREAD_LOOP_COUNT; i++ ){
+ try{
+ schedule2 = control.load_module( PM1 );
+ }
+ catch(...){
+ BOOST_ERROR( "exception : load_module thread8" );
+ }
+ test2_vec.push_back(schedule2);
+ }
+ BOOST_CHECK_EQUAL( test2_vec.size(), (size_t)THREAD_LOOP_COUNT );
+
+ std::vector<l7vs::schedule_module_base*>::iterator test2_it = test2_vec.begin();
+ for( int i = 0; i < THREAD_LOOP_COUNT; i++ ){
+ control.unload_module(*test2_it);
+ test2_it = test2_vec.erase(test2_it);
+ test2_it = test2_vec.begin();
+ }
+ BOOST_CHECK_EQUAL( test2_vec.size(), (size_t)0 );
+ BOOST_TEST_MESSAGE( "thread8 stop" );
+}
+
+void thread9(){
+ BOOST_TEST_MESSAGE( "thread9 start" );
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ l7vs::schedule_module_base* schedule1 = NULL;
+ for( int i = 0; i < THREAD_LOOP_COUNT; i++ ){
+ try{
+ schedule1 = control.load_module( PM1 );
+ }
+ catch(...){
+ BOOST_ERROR( "exception : load_module thread9" );
+ }
+ control.unload_module( schedule1 );
+ }
+ BOOST_TEST_MESSAGE( "thread9 stop" );
+}
+
+void thread10(){
+ BOOST_TEST_MESSAGE( "thread10 start" );
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ l7vs::schedule_module_base* schedule2 = NULL;
+ for( int i = 0; i < THREAD_LOOP_COUNT; i++ ){
+ try{
+ schedule2 = control.load_module( PM2 );
+ }
+ catch(...){
+ BOOST_ERROR( "exception : load_module thread10" );
+ }
+ control.unload_module( schedule2 );
+ }
+ BOOST_TEST_MESSAGE( "thread10 stop" );
+}
+
+void load2_unload2_thread( int id, const std::string& modulename ){
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ l7vs::schedule_module_base* schedule1 = NULL;
+ schedule1 = control.load_module2( id, modulename );
+ control.unload_module2( id, schedule1 );
+
+ control.finalize();
+}
+
+void load_unload2_thread( int id, const std::string& modulename ){
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ l7vs::schedule_module_base* schedule1 = NULL;
+ schedule1 = control.load_module( modulename );
+ control.unload_module2( id, schedule1 );
+
+ control.finalize();
+}
+
+void load2_unload_thread( int id, const std::string& modulename ){
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ l7vs::schedule_module_base* schedule1 = NULL;
+ schedule1 = control.load_module2( id, modulename );
+ control.unload_module( schedule1 );
+
+ control.finalize();
+}
+
+void schedule_module_control_test_thread1(){
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ control.initialize( "." );
+
+ schedule_module_control::name_module_info_map& loadmodulemap = control.get_loadmodule_map();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)0 );
+#if 1
+ // unit_test[1] スレッド1はPM1のロードとアンロード、スレッド2はPM2のロードとアンロードを行い、最終的にロードモジュールのマップのサイズが0となっていることを確認する
+ boost::thread thd1( &thread1 );
+ boost::thread thd2( &thread2 );
+ thd1.join();
+ thd2.join();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)0 );
+#endif
+ control.finalize();
+}
+
+void schedule_module_control_test_thread2(){
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ control.initialize( "." );
+
+ schedule_module_control::name_module_info_map& loadmodulemap = control.get_loadmodule_map();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)0 );
+#if 1
+ // unit_test[2] スレッド1はPM1のロード、スレッド2はPM1のロードを行い、最終的にロードモジュールのマップのサイズが1となっていることを確認する
+ boost::thread thd1( &thread3 );
+ boost::thread thd2( &thread4 );
+ thd1.join();
+ thd2.join();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)1 );
+
+ // unit_test[3] スレッド3はPM1のアンロード、スレッド4はPM1のアンロードを行い、最終的にロードモジュールのマップのサイズが0となっていることを確認する
+ boost::thread thd3( &thread5 );
+ boost::thread thd4( &thread6 );
+ thd3.join();
+ thd4.join();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)0 );
+#endif
+ control.finalize();
+}
+
+void schedule_module_control_test_thread3(){
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ control.initialize( "." );
+
+ schedule_module_control::name_module_info_map& loadmodulemap = control.get_loadmodule_map();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)0 );
+ // unit_test[4] スレッド1はPM1のロードとアンロード、スレッド2はPM1のロードとアンロードを行い、最終的にロードモジュールのマップのサイズが0となっていることを確認する
+ boost::thread thd1( &thread7 );
+ boost::thread thd2( &thread8 );
+ thd1.join();
+ thd2.join();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)0 );
+ control.finalize();
+}
+
+void schedule_module_control_test_thread4(){
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ control.initialize( "." );
+
+ schedule_module_control::name_module_info_map& loadmodulemap = control.get_loadmodule_map();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)0 );
+ // unit_test[5] スレッド1はPM1のロード/アンロード、スレッド2はPM2のロード/アンロードをそれぞれセットで行い、最終的にロードモジュールのマップのサイズが0となっていることを確認する
+ boost::thread thd1( &thread9 );
+ boost::thread thd2( &thread10 );
+ thd1.join();
+ thd2.join();
+ loadmodulemap = control.get_loadmodule_map();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)0 );
+ control.finalize();
+}
+
+void schedule_module_control_test_thread5(){
+ schedule_module_control_testclass& control = schedule_module_control_testclass::getInstance();
+ control.initialize( "." );
+ schedule_module_control::name_module_info_map& loadmodulemap = control.get_loadmodule_map();
+ loadmodulemap = control.get_loadmodule_map();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)0 );
+
+ // unit_test[6] load_moduleを複数スレッドからアクセスした場合の動作チェック(同じモジュールを指定した場合)
+ boost::thread thd1( boost::bind( &load2_unload2_thread, 1, PM1 ) );
+ boost::thread thd2( boost::bind( &load2_unload2_thread, 2, PM1 ) );
+ boost::thread thd3( boost::bind( &load2_unload2_thread, 3, PM1 ) );
+ boost::thread thd4( boost::bind( &load2_unload2_thread, 4, PM1 ) );
+ boost::thread thd5( boost::bind( &load2_unload2_thread, 5, PM1 ) );
+
+ sleep(1);
+ loadmodulemap = control.get_loadmodule_map();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)0 );
+ BOOST_MESSAGE( "notify_all" );
+ control.load_condition.notify_all();
+
+ sleep(1);
+ loadmodulemap = control.get_loadmodule_map();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)1 );
+ // unit_test[7] unload_moduleを複数スレッドからアクセスした場合の動作チェック(同じモジュールを指定した場合)
+ BOOST_MESSAGE( "notify_all" );
+ control.load_condition.notify_all();
+
+ thd1.join();
+ thd2.join();
+ thd3.join();
+ thd4.join();
+ thd5.join();
+
+ loadmodulemap = control.get_loadmodule_map();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)0 );
+
+ // unit_test[8] load_moduleとunload_moduleを複数スレッドからアクセスした場合の動作チェック(同じモジュールを指定した場合)
+ boost::thread thd6( boost::bind( &load2_unload_thread, 6, PM1 ) );
+ boost::thread thd7( boost::bind( &load_unload2_thread, 7, PM1 ) );
+
+ sleep(1);
+ loadmodulemap = control.get_loadmodule_map();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)1 );
+ BOOST_MESSAGE( "notify_all" );
+ control.load_condition.notify_all();
+
+ thd6.join();
+ thd7.join();
+
+ loadmodulemap = control.get_loadmodule_map();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)0 );
+
+ // unit_test[9] load_moduleを複数スレッドからアクセスした場合の動作チェック(それぞれ別のモジュールを指定した場合)
+ boost::thread thd8( boost::bind( &load2_unload2_thread, 8, PM1 ) );
+ boost::thread thd9( boost::bind( &load2_unload2_thread, 9, PM2 ) );
+
+ sleep(1);
+ loadmodulemap = control.get_loadmodule_map();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)0 );
+ BOOST_MESSAGE( "notify_all" );
+ control.load_condition.notify_all();
+
+ sleep(1);
+ loadmodulemap = control.get_loadmodule_map();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)2 );
+ // unit_test[10] unload_moduleを複数スレッドからアクセスした場合の動作チェック(それぞれ別のモジュールを指定した場合)
+ BOOST_MESSAGE( "notify_all" );
+ control.load_condition.notify_all();
+
+ thd8.join();
+ thd9.join();
+
+ loadmodulemap = control.get_loadmodule_map();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)0 );
+
+ // unit_test[11] load_moduleとunload_moduleを複数スレッドからアクセスした場合の動作チェック(それぞれ別のモジュールを指定した場合)
+ boost::thread thd10( boost::bind( &load2_unload_thread, 10, PM1 ) );
+ boost::thread thd11( boost::bind( &load_unload2_thread, 11, PM2 ) );
+
+ sleep(1);
+ loadmodulemap = control.get_loadmodule_map();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)1 );
+ BOOST_MESSAGE( "notify_all" );
+ control.load_condition.notify_all();
+
+ thd10.join();
+ thd11.join();
+
+ loadmodulemap = control.get_loadmodule_map();
+ BOOST_CHECK_EQUAL( loadmodulemap.size(), (size_t)0 );
+ control.finalize();
+}
+
+test_suite* init_unit_test_suite( int argc, char* argv[] ){
+
+// Logger logger;
+// l7vs::Parameter param;
+
+ // create unit test suite
+ test_suite* ts = BOOST_TEST_SUITE( "schedule_module_control_thread_test" );
+
+ // add test case to test suite
+ ts->add( BOOST_TEST_CASE( &schedule_module_control_test_thread1 ) );
+ ts->add( BOOST_TEST_CASE( &schedule_module_control_test_thread2 ) );
+ ts->add( BOOST_TEST_CASE( &schedule_module_control_test_thread3 ) );
+ ts->add( BOOST_TEST_CASE( &schedule_module_control_test_thread4 ) );
+ ts->add( BOOST_TEST_CASE( &schedule_module_control_test_thread5 ) );
+
+ framework::master_test_suite().add( ts );
+
+ return 0;
+}