/* * Copyright (C) 2011 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.ros.internal.loader; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.ros.Assert.assertGraphNameEquals; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.ros.CommandLineVariables; import org.ros.EnvironmentVariables; import org.ros.namespace.GraphName; import org.ros.namespace.NameResolver; import org.ros.node.NodeConfiguration; import java.io.File; import java.net.URI; import java.net.URISyntaxException; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Test CommandLineLoader. * * @author kwc@willowgarage.com (Ken Conley) */ public class CommandLineLoaderTest { private URI defaultMasterUri; private File defaultRosRoot; private List<String> emptyArgv; private HashMap<String, String> getDefaultEnv() { HashMap<String, String> env = new HashMap<String, String>(); env.put(EnvironmentVariables.ROS_MASTER_URI, defaultMasterUri.toString()); env.put(EnvironmentVariables.ROS_ROOT, defaultRosRoot.getAbsolutePath()); return env; } @Before public void setup() throws URISyntaxException { defaultMasterUri = new URI("http://localhost:33133"); defaultRosRoot = new File(System.getProperty("user.dir")); emptyArgv = Lists.newArrayList("Foo"); } @Test public void testCommandLineLoader() { // Test with no args. CommandLineLoader loader = new CommandLineLoader(emptyArgv); assertEquals(0, loader.getNodeArguments().size()); // Test with no remappings. emptyArgv.add("one two --three"); loader = new CommandLineLoader(emptyArgv); Assert.assertEquals(emptyArgv.subList(1, emptyArgv.size()), loader.getNodeArguments()); // Test with actual remappings. All of these are equivalent. List<String> tests = Lists.newArrayList("--help one name:=/my/name -i foo:=/my/foo", "name:=/my/name --help one -i foo:=/my/foo", "name:=/my/name --help foo:=/my/foo one -i"); List<String> expected = Lists.newArrayList("--help", "one", "-i"); for (String test : tests) { loader = new CommandLineLoader(Lists.newArrayList(("Foo " + test).split("\\s+"))); // Test command-line parsing Assert.assertEquals(expected, loader.getNodeArguments()); } } /** * Test createConfiguration() with respect to reading of the environment * configuration, including command-line overrides. */ @Test public void testcreateConfigurationEnvironment() { // Construct artificial environment. Test failure without required settings. // Failure: ROS_ROOT not set. String tmpDir = System.getProperty("java.io.tmpdir"); String rosPackagePath = tmpDir + File.pathSeparator + defaultRosRoot; List<File> rosPackagePathList = Lists.newArrayList(new File(tmpDir), defaultRosRoot); Map<String, String> env = new HashMap<String, String>(); CommandLineLoader loader = null; env = Maps.newHashMap(); env.put(EnvironmentVariables.ROS_ROOT, defaultRosRoot.getAbsolutePath()); loader = new CommandLineLoader(emptyArgv, env); NodeConfiguration nodeConfiguration = loader.build(); assertEquals(NodeConfiguration.DEFAULT_MASTER_URI, nodeConfiguration.getMasterUri()); // Construct artificial environment. Set required environment variables. env = getDefaultEnv(); loader = new CommandLineLoader(emptyArgv, env); nodeConfiguration = loader.build(); assertEquals(defaultMasterUri, nodeConfiguration.getMasterUri()); assertEquals(defaultRosRoot, nodeConfiguration.getRosRoot()); assertTrue(nodeConfiguration.getParentResolver().getNamespace().isRoot()); // Default is loopback. assertTrue(nodeConfiguration.getTcpRosAdvertiseAddress().isLoopbackAddress()); assertTrue(nodeConfiguration.getXmlRpcAdvertiseAddress().isLoopbackAddress()); // Construct artificial environment. Set optional environment variables. env = getDefaultEnv(); env.put(EnvironmentVariables.ROS_IP, "192.168.0.1"); env.put(EnvironmentVariables.ROS_NAMESPACE, "/foo/bar"); env.put(EnvironmentVariables.ROS_PACKAGE_PATH, rosPackagePath); loader = new CommandLineLoader(emptyArgv, env); nodeConfiguration = loader.build(); assertEquals(defaultMasterUri, nodeConfiguration.getMasterUri()); assertEquals(defaultRosRoot, nodeConfiguration.getRosRoot()); assertEquals("192.168.0.1", nodeConfiguration.getTcpRosAdvertiseAddress().getHost()); assertEquals("192.168.0.1", nodeConfiguration.getXmlRpcAdvertiseAddress().getHost()); assertEquals(GraphName.of("/foo/bar"), nodeConfiguration.getParentResolver().getNamespace()); Assert.assertEquals(rosPackagePathList, nodeConfiguration.getRosPackagePath()); // Test ROS namespace resolution and canonicalization GraphName canonical = GraphName.of("/baz/bar"); env = getDefaultEnv(); env.put(EnvironmentVariables.ROS_NAMESPACE, "baz/bar"); loader = new CommandLineLoader(emptyArgv, env); nodeConfiguration = loader.build(); assertEquals(canonical, nodeConfiguration.getParentResolver().getNamespace()); env = getDefaultEnv(); env.put(EnvironmentVariables.ROS_NAMESPACE, "baz/bar/"); loader = new CommandLineLoader(emptyArgv, env); nodeConfiguration = loader.build(); assertEquals(canonical, nodeConfiguration.getParentResolver().getNamespace()); } @Test public void testCreateConfigurationCommandLine() throws URISyntaxException { Map<String, String> env = getDefaultEnv(); // Test __name override NodeConfiguration nodeConfiguration = new CommandLineLoader(emptyArgv, env).build(); assertEquals(null, nodeConfiguration.getNodeName()); List<String> args = Lists.newArrayList("Foo", "__name:=newname"); nodeConfiguration = new CommandLineLoader(args, env).build(); assertEquals("newname", nodeConfiguration.getNodeName().toString()); // Test ROS_MASTER_URI from command-line args = Lists.newArrayList("Foo", CommandLineVariables.ROS_MASTER_URI + ":=http://override:22622"); nodeConfiguration = new CommandLineLoader(args, env).build(); assertEquals(new URI("http://override:22622"), nodeConfiguration.getMasterUri()); // Test again with env var removed, make sure that it still behaves the // same. env.remove(EnvironmentVariables.ROS_MASTER_URI); nodeConfiguration = new CommandLineLoader(args, env).build(); assertEquals(new URI("http://override:22622"), nodeConfiguration.getMasterUri()); // Test ROS namespace resolution and canonicalization GraphName canonical = GraphName.of("/baz/bar"); env = getDefaultEnv(); args = Lists.newArrayList("Foo", CommandLineVariables.ROS_NAMESPACE + ":=baz/bar"); nodeConfiguration = new CommandLineLoader(args, env).build(); assertEquals(canonical, nodeConfiguration.getParentResolver().getNamespace()); args = Lists.newArrayList("Foo", CommandLineVariables.ROS_NAMESPACE + ":=baz/bar/"); nodeConfiguration = new CommandLineLoader(args, env).build(); assertEquals(canonical, nodeConfiguration.getParentResolver().getNamespace()); // Verify precedence of command-line __ns over environment. env.put(EnvironmentVariables.ROS_NAMESPACE, "wrong/answer/"); nodeConfiguration = new CommandLineLoader(args, env).build(); assertEquals(canonical, nodeConfiguration.getParentResolver().getNamespace()); // Verify address override. env = getDefaultEnv(); args = Lists.newArrayList("Foo", CommandLineVariables.ROS_IP + ":=192.168.0.2"); nodeConfiguration = new CommandLineLoader(args, env).build(); assertEquals("192.168.0.2", nodeConfiguration.getTcpRosAdvertiseAddress().getHost()); assertEquals("192.168.0.2", nodeConfiguration.getXmlRpcAdvertiseAddress().getHost()); // Verify multiple options work together. env = getDefaultEnv(); args = Lists.newArrayList("Foo", CommandLineVariables.ROS_NAMESPACE + ":=baz/bar/", "ignore", CommandLineVariables.ROS_MASTER_URI + ":=http://override:22622", "--bad", CommandLineVariables.ROS_IP + ":=192.168.0.2"); nodeConfiguration = new CommandLineLoader(args, env).build(); assertEquals(new URI("http://override:22622"), nodeConfiguration.getMasterUri()); assertEquals("192.168.0.2", nodeConfiguration.getTcpRosAdvertiseAddress().getHost()); assertEquals("192.168.0.2", nodeConfiguration.getXmlRpcAdvertiseAddress().getHost()); assertEquals(canonical, nodeConfiguration.getParentResolver().getNamespace()); } /** * Test the {@link NameResolver} created by createConfiguration(). */ @Test public void testcreateConfigurationResolver() { // Construct artificial environment. Set required environment variables. HashMap<String, String> env = getDefaultEnv(); // Test with no args. CommandLineLoader loader = new CommandLineLoader(emptyArgv, env); NodeConfiguration nodeConfiguration = loader.build(); nodeConfiguration.getParentResolver().getRemappings(); nodeConfiguration = loader.build(); // Test with no remappings. List<String> args = Lists.newArrayList("Foo", "foo", "--bar"); loader = new CommandLineLoader(args, env); nodeConfiguration = loader.build(); NameResolver resolver = nodeConfiguration.getParentResolver(); assertTrue(resolver.getRemappings().isEmpty()); // test with actual remappings. All of these tests are equivalent. List<String> tests = Lists.newArrayList("--help name:=/my/name -i foo:=/my/foo", "name:=/my/name --help -i foo:=/my/foo", "name:=/my/name foo:=/my/foo --help -i"); for (String test : tests) { args = Lists.newArrayList(("Foo " + test).split("\\s+")); loader = new CommandLineLoader(args, env); nodeConfiguration = loader.build(); // Test that our remappings loaded. NameResolver r = nodeConfiguration.getParentResolver(); GraphName n = r.resolve("name"); assertGraphNameEquals("/my/name", n); assertGraphNameEquals("/name", r.resolve("/name")); assertGraphNameEquals("/my/foo", r.resolve("foo")); assertGraphNameEquals("/my/name", r.resolve("/my/name")); } } }