2 The software in this package is distributed under the GNU General
3 Public License version 2 (with a special exception described below).
5 A copy of GNU General Public License (GPL) is included in this distribution,
6 in the file COPYING.GPL.
8 As a special exception, if other files instantiate templates or use macros
9 or inline functions from this file, or you compile this file and link it
10 with other works to produce a work based on this file, this file
11 does not by itself cause the resulting work to be covered
12 by the GNU General Public License.
14 However the source code for this file must still be made available
15 in accordance with section (3) of the GNU General Public License.
17 This exception does not invalidate any other reasons why a work based
18 on this file might be covered by the GNU General Public License.
22 * (c) Copyright 2007-2010 by Intra2net AG
32 #include <async_io.hpp>
33 #include <async_pipe.hpp>
34 #include <async_process.hpp>
35 #include <async_timer.hpp>
36 #include <async_callout.hpp>
37 #include <async_socket.hpp>
38 #include <asyncio_system_tools.hpp>
39 #include <asyncio_containerfunc.hpp>
41 #include <boost/signals2.hpp>
42 #include <boost/bind.hpp>
43 #include <boost/random.hpp>
45 #define BOOST_TEST_MAIN
46 #define BOOST_TEST_DYN_LINK
47 #include <boost/test/unit_test.hpp>
50 #define DOUT(msg) std::cout << msg << std::endl
52 #define DOUT(msg) do {} while (0)
57 using namespace AsyncIo;
67 Counter() : value(0) { DOUT("Counter construct");}
69 void reset() { value=0;}
73 DOUT(" advance called");
82 }; // eo struct Counter
85 class TestTimer : public TimerBase
95 void setDelta(long msec)
97 setDeltaWhenTime(0,msec);
99 } // eo setDelta(long)
106 virtual void execute()
111 }; // eo class TestTimer
117 std::vector<std::string> m_received_vector;
118 std::string m_received_string;
120 unsigned long m_count_lines;
121 unsigned long m_data_size;
124 void resetReceivedData()
126 m_received_vector.clear();
127 m_received_string.clear();
133 void receiveData(const std::string& data)
135 m_received_vector.push_back(data);
136 m_received_string.append(data);
138 m_data_size += data.size();
139 } // eo receiveData(const std::string&)
141 }; // eo struct ReceivedData
145 class TestPipe : public SimplePipe, public ReceivedData
151 signal_received_string.connect( boost::bind(&TestPipe::receiveData, this, _1) );
158 }; // eo class TestPipe
161 class TestIO : public SimpleIO2, public ReceivedData
166 signal_received_string.connect( boost::bind(&TestIO::receiveData, this, _1) );
172 class TestProcess : public ProcessImplementation, public ReceivedData
176 const std::string& path,
177 const std::vector<std::string>& args= std::vector<std::string>() )
178 : ProcessImplementation(path,args)
180 m_signal_read.connect( boost::bind(&TestProcess::slotReceivedData, this) );
181 } // eo Testprocess(const std::string&, const std::vector<std::string>&)
184 const std::string& path,
185 const std::string& arg1 )
186 : ProcessImplementation(
188 TransientPushBackFiller< std::string,std::vector >()(arg1)
191 m_signal_read.connect( boost::bind(&TestProcess::slotReceivedData, this) );
192 } // eo Testprocess(const std::string&, const std::vector<std::string>&)
195 const std::string& path,
196 const std::string& arg1, const std::string& arg2 )
197 : ProcessImplementation(
199 TransientPushBackFiller< std::string, std::vector >()(arg1)(arg2)
202 m_signal_read.connect( boost::bind(&TestProcess::slotReceivedData, this) );
203 } // eo Testprocess(const std::string&, const std::vector<std::string>&)
207 void slotReceivedData()
209 receiveData(m_input_buffer);
210 m_input_buffer.clear();
211 } // eo slotReceivedData()
213 }; // eo class TestProcess
217 class TestUnixIOSocket
218 : public UnixIOSocket
219 , public ReceivedData
226 m_signal_read.connect( boost::bind(&TestUnixIOSocket::slotReceivedData, this) );
227 } // eo TestUnixIOSocket()
231 int fd, const std::string& path
233 : UnixIOSocket(fd, path)
235 m_signal_read.connect( boost::bind(&TestUnixIOSocket::slotReceivedData, this) );
236 } // eo TestUnixIOSocket()
239 void sendData(const std::string& data)
242 } // eo sendData(const std::string&)
246 void slotReceivedData()
248 receiveData(m_input_buffer);
249 m_input_buffer.clear();
250 } // eo slotReceivedData()
252 }; // eo class TestUnixIOSocket
254 typedef boost::shared_ptr< TestUnixIOSocket > TestUnixIOSocketPtr;
257 class UnixIOSocketHolder
258 : public std::vector< UnixIOSocketPtr >
262 void operator()(UnixIOSocketPtr ptr)
267 void storeBase (IOImplementationPtr ptr)
269 push_back(boost::dynamic_pointer_cast< UnixIOSocket >(ptr) );
272 void store (UnixIOSocketPtr ptr)
277 TestUnixIOSocketPtr get(int idx)
279 return boost::dynamic_pointer_cast<
283 }; // eo class UnixIOSocketHolder
286 /// global random generator (from boost lib).
287 boost::mt19937 g_random_gen;
291 * generates a string with random characters from a given ASCII subset.
292 * @param len the desired length of the output string
293 * @return a random string of length @a len
295 std::string makeRandomAsciiString(std::string::size_type len)
297 static std::string chars("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz=+-*/%(){}<>.,:;\\");
300 boost::uniform_int<> discreter(0, chars.size()-1);
301 boost::variate_generator<boost::mt19937&, boost::uniform_int<> > idxgen(g_random_gen, discreter);
303 for(; len-->0;) s+= chars.at( idxgen() );
306 } // eo makeRandomAsciiString
309 } // eo namespace <anonymous>
312 class SimpleioBasicsFixture
316 std::set<std::string> used_check_files;
318 template<class Callable>
319 bool backendLoopUntil( Callable condition, int maxLoops=100 )
321 for (int i=std::max(maxLoops,1); i-->0 && ! condition();)
323 backend->doOneStep(10);
326 } // eo backendLoopUntil
329 bool backendStep(int msTimeout= 10, int count=1)
332 for(;count-->0 && res;)
334 res= backend->doOneStep(msTimeout);
340 std::string getCheckFilepath(std::string tag)
343 result= "__unittest__" + tag + ".dat";
344 used_check_files.insert(result);
346 } // eo get_check_file_path
349 void removeCheckFiles()
351 for(std::set<std::string>::iterator it= used_check_files.begin();
352 it != used_check_files.end();
355 std::string filepath(*it);
356 if (Utils::FileStat(filepath))
358 Utils::unlink(filepath);
361 used_check_files.clear();
362 } // eo removeCheckFiles
365 SimpleioBasicsFixture()
367 backend = Backend::getBackend();
368 installChildHandler();
369 used_check_files.clear();
372 ~SimpleioBasicsFixture()
374 restoreChildHandler();
379 BOOST_FIXTURE_TEST_SUITE(TestSimpleioBasics, SimpleioBasicsFixture)
381 BOOST_AUTO_TEST_CASE(EmptyBackendStepCall)
383 BOOST_REQUIRE( backend );
385 // a backend call without active objects should return false:
386 bool result = backend->doOneStep(0);
388 BOOST_CHECK_EQUAL( false, result );
389 } // eo EmptyBackendStepCall
393 BOOST_AUTO_TEST_CASE(NonEmptyBackendStepCall)
395 BOOST_REQUIRE(backend);
400 // with an active object, a step should return true:
401 bool result = backend->doOneStep(0);
402 BOOST_CHECK_EQUAL( true, result );
403 // the timer should not be executed:
404 BOOST_CHECK_EQUAL( 0u, timer.m_counter );
406 // now it should return false:
407 bool result = backend->doOneStep(0);
408 BOOST_CHECK_EQUAL( false, result );
409 } // eo NonEmptyBackendStepCall
414 * check for timer to execute immediatly.
416 BOOST_AUTO_TEST_CASE(SingleTimerShot)
418 BOOST_REQUIRE(backend);
421 timer.setDelta(0); // shot now!
423 bool result = backend->doOneStep(10);
425 BOOST_CHECK_EQUAL( true, result );
426 // the timer should be executed once:
427 BOOST_CHECK_EQUAL( 1u, timer.m_counter );
429 result = backend->doOneStep(0);
431 BOOST_CHECK_EQUAL( false, result );
432 // the timer should not be executed again:
433 BOOST_CHECK_EQUAL( 1u, timer.m_counter );
435 } // eo SingleTimerShot()
440 * tests a simple timer class to be executed with a timeout.
442 BOOST_AUTO_TEST_CASE(SimpleTimerShot)
445 BOOST_REQUIRE(backend);
449 timer1.addAction( boost::bind(&Counter::advance,&counter1) );
450 BOOST_CHECK_EQUAL(false, timer1.active());
452 timer1.startTimerMS( 100 );
453 BOOST_CHECK_EQUAL(true, timer1.active());
455 res=backend->doOneStep( 1000 );
456 BOOST_CHECK_EQUAL( true, res );
458 BOOST_CHECK_EQUAL( 1, counter1.value );
459 } // eo SimpleTimerShot
464 * tests 3 timers; after the first was active, disable another and check if the remaining one fires.
466 BOOST_AUTO_TEST_CASE(SimpleTimerShot2)
469 BOOST_REQUIRE(backend);
471 SimpleTimer timer1, timer2, timer3;
472 Counter counter1, counter2, counter3;
473 timer1.addAction( boost::bind(&Counter::advance,&counter1) );
474 timer2.addAction( boost::bind(&Counter::advance,&counter2) );
475 timer3.addAction( boost::bind(&Counter::advance,&counter3) );
476 BOOST_CHECK_EQUAL(false, timer1.active());
477 BOOST_CHECK_EQUAL(false, timer2.active());
478 BOOST_CHECK_EQUAL(false, timer3.active());
480 timer1.startTimerMS( 100 );
481 timer2.startTimerMS( 500 );
482 timer3.startTimerMS( 400 );
483 BOOST_CHECK_EQUAL(true, timer1.active());
484 BOOST_CHECK_EQUAL(true, timer2.active());
485 BOOST_CHECK_EQUAL(true, timer3.active());
487 res=backend->doOneStep( 1000 );
488 BOOST_CHECK_EQUAL( true, res );
490 BOOST_CHECK_EQUAL(false, timer1.active());
491 BOOST_CHECK_EQUAL(true, timer2.active());
492 BOOST_CHECK_EQUAL(true, timer3.active());
494 BOOST_CHECK_EQUAL( 1, counter1.value );
495 BOOST_CHECK_EQUAL( 0, counter2.value );
496 BOOST_CHECK_EQUAL( 0, counter3.value );
498 // now stop the next timer:
500 BOOST_CHECK_EQUAL(false, timer3.active());
502 res=backend->doOneStep( 1000 );
503 BOOST_CHECK_EQUAL( true, res );
505 BOOST_CHECK_EQUAL( 1, counter1.value );
506 BOOST_CHECK_EQUAL( 1, counter2.value );
507 BOOST_CHECK_EQUAL( 0, counter3.value );
508 } // eo SimpleTimerShot2
517 BOOST_AUTO_TEST_CASE(EmptyWantTest)
521 BOOST_CHECK_EQUAL(false, io.wantRead() );
522 BOOST_CHECK_EQUAL(false, io.wantWrite() );
523 } // eo EmptyWantTest
527 * a simple pipe (and io) test.
529 * This test basically tests the io framework.
530 * It opens two connected pipes and sends a test string in each direction.
531 * It tests the following functionalities of the base classes:
532 * - set write marks in backend step (enabling direct send of data)
534 * - construct and interpret poll() data structures
536 * - signal chains for received data
541 BOOST_AUTO_TEST_CASE(SimplePipeTest)
543 static const std::string test_string("a test string");
544 static const std::string test_string2("only another short test string");
546 BOOST_REQUIRE(backend);
548 TestPipe pipe1, pipe2;
550 bool res= pipe1.makePipe(pipe2);
552 BOOST_CHECK_EQUAL(true, res);
553 BOOST_CHECK_EQUAL(true, pipe1.opened());
554 BOOST_CHECK_EQUAL(true, pipe2.opened());
556 res= backend->doOneStep(0);
557 BOOST_CHECK_EQUAL(true, res);
559 pipe1.sendString(test_string);
561 res= backend->doOneStep(0);
562 BOOST_CHECK_EQUAL(true, res);
564 BOOST_CHECK_EQUAL( test_string, pipe2.m_received_string );
566 pipe2.sendString(test_string2);
568 res= backend->doOneStep(0);
569 BOOST_CHECK_EQUAL(true, res);
571 BOOST_CHECK_EQUAL( test_string2, pipe1.m_received_string );
574 BOOST_CHECK_EQUAL(false, pipe1.opened());
576 res= backend->doOneStep(0);
577 BOOST_CHECK_EQUAL(true, res);
579 BOOST_CHECK_EQUAL(true, pipe2.eof());
580 } // eo SimplePipeTest
585 * sends a larger data chunk through a pipe.
586 * This tests if sending and receiving data in (smaller internal) chunks works.
588 BOOST_AUTO_TEST_CASE(SimplePipePump)
590 BOOST_REQUIRE(backend);
592 TestPipe pipe1, pipe2;
594 bool res= pipe1.makePipe(pipe2);
596 BOOST_CHECK_EQUAL(true, res);
597 BOOST_CHECK_EQUAL(true, pipe1.opened());
598 BOOST_CHECK_EQUAL(true, pipe2.opened());
600 res= backend->doOneStep(0);
601 BOOST_CHECK_EQUAL(true, res);
603 std::string test_string= makeRandomAsciiString(256*1024);
605 pipe1.sendString(test_string);
607 res= backend->doOneStep(0);
608 BOOST_CHECK_EQUAL(true, res);
610 // do some backend cycles to empty the pipe:
611 for (int i=64; i-->0 && res && !pipe1.empty(); )
613 res= backend->doOneStep(100);
617 BOOST_CHECK_EQUAL(false, pipe1.opened());
619 // now read the remaining data until we recognize EOF:
620 for (int i=64; i-->0 && res && !pipe2.eof();)
622 res= backend->doOneStep(100);
625 BOOST_CHECK_EQUAL( test_string.size(), pipe2.m_received_string.size() );
626 BOOST_CHECK_EQUAL( test_string, pipe2.m_received_string );
628 BOOST_CHECK_EQUAL(true, pipe2.eof());
629 } // eo SimplePipePump
634 * fork a subprocess (/bin/true) and test exit code.
636 BOOST_AUTO_TEST_CASE(SimpleProcessTestBinTrue)
639 BOOST_REQUIRE(backend);
641 TestProcess proc("/bin/true");
643 res= proc.startProcess();
644 BOOST_CHECK_EQUAL(true, res);
646 res= backend->doOneStep(200);
647 BOOST_CHECK_EQUAL(true, res);
649 for(int i=20; i-->0 && proc.processState() != ProcessState::stopped;)
651 backend->doOneStep(15);
654 BOOST_CHECK_EQUAL( ProcessState(ProcessState::stopped), proc.processState() );
655 BOOST_CHECK_EQUAL( true, proc.eof() );
656 BOOST_CHECK_EQUAL( 0, proc.exitCode() );
657 } // eo SimpleProcessTestBinTrue
661 * fork a subprocess (/bin/false) and test exit code.
663 BOOST_AUTO_TEST_CASE(SimpleProcessTestBinFalse)
666 BOOST_REQUIRE(backend);
668 TestProcess proc("/bin/false");
670 res= proc.startProcess();
671 BOOST_CHECK_EQUAL(true, res);
673 res= backend->doOneStep(200);
674 BOOST_CHECK_EQUAL(true, res);
675 for(int i=20; i-->0 && proc.processState() != ProcessState::stopped;)
677 backend->doOneStep(15);
680 BOOST_CHECK_EQUAL( ProcessState(ProcessState::stopped), proc.processState() );
681 BOOST_CHECK_EQUAL( true, proc.eof() );
682 BOOST_CHECK_EQUAL( 1, proc.exitCode() );
683 DOUT("leave SimpleProcessTestBinFalse");
684 } // eo SimpleProcessTestBinFalse
688 * fork an echo subprocess and read back the output.
690 BOOST_AUTO_TEST_CASE(SimpleProcessTestEcho)
692 DOUT("enter SimpleProcessTestEcho");
694 BOOST_REQUIRE(backend);
698 TransientPushBackFiller<std::string, std::vector >()("Eine")("Zeichenkette")
701 res= proc.startProcess();
702 BOOST_CHECK_EQUAL(true, res);
704 res= backend->doOneStep(200);
705 BOOST_CHECK_EQUAL(true, res);
706 for(int i=20; i-->0 && (proc.processState()!= ProcessState::stopped || !proc.eof());)
708 backend->doOneStep(10);
711 BOOST_CHECK_EQUAL( ProcessState(ProcessState::stopped), proc.processState() );
712 BOOST_CHECK_EQUAL( true, proc.eof() );
713 BOOST_CHECK_EQUAL( 0, proc.exitCode() );
714 BOOST_CHECK_EQUAL( std::string("Eine Zeichenkette\n"), proc.m_received_string);
715 } // eo SimpleProcessTestEcho
720 * fork a bash subprocess, echo something on stderr and read back the output.
722 BOOST_AUTO_TEST_CASE(SimpleProcessTestStderr)
725 BOOST_REQUIRE(backend);
731 TransientPushBackFiller<std::string, std::vector >()
733 ("echo Eine Zeichenkette >&2")
736 // start with a seperate io object for stderr.
737 DOUT("## start process");
738 res= proc.startProcess( &my_stderr );
739 BOOST_CHECK_EQUAL(true, res);
740 BOOST_CHECK_EQUAL(true, my_stderr.opened());
742 DOUT("## do a backend step");
743 res= backend->doOneStep(200);
744 BOOST_CHECK_EQUAL(true, res);
745 // wait until process stopped and both io's signal EOF (or until the loop ends ;-) )
746 DOUT("## enter loop");
747 for(int i=17; i-->0 && (proc.processState()!= ProcessState::stopped || !proc.eof() || !my_stderr.eof());)
749 DOUT("## round i=" << i);
750 backend->doOneStep(10);
752 DOUT("## loop left");
754 BOOST_CHECK_EQUAL( ProcessState(ProcessState::stopped), proc.processState() );
755 BOOST_CHECK_EQUAL( true, proc.eof() );
756 BOOST_CHECK_EQUAL( true, my_stderr.eof() );
757 BOOST_CHECK_EQUAL( 0, proc.exitCode() );
758 BOOST_CHECK_EQUAL( std::string("Eine Zeichenkette\n"), my_stderr.m_received_string);
759 DOUT("leave Test SimpleProcessTestStderr");
760 } // eo SimpleProcessTestStderr
765 * checks termination of process by signal and if the signal is returned.
767 BOOST_AUTO_TEST_CASE(SignaledProcessTermination)
770 BOOST_REQUIRE(backend);
772 TestProcess proc("/bin/sleep","2");
773 res= proc.startProcess();
774 BOOST_CHECK_EQUAL(true, res);
776 res= backend->doOneStep(10);
777 BOOST_CHECK_EQUAL(true, res);
778 BOOST_CHECK_EQUAL( ProcessState(ProcessState::running), proc.processState() );
780 res= backend->doOneStep(50);
782 // now send the process an USR1 (which terminates the process)
783 res=proc.kill( Signal::USR1 );
784 BOOST_CHECK_EQUAL(true, res);
786 // give the backend a chance to process the termination event:
787 for(int i=30; i-->0 && proc.processState()!=ProcessState::stopped;) backend->doOneStep(10);
789 BOOST_CHECK_EQUAL( ProcessState(ProcessState::stopped), proc.processState() );
790 BOOST_CHECK_EQUAL( true, proc.eof() );
791 BOOST_CHECK_EQUAL( Signal::USR1 , proc.exitCode()>>8 );
792 } // eo SignaledProcessTermination
795 * fork an echo subprocess and read back the output. Directly use ProcessImplementation without helper class.
797 BOOST_AUTO_TEST_CASE(DirectProcessImplementationTestEcho)
799 DOUT("enter SimpleProcessTestEcho");
801 BOOST_REQUIRE(backend);
803 ProcessImplementation proc(
805 TransientPushBackFiller<std::string, std::vector >()("Eine")("Zeichenkette")
808 res= proc.startProcess();
809 BOOST_CHECK_EQUAL(true, res);
811 res= backend->doOneStep(200);
812 BOOST_CHECK_EQUAL(true, res);
813 for(int i=20; i-->0 && (proc.processState()!= ProcessState::stopped || !proc.eof());)
815 backend->doOneStep(10);
818 BOOST_CHECK_EQUAL( ProcessState(ProcessState::stopped), proc.processState() );
819 BOOST_CHECK_EQUAL( true, proc.eof() );
820 BOOST_CHECK_EQUAL( 0, proc.exitCode() );
821 BOOST_CHECK_EQUAL( std::string("Eine Zeichenkette\n"), proc.getInput());
822 BOOST_CHECK_EQUAL( 5, proc.shortenInput(5));
823 BOOST_CHECK_EQUAL( std::string("Zeichenkette\n"), proc.getInput());
824 BOOST_CHECK_EQUAL( true, proc.inputAvailable());
825 BOOST_CHECK_EQUAL( std::string("Zeichenkette\n"), proc.getInputClear());
826 BOOST_CHECK_EQUAL( false, proc.inputAvailable());
827 } // eo SimpleProcessTestEcho
829 BOOST_AUTO_TEST_CASE(DirectProcessImplementationGetline)
831 DOUT("enter SimpleProcessTestEcho");
833 BOOST_REQUIRE(backend);
835 ProcessImplementation proc(
837 TransientPushBackFiller<std::string, std::vector >()("-c")("echo -n 1; sleep 1; echo 2; echo")
840 res= proc.startProcess();
841 BOOST_CHECK_EQUAL(true, res);
843 res= backend->doOneStep(800);
844 BOOST_CHECK_EQUAL(true, res);
846 // echo -n 1 should be out by now
848 BOOST_CHECK_EQUAL( std::string(""), proc.getline());
850 for(int i=20; i-->0 && (proc.processState()!= ProcessState::stopped || !proc.eof());)
852 backend->doOneStep(100);
855 BOOST_CHECK_EQUAL( ProcessState(ProcessState::stopped), proc.processState() );
856 BOOST_CHECK_EQUAL( true, proc.eof() );
857 BOOST_CHECK_EQUAL( 0, proc.exitCode() );
858 BOOST_CHECK_EQUAL( std::string("12\n"), proc.getline());
859 BOOST_CHECK_EQUAL( std::string("\n"), proc.getline());
860 BOOST_CHECK_EQUAL( false, proc.inputAvailable());
861 } // eo SimpleProcessTestEcho
863 BOOST_AUTO_TEST_CASE(CallOut1)
867 callOut( boost::bind(&Counter::advance, &count), 1 );
868 backend->doOneStep( 10 );
870 BOOST_CHECK_EQUAL( 0, count.value );
871 backend->doOneStep( 1100 );
873 BOOST_CHECK_EQUAL( 1, count.value );
878 BOOST_AUTO_TEST_CASE(CallOut2)
882 callOut( boost::bind(&Counter::advance, &count), 0.5 );
883 backend->doOneStep( 10 );
885 BOOST_CHECK_EQUAL( 0, count.value );
886 backend->doOneStep( 800 );
888 BOOST_CHECK_EQUAL( 1, count.value );
893 BOOST_AUTO_TEST_CASE(RemoveCallOut1)
897 CallOutId id= callOut( boost::bind(&Counter::advance, &count), 1 );
898 backend->doOneStep( 10 );
900 BOOST_CHECK_EQUAL( 0, count.value );
901 bool res1 = removeCallOut(id);
902 bool res2 = removeCallOut(id);
904 BOOST_CHECK_EQUAL( true, res1 );
905 BOOST_CHECK_EQUAL( false, res2 );
907 backend->doOneStep( 1100 );
909 BOOST_CHECK_EQUAL( 0, count.value );
910 } // eo RemoveCallOut1()
914 BOOST_AUTO_TEST_CASE(FrozenCall_Thaw)
918 CallOutId id= frozenCall( boost::bind(&Counter::advance, &count), 1 );
919 backend->doOneStep( 10 );
921 BOOST_CHECK_EQUAL( 0, count.value );
924 backend->doOneStep( 1100 );
926 BOOST_CHECK_EQUAL( 1, count.value );
927 } // eo FrozenCall_Thaw()
931 BOOST_AUTO_TEST_CASE(FrozenCall_Decay)
935 CallOutId id= frozenCall( boost::bind(&Counter::advance, &count), 1 );
936 backend->doOneStep( 10 );
938 BOOST_CHECK_EQUAL( 0, count.value );
939 BOOST_CHECK_EQUAL( true, id.active() );
940 backend->doOneStep( 1100 );
942 BOOST_CHECK_EQUAL( 0, count.value );
943 BOOST_CHECK_EQUAL( false, id.active() );
944 } // eo FrozenCall_Decay()
948 BOOST_AUTO_TEST_CASE(UnixSockets_ClientServer)
950 std::string path= getCheckFilepath("UDS_CS");
952 UnixIOSocketHolder server_holder;
953 UnixServerSocket< TestUnixIOSocket > server_port;
954 UnixIOSocketPtr server;
955 TestUnixIOSocket client0;
956 TestUnixIOSocket client1;
958 bool res1 = server_port.open(path, 0600);
959 BOOST_CHECK_EQUAL( true, res1 );
962 AsyncIo::Utils::FileStat stat(path,false);
963 BOOST_REQUIRE( stat.is_socket() );
964 BOOST_CHECK_EQUAL( 0600u, (stat.mode() & 0777));
967 server_port.setNewConnectionCallback(
968 boost::bind( &UnixIOSocketHolder::store, &server_holder, _1)
971 // open a first client
972 bool res2= client0.open(path);
973 BOOST_CHECK_EQUAL( true, res2 );
975 BOOST_CHECK_EQUAL(0u, server_holder.size() );
977 BOOST_CHECK_EQUAL(1u, server_holder.size() );
978 BOOST_REQUIRE( server_holder.get(0).get() );
980 client0.sendData("a simple test string.");
984 std::string("a simple test string."),
985 server_holder.get(0)->m_received_string
987 server_holder.get(0)->sendData("reply 1");
989 BOOST_CHECK_EQUAL( std::string("reply 1"), client0.m_received_string );
991 // open a second client
992 res2= client1.open(path);
993 BOOST_CHECK_EQUAL( true, res2 );
995 BOOST_CHECK_EQUAL(2u, server_holder.size() );
996 BOOST_REQUIRE( server_holder.get(1).get() );
998 server_holder.get(1)->sendData("::reply 2");
1000 BOOST_CHECK_EQUAL( std::string("::reply 2"), client1.m_received_string );
1002 client1.sendData("another simple test string. 124");
1006 std::string("another simple test string. 124"),
1007 server_holder.get(1)->m_received_string
1010 // close first client
1012 BOOST_CHECK_EQUAL( false, server_holder.get(0)->eof() );
1014 BOOST_CHECK_EQUAL( true, server_holder.get(0)->eof() );
1015 server_holder.get(0)->close();
1017 // close second connection from server side
1018 BOOST_CHECK_EQUAL( false, client1.eof() );
1019 server_holder.get(1)->close();
1021 BOOST_CHECK_EQUAL( true, client1.eof() );
1023 } // eo UnixSockets_ClientServer()
1027 BOOST_AUTO_TEST_CASE(Dummy)
1029 using namespace std;
1030 cout << endl << "Random strings:" << endl;
1031 for (int i=10; i-->0;)
1033 cout << " " << makeRandomAsciiString(70)<< endl;
1038 BOOST_AUTO_TEST_SUITE_END()