1 /*
2 * ========================================================================
3 *
4 * Copyright 2003 The Apache Software Foundation.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * 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, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * ========================================================================
19 */
20 package org.apache.cactus.integration.ant;
21
22 import java.io.File;
23 import java.util.Iterator;
24
25 import org.apache.tools.ant.BuildException;
26 import org.apache.tools.ant.Project;
27 import org.codehaus.cargo.module.webapp.DefaultWarArchive;
28 import org.codehaus.cargo.module.webapp.WarArchive;
29 import org.codehaus.cargo.module.webapp.WebXml;
30 import org.codehaus.cargo.module.webapp.WebXmlTag;
31 import org.codehaus.cargo.module.webapp.WebXmlVersion;
32 import org.codehaus.cargo.module.webapp.weblogic.WeblogicXml;
33 import org.codehaus.cargo.module.webapp.weblogic.WeblogicXmlTag;
34 import org.w3c.dom.Element;
35 import org.w3c.dom.NodeList;
36
37 /**
38 * Unit tests for {@link CactifyWarTask}.
39 *
40 * TODO: test whether all files contained by the source WAR are also added to
41 * the cactified WAR
42 * TODO: test whether the mergewebxml is actually merged into the cactified
43 * web.xml
44 *
45 * @version $Id: TestCactifyWarTask.java,v 1.25 2005/04/26 09:57:59 grimsell Exp $
46 */
47 public final class TestCactifyWarTask extends AntTestCase
48 {
49
50 // Constructors ------------------------------------------------------------
51
52 /**
53 * @see AntTestCase#AntTestCase
54 */
55 public TestCactifyWarTask()
56 {
57 super("org/apache/cactus/integration/ant/test-cactifywar.xml");
58 }
59
60 // TestCase Implementation -------------------------------------------------
61
62 /**
63 * @see junit.framework.TestCase#setUp()
64 */
65 protected void setUp() throws Exception
66 {
67 super.setUp();
68
69 getProject().addTaskDefinition("cactifywar", CactifyWarTask.class);
70 }
71
72 // Test Methods ------------------------------------------------------------
73
74 /**
75 * Verifies that the task throws an exception when neither the srcfile
76 * nor the version attribute has been set.
77 *
78 * @throws Exception If an unexpected error occurs
79 */
80 public void testNeitherSrcFileNorVersionSet() throws Exception
81 {
82 try
83 {
84 executeTestTarget();
85 fail("Expected BuildException");
86 }
87 catch (BuildException expected)
88 {
89 assertEquals("You need to specify either the [srcfile] or the "
90 + "[version] attribute", expected.getMessage());
91 }
92 }
93
94 /**
95 * Verifies that the task throws an exception when the destfile attribute
96 * has not been set.
97 *
98 * @throws Exception If an unexpected error occurs
99 */
100 public void testDestFileNotSet() throws Exception
101 {
102 try
103 {
104 executeTestTarget();
105 fail("Expected BuildException");
106 }
107 catch (BuildException expected)
108 {
109 assertEquals("You must specify the war file to create!",
110 expected.getMessage());
111 }
112 }
113
114 /**
115 * Verifies the error raised when the source archive does not contain a web
116 * deployment descriptor.
117 *
118 * @throws Exception If an unexpected error occurs
119 */
120 public void testSrcFileWithoutWebXml() throws Exception
121 {
122 try
123 {
124 executeTestTarget();
125 fail("Expected BuildException");
126 }
127 catch (BuildException expected)
128 {
129 assertEquals("You need to specify either the [srcfile] or the "
130 + "[version] attribute",
131 expected.getMessage());
132 }
133 }
134
135 /**
136 * Verifies an empty web was created when the source archive does not
137 * contain a web deployment descriptor but specifies the version.
138 *
139 * @throws Exception If an unexpected error occurs
140 */
141 public void testSrcFileWithoutWebXmlNewWebXml22() throws Exception
142 {
143 try
144 {
145 executeTestTarget();
146 }
147 catch (BuildException e)
148 {
149 fail("The WAR source file does not contain a "
150 + "WEB-INF/web.xml deployment descriptor, but Cactus "
151 + "should have created an empty one");
152 }
153 }
154
155 /**
156 * Verifies an empty web was created when the source archive does not
157 * contain a web deployment descriptor but specifies the version.
158 *
159 * @throws Exception If an unexpected error occurs
160 */
161 public void testSrcFileWithoutWebXmlNewWebXml23() throws Exception
162 {
163 try
164 {
165 executeTestTarget();
166 }
167 catch (BuildException e)
168 {
169 fail("The WAR source file does not contain a "
170 + "WEB-INF/web.xml deployment descriptor, but Cactus "
171 + "should have created an empty one");
172 }
173 }
174
175 /**
176 * Tests whether the Cactus test redirectors are correctly added to the
177 * descriptor of the cactified WAR.
178 *
179 * @throws Exception If an unexpected error occurs
180 */
181 public void testDefaultRedirectorsNoDoctype() throws Exception
182 {
183 executeTestTarget();
184
185 File destFile = getProject().resolveFile("work/destfile.war");
186 WarArchive destWar = new DefaultWarArchive(destFile);
187 WebXml webXml = destWar.getWebXml();
188 assertNull("The web.xml should not have a version specified",
189 webXml.getVersion());
190 assertServletMapping(webXml,
191 "org.apache.cactus.server.ServletTestRedirector",
192 "ServletRedirector",
193 "/ServletRedirector");
194 assertJspMapping(webXml, "/jspRedirector.jsp", "JspRedirector",
195 "/JspRedirector");
196 // As the deployment descriptor in the source WAR doesn't contain a
197 // DOCTYPE, it is assumed to be a version 2.2 descriptor. Thus it
198 // should not contain a definition of the filter test redirector.
199 // Assert that.
200 assertTrue("Filter test redirector should not have been defined",
201 !webXml.getFilterNames().hasNext());
202 }
203
204 /**
205 * Tests whether the Cactus test redirectors are correctly added to the
206 * descriptor of the cactified WAR.
207 *
208 * @throws Exception If an unexpected error occurs
209 */
210 public void testDefaultRedirectors22Doctype() throws Exception
211 {
212 executeTestTarget();
213
214 File destFile = getProject().resolveFile("work/destfile.war");
215 WarArchive destWar = new DefaultWarArchive(destFile);
216 WebXml webXml = destWar.getWebXml();
217 assertEquals(WebXmlVersion.V2_2, webXml.getVersion());
218 assertServletMapping(webXml,
219 "org.apache.cactus.server.ServletTestRedirector",
220 "ServletRedirector",
221 "/ServletRedirector");
222 assertJspMapping(webXml, "/jspRedirector.jsp", "JspRedirector",
223 "/JspRedirector");
224 assertTrue("Filter test redirector should not have been defined",
225 !webXml.getFilterNames().hasNext());
226 }
227
228 /**
229 * Tests whether the Cactus test redirectors are correctly added to the
230 * descriptor of the cactified WAR.
231 *
232 * @throws Exception If an unexpected error occurs
233 */
234 public void testDefaultRedirectors23Doctype() throws Exception
235 {
236 executeTestTarget();
237
238 File destFile = getProject().resolveFile("work/destfile.war");
239 WarArchive destWar = new DefaultWarArchive(destFile);
240 WebXml webXml = destWar.getWebXml();
241 assertEquals(WebXmlVersion.V2_3, webXml.getVersion());
242 assertServletMapping(webXml,
243 "org.apache.cactus.server.ServletTestRedirector",
244 "ServletRedirector",
245 "/ServletRedirector");
246 assertJspMapping(webXml, "/jspRedirector.jsp", "JspRedirector",
247 "/JspRedirector");
248 assertFilterMapping(webXml,
249 "org.apache.cactus.server.FilterTestRedirector",
250 "FilterRedirector",
251 "/FilterRedirector");
252 }
253
254 /**
255 * Tests whether the Cactus test redirectors are correctly added to the
256 * descriptor of a WAR when no srcfile attribute had been set, and the
257 * version has been set to 2.2.
258 *
259 * @throws Exception If an unexpected error occurs
260 */
261 public void testDefaultRedirectorsNewWar22() throws Exception
262 {
263 executeTestTarget();
264
265 File destFile = getProject().resolveFile("work/destfile.war");
266 WarArchive destWar = new DefaultWarArchive(destFile);
267 WebXml webXml = destWar.getWebXml();
268 assertEquals(WebXmlVersion.V2_2, webXml.getVersion());
269 assertServletMapping(webXml,
270 "org.apache.cactus.server.ServletTestRedirector",
271 "ServletRedirector",
272 "/ServletRedirector");
273 assertJspMapping(webXml, "/jspRedirector.jsp", "JspRedirector",
274 "/JspRedirector");
275 assertTrue("Filter test redirector should not have been defined",
276 !webXml.getFilterNames().hasNext());
277 }
278
279 /**
280 * Tests whether the Cactus test redirectors are correctly added to the
281 * descriptor of a WAR when no srcfile attribute had been set, and the
282 * version has been set to 2.3.
283 *
284 * @throws Exception If an unexpected error occurs
285 */
286 public void testDefaultRedirectorsNewWar23() throws Exception
287 {
288 executeTestTarget();
289
290 File destFile = getProject().resolveFile("work/destfile.war");
291 WarArchive destWar = new DefaultWarArchive(destFile);
292 WebXml webXml = destWar.getWebXml();
293 assertEquals(WebXmlVersion.V2_3, webXml.getVersion());
294 assertServletMapping(webXml,
295 "org.apache.cactus.server.ServletTestRedirector",
296 "ServletRedirector",
297 "/ServletRedirector");
298 assertJspMapping(webXml, "/jspRedirector.jsp", "JspRedirector",
299 "/JspRedirector");
300 assertFilterMapping(webXml,
301 "org.apache.cactus.server.FilterTestRedirector",
302 "FilterRedirector",
303 "/FilterRedirector");
304 }
305
306 /**
307 * Verifies that the mapping of the servlet redirector is correctly
308 * overridden by a nested 'servletredirector' element.
309 *
310 * @throws Exception If an unexpected error occurs
311 */
312 public void testCustomServletRedirectorMapping() throws Exception
313 {
314 executeTestTarget();
315
316 File destFile = getProject().resolveFile("work/destfile.war");
317 WarArchive destWar = new DefaultWarArchive(destFile);
318 WebXml webXml = destWar.getWebXml();
319 assertServletMapping(webXml,
320 "org.apache.cactus.server.ServletTestRedirector",
321 "ServletRedirector",
322 "/test/servletRedirector");
323 }
324
325 /**
326 * Verifies that the mapping of the JSP redirector is correctly overridden
327 * by a nested 'jspredirector' element.
328 *
329 * @throws Exception If an unexpected error occurs
330 */
331 public void testCustomJspRedirectorMapping() throws Exception
332 {
333 executeTestTarget();
334
335 File destFile = getProject().resolveFile("work/destfile.war");
336 WarArchive destWar = new DefaultWarArchive(destFile);
337 WebXml webXml = destWar.getWebXml();
338 assertJspMapping(webXml, "/jspRedirector.jsp", "JspRedirector",
339 "/test/jspRedirector");
340 }
341
342 /**
343 * Verifies that the mapping of the filter redirector is correctly
344 * overridden by a nested 'filterredirector' element.
345 *
346 * @throws Exception If an unexpected error occurs
347 */
348 public void testCustomFilterRedirectorMapping() throws Exception
349 {
350 executeTestTarget();
351
352 File destFile = getProject().resolveFile("work/destfile.war");
353 WarArchive destWar = new DefaultWarArchive(destFile);
354 WebXml webXml = destWar.getWebXml();
355 assertFilterMapping(webXml,
356 "org.apache.cactus.server.FilterTestRedirector",
357 "FilterRedirector",
358 "/test/filterRedirector");
359 }
360
361 /**
362 * Verifies that no definition of the filter redirector is added to a
363 * Servlet 2.2 descriptor, even when explicitly requested by a nested
364 * 'filterredirector' element.
365 *
366 * @throws Exception If an unexpected error occurs
367 */
368 public void testCustomFilterRedirectorMappingIgnored() throws Exception
369 {
370 executeTestTarget();
371
372 File destFile = getProject().resolveFile("work/destfile.war");
373 WarArchive destWar = new DefaultWarArchive(destFile);
374 WebXml webXml = destWar.getWebXml();
375 assertTrue("The filter redirector should not have been defined",
376 !webXml.getFilterNamesForClass(
377 "org.apache.cactus.server.FilterTestRedirector").hasNext());
378 }
379
380 /**
381 * Verifies that two servlet redirectors with different names and mappings
382 * are added as expected.
383 *
384 * @throws Exception If an unexpected error occurs
385 */
386 public void testMultipleNamedServletRedirectors() throws Exception
387 {
388 executeTestTarget();
389
390 File destFile = getProject().resolveFile("work/destfile.war");
391 WarArchive destWar = new DefaultWarArchive(destFile);
392 WebXml webXml = destWar.getWebXml();
393 assertTrue(webXml.hasServlet("ServletRedirector"));
394 assertEquals("/test/ServletRedirector",
395 webXml.getServletMappings("ServletRedirector").next());
396 assertTrue(webXml.hasServlet("ServletRedirectorSecure"));
397 assertEquals("/test/ServletRedirectorSecure",
398 webXml.getServletMappings("ServletRedirectorSecure").next());
399 }
400
401 /**
402 * Verifies that two JSP redirectors with different names and mappings
403 * are added as expected.
404 *
405 * @throws Exception If an unexpected error occurs
406 */
407 public void testMultipleNamedJspRedirectors() throws Exception
408 {
409 executeTestTarget();
410
411 File destFile = getProject().resolveFile("work/destfile.war");
412 WarArchive destWar = new DefaultWarArchive(destFile);
413 WebXml webXml = destWar.getWebXml();
414 assertTrue(webXml.hasServlet("JspRedirector"));
415 assertEquals("/test/JspRedirector",
416 webXml.getServletMappings("JspRedirector").next());
417 assertTrue(webXml.hasServlet("JspRedirectorSecure"));
418 assertEquals("/test/JspRedirectorSecure",
419 webXml.getServletMappings("JspRedirectorSecure").next());
420 }
421
422 /**
423 * Verifies that two filter redirectors with different names and mappings
424 * are added as expected.
425 *
426 * @throws Exception If an unexpected error occurs
427 */
428 public void testMultipleNamedFilterRedirectors() throws Exception
429 {
430 executeTestTarget();
431
432 File destFile = getProject().resolveFile("work/destfile.war");
433 WarArchive destWar = new DefaultWarArchive(destFile);
434 WebXml webXml = destWar.getWebXml();
435 assertTrue(webXml.hasFilter("FilterRedirector"));
436 assertEquals("/test/FilterRedirector",
437 webXml.getFilterMappings("FilterRedirector").next());
438 assertTrue(webXml.hasFilter("FilterRedirectorSecure"));
439 assertEquals("/test/FilterRedirectorSecure",
440 webXml.getFilterMappings("FilterRedirectorSecure").next());
441 }
442
443 /**
444 * Verifies that a secured servlet redirector gets added alongside the role
445 * names.
446 *
447 * @throws Exception If an unexpected error occurs
448 */
449 public void testSecuredServletRedirector() throws Exception
450 {
451 executeTestTarget();
452
453 File destFile = getProject().resolveFile("work/destfile.war");
454 WarArchive destWar = new DefaultWarArchive(destFile);
455 WebXml webXml = destWar.getWebXml();
456 assertTrue(webXml.hasServlet("ServletRedirectorSecure"));
457 assertEquals("/ServletRedirectorSecure",
458 webXml.getServletMappings("ServletRedirectorSecure").next());
459 assertTrue(webXml.hasSecurityRole("test"));
460 assertTrue(webXml.hasSecurityRole("cactus"));
461 assertTrue(webXml.hasSecurityConstraint("/ServletRedirectorSecure"));
462 Element securityConstraintElement =
463 webXml.getSecurityConstraint("/ServletRedirectorSecure");
464 assertNotNull(securityConstraintElement);
465 Element authConstraintElement = (Element)
466 securityConstraintElement.getElementsByTagName(
467 "auth-constraint").item(0);
468 assertNotNull(authConstraintElement);
469 NodeList roleNameElements =
470 authConstraintElement.getElementsByTagName("role-name");
471 assertEquals(2, roleNameElements.getLength());
472 assertEquals("test",
473 roleNameElements.item(0).getChildNodes().item(0).getNodeValue());
474 assertEquals("cactus",
475 roleNameElements.item(1).getChildNodes().item(0).getNodeValue());
476 Iterator loginConfigElements =
477 webXml.getElements(WebXmlTag.LOGIN_CONFIG);
478 assertTrue(loginConfigElements.hasNext());
479 Element loginConfigElement = (Element) loginConfigElements.next();
480 Element authMethodElement = (Element)
481 loginConfigElement.getElementsByTagName("auth-method").item(0);
482 assertEquals("BASIC",
483 authMethodElement.getChildNodes().item(0).getNodeValue());
484 }
485
486 /**
487 * Verifies that a already existent login configuration does not get
488 * replaced by the default BASIC login configuration when secured
489 * redirectors are defined.
490 *
491 * @throws Exception If an unexpected error occurs
492 */
493 public void testLoginConfigNotOverwritten() throws Exception
494 {
495 executeTestTarget();
496
497 File destFile = getProject().resolveFile("work/destfile.war");
498 WarArchive destWar = new DefaultWarArchive(destFile);
499 WebXml webXml = destWar.getWebXml();
500 assertEquals("FORM", webXml.getLoginConfigAuthMethod());
501 }
502
503 /**
504 * Verifies that JARs already contained by the source archive are not added
505 * again.
506 *
507 * @throws Exception If an unexpected error occurs
508 */
509 public void testNoDuplicateJars() throws Exception
510 {
511 executeTestTarget();
512
513 assertMessageLogged("The AspectJ Runtime JAR is already present in the "
514 + "WAR", Project.MSG_VERBOSE);
515 assertMessageLogged("The Cactus Framework JAR is already present in "
516 + "the WAR", Project.MSG_VERBOSE);
517 assertMessageLogged("The Commons-Logging JAR is already present in the "
518 + "WAR", Project.MSG_VERBOSE);
519 assertMessageLogged("The Commons-HttpClient JAR is already present in "
520 + "the WAR", Project.MSG_VERBOSE);
521 assertMessageLogged("The JUnit JAR is already present in the WAR",
522 Project.MSG_VERBOSE);
523 }
524
525 /**
526 * Tests that ejb refs can be added for weblogic
527 *
528 * @throws Exception iIf an unexpected error occurs
529 */
530 public void testAddWeblogicEjbRefs() throws Exception
531 {
532 executeTestTarget();
533
534 File destFile = getProject().resolveFile("work/destfile.war");
535 WarArchive destWar = new DefaultWarArchive(destFile);
536
537 // test web.xml
538 WebXml webXml = destWar.getWebXml();
539 Iterator i = webXml.getElements(WebXmlTag.EJB_LOCAL_REF);
540 Element e = (Element) i.next();
541 NodeList nl = e.getElementsByTagName("ejb-ref-name");
542 Element f = (Element) nl.item(0);
543 assertEquals("MyEjb", f.getFirstChild().getNodeValue());
544 nl = e.getElementsByTagName("ejb-ref-type");
545 f = (Element) nl.item(0);
546 assertEquals("Session", f.getFirstChild().getNodeValue());
547 nl = e.getElementsByTagName("local-home");
548 f = (Element) nl.item(0);
549 assertEquals("com.wombat.MyEjbHome", f.getFirstChild().getNodeValue());
550 nl = e.getElementsByTagName("local");
551 f = (Element) nl.item(0);
552 assertEquals("com.wombat.MyEjb", f.getFirstChild().getNodeValue());
553
554 // test weblogic.xml
555 WeblogicXml weblogicXml = (WeblogicXml) webXml.getVendorDescriptor();
556 i = weblogicXml.getElements(WeblogicXmlTag.EJB_REFERENCE_DESCRIPTION);
557 e = (Element) i.next();
558 nl = e.getElementsByTagName("ejb-ref-name");
559 f = (Element) nl.item(0);
560 assertEquals("MyEjb", f.getFirstChild().getNodeValue());
561 nl = e.getElementsByTagName("jndi-name");
562 f = (Element) nl.item(0);
563 assertEquals("/wombat/MyEjb", f.getFirstChild().getNodeValue());
564 }
565
566 // Private Methods ---------------------------------------------------------
567
568 /**
569 * Asserts that a filter of the specified class is defined in the given
570 * deployment descriptor and mapped to a specific URL-pattern.
571 *
572 * @param theWebXml The deployment descriptor
573 * @param theFilterClass The name of the filter class
574 * @param theFilterName The name of the filter
575 * @param theMapping The URL-pattern that the filter is expected to be
576 * mapped to
577 */
578 private void assertFilterMapping(WebXml theWebXml, String theFilterClass,
579 String theFilterName, String theMapping)
580 {
581 Iterator names = theWebXml.getFilterNamesForClass(theFilterClass);
582
583 // Look for the definition that matches the JSP servlet name
584 boolean found = false;
585 String name = null;
586 while (names.hasNext())
587 {
588 name = (String) names.next();
589 if (name.equals(theFilterName))
590 {
591 found = true;
592 break;
593 }
594 }
595
596 if (!found)
597 {
598 fail("Definition of [" + theFilterClass + "(" + theFilterName
599 + ")] not found");
600 }
601
602 Iterator mappings = theWebXml.getFilterMappings(name);
603 assertTrue("Mapping for [" + theFilterClass + "(" + theFilterName
604 + ")] not found", mappings.hasNext());
605 assertEquals(theMapping, mappings.next());
606 }
607
608 /**
609 * Asserts that the specified JSP file is defined in the given deployment
610 * descriptor and mapped to a specific URL-pattern.
611 *
612 * @param theWebXml The deployment descriptor
613 * @param theJspFile The JSP file name
614 * @param theJspName The JSP servlet name
615 * @param theMapping The URL-pattern that the JSP file is expected to be
616 * mapped to
617 */
618 private void assertJspMapping(WebXml theWebXml, String theJspFile,
619 String theJspName, String theMapping)
620 {
621 Iterator names = theWebXml.getServletNamesForJspFile(theJspFile);
622
623 // Look for the definition that matches the JSP servlet name
624 boolean found = false;
625 String name = null;
626 while (names.hasNext())
627 {
628 name = (String) names.next();
629 if (name.equals(theJspName))
630 {
631 found = true;
632 break;
633 }
634 }
635
636 if (!found)
637 {
638 fail("Definition of [" + theJspFile + "(" + theJspName
639 + ")] not found");
640 }
641
642 Iterator mappings = theWebXml.getServletMappings(name);
643 assertTrue("Mapping for [" + theJspFile + "(" + theJspName
644 + ")] not found", mappings.hasNext());
645 assertEquals(theMapping, mappings.next());
646 }
647
648 /**
649 * Asserts that a servlet of the specified name is defined in the given
650 * deployment descriptor and mapped to a specific URL-pattern.
651 *
652 * @param theWebXml The deployment descriptor
653 * @param theServletClass The name of servlet class
654 * @param theServletName The name of the servlet
655 * @param theMapping The URL-pattern that the servlet is expected to be
656 * mapped to
657 */
658 private void assertServletMapping(WebXml theWebXml, String theServletClass,
659 String theServletName, String theMapping)
660 {
661 Iterator names = theWebXml.getServletNamesForClass(theServletClass);
662
663 // Look for the definition that matches the servlet name
664 boolean found = false;
665 String name = null;
666 while (names.hasNext())
667 {
668 name = (String) names.next();
669 if (name.equals(theServletName))
670 {
671 found = true;
672 break;
673 }
674 }
675
676 if (!found)
677 {
678 fail("Definition of [" + theServletClass + "(" + theServletName
679 + ")] not found");
680 }
681
682 Iterator mappings = theWebXml.getServletMappings(name);
683 assertTrue("Mapping for [" + theServletClass + "(" + theServletName
684 + ")] not found", mappings.hasNext());
685 assertEquals(theMapping, mappings.next());
686 }
687
688 }