All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.byteman.contrib.dtest.InstrumentedClass Maven / Gradle / Ivy

/*
 * JBoss, Home of Professional Open Source
 * Copyright 2010, Red Hat, Inc. and/or its affiliates,
 * and individual contributors as indicated by the @author tags.
 * See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License, v. 2.1.
 * This program is distributed in the hope that it will be useful, but WITHOUT A
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public License,
 * v.2.1 along with this distribution; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301, USA.
 *
 * (C) 2010,
 * @author JBoss, by Red Hat.
 */
package org.jboss.byteman.contrib.dtest;

import java.rmi.RemoteException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import static org.junit.Assert.assertEquals;

/**
 * InstrumentedClass instances serve two purposes:
 *
 * Internally to the framework they provide a communication endpoint for
 * receiving information from the remote, Byteman instrumented code execution.
 *
 * To the framework user, they provide utility methods for verifying expectations relating
 * to that remote execution e.g. the number of method calls made.
 *
 * @author Jonathan Halliday ([email protected]) 2010-05
 */
public class InstrumentedClass implements RemoteInterface
{
    private static final Integer STATIC_INSTANCE_ID = new Integer(-1);

    private final String className;
    private final Map instrumentedInstances = new ConcurrentHashMap();

    InstrumentedClass(String className)
    {
        this.className = className;
    }

    /**
     * Receiving side of the remote communication between the test code and the BytemanTestHelper.
     *
     * @param methodName the method name that was traced.
     * @param args the arguments to the method invocation, in String form.
     * @throws RemoteException in case of communication failure.
     * @see BytemanTestHelper#remoteTrace(String, String, Object[])
     */
    @Override
    public void trace(String methodName, Object[] args) throws RemoteException
    {
        Integer objectId = (Integer) args[0];
        if(objectId == null)
        {
            objectId = STATIC_INSTANCE_ID;
        }

        InstrumentedInstance createdInstrumentedInstance = new InstrumentedInstance(className, objectId);
        InstrumentedInstance instrumentedInstance = instrumentedInstances.putIfAbsent(objectId, createdInstrumentedInstance);
        if(instrumentedInstance == null) {
            instrumentedInstance = createdInstrumentedInstance;
        }

        Object[] innerArgs = new Object[args.length-1];
        System.arraycopy(args, 1, innerArgs, 0, innerArgs.length);

        instrumentedInstance.addMethodTrace(methodName, innerArgs);
    }

    /**
     * Returns the set of known instances of the class.
     *
     * @return a Set of Objects representing instances of the class.
     */
    public Set getInstances()
    {
        return new HashSet(instrumentedInstances.values());
    }

    /**
     * Returns number of method calls for the class.
* Sum number of method calls on all instrumented instances * belonging to this instrumented class. * It's sum of all method calls for all known instrumented instances. * * @param methodName name of method which we are interested in how many times was called * @return number of method calls on the class (sum of method calls of all instances) */ public int getInvocationCount(String methodName) { int invocationCount = 0; for(InstrumentedInstance instance: getInstances()) { invocationCount += instance.getInvocationCount(methodName); } return invocationCount; } /** * Checks that the number of known, distinct object instances of this class is as stated. * * @param count the expected number of instances of the class. */ public void assertKnownInstances(int count) { assertEquals("Number of known instances of " + className + " does not match", count, instrumentedInstances.size()); } /** * Checks that the number of known invocations of the given method falls within the specified * range for each known instances of the class. * * @param message the message to print in case of assertion failure. * @param methodName the method name to look for. * @param callCount the expected range for the invocation count. */ public void assertMethodCallCount(String message, String methodName, CallCount callCount) { for(InstrumentedInstance instance : getInstances()) { instance.assertMethodCallCount(message, methodName, callCount); } } /** * Checks that the number of known invocations of the given method is specified count. * * @param message the message to print in case of assertion failure. * @param methodName the method name to look for. * @param callCount the expected number of the invocation count. */ public void assertMethodCallCount(String message, String methodName, int callCount) { assertMethodCallCount(message, methodName, new CallCount(callCount, callCount)); } /** * Checks that the number of known invocations of the given method is specified count. * * @param methodName the method name to look for. * @param callCount the expected number of the invocation count. */ public void assertMethodCallCount(String methodName, int callCount) { assertMethodCallCount(null, methodName, new CallCount(callCount, callCount)); } /** * Check that number of known invocations of the given method of all known instances * is specified count.
* Difference against {@link #assertMethodCallCount(String, int)} is that here we query * against all know instances. The other method query each instance to be called * by the specific number times. * * @param method the method name to look for * @param callCount the expected number of the invocation count summed on all instances */ public void assertSumMethodCallCount(String method, int callCount) { assertEquals("Method " + className + "#" + method + " was not called " + callCount + " times", callCount, getInvocationCount(method)); } /** * Checks that the given method has been called at least once on each known instance of the class. * Uses junit internally, hence expect the normal exception throwing in case of failure. * * @param methodName the method name to look for. */ public void assertMethodCalled(String methodName) { assertMethodCallCount(null, methodName, new CallCount(1, Integer.MAX_VALUE)); } /** * Checks that the given method has not been seen to be called on any known instance of the class. * Uses junit internally, hence expect the normal exception throwing in case of failure. * * @param methodName the method name to look for. */ public void assertMethodNotCalled(String methodName) { assertMethodCallCount(null, methodName, new CallCount(0, 0)); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy