package de.twenty11.skysail.server.ext.osgi.monitor.agent.test; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import java.io.File; import java.io.FileInputStream; import java.lang.instrument.IllegalClassFormatException; import javassist.ClassPool; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.osgi.framework.Bundle; import org.slf4j.Logger; import com.google.common.io.ByteStreams; import de.twenty11.skysail.server.ext.osgi.monitor.agent.OsgiFrameworkTransformer; import de.twenty11.skysail.server.ext.osgi.monitor.agent.callback.CallbackDefinition; import de.twenty11.skysail.server.ext.osgi.monitor.agent.callback.Callbacks; import de.twenty11.skysail.server.ext.osgi.monitor.agent.callback.bundle.BundleCallback; public class OsgiFrameworkTransformerTest { private OsgiFrameworkTransformer transformer; private ClassLoader loader; private ClassPool pool = ClassPool.getDefault(); private Logger logger = Mockito.mock(Logger.class); private Logger agentLogger; @Before public void setUp() throws Exception { loader = Mockito.mock(ClassLoader.class); agentLogger = Mockito.mock(Logger.class); transformer = new OsgiFrameworkTransformer(pool, defineCallbacks(), logger); pool.appendClassPath(getPathForClass(OsgiFrameworkTransformerTest.class)); pool.appendClassPath(getPathForClass(BundleCallback.class)); } private Callbacks defineCallbacks() { Callbacks callbacks = new Callbacks(); callbacks.add(new CallbackDefinition(new BundleCallback(), agentLogger)); return callbacks; } @Test public void keeps_standard_classes_identical() throws IllegalClassFormatException { byte[] transformed = transformer.transform(loader, String.class.getCanonicalName(), String.class, null, new byte[] { 'a', 'b', 'c' }); assertThat(new Byte(transformed[0]).intValue(), is(97)); // = 'a' assertThat(new Byte(transformed[1]).intValue(), is(98)); assertThat(new Byte(transformed[2]).intValue(), is(99)); } @Test public void test2() throws Exception { byte[] byteArray = ByteStreams.toByteArray(new FileInputStream(new File(getPathForClass(MyBundleImpl.class)))); byte[] transformed = transformer.transform(loader, MyBundleImpl.class.getName(), MyBundleImpl.class, null, byteArray); Bundle transformedClassInstance = (Bundle) createClass(transformed, MyBundleImpl.class.getName()); transformedClassInstance.start(); } @Test public void calls_callback_code_when_bundle_is_started() throws Exception { byte[] byteArray = ByteStreams.toByteArray(new FileInputStream(new File( getPathForClass(MyBundleImpl.class)))); byte[] transformed = transformer.transform(loader, MyBundleImpl.class.getName(), MyBundleImpl.class, null, byteArray); Bundle transformedClassInstance = (Bundle) createClass(transformed, MyBundleImpl.class.getName()); try { transformedClassInstance.start(); } catch (Exception e) { // ok,ok } Mockito.verify(agentLogger, Mockito.times(1)).info(Mockito.anyString()); } @Test public void calls_exception_code_when_exception_is_thrown_in_bundleStartMethod() throws Exception { pool.appendClassPath(getPathForClass(OsgiFrameworkTransformerTest.class)); pool.appendClassPath(getPathForClass(BundleCallback.class)); byte[] byteArray = ByteStreams.toByteArray(new FileInputStream(new File( getPathForClass(MyBundleWithStartExceptionImpl.class)))); byte[] transformed = transformer.transform(loader, MyBundleWithStartExceptionImpl.class.getName(), MyBundleWithStartExceptionImpl.class, null, byteArray); Bundle transformedClassInstance = (Bundle) createClass(transformed, MyBundleWithStartExceptionImpl.class.getName()); try { transformedClassInstance.start(); } catch (Exception e) { // ok,ok } Mockito.verify(agentLogger, Mockito.times(1)).error(Mockito.anyString());// Mockito.anyVararg()); } private Object createClass(byte[] transformed, String myBundleClassName) throws Exception { FromMemoryClassLoader mcl = new FromMemoryClassLoader(transformed); Class<?> transformedClass = mcl.findClass(myBundleClassName); return transformedClass.newInstance(); } private String getPathForClass(Class<?> cls) { return cls.getResource(cls.getSimpleName() + ".class").getPath(); } }