You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ProjectTest.java 14 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package org.apache.tools.ant;
  19. import org.apache.tools.ant.input.DefaultInputHandler;
  20. import org.apache.tools.ant.input.InputHandler;
  21. import org.apache.tools.ant.input.PropertyFileInputHandler;
  22. import org.apache.tools.ant.taskdefs.condition.Os;
  23. import java.io.File;
  24. import org.apache.tools.ant.types.FileSet;
  25. import org.apache.tools.ant.types.Path;
  26. import org.apache.tools.ant.types.PatternSet;
  27. import org.junit.Before;
  28. import org.junit.Rule;
  29. import org.junit.Test;
  30. import static org.apache.tools.ant.AntAssert.assertContains;
  31. import static org.junit.Assert.assertEquals;
  32. import static org.junit.Assert.assertNotNull;
  33. import static org.junit.Assert.assertNull;
  34. import static org.junit.Assert.assertSame;
  35. import static org.junit.Assert.assertTrue;
  36. import static org.junit.Assert.fail;
  37. /**
  38. * Very limited test class for Project. Waiting to be extended.
  39. *
  40. */
  41. public class ProjectTest {
  42. @Rule
  43. public BuildFileRule buildRule = new BuildFileRule();
  44. private Project p;
  45. private String root;
  46. private MockBuildListener mbl;
  47. @Before
  48. public void setUp() {
  49. p = new Project();
  50. p.init();
  51. root = new File(File.separator).getAbsolutePath().toUpperCase();
  52. mbl = new MockBuildListener(p);
  53. }
  54. @Test
  55. public void testDataTypes() throws BuildException {
  56. assertNull("dummy is not a known data type",
  57. p.createDataType("dummy"));
  58. Object o = p.createDataType("fileset");
  59. assertNotNull("fileset is a known type", o);
  60. assertTrue("fileset creates FileSet", o instanceof FileSet);
  61. assertTrue("PatternSet",
  62. p.createDataType("patternset") instanceof PatternSet);
  63. assertTrue("Path", p.createDataType("path") instanceof Path);
  64. }
  65. /**
  66. * This test has been a starting point for moving the code to FileUtils.
  67. */
  68. @Test
  69. public void testResolveFile() {
  70. if (Os.isFamily("netware") || Os.isFamily("dos")) {
  71. assertEqualsIgnoreDriveCase(localize(File.separator),
  72. p.resolveFile("/", null).getPath());
  73. assertEqualsIgnoreDriveCase(localize(File.separator),
  74. p.resolveFile("\\", null).getPath());
  75. /*
  76. * throw in drive letters
  77. */
  78. String driveSpec = "C:";
  79. String driveSpecLower = "c:";
  80. assertEqualsIgnoreDriveCase(driveSpecLower + "\\",
  81. p.resolveFile(driveSpec + "/", null).getPath());
  82. assertEqualsIgnoreDriveCase(driveSpecLower + "\\",
  83. p.resolveFile(driveSpec + "\\", null).getPath());
  84. assertEqualsIgnoreDriveCase(driveSpecLower + "\\",
  85. p.resolveFile(driveSpecLower + "/", null).getPath());
  86. assertEqualsIgnoreDriveCase(driveSpecLower + "\\",
  87. p.resolveFile(driveSpecLower + "\\", null).getPath());
  88. /*
  89. * promised to eliminate consecutive slashes after drive letter.
  90. */
  91. assertEqualsIgnoreDriveCase(driveSpec + "\\",
  92. p.resolveFile(driveSpec + "/////", null).getPath());
  93. assertEqualsIgnoreDriveCase(driveSpec + "\\",
  94. p.resolveFile(driveSpec + "\\\\\\\\\\\\", null).getPath());
  95. } else {
  96. /*
  97. * Start with simple absolute file names.
  98. */
  99. assertEquals(File.separator,
  100. p.resolveFile("/", null).getPath());
  101. assertEquals(File.separator,
  102. p.resolveFile("\\", null).getPath());
  103. /*
  104. * drive letters are not used, just to be considered as normal
  105. * part of a name
  106. */
  107. String driveSpec = "C:";
  108. String udir = System.getProperty("user.dir") + File.separatorChar;
  109. assertEquals(udir + driveSpec,
  110. p.resolveFile(driveSpec + "/", null).getPath());
  111. assertEquals(udir + driveSpec,
  112. p.resolveFile(driveSpec + "\\", null).getPath());
  113. String driveSpecLower = "c:";
  114. assertEquals(udir + driveSpecLower,
  115. p.resolveFile(driveSpecLower + "/", null).getPath());
  116. assertEquals(udir + driveSpecLower,
  117. p.resolveFile(driveSpecLower + "\\", null).getPath());
  118. }
  119. /*
  120. * Now test some relative file name magic.
  121. */
  122. assertEquals(localize("/1/2/3/4"),
  123. p.resolveFile("4", new File(localize("/1/2/3"))).getPath());
  124. assertEquals(localize("/1/2/3/4"),
  125. p.resolveFile("./4", new File(localize("/1/2/3"))).getPath());
  126. assertEquals(localize("/1/2/3/4"),
  127. p.resolveFile(".\\4", new File(localize("/1/2/3"))).getPath());
  128. assertEquals(localize("/1/2/3/4"),
  129. p.resolveFile("./.\\4", new File(localize("/1/2/3"))).getPath());
  130. assertEquals(localize("/1/2/3/4"),
  131. p.resolveFile("../3/4", new File(localize("/1/2/3"))).getPath());
  132. assertEquals(localize("/1/2/3/4"),
  133. p.resolveFile("..\\3\\4", new File(localize("/1/2/3"))).getPath());
  134. assertEquals(localize("/1/2/3/4"),
  135. p.resolveFile("../../5/.././2/./3/6/../4", new File(localize("/1/2/3"))).getPath());
  136. assertEquals(localize("/1/2/3/4"),
  137. p.resolveFile("..\\../5/..\\./2/./3/6\\../4", new File(localize("/1/2/3"))).getPath());
  138. }
  139. /**
  140. * adapt file separators to local conventions
  141. */
  142. private String localize(String path) {
  143. path = root + path.substring(1);
  144. return path.replace('\\', File.separatorChar).replace('/', File.separatorChar);
  145. }
  146. /**
  147. * convenience method
  148. * the drive letter is in lower case under cygwin
  149. * calling this method allows tests where FileUtils.normalize
  150. * is called via resolveFile to pass under cygwin
  151. */
  152. private void assertEqualsIgnoreDriveCase(String s1, String s2) {
  153. if ((Os.isFamily("dos") || Os.isFamily("netware"))
  154. && s1.length() >= 1 && s2.length() >= 1) {
  155. StringBuilder sb1 = new StringBuilder(s1);
  156. StringBuilder sb2 = new StringBuilder(s2);
  157. sb1.setCharAt(0, Character.toUpperCase(s1.charAt(0)));
  158. sb2.setCharAt(0, Character.toUpperCase(s2.charAt(0)));
  159. assertEquals(sb1.toString(), sb2.toString());
  160. } else {
  161. assertEquals(s1, s2);
  162. }
  163. }
  164. private void assertTaskDefFails(final Class taskClass,
  165. final String message) {
  166. final String dummyName = "testTaskDefinitionDummy";
  167. try {
  168. mbl.addBuildEvent(message, Project.MSG_ERR);
  169. p.addTaskDefinition(dummyName, taskClass);
  170. fail(String.format("expected BuildException(\"%s\", Project.MSG_ERR) when adding task %s",
  171. message, taskClass));
  172. } catch (BuildException e) {
  173. assertEquals(message, e.getMessage());
  174. mbl.assertEmpty();
  175. assertTrue(!p.getTaskDefinitions().containsKey(dummyName));
  176. }
  177. }
  178. @Test
  179. public void testAddTaskDefinition() {
  180. p.addBuildListener(mbl);
  181. p.addTaskDefinition("Ok", DummyTaskOk.class);
  182. assertEquals(DummyTaskOk.class, p.getTaskDefinitions().get("Ok"));
  183. p.addTaskDefinition("OkNonTask", DummyTaskOkNonTask.class);
  184. assertEquals(DummyTaskOkNonTask.class, p.getTaskDefinitions().get("OkNonTask"));
  185. mbl.assertEmpty();
  186. assertTaskDefFails(DummyTaskPrivate.class,
  187. DummyTaskPrivate.class + " is not public");
  188. assertTaskDefFails(DummyTaskProtected.class,
  189. DummyTaskProtected.class + " is not public");
  190. assertTaskDefFails(DummyTaskPackage.class,
  191. DummyTaskPackage.class + " is not public");
  192. assertTaskDefFails(DummyTaskAbstract.class,
  193. DummyTaskAbstract.class + " is abstract");
  194. assertTaskDefFails(DummyTaskInterface.class,
  195. DummyTaskInterface.class + " is abstract");
  196. assertTaskDefFails(DummyTaskWithoutDefaultConstructor.class,
  197. "No public no-arg constructor in " + DummyTaskWithoutDefaultConstructor.class);
  198. assertTaskDefFails(DummyTaskWithoutPublicConstructor.class,
  199. "No public no-arg constructor in " + DummyTaskWithoutPublicConstructor.class);
  200. assertTaskDefFails(DummyTaskWithoutExecute.class,
  201. "No public execute() in " + DummyTaskWithoutExecute.class);
  202. assertTaskDefFails(DummyTaskWithNonPublicExecute.class,
  203. "No public execute() in " + DummyTaskWithNonPublicExecute.class);
  204. mbl.addBuildEvent("return type of execute() should be void but was \"int\" in "
  205. + DummyTaskWithNonVoidExecute.class, Project.MSG_WARN);
  206. p.addTaskDefinition("NonVoidExecute", DummyTaskWithNonVoidExecute.class);
  207. mbl.assertEmpty();
  208. assertEquals(DummyTaskWithNonVoidExecute.class, p.getTaskDefinitions().get("NonVoidExecute"));
  209. }
  210. @Test
  211. public void testInputHandler() {
  212. InputHandler ih = p.getInputHandler();
  213. assertNotNull(ih);
  214. assertTrue(ih instanceof DefaultInputHandler);
  215. InputHandler pfih = new PropertyFileInputHandler();
  216. p.setInputHandler(pfih);
  217. assertSame(pfih, p.getInputHandler());
  218. }
  219. @Test
  220. public void testTaskDefinitionContainsKey() {
  221. assertTrue(p.getTaskDefinitions().containsKey("echo"));
  222. }
  223. @Test
  224. public void testTaskDefinitionContains() {
  225. assertTrue(p.getTaskDefinitions().contains(org.apache.tools.ant.taskdefs.Echo.class));
  226. }
  227. @Test
  228. public void testDuplicateTargets() {
  229. // fail, because buildfile contains two targets with the same name
  230. try {
  231. buildRule.configureProject("src/etc/testcases/core/duplicate-target.xml");
  232. fail("Should throw BuildException about duplicate target");
  233. } catch (BuildException ex) {
  234. assertEquals("specific message",
  235. "Duplicate target 'twice'",
  236. ex.getMessage());
  237. }
  238. }
  239. @Test
  240. public void testDuplicateTargetsImport() {
  241. // overriding target from imported buildfile is allowed
  242. buildRule.configureProject("src/etc/testcases/core/duplicate-target2.xml");
  243. buildRule.executeTarget("once");
  244. assertContains("once from buildfile", buildRule.getLog());
  245. }
  246. @Test
  247. public void testOutputDuringMessageLoggedIsSwallowed()
  248. throws InterruptedException {
  249. final String FOO = "foo", BAR = "bar";
  250. p.addBuildListener(new BuildListener() {
  251. public void buildStarted(BuildEvent event) {
  252. }
  253. public void buildFinished(BuildEvent event) {
  254. }
  255. public void targetStarted(BuildEvent event) {
  256. }
  257. public void targetFinished(BuildEvent event) {
  258. }
  259. public void taskStarted(BuildEvent event) {
  260. }
  261. public void taskFinished(BuildEvent event) {
  262. }
  263. public void messageLogged(final BuildEvent actual) {
  264. assertEquals(FOO, actual.getMessage());
  265. // each of the following lines would cause an
  266. // infinite loop if the message wasn't swallowed
  267. System.err.println(BAR);
  268. System.out.println(BAR);
  269. p.log(BAR, Project.MSG_INFO);
  270. }
  271. });
  272. final boolean[] done = new boolean[] {false};
  273. Thread t = new Thread() {
  274. public void run() {
  275. p.log(FOO, Project.MSG_INFO);
  276. done[0] = true;
  277. }
  278. };
  279. t.start();
  280. t.join(2000);
  281. assertTrue("Expected logging thread to finish successfully", done[0]);
  282. }
  283. /**
  284. * @see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=47623">
  285. * https://issues.apache.org/bugzilla/show_bug.cgi?id=47623</a>
  286. */
  287. @Test
  288. public void testNullThrowableMessageLog() {
  289. p.log(new Task() {}, null, new Throwable(), Project.MSG_ERR);
  290. // be content if no exception has been thrown
  291. }
  292. private class DummyTaskPrivate extends Task {
  293. @SuppressWarnings("unused")
  294. public DummyTaskPrivate() {
  295. }
  296. public void execute() {
  297. }
  298. }
  299. protected class DummyTaskProtected extends Task {
  300. public DummyTaskProtected() {
  301. }
  302. public void execute() {
  303. }
  304. }
  305. class DummyTaskPackage extends Task {
  306. public DummyTaskPackage() {
  307. }
  308. public void execute() {
  309. }
  310. }
  311. }