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.controllers.sql;
12  
13  import static org.junit.jupiter.api.Assertions.assertEquals;
14  import static org.junit.jupiter.api.Assertions.assertTrue;
15  import static org.mockito.Mockito.mock;
16  import static org.mockito.Mockito.when;
17  
18  import java.sql.Connection;
19  import java.sql.DatabaseMetaData;
20  import java.sql.SQLException;
21  import java.util.List;
22  import java.util.Locale;
23  import java.util.Map;
24  
25  import javax.naming.NamingException;
26  import javax.sql.DataSource;
27  
28  import org.apache.catalina.Context;
29  import org.junit.jupiter.api.BeforeEach;
30  import org.junit.jupiter.api.Test;
31  import org.springframework.context.support.StaticApplicationContext;
32  import org.springframework.mock.web.MockHttpServletRequest;
33  import org.springframework.mock.web.MockHttpServletResponse;
34  import org.springframework.test.util.ReflectionTestUtils;
35  import org.springframework.web.servlet.ModelAndView;
36  
37  import psiprobe.TomcatContainer;
38  import psiprobe.beans.ContainerWrapperBean;
39  import psiprobe.beans.ResourceResolver;
40  
41  class ConnectionTestControllerTest {
42  
43    private ConnectionTestController controller;
44    private ContainerWrapperBean containerWrapper;
45    private ResourceResolver resourceResolver;
46    private TomcatContainer tomcatContainer;
47  
48    @BeforeEach
49    void setUp() throws Exception {
50      controller = new ConnectionTestController();
51      controller.setViewName("ajax/sql/connection");
52  
53      StaticApplicationContext applicationContext = new StaticApplicationContext();
54      applicationContext.addMessage("probe.src.dataSourceTest.resource.lookup.failure",
55          Locale.getDefault(), "lookup {0}");
56      applicationContext.addMessage("probe.src.dataSourceTest.connection.failure",
57          Locale.getDefault(), "connection {0}");
58      applicationContext.addMessage("probe.jsp.dataSourceTest.dbMetaData.dbProdName",
59          Locale.getDefault(), "db product");
60      applicationContext.addMessage("probe.jsp.dataSourceTest.dbMetaData.dbProdVersion",
61          Locale.getDefault(), "db version");
62      applicationContext.addMessage("probe.jsp.dataSourceTest.dbMetaData.jdbcDriverName",
63          Locale.getDefault(), "driver name");
64      applicationContext.addMessage("probe.jsp.dataSourceTest.dbMetaData.jdbcDriverVersion",
65          Locale.getDefault(), "driver version");
66      applicationContext.addMessage("probe.jsp.dataSourceTest.dbMetaData.jdbcVersion",
67          Locale.getDefault(), "jdbc version");
68      applicationContext.refresh();
69      controller.setApplicationContext(applicationContext);
70  
71      containerWrapper = mock(ContainerWrapperBean.class);
72      resourceResolver = mock(ResourceResolver.class);
73      tomcatContainer = mock(TomcatContainer.class);
74  
75      when(containerWrapper.getResourceResolver()).thenReturn(resourceResolver);
76      when(containerWrapper.getTomcatContainer()).thenReturn(tomcatContainer);
77      when(tomcatContainer.formatContextName("app")).thenReturn("/app");
78  
79      ReflectionTestUtils.setField(controller, "containerWrapper", containerWrapper);
80    }
81  
82    @Test
83    void handleRequestReturnsDatabaseMetadataWhenLookupSucceeds() throws Exception {
84      Context context = mock(Context.class);
85      DataSource dataSource = mock(DataSource.class);
86      Connection connection = mock(Connection.class);
87      DatabaseMetaData metaData = mock(DatabaseMetaData.class);
88  
89      when(tomcatContainer.findContext("/app")).thenReturn(context);
90      when(resourceResolver.lookupDataSource(context, "jdbc/test", containerWrapper))
91          .thenReturn(dataSource);
92      when(dataSource.getConnection()).thenReturn(connection);
93      when(connection.getMetaData()).thenReturn(metaData);
94      when(metaData.getDatabaseProductName()).thenReturn("PostgreSQL");
95      when(metaData.getDatabaseProductVersion()).thenReturn("16");
96      when(metaData.getDriverName()).thenReturn("Driver");
97      when(metaData.getDriverVersion()).thenReturn("1.0");
98      when(metaData.getJDBCMajorVersion()).thenReturn(4);
99  
100     MockHttpServletRequest request = new MockHttpServletRequest("GET", "/sql/connection.ajax");
101     request.addParameter("webapp", "app");
102     request.addParameter("resource", "jdbc/test");
103 
104     ModelAndView modelAndView = controller.handleRequest(request, new MockHttpServletResponse());
105 
106     assertEquals("ajax/sql/connection", modelAndView.getViewName());
107     @SuppressWarnings("unchecked")
108     List<Map<String, String>> dbMetaData =
109         (List<Map<String, String>>) modelAndView.getModel().get("dbMetaData");
110     assertEquals(5, dbMetaData.size());
111     assertEquals("db product", dbMetaData.get(0).get("propertyName"));
112     assertEquals("PostgreSQL", dbMetaData.get(0).get("propertyValue"));
113   }
114 
115   @Test
116   void handleRequestSetsLookupErrorWhenDatasourceLookupFails() throws Exception {
117     Context context = mock(Context.class);
118     when(tomcatContainer.findContext("/app")).thenReturn(context);
119     when(resourceResolver.lookupDataSource(context, "jdbc/missing", containerWrapper))
120         .thenThrow(new NamingException("boom"));
121 
122     MockHttpServletRequest request = new MockHttpServletRequest("GET", "/sql/connection.ajax");
123     request.addParameter("webapp", "app");
124     request.addParameter("resource", "jdbc/missing");
125 
126     ModelAndView modelAndView = controller.handleRequest(request, new MockHttpServletResponse());
127 
128     assertEquals("ajax/sql/connection", modelAndView.getViewName());
129     assertEquals("lookup jdbc/missing", request.getAttribute("errorMessage"));
130   }
131 
132   @Test
133   void handleRequestSetsConnectionErrorWhenConnectionFails() throws Exception {
134     Context context = mock(Context.class);
135     DataSource dataSource = mock(DataSource.class);
136     when(tomcatContainer.findContext("/app")).thenReturn(context);
137     when(resourceResolver.lookupDataSource(context, "jdbc/test", containerWrapper))
138         .thenReturn(dataSource);
139     when(dataSource.getConnection()).thenThrow(new SQLException("down"));
140 
141     MockHttpServletRequest request = new MockHttpServletRequest("GET", "/sql/connection.ajax");
142     request.addParameter("webapp", "app");
143     request.addParameter("resource", "jdbc/test");
144 
145     ModelAndView modelAndView = controller.handleRequest(request, new MockHttpServletResponse());
146 
147     assertEquals("ajax/sql/connection", modelAndView.getViewName());
148     assertEquals("connection down", request.getAttribute("errorMessage"));
149     assertTrue(modelAndView.getModel().isEmpty());
150   }
151 }