/** * Analytica - beta version - Systems Monitoring Tool * * Copyright (C) 2013, KleeGroup, direction.technique@kleegroup.com (http://www.kleegroup.com) * KleeGroup, Centre d'affaire la Boursidi�re - BP 159 - 92357 Le Plessis Robinson Cedex - France * * This program is free software; you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Foundation; * either version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program; * if not, see <http://www.gnu.org/licenses> * * Linking this library statically or dynamically with other modules is making a combined work based on this library. * Thus, the terms and conditions of the GNU General Public License cover the whole combination. * * As a special exception, the copyright holders of this library give you permission to link this library * with independent modules to produce an executable, regardless of the license terms of these independent modules, * and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, * for each linked independent module, the terms and conditions of the license of that module. * An independent module is a module which is not derived from or based on this library. * If you modify this library, you may extend this exception to your version of the library, * but you are not obliged to do so. * If you do not wish to do so, delete this exception statement from your version. */ package io.analytica.spies.impl.javassist; import io.analytica.AbstractAnalyticaTestCaseJU4; import io.analytica.spies.imp.javassist.AnalyticaSpyAgent; import io.analytica.spies.imp.javassist.agentloader.VirtualMachineAgentLoader; import java.io.File; import java.net.URISyntaxException; import java.net.URL; import org.junit.Assert; import org.junit.Test; /** * Implementation d'un agent de jvm. * Celui ci doit etre inclus dans un jar et pass� en parametre � la jvm : * <code>-javaagent:"monjar.jar"=option</code> * Ce jar doit avoir un manifest qui contient la ligne suivante : * <code>Premain-Class: io.analytica.spies.imp.javassist.AnalyticaSpyAgent</code> * * Cet agent ajoute un ClassFileTransformer sp�cifique qui a pour but d'instrumenter * les m�thodes selon un param�trage externe. * L'option de l'agent dans la ligne de commande repr�sente le nom du fichier de param�trage. * * @author npiedeloup * @version $Id: MemoryLeakAgent.java,v 1.2 2012/09/28 09:30:03 pchretien Exp $ */ public final class AnalyticaSpyAgentTest extends AbstractAnalyticaTestCaseJU4 { private static final String TEST1_CLASS_NAME = "io.analytica.spies.impl.javassist.TestAnalyse"; private static final String TEST2_CLASS_NAME = "io.analytica.spies.impl.javassist.TestAnalyse2"; private static final String TEST3_CLASS_NAME = "io.analytica.spies.impl.javassist.TestAnalyse3"; //private static final String TEST3_PARENT_CLASS_NAME = "io.analytica.spies.impl.javassist.ParentTestAnalyse"; /** * Demarre l'agent de supervision des cr�ation d'instances. */ public static void startAgent() { final File agentJar = getFile("analyticaAgent-1.4.1.jar", AnalyticaSpyAgentTest.class); final File propertiesFile = getFile("testJavassistAnalyticaSpy.json", AnalyticaSpyAgentTest.class); VirtualMachineAgentLoader.loadAgent(agentJar.getAbsolutePath(), propertiesFile.getAbsolutePath()); } /** {@inheritDoc} */ @Override public void doSetUp() throws Exception { //on charge la class avant pour s'assurer que le load fonctionne classForName(TestAnalyse.class.getName()); startAgent(); startServer(); } /** * R�cup�ration d'une classe non typ�e � partir de son nom. * * @param javaClassName Nom de la classe * @return Classe java */ private static Class<?> classForName(final String javaClassName) { try { return Class.forName(javaClassName); } catch (final ClassNotFoundException e) { throw new RuntimeException("Class not found : " + javaClassName, e); } } /** {@inheritDoc} */ @Override protected void doTearDown() throws Exception { AnalyticaSpyAgent.stopAgent(); } @Override protected void flushAgentToServer() { try { Thread.sleep(5000);//on attend 2s que le process soit envoy� au serveur. } catch (final InterruptedException e) { //rien on stop juste l'attente } } /** * R�cup�re un File (pointeur de fichier) vers un fichier relativement � une class. * @param fileName Nom/path du fichier * @param baseClass Class de base pour le chemin relatif * @return File */ private static File getFile(final String fileName, final Class<?> baseClass) { final URL fileURL = baseClass.getResource(fileName); try { return new File(fileURL.toURI()); } catch (final URISyntaxException e) { throw new RuntimeException(e); } } /** * Test simple avec deux compteurs. * Test sur l'envoi de 1000 articles d'un poids de 25 kg. * Chaque article coute 10�. */ @Test public void testJavassistWork1s() { new TestAnalyse().work1s(); flushAgentToServer(); checkMetricCount("HMDURATION", 1, "JAVASSIST", TEST1_CLASS_NAME, "work1s"); } /** * Test d'un traitement qui fait une erreur. * Le process doit-�tre captur� malgr� tout */ @Test public void testJavassistWorkError() { try { new TestAnalyse().workError(); Assert.fail("workError n'a pas lanc�e d'exception"); } catch (final Exception e) { //on veut v�rifier que le process est renseign� apr�s l'exception } flushAgentToServer(); checkMetricCount("HMDURATION", 1, "JAVASSIST", TEST1_CLASS_NAME, "workError"); checkMetricMean("ME_ERROR_PCT", 100, "JAVASSIST", TEST1_CLASS_NAME, "workError"); } @Test public void testJavassistWorkResult() { final int result = new TestAnalyse().workResult(); Assert.assertEquals(1, result); flushAgentToServer(); checkMetricCount("HMDURATION", 1, "JAVASSIST", TEST1_CLASS_NAME, "workResult"); } @Test public void testJavassistWorkReentrant() { new TestAnalyse().workReentrant(); flushAgentToServer(); checkMetricCount("HMDURATION", 1, "JAVASSIST", TEST1_CLASS_NAME, "workReentrant"); checkMetricCount("HMDURATION", 1, "JAVASSIST", TEST1_CLASS_NAME, "work1s"); } @Test public void testJavassistWorkInterface() { new TestAnalyse2().workInterface(); flushAgentToServer(); checkMetricCount("HMDURATION", 1, "JAVASSIST", TEST2_CLASS_NAME, "workInterface"); } @Test public void testJavassistWorkParent() { new TestAnalyse3().workParent(); flushAgentToServer(); checkMetricCount("HMDURATION", 1, "JAVASSIST", TEST3_CLASS_NAME, "workParent"); } @Test public void testJavassistWorkParentAbstract() { new TestAnalyse3().workParentAbstract(); flushAgentToServer(); checkMetricCount("HMDURATION", 1, "JAVASSIST", TEST3_CLASS_NAME, "workParentAbstract"); } /** * Test simple avec deux compteurs. * Test sur l'envoi de 1000 articles d'un poids de 25 kg. * Chaque article coute 10�. */ @Test public void testJavassistWorkStatic() { TestAnalyse.workStatic(); flushAgentToServer(); checkMetricCount("HMDURATION", 1, "JAVASSIST", TEST1_CLASS_NAME, "workStatic"); } /** * Test simple avec deux compteurs. * Test sur l'envoi de 1000 articles d'un poids de 25 kg. * Chaque article coute 10�. */ @Test public void testInstrumentPerf() { for (int i = 0; i < 10; i++) { new TestAnalyse().workFastest(); new TestAnalyse().workFastestNotInstrumented(); } final int nbLoop = 100000; final long start = System.currentTimeMillis(); for (int i = 0; i < nbLoop; i++) { new TestAnalyse().workFastest(); } final long timeInstrumented = System.currentTimeMillis() - start; final long startNotInstrumented = System.currentTimeMillis(); for (int i = 0; i < nbLoop; i++) { new TestAnalyse().workFastestNotInstrumented(); } final long timeNotInstrumented = System.currentTimeMillis() - startNotInstrumented; final long delta = timeInstrumented - timeNotInstrumented; final long percent = timeNotInstrumented > 0 ? delta * 100 / timeNotInstrumented : 0; System.out.println("Time Instrumentation : " + delta + " ms pour " + nbLoop + " soit " + percent + "% de " + timeNotInstrumented + " ms (" + delta * 1000 / nbLoop / 1000d + "ms par appel)"); flushAgentToServer(); checkMetricCount("HMDURATION", nbLoop + 10, "JAVASSIST", TEST1_CLASS_NAME, "workFastest"); } /** * Test simple avec deux compteurs. * Test sur l'envoi de 1000 articles d'un poids de 25 kg. * Chaque article coute 10�. */ @Test public void testActivateDesactivate() { new TestAnalyse().work1s(); flushAgentToServer(); checkMetricCount("HMDURATION", 1, "JAVASSIST", TEST1_CLASS_NAME, "work1s"); AnalyticaSpyAgent.stopAgent(); new TestAnalyse().work1s(); flushAgentToServer(); checkMetricCount("HMDURATION", 1, "JAVASSIST", TEST1_CLASS_NAME, "work1s"); startAgent(); new TestAnalyse().work1s(); flushAgentToServer(); checkMetricCount("HMDURATION", 2, "JAVASSIST", TEST1_CLASS_NAME, "work1s"); } /** * Test simple avec deux compteurs. * Test sur l'envoi de 1000 articles d'un poids de 25 kg. * Chaque article coute 10�. */ @Test public void testActivateDesactivateSameInstance() { final TestAnalyse testAnalyse = new TestAnalyse(); testAnalyse.work1s(); flushAgentToServer(); checkMetricCount("HMDURATION", 1, "JAVASSIST", TEST1_CLASS_NAME, "work1s"); AnalyticaSpyAgent.stopAgent(); testAnalyse.work1s(); flushAgentToServer(); checkMetricCount("HMDURATION", 1, "JAVASSIST", TEST1_CLASS_NAME, "work1s"); startAgent(); testAnalyse.work1s(); flushAgentToServer(); checkMetricCount("HMDURATION", 2, "JAVASSIST", TEST1_CLASS_NAME, "work1s"); } }