test_subst.cpp
Go to the documentation of this file.
1 // Unit tests for substitution args
2 // Author: Max Schwarz <max.schwarz@ais.uni-bonn.de>
3 
4 #include <boost/filesystem.hpp>
5 
6 #include <catch_ros/catch.hpp>
7 
8 #include "../../src/launch/launch_config.h"
9 
10 #include "core_utils.h"
11 #include "param_utils.h"
12 
13 #include <ros/package.h>
14 
15 using namespace rosmon::launch;
16 
17 namespace fs = boost::filesystem;
18 
19 TEST_CASE("env", "[subst]")
20 {
21  SECTION("basic")
22  {
23  LaunchConfig config;
24  config.parseString(R"EOF(
25  <launch>
26  <param name="env_test" value="$(env PATH)" />
27  </launch>
28  )EOF");
29 
30  config.evaluateParameters();
31 
32  CAPTURE(config.parameters());
33 
34  checkTypedParam<std::string>(config.parameters(), "/env_test", XmlRpc::XmlRpcValue::TypeString, getenv("PATH"));
35  }
36 
37  SECTION("failure")
38  {
40  <launch>
41  <param name="env_test" value="$(env ROSMON_UNLIKELY_TO_BE_SET)" />
42  </launch>
43  )EOF");
44  }
45 }
46 
47 TEST_CASE("optenv", "[subst]")
48 {
49  SECTION("present")
50  {
51  LaunchConfig config;
52  config.parseString(R"EOF(
53  <launch>
54  <param name="env_test" value="$(optenv PATH no_such_thing)" />
55  </launch>
56  )EOF");
57 
58  config.evaluateParameters();
59 
60  CAPTURE(config.parameters());
61 
62  checkTypedParam<std::string>(config.parameters(), "/env_test", XmlRpc::XmlRpcValue::TypeString, getenv("PATH"));
63  }
64 
65  SECTION("not present")
66  {
67  LaunchConfig config;
68  config.parseString(R"EOF(
69  <launch>
70  <param name="env_test" value="$(optenv ROSMON_UNLIKELY_TO_BE_SET no_such_thing)" />
71  </launch>
72  )EOF");
73 
74  config.evaluateParameters();
75 
76  CAPTURE(config.parameters());
77 
78  checkTypedParam<std::string>(config.parameters(), "/env_test", XmlRpc::XmlRpcValue::TypeString, "no_such_thing");
79  }
80 
81  SECTION("not present - long")
82  {
83  LaunchConfig config;
84  config.parseString(R"EOF(
85  <launch>
86  <param name="env_test" value="$(optenv ROSMON_UNLIKELY_TO_BE_SET no such thing)" />
87  </launch>
88  )EOF");
89 
90  config.evaluateParameters();
91 
92  CAPTURE(config.parameters());
93 
94  checkTypedParam<std::string>(config.parameters(), "/env_test", XmlRpc::XmlRpcValue::TypeString, "no such thing");
95  }
96 }
97 
98 TEST_CASE("find", "[subst]")
99 {
100  SECTION("regular use")
101  {
102  LaunchConfig config;
103  config.parseString(R"EOF(
104  <launch>
105  <param name="path_to_rosmon" value="$(find rosmon_core)" />
106  <param name="path_to_launch_file" value="$(find rosmon_core)/test/basic.launch" />
107  <param name="path_to_rosmon_executable" value="$(find rosmon_core)/rosmon" />
108  </launch>
109  )EOF");
110 
111  config.evaluateParameters();
112 
113  CAPTURE(config.parameters());
114 
115  checkTypedParam<std::string>(config.parameters(), "/path_to_rosmon", XmlRpc::XmlRpcValue::TypeString, ros::package::getPath("rosmon_core"));
116  checkTypedParam<std::string>(config.parameters(), "/path_to_launch_file", XmlRpc::XmlRpcValue::TypeString, ros::package::getPath("rosmon_core") + "/test/basic.launch");
117 
118  {
119  INFO("Looking for /path_to_rosmon_executable");
120 
121  auto it = config.parameters().find("/path_to_rosmon_executable");
122  REQUIRE(it != config.parameters().end());
123 
124  auto value = it->second;
125 
126  REQUIRE(value.getType() == XmlRpc::XmlRpcValue::TypeString);
127  auto string = static_cast<std::string>(value);
128 
129  CHECK((fs::status(string).permissions() & fs::owner_exe));
130  }
131  }
132 
133  SECTION("unknown package")
134  {
136  <launch>
137  <param name="test" value="$(find rosmon_this_package_is_unlikely_to_be_there)" />
138  </launch>
139  )EOF");
140  }
141 }
142 
143 TEST_CASE("anon", "[subst]")
144 {
145  SECTION("regular use")
146  {
147  LaunchConfig config;
148  config.parseString(R"EOF(
149  <launch>
150  <param name="test_1" value="$(anon rviz-1)" />
151  <param name="test_2" value="$(anon rviz-1)" />
152  <param name="test_3" value="$(anon rviz-2)" />
153  </launch>
154  )EOF");
155 
156  config.evaluateParameters();
157 
158  CAPTURE(config.parameters());
159 
160  auto test1 = getTypedParam<std::string>(config.parameters(), "/test_1");
161  auto test2 = getTypedParam<std::string>(config.parameters(), "/test_2");
162  auto test3 = getTypedParam<std::string>(config.parameters(), "/test_3");
163 
164  CHECK(test1 == test2);
165  CHECK(test1 != test3);
166  }
167 
168  SECTION("clash example")
169  {
170  // from http://wiki.ros.org/roslaunch/XML
172  <launch>
173  <node name="$(anon foo)" pkg="rospy_tutorials" type="talker.py" />
174  <node name="$(anon foo)" pkg="rospy_tutorials" type="talker.py" />
175  </launch>
176  )EOF");
177  }
178 
179  SECTION("nested")
180  {
181  LaunchConfig config;
182  config.parseString(R"EOF(
183  <launch>
184  <param name="test_1_global" value="$(anon test_1)" />
185 
186  <group>
187  <param name="test_1_local" value="$(anon test_1)" />
188  <param name="test_2_local" value="$(anon test_2)" />
189  </group>
190 
191  <param name="test_2_global" value="$(anon test_2)" />
192  </launch>
193  )EOF");
194 
195  config.evaluateParameters();
196 
197  CAPTURE(config.parameters());
198 
199  auto test_1_global = getTypedParam<std::string>(config.parameters(), "/test_1_global");
200  auto test_1_local = getTypedParam<std::string>(config.parameters(), "/test_1_local");
201  auto test_2_global = getTypedParam<std::string>(config.parameters(), "/test_2_global");
202  auto test_2_local = getTypedParam<std::string>(config.parameters(), "/test_2_local");
203 
204  CHECK(test_1_global == test_1_local);
205  CHECK(test_2_global != test_2_local);
206  }
207 }
208 
209 TEST_CASE("arg", "[subst]")
210 {
211  SECTION("basic use")
212  {
213  LaunchConfig config;
214  config.parseString(R"EOF(
215  <launch>
216  <arg name="test_arg" default="hello" />
217  <param name="test" value="$(arg test_arg)" />
218  </launch>
219  )EOF");
220 
221  config.evaluateParameters();
222 
223  CHECK(getTypedParam<std::string>(config.parameters(), "/test") == "hello");
224  }
225 
226  SECTION("unknown arg")
227  {
229  <launch>
230  <arg name="test_arg" default="hello" />
231  <param name="test" value="$(arg test_arg_unknown)" />
232  </launch>
233  )EOF");
234  }
235 
236  // more complicated tests may be in test_arg.cpp
237 }
238 
239 TEST_CASE("eval", "[subst]")
240 {
241  SECTION("example 1")
242  {
243  LaunchConfig config;
244  config.parseString(R"EOF(
245  <launch>
246  <arg name="radius" default="2.0" />
247  <param name="circumference" value="$(eval 2.* pi * arg('radius'))"/>
248  </launch>
249  )EOF");
250 
251  config.evaluateParameters();
252 
253  auto value = getTypedParam<double>(config.parameters(), "/circumference");
254  CHECK(value == Approx(2.0 * M_PI * 2.0));
255  }
256 
257  SECTION("example 2")
258  {
259  LaunchConfig config;
260  config.parseString(R"EOF(
261  <launch>
262  <arg name="foo" default="test" />
263  <param name="test" value="$(eval arg('foo') + env('PATH') + 'bar' + find('rosmon_core'))"/>
264  </launch>
265  )EOF");
266 
267  config.evaluateParameters();
268 
269  auto value = getTypedParam<std::string>(config.parameters(), "/test");
270  CHECK(value == std::string("test") + getenv("PATH") + "bar" + ros::package::getPath("rosmon_core"));
271  }
272 
273  SECTION("example 3")
274  {
275  LaunchConfig config;
276  config.parseString(R"EOF(
277  <launch>
278  <arg name="foo" default="test" />
279  <param name="test" value="$(eval foo + env('PATH') + 'bar' + find('rosmon_core'))"/>
280  </launch>
281  )EOF");
282 
283  config.evaluateParameters();
284 
285  auto value = getTypedParam<std::string>(config.parameters(), "/test");
286  CHECK(value == std::string("test") + getenv("PATH") + "bar" + ros::package::getPath("rosmon_core"));
287  }
288 
289  SECTION("example 4")
290  {
291  LaunchConfig config;
292  config.parseString(R"EOF(
293  <launch>
294  <arg name="foo" default="test" />
295  <param name="test" value="$(eval 2 * 20)"/>
296  </launch>
297  )EOF");
298 
299  config.evaluateParameters();
300 
301  auto value = getTypedParam<int>(config.parameters(), "/test");
302  CHECK(value == 2*20);
303  }
304 
305  SECTION("python errors")
306  {
307  using Catch::Matchers::Contains;
308 
309  std::string input = R"EOF(
310  <launch>
311  <arg name="foo" default="test" />
312  <param name="test" value="$(eval )))"/>
313  </launch>
314  )EOF";
315  CAPTURE(input);
316 
317  REQUIRE_THROWS_WITH(
318  LaunchConfig().parseString(input),
319  Contains("SyntaxError")
320  );
321 
323  <launch>
324  <arg name="foo" default="test" />
325  <param name="test" value="$(eval acos)"/>
326  </launch>
327  )EOF");
328  }
329 
330  SECTION("lowercase booleans")
331  {
332  LaunchConfig config;
333  config.parseString(R"EOF(
334  <launch>
335  <arg name="input" default="false" />
336  <param name="output" value="$(eval input == true)"/>
337  </launch>
338  )EOF");
339 
340  config.evaluateParameters();
341 
342  auto value = getTypedParam<bool>(config.parameters(), "/output");
343  CHECK(value == false);
344  }
345 }
346 
347 TEST_CASE("dirname", "[subst]")
348 {
349  SECTION("basic usage")
350  {
351  LaunchConfig config;
352  config.parseString(R"EOF(
353  <launch>
354  <param name="test" value="$(dirname)" />
355  </launch>
356  )EOF");
357 
358  config.evaluateParameters();
359 
360  auto value = getTypedParam<std::string>(config.parameters(), "/test");
361 
362  CHECK(fs::path(value) == fs::current_path());
363  }
364 }
365 
366 TEST_CASE("subst invalid", "[subst]")
367 {
368  SECTION("unknown subst")
369  {
371  <launch>
372  <param name="test" value="$(unknown_subst parameter)" />
373  </launch>
374  )EOF");
375  }
376 }
TEST_CASE("env","[subst]")
Definition: test_subst.cpp:19
const std::map< std::string, XmlRpc::XmlRpcValue > & parameters() const
static void requireParsingException(const std::string &input)
Definition: core_utils.h:11
void parseString(const std::string &input, bool onlyArguments=false)
config parseString(R"EOF( <launch> <group ns="/"> <param name="param1" value="hello" /> </group> <node name="test_node" pkg="rosmon_core" type="abort" ns="/racecar"> <param name="private_param" value="hello again" /> </node> </launch> )EOF")
ROSLIB_DECL std::string getPath(const std::string &package_name)


rosmon_core
Author(s): Max Schwarz
autogenerated on Sat Jan 9 2021 03:35:43