Convert gr-audio-portaudio to Boost via gruel
[debian/gnuradio] / mblock / src / lib / qa_mblock_send.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2006,2007,2008 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <qa_mblock_send.h>
28 #include <cppunit/TestAssert.h>
29 #include <mblock/mblock.h>
30 #include <mblock/runtime.h>
31 #include <mb_runtime_nop.h>             // QA only
32 #include <mblock/protocol_class.h>
33 #include <mblock/exception.h>
34 #include <mblock/msg_queue.h>
35 #include <mblock/message.h>
36 #include <mb_mblock_impl.h>
37 #include <mblock/msg_accepter.h>
38 #include <mblock/class_registry.h>
39 #include <stdio.h>
40
41 using namespace pmt;
42
43 static pmt_t s_data    = pmt_intern("data");
44 static pmt_t s_status  = pmt_intern("status");
45 static pmt_t s_control = pmt_intern("control");
46 static pmt_t s_p0   = pmt_intern("p0");
47 static pmt_t s_p1   = pmt_intern("p1");
48 static pmt_t s_p2   = pmt_intern("p2");
49 static pmt_t s_p3   = pmt_intern("p3");
50 static pmt_t s_e1   = pmt_intern("e1");
51 static pmt_t s_r1   = pmt_intern("r1");
52
53 static void
54 define_protocol_classes()
55 {
56   // Defined from client point-of-view.
57   mb_make_protocol_class(pmt_intern("qa-send-cs"),      // name
58                          pmt_list1(s_status),           // incoming
59                          pmt_list1(s_control));         // outgoing
60
61 }
62
63 mb_mblock_sptr
64 get_top(mb_runtime_sptr rts)
65 {
66   return dynamic_cast<mb_runtime_nop *>(rts.get())->top();
67 }
68
69 // ================================================================
70 //                     test_simple_routing
71 // ================================================================
72
73 // sub-block for test_simple_routing
74
75 class sr1 : public mb_mblock
76 {
77   mb_port_sptr  d_p1;
78   mb_port_sptr  d_p2;
79   mb_port_sptr  d_p3;
80
81 public:
82   sr1(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
83   ~sr1();
84   void initial_transition();
85 };
86
87 sr1::sr1(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
88   : mb_mblock(runtime, instance_name, user_arg)
89 {
90   d_p1 = define_port("p1", "qa-send-cs", true, mb_port::EXTERNAL);
91   d_p2 = define_port("p2", "qa-send-cs", true, mb_port::EXTERNAL);
92   d_p3 = define_port("p3", "qa-send-cs", false, mb_port::EXTERNAL);
93 }
94
95 sr1::~sr1(){}
96   
97 void
98 sr1::initial_transition()
99 {
100   // std::cout << instance_name() << "[sr1]: initial_transition\n";
101
102   // send two messages to each port
103   pmt_t our_name = pmt_intern(instance_name());
104   d_p1->send(s_status, pmt_list3(our_name, s_p1, pmt_from_long(0)));
105   d_p1->send(s_status, pmt_list3(our_name, s_p1, pmt_from_long(1)));
106
107   d_p2->send(s_status, pmt_list3(our_name, s_p2, pmt_from_long(0)));
108   d_p2->send(s_status, pmt_list3(our_name, s_p2, pmt_from_long(1)));
109 }
110
111 REGISTER_MBLOCK_CLASS(sr1);
112
113 // ----------------------------------------------------------------
114
115 // top-level container block for test_simple_routing
116 class sr0 : public mb_mblock
117 {
118   mb_port_sptr  d_p0;
119   
120 public:
121   sr0(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
122   ~sr0();
123   void initial_transition();
124 };
125
126 sr0::sr0(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
127   : mb_mblock(runtime, instance_name, user_arg)
128 {
129   d_p0 = define_port("p0", "qa-send-cs", false, mb_port::INTERNAL);
130
131   define_component("mb1", "sr1");
132   define_component("mb2", "sr1");
133
134   connect("self", "p0", "mb1", "p1");
135   connect("mb1", "p2", "mb2", "p3");
136   connect("mb1", "p3", "mb2", "p2");
137 }
138
139 sr0::~sr0(){}
140
141 void
142 sr0::initial_transition()
143 {
144   // std::cout << instance_name() << "[sr0]: initial_transition\n";
145
146   // send two messages to p0
147   pmt_t our_name = pmt_intern(instance_name());
148   d_p0->send(s_control, pmt_list3(our_name, s_p0, pmt_from_long(0)));
149   d_p0->send(s_control, pmt_list3(our_name, s_p0, pmt_from_long(1)));
150 }
151   
152 REGISTER_MBLOCK_CLASS(sr0);
153
154 // ----------------------------------------------------------------
155
156 /*
157  * This tests basic message routing using INTERNAL and EXTERNAL ports.
158  * It does not rely on the guts of the runtime being complete,
159  * which is good, because at the time this is being written, it isn't.
160  */
161 void
162 qa_mblock_send::test_simple_routing()
163 {
164   define_protocol_classes();
165
166   mb_message_sptr msg;
167
168   mb_runtime_sptr rt = mb_make_runtime_nop();
169   rt->run("top", "sr0", PMT_F);
170
171   mb_mblock_sptr mb0 = get_top(rt);
172   
173   // Reach into the guts and see if the messages ended up where they should have
174
175   // mb0 should have received two messages sent from mb1 via its p1
176   msg = mb0->impl()->msgq().get_highest_pri_msg_nowait();
177   CPPUNIT_ASSERT(msg);
178   // std::cerr << msg->data() << std::endl;
179   CPPUNIT_ASSERT_EQUAL(s_p0, msg->port_id());
180   CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/mb1"), s_p1, pmt_from_long(0)),
181                            msg->data()));
182
183   msg = mb0->impl()->msgq().get_highest_pri_msg_nowait();
184   CPPUNIT_ASSERT(msg);
185   // std::cerr << msg->data() << std::endl;
186   CPPUNIT_ASSERT_EQUAL(s_p0, msg->port_id());
187   CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/mb1"), s_p1, pmt_from_long(1)),
188                            msg->data()));
189
190   // mb1 should have received
191   //   two messages from mb0 via its p0 and
192   //   two messages from mb2 via its p3
193
194   mb_mblock_sptr mb1 = mb0->impl()->component("mb1");
195
196   msg = mb1->impl()->msgq().get_highest_pri_msg_nowait();
197   CPPUNIT_ASSERT(msg);
198   // std::cerr << msg->data() << std::endl;
199   CPPUNIT_ASSERT_EQUAL(s_p1, msg->port_id());
200   CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top"), s_p0, pmt_from_long(0)),
201                            msg->data()));
202
203   msg = mb1->impl()->msgq().get_highest_pri_msg_nowait();
204   CPPUNIT_ASSERT(msg);
205   // std::cerr << msg->data() << std::endl;
206   CPPUNIT_ASSERT_EQUAL(s_p1, msg->port_id());
207   CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top"), s_p0, pmt_from_long(1)),
208                            msg->data()));
209
210   msg = mb1->impl()->msgq().get_highest_pri_msg_nowait();
211   CPPUNIT_ASSERT(msg);
212   // std::cerr << msg->data() << std::endl;
213   CPPUNIT_ASSERT_EQUAL(s_p3, msg->port_id());
214   CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/mb2"), s_p2, pmt_from_long(0)),
215                            msg->data()));
216
217   msg = mb1->impl()->msgq().get_highest_pri_msg_nowait();
218   CPPUNIT_ASSERT(msg);
219   // std::cerr << msg->data() << std::endl;
220   CPPUNIT_ASSERT_EQUAL(s_p3, msg->port_id());
221   CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/mb2"), s_p2, pmt_from_long(1)),
222                            msg->data()));
223
224
225   // mb2 should have received
226   //   two messages from mb2 via its p2
227
228   mb_mblock_sptr mb2 = mb0->impl()->component("mb2");
229
230   msg = mb2->impl()->msgq().get_highest_pri_msg_nowait();
231   CPPUNIT_ASSERT(msg);
232   // std::cerr << msg->data() << std::endl;
233   CPPUNIT_ASSERT_EQUAL(s_p3, msg->port_id());
234   CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/mb1"), s_p2, pmt_from_long(0)),
235                            msg->data()));
236
237   msg = mb2->impl()->msgq().get_highest_pri_msg_nowait();
238   CPPUNIT_ASSERT(msg);
239   // std::cerr << msg->data() << std::endl;
240   CPPUNIT_ASSERT_EQUAL(s_p3, msg->port_id());
241   CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/mb1"), s_p2, pmt_from_long(1)),
242                            msg->data()));
243 }
244
245 // ================================================================
246 //                     test_relay_routing_1
247 // ================================================================
248
249 // internal block for test_relay_routing
250
251 class rr2 : public mb_mblock
252 {
253   mb_port_sptr  d_p1;
254   mb_port_sptr  d_p2;
255
256 public:
257   rr2(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
258   ~rr2();
259   void initial_transition();
260 };
261
262 rr2::rr2(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
263   : mb_mblock(runtime, instance_name, user_arg)
264 {
265   d_p1 = define_port("p1", "qa-send-cs", true,  mb_port::EXTERNAL);
266   d_p2 = define_port("p2", "qa-send-cs", false, mb_port::EXTERNAL);
267 }
268
269 rr2::~rr2(){}
270   
271 void
272 rr2::initial_transition()
273 {
274   // std::cout << instance_name() << "[rr2]: initial_transition\n";
275
276   // send two messages via p1
277   pmt_t our_name = pmt_intern(instance_name());
278   d_p1->send(s_status, pmt_list3(our_name, s_p1, pmt_from_long(0)));
279   d_p1->send(s_status, pmt_list3(our_name, s_p1, pmt_from_long(1)));
280 }
281
282 REGISTER_MBLOCK_CLASS(rr2);
283
284 // ----------------------------------------------------------------
285
286 // intermediate block for test_relay_routing
287
288 class rr1 : public mb_mblock
289 {
290   mb_port_sptr  d_p1;
291   mb_port_sptr  d_p2;
292
293 public:
294   rr1(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
295   ~rr1();
296 };
297
298 rr1::rr1(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
299   : mb_mblock(runtime, instance_name, user_arg)
300 {
301   d_p1 = define_port("p1", "qa-send-cs", true,  mb_port::RELAY);
302   d_p2 = define_port("p2", "qa-send-cs", false, mb_port::RELAY);
303
304   define_component("c0", "rr2");
305
306   connect("self", "p1", "c0", "p1");
307   connect("self", "p2", "c0", "p2");
308 }
309
310 rr1::~rr1(){}
311
312 REGISTER_MBLOCK_CLASS(rr1);
313
314 // ----------------------------------------------------------------
315
316 // top-level container for test_relay_routing
317
318 class rr0_a : public mb_mblock
319 {
320 public:
321   rr0_a(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
322   ~rr0_a();
323 };
324
325 rr0_a::rr0_a(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
326   : mb_mblock(runtime, instance_name, user_arg)
327 {
328   define_component("c0", "rr1");
329   define_component("c1", "rr2");
330
331   connect("c0", "p1", "c1", "p2");
332   connect("c0", "p2", "c1", "p1");
333 }
334
335 rr0_a::~rr0_a(){}
336
337 REGISTER_MBLOCK_CLASS(rr0_a);
338
339 /*
340  * This tests basic message routing using RELAY and EXTERNAL ports.
341  * It does not rely on the guts of the runtime being complete,
342  * which is good, because at the time this is being written, it isn't.
343  */
344 void
345 qa_mblock_send::test_relay_routing_1()
346 {
347   mb_message_sptr msg;
348
349   mb_runtime_sptr rt = mb_make_runtime_nop();
350   rt->run("top", "rr0_a", PMT_F);
351   mb_mblock_sptr top = get_top(rt);
352
353   // Reach into the guts and see if the messages ended up where they should have
354
355   mb_mblock_sptr c0 = top->impl()->component("c0");
356   mb_mblock_sptr c0c0 = c0->impl()->component("c0");
357
358   mb_mblock_sptr c1 = top->impl()->component("c1");
359
360   // c0c0 should have received
361   //   two message from c1 via its p2
362
363   msg = c0c0->impl()->msgq().get_highest_pri_msg_nowait();
364   CPPUNIT_ASSERT(msg);
365   //std::cerr << msg->data() << std::endl;
366   CPPUNIT_ASSERT_EQUAL(s_p2, msg->port_id());
367   CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/c1"), s_p1, pmt_from_long(0)),
368                            msg->data()));
369
370   msg = c0c0->impl()->msgq().get_highest_pri_msg_nowait();
371   CPPUNIT_ASSERT(msg);
372   //std::cerr << msg->data() << std::endl;
373   CPPUNIT_ASSERT_EQUAL(s_p2, msg->port_id());
374   CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/c1"), s_p1, pmt_from_long(1)),
375                            msg->data()));
376
377   // c1 should have received
378   //   two message from c0c0 via its p2
379
380   msg = c1->impl()->msgq().get_highest_pri_msg_nowait();
381   CPPUNIT_ASSERT(msg);
382   //std::cerr << msg->data() << std::endl;
383   CPPUNIT_ASSERT_EQUAL(s_p2, msg->port_id());
384   CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/c0/c0"), s_p1, pmt_from_long(0)),
385                            msg->data()));
386
387   msg = c1->impl()->msgq().get_highest_pri_msg_nowait();
388   CPPUNIT_ASSERT(msg);
389   //std::cerr << msg->data() << std::endl;
390   CPPUNIT_ASSERT_EQUAL(s_p2, msg->port_id());
391   CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/c0/c0"), s_p1, pmt_from_long(1)),
392                            msg->data()));
393 }
394
395 // ================================================================
396 //                     test_relay_routing_2
397 // ================================================================
398
399 // top-level container for test_relay_routing_2
400
401 class rr0_b : public mb_mblock
402 {
403 public:
404   rr0_b(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
405   ~rr0_b();
406 };
407
408 rr0_b::rr0_b(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
409   : mb_mblock(runtime, instance_name, user_arg)
410 {
411   define_component("c0", "rr1");
412   define_component("c1", "rr1");
413
414   connect("c0", "p1", "c1", "p2");
415   connect("c0", "p2", "c1", "p1");
416 }
417
418 rr0_b::~rr0_b(){}
419
420 REGISTER_MBLOCK_CLASS(rr0_b);
421
422 /*
423  * This tests basic message routing using RELAY and EXTERNAL ports.
424  * It does not rely on the guts of the runtime being complete,
425  * which is good, because at the time this is being written, it isn't.
426  */
427 void
428 qa_mblock_send::test_relay_routing_2()
429 {
430   mb_message_sptr msg;
431
432   mb_runtime_sptr rt = mb_make_runtime_nop();
433   rt->run("top", "rr0_b", PMT_F);
434   mb_mblock_sptr top = get_top(rt);
435
436   // Reach into the guts and see if the messages ended up where they should have
437
438   mb_mblock_sptr c0 = top->impl()->component("c0");
439   mb_mblock_sptr c0c0 = c0->impl()->component("c0");
440
441   mb_mblock_sptr c1 = top->impl()->component("c1");
442   mb_mblock_sptr c1c0 = c1->impl()->component("c0");
443
444   // c0c0 should have received
445   //   two message from c1c0 via its p2
446
447   msg = c0c0->impl()->msgq().get_highest_pri_msg_nowait();
448   CPPUNIT_ASSERT(msg);
449   // std::cerr << msg->data() << std::endl;
450   CPPUNIT_ASSERT_EQUAL(s_p2, msg->port_id());
451   CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/c1/c0"), s_p1, pmt_from_long(0)),
452                            msg->data()));
453
454   msg = c0c0->impl()->msgq().get_highest_pri_msg_nowait();
455   CPPUNIT_ASSERT(msg);
456   // std::cerr << msg->data() << std::endl;
457   CPPUNIT_ASSERT_EQUAL(s_p2, msg->port_id());
458   CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/c1/c0"), s_p1, pmt_from_long(1)),
459                            msg->data()));
460
461   // c1c0 should have received
462   //   two message from c0c0 via its p2
463
464   msg = c1c0->impl()->msgq().get_highest_pri_msg_nowait();
465   CPPUNIT_ASSERT(msg);
466   // std::cerr << msg->data() << std::endl;
467   CPPUNIT_ASSERT_EQUAL(s_p2, msg->port_id());
468   CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/c0/c0"), s_p1, pmt_from_long(0)),
469                            msg->data()));
470
471   msg = c1c0->impl()->msgq().get_highest_pri_msg_nowait();
472   CPPUNIT_ASSERT(msg);
473   // std::cerr << msg->data() << std::endl;
474   CPPUNIT_ASSERT_EQUAL(s_p2, msg->port_id());
475   CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/c0/c0"), s_p1, pmt_from_long(1)),
476                            msg->data()));
477 }