← Back to team overview

nrtb-core team mailing list archive

[Branch ~fpstovall/nrtb/cpp_common] Rev 45: Complete unit tests for thread and updated the c++ common build order.

 

------------------------------------------------------------
revno: 45
committer: fpstovall@xxxxxxxxx
branch nick: dev
timestamp: Mon 2011-08-08 00:56:03 -0400
message:
  Complete unit tests for thread and updated the c++ common build order.
added:
  common/threads/Makefile
  common/threads/tests/
  common/threads/tests/cond_var.h
  common/threads/tests/general.h
  common/threads/tests/loop_counter.h
  common/threads/thread_test.cpp
modified:
  common/Makefile


--
lp:~fpstovall/nrtb/cpp_common
https://code.launchpad.net/~fpstovall/nrtb/cpp_common

Your team NRTB Core is subscribed to branch lp:~fpstovall/nrtb/cpp_common.
To unsubscribe from this branch go to https://code.launchpad.net/~fpstovall/nrtb/cpp_common/+edit-subscription
=== modified file 'common/Makefile'
--- common/Makefile	2011-07-22 02:58:56 +0000
+++ common/Makefile	2011-08-08 04:56:03 +0000
@@ -37,9 +37,10 @@
 
 doit:
 	@cd common_rl; make ${action}
-	@cd serializer; make ${action}
 	@cd point; make ${action}
 	@cd timer; make ${action}
+	@cd threads; make ${action}
+	@cd serializer; make ${action}
 	@cd logger; make ${action}
 	@cd confreader; make ${action}
 	@cd GPB; make ${action}

=== added file 'common/threads/Makefile'
--- common/threads/Makefile	1970-01-01 00:00:00 +0000
+++ common/threads/Makefile	2011-08-08 04:56:03 +0000
@@ -0,0 +1,36 @@
+#***********************************************
+#This file is part of the NRTB project (https://launchpad.net/nrtb).
+#
+#    NRTB is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    NRTB 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 General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
+#
+#***********************************************
+
+lib:	thread_test
+	@./thread_test
+	@cp -v base_thread.h ../include
+	@cp -v base_thread.o ../obj
+	@echo build complete
+
+base_thread.o:	base_thread.cpp base_thread.h Makefile
+	@rm -f base_thread.o
+	g++ -c -O3 base_thread.cpp -I ../include
+
+thread_test:	base_thread.o thread_test.cpp
+	@rm -f thread_test
+	g++ -c thread_test.cpp -I../include
+	g++ -o thread_test thread_test.o base_thread.o ../obj/hires_timer.o ../obj/common.o -lpthread
+
+clean:
+	@rm -rvf *.o thread_test ../include/base_thread.h ../obj/base_thread.o
+	@echo all objects and executables have been erased.

=== added directory 'common/threads/tests'
=== added file 'common/threads/tests/cond_var.h'
--- common/threads/tests/cond_var.h	1970-01-01 00:00:00 +0000
+++ common/threads/tests/cond_var.h	2011-08-08 04:56:03 +0000
@@ -0,0 +1,124 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+ 
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ 
+ NRTB 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 General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
+ 
+ **********************************************/
+ 
+#ifndef base_cond_var_test_h
+#define base_cond_var_test_h 
+ 
+#include "../base_thread.h"
+#include "general.h"
+#include "../../include/hires_timer.h"
+#include <sstream>
+#include <boost/concept_check.hpp>
+
+using namespace nrtb;
+using namespace std;
+
+class seller: public runnable
+{
+public:
+  hirez_timer elapsed;
+  int hits;
+  
+  seller()
+  {
+	message = "";
+	hits = 0;
+  };
+  
+  void signal(const string & msg)
+  {
+	{
+	  scope_lock lock(signal_lock);
+	  message = msg;
+	  signal_lock.signal();
+	}
+	{
+	  scope_lock lock(ready_lock);
+	  ready_lock.timed_wait(1);
+	}
+  };
+  
+  void run()
+  {
+	elapsed.start(0);
+	bool done = false;
+	while (!done)
+	{
+	  scope_lock lock(signal_lock);
+	  while (message == "")
+		signal_lock.wait();
+	  cout << elapsed.interval() << " Recieved " 
+		<< message << endl;
+	  if (message == "done")
+	  {
+		done = true;
+	  };
+	  hits++;
+	  message = "";
+	  {
+		scope_lock t(ready_lock);
+		ready_lock.signal();
+	  }
+	};
+  };
+  
+protected:
+  cond_variable signal_lock;
+  cond_variable ready_lock;
+  string message;
+};
+
+seller store;
+
+class cond_test: public runnable
+{
+public:
+  int ec;
+  
+  cond_test()
+  {
+	ec = 0;
+  };
+  
+  void run()
+  {
+	for (int i=0; i < 1000; i++)
+	{
+	  stringstream message;
+	  message << "Request_" << i;
+	  store.signal(message.str());
+	};
+	store.signal("done");
+  };
+
+  string operator() ()
+  {
+	stringstream msg;
+	msg << "Condition Variable Test\n"
+	  << "\tSent : 1001\n"
+	  << "\tRecd : " << store.hits
+	  << "\n\tPassed: " << ((store.hits == 1001)?"True":"False")
+	  << endl;
+	ec = 1001 - store.hits;
+	return msg.str();
+  };
+  
+};
+
+
+#endif // base_cond_var_test_h
\ No newline at end of file

