113f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann/******************************************************************************* 2b9d1b54e300318b470d9fedccc69d75187016444Evgeny Mandrikov * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors 313f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann * All rights reserved. This program and the accompanying materials 413f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann * are made available under the terms of the Eclipse Public License v1.0 513f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann * which accompanies this distribution, and is available at 613f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann * http://www.eclipse.org/legal/epl-v10.html 713f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann * 813f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann * Contributors: 913f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann * Marc R. Hoffmann - initial API and implementation 1013f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann * 1113f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann *******************************************************************************/ 1213f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannpackage org.jacoco.cli.internal.commands; 1313f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 1413f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport static org.junit.Assert.assertArrayEquals; 1513f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport static org.junit.Assert.assertFalse; 1613f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport static org.junit.Assert.assertTrue; 1713f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport static org.junit.Assert.fail; 1813f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 1913f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport java.io.File; 2013f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport java.io.FileInputStream; 2113f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport java.io.FileOutputStream; 2213f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport java.io.IOException; 2313f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport java.io.InputStream; 2413f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport java.io.OutputStream; 2513f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport java.util.HashSet; 2613f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport java.util.Set; 2713f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 2813f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport org.jacoco.cli.internal.CommandTestBase; 2913f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport org.junit.Rule; 3013f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport org.junit.Test; 3113f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport org.junit.rules.TemporaryFolder; 3213f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport org.objectweb.asm.ClassReader; 3313f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport org.objectweb.asm.ClassVisitor; 3413f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport org.objectweb.asm.FieldVisitor; 3513f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannimport org.objectweb.asm.Opcodes; 3613f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 3713f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann/** 3813f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann * Unit tests for {@link Instrument}. 3913f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann */ 4013f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmannpublic class InstrumentTest extends CommandTestBase { 4113f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 4213f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann @Rule 4313f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann public TemporaryFolder tmp = new TemporaryFolder(); 4413f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 4513f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann @Test 4613f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann public void should_print_usage_when_no_options_are_given() 4713f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann throws Exception { 4813f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann execute("instrument"); 4913f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann assertFailure(); 5013f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann assertContains("Option \"--dest\" is required", err); 5113f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann assertContains( 5213f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann "Usage: java -jar jacococli.jar instrument [<sourcefiles> ...]", 5313f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann err); 5413f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann } 5513f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 5613f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann @Test 572a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann public void should_instrument_class_files_and_copy_resources_when_folder_is_given() 5813f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann throws Exception { 5913f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann File destdir = tmp.getRoot(); 6013f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 6113f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann execute("instrument", "--dest", destdir.getAbsolutePath(), 6213f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann getClassPath()); 6313f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 6413f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann assertOk(); 6513f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann assertContains("[INFO] 14 classes instrumented to " 6613f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann + destdir.getAbsolutePath(), out); 6713f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 6813f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann // non class-file resources are copied: 6913f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann assertTrue(new File(destdir, "about.html").isFile()); 7013f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 7113f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann assertInstrumented(new File(destdir, 7213f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann "org/jacoco/cli/internal/commands/InstrumentTest.class")); 7313f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann } 7413f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 7513f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann @Test 762a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann public void should_instrument_class_files_to_dest_folder_when_class_files_are_given() 772a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann throws Exception { 782a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann File destdir = tmp.getRoot(); 792a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann 802a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann File src = new File(getClassPath(), 812a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann "org/jacoco/cli/internal/commands/InstrumentTest.class"); 822a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann 832a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann execute("instrument", "--dest", destdir.getAbsolutePath(), 842a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann src.getAbsolutePath()); 852a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann 862a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann assertOk(); 872a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann assertContains( 882a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann "[INFO] 1 classes instrumented to " + destdir.getAbsolutePath(), 892a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann out); 902a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann 912a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann assertInstrumented(new File(destdir, "InstrumentTest.class")); 922a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann } 932a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann 942a2f161920d7608630ba1163d45a858803cfef2eMarc R. Hoffmann @Test 9513f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann public void should_not_instrument_anything_when_no_source_is_given() 9613f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann throws Exception { 9713f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann File destdir = tmp.getRoot(); 9813f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 9913f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann execute("instrument", "--dest", destdir.getAbsolutePath()); 10013f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 10113f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann assertOk(); 10213f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann assertArrayEquals(new String[0], destdir.list()); 10313f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann } 10413f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 10513f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann @Test 10613f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann public void should_not_create_dest_file_when_source_class_is_broken() 10713f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann throws Exception { 10813f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann File srcdir = new File(tmp.getRoot(), "src"); 10913f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann srcdir.mkdir(); 11013f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann File destdir = new File(tmp.getRoot(), "dest"); 11113f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann destdir.mkdir(); 11213f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 11313f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann OutputStream out = new FileOutputStream( 11413f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann new File(srcdir, "Broken.class")); 11513f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann out.write((byte) 0xca); 11613f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann out.write((byte) 0xfe); 11713f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann out.write((byte) 0xba); 11813f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann out.write((byte) 0xbe); 11913f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann out.write((byte) 0x00); 12013f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann out.write((byte) 0x00); 12113f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann out.write((byte) 0x00); 12213f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann out.write((byte) 50); 12313f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann out.close(); 12413f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 12513f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann try { 12613f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann execute("instrument", "--dest", destdir.getAbsolutePath(), 12713f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann srcdir.getAbsolutePath()); 12813f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann fail("exception expected"); 12913f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann } catch (IOException expected) { 13013f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann } 13113f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 13213f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann assertFalse(new File(destdir, "Broken.class").exists()); 13313f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann } 13413f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 13513f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann private void assertInstrumented(File classfile) throws IOException { 13613f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann InputStream in = new FileInputStream(classfile); 13713f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann ClassReader reader = new ClassReader(in); 13813f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann in.close(); 13913f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann final Set<String> fields = new HashSet<String>(); 140caa820ed62133f47bacba06ea931bf5d7c43dcd6Roberto Araujo reader.accept(new ClassVisitor(Opcodes.ASM6) { 14113f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann @Override 14213f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann public FieldVisitor visitField(int access, String name, String desc, 14313f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann String signature, Object value) { 14413f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann fields.add(name); 14513f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann return null; 14613f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann } 14713f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann }, 0); 14813f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann assertTrue(fields.contains("$jacocoData")); 14913f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann } 15013f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann 15113f12d39db0b3c0ddc60124572e5d4f984be0255Marc R. Hoffmann} 152