Skip to content

Commit b7edf47

Browse files
author
Juan Ignacio Ubeira
authored
Merge pull request rosjava#284 from jubeira/feature/rosjava_helpers_test
Imrpoving ParameterLoaderNode error checking
2 parents f2134b2 + 9ab275a commit b7edf47

File tree

5 files changed

+181
-31
lines changed

5 files changed

+181
-31
lines changed

rosjava_helpers/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
apply plugin: 'java'
2-
31
dependencies {
42
compile project(':rosjava')
53
compile 'org.yaml:snakeyaml:[1.17, 1.18)'
6-
}
4+
testCompile 'junit:junit:4.8.2'
5+
testCompile project(':rosjava').sourceSets.test.output
6+
}

rosjava_helpers/src/main/java/org/ros/helpers/ParameterLoaderNode.java

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.ros.helpers;
1818

19+
import com.google.common.base.Preconditions;
20+
1921
import org.apache.commons.logging.Log;
2022
import org.ros.namespace.GraphName;
2123
import org.ros.node.AbstractNodeMain;
@@ -47,36 +49,39 @@ public class ParameterLoaderNode extends AbstractNodeMain {
4749
* Default constructor
4850
* @param resources Array of resources with their respective namespace to load.
4951
*/
50-
public ParameterLoaderNode(ArrayList<Resource> resources) {
52+
public ParameterLoaderNode(List<Resource> resources) {
53+
Preconditions.checkNotNull(resources);
5154
for (Resource r : resources) {
55+
Preconditions.checkNotNull(r.inputStream);
5256
addSingleYmlInput(r.inputStream, r.namespace == null ? "" : r.namespace);
5357
}
5458
}
5559

5660
private void addSingleYmlInput(InputStream ymlInputStream, String namespace) {
57-
this.params.add(new LoadedResource((new Yaml()).load(ymlInputStream), namespace));
61+
Object loadedYaml = new Yaml().load(ymlInputStream);
62+
if (loadedYaml != null && loadedYaml instanceof Map<?, ?>) {
63+
this.params.add(new LoadedResource(Map.class.cast(loadedYaml), namespace));
64+
}
5865
}
5966

60-
@SuppressWarnings("unchecked")
61-
private void addParams(ParameterTree parameterTree, String namespace, Map<String, Object> params) {
62-
for (Map.Entry<String, Object> e : params.entrySet()) {
63-
String fullKeyName = namespace + "/" + e.getKey();
67+
private void addParams(ParameterTree parameterTree, String namespace, Map<?, ?> params) {
68+
for (Map.Entry<?, ?> e : params.entrySet()) {
69+
String fullKeyName = namespace + "/" + e.getKey().toString();
6470
if (log != null) {
65-
log.info("Loading parameter " + fullKeyName + " \nValue = " + e.getValue());
71+
log.debug("Loading parameter " + fullKeyName + " \nValue = " + e.getValue());
6672
}
67-
6873
if (e.getValue() instanceof String) {
69-
parameterTree.set(fullKeyName, (String)e.getValue());
74+
parameterTree.set(fullKeyName, String.class.cast(e.getValue()));
7075
} else if (e.getValue() instanceof Integer) {
71-
parameterTree.set(fullKeyName, (Integer)e.getValue());
76+
parameterTree.set(fullKeyName, Integer.class.cast(e.getValue()));
7277
} else if (e.getValue() instanceof Double) {
73-
parameterTree.set(fullKeyName, (Double)e.getValue());
78+
parameterTree.set(fullKeyName, Double.class.cast(e.getValue()));
7479
} else if (e.getValue() instanceof Map) {
75-
parameterTree.set(fullKeyName, (Map)e.getValue());
80+
parameterTree.set(fullKeyName, Map.class.cast(e.getValue()));
7681
} else if (e.getValue() instanceof Boolean) {
77-
parameterTree.set(fullKeyName, (Boolean)e.getValue());
82+
parameterTree.set(fullKeyName, Boolean.class.cast(e.getValue()));
7883
} else if (e.getValue() instanceof List) {
79-
parameterTree.set(fullKeyName, (List)e.getValue());
84+
parameterTree.set(fullKeyName, List.class.cast(e.getValue()));
8085
} else if (log != null) {
8186
log.debug("I don't know what type parameter " + fullKeyName + " is. Value = " + e.getValue());
8287
log.debug("Class name is: " + e.getValue().getClass().getName());
@@ -95,18 +100,16 @@ public GraphName getDefaultNodeName() {
95100

96101
@Override
97102
public void onStart(ConnectedNode connectedNode) {
98-
if (params != null) {
99-
ParameterTree parameterTree = connectedNode.getParameterTree();
100-
log = connectedNode.getLog();
101-
102-
// TODO: For some reason, setting the / param when using a rosjava master doesn't work
103-
// It does work fine with an external master, and also setting other params of any type
104-
for (LoadedResource r : params) {
105-
addParams(parameterTree, r.namespace, r.resource);
106-
}
103+
ParameterTree parameterTree = connectedNode.getParameterTree();
104+
log = connectedNode.getLog();
107105

108-
connectedNode.shutdown();
106+
// TODO: For some reason, setting the / param when using a rosjava master doesn't work
107+
// It does work fine with an external master, and also setting other params of any type
108+
for (LoadedResource r : params) {
109+
addParams(parameterTree, r.namespace, r.resource);
109110
}
111+
112+
connectedNode.shutdown();
110113
}
111114

112115
/**
@@ -128,11 +131,11 @@ public Resource(InputStream inputStream, String namespace) {
128131
* keep the code simple.
129132
*/
130133
private class LoadedResource {
131-
public Map<String, Object> resource;
132-
public String namespace;
134+
private Map<?, ?> resource;
135+
private String namespace;
133136

134-
LoadedResource(Object resource, String namespace) {
135-
this.resource = (Map<String, Object>) resource;
137+
LoadedResource(Map resource, String namespace) {
138+
this.resource = resource;
136139
this.namespace = namespace;
137140
}
138141
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* Copyright (C) 2018 Ekumen, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package org.ros.helpers;
17+
18+
19+
import org.apache.commons.logging.Log;
20+
import org.junit.Before;
21+
import org.junit.Test;
22+
import org.ros.RosTest;
23+
import org.ros.exception.ParameterNotFoundException;
24+
import org.ros.namespace.GraphName;
25+
import org.ros.node.AbstractNodeMain;
26+
import org.ros.node.ConnectedNode;
27+
import org.ros.node.DefaultNodeListener;
28+
import org.ros.node.Node;
29+
import org.ros.node.NodeListener;
30+
import org.ros.node.parameter.ParameterTree;
31+
32+
import java.util.ArrayList;
33+
import java.util.List;
34+
import java.util.concurrent.CountDownLatch;
35+
import java.util.concurrent.TimeUnit;
36+
37+
import static org.junit.Assert.assertEquals;
38+
import static org.junit.Assert.assertTrue;
39+
import static org.junit.Assert.fail;
40+
41+
42+
/**
43+
* @author jubeira@ekumenlabs.com (Juan I. Ubeira)
44+
*/
45+
public class ParameterLoaderNodeTest extends RosTest {
46+
47+
private ParameterTree parameters;
48+
private Log log;
49+
50+
@Before
51+
public void setup() throws InterruptedException {
52+
final CountDownLatch latch = new CountDownLatch(1);
53+
nodeMainExecutor.execute(new AbstractNodeMain() {
54+
@Override
55+
public GraphName getDefaultNodeName() {
56+
return GraphName.of("node_name");
57+
}
58+
59+
@Override
60+
public void onStart(ConnectedNode connectedNode) {
61+
parameters = connectedNode.getParameterTree();
62+
log = connectedNode.getLog();
63+
latch.countDown();
64+
}
65+
}, nodeConfiguration);
66+
assertTrue(latch.await(1, TimeUnit.SECONDS));
67+
}
68+
69+
@Test
70+
public void testParameterLoad() throws InterruptedException {
71+
final String namespace = "foo";
72+
List<ParameterLoaderNode.Resource> resourceList = new ArrayList<ParameterLoaderNode.Resource>() {{
73+
add(new ParameterLoaderNode.Resource(getClass().getResourceAsStream("/parameters.yaml"), ""));
74+
add(new ParameterLoaderNode.Resource(getClass().getResourceAsStream("/parameters.yaml"), namespace));
75+
}};
76+
ParameterLoaderNode parameterLoaderNode = new ParameterLoaderNode(resourceList);
77+
78+
final CountDownLatch parameterNodeLatch = new CountDownLatch(1);
79+
nodeMainExecutor.execute(parameterLoaderNode, nodeConfiguration, new ArrayList<NodeListener>() {{
80+
add(new DefaultNodeListener() {
81+
@Override
82+
public void onShutdown(Node node) {
83+
parameterNodeLatch.countDown();
84+
}
85+
});
86+
}});
87+
88+
assertTrue(parameterNodeLatch.await(1, TimeUnit.SECONDS));
89+
90+
try {
91+
// Without namespace.
92+
assertEquals("bar", parameters.getString("/string_param"));
93+
assertEquals(1823, parameters.getInteger("/int_param"));
94+
assertEquals(1.74, parameters.getDouble("/double_param"), 0.001);
95+
assertEquals(false, parameters.getBoolean("/boolean_param"));
96+
List<?> list = parameters.getList("/list_param");
97+
assertEquals("Hello", list.get(0));
98+
assertEquals(1, list.get(1));
99+
assertEquals(2.3, list.get(2));
100+
assertEquals(true, list.get(3));
101+
102+
// With namespace.
103+
assertEquals("bar", parameters.getString(namespace + "/string_param"));
104+
assertEquals(1823, parameters.getInteger(namespace + "/int_param"));
105+
assertEquals(1.74, parameters.getDouble(namespace + "/double_param"), 0.001);
106+
assertEquals(false, parameters.getBoolean(namespace + "/boolean_param"));
107+
list = parameters.getList(namespace + "/list_param");
108+
assertEquals("Hello", list.get(0));
109+
assertEquals(1, list.get(1));
110+
assertEquals(2.3, list.get(2));
111+
assertEquals(true, list.get(3));
112+
} catch (ParameterNotFoundException e) {
113+
log.error("Error: " + e.getMessage());
114+
fail();
115+
}
116+
}
117+
118+
@Test
119+
public void testEmptyYaml() throws InterruptedException {
120+
List<ParameterLoaderNode.Resource> resourceList = new ArrayList<ParameterLoaderNode.Resource>() {{
121+
add(new ParameterLoaderNode.Resource(getClass().getResourceAsStream("/empty.yaml"), ""));
122+
}};
123+
ParameterLoaderNode parameterLoaderNode = new ParameterLoaderNode(resourceList);
124+
125+
final CountDownLatch parameterNodeLatch = new CountDownLatch(1);
126+
nodeMainExecutor.execute(parameterLoaderNode, nodeConfiguration, new ArrayList<NodeListener>() {{
127+
add(new DefaultNodeListener() {
128+
@Override
129+
public void onShutdown(Node node) {
130+
parameterNodeLatch.countDown();
131+
}
132+
});
133+
}});
134+
135+
// No exceptions shall be thrown on node execution, and it should shut down properly.
136+
assertTrue(parameterNodeLatch.await(1, TimeUnit.SECONDS));
137+
}
138+
}

rosjava_helpers/src/test/resources/empty.yaml

Whitespace-only changes.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
string_param: "bar"
2+
int_param: 1823
3+
double_param: 1.74
4+
boolean_param: false
5+
list_param:
6+
- "Hello"
7+
- 1
8+
- 2.3
9+
- true

0 commit comments

Comments
 (0)