=== added file 'common/threads/tests/general.h'
--- common/threads/tests/general.h	1970-01-01 00:00:00 +0000
+++ common/threads/tests/general.h	2011-08-08 04:56:03 +0000
@@ -0,0 +1,194 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+ 
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ 
+ NRTB 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 General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
+ 
+ **********************************************/
+ 
+#ifndef base_general_test_h
+#define base_general_test_h 
+ 
+#include "../base_thread.h"
+#include "../../include/hires_timer.h"
+#include <sstream>
+#include <boost/smart_ptr.hpp>
+
+using namespace nrtb;
+using namespace std;
+
+class console_writer
+{
+public:
+  mutex mylock;
+  hirez_timer elapsed;
+  
+  void write(const string & output)
+  {
+	scope_lock lock(mylock);
+	cout << elapsed.interval() << ": " << output << endl;
+  };
+};
+
+console_writer console;
+
+class gen_test_task: public runnable
+{
+  public:
+
+	int loop_counter;
+	int count_to;
+	string name;
+	int desired_priority;
+	hirez_timer runtime; 
+	
+	gen_test_task(
+	  const string & text,
+	  int target,
+	  int priority
+	)
+	{
+	  loop_counter = 0;
+	  count_to = target;
+	  name = text;
+	};
+	
+    virtual ~gen_test_task() {};
+	
+	void run()
+	{
+	  runtime.start(0);
+	  set_cancel_anytime();
+	  stringstream msg;
+	  msg.clear();
+	  msg << name
+		<< "(" << count_to << "," << desired_priority 
+		<< ") started.";
+	  console.write(msg.str());
+	  // loop till we die.
+	  for (int i=0; i<count_to; i++)
+	  {
+		loop_counter++;
+		// yeild the timeslice
+		sleep(0);
+	  };
+	  // report status and stop runtime counter.
+	  msg.str("");
+	  msg << name << " has counted to " << loop_counter;
+	  console.write(msg.str());
+	  runtime.stop();
+	};
+	
+	string report()
+	{
+	  stringstream maker;
+	  maker << "Task " << name << " Report"
+		<< "\n\tIterations  : " << loop_counter
+		<< "\n\tRun Time    : " << runtime.interval()
+		<< endl;
+	  return maker.str();
+	};
+};
+
+class gen_tester
+{
+  public:
+	typedef boost::shared_ptr<gen_test_task> taskp;
+	typedef vector<taskp> task_list;
+	typedef vector<thread> thread_list;
+	task_list tasks;
+	thread_list threads;
+	hirez_timer runtime;
+	int ec;
+	
+	gen_tester()
+	{
+	  ec = 0;
+	  for (int i=0; i<10; i++)
+	  {
+		stringstream s;
+		s << "task_" << i;
+		taskp t(new gen_test_task(s.str(),1e5,i*10));
+		tasks.push_back(t);
+		thread p(*t);
+		threads.push_back(p);
+	  };
+	};
+	
+	void run()
+	{
+	  stringstream msg;
+	  msg.str("");
+	  msg << "Starting " << threads.size() << " threads.";
+	  console.write(msg.str());
+	  // start all threads
+	  thread_list::iterator s = threads.begin();
+	  thread_list::iterator e = threads.end();
+	  thread_list::iterator c = s;
+	  while (c != e)
+	  {
+		c->start();
+		c++;
+	  };
+	  msg.str("");
+	  msg << "All threads started.";
+	  console.write(msg.str());
+	  // wait for the threads to complete.
+	  c = s;
+	  while (c != e)
+	  {
+		c->join();
+		c++;
+	  };
+	  msg.str("");
+	  msg << threads.size() << " threads complete.";
+	  console.write(msg.str());
+	  runtime.stop();
+	};
+	
+	string operator() ()
+	{
+	  stringstream msg;
+	  task_list::iterator s = tasks.begin();
+	  task_list::iterator e = tasks.end();
+	  task_list::iterator c = s;
+	  while (c != e)
+	  {
+		taskp t = *c;
+		msg << t->report();
+		if (t->loop_counter != t->count_to)
+		{
+		  ec++;
+		  msg << "The counter does not appear correct." << endl;
+		};
+		c++;
+	  };
+	  thread_list::iterator ts = threads.begin();
+	  thread_list::iterator te = threads.end();
+	  thread_list::iterator tc = ts;
+	  while (tc != te)
+	  {
+		if (tc->is_running())
+		{
+		  msg << "ERROR: A thread appears to be running." << endl;
+		  ec++;
+		};
+		tc++;
+	  };
+	  msg << "\nGeneral test run time " << runtime.interval() 
+		<< " seconds." << endl;
+	  return msg.str();
+	};
+};
+
+#endif // base_general_test_h
\ No newline at end of file

