| /******************************************************************************* |
| * Copyright (c) 2009, 2017 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.flow; |
| |
| import static org.junit.Assert.assertEquals; |
| |
| import java.util.Arrays; |
| |
| import org.jacoco.core.instr.MethodRecorder; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.objectweb.asm.Label; |
| import org.objectweb.asm.MethodVisitor; |
| import org.objectweb.asm.Opcodes; |
| import org.objectweb.asm.commons.AnalyzerAdapter; |
| import org.objectweb.asm.util.Printer; |
| |
| /** |
| * Unit tests for {@link MethodProbesAdapter}. |
| */ |
| public class MethodProbesAdapterTest implements IProbeIdGenerator { |
| |
| private Label label; |
| |
| private int id; |
| |
| private MethodRecorder expected, actual; |
| |
| private MethodProbesVisitor expectedVisitor; |
| |
| private MethodVisitor adapter; |
| |
| private IFrame frame; |
| |
| private static class TraceAdapter extends MethodProbesVisitor { |
| |
| private final Printer printer; |
| |
| TraceAdapter(MethodRecorder recorder) { |
| super(recorder.getVisitor()); |
| printer = recorder.getPrinter(); |
| } |
| |
| @Override |
| public void visitProbe(int probeId) { |
| rec("visitProbe", Integer.valueOf(probeId)); |
| } |
| |
| @Override |
| public void visitInsnWithProbe(int opcode, int probeId) { |
| rec("visitInsnWithProbe", Integer.valueOf(opcode), |
| Integer.valueOf(probeId)); |
| } |
| |
| @Override |
| public void visitJumpInsnWithProbe(int opcode, Label label, |
| int probeId, IFrame frame) { |
| rec("visitJumpInsnWithProbe", Integer.valueOf(opcode), label, |
| Integer.valueOf(probeId)); |
| frame.accept(this); |
| } |
| |
| @Override |
| public void visitTableSwitchInsnWithProbes(int min, int max, |
| Label dflt, Label[] labels, IFrame frame) { |
| rec("visitTableSwitchInsnWithProbes", Integer.valueOf(min), |
| Integer.valueOf(max), dflt, labels); |
| frame.accept(this); |
| } |
| |
| @Override |
| public void visitLookupSwitchInsnWithProbes(Label dflt, int[] keys, |
| Label[] labels, IFrame frame) { |
| rec("visitLookupSwitchInsnWithProbes", dflt, keys, labels); |
| frame.accept(this); |
| } |
| |
| private void rec(String name, Object... args) { |
| printer.text.add(name + Arrays.asList(args)); |
| } |
| |
| } |
| |
| @Before |
| public void setup() { |
| label = new Label(); |
| id = 1000; |
| expected = new MethodRecorder(); |
| expectedVisitor = new TraceAdapter(expected); |
| actual = new MethodRecorder(); |
| MethodProbesVisitor actualVisitor = new TraceAdapter(actual); |
| MethodProbesAdapter probesAdapter = new MethodProbesAdapter( |
| actualVisitor, this); |
| final AnalyzerAdapter analyzer = new AnalyzerAdapter("Foo", 0, "doit", |
| "()V", probesAdapter); |
| probesAdapter.setAnalyzer(analyzer); |
| adapter = analyzer; |
| frame = new IFrame() { |
| |
| public void accept(MethodVisitor mv) { |
| } |
| }; |
| } |
| |
| @After |
| public void verify() { |
| assertEquals(expected, actual); |
| } |
| |
| @Test |
| public void testVisitProbe1() { |
| LabelInfo.setTarget(label); |
| LabelInfo.setSuccessor(label); |
| |
| adapter.visitLabel(label); |
| |
| expectedVisitor.visitProbe(1000); |
| expectedVisitor.visitLabel(label); |
| } |
| |
| @Test |
| public void testVisitProbe2() { |
| LabelInfo.setTarget(label); |
| LabelInfo.setTarget(label); |
| |
| adapter.visitLabel(label); |
| |
| expectedVisitor.visitLabel(label); |
| } |
| |
| @Test |
| public void testVisitProbe3() { |
| adapter.visitLabel(label); |
| |
| expectedVisitor.visitLabel(label); |
| } |
| |
| @Test |
| public void testVisitInsn1() { |
| adapter.visitInsn(Opcodes.RETURN); |
| |
| expectedVisitor.visitInsnWithProbe(Opcodes.RETURN, 1000); |
| } |
| |
| @Test |
| public void testVisitInsn2() { |
| adapter.visitInsn(Opcodes.ICONST_0); |
| adapter.visitInsn(Opcodes.ICONST_0); |
| adapter.visitInsn(Opcodes.IADD); |
| |
| expectedVisitor.visitInsn(Opcodes.ICONST_0); |
| expectedVisitor.visitInsn(Opcodes.ICONST_0); |
| expectedVisitor.visitInsn(Opcodes.IADD); |
| } |
| |
| @Test |
| public void testVisitJumpInsn1() { |
| LabelInfo.setTarget(label); |
| LabelInfo.setTarget(label); |
| |
| adapter.visitJumpInsn(Opcodes.GOTO, label); |
| |
| expectedVisitor |
| .visitJumpInsnWithProbe(Opcodes.GOTO, label, 1000, frame); |
| expectedVisitor.visitFrame(Opcodes.F_FULL, 1, new Object[] { "Foo" }, |
| 0, null); |
| } |
| |
| @Test |
| public void testVisitJumpInsn2() { |
| LabelInfo.setTarget(label); |
| LabelInfo.setTarget(label); |
| |
| adapter.visitInsn(Opcodes.ICONST_0); |
| adapter.visitJumpInsn(Opcodes.IFLT, label); |
| |
| expectedVisitor.visitInsn(Opcodes.ICONST_0); |
| expectedVisitor |
| .visitJumpInsnWithProbe(Opcodes.IFLT, label, 1000, frame); |
| expectedVisitor.visitFrame(Opcodes.F_FULL, 1, new Object[] { "Foo" }, |
| 0, null); |
| } |
| |
| @Test |
| public void testVisitJumpInsn3() { |
| adapter.visitInsn(Opcodes.ICONST_0); |
| adapter.visitJumpInsn(Opcodes.IFLT, label); |
| |
| expectedVisitor.visitInsn(Opcodes.ICONST_0); |
| expectedVisitor.visitJumpInsn(Opcodes.IFLT, label); |
| } |
| |
| @Test |
| public void testVisitJumpInsn4() { |
| LabelInfo.setTarget(label); |
| LabelInfo.setTarget(label); |
| |
| adapter.visitInsn(Opcodes.ICONST_0); |
| adapter.visitInsn(Opcodes.ICONST_0); |
| adapter.visitJumpInsn(Opcodes.IF_ICMPEQ, label); |
| |
| expectedVisitor.visitInsn(Opcodes.ICONST_0); |
| expectedVisitor.visitInsn(Opcodes.ICONST_0); |
| expectedVisitor.visitJumpInsnWithProbe(Opcodes.IF_ICMPEQ, label, 1000, |
| frame); |
| expectedVisitor.visitFrame(Opcodes.F_FULL, 1, new Object[] { "Foo" }, |
| 0, null); |
| } |
| |
| @Test |
| public void testVisitLookupSwitchInsn1() { |
| LabelInfo.setTarget(label); |
| LabelInfo.setTarget(label); |
| |
| final int[] keys = new int[] { 0, 1 }; |
| final Label[] labels = new Label[] { label, label }; |
| adapter.visitInsn(Opcodes.ICONST_0); |
| adapter.visitLookupSwitchInsn(label, keys, labels); |
| |
| expectedVisitor.visitInsn(Opcodes.ICONST_0); |
| expectedVisitor.visitLookupSwitchInsnWithProbes(label, keys, labels, |
| frame); |
| expectedVisitor.visitFrame(Opcodes.F_FULL, 1, new Object[] { "Foo" }, |
| 0, null); |
| assertEquals(1000, LabelInfo.getProbeId(label)); |
| } |
| |
| @Test |
| public void testVisitLookupSwitchInsn2() { |
| Label label2 = new Label(); |
| LabelInfo.setTarget(label2); |
| LabelInfo.setTarget(label2); |
| |
| final int[] keys = new int[] { 0, 1 }; |
| final Label[] labels = new Label[] { label2, label }; |
| adapter.visitInsn(Opcodes.ICONST_0); |
| adapter.visitLookupSwitchInsn(label, keys, labels); |
| |
| expectedVisitor.visitInsn(Opcodes.ICONST_0); |
| expectedVisitor.visitLookupSwitchInsnWithProbes(label, keys, labels, |
| frame); |
| expectedVisitor.visitFrame(Opcodes.F_FULL, 1, new Object[] { "Foo" }, |
| 0, null); |
| assertEquals(LabelInfo.NO_PROBE, LabelInfo.getProbeId(label)); |
| assertEquals(1000, LabelInfo.getProbeId(label2)); |
| } |
| |
| @Test |
| public void testVisitLookupSwitchInsn3() { |
| final int[] keys = new int[] { 0, 1 }; |
| final Label[] labels = new Label[] { label, label }; |
| adapter.visitInsn(Opcodes.ICONST_0); |
| adapter.visitLookupSwitchInsn(label, keys, labels); |
| |
| expectedVisitor.visitInsn(Opcodes.ICONST_0); |
| expectedVisitor.visitLookupSwitchInsn(label, keys, labels); |
| } |
| |
| @Test |
| public void testVisitTableSwitchInsn1() { |
| LabelInfo.setTarget(label); |
| LabelInfo.setTarget(label); |
| |
| final Label[] labels = new Label[] { label, label }; |
| adapter.visitInsn(Opcodes.ICONST_0); |
| adapter.visitTableSwitchInsn(0, 1, label, labels); |
| |
| expectedVisitor.visitInsn(Opcodes.ICONST_0); |
| expectedVisitor.visitTableSwitchInsnWithProbes(0, 1, label, labels, |
| frame); |
| expectedVisitor.visitFrame(Opcodes.F_FULL, 1, new Object[] { "Foo" }, |
| 0, null); |
| assertEquals(1000, LabelInfo.getProbeId(label)); |
| } |
| |
| @Test |
| public void testVisitTableSwitchInsn2() { |
| Label label2 = new Label(); |
| LabelInfo.setTarget(label2); |
| LabelInfo.setTarget(label2); |
| |
| final Label[] labels = new Label[] { label2, label }; |
| adapter.visitInsn(Opcodes.ICONST_0); |
| adapter.visitTableSwitchInsn(0, 1, label, labels); |
| |
| expectedVisitor.visitInsn(Opcodes.ICONST_0); |
| expectedVisitor.visitTableSwitchInsnWithProbes(0, 1, label, labels, |
| frame); |
| expectedVisitor.visitFrame(Opcodes.F_FULL, 1, new Object[] { "Foo" }, |
| 0, null); |
| assertEquals(LabelInfo.NO_PROBE, LabelInfo.getProbeId(label)); |
| assertEquals(1000, LabelInfo.getProbeId(label2)); |
| } |
| |
| @Test |
| public void testVisitTableSwitchInsn3() { |
| final Label[] labels = new Label[] { label, label }; |
| adapter.visitInsn(Opcodes.ICONST_0); |
| adapter.visitTableSwitchInsn(0, 1, label, labels); |
| |
| expectedVisitor.visitInsn(Opcodes.ICONST_0); |
| expectedVisitor.visitTableSwitchInsn(0, 1, label, labels); |
| } |
| |
| @Test |
| public void testVisitTryCatchBlockNoProbe() { |
| Label start = new Label(); |
| Label end = new Label(); |
| Label handler = new Label(); |
| |
| adapter.visitTryCatchBlock(start, end, handler, "java/lang/Exception"); |
| adapter.visitLabel(start); |
| |
| expectedVisitor.visitTryCatchBlock(start, end, handler, |
| "java/lang/Exception"); |
| expectedVisitor.visitLabel(start); |
| } |
| |
| @Test |
| public void testVisitTryCatchBlockWithProbe() { |
| Label target = new Label(); |
| LabelInfo.setSuccessor(target); |
| LabelInfo.setTarget(target); |
| Label end = new Label(); |
| Label handler = new Label(); |
| Label start = new Label(); |
| |
| adapter.visitTryCatchBlock(target, end, handler, "java/lang/Exception"); |
| adapter.visitLabel(target); |
| |
| expectedVisitor.visitTryCatchBlock(start, end, handler, |
| "java/lang/Exception"); |
| expectedVisitor.visitLabel(start); |
| expectedVisitor.visitProbe(1000); |
| expectedVisitor.visitLabel(target); |
| } |
| |
| @Test |
| public void testVisitMultipleTryCatchBlocksWithProbe() { |
| Label target = new Label(); |
| LabelInfo.setSuccessor(target); |
| LabelInfo.setTarget(target); |
| Label end = new Label(); |
| Label handler1 = new Label(); |
| Label handler2 = new Label(); |
| Label start = new Label(); |
| |
| adapter.visitTryCatchBlock(target, end, handler1, "java/lang/Exception"); |
| adapter.visitTryCatchBlock(target, end, handler2, "java/io/IOException"); |
| adapter.visitLabel(target); |
| |
| expectedVisitor.visitTryCatchBlock(start, end, handler1, |
| "java/lang/Exception"); |
| expectedVisitor.visitTryCatchBlock(start, end, handler2, |
| "java/io/IOException"); |
| expectedVisitor.visitLabel(start); |
| expectedVisitor.visitProbe(1000); |
| expectedVisitor.visitLabel(target); |
| } |
| |
| // === IProbeIdGenerator === |
| |
| public int nextId() { |
| return id++; |
| } |
| |
| } |