Convert gr-audio-portaudio to Boost via gruel
[debian/gnuradio] / mblock / src / lib / qa_mblock_sys.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_sys.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 #include <string.h>
41 #include <iostream>
42
43 using namespace pmt;
44
45 static pmt_t s_data    = pmt_intern("data");
46 static pmt_t s_status  = pmt_intern("status");
47 static pmt_t s_control = pmt_intern("control");
48 static pmt_t s_p0   = pmt_intern("p0");
49 static pmt_t s_p1   = pmt_intern("p1");
50 static pmt_t s_p2   = pmt_intern("p2");
51 static pmt_t s_p3   = pmt_intern("p3");
52 static pmt_t s_e1   = pmt_intern("e1");
53 static pmt_t s_r1   = pmt_intern("r1");
54
55 static void
56 define_protocol_classes()
57 {
58   mb_make_protocol_class(s_data,                // name
59                          pmt_list1(s_data),     // incoming
60                          pmt_list1(s_data));    // outgoing
61 }
62
63
64 // ================================================================
65 //                        test_sys_1
66 // ================================================================
67
68 class sys_1 : public mb_mblock
69 {
70   pmt_t         d_user_arg;
71   mb_port_sptr  d_data;
72
73 public:
74   sys_1(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
75   ~sys_1();
76   void initial_transition();
77 };
78
79 sys_1::sys_1(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
80   : mb_mblock(runtime, instance_name, user_arg),
81     d_user_arg(user_arg)
82 {
83   d_data = define_port("data", "data", true, mb_port::EXTERNAL);
84 }
85
86 sys_1::~sys_1(){}
87   
88 void
89 sys_1::initial_transition()
90 {
91   shutdown_all(d_user_arg);
92 }
93
94 REGISTER_MBLOCK_CLASS(sys_1);
95
96 void
97 qa_mblock_sys::test_sys_1()
98 {
99   define_protocol_classes();
100
101   pmt_t result;
102   pmt_t n1 = pmt_from_long(1);
103   pmt_t n2 = pmt_from_long(2);
104
105   mb_runtime_sptr rt1 = mb_make_runtime();
106
107 #if 0
108   try {
109     rt1->run("top-1", "sys_1", n1, &result);
110   }
111   catch (omni_thread_fatal e){
112     std::cerr << "caught omni_thread_fatal: error = " << e.error
113               << ": " << strerror(e.error) << std::endl;
114   }
115   catch (omni_thread_invalid){
116     std::cerr << "caught omni_thread_invalid\n";
117   }
118 #else
119     rt1->run("top-1", "sys_1", n1, &result);
120 #endif
121   CPPUNIT_ASSERT(pmt_equal(n1, result));
122   
123   // Execute run a second time, with the same rt, to ensure sanity.
124   rt1->run("top-2", "sys_1", n2, &result);
125   CPPUNIT_ASSERT(pmt_equal(n2, result));
126 }
127
128 // ================================================================
129 //                        test_sys_2
130 // ================================================================
131
132 class squarer : public mb_mblock
133 {
134   mb_port_sptr  d_data;
135
136 public:
137   squarer(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
138
139   void handle_message(mb_message_sptr msg);
140 };
141
142 squarer::squarer(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
143   : mb_mblock(runtime, instance_name, user_arg)
144 {
145   d_data = define_port("data", "data", true, mb_port::EXTERNAL);
146 }
147
148 void
149 squarer::handle_message(mb_message_sptr msg)
150 {
151   if (!pmt_eq(msg->signal(), s_data))   // we only handle the "data" message
152     return;
153
154   // long x -> (long x . long (x * x))
155
156   pmt_t x_pmt = msg->data();
157   long x = pmt_to_long(x_pmt);
158   d_data->send(s_data, pmt_cons(x_pmt, pmt_from_long(x * x)));
159 }
160
161 REGISTER_MBLOCK_CLASS(squarer);
162
163 // ----------------------------------------------------------------
164
165 class sys_2 : public mb_mblock
166 {
167   mb_port_sptr  d_data;
168
169 public:
170   sys_2(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
171   void initial_transition();
172   void handle_message(mb_message_sptr msg);
173 };
174
175 sys_2::sys_2(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
176   : mb_mblock(runtime, instance_name, user_arg)
177 {
178   d_data = define_port("data", "data", true, mb_port::INTERNAL);
179   define_component("squarer", "squarer");
180   connect("self", "data", "squarer", "data");
181 }
182
183 void
184 sys_2::initial_transition()
185 {
186   // FIXME start timer to detect general failure
187
188   d_data->send(s_data, pmt_from_long(0)); // send initial message
189 }
190
191 void
192 sys_2::handle_message(mb_message_sptr msg)
193 {
194   if (!pmt_eq(msg->signal(), s_data))   // we only handle the "data" message
195     return;
196
197   // first check correctness of message
198
199   long x = pmt_to_long(pmt_car(msg->data()));
200   long y = pmt_to_long(pmt_cdr(msg->data()));
201
202   // std::cout << msg->data() << std::endl;
203
204   if (y != x * x){
205     std::cerr << "sys_2::handle_message: Expected y == x * x.  Got y = "
206               << y << " for x = " << x << std::endl;
207
208     shutdown_all(PMT_F);        // failed
209   }
210
211   if (x == 100)
212     shutdown_all(PMT_T);                        // done, OK
213   else 
214     d_data->send(s_data, pmt_from_long(x + 1)); // send next request
215 }
216
217 REGISTER_MBLOCK_CLASS(sys_2);
218
219 // ----------------------------------------------------------------
220
221 void
222 qa_mblock_sys::test_sys_2()
223 {
224   mb_runtime_sptr rt = mb_make_runtime();
225   pmt_t result = PMT_NIL;
226
227   // std::cerr << "qa_mblock_sys::test_sys_2 (enter)\n";
228   
229   rt->run("top-sys-2", "sys_2", PMT_F, &result);
230   CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
231 }
232
233 // ================================================================
234 //                        test_bitset_1
235 // ================================================================
236
237 void
238 qa_mblock_sys::test_bitset_1()
239 {
240   mb_runtime_sptr rt = mb_make_runtime();
241   pmt_t result = PMT_NIL;
242
243   long nmsgs =        1000;
244   long batch_size =      8;
245   
246   pmt_t arg = pmt_list2(pmt_from_long(nmsgs),   // # of messages to send through pipe
247                         pmt_from_long(batch_size));
248
249   rt->run("top", "qa_bitset_top", arg, &result);
250
251   CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
252 }
253
254 // ================================================================
255 //                        test_disconnect
256 // ================================================================
257
258 void
259 qa_mblock_sys::test_disconnect()
260 {
261   mb_runtime_sptr rt = mb_make_runtime();
262   pmt_t result = PMT_NIL;
263
264   long nmsgs =        10240;
265   
266   pmt_t arg = pmt_list1(pmt_from_long(nmsgs));  // # of messages to send through pipe
267
268
269   rt->run("top", "qa_disconnect_top", arg, &result);
270
271   CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
272 }