Skip to content

Commit cc0ed1f

Browse files
committed
Add test for resolve_parameter_overrides
1 parent 1487666 commit cc0ed1f

File tree

4 files changed

+131
-4
lines changed

4 files changed

+131
-4
lines changed

rclrs/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ parking_lot = "0.11.2"
1818
# Needed for the Message trait, among others
1919
rosidl_runtime_rs = "*"
2020

21+
[dev-dependencies]
22+
# Needed for e.g. writing yaml files in tests
23+
tempfile = "3.3.0"
24+
2125
[build-dependencies]
2226
# Needed for FFI
2327
bindgen = "0.59.1"

rclrs/src/node/builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ impl NodeBuilder {
267267
let _parameter_map = unsafe {
268268
let fqn = call_string_getter_with_handle(&rcl_node, rcl_node_get_fully_qualified_name);
269269
resolve_parameter_overrides(
270-
fqn,
270+
&fqn,
271271
&rcl_node_options.arguments,
272272
&rcl_context.global_arguments,
273273
)?

rclrs/src/parameter/override_map.rs

Lines changed: 125 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ pub(crate) type ParameterOverrideMap = BTreeMap<String, ParameterValue>;
108108
/// This function is unsafe since the rcl_global_arguments argument might contain incorrect array
109109
/// sizes or dangling pointers.
110110
pub(crate) unsafe fn resolve_parameter_overrides(
111-
node_fqn: String,
111+
node_fqn: &str,
112112
rcl_node_arguments: &rcl_arguments_t,
113113
rcl_global_arguments: &rcl_arguments_t,
114114
) -> Result<ParameterOverrideMap, RclrsError> {
@@ -118,7 +118,7 @@ pub(crate) unsafe fn resolve_parameter_overrides(
118118
rcl_arguments_get_param_overrides(rcl_arguments, &mut rcl_params).ok()?;
119119
// Check for the /** node first, and later overwrite with the more specific node
120120
// parameters, if they exist
121-
for name_to_match in ["/**", node_fqn.as_str()] {
121+
for name_to_match in ["/**", node_fqn] {
122122
for (node_name, node_params) in RclParamsIter::new(rcl_params) {
123123
if node_name == name_to_match {
124124
for (param_name, variant) in RclNodeParamsIter::new(node_params) {
@@ -132,3 +132,126 @@ pub(crate) unsafe fn resolve_parameter_overrides(
132132
}
133133
Ok(map)
134134
}
135+
136+
#[cfg(test)]
137+
mod tests {
138+
use super::*;
139+
use std::error::Error;
140+
use std::ffi::CString;
141+
use std::io::Write;
142+
use tempfile::NamedTempFile;
143+
144+
// These files have values for every possible four-bit number, with the four bits being
145+
// * `/**` global params
146+
// * named global params
147+
// * `/**` node params
148+
// * named node params
149+
const GLOBAL_PARAMS_FILE: &str = r#"
150+
/**:
151+
ros__parameters:
152+
a: 1
153+
b: 1
154+
c: 1
155+
d: 1
156+
e: 1
157+
f: 1
158+
g: 1
159+
h: 1
160+
/my_ns/my_node:
161+
ros__parameters:
162+
a: 2
163+
b: 2
164+
c: 2
165+
d: 2
166+
i: 2
167+
j: 2
168+
k: 2
169+
l: 2
170+
"#;
171+
172+
const NODE_PARAMS_FILE: &str = r#"
173+
/my_ns/my_node:
174+
ros__parameters:
175+
a: 3
176+
b: 3
177+
e: 3
178+
f: 3
179+
i: 3
180+
j: 3
181+
m: 3
182+
n: 3
183+
/my_ns/my_node:
184+
ros__parameters:
185+
a: 4
186+
c: 4
187+
e: 4
188+
g: 4
189+
i: 4
190+
k: 4
191+
m: 4
192+
o: 4
193+
"#;
194+
195+
// The returned rcl_arguments need to be manually finalized with rcl_arguments_fini
196+
fn convert_to_rcl_arguments(
197+
param_file_contents: &str,
198+
) -> Result<rcl_arguments_t, Box<dyn Error>> {
199+
let mut params_file = NamedTempFile::new()?;
200+
write!(params_file, "{}", param_file_contents)?;
201+
let params_filename = params_file.path().display().to_string();
202+
let args = ["--ros-args", "--params-file", &params_filename]
203+
.into_iter()
204+
.map(CString::new)
205+
.collect::<Result<Vec<_>, _>>()?;
206+
let args_ptrs = args.iter().map(|s| s.as_ptr()).collect::<Vec<_>>();
207+
let mut rcl_arguments = unsafe { rcl_get_zero_initialized_arguments() };
208+
unsafe {
209+
rcl_parse_arguments(
210+
args_ptrs.len() as i32,
211+
args_ptrs.as_ptr(),
212+
rcutils_get_default_allocator(),
213+
&mut rcl_arguments,
214+
);
215+
}
216+
Ok(rcl_arguments)
217+
}
218+
219+
#[test]
220+
fn test_resolve_parameter_overrides() -> Result<(), Box<dyn Error>> {
221+
let node_fqn = "/my_ns/my_node";
222+
let mut rcl_node_arguments = convert_to_rcl_arguments(NODE_PARAMS_FILE)?;
223+
let mut rcl_global_arguments = convert_to_rcl_arguments(GLOBAL_PARAMS_FILE)?;
224+
let overrides_map = unsafe {
225+
resolve_parameter_overrides(node_fqn, &rcl_node_arguments, &rcl_global_arguments)?
226+
};
227+
unsafe {
228+
rcl_arguments_fini(&mut rcl_node_arguments);
229+
rcl_arguments_fini(&mut rcl_global_arguments);
230+
}
231+
let values: Vec<_> = overrides_map
232+
.iter()
233+
.map(|(k, v)| (k.as_str(), v.clone()))
234+
.collect();
235+
assert_eq!(
236+
values,
237+
vec![
238+
("a", ParameterValue::Integer(4)),
239+
("b", ParameterValue::Integer(3)),
240+
("c", ParameterValue::Integer(4)),
241+
("d", ParameterValue::Integer(2)),
242+
("e", ParameterValue::Integer(4)),
243+
("f", ParameterValue::Integer(3)),
244+
("g", ParameterValue::Integer(4)),
245+
("h", ParameterValue::Integer(1)),
246+
("i", ParameterValue::Integer(4)),
247+
("j", ParameterValue::Integer(3)),
248+
("k", ParameterValue::Integer(4)),
249+
("l", ParameterValue::Integer(2)),
250+
("m", ParameterValue::Integer(4)),
251+
("n", ParameterValue::Integer(3)),
252+
("o", ParameterValue::Integer(4)),
253+
]
254+
);
255+
Ok(())
256+
}
257+
}

rclrs/src/parameter/value.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ mod tests {
154154
let mut rcl_params = std::ptr::null_mut();
155155
unsafe {
156156
rcl_arguments_get_param_overrides(
157-
&ctx.handle.lock().global_arguments,
157+
&ctx.rcl_context_mtx.lock().global_arguments,
158158
&mut rcl_params,
159159
)
160160
.ok()?;

0 commit comments

Comments
 (0)