Home | History | Annotate | Download | only in commands
      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