3 * Copyright 2006,2007,2008 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
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)
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.
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.
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>
43 using namespace gruel;
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");
56 define_protocol_classes()
58 mb_make_protocol_class(s_data, // name
59 pmt_list1(s_data), // incoming
60 pmt_list1(s_data)); // outgoing
64 // ================================================================
66 // ================================================================
68 class sys_1 : public mb_mblock
74 sys_1(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
76 void initial_transition();
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),
83 d_data = define_port("data", "data", true, mb_port::EXTERNAL);
89 sys_1::initial_transition()
91 shutdown_all(d_user_arg);
94 REGISTER_MBLOCK_CLASS(sys_1);
97 qa_mblock_sys::test_sys_1()
99 define_protocol_classes();
102 pmt_t n1 = pmt_from_long(1);
103 pmt_t n2 = pmt_from_long(2);
105 mb_runtime_sptr rt1 = mb_make_runtime();
109 rt1->run("top-1", "sys_1", n1, &result);
111 catch (omni_thread_fatal e){
112 std::cerr << "caught omni_thread_fatal: error = " << e.error
113 << ": " << strerror(e.error) << std::endl;
115 catch (omni_thread_invalid){
116 std::cerr << "caught omni_thread_invalid\n";
119 rt1->run("top-1", "sys_1", n1, &result);
121 CPPUNIT_ASSERT(pmt_equal(n1, result));
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));
128 // ================================================================
130 // ================================================================
132 class squarer : public mb_mblock
137 squarer(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
139 void handle_message(mb_message_sptr msg);
142 squarer::squarer(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
143 : mb_mblock(runtime, instance_name, user_arg)
145 d_data = define_port("data", "data", true, mb_port::EXTERNAL);
149 squarer::handle_message(mb_message_sptr msg)
151 if (!pmt_eq(msg->signal(), s_data)) // we only handle the "data" message
154 // long x -> (long x . long (x * x))
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)));
161 REGISTER_MBLOCK_CLASS(squarer);
163 // ----------------------------------------------------------------
165 class sys_2 : public mb_mblock
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);
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)
178 d_data = define_port("data", "data", true, mb_port::INTERNAL);
179 define_component("squarer", "squarer");
180 connect("self", "data", "squarer", "data");
184 sys_2::initial_transition()
186 // FIXME start timer to detect general failure
188 d_data->send(s_data, pmt_from_long(0)); // send initial message
192 sys_2::handle_message(mb_message_sptr msg)
194 if (!pmt_eq(msg->signal(), s_data)) // we only handle the "data" message
197 // first check correctness of message
199 long x = pmt_to_long(pmt_car(msg->data()));
200 long y = pmt_to_long(pmt_cdr(msg->data()));
202 // std::cout << msg->data() << std::endl;
205 std::cerr << "sys_2::handle_message: Expected y == x * x. Got y = "
206 << y << " for x = " << x << std::endl;
208 shutdown_all(PMT_F); // failed
212 shutdown_all(PMT_T); // done, OK
214 d_data->send(s_data, pmt_from_long(x + 1)); // send next request
217 REGISTER_MBLOCK_CLASS(sys_2);
219 // ----------------------------------------------------------------
222 qa_mblock_sys::test_sys_2()
224 mb_runtime_sptr rt = mb_make_runtime();
225 pmt_t result = PMT_NIL;
227 // std::cerr << "qa_mblock_sys::test_sys_2 (enter)\n";
229 rt->run("top-sys-2", "sys_2", PMT_F, &result);
230 CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
233 // ================================================================
235 // ================================================================
238 qa_mblock_sys::test_bitset_1()
240 mb_runtime_sptr rt = mb_make_runtime();
241 pmt_t result = PMT_NIL;
246 pmt_t arg = pmt_list2(pmt_from_long(nmsgs), // # of messages to send through pipe
247 pmt_from_long(batch_size));
249 rt->run("top", "qa_bitset_top", arg, &result);
251 CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
254 // ================================================================
256 // ================================================================
259 qa_mblock_sys::test_disconnect()
261 mb_runtime_sptr rt = mb_make_runtime();
262 pmt_t result = PMT_NIL;
266 pmt_t arg = pmt_list1(pmt_from_long(nmsgs)); // # of messages to send through pipe
269 rt->run("top", "qa_disconnect_top", arg, &result);
271 CPPUNIT_ASSERT(pmt_equal(PMT_T, result));