1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.struts2;
22
23 import com.opensymphony.xwork2.ActionContext;
24 import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
25 import com.opensymphony.xwork2.inject.Container;
26 import com.opensymphony.xwork2.util.ValueStack;
27 import com.opensymphony.xwork2.util.finder.ClassLoaderInterface;
28 import com.opensymphony.xwork2.util.finder.ClassLoaderInterfaceDelegate;
29 import junit.framework.TestCase;
30 import org.apache.commons.lang.xwork.StringUtils;
31 import org.easymock.EasyMock;
32 import org.easymock.IAnswer;
33 import org.springframework.mock.web.MockHttpServletResponse;
34 import org.springframework.mock.web.MockServletContext;
35
36 import javax.servlet.Servlet;
37 import javax.servlet.http.HttpServletRequest;
38 import javax.servlet.http.HttpSession;
39 import java.io.InputStream;
40 import java.util.ArrayList;
41 import java.util.HashMap;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.concurrent.BrokenBarrierException;
45 import java.util.concurrent.CyclicBarrier;
46
47 public class EmbeddedJSPResultTest extends TestCase {
48 private HttpServletRequest request;
49 private MockHttpServletResponse response;
50 private MockServletContext context;
51 private EmbeddedJSPResult result;
52
53 public void testScriptlet() throws Exception {
54 result.setLocation("org/apache/struts2/scriptlet.jsp");
55 result.execute(null);
56
57 assertEquals("Saynotoscriptlets", StringUtils.deleteWhitespace(response.getContentAsString()));
58 }
59
60 public void testEmbedded() throws Exception {
61
62 result.setLocation("dir/all.jsp");
63 result.execute(null);
64
65 assertEquals("helloJGWhoamI?XXXXXXXXXXXYThissessionisnotsecure.", StringUtils.deleteWhitespace(response.getContentAsString()));
66 }
67
68 public void testFilesAreReadOnlyOnce() throws Exception {
69
70 String jsp = "org/apache/struts2/dont-use.jsp";
71
72 CountingClassLoaderInterface classLoaderInterface = new CountingClassLoaderInterface(this.getClass().getClassLoader());
73 context.setAttribute(ClassLoaderInterface.CLASS_LOADER_INTERFACE, classLoaderInterface);
74 result.setLocation(jsp);
75
76 result.execute(null);
77 Integer counter0 = classLoaderInterface.counters.get(jsp);
78 assertNotNull(counter0);
79
80 result.execute(null);
81 Integer counter1 = classLoaderInterface.counters.get(jsp);
82 assertNotNull(counter1);
83
84 assertEquals(counter0, counter1);
85 }
86
87 public void testEmbeddedAbsolutePath() throws Exception {
88
89 result.setLocation("/dir/all.jsp");
90 result.execute(null);
91
92 assertEquals("helloJGWhoamI?XXXXXXXXXXXYThissessionisnotsecure.", StringUtils.deleteWhitespace(response.getContentAsString()));
93 }
94
95 public void testSimple() throws Exception {
96 result.setLocation("org/apache/struts2/simple0.jsp");
97 result.execute(null);
98
99 assertEquals("hello", response.getContentAsString());
100 }
101
102 public void testEL() throws Exception {
103 result.setLocation("org/apache/struts2/el.jsp");
104 result.execute(null);
105
106 assertEquals("somethingelseText", response.getContentAsString());
107 }
108
109 public void tesAbsolutePatht() throws Exception {
110 result.setLocation("/org/apache/struts2/simple0.jsp");
111 result.execute(null);
112
113 assertEquals("hello", response.getContentAsString());
114 }
115
116 public void testTag0() throws Exception {
117 result.setLocation("org/apache/struts2/tag0.jsp");
118 result.execute(null);
119
120 assertEquals("Thissessionisnotsecure.OtherText", StringUtils.deleteWhitespace(response.getContentAsString()));
121 }
122
123 public void testIncludeSimple() throws Exception {
124 result.setLocation("org/apache/struts2/includes0.jsp");
125 result.execute(null);
126
127 assertEquals("helloTest", StringUtils.deleteWhitespace(response.getContentAsString()));
128 }
129
130 public void testIncludeSimpleWithDirective() throws Exception {
131 result.setLocation("org/apache/struts2/includes3.jsp");
132 result.execute(null);
133
134 assertEquals("helloTest", StringUtils.deleteWhitespace(response.getContentAsString()));
135 }
136
137 public void testIncludeWithSubdir() throws Exception {
138 result.setLocation("org/apache/struts2/includes1.jsp");
139 result.execute(null);
140
141 assertEquals("subTest", StringUtils.deleteWhitespace(response.getContentAsString()));
142 }
143
144 public void testIncludeWithParam() throws Exception {
145 result.setLocation("org/apache/struts2/includes2.jsp");
146 result.execute(null);
147
148 assertEquals("JGTest", StringUtils.deleteWhitespace(response.getContentAsString()));
149 }
150
151 public void testBroken0() throws Exception {
152 try {
153 result.setLocation("org/apache/struts2/broken0.jsp");
154 result.execute(null);
155 fail("should have failed with broken jsp");
156 } catch (IllegalStateException ex) {
157
158 }
159 }
160
161 public void testJSTL() throws Exception {
162 result.setLocation("org/apache/struts2/jstl.jsp");
163 result.execute(null);
164
165 assertEquals("XXXXXXXXXXXY", StringUtils.deleteWhitespace(response.getContentAsString()));
166 }
167
168
169 public void testCachedInstances() throws InterruptedException {
170 ServletCache cache = new ServletCache();
171 Servlet servlet1 = cache.get("org/apache/struts2/simple0.jsp");
172 Servlet servlet2 = cache.get("org/apache/struts2/simple0.jsp");
173
174 assertSame(servlet1, servlet2);
175 }
176
177 public void testCacheInstanceWithManyThreads() throws BrokenBarrierException, InterruptedException {
178
179
180
181
182 DummyServletCache cache = new DummyServletCache();
183 int numThreads = 70;
184
185 CyclicBarrier startBarrier = new CyclicBarrier(numThreads + 1);
186 CyclicBarrier endBarrier = new CyclicBarrier(numThreads + 1);
187
188 List<ServletGetRunnable> runnables = new ArrayList<ServletGetRunnable>(numThreads);
189
190
191 for (int i = 0; i < numThreads; i++) {
192 ServletGetRunnable runnable = new ServletGetRunnable(cache, startBarrier, endBarrier, ActionContext.getContext());
193 Thread thread = new Thread(runnable);
194 runnables.add(runnable);
195 thread.start();
196 }
197
198 startBarrier.await();
199 endBarrier.await();
200 Object servlet = cache.get("org/apache/struts2/simple0.jsp");
201 assertEquals(1, cache.size());
202
203 for (ServletGetRunnable runnable : runnables) {
204 assertSame(servlet, runnable.getObject());
205 }
206 }
207
208 public void testBeans() throws Exception {
209 result.setLocation("org/apache/struts2/beans.jsp");
210 result.execute(null);
211
212 assertEquals("WhoamI?", StringUtils.deleteWhitespace(response.getContentAsString()));
213 }
214
215 @Override
216 protected void setUp() throws Exception {
217 super.setUp();
218
219 result = new EmbeddedJSPResult();
220
221 request = EasyMock.createNiceMock(HttpServletRequest.class);
222 response = new MockHttpServletResponse();
223 context = new MockServletContext();
224
225 final Map params = new HashMap();
226
227 HttpSession session = EasyMock.createNiceMock(HttpSession.class);
228 EasyMock.replay(session);
229
230 EasyMock.expect(request.getSession()).andReturn(session).anyTimes();
231 EasyMock.expect(request.getParameterMap()).andReturn(params).anyTimes();
232 EasyMock.expect(request.getParameter("username")).andAnswer(new IAnswer<String>() {
233 public String answer() throws Throwable {
234 return ((String[]) params.get("username"))[0];
235 }
236 });
237 EasyMock.expect(request.getAttribute("something")).andReturn("somethingelse").anyTimes();
238
239 EasyMock.replay(request);
240
241 ActionContext actionContext = new ActionContext(new HashMap<String, Object>());
242 ActionContext.setContext(actionContext);
243 actionContext.setParameters(params);
244 ServletActionContext.setRequest(request);
245 ServletActionContext.setResponse(response);
246 ServletActionContext.setServletContext(context);
247
248
249 Map stackContext = new HashMap();
250 ValueStack valueStack = EasyMock.createNiceMock(ValueStack.class);
251 EasyMock.expect(valueStack.getContext()).andReturn(stackContext).anyTimes();
252 EasyMock.replay(valueStack);
253
254
255 XWorkConverter converter = new DummyConverter();
256
257
258 Container container = EasyMock.createNiceMock(Container.class);
259 EasyMock.expect(container.getInstance(XWorkConverter.class)).andReturn(converter).anyTimes();
260 EasyMock.replay(container);
261 stackContext.put(ActionContext.CONTAINER, container);
262 actionContext.setContainer(container);
263
264 actionContext.setValueStack(valueStack);
265 }
266 }
267
268
269 class DummyConverter extends XWorkConverter {
270
271 }
272
273 class DummyServletCache extends ServletCache {
274 public int size() {
275 return cache.size();
276 }
277 }
278
279 class ServletGetRunnable implements Runnable {
280 private ServletCache servletCache;
281 private Object object;
282 private CyclicBarrier startBarrier;
283 private ActionContext actionContext;
284 private CyclicBarrier endBarrier;
285
286 ServletGetRunnable(ServletCache servletCache, CyclicBarrier startBarrier, CyclicBarrier endBarrier, ActionContext actionContext) {
287 this.servletCache = servletCache;
288 this.startBarrier = startBarrier;
289 this.endBarrier = endBarrier;
290 this.actionContext = actionContext;
291 }
292
293 public void run() {
294 ActionContext.setContext(actionContext);
295
296 try {
297 startBarrier.await();
298 object = servletCache.get("org/apache/struts2/simple0.jsp");
299
300 for (int i = 0; i < 10; i++) {
301 Object object2 = servletCache.get("org/apache/struts2/simple0.jsp");
302 if (object2 != object)
303 throw new RuntimeException("got different object from cache");
304 }
305
306 endBarrier.await();
307 } catch (Exception e) {
308 throw new RuntimeException(e);
309 }
310 }
311
312 public Object getObject() {
313 return object;
314 }
315 }
316
317 class CountingClassLoaderInterface extends ClassLoaderInterfaceDelegate {
318 public Map<String, Integer> counters = new HashMap<String, Integer>();
319
320 public CountingClassLoaderInterface(ClassLoader classLoader) {
321 super(classLoader);
322 }
323
324 @Override
325 public InputStream getResourceAsStream(String name) {
326 Integer counter = counters.get(name);
327 counter = counter == null ? 1 : counter + 1;
328 counters.put(name, counter);
329
330 return super.getResourceAsStream(name);
331 }
332 }