PageRenderTime 25ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/core/src/test/java/hudson/util/ArgumentListBuilderTest.java

https://gitlab.com/CORP-RESELLER/jenkins
Java | 241 lines | 178 code | 33 blank | 30 comment | 0 complexity | b5ae4e99c75744a657c6df3e3575ff94 MD5 | raw file
  1. /*
  2. * The MIT License
  3. *
  4. * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Yahoo! Inc.
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. package hudson.util;
  25. import static org.junit.Assert.*;
  26. import static org.hamcrest.CoreMatchers.*;
  27. import java.io.IOException;
  28. import java.util.HashMap;
  29. import java.util.HashSet;
  30. import java.util.Map;
  31. import java.util.Set;
  32. import org.junit.Ignore;
  33. import org.junit.Test;
  34. import org.jvnet.hudson.test.Issue;
  35. public class ArgumentListBuilderTest {
  36. @Test
  37. public void assertEmptyMask() {
  38. ArgumentListBuilder builder = new ArgumentListBuilder();
  39. builder.add("arg");
  40. builder.add("other", "arguments");
  41. assertFalse("There should not be any masked arguments", builder.hasMaskedArguments());
  42. boolean[] array = builder.toMaskArray();
  43. assertNotNull("The mask array should not be null", array);
  44. assertThat("The mask array was incorrect", array, is(new boolean[] { false, false, false }));
  45. }
  46. @Test
  47. public void assertLastArgumentIsMasked() {
  48. ArgumentListBuilder builder = new ArgumentListBuilder();
  49. builder.add("arg");
  50. builder.addMasked("ismasked");
  51. assertTrue("There should be masked arguments", builder.hasMaskedArguments());
  52. boolean[] array = builder.toMaskArray();
  53. assertNotNull("The mask array should not be null", array);
  54. assertThat("The mask array was incorrect", array, is(new boolean[] { false, true }));
  55. }
  56. @Test
  57. public void assertSeveralMaskedArguments() {
  58. ArgumentListBuilder builder = new ArgumentListBuilder();
  59. builder.add("arg");
  60. builder.addMasked("ismasked");
  61. builder.add("non masked arg");
  62. builder.addMasked("ismasked2");
  63. assertTrue("There should be masked arguments", builder.hasMaskedArguments());
  64. boolean[] array = builder.toMaskArray();
  65. assertNotNull("The mask array should not be null", array);
  66. assertThat("The mask array was incorrect", array, is(new boolean[] { false, true, false, true }));
  67. }
  68. @Test
  69. public void assertPrependAfterAddingMasked() {
  70. ArgumentListBuilder builder = new ArgumentListBuilder();
  71. builder.addMasked("ismasked");
  72. builder.add("arg");
  73. builder.prepend("first", "second");
  74. assertTrue("There should be masked arguments", builder.hasMaskedArguments());
  75. boolean[] array = builder.toMaskArray();
  76. assertNotNull("The mask array should not be null", array);
  77. assertThat("The mask array was incorrect", array, is(new boolean[] { false, false, true, false }));
  78. }
  79. @Test
  80. public void assertPrependBeforeAddingMasked() {
  81. ArgumentListBuilder builder = new ArgumentListBuilder();
  82. builder.prepend("first", "second");
  83. builder.addMasked("ismasked");
  84. builder.add("arg");
  85. assertTrue("There should be masked arguments", builder.hasMaskedArguments());
  86. boolean[] array = builder.toMaskArray();
  87. assertNotNull("The mask array should not be null", array);
  88. assertThat("The mask array was incorrect", array, is(new boolean[] { false, false, true, false }));
  89. }
  90. @Test
  91. public void testToWindowsCommand() {
  92. ArgumentListBuilder builder = new ArgumentListBuilder().
  93. add("ant.bat").add("-Dfoo1=abc"). // nothing special, no quotes
  94. add("-Dfoo2=foo bar").add("-Dfoo3=/u*r").add("-Dfoo4=/us?"). // add quotes
  95. add("-Dfoo10=bar,baz").
  96. add("-Dfoo5=foo;bar^baz").add("-Dfoo6=<xml>&here;</xml>"). // add quotes
  97. add("-Dfoo7=foo|bar\"baz"). // add quotes and "" for "
  98. add("-Dfoo8=% %QED% %comspec% %-%(%.%"). // add quotes, and extra quotes for %Q and %c
  99. add("-Dfoo9=%'''%%@%"); // no quotes as none of the % are followed by a letter
  100. // By default, does not escape %VAR%
  101. assertThat(builder.toWindowsCommand().toCommandArray(), is(new String[] { "cmd.exe", "/C",
  102. "\"ant.bat", "-Dfoo1=abc", "\"-Dfoo2=foo bar\"", "\"-Dfoo3=/u*r\"", "\"-Dfoo4=/us?\"",
  103. "\"-Dfoo10=bar,baz\"", "\"-Dfoo5=foo;bar^baz\"", "\"-Dfoo6=<xml>&here;</xml>\"",
  104. "\"-Dfoo7=foo|bar\"\"baz\"", "\"-Dfoo8=% %QED% %comspec% %-%(%.%\"",
  105. "-Dfoo9=%'''%%@%", "&&", "exit", "%%ERRORLEVEL%%\"" }));
  106. // Pass flag to escape %VAR%
  107. assertThat(builder.toWindowsCommand(true).toCommandArray(), is(new String[] { "cmd.exe", "/C",
  108. "\"ant.bat", "-Dfoo1=abc", "\"-Dfoo2=foo bar\"", "\"-Dfoo3=/u*r\"", "\"-Dfoo4=/us?\"",
  109. "\"-Dfoo10=bar,baz\"", "\"-Dfoo5=foo;bar^baz\"", "\"-Dfoo6=<xml>&here;</xml>\"",
  110. "\"-Dfoo7=foo|bar\"\"baz\"", "\"-Dfoo8=% %\"Q\"ED% %\"c\"omspec% %-%(%.%\"",
  111. "-Dfoo9=%'''%%@%", "&&", "exit", "%%ERRORLEVEL%%\"" }));
  112. // Try to hide password
  113. builder.add("-Dpassword=hidden", true);
  114. // By default, does not escape %VAR%
  115. assertThat(builder.toWindowsCommand().toString(), is("cmd.exe /C \"ant.bat -Dfoo1=abc \"\"-Dfoo2=foo bar\"\" \"-Dfoo3=/u*r\" \"-Dfoo4=/us?\" \"-Dfoo10=bar,baz\" \"-Dfoo5=foo;bar^baz\" \"-Dfoo6=<xml>&here;</xml>\" \"-Dfoo7=foo|bar\"\"baz\" \"\"-Dfoo8=% %QED% %comspec% %-%(%.%\"\" -Dfoo9=%'''%%@% ****** && exit %%ERRORLEVEL%%\"" ));
  116. // Pass flag to escape %VAR%
  117. assertThat(builder.toWindowsCommand(true).toString(), is("cmd.exe /C \"ant.bat -Dfoo1=abc \"\"-Dfoo2=foo bar\"\" \"-Dfoo3=/u*r\" \"-Dfoo4=/us?\" \"-Dfoo10=bar,baz\" \"-Dfoo5=foo;bar^baz\" \"-Dfoo6=<xml>&here;</xml>\" \"-Dfoo7=foo|bar\"\"baz\" \"\"-Dfoo8=% %\"Q\"ED% %\"c\"omspec% %-%(%.%\"\" -Dfoo9=%'''%%@% ****** && exit %%ERRORLEVEL%%\""));
  118. }
  119. @Test
  120. @Ignore("It's only for reproduce JENKINS-28790 issue. It's added to testToWindowsCommand")
  121. @Issue("JENKINS-28790")
  122. public void testToWindowsCommandMasked() {
  123. ArgumentListBuilder builder = new ArgumentListBuilder().
  124. add("ant.bat").add("-Dfoo1=abc"). // nothing special, no quotes
  125. add("-Dfoo2=foo bar").add("-Dfoo3=/u*r").add("-Dfoo4=/us?"). // add quotes
  126. add("-Dfoo10=bar,baz").
  127. add("-Dfoo5=foo;bar^baz").add("-Dfoo6=<xml>&here;</xml>"). // add quotes
  128. add("-Dfoo7=foo|bar\"baz"). // add quotes and "" for "
  129. add("-Dfoo8=% %QED% %comspec% %-%(%.%"). // add quotes, and extra quotes for %Q and %c
  130. add("-Dfoo9=%'''%%@%"). // no quotes as none of the % are followed by a letter
  131. add("-Dpassword=hidden", true);
  132. // By default, does not escape %VAR%
  133. assertThat(builder.toWindowsCommand().toString(), is("cmd.exe /C \"ant.bat -Dfoo1=abc \"\"-Dfoo2=foo bar\"\" \"-Dfoo3=/u*r\" \"-Dfoo4=/us?\" \"-Dfoo10=bar,baz\" \"-Dfoo5=foo;bar^baz\" \"-Dfoo6=<xml>&here;</xml>\" \"-Dfoo7=foo|bar\"\"baz\" \"\"-Dfoo8=% %QED% %comspec% %-%(%.%\"\" -Dfoo9=%'''%%@% ****** && exit %%ERRORLEVEL%%\"" ));
  134. // Pass flag to escape %VAR%
  135. assertThat(builder.toWindowsCommand(true).toString(), is("cmd.exe /C \"ant.bat -Dfoo1=abc \"\"-Dfoo2=foo bar\"\" \"-Dfoo3=/u*r\" \"-Dfoo4=/us?\" \"-Dfoo10=bar,baz\" \"-Dfoo5=foo;bar^baz\" \"-Dfoo6=<xml>&here;</xml>\" \"-Dfoo7=foo|bar\"\"baz\" \"\"-Dfoo8=% %\"Q\"ED% %\"c\"omspec% %-%(%.%\"\" -Dfoo9=%'''%%@% ****** && exit %%ERRORLEVEL%%\""));
  136. }
  137. @Test
  138. public void assertMaskOnClone() {
  139. ArgumentListBuilder builder = new ArgumentListBuilder();
  140. builder.add("arg1");
  141. builder.addMasked("masked1");
  142. builder.add("arg2");
  143. ArgumentListBuilder clone = builder.clone();
  144. assertTrue("There should be masked arguments", clone.hasMaskedArguments());
  145. boolean[] array = clone.toMaskArray();
  146. assertNotNull("The mask array should not be null", array);
  147. assertThat("The mask array was incorrect", array, is(builder.toMaskArray()));
  148. }
  149. private static final Map<String, String> KEY_VALUES = new HashMap<String, String>() {{
  150. put("key1", "value1");
  151. put("key2", "value2");
  152. put("key3", "value3");
  153. }};
  154. private static final Set<String> MASKS = new HashSet<String>() {{
  155. add("key2");
  156. }};
  157. @Test
  158. public void assertKeyValuePairsWithMask() {
  159. ArgumentListBuilder builder = new ArgumentListBuilder();
  160. builder.addKeyValuePairs(null, KEY_VALUES, MASKS);
  161. assertTrue("There should be masked arguments", builder.hasMaskedArguments());
  162. boolean[] array = builder.toMaskArray();
  163. assertNotNull("The mask array should not be null", array);
  164. assertThat("The mask array was incorrect", array, is(new boolean[] { false, true, false }));
  165. }
  166. @Test
  167. public void assertKeyValuePairs() {
  168. ArgumentListBuilder builder = new ArgumentListBuilder();
  169. builder.addKeyValuePairs(null, KEY_VALUES);
  170. assertFalse("There should not be any masked arguments", builder.hasMaskedArguments());
  171. boolean[] array = builder.toMaskArray();
  172. assertNotNull("The mask array should not be null", array);
  173. assertThat("The mask array was incorrect", array, is(new boolean[] { false, false, false }));
  174. }
  175. @Test
  176. public void addKeyValuePairsFromPropertyString() throws IOException {
  177. final Map<String, String> map = new HashMap<String, String>();
  178. map.put("PATH", "C:\\Windows");
  179. final VariableResolver<String> resolver = new VariableResolver.ByMap<String>(map);
  180. final String properties = "my.path=$PATH";
  181. ArgumentListBuilder builder = new ArgumentListBuilder();
  182. builder.addKeyValuePairsFromPropertyString("", properties, resolver);
  183. assertEquals("my.path=C:\\Windows", builder.toString());
  184. builder = new ArgumentListBuilder();
  185. builder.addKeyValuePairsFromPropertyString("", properties, resolver, null);
  186. assertEquals("my.path=C:\\Windows", builder.toString());
  187. }
  188. @Test
  189. public void numberOfBackslashesInPropertiesShouldBePreservedAfterMacroExpansion() throws IOException {
  190. final Map<String, String> map = new HashMap<String, String>();
  191. map.put("ONE", "one\\backslash");
  192. map.put("TWO", "two\\\\backslashes");
  193. map.put("FOUR", "four\\\\\\\\backslashes");
  194. final String properties = new StringBuilder()
  195. .append("one=$ONE\n")
  196. .append("two=$TWO\n")
  197. .append("four=$FOUR\n")
  198. .toString()
  199. ;
  200. final String args = new ArgumentListBuilder()
  201. .addKeyValuePairsFromPropertyString("", properties, new VariableResolver.ByMap<String>(map))
  202. .toString()
  203. ;
  204. assertThat(args, containsString("one=one\\backslash"));
  205. assertThat(args, containsString("two=two\\\\backslashes"));
  206. assertThat(args, containsString("four=four\\\\\\\\backslashes"));
  207. }
  208. }