View Javadoc

1   /*
2    * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3    * the spring framework, http://el4j.sf.net
4    * Copyright (C) 2005 by ELCA Informatique SA, Av. de la Harpe 22-24,
5    * 1000 Lausanne, Switzerland, http://www.elca.ch
6    *
7    * EL4J is published under the GNU Lesser General Public License (LGPL)
8    * Version 2.1. See http://www.gnu.org/licenses/
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU Lesser General Public License for more details.
14   *
15   * For alternative licensing, please contact info@elca.ch
16   */
17  
18  package ch.elca.el4j.tests.services.exceptionhandler;
19  
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.fail;
22  
23  import org.junit.Test;
24  import org.springframework.context.ApplicationContext;
25  
26  import ch.elca.el4j.core.context.ModuleApplicationContext;
27  
28  // Checkstyle: MagicNumber off
29  // Checkstyle: EmptyBlock off
30  
31  /**
32   * This class tests the security facade.
33   *
34   * @svnLink $Revision: 3883 $;$Date: 2009-08-04 15:35:01 +0200 (Di, 04. Aug 2009) $;$Author: swismer $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/modules/exception_handling/src/test/java/ch/elca/el4j/tests/services/exceptionhandler/SafetyFacadeTest.java $
35   *
36   * @author Andreas Bur (ABU)
37   */
38  public class SafetyFacadeTest {
39  
40  	/** The application context. */
41  	private ApplicationContext m_appContext;
42  	
43  	/** The bean that is guarded by the security facade. */
44  	private A m_a;
45  	
46  	/** The bare bean. */
47  	private A m_unsafeA;
48  	
49  	/**
50  	 * Default constructor.
51  	 */
52  	public SafetyFacadeTest() {
53  		m_appContext = new ModuleApplicationContext(
54  			"scenarios/services/exceptionhandler/safetyFacadeTest.xml", false);
55  		
56  		m_a = (A) m_appContext.getBean("A");
57  		m_unsafeA = (A) m_appContext.getBean("unsafeA");
58  	}
59  	
60  	/**
61  	 * Checks on the guarded bean that no exception is thrown and that the
62  	 * result is converted correctly.
63  	 */
64  	@Test
65  	public void testA() {
66  		try {
67  			int result = m_a.div(1, 0);
68  			assertEquals("null was not transformed to 0.", 0, result);
69  		} catch (Throwable t) {
70  			fail("Caught exception although it wasn't expected. " + t);
71  		}
72  	}
73  
74  	/**
75  	 * Checks that the bare bean is still available.
76  	 */
77  	@Test
78  	public void testUnsafeA() {
79  		try {
80  			m_unsafeA.div(1, 0);
81  			fail("Didn't catch any exception.");
82  		} catch (ArithmeticException ae) {
83  			// expected
84  		} catch (Throwable t) {
85  			fail("Caught wrong exception: " + t);
86  		}
87  	}
88  	
89  	/**
90  	 * Checks that an runtime exception is consumed by the security facade.
91  	 */
92  	@Test
93  	public void testRTException() {
94  		try {
95  			m_a.throwRTException();
96  		} catch (Throwable t) {
97  			fail("Caught exception although it wasn't expected. " + t);
98  		}
99  	}
100 	
101 	/**
102 	 * Tests whether the checked application exception is forwarded correctly.
103 	 */
104 	@Test
105 	public void testForwardInterfaceExceptions() {
106 		try {
107 			m_a.throwException();
108 		} catch (ApplicationException ae) {
109 			// expected
110 		} catch (RuntimeException re) {
111 			fail("Expected ApplicationException but caught RunitmeException.");
112 		} catch (Throwable t) {
113 			fail("Expected RuntimeException but caught another one: " + t);
114 		}
115 	}
116 	
117 	/**
118 	 * Tests the reconfiguration of a bean. A delegates add invocations to
119 	 * bean B, which throws an unsupported operation exception. After that, A is
120 	 * reconfigured to use C.
121 	 *
122 	 * <p/>First, we check that B and C are called exactly once. From now on,
123 	 * A is configured to use C. A subsequent call does not touch B at all,
124 	 * which is tested after the counters are reset.
125 	 */
126 	@Test
127 	public void testReconfigurationExceptionHandler() {
128 		int result = 0;
129 		try {
130 			result = m_a.add(4, 5);
131 		} catch (Throwable t) {
132 			fail("Caught exception although it wasn't expected. " + t);
133 		}
134 		assertEquals("Wrongly added (first call).", 9, result);
135 		assertEquals("Called wrong method (B, first call)",
136 				1, B.s_numberOfAddCalls);
137 		assertEquals("Called wrong method (C, first call)",
138 				1, C.s_numberOfAddCalls);
139 		
140 		B.reset();
141 		C.reset();
142 		
143 		result = m_a.add(4, 5);
144 		assertEquals("Wrongly added (second call).", 9, result);
145 		assertEquals("Called wrong method (B, second call)",
146 				0, B.s_numberOfAddCalls);
147 		assertEquals("Called wrong method (C, second call)",
148 				1, C.s_numberOfAddCalls);
149 	}
150 	
151 	/**
152 	 * Tests the round robin exception handler. First, the call on A fails
153 	 * letting the system switch to B. Then, B will be called directly (the
154 	 * proxy's target has been changed). In the third test it's assured that
155 	 * the round robin really cycles back to A and in the last round we just
156 	 * make sure that A is again referenced by the proxy as its target.
157 	 */
158 	@Test
159 	public void testRoundRobinExceptonHandler() {
160 		String foo = "foo";
161 		String bar = "bar";
162 		String result = null;
163 		try {
164 			result = m_a.concat(foo, bar);
165 		} catch (Throwable t) {
166 			fail("Caught exception although it wasn't expected. " + t);
167 		}
168 		assertEquals("Strings are badly concatenated (first call).",
169 				foo.concat(bar), result);
170 		assertEquals("Called wrong method (A, first call)",
171 				1, AImpl.s_numberOfConcatCalls);
172 		assertEquals("Called wrong method (B, first call)",
173 				1, B.s_numberOfConcatCalls);
174 		
175 		AImpl.reset();
176 		B.reset();
177 		
178 		// now we should use B
179 		result = m_a.concat(foo, bar);
180 		assertEquals("Strings are badly concatenated (second call).",
181 				foo.concat(bar), result);
182 		assertEquals("Called wrong method (A, second call)",
183 				0, AImpl.s_numberOfConcatCalls);
184 		assertEquals("Called wrong method (B, second call)",
185 				1, B.s_numberOfConcatCalls);
186 		
187 		AImpl.reset(); AImpl.s_concatFails = false;
188 		B.reset(); B.s_concatFails = true;
189 		
190 		// call B which fails, call A
191 		result = m_a.concat(foo, bar);
192 		assertEquals("Strings are badly concatenated (third call).",
193 				foo.concat(bar), result);
194 		assertEquals("Called wrong method (A, third call)",
195 				1, AImpl.s_numberOfConcatCalls);
196 		assertEquals("Called wrong method (B, third call)",
197 				1, B.s_numberOfConcatCalls);
198 		
199 		AImpl.reset(); AImpl.s_concatFails = false;
200 		B.reset(); B.s_concatFails = true;
201 		
202 		// finally we should use A
203 		result = m_a.concat(foo, bar);
204 		assertEquals("Strings are badly concatenated (fourth call).",
205 				foo.concat(bar), result);
206 		assertEquals("Called wrong method (A, fourth call)",
207 				1, AImpl.s_numberOfConcatCalls);
208 		assertEquals("Called wrong method (B, fourth call)",
209 				0, B.s_numberOfConcatCalls);
210 	}
211 	
212 	/**
213 	 * Tests the retry exception handler. First we check that it retries several
214 	 * times without exceeding the specified number of maximum retries. Then
215 	 * the number of retries is increased and the invocation is expected to
216 	 * fail, as tested in the second part.
217 	 */
218 	@Test
219 	public void testRetry() {
220 		int result = 0;
221 		try {
222 			result = m_a.sub(10, 8);
223 		} catch (IllegalArgumentException rt) {
224 			fail("Caught unexpected IllegalArgumentException.");
225 		}
226 		assertEquals("Calculated wrong value (first call)", 2, result);
227 		
228 		m_a.setRetries(6);
229 		try {
230 			m_a.sub(10, 8);
231 			fail("Didn't caught the expected IllegalArgumentException"
232 					+ "(second call).");
233 		} catch (IllegalArgumentException rt) {
234 			// expected
235 		} catch (Throwable t) {
236 			fail("Caught unexpected exception (second call): " + t);
237 		}
238 	}
239 }
240 //Checkstyle: MagicNumber on
241 //Checkstyle: EmptyBlock on