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 Tomcat10ContainerAdapterTest.
54   */
55  @ExtendWith(MockitoExtension.class)
56  class Tomcat10ContainerAdapterTest {
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 Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
72      Valve valve = adapter.createValve();
73      assertEquals("Tomcat10AgentValve[Container is null]", valve.toString());
74    }
75  
76    /**
77     * Can bound to null.
78     */
79    @Test
80    void canBoundToNull() {
81      final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
82      assertFalse(adapter.canBoundTo(null));
83    }
84  
85    /**
86     * Can bound to tomcat 10.1, tomee 10.0, nsjsp 10.1, vmware tc 10.1.
87     *
88     * @param container the container
89     */
90    @ParameterizedTest
91    @ValueSource(strings = {"Apache Tomcat/10.1", "Apache Tomcat (TomEE)/10.0",
92        "NonStop(tm) Servlets For JavaServer Pages(tm) v10.1", "Vmware tc..../10.1"})
93    void canBoundTo(String container) {
94      final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
95      assertTrue(adapter.canBoundTo(container));
96    }
97  
98    /**
99     * Can not bound to other containers.
100    *
101    * @param container the container
102    */
103   @ParameterizedTest
104   @ValueSource(strings = {"Vmware tc", "Other"})
105   void cannotBoundToOthers(String container) {
106     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
107     assertFalse(adapter.canBoundTo(container));
108   }
109 
110   /**
111    * Filter mappings.
112    */
113   @Test
114   void filterMappings() {
115     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
116     FilterMap map = new FilterMap();
117     map.addServletName("psi-probe");
118     map.addURLPattern("/psi-probe");
119     assertEquals(2, adapter.getFilterMappings(map, "dispatcherMap", "filterClass").size());
120   }
121 
122   /**
123    * Creates the jsp compilation context.
124    */
125   @Test
126   void createJspCompilationContext() {
127     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
128     Mockito.when(this.options.getGeneratedJspPackageName()).thenReturn("org.apache.jsp");
129     JspCompilationContext jspContext = adapter.createJspCompilationContext("name", this.options,
130         null, null, ClassLoader.getSystemClassLoader());
131     assertEquals("org.apache.jsp.name", jspContext.getFQCN());
132   }
133 
134   /**
135    * Adds the context resource link.
136    */
137   @Test
138   void addContextResourceLink() {
139     NamingResourcesImpl namingResources = Mockito.mock(NamingResourcesImpl.class);
140     Mockito.when(context.getNamingResources()).thenReturn(namingResources);
141 
142     ContextResourceLink link = new ContextResourceLink();
143     link.setName("jdbc/MyDataSource");
144     link.setGlobal("jdbc/GlobalDataSource");
145     link.setType("javax.sql.DataSource");
146 
147     Mockito.when(namingResources.findResourceLinks()).thenReturn(new ContextResourceLink[] {link});
148 
149     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
150     final List<ApplicationResource> list = new ArrayList<ApplicationResource>();
151     adapter.addContextResourceLink(context, list);
152     assertFalse(list.isEmpty());
153   }
154 
155   /**
156    * Adds the context resource.
157    */
158   @Test
159   void addContextResource() {
160     NamingResourcesImpl namingResources = Mockito.mock(NamingResourcesImpl.class);
161     Mockito.when(context.getNamingResources()).thenReturn(namingResources);
162     Mockito.when(namingResources.findResources())
163         .thenReturn(new ContextResource[] {new ContextResource()});
164 
165     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
166     final List<ApplicationResource> list = new ArrayList<ApplicationResource>();
167     adapter.addContextResource(context, list);
168     assertFalse(list.isEmpty());
169   }
170 
171   /**
172    * Gets the application filter maps.
173    */
174   @Test
175   void applicationFilterMaps() {
176     Mockito.when(context.findFilterMaps()).thenReturn(new FilterMap[] {new FilterMap()});
177 
178     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
179     assertEquals(0, adapter.getApplicationFilterMaps(context).size());
180   }
181 
182   /**
183    * Gets the application filter maps async.
184    *
185    * @param dispatcher the dispatcher
186    */
187   @ParameterizedTest
188   @ValueSource(strings = {"ASYNC", "ERROR", "FORWARD", "INCLUDE", "NONE"})
189   void applicationFilterMapsTypes(String dispatcher) {
190     FilterMap filterMap = new FilterMap();
191     filterMap.setDispatcher(dispatcher);
192     Mockito.when(context.findFilterMaps()).thenReturn(new FilterMap[] {filterMap});
193 
194     Mockito.when(context.findFilterDef(Mockito.any())).thenReturn(new FilterDef());
195 
196     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
197     assertEquals(0, adapter.getApplicationFilterMaps(context).size());
198   }
199 
200   /**
201    * Gets the application filter maps throws on unknown dispatcher mapping.
202    */
203   @Test
204   void applicationFilterMapsThrowsOnUnknownDispatcherMapping() {
205     Context mockContext = Mockito.mock(Context.class);
206     FilterMap filterMap = Mockito.mock(FilterMap.class);
207 
208     // Return an invalid dispatcher mapping value
209     Mockito.when(filterMap.getDispatcherMapping()).thenReturn(-1);
210     Mockito.when(mockContext.findFilterMaps()).thenReturn(new FilterMap[] {filterMap});
211 
212     Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
213 
214     assertThrows(NullPointerException.class, () -> adapter.getApplicationFilterMaps(mockContext));
215   }
216 
217   /**
218    * Application filters.
219    */
220   @Test
221   void applicationFilters() {
222     Mockito.when(context.findFilterDefs()).thenReturn(new FilterDef[] {new FilterDef()});
223 
224     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
225     assertEquals(1, adapter.getApplicationFilters(context).size());
226   }
227 
228   /**
229    * Application init params.
230    */
231   @Test
232   void applicationInitParams() {
233     Mockito.when(context.findApplicationParameters())
234         .thenReturn(new ApplicationParameter[] {new ApplicationParameter()});
235 
236     ServletContext servletContext = Mockito.mock(ServletContext.class);
237     Mockito.when(context.getServletContext()).thenReturn(servletContext);
238 
239     List<String> initParams = new ArrayList<>();
240     initParams.add("name");
241     Enumeration<String> initParameterNames = Collections.enumeration(initParams);
242     Mockito.when(servletContext.getInitParameterNames()).thenReturn(initParameterNames);
243 
244     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
245     assertEquals(1, adapter.getApplicationInitParams(context).size());
246   }
247 
248   /**
249    * Application init params none.
250    */
251   @Test
252   void applicationInitParamsNone() {
253     Mockito.when(context.findApplicationParameters())
254         .thenReturn(new ApplicationParameter[] {(ApplicationParameter) null});
255 
256     ServletContext servletContext = Mockito.mock(ServletContext.class);
257     Mockito.when(context.getServletContext()).thenReturn(servletContext);
258 
259     List<String> initParams = new ArrayList<>();
260     initParams.add("name");
261     Enumeration<String> initParameterNames = Collections.enumeration(initParams);
262     Mockito.when(servletContext.getInitParameterNames()).thenReturn(initParameterNames);
263 
264     Mockito.when(context.findParameter(Mockito.any())).thenReturn(null);
265 
266     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
267     assertEquals(1, adapter.getApplicationInitParams(context).size());
268   }
269 
270   /**
271    * Application init params not override attempt.
272    */
273   @Test
274   void applicationInitParamsNotOverrideAttempt() {
275     ApplicationParameter appParam = new ApplicationParameter();
276     appParam.setName("noOverride");
277     appParam.setOverride(false);
278     Mockito.when(context.findApplicationParameters())
279         .thenReturn(new ApplicationParameter[] {appParam});
280 
281     ServletContext servletContext = Mockito.mock(ServletContext.class);
282     Mockito.when(context.getServletContext()).thenReturn(servletContext);
283 
284     List<String> initParams = new ArrayList<>();
285     initParams.add("name");
286     Enumeration<String> initParameterNames = Collections.enumeration(initParams);
287     Mockito.when(servletContext.getInitParameterNames()).thenReturn(initParameterNames);
288 
289     Mockito.when(context.findParameter(Mockito.any())).thenReturn("name");
290 
291     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
292     assertEquals(1, adapter.getApplicationInitParams(context).size());
293   }
294 
295   /**
296    * Application init params not override attempt.
297    */
298   @Test
299   void applicationInitParamsOverrideAttempt() {
300     ApplicationParameter appParam = new ApplicationParameter();
301     appParam.setName("override");
302     appParam.setOverride(false);
303     Mockito.when(context.findApplicationParameters())
304         .thenReturn(new ApplicationParameter[] {appParam});
305 
306     ServletContext servletContext = Mockito.mock(ServletContext.class);
307     Mockito.when(context.getServletContext()).thenReturn(servletContext);
308 
309     List<String> initParams = new ArrayList<>();
310     initParams.add("override");
311     Enumeration<String> initParameterNames = Collections.enumeration(initParams);
312     Mockito.when(servletContext.getInitParameterNames()).thenReturn(initParameterNames);
313 
314     Mockito.when(context.findParameter(Mockito.any())).thenReturn("override");
315 
316     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
317     assertEquals(1, adapter.getApplicationInitParams(context).size());
318   }
319 
320   /**
321    * Resource exists.
322    */
323   @Test
324   void resourceExists() {
325     WebResourceRoot webResourceRoot = Mockito.mock(WebResourceRoot.class);
326     Mockito.when(context.getResources()).thenReturn(webResourceRoot);
327 
328     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
329     assertFalse(adapter.resourceExists("name", context));
330   }
331 
332   /**
333    * Resource exists when true.
334    */
335   @Test
336   void resourceExistsWhenTrue() {
337     WebResourceRoot webResourceRoot = Mockito.mock(WebResourceRoot.class);
338     Mockito.when(context.getResources()).thenReturn(webResourceRoot);
339 
340     WebResource webResource = Mockito.mock(WebResource.class);
341     Mockito.when(webResourceRoot.getResource("name")).thenReturn(webResource);
342 
343     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
344     assertTrue(adapter.resourceExists("name", context));
345   }
346 
347   /**
348    * Resource stream.
349    *
350    * @throws IOException Signals that an I/O exception has occurred.
351    */
352   @Test
353   void resourceStream() throws IOException {
354     WebResourceRoot webResourceRoot = Mockito.mock(WebResourceRoot.class);
355     Mockito.when(context.getResources()).thenReturn(webResourceRoot);
356 
357     WebResource webResource = Mockito.mock(WebResource.class);
358     Mockito.when(webResourceRoot.getResource("name")).thenReturn(webResource);
359 
360     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
361     assertNull(adapter.getResourceStream("name", context));
362   }
363 
364   /**
365    * Resource attributes.
366    */
367   @Test
368   void resourceAttributes() {
369     WebResourceRoot webResourceRoot = Mockito.mock(WebResourceRoot.class);
370     Mockito.when(context.getResources()).thenReturn(webResourceRoot);
371 
372     WebResource webResource = Mockito.mock(WebResource.class);
373     Mockito.when(webResourceRoot.getResource("name")).thenReturn(webResource);
374 
375     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
376     assertNotNull(adapter.getResourceAttributes("name", context));
377   }
378 
379   /**
380    * Gets the naming token.
381    */
382   @Test
383   void namingToken() {
384     Mockito.when(context.getNamingToken()).thenReturn(new Object());
385 
386     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
387     assertNotNull(adapter.getNamingToken(context));
388   }
389 
390   /**
391    * Gets the naming token with security token check false.
392    */
393   @Test
394   void namingTokenWithSecurityTokenCheckFalse() {
395     Mockito.when(context.getNamingToken()).thenReturn(new Object());
396 
397     try (MockedStatic<ContextAccessController> mocked =
398         Mockito.mockStatic(ContextAccessController.class)) {
399       mocked.when(() -> ContextAccessController.checkSecurityToken(Mockito.any(), Mockito.any()))
400           .thenReturn(false);
401 
402       final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
403       assertNotNull(adapter.getNamingToken(context));
404     }
405   }
406 
407   /**
408    * Application filters when none.
409    */
410   @Test
411   void applicationFiltersWhenNone() {
412     Mockito.when(context.findFilterDefs()).thenReturn(new FilterDef[] {(FilterDef) null});
413 
414     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
415     assertTrue(adapter.getApplicationFilters(context).isEmpty());
416   }
417 
418   /**
419    * Application filter maps when none.
420    */
421   @Test
422   void applicationFilterMapsWhenNone() {
423     Mockito.when(context.findFilterMaps()).thenReturn(new FilterMap[] {(FilterMap) null});
424 
425     final Tomcat10ContainerAdapter adapter = new Tomcat10ContainerAdapter();
426     assertTrue(adapter.getApplicationFilterMaps(context).isEmpty());
427   }
428 
429 }