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 *******************************************************************************/ 12 package org.jacoco.cli.internal.commands; 13 14 import static org.junit.Assert.assertArrayEquals; 15 import static org.junit.Assert.assertFalse; 16 import static org.junit.Assert.assertTrue; 17 import static org.junit.Assert.fail; 18 19 import java.io.File; 20 import java.io.FileInputStream; 21 import java.io.FileOutputStream; 22 import java.io.IOException; 23 import java.io.InputStream; 24 import java.io.OutputStream; 25 import java.util.HashSet; 26 import java.util.Set; 27 28 import org.jacoco.cli.internal.CommandTestBase; 29 import org.junit.Rule; 30 import org.junit.Test; 31 import org.junit.rules.TemporaryFolder; 32 import org.objectweb.asm.ClassReader; 33 import org.objectweb.asm.ClassVisitor; 34 import org.objectweb.asm.FieldVisitor; 35 import org.objectweb.asm.Opcodes; 36 37 /** 38 * Unit tests for {@link Instrument}. 39 */ 40 public class InstrumentTest extends CommandTestBase { 41 42 @Rule 43 public TemporaryFolder tmp = new TemporaryFolder(); 44 45 @Test 46 public void should_print_usage_when_no_options_are_given() 47 throws Exception { 48 execute("instrument"); 49 assertFailure(); 50 assertContains("Option \"-dest\" is required", err); 51 assertContains( 52 "Usage: java -jar jacococli.jar instrument [<sourcefiles> ...]", 53 err); 54 } 55 56 @Test 57 public void should_instrument_class_files_and_copy_resources() 58 throws Exception { 59 File destdir = tmp.getRoot(); 60 61 execute("instrument", "-dest", destdir.getAbsolutePath(), 62 getClassPath()); 63 64 assertOk(); 65 assertContains("[INFO] 14 classes instrumented to " 66 + destdir.getAbsolutePath(), out); 67 68 // non class-file resources are copied: 69 assertTrue(new File(destdir, "about.html").isFile()); 70 71 assertInstrumented(new File(destdir, 72 "org/jacoco/cli/internal/commands/InstrumentTest.class")); 73 } 74 75 @Test 76 public void should_not_instrument_anything_when_no_source_is_given() 77 throws Exception { 78 File destdir = tmp.getRoot(); 79 80 execute("instrument", "-dest", destdir.getAbsolutePath()); 81 82 assertOk(); 83 assertArrayEquals(new String[0], destdir.list()); 84 } 85 86 @Test 87 public void should_not_create_dest_file_when_source_class_is_broken() 88 throws Exception { 89 File srcdir = new File(tmp.getRoot(), "src"); 90 srcdir.mkdir(); 91 File destdir = new File(tmp.getRoot(), "dest"); 92 destdir.mkdir(); 93 94 OutputStream out = new FileOutputStream( 95 new File(srcdir, "Broken.class")); 96 out.write((byte) 0xca); 97 out.write((byte) 0xfe); 98 out.write((byte) 0xba); 99 out.write((byte) 0xbe); 100 out.write((byte) 0x00); 101 out.write((byte) 0x00); 102 out.write((byte) 0x00); 103 out.write((byte) 50); 104 out.close(); 105 106 try { 107 execute("instrument", "-dest", destdir.getAbsolutePath(), 108 srcdir.getAbsolutePath()); 109 fail("exception expected"); 110 } catch (IOException expected) { 111 } 112 113 assertFalse(new File(destdir, "Broken.class").exists()); 114 } 115 116 private void assertInstrumented(File classfile) throws IOException { 117 InputStream in = new FileInputStream(classfile); 118 ClassReader reader = new ClassReader(in); 119 in.close(); 120 final Set<String> fields = new HashSet<String>(); 121 reader.accept(new ClassVisitor(Opcodes.ASM5) { 122 @Override 123 public FieldVisitor visitField(int access, String name, String desc, 124 String signature, Object value) { 125 fields.add(name); 126 return null; 127 } 128 }, 0); 129 assertTrue(fields.contains("$jacocoData")); 130 } 131 132 } 133