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/signal.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 pid_t pid() { return m_pid; }
209 bool kill( Signal signal) { return ProcessImplementation::kill(signal); }
213 void slotReceivedData()
215 receiveData(m_input_buffer);
216 m_input_buffer.clear();
217 } // eo slotReceivedData()
219 }; // eo class TestProcess
223 class TestUnixIOSocket
224 : public UnixIOSocket
225 , public ReceivedData
232 m_signal_read.connect( boost::bind(&TestUnixIOSocket::slotReceivedData, this) );
233 } // eo TestUnixIOSocket()
237 int fd, const std::string& path
239 : UnixIOSocket(fd, path)
241 m_signal_read.connect( boost::bind(&TestUnixIOSocket::slotReceivedData, this) );
242 } // eo TestUnixIOSocket()
245 void sendData(const std::string& data)
248 } // eo sendData(const std::string&)
252 void slotReceivedData()
254 receiveData(m_input_buffer);
255 m_input_buffer.clear();
256 } // eo slotReceivedData()
258 }; // eo class TestUnixIOSocket
260 typedef boost::shared_ptr< TestUnixIOSocket > TestUnixIOSocketPtr;
263 class UnixIOSocketHolder
264 : public std::vector< UnixIOSocketPtr >
268 void operator()(UnixIOSocketPtr ptr)
273 void storeBase (IOImplementationPtr ptr)
275 push_back(boost::dynamic_pointer_cast< UnixIOSocket >(ptr) );
278 void store (UnixIOSocketPtr ptr)
283 TestUnixIOSocketPtr get(int idx)
285 return boost::dynamic_pointer_cast<
289 }; // eo class UnixIOSocketHolder
292 /// global random generator (from boost lib).
293 boost::mt19937 g_random_gen;
297 * generates a string with random characters from a given ASCII subset.
298 * @param len the desired length of the output string
299 * @return a random string of length @a len
301 std::string makeRandomAsciiString(std::string::size_type len)
303 static std::string chars("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz=+-*/%(){}<>.,:;\\");
306 boost::uniform_int<> discreter(0, chars.size()-1);
307 boost::variate_generator<boost::mt19937&, boost::uniform_int<> > idxgen(g_random_gen, discreter);
309 for(; len-->0;) s+= chars.at( idxgen() );
312 } // eo makeRandomAsciiString
315 } // eo namespace <anonymous>
318 class SimpleioBasicsFixture
322 std::set<std::string> used_check_files;
324 template<class Callable>
325 bool backendLoopUntil( Callable condition, int maxLoops=100 )
327 for (int i=std::max(maxLoops,1); i-->0 && ! condition();)
329 backend->doOneStep(10);
332 } // eo backendLoopUntil
335 bool backendStep(int msTimeout= 10, int count=1)
338 for(;count-->0 && res;)
340 res= backend->doOneStep(msTimeout);
346 std::string getCheckFilepath(std::string tag)
349 result= "__unittest__" + tag + ".dat";
350 used_check_files.insert(result);
352 } // eo get_check_file_path
355 void removeCheckFiles()
357 for(std::set<std::string>::iterator it= used_check_files.begin();
358 it != used_check_files.end();
361 std::string filepath(*it);
362 if (Utils::FileStat(filepath))
364 Utils::unlink(filepath);
367 used_check_files.clear();
368 } // eo removeCheckFiles
371 SimpleioBasicsFixture()
373 backend = Backend::getBackend();
374 installChildHandler();
375 used_check_files.clear();
378 ~SimpleioBasicsFixture()
380 restoreChildHandler();
385 BOOST_FIXTURE_TEST_SUITE(TestSimpleioBasics, SimpleioBasicsFixture)
387 BOOST_AUTO_TEST_CASE(EmptyBackendStepCall)
389 BOOST_REQUIRE( backend );
391 // a backend call without active objects should return false:
392 bool result = backend->doOneStep(0);
394 BOOST_CHECK_EQUAL( false, result );
395 } // eo EmptyBackendStepCall
399 BOOST_AUTO_TEST_CASE(NonEmptyBackendStepCall)
401 BOOST_REQUIRE(backend);
406 // with an active object, a step should return true:
407 bool result = backend->doOneStep(0);
408 BOOST_CHECK_EQUAL( true, result );
409 // the timer should not be executed:
410 BOOST_CHECK_EQUAL( 0u, timer.m_counter );
412 // now it should return false:
413 bool result = backend->doOneStep(0);
414 BOOST_CHECK_EQUAL( false, result );
415 } // eo NonEmptyBackendStepCall
420 * check for timer to execute immediatly.
422 BOOST_AUTO_TEST_CASE(SingleTimerShot)
424 BOOST_REQUIRE(backend);
427 timer.setDelta(0); // shot now!
429 bool result = backend->doOneStep(10);
431 BOOST_CHECK_EQUAL( true, result );
432 // the timer should be executed once:
433 BOOST_CHECK_EQUAL( 1u, timer.m_counter );
435 result = backend->doOneStep(0);
437 BOOST_CHECK_EQUAL( false, result );
438 // the timer should not be executed again:
439 BOOST_CHECK_EQUAL( 1u, timer.m_counter );
441 } // eo SingleTimerShot()
446 * tests a simple timer class to be executed with a timeout.
448 BOOST_AUTO_TEST_CASE(SimpleTimerShot)
451 BOOST_REQUIRE(backend);
455 timer1.addAction( boost::bind(&Counter::advance,&counter1) );
456 BOOST_CHECK_EQUAL(false, timer1.active());
458 timer1.startTimerMS( 100 );
459 BOOST_CHECK_EQUAL(true, timer1.active());
461 res=backend->doOneStep( 1000 );
462 BOOST_CHECK_EQUAL( true, res );
464 BOOST_CHECK_EQUAL( 1, counter1.value );
465 } // eo SimpleTimerShot
470 * tests 3 timers; after the first was active, disable another and check if the remaining one fires.
472 BOOST_AUTO_TEST_CASE(SimpleTimerShot2)
475 BOOST_REQUIRE(backend);
477 SimpleTimer timer1, timer2, timer3;
478 Counter counter1, counter2, counter3;
479 timer1.addAction( boost::bind(&Counter::advance,&counter1) );
480 timer2.addAction( boost::bind(&Counter::advance,&counter2) );
481 timer3.addAction( boost::bind(&Counter::advance,&counter3) );
482 BOOST_CHECK_EQUAL(false, timer1.active());
483 BOOST_CHECK_EQUAL(false, timer2.active());
484 BOOST_CHECK_EQUAL(false, timer3.active());
486 timer1.startTimerMS( 100 );
487 timer2.startTimerMS( 500 );
488 timer3.startTimerMS( 400 );
489 BOOST_CHECK_EQUAL(true, timer1.active());
490 BOOST_CHECK_EQUAL(true, timer2.active());
491 BOOST_CHECK_EQUAL(true, timer3.active());
493 res=backend->doOneStep( 1000 );
494 BOOST_CHECK_EQUAL( true, res );
496 BOOST_CHECK_EQUAL(false, timer1.active());
497 BOOST_CHECK_EQUAL(true, timer2.active());
498 BOOST_CHECK_EQUAL(true, timer3.active());
500 BOOST_CHECK_EQUAL( 1, counter1.value );
501 BOOST_CHECK_EQUAL( 0, counter2.value );
502 BOOST_CHECK_EQUAL( 0, counter3.value );
504 // now stop the next timer:
506 BOOST_CHECK_EQUAL(false, timer3.active());
508 res=backend->doOneStep( 1000 );
509 BOOST_CHECK_EQUAL( true, res );
511 BOOST_CHECK_EQUAL( 1, counter1.value );
512 BOOST_CHECK_EQUAL( 1, counter2.value );
513 BOOST_CHECK_EQUAL( 0, counter3.value );
514 } // eo SimpleTimerShot2
523 BOOST_AUTO_TEST_CASE(EmptyWantTest)
527 BOOST_CHECK_EQUAL(false, io.wantRead() );
528 BOOST_CHECK_EQUAL(false, io.wantWrite() );
529 } // eo EmptyWantTest
533 * a simple pipe (and io) test.
535 * This test basically tests the io framework.
536 * It opens two connected pipes and sends a test string in each direction.
537 * It tests the following functionalities of the base classes:
538 * - set write marks in backend step (enabling direct send of data)
540 * - construct and interpret poll() data structures
542 * - signal chains for received data
547 BOOST_AUTO_TEST_CASE(SimplePipeTest)
549 static const std::string test_string("a test string");
550 static const std::string test_string2("only another short test string");
552 BOOST_REQUIRE(backend);
554 TestPipe pipe1, pipe2;
556 bool res= pipe1.makePipe(pipe2);
558 BOOST_CHECK_EQUAL(true, res);
559 BOOST_CHECK_EQUAL(true, pipe1.opened());
560 BOOST_CHECK_EQUAL(true, pipe2.opened());
562 res= backend->doOneStep(0);
563 BOOST_CHECK_EQUAL(true, res);
565 pipe1.sendString(test_string);
567 res= backend->doOneStep(0);
568 BOOST_CHECK_EQUAL(true, res);
570 BOOST_CHECK_EQUAL( test_string, pipe2.m_received_string );
572 pipe2.sendString(test_string2);
574 res= backend->doOneStep(0);
575 BOOST_CHECK_EQUAL(true, res);
577 BOOST_CHECK_EQUAL( test_string2, pipe1.m_received_string );
580 BOOST_CHECK_EQUAL(false, pipe1.opened());
582 res= backend->doOneStep(0);
583 BOOST_CHECK_EQUAL(true, res);
585 BOOST_CHECK_EQUAL(true, pipe2.eof());
586 } // eo SimplePipeTest
591 * sends a larger data chunk through a pipe.
592 * This tests if sending and receiving data in (smaller internal) chunks works.
594 BOOST_AUTO_TEST_CASE(SimplePipePump)
596 BOOST_REQUIRE(backend);
598 TestPipe pipe1, pipe2;
600 bool res= pipe1.makePipe(pipe2);
602 BOOST_CHECK_EQUAL(true, res);
603 BOOST_CHECK_EQUAL(true, pipe1.opened());
604 BOOST_CHECK_EQUAL(true, pipe2.opened());
606 res= backend->doOneStep(0);
607 BOOST_CHECK_EQUAL(true, res);
609 std::string test_string= makeRandomAsciiString(256*1024);
611 pipe1.sendString(test_string);
613 res= backend->doOneStep(0);
614 BOOST_CHECK_EQUAL(true, res);
616 // do some backend cycles to empty the pipe:
617 for (int i=64; i-->0 && res && !pipe1.empty(); )
619 res= backend->doOneStep(100);
623 BOOST_CHECK_EQUAL(false, pipe1.opened());
625 // now read the remaining data until we recognize EOF:
626 for (int i=64; i-->0 && res && !pipe2.eof();)
628 res= backend->doOneStep(100);
631 BOOST_CHECK_EQUAL( test_string.size(), pipe2.m_received_string.size() );
632 BOOST_CHECK_EQUAL( test_string, pipe2.m_received_string );
634 BOOST_CHECK_EQUAL(true, pipe2.eof());
635 } // eo SimplePipePump
640 * fork a subprocess (/bin/true) and test exit code.
642 BOOST_AUTO_TEST_CASE(SimpleProcessTestBinTrue)
645 BOOST_REQUIRE(backend);
647 TestProcess proc("/bin/true");
649 res= proc.startProcess();
650 BOOST_CHECK_EQUAL(true, res);
652 res= backend->doOneStep(200);
653 BOOST_CHECK_EQUAL(true, res);
655 for(int i=20; i-->0 && proc.processState() != ProcessState::stopped;)
657 backend->doOneStep(15);
660 BOOST_CHECK_EQUAL( ProcessState(ProcessState::stopped), proc.processState() );
661 BOOST_CHECK_EQUAL( true, proc.eof() );
662 BOOST_CHECK_EQUAL( 0, proc.exitCode() );
663 } // eo SimpleProcessTestBinTrue
667 * fork a subprocess (/bin/false) and test exit code.
669 BOOST_AUTO_TEST_CASE(SimpleProcessTestBinFalse)
672 BOOST_REQUIRE(backend);
674 TestProcess proc("/bin/false");
676 res= proc.startProcess();
677 BOOST_CHECK_EQUAL(true, res);
679 res= backend->doOneStep(200);
680 BOOST_CHECK_EQUAL(true, res);
681 for(int i=20; i-->0 && proc.processState() != ProcessState::stopped;)
683 backend->doOneStep(15);
686 BOOST_CHECK_EQUAL( ProcessState(ProcessState::stopped), proc.processState() );
687 BOOST_CHECK_EQUAL( true, proc.eof() );
688 BOOST_CHECK_EQUAL( 1, proc.exitCode() );
689 DOUT("leave SimpleProcessTestBinFalse");
690 } // eo SimpleProcessTestBinFalse
694 * fork an echo subprocess and read back the output.
696 BOOST_AUTO_TEST_CASE(SimpleProcessTestEcho)
698 DOUT("enter SimpleProcessTestEcho");
700 BOOST_REQUIRE(backend);
704 TransientPushBackFiller<std::string, std::vector >()("Eine")("Zeichenkette")
707 res= proc.startProcess();
708 BOOST_CHECK_EQUAL(true, res);
710 res= backend->doOneStep(200);
711 BOOST_CHECK_EQUAL(true, res);
712 for(int i=20; i-->0 && (proc.processState()!= ProcessState::stopped || !proc.eof());)
714 backend->doOneStep(10);
717 BOOST_CHECK_EQUAL( ProcessState(ProcessState::stopped), proc.processState() );
718 BOOST_CHECK_EQUAL( true, proc.eof() );
719 BOOST_CHECK_EQUAL( 0, proc.exitCode() );
720 BOOST_CHECK_EQUAL( std::string("Eine Zeichenkette\n"), proc.m_received_string);
721 } // eo SimpleProcessTestEcho
726 * fork a bash subprocess, echo something on stderr and read back the output.
728 BOOST_AUTO_TEST_CASE(SimpleProcessTestStderr)
731 BOOST_REQUIRE(backend);
737 TransientPushBackFiller<std::string, std::vector >()
739 ("echo Eine Zeichenkette >&2")
742 // start with a seperate io object for stderr.
743 DOUT("## start process");
744 res= proc.startProcess( &my_stderr );
745 BOOST_CHECK_EQUAL(true, res);
746 BOOST_CHECK_EQUAL(true, my_stderr.opened());
748 DOUT("## do a backend step");
749 res= backend->doOneStep(200);
750 BOOST_CHECK_EQUAL(true, res);
751 // wait until process stopped and both io's signal EOF (or until the loop ends ;-) )
752 DOUT("## enter loop");
753 for(int i=17; i-->0 && (proc.processState()!= ProcessState::stopped || !proc.eof() || !my_stderr.eof());)
755 DOUT("## round i=" << i);
756 backend->doOneStep(10);
758 DOUT("## loop left");
760 BOOST_CHECK_EQUAL( ProcessState(ProcessState::stopped), proc.processState() );
761 BOOST_CHECK_EQUAL( true, proc.eof() );
762 BOOST_CHECK_EQUAL( true, my_stderr.eof() );
763 BOOST_CHECK_EQUAL( 0, proc.exitCode() );
764 BOOST_CHECK_EQUAL( std::string("Eine Zeichenkette\n"), my_stderr.m_received_string);
765 DOUT("leave Test SimpleProcessTestStderr");
766 } // eo SimpleProcessTestStderr
771 * checks termination of process by signal and if the signal is returned.
773 BOOST_AUTO_TEST_CASE(SignaledProcessTermination)
776 BOOST_REQUIRE(backend);
778 TestProcess proc("/bin/sleep","2");
779 res= proc.startProcess();
780 BOOST_CHECK_EQUAL(true, res);
782 res= backend->doOneStep(10);
783 BOOST_CHECK_EQUAL(true, res);
784 BOOST_CHECK_EQUAL( ProcessState(ProcessState::running), proc.processState() );
786 res= backend->doOneStep(50);
788 // now send the process an USR1 (which terminates the process)
789 res=proc.kill( Signal::USR1 );
790 BOOST_CHECK_EQUAL(true, res);
792 // give the backend a chance to process the termination event:
793 for(int i=30; i-->0 && proc.processState()!=ProcessState::stopped;) backend->doOneStep(10);
795 BOOST_CHECK_EQUAL( ProcessState(ProcessState::stopped), proc.processState() );
796 BOOST_CHECK_EQUAL( true, proc.eof() );
797 BOOST_CHECK_EQUAL( Signal::USR1 , proc.exitCode()>>8 );
798 } // eo SignaledProcessTermination
802 BOOST_AUTO_TEST_CASE(CallOut1)
806 callOut( boost::bind(&Counter::advance, &count), 1 );
807 backend->doOneStep( 10 );
809 BOOST_CHECK_EQUAL( 0, count.value );
810 backend->doOneStep( 1100 );
812 BOOST_CHECK_EQUAL( 1, count.value );
817 BOOST_AUTO_TEST_CASE(CallOut2)
821 callOut( boost::bind(&Counter::advance, &count), 0.5 );
822 backend->doOneStep( 10 );
824 BOOST_CHECK_EQUAL( 0, count.value );
825 backend->doOneStep( 800 );
827 BOOST_CHECK_EQUAL( 1, count.value );
832 BOOST_AUTO_TEST_CASE(RemoveCallOut1)
836 CallOutId id= callOut( boost::bind(&Counter::advance, &count), 1 );
837 backend->doOneStep( 10 );
839 BOOST_CHECK_EQUAL( 0, count.value );
840 bool res1 = removeCallOut(id);
841 bool res2 = removeCallOut(id);
843 BOOST_CHECK_EQUAL( true, res1 );
844 BOOST_CHECK_EQUAL( false, res2 );
846 backend->doOneStep( 1100 );
848 BOOST_CHECK_EQUAL( 0, count.value );
849 } // eo RemoveCallOut1()
853 BOOST_AUTO_TEST_CASE(FrozenCall_Thaw)
857 CallOutId id= frozenCall( boost::bind(&Counter::advance, &count), 1 );
858 backend->doOneStep( 10 );
860 BOOST_CHECK_EQUAL( 0, count.value );
863 backend->doOneStep( 1100 );
865 BOOST_CHECK_EQUAL( 1, count.value );
866 } // eo FrozenCall_Thaw()
870 BOOST_AUTO_TEST_CASE(FrozenCall_Decay)
874 CallOutId id= frozenCall( boost::bind(&Counter::advance, &count), 1 );
875 backend->doOneStep( 10 );
877 BOOST_CHECK_EQUAL( 0, count.value );
878 BOOST_CHECK_EQUAL( true, id.active() );
879 backend->doOneStep( 1100 );
881 BOOST_CHECK_EQUAL( 0, count.value );
882 BOOST_CHECK_EQUAL( false, id.active() );
883 } // eo FrozenCall_Decay()
887 BOOST_AUTO_TEST_CASE(UnixSockets_ClientServer)
889 std::string path= getCheckFilepath("UDS_CS");
891 UnixIOSocketHolder server_holder;
892 UnixServerSocket< TestUnixIOSocket > server_port;
893 UnixIOSocketPtr server;
894 TestUnixIOSocket client0;
895 TestUnixIOSocket client1;
897 bool res1 = server_port.open(path, 0600);
898 BOOST_CHECK_EQUAL( true, res1 );
901 AsyncIo::Utils::FileStat stat(path,false);
902 BOOST_REQUIRE( stat.is_socket() );
903 BOOST_CHECK_EQUAL( 0600u, (stat.mode() & 0777));
906 server_port.setNewConnectionCallback(
907 boost::bind( &UnixIOSocketHolder::store, &server_holder, _1)
910 // open a first client
911 bool res2= client0.open(path);
912 BOOST_CHECK_EQUAL( true, res2 );
914 BOOST_CHECK_EQUAL(0u, server_holder.size() );
916 BOOST_CHECK_EQUAL(1u, server_holder.size() );
917 BOOST_REQUIRE( server_holder.get(0).get() );
919 client0.sendData("a simple test string.");
923 std::string("a simple test string."),
924 server_holder.get(0)->m_received_string
926 server_holder.get(0)->sendData("reply 1");
928 BOOST_CHECK_EQUAL( std::string("reply 1"), client0.m_received_string );
930 // open a second client
931 res2= client1.open(path);
932 BOOST_CHECK_EQUAL( true, res2 );
934 BOOST_CHECK_EQUAL(2u, server_holder.size() );
935 BOOST_REQUIRE( server_holder.get(1).get() );
937 server_holder.get(1)->sendData("::reply 2");
939 BOOST_CHECK_EQUAL( std::string("::reply 2"), client1.m_received_string );
941 client1.sendData("another simple test string. 124");
945 std::string("another simple test string. 124"),
946 server_holder.get(1)->m_received_string
949 // close first client
951 BOOST_CHECK_EQUAL( false, server_holder.get(0)->eof() );
953 BOOST_CHECK_EQUAL( true, server_holder.get(0)->eof() );
954 server_holder.get(0)->close();
956 // close second connection from server side
957 BOOST_CHECK_EQUAL( false, client1.eof() );
958 server_holder.get(1)->close();
960 BOOST_CHECK_EQUAL( true, client1.eof() );
962 } // eo UnixSockets_ClientServer()
966 BOOST_AUTO_TEST_CASE(Dummy)
969 cout << endl << "Random strings:" << endl;
970 for (int i=10; i-->0;)
972 cout << " " << makeRandomAsciiString(70)<< endl;
977 BOOST_AUTO_TEST_SUITE_END()