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