1 /* -*- c++ -*- */
2 /*
3 * Copyright 2007,2013 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., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <gnuradio/blocks/nop.h>
28 #include <gnuradio/blocks/null_sink.h>
29 #include <gnuradio/blocks/null_source.h>
30 #include <gnuradio/flowgraph.h>
31 #include <boost/test/unit_test.hpp>
32
33 namespace gr {
34 namespace blocks {
35 class null_qa_source : virtual public sync_block
36 {
37 public:
38 typedef boost::shared_ptr<null_qa_source> sptr;
39 static sptr make(size_t sizeof_stream_item);
40 };
41 class null_source_qa_impl : public null_qa_source
42 {
43 public:
null_source_qa_impl(size_t sizeof_stream_item)44 null_source_qa_impl(size_t sizeof_stream_item)
45 : sync_block("null_source",
46 io_signature::make(0, 0, 0),
47 io_signature::make(1, 1, sizeof_stream_item))
48 {
49 }
~null_source_qa_impl()50 ~null_source_qa_impl() {}
51
work(int noutput_items,gr_vector_const_void_star & input_items,gr_vector_void_star & output_items)52 int work(int noutput_items,
53 gr_vector_const_void_star& input_items,
54 gr_vector_void_star& output_items)
55 {
56 void* optr;
57 for (size_t n = 0; n < input_items.size(); n++) {
58 optr = (void*)output_items[n];
59 memset(optr, 0, noutput_items * output_signature()->sizeof_stream_item(n));
60 }
61 return noutput_items;
62 }
63 };
make(size_t sizeof_stream_item)64 null_qa_source::sptr null_qa_source::make(size_t sizeof_stream_item)
65 {
66 return gnuradio::get_initial_sptr(new null_source_qa_impl(sizeof_stream_item));
67 }
68 class null_qa_sink : virtual public sync_block
69 {
70 public:
71 typedef boost::shared_ptr<null_qa_sink> sptr;
72 static sptr make(size_t sizeof_stream_item);
73 };
74 class null_sink_qa_impl : public null_qa_sink
75 {
76 public:
null_sink_qa_impl(size_t sizeof_stream_item)77 null_sink_qa_impl(size_t sizeof_stream_item)
78 : sync_block("null_qa_sink",
79 io_signature::make(1, 1, sizeof_stream_item),
80 io_signature::make(0, 0, 0))
81 {
82 }
~null_sink_qa_impl()83 ~null_sink_qa_impl() {}
work(int noutput_items,gr_vector_const_void_star & input_items,gr_vector_void_star & output_items)84 int work(int noutput_items,
85 gr_vector_const_void_star& input_items,
86 gr_vector_void_star& output_items)
87 {
88 return noutput_items;
89 }
90 };
make(size_t sizeof_stream_item)91 null_qa_sink::sptr null_qa_sink::make(size_t sizeof_stream_item)
92 {
93 return gnuradio::get_initial_sptr(new null_sink_qa_impl(sizeof_stream_item));
94 }
95 } /* namespace blocks */
96 } /* namespace gr */
97
BOOST_AUTO_TEST_CASE(t0)98 BOOST_AUTO_TEST_CASE(t0)
99 {
100 gr::flowgraph_sptr fg = gr::make_flowgraph();
101
102 BOOST_REQUIRE(fg);
103 }
104
BOOST_AUTO_TEST_CASE(t1_connect)105 BOOST_AUTO_TEST_CASE(t1_connect)
106 {
107 gr::flowgraph_sptr fg = gr::make_flowgraph();
108
109 gr::block_sptr nop1 = gr::blocks::nop::make(sizeof(int));
110 gr::block_sptr nop2 = gr::blocks::nop::make(sizeof(int));
111
112 fg->connect(nop1, 0, nop2, 0);
113 }
114
BOOST_AUTO_TEST_CASE(t2_connect_invalid_src_port_neg)115 BOOST_AUTO_TEST_CASE(t2_connect_invalid_src_port_neg)
116 {
117 gr::flowgraph_sptr fg = gr::make_flowgraph();
118
119 gr::block_sptr nop1 = gr::blocks::nop::make(sizeof(int));
120 gr::block_sptr nop2 = gr::blocks::nop::make(sizeof(int));
121
122 BOOST_REQUIRE_THROW(fg->connect(nop1, -1, nop2, 0), std::invalid_argument);
123 }
124
BOOST_AUTO_TEST_CASE(t3_connect_src_port_exceeds)125 BOOST_AUTO_TEST_CASE(t3_connect_src_port_exceeds)
126 {
127 gr::flowgraph_sptr fg = gr::make_flowgraph();
128
129 gr::block_sptr src = gr::blocks::null_qa_source::make(sizeof(int));
130 gr::block_sptr dst = gr::blocks::null_sink::make(sizeof(int));
131
132 BOOST_REQUIRE_THROW(fg->connect(src, 1, dst, 0), std::invalid_argument);
133 }
134
BOOST_AUTO_TEST_CASE(t4_connect_invalid_dst_port_neg)135 BOOST_AUTO_TEST_CASE(t4_connect_invalid_dst_port_neg)
136 {
137 gr::flowgraph_sptr fg = gr::make_flowgraph();
138
139 gr::block_sptr nop1 = gr::blocks::nop::make(sizeof(int));
140 gr::block_sptr nop2 = gr::blocks::nop::make(sizeof(int));
141
142 BOOST_REQUIRE_THROW(fg->connect(nop1, 0, nop2, -1), std::invalid_argument);
143 }
144
BOOST_AUTO_TEST_CASE(t5_connect_dst_port_exceeds)145 BOOST_AUTO_TEST_CASE(t5_connect_dst_port_exceeds)
146 {
147 gr::flowgraph_sptr fg = gr::make_flowgraph();
148
149 gr::block_sptr src = gr::blocks::null_source::make(sizeof(int));
150 gr::block_sptr dst = gr::blocks::null_qa_sink::make(sizeof(int));
151
152 BOOST_REQUIRE_THROW(fg->connect(src, 0, dst, 1), std::invalid_argument);
153 }
154
BOOST_AUTO_TEST_CASE(t6_connect_dst_in_use)155 BOOST_AUTO_TEST_CASE(t6_connect_dst_in_use)
156 {
157 gr::flowgraph_sptr fg = gr::make_flowgraph();
158
159 gr::block_sptr src1 = gr::blocks::null_source::make(sizeof(int));
160 gr::block_sptr src2 = gr::blocks::null_source::make(sizeof(int));
161 gr::block_sptr dst = gr::blocks::null_sink::make(sizeof(int));
162
163 fg->connect(src1, 0, dst, 0);
164 BOOST_REQUIRE_THROW(fg->connect(src2, 0, dst, 0), std::invalid_argument);
165 }
166
BOOST_AUTO_TEST_CASE(t7_connect_one_src_two_dst)167 BOOST_AUTO_TEST_CASE(t7_connect_one_src_two_dst)
168 {
169 gr::flowgraph_sptr fg = gr::make_flowgraph();
170
171 gr::block_sptr src = gr::blocks::null_source::make(sizeof(int));
172 gr::block_sptr dst1 = gr::blocks::null_sink::make(sizeof(int));
173 gr::block_sptr dst2 = gr::blocks::null_sink::make(sizeof(int));
174
175 fg->connect(src, 0, dst1, 0);
176 fg->connect(src, 0, dst2, 0);
177 }
178
BOOST_AUTO_TEST_CASE(t8_connect_type_mismatch)179 BOOST_AUTO_TEST_CASE(t8_connect_type_mismatch)
180 {
181 gr::flowgraph_sptr fg = gr::make_flowgraph();
182
183 gr::block_sptr nop1 = gr::blocks::nop::make(sizeof(char));
184 gr::block_sptr nop2 = gr::blocks::nop::make(sizeof(int));
185
186 BOOST_REQUIRE_THROW(fg->connect(nop1, 0, nop2, 0), std::invalid_argument);
187 }
188
BOOST_AUTO_TEST_CASE(t9_disconnect)189 BOOST_AUTO_TEST_CASE(t9_disconnect)
190 {
191 gr::flowgraph_sptr fg = gr::make_flowgraph();
192
193 gr::block_sptr nop1 = gr::blocks::nop::make(sizeof(int));
194 gr::block_sptr nop2 = gr::blocks::nop::make(sizeof(int));
195
196 fg->connect(nop1, 0, nop2, 0);
197 fg->disconnect(nop1, 0, nop2, 0);
198 }
199
BOOST_AUTO_TEST_CASE(t10_disconnect_unconnected_block)200 BOOST_AUTO_TEST_CASE(t10_disconnect_unconnected_block)
201 {
202 gr::flowgraph_sptr fg = gr::make_flowgraph();
203
204 gr::block_sptr nop1 = gr::blocks::nop::make(sizeof(int));
205 gr::block_sptr nop2 = gr::blocks::nop::make(sizeof(int));
206 gr::block_sptr nop3 = gr::blocks::nop::make(sizeof(int));
207
208 fg->connect(nop1, 0, nop2, 0);
209 BOOST_REQUIRE_THROW(fg->disconnect(nop1, 0, nop3, 0), std::invalid_argument);
210 }
211
BOOST_AUTO_TEST_CASE(t11_disconnect_unconnected_port)212 BOOST_AUTO_TEST_CASE(t11_disconnect_unconnected_port)
213 {
214 gr::flowgraph_sptr fg = gr::make_flowgraph();
215
216 gr::block_sptr nop1 = gr::blocks::nop::make(sizeof(int));
217 gr::block_sptr nop2 = gr::blocks::nop::make(sizeof(int));
218
219 fg->connect(nop1, 0, nop2, 0);
220 BOOST_REQUIRE_THROW(fg->disconnect(nop1, 0, nop2, 1), std::invalid_argument);
221 }
222
BOOST_AUTO_TEST_CASE(t12_validate)223 BOOST_AUTO_TEST_CASE(t12_validate)
224 {
225 gr::flowgraph_sptr fg = gr::make_flowgraph();
226
227 gr::block_sptr nop1 = gr::blocks::nop::make(sizeof(int));
228 gr::block_sptr nop2 = gr::blocks::nop::make(sizeof(int));
229
230 fg->connect(nop1, 0, nop2, 0);
231 fg->validate();
232 }
233
BOOST_AUTO_TEST_CASE(t13_validate_missing_input_assignment)234 BOOST_AUTO_TEST_CASE(t13_validate_missing_input_assignment)
235 {
236 gr::flowgraph_sptr fg = gr::make_flowgraph();
237
238 gr::block_sptr nop1 = gr::blocks::nop::make(sizeof(int));
239 gr::block_sptr nop2 = gr::blocks::nop::make(sizeof(int));
240
241 fg->connect(nop1, 0, nop2, 0);
242 fg->connect(nop1, 0, nop2, 2);
243 BOOST_REQUIRE_THROW(fg->validate(), std::runtime_error);
244 }
245
BOOST_AUTO_TEST_CASE(t14_validate_missing_output_assignment)246 BOOST_AUTO_TEST_CASE(t14_validate_missing_output_assignment)
247 {
248 gr::flowgraph_sptr fg = gr::make_flowgraph();
249
250 gr::block_sptr nop1 = gr::blocks::nop::make(sizeof(int));
251 gr::block_sptr nop2 = gr::blocks::nop::make(sizeof(int));
252
253 fg->connect(nop1, 0, nop2, 0);
254 fg->connect(nop1, 2, nop2, 1);
255 BOOST_REQUIRE_THROW(fg->validate(), std::runtime_error);
256 }
257
BOOST_AUTO_TEST_CASE(t15_clear)258 BOOST_AUTO_TEST_CASE(t15_clear)
259 {
260 gr::flowgraph_sptr fg = gr::make_flowgraph();
261
262 gr::block_sptr nop1 = gr::blocks::nop::make(sizeof(int));
263 gr::block_sptr nop2 = gr::blocks::nop::make(sizeof(int));
264
265 fg->connect(nop1, 0, nop2, 0);
266
267 BOOST_REQUIRE(fg->edges().size() == 1);
268 BOOST_REQUIRE(fg->calc_used_blocks().size() == 2);
269
270 fg->clear();
271
272 BOOST_REQUIRE(fg->edges().empty());
273 BOOST_REQUIRE(fg->calc_used_blocks().empty());
274 }
275
BOOST_AUTO_TEST_CASE(t16_partition)276 BOOST_AUTO_TEST_CASE(t16_partition)
277 {
278 gr::flowgraph_sptr fg = gr::make_flowgraph();
279
280 gr::block_sptr nop11 = gr::blocks::nop::make(sizeof(int));
281 gr::block_sptr nop12 = gr::blocks::nop::make(sizeof(int));
282 gr::block_sptr nop13 = gr::blocks::nop::make(sizeof(int));
283 gr::block_sptr nop14 = gr::blocks::nop::make(sizeof(int));
284
285 gr::block_sptr nop21 = gr::blocks::nop::make(sizeof(int));
286 gr::block_sptr nop22 = gr::blocks::nop::make(sizeof(int));
287 gr::block_sptr nop23 = gr::blocks::nop::make(sizeof(int));
288
289 gr::block_sptr nop31 = gr::blocks::nop::make(sizeof(int));
290 gr::block_sptr nop32 = gr::blocks::nop::make(sizeof(int));
291
292 // Build disjoint graph #1
293 fg->connect(nop11, 0, nop12, 0);
294 fg->connect(nop12, 0, nop13, 0);
295 fg->connect(nop13, 0, nop14, 0);
296
297 // Build disjoint graph #2
298 fg->connect(nop21, 0, nop22, 0);
299 fg->connect(nop22, 0, nop23, 0);
300
301 // Build disjoint graph #3
302 fg->connect(nop31, 0, nop32, 0);
303
304 std::vector<gr::basic_block_vector_t> graphs = fg->partition();
305
306 BOOST_REQUIRE(graphs.size() == 3);
307 BOOST_REQUIRE(graphs[0].size() == 4);
308 BOOST_REQUIRE(graphs[1].size() == 3);
309 BOOST_REQUIRE(graphs[2].size() == 2);
310 }
311