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 
144     ContextResourceLink link = new ContextResourceLink();
145     link.setName("jdbc/MyDataSource");
146     link.setGlobal("jdbc/GlobalDataSource");
147     link.setType("javax.sql.DataSource");
148 
149     Mockito.when(namingResources.findResourceLinks()).thenReturn(new ContextResourceLink[] {link});
150 
151     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
152     final List<ApplicationResource> list = new ArrayList<ApplicationResource>();
153     adapter.addContextResourceLink(context, list);
154     assertFalse(list.isEmpty());
155   }
156 
157   /**
158    * Adds the context resource.
159    */
160   @Test
161   void addContextResource() {
162     NamingResourcesImpl namingResources = Mockito.mock(NamingResourcesImpl.class);
163     Mockito.when(context.getNamingResources()).thenReturn(namingResources);
164     Mockito.when(namingResources.findResources())
165         .thenReturn(new ContextResource[] {new ContextResource()});
166 
167     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
168     final List<ApplicationResource> list = new ArrayList<ApplicationResource>();
169     adapter.addContextResource(context, list);
170     assertFalse(list.isEmpty());
171   }
172 
173   /**
174    * Gets the application filter maps.
175    */
176   @Test
177   void applicationFilterMaps() {
178     Mockito.when(context.findFilterMaps()).thenReturn(new FilterMap[] {new FilterMap()});
179 
180     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
181     assertEquals(0, adapter.getApplicationFilterMaps(context).size());
182   }
183 
184   /**
185    * Gets the application filter maps async.
186    *
187    * @param dispatcher the dispatcher
188    */
189   @ParameterizedTest
190   @ValueSource(strings = {"ASYNC", "ERROR", "FORWARD", "INCLUDE", "NONE"})
191   void applicationFilterMapsTypes(String dispatcher) {
192     FilterMap filterMap = new FilterMap();
193     filterMap.setDispatcher(dispatcher);
194     Mockito.when(context.findFilterMaps()).thenReturn(new FilterMap[] {filterMap});
195 
196     Mockito.when(context.findFilterDef(Mockito.any())).thenReturn(new FilterDef());
197 
198     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
199     assertEquals(0, adapter.getApplicationFilterMaps(context).size());
200   }
201 
202   /**
203    * Gets the application filter maps throws on unknown dispatcher mapping.
204    */
205   @Test
206   void applicationFilterMapsThrowsOnUnknownDispatcherMapping() {
207     Context mockContext = Mockito.mock(Context.class);
208     FilterMap filterMap = Mockito.mock(FilterMap.class);
209 
210     // Return an invalid dispatcher mapping value
211     Mockito.when(filterMap.getDispatcherMapping()).thenReturn(-1);
212     Mockito.when(mockContext.findFilterMaps()).thenReturn(new FilterMap[] {filterMap});
213 
214     Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
215 
216     assertThrows(NullPointerException.class, () -> adapter.getApplicationFilterMaps(mockContext));
217   }
218 
219   /**
220    * Application filters.
221    */
222   @Test
223   void applicationFilters() {
224     Mockito.when(context.findFilterDefs()).thenReturn(new FilterDef[] {new FilterDef()});
225 
226     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
227     assertEquals(1, adapter.getApplicationFilters(context).size());
228   }
229 
230   /**
231    * Application init params.
232    */
233   @Test
234   void applicationInitParams() {
235     Mockito.when(context.findApplicationParameters())
236         .thenReturn(new ApplicationParameter[] {new ApplicationParameter()});
237 
238     ServletContext servletContext = Mockito.mock(ServletContext.class);
239     Mockito.when(context.getServletContext()).thenReturn(servletContext);
240 
241     List<String> initParams = new ArrayList<>();
242     initParams.add("name");
243     Enumeration<String> initParameterNames = Collections.enumeration(initParams);
244     Mockito.when(servletContext.getInitParameterNames()).thenReturn(initParameterNames);
245 
246     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
247     assertEquals(1, adapter.getApplicationInitParams(context).size());
248   }
249 
250   /**
251    * Application init params none.
252    */
253   @Test
254   void applicationInitParamsNone() {
255     Mockito.when(context.findApplicationParameters())
256         .thenReturn(new ApplicationParameter[] {(ApplicationParameter) null});
257 
258     ServletContext servletContext = Mockito.mock(ServletContext.class);
259     Mockito.when(context.getServletContext()).thenReturn(servletContext);
260 
261     List<String> initParams = new ArrayList<>();
262     initParams.add("name");
263     Enumeration<String> initParameterNames = Collections.enumeration(initParams);
264     Mockito.when(servletContext.getInitParameterNames()).thenReturn(initParameterNames);
265 
266     Mockito.when(context.findParameter(Mockito.any())).thenReturn(null);
267 
268     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
269     assertEquals(1, adapter.getApplicationInitParams(context).size());
270   }
271 
272   /**
273    * Application init params not override attempt.
274    */
275   @Test
276   void applicationInitParamsNotOverrideAttempt() {
277     ApplicationParameter appParam = new ApplicationParameter();
278     appParam.setName("noOverride");
279     appParam.setOverride(false);
280     Mockito.when(context.findApplicationParameters())
281         .thenReturn(new ApplicationParameter[] {appParam});
282 
283     ServletContext servletContext = Mockito.mock(ServletContext.class);
284     Mockito.when(context.getServletContext()).thenReturn(servletContext);
285 
286     List<String> initParams = new ArrayList<>();
287     initParams.add("name");
288     Enumeration<String> initParameterNames = Collections.enumeration(initParams);
289     Mockito.when(servletContext.getInitParameterNames()).thenReturn(initParameterNames);
290 
291     Mockito.when(context.findParameter(Mockito.any())).thenReturn("name");
292 
293     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
294     assertEquals(1, adapter.getApplicationInitParams(context).size());
295   }
296 
297   /**
298    * Application init params not override attempt.
299    */
300   @Test
301   void applicationInitParamsOverrideAttempt() {
302     ApplicationParameter appParam = new ApplicationParameter();
303     appParam.setName("override");
304     appParam.setOverride(false);
305     Mockito.when(context.findApplicationParameters())
306         .thenReturn(new ApplicationParameter[] {appParam});
307 
308     ServletContext servletContext = Mockito.mock(ServletContext.class);
309     Mockito.when(context.getServletContext()).thenReturn(servletContext);
310 
311     List<String> initParams = new ArrayList<>();
312     initParams.add("override");
313     Enumeration<String> initParameterNames = Collections.enumeration(initParams);
314     Mockito.when(servletContext.getInitParameterNames()).thenReturn(initParameterNames);
315 
316     Mockito.when(context.findParameter(Mockito.any())).thenReturn("override");
317 
318     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
319     assertEquals(1, adapter.getApplicationInitParams(context).size());
320   }
321 
322   /**
323    * Resource exists.
324    */
325   @Test
326   void resourceExists() {
327     WebResourceRoot webResourceRoot = Mockito.mock(WebResourceRoot.class);
328     Mockito.when(context.getResources()).thenReturn(webResourceRoot);
329 
330     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
331     assertFalse(adapter.resourceExists("name", context));
332   }
333 
334   /**
335    * Resource exists when true.
336    */
337   @Test
338   void resourceExistsWhenTrue() {
339     WebResourceRoot webResourceRoot = Mockito.mock(WebResourceRoot.class);
340     Mockito.when(context.getResources()).thenReturn(webResourceRoot);
341 
342     WebResource webResource = Mockito.mock(WebResource.class);
343     Mockito.when(webResourceRoot.getResource("name")).thenReturn(webResource);
344 
345     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
346     assertTrue(adapter.resourceExists("name", context));
347   }
348 
349   /**
350    * Resource stream.
351    *
352    * @throws IOException Signals that an I/O exception has occurred.
353    */
354   @Test
355   void resourceStream() throws IOException {
356     WebResourceRoot webResourceRoot = Mockito.mock(WebResourceRoot.class);
357     Mockito.when(context.getResources()).thenReturn(webResourceRoot);
358 
359     WebResource webResource = Mockito.mock(WebResource.class);
360     Mockito.when(webResourceRoot.getResource("name")).thenReturn(webResource);
361 
362     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
363     assertNull(adapter.getResourceStream("name", context));
364   }
365 
366   /**
367    * Resource attributes.
368    */
369   @Test
370   void resourceAttributes() {
371     WebResourceRoot webResourceRoot = Mockito.mock(WebResourceRoot.class);
372     Mockito.when(context.getResources()).thenReturn(webResourceRoot);
373 
374     WebResource webResource = Mockito.mock(WebResource.class);
375     Mockito.when(webResourceRoot.getResource("name")).thenReturn(webResource);
376 
377     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
378     assertNotNull(adapter.getResourceAttributes("name", context));
379   }
380 
381   /**
382    * Gets the naming token.
383    */
384   @Test
385   void namingToken() {
386     Mockito.when(context.getNamingToken()).thenReturn(new Object());
387 
388     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
389     assertNotNull(adapter.getNamingToken(context));
390   }
391 
392   /**
393    * Gets the naming token with security token check false.
394    */
395   @Test
396   void namingTokenWithSecurityTokenCheckFalse() {
397     Mockito.when(context.getNamingToken()).thenReturn(new Object());
398 
399     try (MockedStatic<ContextAccessController> mocked =
400         Mockito.mockStatic(ContextAccessController.class)) {
401       mocked.when(() -> ContextAccessController.checkSecurityToken(Mockito.any(), Mockito.any()))
402           .thenReturn(false);
403 
404       final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
405       assertNotNull(adapter.getNamingToken(context));
406     }
407   }
408 
409   /**
410    * Application filters when none.
411    */
412   @Test
413   void applicationFiltersWhenNone() {
414     Mockito.when(context.findFilterDefs()).thenReturn(new FilterDef[] {(FilterDef) null});
415 
416     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
417     assertTrue(adapter.getApplicationFilters(context).isEmpty());
418   }
419 
420   /**
421    * Application filter maps when none.
422    */
423   @Test
424   void applicationFilterMapsWhenNone() {
425     Mockito.when(context.findFilterMaps()).thenReturn(new FilterMap[] {(FilterMap) null});
426 
427     final Tomcat11ContainerAdapter adapter = new Tomcat11ContainerAdapter();
428     assertTrue(adapter.getApplicationFilterMaps(context).isEmpty());
429   }
430 
431 }