View Javadoc
1   /*
2    * Licensed under the GPL License. You may not use this file except in compliance with the License.
3    * You may obtain a copy of the License at
4    *
5    *   https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
6    *
7    * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
8    * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
9    * PURPOSE.
10   */
11  package psiprobe;
12  
13  import static org.junit.jupiter.api.Assertions.assertEquals;
14  import static org.junit.jupiter.api.Assertions.assertFalse;
15  import static org.junit.jupiter.api.Assertions.assertNotNull;
16  import static org.junit.jupiter.api.Assertions.assertNull;
17  import static org.junit.jupiter.api.Assertions.assertThrows;
18  import static org.junit.jupiter.api.Assertions.assertTrue;
19  
20  import jakarta.servlet.ServletContext;
21  
22  import java.io.IOException;
23  import java.util.ArrayList;
24  import java.util.Collections;
25  import java.util.Enumeration;
26  import java.util.List;
27  
28  import org.apache.catalina.Context;
29  import org.apache.catalina.Valve;
30  import org.apache.catalina.WebResource;
31  import org.apache.catalina.WebResourceRoot;
32  import org.apache.catalina.deploy.NamingResourcesImpl;
33  import org.apache.jasper.EmbeddedServletOptions;
34  import org.apache.jasper.JspCompilationContext;
35  import org.apache.naming.ContextAccessController;
36  import org.apache.tomcat.util.descriptor.web.ApplicationParameter;
37  import org.apache.tomcat.util.descriptor.web.ContextResource;
38  import org.apache.tomcat.util.descriptor.web.ContextResourceLink;
39  import org.apache.tomcat.util.descriptor.web.FilterDef;
40  import org.apache.tomcat.util.descriptor.web.FilterMap;
41  import org.junit.jupiter.api.Test;
42  import org.junit.jupiter.api.extension.ExtendWith;
43  import org.junit.jupiter.params.ParameterizedTest;
44  import org.junit.jupiter.params.provider.ValueSource;
45  import org.mockito.Mock;
46  import org.mockito.MockedStatic;
47  import org.mockito.Mockito;
48  import org.mockito.junit.jupiter.MockitoExtension;
49  
50  import psiprobe.model.ApplicationResource;
51  
52  /**
53   * The Class Tomcat11ContainerAdapterTest.
54   */
55  @ExtendWith(MockitoExtension.class)
56  class Tomcat11ContainerAdapterTest {
57  
58    /** The context. */
59    @Mock
60    Context context;
61  
62    /** The embedded servlet options. */
63    @Mock
64    EmbeddedServletOptions options;
65  
66    /**
67     * Creates the valve.
68     */
69    @Test
70    void createValve() {
71      final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
72      Valve valve = adapter.createValve();
73      assertEquals("Tomcat11AgentValve[Container is null]", valve.toString());
74    }
75  
76    /**
77     * Can bound to null.
78     */
79    @Test
80    void canBoundToNull() {
81      final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
82      assertFalse(adapter.canBoundTo(null));
83    }
84  
85    /**
86     * Can bound to tomcat 11, tomee 11.0, nsjsp 11.0, vmware tc 11.0.
87     *
88     * @param container the container
89     */
90    @ParameterizedTest
91    @ValueSource(strings = {"Apache Tomcat/11.0",
92        // "Apache Tomcat (TomEE)/11.0",
93        // "NonStop(tm) Servlets For JavaServer Pages(tm) v11.0",
94        "Vmware tc..../11.0"})
95    void canBoundTo(String container) {
96      final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
97      assertTrue(adapter.canBoundTo(container));
98    }
99  
100   /**
101    * Can not bound to other containers.
102    *
103    * @param container the container
104    */
105   @ParameterizedTest
106   @ValueSource(strings = {"Vmware tc", "Other"})
107   void cannotBoundToOthers(String container) {
108     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
109     assertFalse(adapter.canBoundTo(container));
110   }
111 
112   /**
113    * Filter mappings.
114    */
115   @Test
116   void filterMappings() {
117     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
118     FilterMap map = new FilterMap();
119     map.addServletName("psi-probe");
120     map.addURLPattern("/psi-probe");
121     assertEquals(2, adapter.getFilterMappings(map, "dispatcherMap", "filterClass").size());
122   }
123 
124   /**
125    * Creates the jsp compilation context.
126    */
127   @Test
128   void createJspCompilationContext() {
129     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
130     Mockito.when(this.options.getGeneratedJspPackageName()).thenReturn("org.apache.jsp");
131     JspCompilationContext jspContext = adapter.createJspCompilationContext("name", this.options,
132         null, null, ClassLoader.getSystemClassLoader());
133     assertEquals("org.apache.jsp.name", jspContext.getFQCN());
134   }
135 
136   /**
137    * Adds the context resource link.
138    */
139   @Test
140   void addContextResourceLink() {
141     NamingResourcesImpl namingResources = Mockito.mock(NamingResourcesImpl.class);
142     Mockito.when(context.getNamingResources()).thenReturn(namingResources);
143     Mockito.when(namingResources.findResourceLinks())
144         .thenReturn(new ContextResourceLink[] {new ContextResourceLink()});
145 
146     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
147     final List<ApplicationResource> list = new ArrayList<ApplicationResource>();
148     adapter.addContextResourceLink(context, list);
149     assertFalse(list.isEmpty());
150   }
151 
152   /**
153    * Adds the context resource.
154    */
155   @Test
156   void addContextResource() {
157     NamingResourcesImpl namingResources = Mockito.mock(NamingResourcesImpl.class);
158     Mockito.when(context.getNamingResources()).thenReturn(namingResources);
159     Mockito.when(namingResources.findResources())
160         .thenReturn(new ContextResource[] {new ContextResource()});
161 
162     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
163     final List<ApplicationResource> list = new ArrayList<ApplicationResource>();
164     adapter.addContextResource(context, list);
165     assertFalse(list.isEmpty());
166   }
167 
168   /**
169    * Gets the application filter maps.
170    */
171   @Test
172   void applicationFilterMaps() {
173     Mockito.when(context.findFilterMaps()).thenReturn(new FilterMap[] {new FilterMap()});
174 
175     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
176     assertEquals(0, adapter.getApplicationFilterMaps(context).size());
177   }
178 
179   /**
180    * Gets the application filter maps async.
181    *
182    * @param dispatcher the dispatcher
183    */
184   @ParameterizedTest
185   @ValueSource(strings = {"ASYNC", "ERROR", "FORWARD", "INCLUDE", "NONE"})
186   void applicationFilterMapsTypes(String dispatcher) {
187     FilterMap filterMap = new FilterMap();
188     filterMap.setDispatcher(dispatcher);
189     Mockito.when(context.findFilterMaps()).thenReturn(new FilterMap[] {filterMap});
190 
191     Mockito.when(context.findFilterDef(Mockito.any())).thenReturn(new FilterDef());
192 
193     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
194     assertEquals(0, adapter.getApplicationFilterMaps(context).size());
195   }
196 
197   /**
198    * Gets the application filter maps throws on unknown dispatcher mapping.
199    */
200   @Test
201   void applicationFilterMapsThrowsOnUnknownDispatcherMapping() {
202     Context mockContext = Mockito.mock(Context.class);
203     FilterMap filterMap = Mockito.mock(FilterMap.class);
204 
205     // Return an invalid dispatcher mapping value
206     Mockito.when(filterMap.getDispatcherMapping()).thenReturn(-1);
207     Mockito.when(mockContext.findFilterMaps()).thenReturn(new FilterMap[] {filterMap});
208 
209     Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
210 
211     assertThrows(IllegalArgumentException.class,
212         () -> adapter.getApplicationFilterMaps(mockContext));
213   }
214 
215   /**
216    * Application filters.
217    */
218   @Test
219   void applicationFilters() {
220     Mockito.when(context.findFilterDefs()).thenReturn(new FilterDef[] {new FilterDef()});
221 
222     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
223     assertEquals(1, adapter.getApplicationFilters(context).size());
224   }
225 
226   /**
227    * Application init params.
228    */
229   @Test
230   void applicationInitParams() {
231     Mockito.when(context.findApplicationParameters())
232         .thenReturn(new ApplicationParameter[] {new ApplicationParameter()});
233 
234     ServletContext servletContext = Mockito.mock(ServletContext.class);
235     Mockito.when(context.getServletContext()).thenReturn(servletContext);
236 
237     List<String> initParams = new ArrayList<>();
238     initParams.add("name");
239     Enumeration<String> initParameterNames = Collections.enumeration(initParams);
240     Mockito.when(servletContext.getInitParameterNames()).thenReturn(initParameterNames);
241 
242     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
243     assertEquals(1, adapter.getApplicationInitParams(context).size());
244   }
245 
246   /**
247    * Application init params none.
248    */
249   @Test
250   void applicationInitParamsNone() {
251     Mockito.when(context.findApplicationParameters())
252         .thenReturn(new ApplicationParameter[] {(ApplicationParameter) null});
253 
254     ServletContext servletContext = Mockito.mock(ServletContext.class);
255     Mockito.when(context.getServletContext()).thenReturn(servletContext);
256 
257     List<String> initParams = new ArrayList<>();
258     initParams.add("name");
259     Enumeration<String> initParameterNames = Collections.enumeration(initParams);
260     Mockito.when(servletContext.getInitParameterNames()).thenReturn(initParameterNames);
261 
262     Mockito.when(context.findParameter(Mockito.any())).thenReturn(null);
263 
264     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
265     assertEquals(1, adapter.getApplicationInitParams(context).size());
266   }
267 
268   /**
269    * Application init params not override attempt.
270    */
271   @Test
272   void applicationInitParamsNotOverrideAttempt() {
273     ApplicationParameter appParam = new ApplicationParameter();
274     appParam.setName("noOverride");
275     appParam.setOverride(false);
276     Mockito.when(context.findApplicationParameters())
277         .thenReturn(new ApplicationParameter[] {appParam});
278 
279     ServletContext servletContext = Mockito.mock(ServletContext.class);
280     Mockito.when(context.getServletContext()).thenReturn(servletContext);
281 
282     List<String> initParams = new ArrayList<>();
283     initParams.add("name");
284     Enumeration<String> initParameterNames = Collections.enumeration(initParams);
285     Mockito.when(servletContext.getInitParameterNames()).thenReturn(initParameterNames);
286 
287     Mockito.when(context.findParameter(Mockito.any())).thenReturn("name");
288 
289     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
290     assertEquals(1, adapter.getApplicationInitParams(context).size());
291   }
292 
293   /**
294    * Application init params not override attempt.
295    */
296   @Test
297   void applicationInitParamsOverrideAttempt() {
298     ApplicationParameter appParam = new ApplicationParameter();
299     appParam.setName("override");
300     appParam.setOverride(false);
301     Mockito.when(context.findApplicationParameters())
302         .thenReturn(new ApplicationParameter[] {appParam});
303 
304     ServletContext servletContext = Mockito.mock(ServletContext.class);
305     Mockito.when(context.getServletContext()).thenReturn(servletContext);
306 
307     List<String> initParams = new ArrayList<>();
308     initParams.add("override");
309     Enumeration<String> initParameterNames = Collections.enumeration(initParams);
310     Mockito.when(servletContext.getInitParameterNames()).thenReturn(initParameterNames);
311 
312     Mockito.when(context.findParameter(Mockito.any())).thenReturn("override");
313 
314     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
315     assertEquals(1, adapter.getApplicationInitParams(context).size());
316   }
317 
318   /**
319    * Resource exists.
320    */
321   @Test
322   void resourceExists() {
323     WebResourceRoot webResourceRoot = Mockito.mock(WebResourceRoot.class);
324     Mockito.when(context.getResources()).thenReturn(webResourceRoot);
325 
326     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
327     assertFalse(adapter.resourceExists("name", context));
328   }
329 
330   /**
331    * Resource exists when true.
332    */
333   @Test
334   void resourceExistsWhenTrue() {
335     WebResourceRoot webResourceRoot = Mockito.mock(WebResourceRoot.class);
336     Mockito.when(context.getResources()).thenReturn(webResourceRoot);
337 
338     WebResource webResource = Mockito.mock(WebResource.class);
339     Mockito.when(webResourceRoot.getResource("name")).thenReturn(webResource);
340 
341     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
342     assertTrue(adapter.resourceExists("name", context));
343   }
344 
345   /**
346    * Resource stream.
347    *
348    * @throws IOException Signals that an I/O exception has occurred.
349    */
350   @Test
351   void resourceStream() throws IOException {
352     WebResourceRoot webResourceRoot = Mockito.mock(WebResourceRoot.class);
353     Mockito.when(context.getResources()).thenReturn(webResourceRoot);
354 
355     WebResource webResource = Mockito.mock(WebResource.class);
356     Mockito.when(webResourceRoot.getResource("name")).thenReturn(webResource);
357 
358     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
359     assertNull(adapter.getResourceStream("name", context));
360   }
361 
362   /**
363    * Resource attributes.
364    */
365   @Test
366   void resourceAttributes() {
367     WebResourceRoot webResourceRoot = Mockito.mock(WebResourceRoot.class);
368     Mockito.when(context.getResources()).thenReturn(webResourceRoot);
369 
370     WebResource webResource = Mockito.mock(WebResource.class);
371     Mockito.when(webResourceRoot.getResource("name")).thenReturn(webResource);
372 
373     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
374     assertNotNull(adapter.getResourceAttributes("name", context));
375   }
376 
377   /**
378    * Gets the naming token.
379    */
380   @Test
381   void namingToken() {
382     Mockito.when(context.getNamingToken()).thenReturn(new Object());
383 
384     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
385     assertNotNull(adapter.getNamingToken(context));
386   }
387 
388   /**
389    * Gets the naming token with security token check false.
390    */
391   @Test
392   void namingTokenWithSecurityTokenCheckFalse() {
393     Mockito.when(context.getNamingToken()).thenReturn(new Object());
394 
395     try (MockedStatic<ContextAccessController> mocked =
396         Mockito.mockStatic(ContextAccessController.class)) {
397       mocked.when(() -> ContextAccessController.checkSecurityToken(Mockito.any(), Mockito.any()))
398           .thenReturn(false);
399 
400       final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
401       assertNotNull(adapter.getNamingToken(context));
402     }
403   }
404 
405   /**
406    * Application filters when none.
407    */
408   @Test
409   void applicationFiltersWhenNone() {
410     Mockito.when(context.findFilterDefs()).thenReturn(new FilterDef[] {(FilterDef) null});
411 
412     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
413     assertTrue(adapter.getApplicationFilters(context).isEmpty());
414   }
415 
416   /**
417    * Application filter maps when none.
418    */
419   @Test
420   void applicationFilterMapsWhenNone() {
421     Mockito.when(context.findFilterMaps()).thenReturn(new FilterMap[] {(FilterMap) null});
422 
423     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
424     assertTrue(adapter.getApplicationFilterMaps(context).isEmpty());
425   }
426 
427 }