blob: 6a2f9c69bc38e7e084b8795b956b06b5907b1e30 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2016 Mountainminds GmbH & Co. KG and Contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc R. Hoffmann - initial API and implementation
*
*******************************************************************************/
package org.jacoco.core.internal.instr;
import static org.junit.Assert.assertEquals;
import org.jacoco.core.instr.MethodRecorder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* Unit tests for {@link ProbeInserter}.
*/
public class ProbeInserterTest {
private MethodRecorder actual, expected;
private MethodVisitor actualVisitor, expectedVisitor;
private IProbeArrayStrategy arrayStrategy;
@Before
public void setup() {
actual = new MethodRecorder();
actualVisitor = actual.getVisitor();
expected = new MethodRecorder();
expectedVisitor = expected.getVisitor();
arrayStrategy = new IProbeArrayStrategy() {
public int storeInstance(MethodVisitor mv, boolean clinit, int variable) {
mv.visitLdcInsn(clinit ? "clinit" : "init");
return 5;
}
public void addMembers(ClassVisitor delegate, int probeCount) {
}
};
}
@After
public void verify() {
assertEquals(expected, actual);
}
@Test
public void testVariableStatic() {
ProbeInserter pi = new ProbeInserter(Opcodes.ACC_STATIC, "m", "()V",
actualVisitor, arrayStrategy);
pi.insertProbe(0);
expectedVisitor.visitVarInsn(Opcodes.ALOAD, 0);
expectedVisitor.visitInsn(Opcodes.ICONST_0);
expectedVisitor.visitInsn(Opcodes.ICONST_1);
expectedVisitor.visitInsn(Opcodes.BASTORE);
}
@Test
public void testVariableNonStatic() {
ProbeInserter pi = new ProbeInserter(0, "m", "()V", actualVisitor,
arrayStrategy);
pi.insertProbe(0);
expectedVisitor.visitVarInsn(Opcodes.ALOAD, 1);
expectedVisitor.visitInsn(Opcodes.ICONST_0);
expectedVisitor.visitInsn(Opcodes.ICONST_1);
expectedVisitor.visitInsn(Opcodes.BASTORE);
}
@Test
public void testVariableNonStatic_IZObject() {
ProbeInserter pi = new ProbeInserter(0, "m", "(IZLjava/lang/Object;)V",
actualVisitor, arrayStrategy);
pi.insertProbe(0);
expectedVisitor.visitVarInsn(Opcodes.ALOAD, 4);
expectedVisitor.visitInsn(Opcodes.ICONST_0);
expectedVisitor.visitInsn(Opcodes.ICONST_1);
expectedVisitor.visitInsn(Opcodes.BASTORE);
}
@Test
public void testVariableNonStatic_JD() {
ProbeInserter pi = new ProbeInserter(0, "m", "(JD)V", actualVisitor,
arrayStrategy);
pi.insertProbe(0);
expectedVisitor.visitVarInsn(Opcodes.ALOAD, 5);
expectedVisitor.visitInsn(Opcodes.ICONST_0);
expectedVisitor.visitInsn(Opcodes.ICONST_1);
expectedVisitor.visitInsn(Opcodes.BASTORE);
}
@Test
public void testVisitCode() {
ProbeInserter pi = new ProbeInserter(0, "m", "()V", actualVisitor,
arrayStrategy);
pi.visitCode();
expectedVisitor.visitLdcInsn("init");
}
@Test
public void testVisitClinit() {
ProbeInserter pi = new ProbeInserter(0, "<clinit>", "()V",
actualVisitor, arrayStrategy);
pi.visitCode();
expectedVisitor.visitLdcInsn("clinit");
}
@Test
public void testVisitVarIns() {
ProbeInserter pi = new ProbeInserter(0, "m", "(II)V", actualVisitor,
arrayStrategy);
pi.visitVarInsn(Opcodes.ALOAD, 0);
pi.visitVarInsn(Opcodes.ILOAD, 1);
pi.visitVarInsn(Opcodes.ILOAD, 2);
pi.visitVarInsn(Opcodes.ISTORE, 3);
pi.visitVarInsn(Opcodes.FSTORE, 4);
// Argument variables stay at the same position:
expectedVisitor.visitVarInsn(Opcodes.ALOAD, 0);
expectedVisitor.visitVarInsn(Opcodes.ILOAD, 1);
expectedVisitor.visitVarInsn(Opcodes.ILOAD, 2);
// Local variables are shifted by one:
expectedVisitor.visitVarInsn(Opcodes.ISTORE, 4);
expectedVisitor.visitVarInsn(Opcodes.FSTORE, 5);
}
@Test
public void testVisitIincInsn() {
ProbeInserter pi = new ProbeInserter(0, "m", "(II)V", actualVisitor,
arrayStrategy);
pi.visitIincInsn(0, 100);
pi.visitIincInsn(1, 101);
pi.visitIincInsn(2, 102);
pi.visitIincInsn(3, 103);
pi.visitIincInsn(4, 104);
// Argument variables stay at the same position:
expectedVisitor.visitIincInsn(0, 100);
expectedVisitor.visitIincInsn(1, 101);
expectedVisitor.visitIincInsn(2, 102);
// Local variables are shifted by one:
expectedVisitor.visitIincInsn(4, 103);
expectedVisitor.visitIincInsn(5, 104);
}
@Test
public void testVisitLocalVariable() {
ProbeInserter pi = new ProbeInserter(0, "m", "(II)V", actualVisitor,
arrayStrategy);
pi.visitLocalVariable(null, null, null, null, null, 0);
pi.visitLocalVariable(null, null, null, null, null, 1);
pi.visitLocalVariable(null, null, null, null, null, 2);
pi.visitLocalVariable(null, null, null, null, null, 3);
pi.visitLocalVariable(null, null, null, null, null, 4);
// Argument variables stay at the same position:
expectedVisitor.visitLocalVariable(null, null, null, null, null, 0);
expectedVisitor.visitLocalVariable(null, null, null, null, null, 1);
expectedVisitor.visitLocalVariable(null, null, null, null, null, 2);
// Local variables are shifted by one:
expectedVisitor.visitLocalVariable(null, null, null, null, null, 4);
expectedVisitor.visitLocalVariable(null, null, null, null, null, 5);
}
@Test
public void testVisitMaxs1() {
ProbeInserter pi = new ProbeInserter(0, "m", "(II)V", actualVisitor,
arrayStrategy);
pi.visitCode();
pi.visitMaxs(0, 8);
expectedVisitor.visitLdcInsn("init");
expectedVisitor.visitMaxs(5, 9);
}
@Test
public void testVisitMaxs2() {
ProbeInserter pi = new ProbeInserter(0, "m", "(II)V", actualVisitor,
arrayStrategy);
pi.visitCode();
pi.visitMaxs(10, 8);
expectedVisitor.visitLdcInsn("init");
expectedVisitor.visitMaxs(13, 9);
}
@Test
public void testVisitFrame() {
ProbeInserter pi = new ProbeInserter(0, "m", "(J)V", actualVisitor,
arrayStrategy);
pi.visitFrame(Opcodes.F_NEW, 3, new Object[] { "Foo", Opcodes.LONG,
"java/lang/String" }, 0, new Object[0]);
expectedVisitor.visitFrame(Opcodes.F_NEW, 4, new Object[] { "Foo",
Opcodes.LONG, "[Z", "java/lang/String" }, 0, new Object[0]);
}
@Test
public void testVisitFrameNoLocals() {
ProbeInserter pi = new ProbeInserter(Opcodes.ACC_STATIC, "m", "()V",
actualVisitor, arrayStrategy);
pi.visitFrame(Opcodes.F_NEW, 0, new Object[] {}, 0, new Object[0]);
expectedVisitor.visitFrame(Opcodes.F_NEW, 1, new Object[] { "[Z" }, 0,
new Object[0]);
}
@Test
public void testVisitFrameProbeAt0() {
ProbeInserter pi = new ProbeInserter(Opcodes.ACC_STATIC, "m", "()V",
actualVisitor, arrayStrategy);
pi.visitFrame(Opcodes.F_NEW, 2, new Object[] { Opcodes.DOUBLE, "Foo" },
0, new Object[0]);
expectedVisitor.visitFrame(Opcodes.F_NEW, 3, new Object[] { "[Z",
Opcodes.DOUBLE, "Foo" }, 0, new Object[0]);
}
@Test
public void testFillOneWord() {
ProbeInserter pi = new ProbeInserter(Opcodes.ACC_STATIC, "m", "(I)V",
actualVisitor, arrayStrategy);
pi.visitFrame(Opcodes.F_NEW, 0, new Object[] {}, 0, new Object[] {});
// The locals in this frame are filled with TOP up to the probe variable
expectedVisitor.visitFrame(Opcodes.F_NEW, 2, new Object[] {
Opcodes.TOP, "[Z", }, 0, new Object[] {});
}
@Test
public void testFillTwoWord() {
ProbeInserter pi = new ProbeInserter(Opcodes.ACC_STATIC, "m", "(J)V",
actualVisitor, arrayStrategy);
pi.visitFrame(Opcodes.F_NEW, 0, new Object[] {}, 0, new Object[] {});
// The locals in this frame are filled with TOP up to the probe variable
expectedVisitor.visitFrame(Opcodes.F_NEW, 3, new Object[] {
Opcodes.TOP, Opcodes.TOP, "[Z", }, 0, new Object[] {});
}
@Test
public void testFillPartly() {
ProbeInserter pi = new ProbeInserter(Opcodes.ACC_STATIC, "m", "(DIJ)V",
actualVisitor, arrayStrategy);
pi.visitFrame(Opcodes.F_NEW, 1, new Object[] { Opcodes.DOUBLE }, 0,
new Object[] {});
// The locals in this frame are filled with TOP up to the probe variable
expectedVisitor.visitFrame(Opcodes.F_NEW, 5, new Object[] {
Opcodes.DOUBLE, Opcodes.TOP, Opcodes.TOP, Opcodes.TOP, "[Z", },
0, new Object[] {});
}
@Test(expected = IllegalArgumentException.class)
public void testVisitFrame_invalidType() {
ProbeInserter pi = new ProbeInserter(0, "m", "()V", actualVisitor,
arrayStrategy);
pi.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
}
}