=== added file 'common/threads/tests/loop_counter.h'
--- common/threads/tests/loop_counter.h	1970-01-01 00:00:00 +0000
+++ common/threads/tests/loop_counter.h	2011-08-08 04:56:03 +0000
@@ -0,0 +1,76 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+ 
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ 
+ NRTB 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 General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
+ 
+ **********************************************/
+ 
+#ifndef base_thread_loop_test_h
+#define base_thread_loop_test_h 
+ 
+#include "../base_thread.h"
+#include "../../include/hires_timer.h"
+#include <sstream>
+
+using namespace nrtb;
+using namespace std;
+
+class counter_work_packet: public runnable
+{
+  public:
+
+	int loop_counter;
+	int call_counter;
+	int count_to;
+	hirez_timer runtime; 
+	
+	counter_work_packet()
+	{
+	  loop_counter = 0;
+	  call_counter = 0;
+	  count_to = 1000;
+	  runtime.reset();
+	};
+	
+	~counter_work_packet() {};
+	
+	void run()
+	{
+	  runtime.start();
+	  call_counter++;
+	  for (int i = 0; i < count_to; i++)
+	  {
+		loop_counter++;
+	  };
+	  runtime.stop();
+	};
+	
+	string report()
+	{
+	  stringstream maker;
+	  maker << "\ncounter_work_packet Report\n"
+		<<   "\tInvoications: " << call_counter 
+		<< "\n\tIterations  : " << loop_counter
+		<< "\n\tRun Time    : " << runtime.interval()
+		<< endl;
+	  return maker.str();
+	};
+	
+	string operator() ()
+	{
+	  return report();
+	};
+};
+
+#endif // base_thread_loop_test_h
\ No newline at end of file

=== added file 'common/threads/thread_test.cpp'
--- common/threads/thread_test.cpp	1970-01-01 00:00:00 +0000
+++ common/threads/thread_test.cpp	2011-08-08 04:56:03 +0000
@@ -0,0 +1,77 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+ 
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ 
+ NRTB 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 General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
+ 
+ **********************************************/
+ 
+#include "base_thread.h"
+#include <iostream>
+#include <sstream>
+#include "./tests/loop_counter.h"
+#include "./tests/general.h"
+#include "./tests/cond_var.h"
+
+using namespace std;
+using namespace nrtb;
+
+void runnable_pair_test(runnable & a, runnable & b)
+{
+  cerr << "Entering runnable_pair_test" << endl;
+  static thread ut1, ut2;
+  ut1.start(a);
+  ut2.start(b);
+  ut1.join();
+  ut2.join();
+};
+
+int main()
+{
+  int ec_count = 0;
+  // runnable work packet test.
+  counter_work_packet cwp1, cwp2;
+  cwp2.count_to = 1500;
+  runnable_pair_test(cwp1, cwp2);
+  runnable_pair_test(cwp2, cwp1);
+  cout << cwp1() << "\n" << cwp2() << endl;
+  // check the results.
+  if ((cwp1.loop_counter != 2000) or (cwp1.call_counter != 2))
+  {
+	ec_count++;
+  };
+  if ((cwp2.loop_counter != 3000) or (cwp2.call_counter != 2))
+  {
+	ec_count++;
+  };
+
+  // general thread test
+  gen_tester gen_test;
+  gen_test.run();
+  cout << "\nGeneral thread test\n" << gen_test() << endl;
+  ec_count += gen_test.ec;
+
+  // conditional variable tests
+  cond_test cv_test;
+  runnable_pair_test(store, cv_test);
+  cout << cv_test() << endl;
+  ec_count += cv_test.ec;
+  
+  if (ec_count)
+  {
+	cerr << "*** thread_test failed with " << ec_count
+	  << " errors" << endl;
+  };
+  
+  return ec_count;
+};
\ No newline at end of file