1/******************************************************************************* 2 * Copyright (c) 2009, 2018 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.cli.internal.commands; 13 14import static org.junit.Assert.assertArrayEquals; 15import static org.junit.Assert.assertFalse; 16import static org.junit.Assert.assertTrue; 17import static org.junit.Assert.fail; 18 19import java.io.File; 20import java.io.FileInputStream; 21import java.io.FileOutputStream; 22import java.io.IOException; 23import java.io.InputStream; 24import java.io.OutputStream; 25import java.util.HashSet; 26import java.util.Set; 27 28import org.jacoco.cli.internal.CommandTestBase; 29import org.junit.Rule; 30import org.junit.Test; 31import org.junit.rules.TemporaryFolder; 32import org.objectweb.asm.ClassReader; 33import org.objectweb.asm.ClassVisitor; 34import org.objectweb.asm.FieldVisitor; 35import org.objectweb.asm.Opcodes; 36 37/** 38 * Unit tests for {@link Instrument}. 39 */ 40public 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_when_folder_is_given() 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_instrument_class_files_to_dest_folder_when_class_files_are_given() 77 throws Exception { 78 File destdir = tmp.getRoot(); 79 80 File src = new File(getClassPath(), 81 "org/jacoco/cli/internal/commands/InstrumentTest.class"); 82 83 execute("instrument", "--dest", destdir.getAbsolutePath(), 84 src.getAbsolutePath()); 85 86 assertOk(); 87 assertContains( 88 "[INFO] 1 classes instrumented to " + destdir.getAbsolutePath(), 89 out); 90 91 assertInstrumented(new File(destdir, "InstrumentTest.class")); 92 } 93 94 @Test 95 public void should_not_instrument_anything_when_no_source_is_given() 96 throws Exception { 97 File destdir = tmp.getRoot(); 98 99 execute("instrument", "--dest", destdir.getAbsolutePath()); 100 101 assertOk(); 102 assertArrayEquals(new String[0], destdir.list()); 103 } 104 105 @Test 106 public void should_not_create_dest_file_when_source_class_is_broken() 107 throws Exception { 108 File srcdir = new File(tmp.getRoot(), "src"); 109 srcdir.mkdir(); 110 File destdir = new File(tmp.getRoot(), "dest"); 111 destdir.mkdir(); 112 113 OutputStream out = new FileOutputStream( 114 new File(srcdir, "Broken.class")); 115 out.write((byte) 0xca); 116 out.write((byte) 0xfe); 117 out.write((byte) 0xba); 118 out.write((byte) 0xbe); 119 out.write((byte) 0x00); 120 out.write((byte) 0x00); 121 out.write((byte) 0x00); 122 out.write((byte) 50); 123 out.close(); 124 125 try { 126 execute("instrument", "--dest", destdir.getAbsolutePath(), 127 srcdir.getAbsolutePath()); 128 fail("exception expected"); 129 } catch (IOException expected) { 130 } 131 132 assertFalse(new File(destdir, "Broken.class").exists()); 133 } 134 135 private void assertInstrumented(File classfile) throws IOException { 136 InputStream in = new FileInputStream(classfile); 137 ClassReader reader = new ClassReader(in); 138 in.close(); 139 final Set<String> fields = new HashSet<String>(); 140 reader.accept(new ClassVisitor(Opcodes.ASM6) { 141 @Override 142 public FieldVisitor visitField(int access, String name, String desc, 143 String signature, Object value) { 144 fields.add(name); 145 return null; 146 } 147 }, 0); 148 assertTrue(fields.contains("$jacocoData")); 149 } 150 151} 152