package org.geoserver.monitor.rest; import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.Matchers.startsWith; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.text.ParseException; import java.util.Arrays; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Row; import org.geoserver.data.test.SystemTestData; import org.geoserver.monitor.Monitor; import org.geoserver.monitor.MonitorTestData; import org.geoserver.monitor.RequestData; import org.geoserver.rest.RestBaseController; import org.geoserver.test.GeoServerSystemTestSupport; import org.geotools.feature.type.DateUtil; import org.jsoup.Jsoup; import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.MockHttpServletResponse; public class RequestControllerTest extends GeoServerSystemTestSupport { private Monitor monitor; @Override protected void setUpTestData(SystemTestData testData) throws Exception { // no test data } @Before public void setupMonitorContents() throws ParseException { monitor = applicationContext.getBean(Monitor.class); monitor.getDAO().dispose(); new MonitorTestData(monitor.getDAO(), false).setup(); } @Test public void testGetAllHTML() throws Exception { MockHttpServletResponse response = getAsServletResponse( RestBaseController.ROOT_PATH + "/monitor/requests.html"); assertEquals(200, response.getStatus()); // System.out.println(response.getContentAsString()); // this check is's actual XML org.jsoup.nodes.Document document = Jsoup.parse(response.getContentAsString()); // testing the first element assertEquals("http://localhost:8080/geoserver" + RestBaseController.ROOT_PATH + "/monitor/requests/1.html", document.select("a:contains(1)").attr("href")); assertEquals("RUNNING", document.select("tr.even > td").get(1).text()); } @Test public void testGetHTMLById() throws Exception { MockHttpServletResponse response = getAsServletResponse( RestBaseController.ROOT_PATH + "/monitor/requests/5.html"); assertEquals(200, response.getStatus()); // System.out.println(response.getContentAsString()); // this check is's actual XML org.jsoup.nodes.Document document = Jsoup.parse(response.getContentAsString()); // the structure is different, check the title assertEquals("Request 5", document.select("#content > h1 > span").text()); } @Test public void testGetAllCSV() throws Exception { MockHttpServletResponse response = getAsServletResponse( RestBaseController.ROOT_PATH + "/monitor/requests.csv?fields=id;path;startTime"); assertEquals(200, response.getStatus()); // System.out.println(response.getContentAsString()); BufferedReader in = new BufferedReader( new InputStreamReader(new ByteArrayInputStream(response.getContentAsByteArray()))); String line = in.readLine(); assertEquals("id,path,startTime", line); Iterator<RequestData> it = monitor.getDAO().getRequests().iterator(); while ((line = in.readLine()) != null) { assertTrue(it.hasNext()); RequestData data = it.next(); String expected = data.getId() + "," + data.getPath() + "," + DateUtil.serializeDateTime(data.getStartTime()); assertEquals(expected, line); } assertFalse(it.hasNext()); } @Test public void testDelete() throws Exception { // delete all MockHttpServletResponse response = deleteAsServletResponse(RestBaseController.ROOT_PATH + "/monitor/requests"); assertEquals(200, response.getStatus()); assertEquals(0, monitor.getDAO().getRequests().size()); } @Test public void testGetAllExcel() throws Exception { MockHttpServletResponse response = getAsServletResponse( RestBaseController.ROOT_PATH + "/monitor/requests.xls?fields=id;path;startTime"); assertEquals(200, response.getStatus()); HSSFWorkbook wb = new HSSFWorkbook(new ByteArrayInputStream(response.getContentAsByteArray())); HSSFSheet sheet = wb.getSheet("requests"); Iterator<Row> rows = sheet.iterator(); Iterator<RequestData> it = monitor.getDAO().getRequests().iterator(); assertTrue(rows.hasNext()); Row row = rows.next(); assertEquals("id", row.getCell(0).getStringCellValue()); assertEquals("path", row.getCell(1).getStringCellValue()); assertEquals("startTime", row.getCell(2).getStringCellValue()); while(rows.hasNext()) { row = rows.next(); assertTrue(it.hasNext()); RequestData data = it.next(); assertEquals((double) data.getId(), row.getCell(0).getNumericCellValue(), 0.1); assertEquals(data.getPath(), row.getCell(1).getStringCellValue()); assertEquals(data.getStartTime(), row.getCell(2).getDateCellValue()); } assertFalse(it.hasNext()); } @Test public void testGetZIP() throws Exception { // setup a single value in the DAO Date startTime = new Date(); Throwable throwable = new Throwable(); RequestData data = new RequestData(); data.setId(12345); data.setPath("/foo"); data.setStartTime(startTime); data.setBody("<foo></foo>".getBytes()); data.setError(throwable); monitor.getDAO().dispose(); monitor.getDAO().add(data); // running request MockHttpServletResponse response = getAsServletResponse( RestBaseController.ROOT_PATH + "/monitor/requests/12345.zip?fields=id;path;startTime;Error;Body"); assertEquals(200, response.getStatus()); ZipInputStream zin = new ZipInputStream(new ByteArrayInputStream(response.getContentAsByteArray())); ZipEntry entry = null; boolean requests = false; boolean body = false; boolean error = false; while((entry = zin.getNextEntry()) != null) { if ("requests.csv".equals(entry.getName())) { requests = true; String expected = "id,path,startTime\n12345,/foo," + DateUtil.serializeDateTime(startTime); assertEquals(expected, readEntry(zin)); } else if ("body.txt".equals(entry.getName())) { body = true; assertEquals("<foo></foo>", readEntry(zin)); } else if ("error.txt".equals(entry.getName())) { error = true; ByteArrayOutputStream bout = new ByteArrayOutputStream(); PrintStream stream = new PrintStream(bout); throwable.printStackTrace(stream); stream.flush(); assertEquals(new String(bout.toByteArray()).trim(), readEntry(zin)); } } assertTrue(requests); assertTrue(body); assertTrue(error); } String readEntry(ZipInputStream zin) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buf = new byte[1024]; int n = -1; while ((n = zin.read(buf)) != -1) { out.write(buf, 0, n); } return new String(out.toByteArray()).trim(); } @Test public void testGetDateRange() throws Exception { // running request MockHttpServletResponse response = getAsServletResponse( RestBaseController.ROOT_PATH + "/monitor/requests.csv?fields=id;path;startTime&from=2010-07-23T15:56:44&to=2010-07-23T16:16:44"); assertEquals(200, response.getStatus()); assertCoveredInOrder(response, 6, 5, 4); } @Test public void testGetDateRangeWithTimeZone() throws Exception { // running request MockHttpServletResponse response = getAsServletResponse( RestBaseController.ROOT_PATH + "/monitor/requests.csv?fields=id;path;startTime&from=2010-07-23T15:56:44+0000&to=2010-07-23T16:16:44+0000"); assertEquals(200, response.getStatus()); assertCoveredInOrder(response, 6, 5, 4); } @Test public void testFilter() throws Exception { MockHttpServletResponse response = getAsServletResponse( RestBaseController.ROOT_PATH + "/monitor/requests.csv?fields=id;path;startTime&filter=path:EQ:/seven"); assertEquals(200, response.getStatus()); assertCoveredInOrder(response, 7); } @Test public void testFilterIn() throws Exception { MockHttpServletResponse response = getAsServletResponse( RestBaseController.ROOT_PATH + "/monitor/requests.csv?fields=id;path;startTime&filter=path:IN:/seven,/six,/five"); assertEquals(200, response.getStatus()); assertCovered(response, 5, 6, 7); } @Test public void testFilterStatus() throws Exception { MockHttpServletResponse response = getAsServletResponse( RestBaseController.ROOT_PATH + "/monitor/requests.csv?fields=id;path;startTime&filter=status:EQ:WAITING"); assertEquals(200, response.getStatus()); assertCovered(response, 2, 6); } @Test public void testSorting() throws Exception { MockHttpServletResponse response = getAsServletResponse( RestBaseController.ROOT_PATH + "/monitor/requests.csv?fields=id;path;startTime&order=path"); assertEquals(200, response.getStatus()); assertCoveredInOrder(response, 8, 5, 4, 9, 1, 7, 6, 10, 3, 2); response = getAsServletResponse( RestBaseController.ROOT_PATH + "/monitor/requests.csv?fields=id;path;startTime&order=path;ASC"); assertEquals(200, response.getStatus()); assertCoveredInOrder(response, 8, 5, 4, 9, 1, 7, 6, 10, 3, 2); response = getAsServletResponse( RestBaseController.ROOT_PATH + "/monitor/requests.csv?fields=id;path;startTime&order=path;DESC"); assertEquals(200, response.getStatus()); assertCoveredInOrder(response, 2, 3, 10, 6, 7, 1, 9, 4, 5, 8); } @Test public void testPaging() throws Exception { MockHttpServletResponse response = getAsServletResponse( RestBaseController.ROOT_PATH + "/monitor/requests.csv?fields=id;path;startTime&order=startTime&offset=5&count=2"); assertEquals(200, response.getStatus()); assertCoveredInOrder(response, 6, 7); } @Test public void testLive() throws Exception { MockHttpServletResponse response = getAsServletResponse( RestBaseController.ROOT_PATH + "/monitor/requests.csv?fields=id;path;startTime&live=yes"); assertEquals(200, response.getStatus()); assertCovered(response, 1, 2, 5, 6, 9, 10); } private void assertCoveredInOrder(MockHttpServletResponse response, int... expectedIds) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(response.getContentAsByteArray()))); // skip the header line String line = in.readLine(); Iterator<Integer> it = Arrays.stream(expectedIds).iterator(); while ((line = in.readLine()) != null) { assertTrue(it.hasNext()); Integer id = it.next(); assertThat(line, startsWith("" + id)); } assertFalse(it.hasNext()); } public static void assertCovered(MockHttpServletResponse response, int... expectedIds) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(response.getContentAsByteArray()))); // skip the header line String line = in.readLine(); Set<Integer> actualIds = new HashSet<>(); while ((line = in.readLine()) != null) { String[] split = line.split("\\s*,\\s*"); actualIds.add(Integer.parseInt(split[0])); } assertEquals(expectedIds.length, actualIds.size()); for (int i = 0; i < expectedIds.length; i++) { assertThat(actualIds, hasItem(expectedIds[i])); } } }