1 /*
2 * ========================================================================
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * ========================================================================
20 */
21 package org.apache.cactus.internal;
22
23 import junit.framework.Test;
24 import junit.framework.TestCase;
25
26 import org.apache.cactus.internal.client.ClientTestCaseCaller;
27 import org.apache.cactus.internal.configuration.ConfigurationInitializer;
28 import org.apache.cactus.internal.server.ServerTestCaseCaller;
29 import org.apache.cactus.internal.util.TestCaseImplementChecker;
30 import org.apache.cactus.spi.client.connector.ProtocolHandler;
31
32 /**
33 * Base class for all Cactus test case extensions.
34 *
35 * Note: We must not add any method that can be called by the end user to this
36 * class as users will those methods and it will create a runtime dependency to
37 * this class. We will then have to break binary compatibility if we wish to
38 * move this class around or change its implementation.
39 *
40 * @version $Id: AbstractCactusTestCase.java 238991 2004-05-22 11:34:50Z vmassol $
41 * @since 1.6
42 */
43 public abstract class AbstractCactusTestCase extends TestCase
44 {
45 /**
46 * As this class is the first one loaded on the client side, we ensure
47 * that the Cactus configuration has been initialized. In the future,
48 * this block will be removed as all initialization will be done in Cactus
49 * test suites. However, as we still support using Cactus TestCase classes
50 * we don't have a proper initialization hook and thus we need this hack.
51 */
52 static
53 {
54 ConfigurationInitializer.initialize();
55 }
56
57 /**
58 * Provides all client side Cactus calling logic.
59 * Note that we are using a delegate class instead of inheritance in order
60 * to hide non public API to the users and thus to be able to easily change
61 * the implementation.
62 */
63 private ClientTestCaseCaller clientCaller;
64
65 /**
66 * Provides all server side Cactus calling logic.
67 * Note that we are using a delegate class instead of inheritance in order
68 * to hide non public API to the users and thus to be able to easily change
69 * the implementation.
70 */
71 private ServerTestCaseCaller serverCaller;
72
73 // Abstract methods -----------------------------------------------------
74
75 /**
76 * Create a protocol handler instance that will be used to connect to the
77 * server side.
78 *
79 * @return the protocol handler instance
80 */
81 protected abstract ProtocolHandler createProtocolHandler();
82
83 // Constructors ---------------------------------------------------------
84
85 /**
86 * Default constructor defined in order to allow creating Test Case
87 * without needing to define constructor (new feature in JUnit 3.8.1).
88 * Should only be used with JUnit 3.8.1 or greater.
89 */
90 public AbstractCactusTestCase()
91 {
92 init(null);
93 }
94
95 /**
96 * Constructs a JUnit test case with the given name.
97 *
98 * @param theName the name of the test case
99 */
100 public AbstractCactusTestCase(String theName)
101 {
102 super(theName);
103 init(null);
104 }
105
106 /**
107 * Wraps a pure JUnit Test Case in a Cactus Test Case.
108 *
109 * @param theName the name of the test
110 * @param theTest the Test Case class to wrap
111 */
112 public AbstractCactusTestCase(String theName, Test theTest)
113 {
114 super(theName);
115 init(theTest);
116 }
117
118 // Public methods -------------------------------------------------------
119
120 /**
121 * JUnit method that is used to run the tests. However, we're intercepting
122 * it so that we can call the server side of Cactus where the tests will
123 * be run (instead of on the client side).
124 *
125 * @exception Throwable if any exception is thrown during the test. Any
126 * exception will be displayed by the JUnit Test Runner
127 */
128 public void runBare() throws Throwable
129 {
130 TestCaseImplementChecker.checkTestName(this);
131 TestCaseImplementChecker.checkTestName(
132 getServerCaller().getWrappedTest());
133
134 runBareClient();
135 }
136
137 /**
138 * {@inheritDoc}
139 * @see CactusTestCase#runBareServer()
140 */
141 public void runBareServer() throws Throwable
142 {
143 getServerCaller().runBareInit();
144
145 // Note: We cannot delegate this piece of code in the
146 // ServerTestCaseDelegate class as it requires to call
147 // super.runBare()
148
149 if (getServerCaller().getWrappedTest() != null)
150 {
151 ((TestCase) getServerCaller().getWrappedTest()).runBare();
152 }
153 else
154 {
155 super.runBare();
156 }
157 }
158
159 // Private methods ------------------------------------------------------
160
161 /**
162 * @param theCaller the client test case calling class
163 */
164 private void setClientCaller(ClientTestCaseCaller theCaller)
165 {
166 this.clientCaller = theCaller;
167 }
168
169 /**
170 * @param theCaller the server test case calling class
171 */
172 private void setServerCaller(ServerTestCaseCaller theCaller)
173 {
174 this.serverCaller = theCaller;
175 }
176
177 /**
178 * @return the client test case caller
179 */
180 private ClientTestCaseCaller getClientCaller()
181 {
182 return this.clientCaller;
183 }
184
185 /**
186 * @return the server test case caller
187 */
188 private ServerTestCaseCaller getServerCaller()
189 {
190 return this.serverCaller;
191 }
192
193 /**
194 * Initializations common to all constructors.
195 *
196 * @param theTest a pure JUnit Test that Cactus will wrap
197 */
198 private void init(Test theTest)
199 {
200 setClientCaller(new ClientTestCaseCaller(this, theTest,
201 createProtocolHandler()));
202 setServerCaller(new ServerTestCaseCaller(this, theTest));
203 }
204
205 /**
206 * Introduced for symmetry with {@link #runBareServer()}.
207 *
208 * {@inheritDoc}
209 * @see #runBare()
210 */
211 private void runBareClient() throws Throwable
212 {
213 getClientCaller().runBareInit();
214
215 // Catch the exception just to have a chance to log it
216 try
217 {
218 getClientCaller().runTest();
219 }
220 catch (Throwable t)
221 {
222 // TODO: Move getLogger to this class instead
223 getClientCaller().getLogger().debug("Exception in test", t);
224 throw t;
225 }
226 }
227 }