1/******************************************************************************* 2 * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * Marc R. Hoffmann - initial API and implementation 10 * 11 *******************************************************************************/ 12package org.jacoco.core.internal.flow; 13 14import static org.junit.Assert.assertEquals; 15 16import java.util.Arrays; 17 18import org.jacoco.core.instr.MethodRecorder; 19import org.junit.After; 20import org.junit.Before; 21import org.junit.Test; 22import org.objectweb.asm.Label; 23import org.objectweb.asm.MethodVisitor; 24import org.objectweb.asm.Opcodes; 25import org.objectweb.asm.commons.AnalyzerAdapter; 26import org.objectweb.asm.util.Printer; 27 28/** 29 * Unit tests for {@link MethodProbesAdapter}. 30 */ 31public class MethodProbesAdapterTest implements IProbeIdGenerator { 32 33 private Label label; 34 35 private int id; 36 37 private MethodRecorder expected, actual; 38 39 private MethodProbesVisitor expectedVisitor; 40 41 private MethodVisitor adapter; 42 43 private IFrame frame; 44 45 private static class TraceAdapter extends MethodProbesVisitor { 46 47 private final Printer printer; 48 49 TraceAdapter(MethodRecorder recorder) { 50 super(recorder.getVisitor()); 51 printer = recorder.getPrinter(); 52 } 53 54 @Override 55 public void visitProbe(int probeId) { 56 rec("visitProbe", Integer.valueOf(probeId)); 57 } 58 59 @Override 60 public void visitInsnWithProbe(int opcode, int probeId) { 61 rec("visitInsnWithProbe", Integer.valueOf(opcode), 62 Integer.valueOf(probeId)); 63 } 64 65 @Override 66 public void visitJumpInsnWithProbe(int opcode, Label label, 67 int probeId, IFrame frame) { 68 rec("visitJumpInsnWithProbe", Integer.valueOf(opcode), label, 69 Integer.valueOf(probeId)); 70 frame.accept(this); 71 } 72 73 @Override 74 public void visitTableSwitchInsnWithProbes(int min, int max, 75 Label dflt, Label[] labels, IFrame frame) { 76 rec("visitTableSwitchInsnWithProbes", Integer.valueOf(min), 77 Integer.valueOf(max), dflt, labels); 78 frame.accept(this); 79 } 80 81 @Override 82 public void visitLookupSwitchInsnWithProbes(Label dflt, int[] keys, 83 Label[] labels, IFrame frame) { 84 rec("visitLookupSwitchInsnWithProbes", dflt, keys, labels); 85 frame.accept(this); 86 } 87 88 private void rec(String name, Object... args) { 89 printer.text.add(name + Arrays.asList(args)); 90 } 91 92 } 93 94 @Before 95 public void setup() { 96 label = new Label(); 97 id = 1000; 98 expected = new MethodRecorder(); 99 expectedVisitor = new TraceAdapter(expected); 100 actual = new MethodRecorder(); 101 MethodProbesVisitor actualVisitor = new TraceAdapter(actual); 102 MethodProbesAdapter probesAdapter = new MethodProbesAdapter( 103 actualVisitor, this); 104 final AnalyzerAdapter analyzer = new AnalyzerAdapter("Foo", 0, "doit", 105 "()V", probesAdapter); 106 probesAdapter.setAnalyzer(analyzer); 107 adapter = analyzer; 108 frame = new IFrame() { 109 110 public void accept(MethodVisitor mv) { 111 } 112 }; 113 } 114 115 @After 116 public void verify() { 117 assertEquals(expected, actual); 118 } 119 120 @Test 121 public void testVisitProbe1() { 122 LabelInfo.setTarget(label); 123 LabelInfo.setSuccessor(label); 124 125 adapter.visitLabel(label); 126 127 expectedVisitor.visitProbe(1000); 128 expectedVisitor.visitLabel(label); 129 } 130 131 @Test 132 public void testVisitProbe2() { 133 LabelInfo.setTarget(label); 134 LabelInfo.setTarget(label); 135 136 adapter.visitLabel(label); 137 138 expectedVisitor.visitLabel(label); 139 } 140 141 @Test 142 public void testVisitProbe3() { 143 adapter.visitLabel(label); 144 145 expectedVisitor.visitLabel(label); 146 } 147 148 @Test 149 public void testVisitInsn1() { 150 adapter.visitInsn(Opcodes.RETURN); 151 152 expectedVisitor.visitInsnWithProbe(Opcodes.RETURN, 1000); 153 } 154 155 @Test 156 public void testVisitInsn2() { 157 adapter.visitInsn(Opcodes.ICONST_0); 158 adapter.visitInsn(Opcodes.ICONST_0); 159 adapter.visitInsn(Opcodes.IADD); 160 161 expectedVisitor.visitInsn(Opcodes.ICONST_0); 162 expectedVisitor.visitInsn(Opcodes.ICONST_0); 163 expectedVisitor.visitInsn(Opcodes.IADD); 164 } 165 166 @Test 167 public void testVisitJumpInsn1() { 168 LabelInfo.setTarget(label); 169 LabelInfo.setTarget(label); 170 171 adapter.visitJumpInsn(Opcodes.GOTO, label); 172 173 expectedVisitor 174 .visitJumpInsnWithProbe(Opcodes.GOTO, label, 1000, frame); 175 expectedVisitor.visitFrame(Opcodes.F_FULL, 1, new Object[] { "Foo" }, 176 0, null); 177 } 178 179 @Test 180 public void testVisitJumpInsn2() { 181 LabelInfo.setTarget(label); 182 LabelInfo.setTarget(label); 183 184 adapter.visitInsn(Opcodes.ICONST_0); 185 adapter.visitJumpInsn(Opcodes.IFLT, label); 186 187 expectedVisitor.visitInsn(Opcodes.ICONST_0); 188 expectedVisitor 189 .visitJumpInsnWithProbe(Opcodes.IFLT, label, 1000, frame); 190 expectedVisitor.visitFrame(Opcodes.F_FULL, 1, new Object[] { "Foo" }, 191 0, null); 192 } 193 194 @Test 195 public void testVisitJumpInsn3() { 196 adapter.visitInsn(Opcodes.ICONST_0); 197 adapter.visitJumpInsn(Opcodes.IFLT, label); 198 199 expectedVisitor.visitInsn(Opcodes.ICONST_0); 200 expectedVisitor.visitJumpInsn(Opcodes.IFLT, label); 201 } 202 203 @Test 204 public void testVisitJumpInsn4() { 205 LabelInfo.setTarget(label); 206 LabelInfo.setTarget(label); 207 208 adapter.visitInsn(Opcodes.ICONST_0); 209 adapter.visitInsn(Opcodes.ICONST_0); 210 adapter.visitJumpInsn(Opcodes.IF_ICMPEQ, label); 211 212 expectedVisitor.visitInsn(Opcodes.ICONST_0); 213 expectedVisitor.visitInsn(Opcodes.ICONST_0); 214 expectedVisitor.visitJumpInsnWithProbe(Opcodes.IF_ICMPEQ, label, 1000, 215 frame); 216 expectedVisitor.visitFrame(Opcodes.F_FULL, 1, new Object[] { "Foo" }, 217 0, null); 218 } 219 220 @Test 221 public void testVisitLookupSwitchInsn1() { 222 LabelInfo.setTarget(label); 223 LabelInfo.setTarget(label); 224 225 final int[] keys = new int[] { 0, 1 }; 226 final Label[] labels = new Label[] { label, label }; 227 adapter.visitInsn(Opcodes.ICONST_0); 228 adapter.visitLookupSwitchInsn(label, keys, labels); 229 230 expectedVisitor.visitInsn(Opcodes.ICONST_0); 231 expectedVisitor.visitLookupSwitchInsnWithProbes(label, keys, labels, 232 frame); 233 expectedVisitor.visitFrame(Opcodes.F_FULL, 1, new Object[] { "Foo" }, 234 0, null); 235 assertEquals(1000, LabelInfo.getProbeId(label)); 236 } 237 238 @Test 239 public void testVisitLookupSwitchInsn2() { 240 Label label2 = new Label(); 241 LabelInfo.setTarget(label2); 242 LabelInfo.setTarget(label2); 243 244 final int[] keys = new int[] { 0, 1 }; 245 final Label[] labels = new Label[] { label2, label }; 246 adapter.visitInsn(Opcodes.ICONST_0); 247 adapter.visitLookupSwitchInsn(label, keys, labels); 248 249 expectedVisitor.visitInsn(Opcodes.ICONST_0); 250 expectedVisitor.visitLookupSwitchInsnWithProbes(label, keys, labels, 251 frame); 252 expectedVisitor.visitFrame(Opcodes.F_FULL, 1, new Object[] { "Foo" }, 253 0, null); 254 assertEquals(LabelInfo.NO_PROBE, LabelInfo.getProbeId(label)); 255 assertEquals(1000, LabelInfo.getProbeId(label2)); 256 } 257 258 @Test 259 public void testVisitLookupSwitchInsn3() { 260 final int[] keys = new int[] { 0, 1 }; 261 final Label[] labels = new Label[] { label, label }; 262 adapter.visitInsn(Opcodes.ICONST_0); 263 adapter.visitLookupSwitchInsn(label, keys, labels); 264 265 expectedVisitor.visitInsn(Opcodes.ICONST_0); 266 expectedVisitor.visitLookupSwitchInsn(label, keys, labels); 267 } 268 269 @Test 270 public void testVisitTableSwitchInsn1() { 271 LabelInfo.setTarget(label); 272 LabelInfo.setTarget(label); 273 274 final Label[] labels = new Label[] { label, label }; 275 adapter.visitInsn(Opcodes.ICONST_0); 276 adapter.visitTableSwitchInsn(0, 1, label, labels); 277 278 expectedVisitor.visitInsn(Opcodes.ICONST_0); 279 expectedVisitor.visitTableSwitchInsnWithProbes(0, 1, label, labels, 280 frame); 281 expectedVisitor.visitFrame(Opcodes.F_FULL, 1, new Object[] { "Foo" }, 282 0, null); 283 assertEquals(1000, LabelInfo.getProbeId(label)); 284 } 285 286 @Test 287 public void testVisitTableSwitchInsn2() { 288 Label label2 = new Label(); 289 LabelInfo.setTarget(label2); 290 LabelInfo.setTarget(label2); 291 292 final Label[] labels = new Label[] { label2, label }; 293 adapter.visitInsn(Opcodes.ICONST_0); 294 adapter.visitTableSwitchInsn(0, 1, label, labels); 295 296 expectedVisitor.visitInsn(Opcodes.ICONST_0); 297 expectedVisitor.visitTableSwitchInsnWithProbes(0, 1, label, labels, 298 frame); 299 expectedVisitor.visitFrame(Opcodes.F_FULL, 1, new Object[] { "Foo" }, 300 0, null); 301 assertEquals(LabelInfo.NO_PROBE, LabelInfo.getProbeId(label)); 302 assertEquals(1000, LabelInfo.getProbeId(label2)); 303 } 304 305 @Test 306 public void testVisitTableSwitchInsn3() { 307 final Label[] labels = new Label[] { label, label }; 308 adapter.visitInsn(Opcodes.ICONST_0); 309 adapter.visitTableSwitchInsn(0, 1, label, labels); 310 311 expectedVisitor.visitInsn(Opcodes.ICONST_0); 312 expectedVisitor.visitTableSwitchInsn(0, 1, label, labels); 313 } 314 315 @Test 316 public void testVisitTryCatchBlockNoProbe() { 317 Label start = new Label(); 318 Label end = new Label(); 319 Label handler = new Label(); 320 321 adapter.visitTryCatchBlock(start, end, handler, "java/lang/Exception"); 322 adapter.visitLabel(start); 323 324 expectedVisitor.visitTryCatchBlock(start, end, handler, 325 "java/lang/Exception"); 326 expectedVisitor.visitLabel(start); 327 } 328 329 @Test 330 public void testVisitTryCatchBlockWithProbe() { 331 Label target = new Label(); 332 LabelInfo.setSuccessor(target); 333 LabelInfo.setTarget(target); 334 Label end = new Label(); 335 Label handler = new Label(); 336 Label start = new Label(); 337 338 adapter.visitTryCatchBlock(target, end, handler, "java/lang/Exception"); 339 adapter.visitLabel(target); 340 341 expectedVisitor.visitTryCatchBlock(start, end, handler, 342 "java/lang/Exception"); 343 expectedVisitor.visitLabel(start); 344 expectedVisitor.visitProbe(1000); 345 expectedVisitor.visitLabel(target); 346 } 347 348 @Test 349 public void testVisitMultipleTryCatchBlocksWithProbe() { 350 Label target = new Label(); 351 LabelInfo.setSuccessor(target); 352 LabelInfo.setTarget(target); 353 Label end = new Label(); 354 Label handler1 = new Label(); 355 Label handler2 = new Label(); 356 Label start = new Label(); 357 358 adapter.visitTryCatchBlock(target, end, handler1, "java/lang/Exception"); 359 adapter.visitTryCatchBlock(target, end, handler2, "java/io/IOException"); 360 adapter.visitLabel(target); 361 362 expectedVisitor.visitTryCatchBlock(start, end, handler1, 363 "java/lang/Exception"); 364 expectedVisitor.visitTryCatchBlock(start, end, handler2, 365 "java/io/IOException"); 366 expectedVisitor.visitLabel(start); 367 expectedVisitor.visitProbe(1000); 368 expectedVisitor.visitLabel(target); 369 } 370 371 // === IProbeIdGenerator === 372 373 public int nextId() { 374 return id++; 375 } 376 377} 378