mqueue_test.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: The SourceWorks Tue Sep 7 00:54:57 CEST 2010 mqueue_test.cpp
3 
4  mqueue_test.cpp - description
5  -------------------
6  begin : Tue September 07 2010
7  copyright : (C) 2010 The SourceWorks
8  email : peter@thesourceworks.com
9 
10  ***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 
19 #include "unit.hpp"
20 
21 #include <iostream>
22 
23 #include <Service.hpp>
27 #include <os/fosi.h>
28 
29 using namespace std;
30 using namespace RTT;
31 using namespace RTT::detail;
32 
33 #include <InputPort.hpp>
34 #include <OutputPort.hpp>
35 #include <TaskContext.hpp>
36 #include <string>
37 
38 using namespace RTT;
39 using namespace RTT::detail;
40 
42 {
43 public:
45  {
46  // connect DataPorts
47  mr1 = new InputPort<double>("mr");
48  mw1 = new OutputPort<double>("mw");
49 
50  mr2 = new InputPort<double>("mr");
51  mw2 = new OutputPort<double>("mw");
52 
53  // both tc's are non periodic
54  tc = new TaskContext( "root" );
55  tc->ports()->addEventPort( *mr1 );
56  tc->ports()->addPort( *mw1 );
57 
58  t2 = new TaskContext("other");
59  t2->ports()->addEventPort( *mr2, boost::bind(&MQueueTest::new_data_listener, this, _1) );
60  t2->ports()->addPort( *mw2 );
61 
62  tc->start();
63  t2->start();
64  }
65 
67  {
68  delete tc;
69  delete t2;
70 
71  delete mr1;
72  delete mw1;
73  delete mr2;
74  delete mw2;
75  }
76 
79 
80  PortInterface* signalled_port;
81  void new_data_listener(PortInterface* port)
82  {
83  signalled_port = port;
84  }
85 
86  // Ports
91 
93 
94  // helper test functions
95  void testPortDataConnection();
96  void testPortBufferConnection();
97  void testPortDisconnected();
98 };
99 
100 class MQueueFixture : public MQueueTest
101 {
102 public:
104  // Create a default policy specification
105  policy.type = ConnPolicy::DATA;
106  policy.init = false;
107  policy.lock_policy = ConnPolicy::LOCK_FREE;
108  policy.size = 0;
109  policy.pull = true;
110  policy.transport = ORO_MQUEUE_PROTOCOL_ID;
111  }
112 };
113 
114 #define ASSERT_PORT_SIGNALLING(code, read_port) do { \
115  signalled_port = 0; \
116  code; \
117  rtos_disable_rt_warning(); \
118  usleep(100000); \
119  rtos_enable_rt_warning(); \
120  BOOST_CHECK( read_port == signalled_port ); \
121 } while(0)
122 
124 {
126  // This test assumes that there is a data connection mw1 => mr2
127  // Check if connection succeeded both ways:
128  BOOST_CHECK( mw1->connected() );
129  BOOST_CHECK( mr2->connected() );
130 
131  double value = 0;
132 
133  // Check if no-data works
134  BOOST_CHECK( NoData == mr2->read(value) );
135 
136  // Check if writing works (including signalling)
137  ASSERT_PORT_SIGNALLING(mw1->write(1.0), mr2);
138  BOOST_CHECK( mr2->read(value) );
139  BOOST_CHECK_EQUAL( 1.0, value );
140  ASSERT_PORT_SIGNALLING(mw1->write(2.0), mr2);
141  BOOST_CHECK( mr2->read(value) );
142  BOOST_CHECK_EQUAL( 2.0, value );
143  BOOST_CHECK( OldData == mr2->read(value) );
144 
146 }
147 
149 {
151  // This test assumes that there is a buffer connection mw1 => mr2 of size 3
152  // Check if connection succeeded both ways:
153  BOOST_CHECK( mw1->connected() );
154  BOOST_CHECK( mr2->connected() );
155 
156  double value = 0;
157 
158  // Check if no-data works
159  BOOST_CHECK( NoData == mr2->read(value) );
160 
161  // Check if writing works
162  ASSERT_PORT_SIGNALLING(mw1->write(1.0), mr2);
163  ASSERT_PORT_SIGNALLING(mw1->write(2.0), mr2);
164  ASSERT_PORT_SIGNALLING(mw1->write(3.0), mr2);
165  ASSERT_PORT_SIGNALLING(mw1->write(4.0), 0); // because size == 3
166  BOOST_CHECK( mr2->read(value) );
167  BOOST_CHECK_EQUAL( 1.0, value );
168  BOOST_CHECK( mr2->read(value) );
169  BOOST_CHECK_EQUAL( 2.0, value );
170  BOOST_CHECK( mr2->read(value) );
171  BOOST_CHECK_EQUAL( 3.0, value );
172  BOOST_CHECK( OldData == mr2->read(value) );
173 
175 }
176 
178 {
179  BOOST_CHECK( !mw1->connected() );
180  BOOST_CHECK( !mr2->connected() );
181 }
182 
183 
184 // Registers the fixture into the 'registry'
185 BOOST_FIXTURE_TEST_SUITE( MQueueTestSuite, MQueueFixture )
186 
187 
191 BOOST_AUTO_TEST_CASE( testPortConnections )
192 {
193 #if 1
194  // WARNING: in the following, there is four configuration tested.
195  // We need to manually disconnect both sides since mqueue are connection-less.
196  policy.type = ConnPolicy::DATA;
197  policy.pull = true;
198  // test user supplied connection.
199  policy.name_id = "/data1";
200  BOOST_REQUIRE( mw1->createConnection(*mr2, policy) );
201  BOOST_CHECK( policy.name_id == "/data1" );
202  testPortDataConnection();
203  mw1->disconnect();
204  mr2->disconnect();
205  testPortDisconnected();
206 
207  policy.type = ConnPolicy::DATA;
208  policy.pull = true;
209  policy.name_id = "";
210  BOOST_REQUIRE( mw1->createConnection(*mr2, policy) );
211  testPortDataConnection();
212  mw1->disconnect();
213  mr2->disconnect();
214  testPortDisconnected();
215 #endif
216 #if 1
217  policy.type = ConnPolicy::BUFFER;
218  policy.pull = false;
219  policy.size = 3;
220  policy.name_id = "";
221  //policy.name_id = "buffer1";
222  BOOST_REQUIRE( mw1->createConnection(*mr2, policy) );
223  testPortBufferConnection();
224  mw1->disconnect();
225  mr2->disconnect();
226  testPortDisconnected();
227 #endif
228 #if 1
229  policy.type = ConnPolicy::BUFFER;
230  policy.pull = true;
231  policy.size = 3;
232  policy.name_id = "";
233  //policy.name_id = "buffer2";
234  BOOST_REQUIRE( mw1->createConnection(*mr2, policy) );
235  testPortBufferConnection();
236  //while(1) sleep(1);
237  mw1->disconnect();
238  mr2->disconnect();
239  testPortDisconnected();
240 #endif
241  }
242 
243 BOOST_AUTO_TEST_CASE( testPortStreams )
244 {
245  // Test all four configurations of Data/Buffer & push/pull
246  policy.type = ConnPolicy::DATA;
247  policy.pull = false;
248  policy.name_id = "/data1";
249  BOOST_REQUIRE( mw1->createStream( policy ) );
250  BOOST_REQUIRE( mr2->createStream( policy ) );
251  testPortDataConnection();
252  mw1->disconnect();
253  mr2->disconnect();
254  testPortDisconnected();
255 
256  policy.type = ConnPolicy::DATA;
257  policy.pull = true;
258  policy.name_id = "";
259  BOOST_REQUIRE( mw1->createStream( policy ) );
260  BOOST_REQUIRE( mr2->createStream( policy ) );
261  testPortDataConnection();
262  mw1->disconnect();
263  mr2->disconnect();
264  testPortDisconnected();
265 
266  policy.type = ConnPolicy::BUFFER;
267  policy.pull = false;
268  policy.size = 3;
269  policy.name_id = "/buffer1";
270  BOOST_REQUIRE( mw1->createStream( policy ) );
271  BOOST_REQUIRE( mr2->createStream( policy ) );
272  testPortBufferConnection();
273  mw1->disconnect();
274  mr2->disconnect();
275  testPortDisconnected();
276 
277  policy.type = ConnPolicy::BUFFER;
278  policy.pull = true;
279  policy.size = 3;
280  policy.name_id = "";
281  BOOST_REQUIRE( mw1->createStream( policy ) );
282  BOOST_REQUIRE( mr2->createStream( policy ) );
283  testPortBufferConnection();
284  mw1->disconnect();
285  mr2->disconnect();
286  testPortDisconnected();
287 }
288 
289 BOOST_AUTO_TEST_CASE( testPortStreamsTimeout )
290 {
291  // Test creating an input stream without an output stream available.
292  policy.type = ConnPolicy::DATA;
293  policy.pull = false;
294  policy.name_id = "/data1";
295  BOOST_REQUIRE( mr2->createStream( policy ) == false );
296  BOOST_CHECK( mr2->connected() == false );
297  mr2->disconnect();
298 
299  policy.type = ConnPolicy::BUFFER;
300  policy.pull = false;
301  policy.size = 10;
302  policy.name_id = "/buffer1";
303  BOOST_REQUIRE( mr2->createStream( policy ) == false );
304  BOOST_CHECK( mr2->connected() == false );
305  mr2->disconnect();
306 }
307 
308 
309 BOOST_AUTO_TEST_CASE( testPortStreamsWrongName )
310 {
311  // Test creating an input/output stream with a wrong name
312  policy.type = ConnPolicy::DATA;
313  policy.pull = false;
314  policy.name_id = "data1"; // name must start with '/'
315  BOOST_REQUIRE( mr2->createStream( policy ) == false );
316  BOOST_CHECK( mr2->connected() == false );
317  mr2->disconnect();
318 
319  policy.type = ConnPolicy::BUFFER;
320  policy.pull = false;
321  policy.size = 10;
322  policy.name_id = "buffer1";
323  BOOST_REQUIRE( mw2->createStream( policy ) == false );
324  BOOST_CHECK( mw2->connected() == false );
325  mw2->disconnect();
326 }
327 
328 // copied from testPortStreams
329 BOOST_AUTO_TEST_CASE( testVectorTransport )
330 {
331  DataFlowInterface* ports = tc->ports();
332  DataFlowInterface* ports2 = t2->ports();
333 
334  std::vector<double> data(20, 3.33);
335  InputPort< std::vector<double> > vin("VIn");
336  OutputPort< std::vector<double> > vout("Vout");
337  ports->addPort(vin).doc("input port");
338  ports2->addPort(vout).doc("output port");
339 
340  // init the output port with a vector of size 20, values 3.33
341  vout.setDataSample( data );
342  data = vout.getLastWrittenValue();
343  for(int i=0; i != 20; ++i)
344  BOOST_CHECK_CLOSE( data[i], 3.33, 0.01);
345 
346  policy.type = ConnPolicy::DATA;
347  policy.pull = false;
348  policy.name_id = "/vdata1";
349  BOOST_REQUIRE( vout.createStream( policy ) );
350  BOOST_REQUIRE( vin.createStream( policy ) );
351 
352  // check that the receiver did not get any data
353  BOOST_CHECK_EQUAL( vin.read(data), NoData);
354 
355  // prepare a new data sample, size 10, values 6.66
356  data.clear();
357  data.resize(10, 6.66);
358  for(unsigned int i=0; i != data.size(); ++i)
359  BOOST_CHECK_CLOSE( data[i], 6.66, 0.01);
360 
362  vout.write( data );
364 
365  // prepare data buffer for reception:
366  data.clear();
367  data.resize(20, 0.0);
368  usleep(200000);
369 
371  BOOST_CHECK_EQUAL( vin.read(data), NewData);
373 
374  // check if both size and capacity and values are as expected.
375  BOOST_CHECK_EQUAL( data.size(), 10);
376  BOOST_CHECK_EQUAL( data.capacity(), 20);
377  for(unsigned int i=0; i != data.size(); ++i)
378  BOOST_CHECK_CLOSE( data[i], 6.66, 0.01);
379 
381  BOOST_CHECK_EQUAL( vin.read(data), OldData);
383 }
384 
386 
void setDataSample(const T &sample)
Definition: OutputPort.hpp:209
base::PortInterface & addPort(const std::string &name, base::PortInterface &port)
#define BOOST_FIXTURE_TEST_SUITE(suite_name, F)
ConnPolicy policy
Definition: mqueue_test.cpp:92
#define BOOST_AUTO_TEST_SUITE_END()
TaskContext * tc
Definition: mqueue_test.cpp:77
void testPortDisconnected()
Definition: mystd.hpp:163
int usleep(unsigned int us)
Definition: fosi.cpp:58
void testPortBufferConnection()
FlowStatus read(base::DataSourceBase::shared_ptr source)
Definition: InputPort.hpp:97
static const int DATA
Definition: ConnPolicy.hpp:111
InputPort< double > * mr2
Definition: mqueue_test.cpp:89
void rtos_disable_rt_warning()
BOOST_AUTO_TEST_CASE(testPortConnections)
#define ASSERT_PORT_SIGNALLING(code, read_port)
InputPort< double > * mr1
Definition: mqueue_test.cpp:87
virtual bool createStream(ConnPolicy const &policy)
Definition: OutputPort.hpp:314
WriteStatus write(const T &sample)
Definition: OutputPort.hpp:243
static const int LOCK_FREE
Definition: ConnPolicy.hpp:117
OutputPort< double > * mw1
Definition: mqueue_test.cpp:88
OutputPort< double > * mw2
Definition: mqueue_test.cpp:90
void new_data_listener(PortInterface *port)
Definition: mqueue_test.cpp:81
static const int BUFFER
Definition: ConnPolicy.hpp:112
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:53
PortInterface * signalled_port
Definition: mqueue_test.cpp:80
TaskContext * t2
Definition: mqueue_test.cpp:78
PortInterface & doc(const std::string &desc)
void testPortDataConnection()
void rtos_enable_rt_warning()
T getLastWrittenValue() const
Definition: OutputPort.hpp:173
virtual bool createStream(ConnPolicy const &policy)
Definition: InputPort.hpp:207
#define ORO_MQUEUE_PROTOCOL_ID
Definition: MQLib.hpp:57


rtt
Author(s): RTT Developers
autogenerated on Tue Jun 25 2019 19:33:25