View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.shared.utils.cli;
20  
21  import java.util.Arrays;
22  import java.util.HashMap;
23  import java.util.Locale;
24  import java.util.Map;
25  import java.util.Properties;
26  
27  import org.apache.maven.shared.utils.Os;
28  import org.junit.Test;
29  
30  import static org.hamcrest.MatcherAssert.assertThat;
31  import static org.hamcrest.Matchers.hasItemInArray;
32  import static org.hamcrest.Matchers.not;
33  import static org.junit.Assert.assertEquals;
34  import static org.junit.Assert.assertNotNull;
35  import static org.junit.Assert.assertTrue;
36  import static org.junit.Assert.fail;
37  
38  public class CommandLineUtilsTest {
39  
40      /**
41       * Tests that case-insensitive environment variables are normalized to upper case.
42       */
43      @Test
44      public void testGetSystemEnvVarsCaseInsensitive() {
45          Properties vars = CommandLineUtils.getSystemEnvVars(false);
46          for (Object o : vars.keySet()) {
47              String variable = (String) o;
48              assertEquals(variable.toUpperCase(Locale.ENGLISH), variable);
49          }
50      }
51  
52      @Test
53      public void testEnsureCaseSensitivity() {
54          Map<String, String> data = new HashMap<>();
55          data.put("abz", "cool");
56          assertTrue(CommandLineUtils.ensureCaseSensitivity(data, false).containsKey("ABZ"));
57          assertTrue(CommandLineUtils.ensureCaseSensitivity(data, true).containsKey("abz"));
58      }
59  
60      /**
61       * Tests that environment variables on Windows are normalized to upper case. Does nothing on Unix platforms.
62       */
63      @Test
64      public void testGetSystemEnvVarsWindows() {
65          if (!Os.isFamily(Os.FAMILY_WINDOWS)) {
66              return;
67          }
68          Properties vars = CommandLineUtils.getSystemEnvVars();
69          for (Object o : vars.keySet()) {
70              String variable = (String) o;
71              assertEquals(variable.toUpperCase(Locale.ENGLISH), variable);
72          }
73      }
74  
75      /**
76       * Tests the splitting of a command line into distinct arguments.
77       */
78      @Test
79      public void testTranslateCommandline() throws Exception {
80          assertCmdLineArgs(new String[] {}, null);
81          assertCmdLineArgs(new String[] {}, "");
82  
83          assertCmdLineArgs(new String[] {"foo", "bar"}, "foo bar");
84          assertCmdLineArgs(new String[] {"foo", "bar"}, "   foo   bar   ");
85  
86          assertCmdLineArgs(new String[] {"foo", " double quotes ", "bar"}, "foo \" double quotes \" bar");
87          assertCmdLineArgs(new String[] {"foo", " single quotes ", "bar"}, "foo ' single quotes ' bar");
88  
89          assertCmdLineArgs(new String[] {"foo", " \" ", "bar"}, "foo ' \" ' bar");
90          assertCmdLineArgs(new String[] {"foo", " ' ", "bar"}, "foo \" ' \" bar");
91      }
92  
93      @Test
94      public void givenADoubleQuoteMarkInArgument_whenExecutingCode_thenCommandLineExceptionIsThrown() {
95          try {
96              new Commandline("echo \"let\"s go\"").execute();
97          } catch (CommandLineException e) {
98              assertTrue(true);
99              return;
100         }
101         fail("Exception was not thrown when given invalid (3 unescaped double quote) input");
102     }
103 
104     @Test
105     public void givenASingleQuoteMarkInArgument_whenExecutingCode_thenExitCode0Returned() throws Exception {
106         final Process p = new Commandline("echo \"let's go\"").execute();
107         p.waitFor();
108         assertEquals(0, p.exitValue());
109     }
110 
111     @Test
112     public void givenASingleQuoteMarkInArgument_whenTranslatingToCmdLineArgs_thenTheQuotationMarkIsNotEscaped()
113             throws Exception {
114         final String command = "echo \"let's go\"";
115         final String[] expected = new String[] {"echo", "let's go"};
116         assertCmdLineArgs(expected, command);
117     }
118 
119     @Test
120     public void
121             givenAnEscapedDoubleQuoteMarkInArgument_whenTranslatingToCmdLineArgs_thenTheQuotationMarkRemainsEscaped()
122                     throws Exception {
123         final String command = "echo \"let\\\"s go\"";
124         final String[] expected = new String[] {"echo", "let\\\"s go"};
125         assertCmdLineArgs(expected, command);
126     }
127 
128     @Test
129     public void
130             givenAnEscapedSingleQuoteMarkInArgument_whenTranslatingToCmdLineArgs_thenTheQuotationMarkRemainsEscaped()
131                     throws Exception {
132         final String command = "echo \"let\\'s go\"";
133         final String[] expected = new String[] {"echo", "let\\'s go"};
134         assertCmdLineArgs(expected, command);
135     }
136 
137     @Test
138     public void givenAnEscapedDoubleQuoteMarkInArgument_whenTranslatingToCmdLineArgs_thenNoExceptionIsThrown()
139             throws Exception {
140         Process p = new Commandline("echo \"let\\\"s go\"").execute();
141         p.waitFor();
142         assertEquals(0, p.exitValue());
143     }
144 
145     private void assertCmdLineArgs(final String[] expected, final String cmdLine) throws Exception {
146         String[] actual = CommandLineUtils.translateCommandline(cmdLine);
147         assertNotNull(actual);
148         assertEquals(expected.length, actual.length);
149         assertEquals(Arrays.asList(expected), Arrays.asList(actual));
150     }
151 
152     @Test
153     public void environmentVariableWithNullShouldNotBeSet() {
154 
155         Commandline commandline = new Commandline();
156         commandline.addEnvironment("TEST_NULL_ENV", null);
157 
158         String[] environmentVariables = commandline.getEnvironmentVariables();
159 
160         assertNotNull(environmentVariables);
161         assertThat(environmentVariables, not(hasItemInArray("TEST_NULL_ENV=null")));
162     }
163 
164     @Test
165     public void environmentVariableFromSystemIsCopiedByDefault() {
166 
167         Commandline commandline = new Commandline();
168 
169         String[] environmentVariables = commandline.getEnvironmentVariables();
170 
171         assertNotNull(environmentVariables);
172         assertThat(environmentVariables, hasItemInArray("TEST_SHARED_ENV=TestValue"));
173     }
174 
175     @Test
176     public void environmentVariableFromSystemIsNotCopiedIfInheritedIsFalse() {
177 
178         Commandline commandline = new Commandline();
179         commandline.setShellEnvironmentInherited(false);
180 
181         String[] environmentVariables = commandline.getEnvironmentVariables();
182 
183         assertNotNull(environmentVariables);
184         assertEquals(0, environmentVariables.length);
185     }
186 
187     @Test
188     public void environmentVariableFromSystemIsRemoved() {
189 
190         Commandline commandline = new Commandline();
191         commandline.addEnvironment("TEST_SHARED_ENV", null);
192 
193         String[] environmentVariables = commandline.getEnvironmentVariables();
194 
195         assertNotNull(environmentVariables);
196         assertThat(environmentVariables, not(hasItemInArray("TEST_SHARED_ENV=TestValue")));
197     }
198 }