/* * Copyright 2008-2017 by Emeric Vernat * * This file is part of Java Melody. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.bull.javamelody; import static org.easymock.EasyMock.createNiceMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import org.junit.After; import org.junit.Before; import org.junit.Test; /** * Test unitaire de la classe Counter. * @author Emeric Vernat */ public class TestCounter { private Counter counter; /** Initialisation. */ @Before public void setUp() { Utils.initialize(); counter = new Counter("test", null); counter.bindContext("bind context", "bind my context", null, -1); } /** Finalisation. */ @After public void tearDown() { counter.unbindContext(); } private CounterRequest createCounterRequest() { final CounterRequest request = new CounterRequest("test Counter", counter.getName()); request.addHit(100, 50, false, null, 1000); return request; } /** Test. */ @Test public void testAddRequest() { final CounterRequest request = createCounterRequest(); // ce bindContext pour tester le cas où une requête est ajoutée avec un contexte et un contexte parent // puis une requête ajoutée avec un contexte sans contexte parent counter.bindContext(request.getName(), request.getName(), null, -1); counter.addRequest(request.getName(), request.getMean(), 0, false, request.getResponseSizeMean()); final List<CounterRequest> before = counter.getOrderedRequests(); counter.addRequest(request.getName(), request.getMean(), 0, false, request.getResponseSizeMean()); counter.setRequestTransformPattern(Pattern.compile("aaaaa")); counter.addRequest(request.getName(), request.getMean(), 0, false, request.getResponseSizeMean()); final List<CounterRequest> after = counter.getOrderedRequests(); after.get(0).removeHits(request); after.get(0).removeHits(request); // on teste le contenu des CounterRequest par le contenu de toString assertEquals("requests", before.toString(), after.toString()); // test addChildRequest dans addRequest final Counter sqlCounter = new Counter("sql", null); final Counter httpCounter = new Counter("http", null, sqlCounter); httpCounter.bindContext("http request", "http request", null, -1); final String sqlRequest = "sql request"; sqlCounter.bindContext(sqlRequest, sqlRequest, null, -1); sqlCounter.addRequest(sqlRequest, 0, 0, false, -1); // ici context.addChildRequest sqlCounter.addRequest(sqlRequest, 0, 0, false, -1); // 2ème pour passer dans le else de addChildRequestForDrillDown httpCounter.addRequest("http request", 10, 2, false, 100); } /** Test. */ @Test public void testAddRequestForSystemError() { final CounterRequest request = createCounterRequest(); final Counter errorCounter = new Counter(Counter.ERROR_COUNTER_NAME, null); errorCounter.setMaxRequestsCount(200); errorCounter.addRequestForSystemError(request.getName(), request.getMean(), 0, null); final List<CounterRequest> before = errorCounter.getOrderedRequests(); errorCounter.addRequestForSystemError(request.getName(), request.getMean(), 0, "stacktrace"); final List<CounterRequest> after = errorCounter.getOrderedRequests(); after.get(0).removeHits(request); // on teste le contenu des CounterRequest par le contenu de toString assertEquals("error requests", before.toString(), after.toString()); int i = 0; while (errorCounter.getRequestsCount() < Counter.MAX_ERRORS_COUNT) { errorCounter.addRequestForSystemError("request a" + i, 1, 0, null); i++; } errorCounter.addRequestForSystemError("request a" + i, 1, 0, null); errorCounter.clear(); i = 0; while (errorCounter.getRequestsCount() < Counter.MAX_ERRORS_COUNT) { errorCounter.bindContextIncludingCpu("request b" + i); errorCounter.addRequestForCurrentContext("stack trace"); i++; } errorCounter.bindContextIncludingCpu("request b" + i); errorCounter.addRequestForCurrentContext("stack trace"); // addRequestForCurrentContext mais sans contexte courant errorCounter.addRequestForCurrentContext("stack trace"); errorCounter.addRequestForCurrentContext(true); } /** Test. */ @Test public void testAddHits() { final CounterRequest counterRequest = createCounterRequest(); counter.addHits(counterRequest); final List<CounterRequest> before = counter.getOrderedRequests(); counter.addHits(counterRequest); counter.addHits(new CounterRequest("test", counter.getName())); final List<CounterRequest> after = counter.getOrderedRequests(); after.get(0).removeHits(counterRequest); // on teste le contenu des CounterRequest par le contenu de toString assertEquals("requests", before.toString(), after.toString()); // on remet counterRequests.getHits() à 0 counterRequest.removeHits(counterRequest); // on teste l'ajout de hits avec counterRequests à 0 hit(s) counter.addHits(counterRequest); } /** Test. */ @Test public void testCounterRequestRemoveHits() { final CounterRequest counterRequest = createCounterRequest(); final CounterRequest counterRequest2 = createCounterRequest(); // test de CounterRequest.removeHits (avec counterRequest2.hits == 0) counterRequest.removeHits(counterRequest2); counterRequest2.addHit(0, 0, false, null, -1); // test de CounterRequest.removeHits (counterRequest2.hits doit être != 0) counterRequest.removeHits(counterRequest2); final String childId1 = "test"; counterRequest2.addChildRequests(Collections.singletonMap(childId1, 0L)); // test de CounterRequest.removeHits counterRequest.removeHits(counterRequest2); // test de CounterRequest.removeHits final String childId2 = "autre test"; counterRequest.addChildRequests(Collections.singletonMap(childId2, 0L)); counterRequest.removeHits(counterRequest2); // test de CounterRequest.removeHits counterRequest.addChildRequests(Collections.singletonMap(childId1, 0L)); counterRequest.removeHits(counterRequest2); // test de CounterRequest.removeHits counterRequest2.addChildRequests(Collections.singletonMap(childId2, 0L)); counterRequest.removeHits(counterRequest2); } /** Test. */ @Test public void testRemoveRequest() { final int count = counter.getRequestsCount(); counter.addRequest("remove request", 100, 50, false, 1000); counter.removeRequest("remove request"); assertEquals("requests count", count, counter.getRequestsCount()); } /** Test. */ @Test public void testAddRequests() { final CounterRequest counterRequest = createCounterRequest(); counter.addHits(counterRequest); counter.bindContext("context", "context", null, -1); final CounterRequest counterRequestWithoutHits = counter .getCounterRequest(counter.getOrderedRootCurrentContexts().get(0)); counter.addHits(counterRequestWithoutHits); final List<CounterRequest> before = counter.getOrderedRequests(); // ajout d'une instance de compteur avec requêtes qui ont des hits ou pas counter.addRequestsAndErrors(counter); final List<CounterRequest> after = counter.getOrderedRequests(); after.get(0).removeHits(counterRequest); // on teste le contenu des CounterRequest par le contenu de toString assertEquals("requests", before.toString(), after.toString()); // test de la limitation à maxRequestsCount dans l'ajout de requêtes final Counter counter2 = new Counter(counter.getName(), null); counter2.addRequest("request 2", 100, 50, false, 100); for (int i = 0; i < 20; i++) { counter2.addRequest("request 3", 100, 50, false, 100); } counter.setMaxRequestsCount(1); counter.addRequestsAndErrors(counter2); assertEquals("count", 1, counter.getRequestsCount()); for (int i = 0; i < 20; i++) { counter2.addRequest("request 4", 100, 50, false, 100); } counter.addRequestsAndErrors(counter2); assertEquals("count", 2, counter.getRequestsCount()); } /** Test. */ @Test public void testAddErrors() { final CounterError beforeError = new CounterError("before", null); assertNotNull("CounterError.toString()", beforeError.toString()); try { Thread.sleep(50); } catch (final InterruptedException e) { throw new IllegalStateException(e); } final Counter errorCounter = new Counter(Counter.ERROR_COUNTER_NAME, null); CounterError.bindRequest(null); CounterError.unbindRequest(); final HttpServletRequest httpRequest = createNiceMock(HttpServletRequest.class); expect(httpRequest.getAttribute(CounterError.REQUEST_KEY)).andReturn("/test GET"); expect(httpRequest.getRemoteUser()).andReturn("me"); replay(httpRequest); CounterError.bindRequest(httpRequest); assertNotNull("new CounterError", new CounterError("with request", null)); CounterError.unbindRequest(); verify(httpRequest); final int errorsCount = errorCounter.getErrorsCount(); final List<CounterError> errors = new ArrayList<CounterError>(); errors.add(new CounterError("erreur", null)); errors.add(new CounterError("erreur", "stacktrace")); errorCounter.addErrors(errors); errors.add(0, beforeError); errorCounter.addErrors(errors); assertEquals("addErrors", errorsCount + 5, errorCounter.getErrorsCount()); while (errorCounter.getErrorsCount() < Counter.MAX_ERRORS_COUNT) { errorCounter.addErrors(errors); } errorCounter.addErrors(errors); } /** Test. */ @Test public void testGetErrors() { assertTrue("getErrors", counter.getErrors().isEmpty()); assertNotNull("getErrors", new Counter(Counter.ERROR_COUNTER_NAME, null).getErrors()); } /** Test. */ @Test public void testClear() { counter.addRequest("test clear", 100, 50, false, 1000); counter.clear(); assertEquals("requests count", 0, counter.getRequestsCount()); } /** Test. */ @Test public void testGetCounterRequest() { counter.unbindContext(); final String requestName = "get counter request"; counter.bindContext(requestName, "my context", null, -1); final CounterRequest counterRequest = counter .getCounterRequest(counter.getOrderedRootCurrentContexts().get(0)); assertEquals("request name", requestName, counterRequest.getName()); } /** Test. */ @Test public void testGetOrderedRequests() { counter.clear(); counter.addRequest("test a", 0, 0, false, 1000); counter.addRequest("test b", 1000, 500, false, 1000); // supérieur counter.addRequest("test c", 1000, 500, false, 1000); // égal counter.addRequest("test d", 100, 50, false, 1000); // inférieur final List<CounterRequest> requests = counter.getOrderedRequests(); assertEquals("requests size", 4, requests.size()); } /** Test. */ @Test public void testGetOrderedByHitsRequests() { counter.clear(); counter.addRequest("test 1", 0, 0, false, 1000); counter.addRequest("test 2", 1000, 500, false, 1000); // supérieur en hits counter.addRequest("test 2", 1000, 500, false, 1000); counter.addRequest("test 2", 1000, 500, false, 1000); counter.addRequest("test 3", 100, 50, false, 1000); // égal counter.addRequest("test 4", 100, 50, false, 1000); // inférieur counter.addRequest("test 4", 100, 50, false, 1000); final List<CounterRequest> requests = counter.getOrderedByHitsRequests(); assertEquals("requests size", 4, requests.size()); } /** Test. */ @Test public void testGetOrderedRootCurrentContexts() { counter.unbindContext(); final String requestName = "root context"; final int nbRootContexts = 100; // 100 pour couvrir tous les cas du compartor de tri bindRootContexts(requestName, counter, nbRootContexts); // addRequest pour rentrer dans le if de la map dans CounterRequestContext.clone counter.addRequest(requestName, 100, 100, false, 1000); final List<CounterRequestContext> rootContexts = counter.getOrderedRootCurrentContexts(); assertEquals("contexts size", nbRootContexts + 1, rootContexts.size()); assertEquals("context name", requestName, rootContexts.get(0).getRequestName()); final String string = rootContexts.get(0).toString(); assertNotNull("toString not null", string); assertFalse("toString not empty", string.isEmpty()); } static void bindRootContexts(String firstRequestName, Counter myCounter, int nbRootContexts) { myCounter.bindContext(firstRequestName, "my context", null, -1); myCounter.bindContext("child context", "my child context", null, -1); // on crée d'autres racines de contexte try { Thread.sleep(100); for (int i = 0; i < nbRootContexts; i++) { bindRootContext(myCounter).join(1000); } } catch (final InterruptedException e) { fail(e.toString()); } } private static Thread bindRootContext(final Counter myCounter) { final Thread thread = new Thread(new Runnable() { @Override public void run() { // bindContext avec un remoteUser pour avoir au moins un cas d'affichage de l'utilisateur myCounter.bindContext("second root context", "my context", "me", -1); } }); thread.setDaemon(true); thread.start(); return thread; } /** Test. */ @Test public void testGetRequests() { counter.clear(); final CounterRequest counterRequest = createCounterRequest(); counter.addHits(counterRequest); final List<CounterRequest> requests = counter.getRequests(); assertEquals("requests size", 1, requests.size()); assertEquals("request", counterRequest.toString(), requests.get(0).toString()); } /** Test. */ @Test public void testGetRequestsCount() { counter.addRequest("test requests count", 100, 50, false, 1000); assertEquals("requests count", counter.getRequests().size(), counter.getRequestsCount()); } /** Test. */ @Test public void testApplication() { final String value = "app"; assertNotSame(value, counter.getApplication()); counter.setApplication(value); assertSame("application", value, counter.getApplication()); } /** Test. */ @Test public void testRequestTransformPattern() { final Pattern value = Pattern.compile("a*"); assertNotSame(value, counter.getRequestTransformPattern()); counter.setRequestTransformPattern(value); assertSame("request transform pattern", value, counter.getRequestTransformPattern()); } /** Test. */ @Test public void testStartDate() { final Date value = new Date(System.currentTimeMillis() + 1000); assertNotSame(value, counter.getStartDate()); counter.setStartDate(value); assertSame("start date", value, counter.getStartDate()); } /** Test. */ @Test public void testDisplayed() { final boolean value = false; assertNotSame(value, counter.isDisplayed()); counter.setDisplayed(value); assertSame("displayed", value, counter.isDisplayed()); } /** Test. */ @Test public void testErrorCounter() { final String message = "errorCounter"; assertFalse(message, new Counter("http", null).isErrorCounter()); assertTrue(message, new Counter("error", null).isErrorCounter()); assertTrue(message, new Counter("log", null).isErrorCounter()); assertTrue(message, new Counter("job", null).isErrorCounter()); } /** Test. */ @Test public void testJobCounter() { assertFalse("jobCounter", new Counter("spring", null).isJobCounter()); assertTrue("jobCounter", new Counter("job", null).isJobCounter()); } /** Test. */ @Test public void testJspOrStrutsCounter() { assertFalse("jspOrStrutsCounter", new Counter("http", null).isJspOrStrutsCounter()); assertTrue("jspOrStrutsCounter", new Counter("jsp", null).isJspOrStrutsCounter()); assertTrue("jspOrStrutsCounter", new Counter("struts", null).isJspOrStrutsCounter()); } /** Test. */ @Test public void testBusinessFacadeCounter() { final String message = "businessFacadeCounter"; assertFalse(message, new Counter("log", null).isBusinessFacadeCounter()); assertTrue(message, new Counter("services", null).isBusinessFacadeCounter()); assertTrue(message, new Counter("ejb", null).isBusinessFacadeCounter()); assertTrue(message, new Counter("spring", null).isBusinessFacadeCounter()); assertTrue(message, new Counter("guice", null).isBusinessFacadeCounter()); } /** Test. * @throws IOException e */ @Test public void testReadFromFile() throws IOException { // test pour un counter vide counter.clear(); counter.writeToFile(); counter.readFromFile(); // test pour un counter non vide final CounterRequest counterRequest = createCounterRequest(); counter.addHits(counterRequest); counter.writeToFile(); // readFromFile ajoute les requêtes lues aux requêtes actuelles counter.readFromFile(); assertEquals("request hits", counterRequest.getHits() * 2, counter.getRequests().get(0).getHits()); counter.clear(); counter.readFromFile(); assertEquals("request", counterRequest.toString(), counter.getRequests().get(0).toString()); } /** Test. * @throws IOException e */ @Test public void testWriteToFile() throws IOException { // test pour un counter vide counter.clear(); counter.writeToFile(); // test pour un counter non vide final Counter errorCounter = new Counter(Counter.ERROR_COUNTER_NAME, null); errorCounter.addErrors(Collections.singletonList(new CounterError("erreur", null))); errorCounter.writeToFile(); counter.addRequest("test writeToFile", 100, 50, false, 1000); final String before = counter.toString(); counter.writeToFile(); assertEquals("counter", before, counter.toString()); } /** Test. */ @Test public void testToString() { counter.addRequest("test toString", 100, 50, false, 1000); final String string = counter.toString(); assertNotNull("toString not null", string); assertFalse("toString not empty", string.isEmpty()); final String string2 = new Counter(Counter.ERROR_COUNTER_NAME, null).toString(); assertNotNull("toString not null", string2); assertFalse("toString not empty", string2.isEmpty()); if (createCounterRequest().toString().isEmpty()) { fail("toString vide"); } } }