test_rosparam.cpp
Go to the documentation of this file.
1 // Unit tests for rosparam tag
2 // Author: Max Schwarz <max.schwarz@ais.uni-bonn.de>
3 
4 #include <catch_ros/catch.hpp>
5 
6 #include "../../src/launch/launch_config.h"
7 
8 #include "core_utils.h"
9 #include "param_utils.h"
10 
11 using namespace rosmon::launch;
12 
13 TEST_CASE("rosparam basic", "[rosparam]")
14 {
15  LaunchConfig config;
16  config.parseString(R"EOF(
17  <launch>
18 <rosparam>
19 test_ns:
20  param1: true
21  param2: hello
22  param3: 3
23  param4: 10.0
24  param5: "3"
25 </rosparam>
26  </launch>
27  )EOF");
28 
29  config.evaluateParameters();
30 
31  CAPTURE(config.parameters());
32 
33  auto& params = config.parameters();
34  checkTypedParam<bool>(params, "/test_ns/param1", XmlRpc::XmlRpcValue::TypeBoolean, true);
35  checkTypedParam<std::string>(params, "/test_ns/param2", XmlRpc::XmlRpcValue::TypeString, "hello");
36  checkTypedParam<int>(params, "/test_ns/param3", XmlRpc::XmlRpcValue::TypeInt, 3);
37  checkTypedParam<double>(params, "/test_ns/param4", XmlRpc::XmlRpcValue::TypeDouble, 10.0);
38  checkTypedParam<std::string>(params, "/test_ns/param5", XmlRpc::XmlRpcValue::TypeString, "3");
39 }
40 
41 TEST_CASE("rosparam empty", "[rosparam]")
42 {
43  LaunchConfig config;
44  config.parseString(R"EOF(
45  <launch>
46 <rosparam>
47 </rosparam>
48 
49  <rosparam command="load" file="$(find rosmon_core)/test/empty.yaml" />
50  </launch>
51  )EOF");
52 }
53 
54 TEST_CASE("rosparam invalid YAML", "[rosparam]")
55 {
57  <launch>
58 <rosparam>
59 hello: {{ invalid }} test
60 </rosparam>
61  </launch>
62  )EOF");
63 }
64 
65 TEST_CASE("rosparam naming", "[rosparam]")
66 {
67  LaunchConfig config;
68  config.parseString(R"EOF(
69  <launch>
70  <rosparam param="a_list">[1, 2, 3, 4]</rosparam>
71 
72  <arg name="whitelist" default="[3, 2]"/>
73  <rosparam param="whitelist" subst_value="True">$(arg whitelist)</rosparam>
74 
75 <rosparam ns="namespace">
76 a: false
77 </rosparam>
78  </launch>
79  )EOF");
80 
81  config.evaluateParameters();
82 
83  CAPTURE(config.parameters());
84 
85  {
86  INFO("looking for: a_list");
87 
88  auto it = config.parameters().find("/a_list");
89  REQUIRE(it != config.parameters().end());
90 
91  auto value = it->second;
92 
93  REQUIRE(value.getType() == XmlRpc::XmlRpcValue::TypeArray);
94  REQUIRE(value.size() == 4);
95  }
96 
97  {
98  INFO("looking for: whitelist");
99 
100  auto it = config.parameters().find("/whitelist");
101  REQUIRE(it != config.parameters().end());
102 
103  auto value = it->second;
104 
105  REQUIRE(value.getType() == XmlRpc::XmlRpcValue::TypeArray);
106  REQUIRE(value.size() == 2);
107  }
108 
109  checkTypedParam<bool>(config.parameters(), "/namespace/a", XmlRpc::XmlRpcValue::TypeBoolean, false);
110 }
111 
112 TEST_CASE("rosparam explicit types", "[rosparam]")
113 {
114  LaunchConfig config;
115  config.parseString(R"EOF(
116  <launch>
117 <rosparam>
118 test_ns:
119  param1: !!str 1
120  param2: !!float 1
121  param3: !!binary "aGVsbG8K"
122 </rosparam>
123  </launch>
124  )EOF");
125 
126  config.evaluateParameters();
127 
128  CAPTURE(config.parameters());
129 
130  auto& params = config.parameters();
131  checkTypedParam<std::string>(params, "/test_ns/param1", XmlRpc::XmlRpcValue::TypeString, "1");
132  checkTypedParam<double>(params, "/test_ns/param2", XmlRpc::XmlRpcValue::TypeDouble, 1.0);
133 
134  auto binParam = getTypedParam<XmlRpc::XmlRpcValue::BinaryData>(params, "/test_ns/param3", XmlRpc::XmlRpcValue::TypeBase64);
135  XmlRpc::XmlRpcValue::BinaryData expected{'h', 'e', 'l', 'l', 'o', '\n'};
136  CHECK(binParam == expected);
137 }
138 
139 TEST_CASE("rosparam angle extensions", "[rosparam]")
140 {
141  LaunchConfig config;
142  config.parseString(R"EOF(
143  <launch>
144 <rosparam>
145 test_ns:
146  param1: rad(2*pi)
147  param2: deg(180)
148  param3: !degrees 181.0
149  param4: !radians 3.14169
150  param5: deg( 0.1)
151 </rosparam>
152  </launch>
153  )EOF");
154 
155  config.evaluateParameters();
156 
157  CAPTURE(config.parameters());
158 
159  auto& params = config.parameters();
160 
161  double param1 = getTypedParam<double>(params, "/test_ns/param1", XmlRpc::XmlRpcValue::TypeDouble);
162  CHECK(param1 == Approx(2.0 * M_PI));
163 
164  double param2 = getTypedParam<double>(params, "/test_ns/param2", XmlRpc::XmlRpcValue::TypeDouble);
165  CHECK(param2 == Approx(180.0 * M_PI / 180.0));
166 
167  double param3 = getTypedParam<double>(params, "/test_ns/param3", XmlRpc::XmlRpcValue::TypeDouble);
168  CHECK(param3 == Approx(181.0 * M_PI / 180.0));
169 
170  double param4 = getTypedParam<double>(params, "/test_ns/param4", XmlRpc::XmlRpcValue::TypeDouble);
171  CHECK(param4 == Approx(3.14169));
172 
173  double param5 = getTypedParam<double>(params, "/test_ns/param5", XmlRpc::XmlRpcValue::TypeDouble);
174  CHECK(param5 == Approx(0.1 * M_PI / 180.0));
175 }
176 
177 TEST_CASE("merge keys", "[rosparam]")
178 {
179  LaunchConfig config;
180  config.parseString(R"EOF(
181  <launch>
182 <rosparam>
183 common: &amp;common
184  param1: true
185  param2: 5.0
186  param3: hello
187 commonclass: &amp;commonclass
188  testclass:
189  &lt;&lt;: *common
190  testparam: 140
191 class1:
192  &lt;&lt;: *common
193  param4: 514
194 class2:
195  param1: false
196  &lt;&lt;: *common
197 class3:
198  &lt;&lt;: *common
199  param1: false
200 class4:
201  &lt;&lt;: *common
202  param1: 5
203  param2: test
204  param3: 0.1
205 class5:
206  &lt;&lt;: *commonclass
207  param4: sub
208 class6:
209  &lt;&lt;: *commonclass
210  testclass:
211  param2: 10.0
212 array:
213  - &lt;&lt;: *common
214  A: 23
215  C: 99
216 </rosparam>
217  </launch>
218  )EOF");
219 
220  config.evaluateParameters();
221 
222  CAPTURE(config.parameters());
223 
224  auto& params = config.parameters();
225 
226  // Class 1 test simple addition
227  std::string class_ns = "/class1";
228  checkTypedParam<bool>(params, class_ns + "/param1", XmlRpc::XmlRpcValue::TypeBoolean, true);
229  checkTypedParam<double>(params, class_ns + "/param2", XmlRpc::XmlRpcValue::TypeDouble, 5.0);
230  checkTypedParam<std::string>(params, class_ns + "/param3", XmlRpc::XmlRpcValue::TypeString, "hello");
231  checkTypedParam<int>(params, class_ns + "/param4", XmlRpc::XmlRpcValue::TypeInt, 514);
232 
233  // Class 2 test override pre-assigned
234  class_ns = "/class2";
235  checkTypedParam<bool>(params, class_ns + "/param1", XmlRpc::XmlRpcValue::TypeBoolean, false);
236  checkTypedParam<double>(params, class_ns + "/param2", XmlRpc::XmlRpcValue::TypeDouble, 5.0);
237  checkTypedParam<std::string>(params, class_ns + "/param3", XmlRpc::XmlRpcValue::TypeString, "hello");
238 
239  // Class 3 test override post-assigned
240  class_ns = "/class3";
241  checkTypedParam<bool>(params, class_ns + "/param1", XmlRpc::XmlRpcValue::TypeBoolean, false);
242  checkTypedParam<double>(params, class_ns + "/param2", XmlRpc::XmlRpcValue::TypeDouble, 5.0);
243  checkTypedParam<std::string>(params, class_ns + "/param3", XmlRpc::XmlRpcValue::TypeString, "hello");
244 
245  // Class 4 test typechange overrides
246  class_ns = "/class4";
247  checkTypedParam<int>(params, class_ns + "/param1", XmlRpc::XmlRpcValue::TypeInt, 5);
248  checkTypedParam<std::string>(params, class_ns + "/param2", XmlRpc::XmlRpcValue::TypeString, "test");
249  checkTypedParam<double>(params, class_ns + "/param3", XmlRpc::XmlRpcValue::TypeDouble, 0.1);
250 
251  // Class 5 test nested merge
252  class_ns = "/class5";
253  checkTypedParam<bool>(params, class_ns + "/testclass/param1", XmlRpc::XmlRpcValue::TypeBoolean, true);
254  checkTypedParam<double>(params, class_ns + "/testclass/param2", XmlRpc::XmlRpcValue::TypeDouble, 5.0);
255  checkTypedParam<std::string>(params, class_ns + "/testclass/param3", XmlRpc::XmlRpcValue::TypeString, "hello");
256  checkTypedParam<int>(params, class_ns + "/testclass/testparam", XmlRpc::XmlRpcValue::TypeInt, 140);
257  checkTypedParam<std::string>(params, class_ns + "/param4", XmlRpc::XmlRpcValue::TypeString, "sub");
258 
259  // Class 6 test override on nested merge
260  class_ns = "/class6";
261  checkTypedParam<bool>(params, class_ns + "/testclass/param1", XmlRpc::XmlRpcValue::TypeBoolean, true);
262  checkTypedParam<double>(params, class_ns + "/testclass/param2", XmlRpc::XmlRpcValue::TypeDouble, 10.0);
263  checkTypedParam<std::string>(params, class_ns + "/testclass/param3", XmlRpc::XmlRpcValue::TypeString, "hello");
264  checkTypedParam<int>(params, class_ns + "/testclass/testparam", XmlRpc::XmlRpcValue::TypeInt, 140);
265 
266  {
267  // Structs in arrays (#150)
268  auto array = getTypedParam<XmlRpc::XmlRpcValue>(params, "/array", XmlRpc::XmlRpcValue::TypeArray);
269  REQUIRE(array.size() == 1);
270  auto element = array[0];
271  REQUIRE(element.getType() == XmlRpc::XmlRpcValue::TypeStruct);
272 
273  CAPTURE(element);
274  CHECK(element.hasMember("A"));
275  CHECK(static_cast<int>(element["A"]) == 23);
276  CHECK(element.hasMember("param1"));
277  CHECK(static_cast<bool>(element["param1"]) == true);
278  }
279 }
280 
281 TEST_CASE("rosparam /param", "[rosparam]")
282 {
283  LaunchConfig config;
284  config.parseString(R"EOF(
285  <launch>
286 <rosparam ns="ns">
287 /fake_param: 20.0
288 namespace:
289  /other_param: 10.0
290  /global_ns:
291  third_param: 5.0
292 </rosparam>
293  </launch>
294  )EOF");
295 
296  config.evaluateParameters();
297 
298  CAPTURE(config.parameters());
299 
300  auto& params = config.parameters();
301 
302  double param1 = getTypedParam<double>(params, "/fake_param", XmlRpc::XmlRpcValue::TypeDouble);
303  CHECK(param1 == Approx(20.0));
304 
305  double param2 = getTypedParam<double>(params, "/other_param", XmlRpc::XmlRpcValue::TypeDouble);
306  CHECK(param2 == Approx(10.0));
307 
308  double param3 = getTypedParam<double>(params, "/global_ns/third_param", XmlRpc::XmlRpcValue::TypeDouble);
309  CHECK(param3 == Approx(5.0));
310 }
auto & params
Definition: test_param.cpp:226
TEST_CASE("rosparam basic", "[rosparam]")
static void requireParsingException(const std::string &input)
Definition: core_utils.h:11
void parseString(const std::string &input, bool onlyArguments=false)
const std::map< std::string, XmlRpc::XmlRpcValue > & parameters() const
std::vector< char > BinaryData


rosmon_core
Author(s): Max Schwarz
autogenerated on Fri Jun 16 2023 02:15:06