taskthread_fd_test.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: S Roderick taskthread_fd_test.cpp
3 
4  taskthread_fd_test.cpp - description
5  -------------------
6  copyright : (C) 2012 S Roderick
7  email : kiwi.net@mac.com
8 
9  ***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 
19 #include "taskthread_test.hpp"
20 
21 #include <iostream>
22 #include <errno.h>
23 
24 #include <TaskContext.hpp>
26 #include <os/MainThread.hpp>
27 #include <Logger.hpp>
28 #include <rtt-config.h>
29 
30 using namespace std;
31 
32 #include <boost/test/unit_test.hpp>
33 #include <boost/test/floating_point_comparison.hpp>
34 
35 
36 using namespace RTT;
37 
38 
40  : public TaskContext
41 {
42  TestFileDescriptor(std::string name) :
43  TaskContext(name, TaskContext::PreOperational),
44  countError(0),
45  countTimeout(0),
46  countRead(0),
47  countUpdate(0)
48  {
49  fd[0] = fd[1] = -1;
50  }
51 
53  {
54  }
55 
56  virtual bool configureHook()
57  {
58  int rc = pipe(fd);
59  assert(0 == rc);
60  (void)rc; // avoid compiler warning
61 
62  extras::FileDescriptorActivity* fd_activity =
63  dynamic_cast<extras::FileDescriptorActivity*>(getActivity());
64  assert(0 != fd_activity);
65 
66  fd_activity->watch(fd[0]);
67  // set no timeout - leave that for test code
68 
69  return true;
70  }
71 
72  virtual bool startHook()
73  {
74  countError = 0;
75  countTimeout = 0;
76  countRead = 0;
77  countUpdate = 0;
78  return true;
79  }
80 
81  virtual void updateHook()
82  {
83  extras::FileDescriptorActivity* fd_activity =
84  dynamic_cast<extras::FileDescriptorActivity*>(getActivity());
85  assert(0 != fd_activity);
86 
87  ++countUpdate;
88  if (fd_activity->hasError())
89  {
90  ++countError;
91  }
92  else if (fd_activity->hasTimeout())
93  {
94  ++countTimeout;
95  }
96  else
97  {
98  if (fd_activity->isUpdated(fd[0]))
99  {
100  ++countRead;
101  // remove pipe contents
102  char ch;
103  int rc = read(fd[0], &ch, sizeof(ch));
104  if (0 >= rc)
105  {
106 // std::cerr << "Failed read: rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
107  }
108  }
109  }
110  }
111 
112  virtual void cleanupHook()
113  {
114  if (-1 != fd[0]) close(fd[0]);
115  if (-1 != fd[1]) close(fd[1]);
116  fd[0] = fd[1] = -1;
117  }
118 
123  int fd[2]; // from pipe()
124 };
125 
126 // Registers the fixture into the 'registry'
127 BOOST_FIXTURE_TEST_SUITE( ActivitiesThreadTestSuite, ActivitiesThreadTest )
128 
129 BOOST_AUTO_TEST_CASE(testFileDescriptor )
130 {
131  FileDescriptorActivity mtask( 15 );
132  BOOST_CHECK( mtask.isActive() == false );
133  BOOST_CHECK( mtask.isRunning() == false );
134  BOOST_CHECK( !mtask.thread()->isRunning() );
135  BOOST_CHECK_EQUAL( 0.0, mtask.thread()->getPeriod() );
136 
137  // Adapt priority levels to OS.
138  int bprio = 15, rtsched = ORO_SCHED_RT;
139  os::CheckPriority( rtsched, bprio );
140 
141  BOOST_CHECK_EQUAL( bprio, mtask.thread()->getPriority() );
142  BOOST_CHECK_EQUAL( rtsched, mtask.thread()->getScheduler() );
143 
144  FileDescriptorActivity m2task( 15 );
145  BOOST_CHECK( mtask.thread() != m2task.thread() );
146 
147  // starting...
148  BOOST_CHECK( mtask.start() == true );
149  BOOST_CHECK( mtask.isRunning() == false );
150  BOOST_CHECK( m2task.isRunning() == false );
151  BOOST_CHECK( m2task.start() == true );
152  BOOST_CHECK( m2task.isRunning() == false );
153 
154  usleep(1000000/4);
155 
156  // stopping...
157  BOOST_CHECK( mtask.stop() == true );
158  BOOST_CHECK( mtask.isRunning() == false );
159  BOOST_CHECK( m2task.isRunning() == false );
160  BOOST_CHECK( m2task.stop() == true );
161  BOOST_CHECK( m2task.isRunning() == false );
162 
163  // Starting thread if thread not running
164  BOOST_CHECK( mtask.thread()->stop() == false );
165  BOOST_CHECK( mtask.thread()->isRunning() == false );
166  BOOST_CHECK( mtask.start() );
167  BOOST_CHECK( mtask.isRunning() == false );
168  BOOST_CHECK( mtask.thread()->isRunning() == false);
169 }
170 
171 BOOST_AUTO_TEST_CASE(testFileDescriptor_Write )
172 {
173  TestFileDescriptor mcomp("Comp");
174  mcomp.setActivity( new FileDescriptorActivity( 15 ) );
175  FileDescriptorActivity* mtask = dynamic_cast<FileDescriptorActivity*>( mcomp.getActivity() );
176  char ch='a';
177  int rc;
178 
179  BOOST_CHECK( mtask->hasError() == false );
180  BOOST_CHECK( mtask->hasTimeout() == false );
181 
182  BOOST_CHECK( mcomp.configure() == true );
183  BOOST_CHECK( mtask->isWatched(mcomp.fd[0]) == true );
184 
185  BOOST_CHECK( mcomp.start() == true );
186  BOOST_CHECK( mtask->hasError() == false );
187  BOOST_CHECK( mtask->hasTimeout() == false );
188 
189  // no activity
190  usleep(1000000/4);
191  BOOST_CHECK_EQUAL( 0, mcomp.countError );
192  BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
193  BOOST_CHECK_EQUAL( 0, mcomp.countRead );
194  BOOST_CHECK_LE( 0, mcomp.countUpdate );
195 
196  // write to fd
197  rc = write(mcomp.fd[1], &ch, sizeof(ch));
198  if (1 != rc) std::cerr << "rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
199  BOOST_CHECK_EQUAL( 1, rc );
200  usleep(1000000/10);
201  BOOST_CHECK_EQUAL( 0, mcomp.countError );
202  BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
203  BOOST_CHECK_EQUAL( 1, mcomp.countRead );
204  BOOST_CHECK_LE( 0, mcomp.countUpdate );
205 
206  ++ch;
207  rc = write(mcomp.fd[1], &ch, sizeof(ch));
208  if (1 != rc) std::cerr << "rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
209  BOOST_CHECK_EQUAL( 1, rc );
210  usleep(1000000/10);
211  BOOST_CHECK_EQUAL( 0, mcomp.countError );
212  BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
213  BOOST_CHECK_EQUAL( 2, mcomp.countRead );
214  BOOST_CHECK_LE( 0, mcomp.countUpdate );
215 
216  // unwatch
217  BOOST_CHECK( mtask->isWatched(mcomp.fd[0]) == true );
218  mtask->unwatch(mcomp.fd[0]);
219  BOOST_CHECK( mtask->isWatched(mcomp.fd[0]) == false );
220 
221  ++ch;
222  rc = write(mcomp.fd[1], &ch, sizeof(ch));
223  if (1 != rc) std::cerr << "rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
224  BOOST_CHECK_EQUAL( 1, rc );
225  usleep(1000000/10);
226  BOOST_CHECK_EQUAL( 0, mcomp.countError );
227  BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
228  BOOST_CHECK_EQUAL( 2, mcomp.countRead ); // no change
229  BOOST_CHECK_LE( 0, mcomp.countUpdate );
230 
231 #if 0
232  // close pipe => cause error
233  (void)close(mcomp.fd[1]);
234  usleep(1000000/100);
235 
236  BOOST_CHECK_EQUAL( 1, mcomp.countError );
237  BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
238  BOOST_CHECK_EQUAL( 2, mcomp.countRead );
239  BOOST_CHECK_LE( 0, mcomp.countUpdate );
240 #endif
241 
242  // Note: normally not allowed once loaded in a TC:
243  BOOST_CHECK( mtask->stop() == true );
244 }
245 
246 BOOST_AUTO_TEST_CASE(testFileDescriptor_Timeout )
247 {
248  if(std::getenv("CI") != NULL) {
249  BOOST_TEST_MESSAGE("Skipping testFileDescriptor_Timeout because it can fail on integration servers.");
250  return;
251  }
252 
253  TestFileDescriptor mcomp("Comp");
254  mcomp.setActivity( new FileDescriptorActivity( 15 ) );
255  FileDescriptorActivity* mtask = dynamic_cast<FileDescriptorActivity*>( mcomp.getActivity() );
256  char ch='a';
257  int rc;
258  static const int RATE = 10;
259  static const int timeout_ms = 1000 / RATE;
260 
261  BOOST_CHECK( mcomp.configure() == true );
262  mtask->setTimeout( timeout_ms );
263  BOOST_CHECK( timeout_ms == mtask->getTimeout() );
264  BOOST_CHECK( mcomp.start() == true );
265 
266  // no activity
267  usleep(1000000 / RATE * 4.5); // ~4.5 timeout periods
268  BOOST_CHECK_EQUAL( 0, mcomp.countError );
269  BOOST_CHECK_EQUAL( 4, mcomp.countTimeout );
270  BOOST_CHECK_EQUAL( 0, mcomp.countRead );
271  BOOST_CHECK_LE( 0, mcomp.countUpdate );
272 
273  // write to fd
274  rc = write(mcomp.fd[1], &ch, sizeof(ch));
275  if (1 != rc) std::cerr << "rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
276  BOOST_CHECK_EQUAL( 1, rc );
277  usleep(1000000 / RATE * 1.5); // ~1.5 timeout periods
278  BOOST_CHECK_EQUAL( 0, mcomp.countError );
279  BOOST_CHECK_EQUAL( 5, mcomp.countTimeout );
280  BOOST_CHECK_EQUAL( 1, mcomp.countRead );
281  BOOST_CHECK_LE( 0, mcomp.countUpdate );
282 
283  // no activity
284  usleep(1000000 / RATE * 3); // ~3 timeout periods
285  BOOST_CHECK_EQUAL( 0, mcomp.countError );
286  BOOST_CHECK_EQUAL( 5 + 3, mcomp.countTimeout );
287  BOOST_CHECK_EQUAL( 1, mcomp.countRead );
288  BOOST_CHECK_LE( 0, mcomp.countUpdate );
289 }
290 
292 
#define BOOST_FIXTURE_TEST_SUITE(suite_name, F)
virtual void cleanupHook()
virtual int getScheduler() const =0
virtual int getPriority() const =0
virtual void updateHook()
virtual bool configureHook()
virtual os::ThreadInterface * thread()
Definition: Activity.cpp:114
#define BOOST_AUTO_TEST_SUITE_END()
virtual bool isRunning() const =0
Definition: mystd.hpp:163
int usleep(unsigned int us)
Definition: fosi.cpp:58
bool CheckPriority(int &sched_type, int &priority)
Definition: threads.cpp:51
virtual bool configure()
Definition: TaskCore.cpp:96
bool setActivity(base::ActivityInterface *new_act)
virtual Seconds getPeriod() const =0
TestFileDescriptor(std::string name)
virtual bool startHook()
basic_ostreams & endl(basic_ostreams &s)
Definition: rtstreams.cpp:110
#define ORO_SCHED_RT
Definition: ecos/fosi.h:61
virtual bool stop()=0
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:53
virtual bool isActive() const
Definition: Activity.cpp:332
virtual bool start()
base::ActivityInterface * getActivity()
BOOST_AUTO_TEST_CASE(testFileDescriptor)


rtt
Author(s): RTT Developers
autogenerated on Fri Oct 25 2019 03:59:44