Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/instrument/ATransformerManagementTestCase.java
38813 views
/*1* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/222324import java.io.*;25import java.lang.instrument.*;2627import java.security.ProtectionDomain;28import java.util.*;293031/**32* Simple tests for the TransformerManager33*34*/35public abstract class36ATransformerManagementTestCase37extends AInstrumentationTestCase38{39private static final String redefinedClassName = "DummyClass";4041protected int kModSamples = 2;42public final ClassFileTransformer[] kTransformerSamples = new ClassFileTransformer[]43{44new MyClassFileTransformer( Integer.toString(0)),45new MyClassFileTransformer( Integer.toString(1)),46new MyClassFileTransformer( Integer.toString(2)),47new MyClassFileTransformer( Integer.toString(3)),48new MyClassFileTransformer( Integer.toString(4)),49new MyClassFileTransformer( Integer.toString(5)),50new MyClassFileTransformer( Integer.toString(6)),51new MyClassFileTransformer( Integer.toString(7)),52new MyClassFileTransformer( Integer.toString(8)),53new MyClassFileTransformer( Integer.toString(9)),54new MyClassFileTransformer( Integer.toString(10)),55new MyClassFileTransformer( Integer.toString(11)),56new MyClassFileTransformer( Integer.toString(12)),57new MyClassFileTransformer( Integer.toString(13)),58new MyClassFileTransformer( Integer.toString(14)),59new MyClassFileTransformer( Integer.toString(15)),60new MyClassFileTransformer( Integer.toString(16)),61new MyClassFileTransformer( Integer.toString(17)),62new MyClassFileTransformer( Integer.toString(18)),63};6465private ArrayList fTransformers; // The list of transformers66private int fTransformerIndex; // The number of transformers encountered67private String fDelayedFailure; // Set non-null if failed in transformer686970/**71* Constructor for ATransformerManagementTestCase.72*/73public ATransformerManagementTestCase(String name)74{75super(name);76}777879/**80* Returns one of the sample transformers81* @return a random transformer82*/83protected ClassFileTransformer84getRandomTransformer()85{86int randIndex = (int)Math.floor(Math.random() * kTransformerSamples.length);87verbosePrint("Choosing random transformer #" + randIndex);88return kTransformerSamples[randIndex];89}9091/**92* Method addTransformerToManager.93* @param manager94* @param transformer95*/96protected void97addTransformerToManager(98Instrumentation manager,99ClassFileTransformer transformer)100{101addTransformerToManager(manager, transformer, false);102}103104/**105* Method addTransformerToManager.106* @param manager107* @param transformer108* @param canRetransform109*/110protected void111addTransformerToManager(112Instrumentation manager,113ClassFileTransformer transformer,114boolean canRetransform)115{116if (transformer != null)117{118fTransformers.add(transformer);119}120manager.addTransformer(transformer, canRetransform);121verbosePrint("Added transformer " + transformer122+ " with canRetransform=" + canRetransform);123}124125/**126* Remove transformer from manager and list127* @param manager128* @param transformer129*/130protected void131removeTransformerFromManager(132Instrumentation manager,133ClassFileTransformer transformer)134{135assertTrue("Transformer not found in manager ("+transformer+")", manager.removeTransformer(transformer));136137if (transformer != null)138{139fTransformers.remove(transformer);140}141verbosePrint("Removed transformer " + transformer);142}143144/**145* Decrements the transformer index as well as removes transformer146* @param fInst manager147* @param transformer transformer to remove148* @param decrementIndex the tranformer index gets out of sync with transformers149* that are removed from the manager150*/151protected void152removeTransformerFromManager( Instrumentation manager,153ClassFileTransformer transformer,154boolean decrementIndex)155{156removeTransformerFromManager(manager, transformer);157if (decrementIndex)158{159fTransformerIndex--;160verbosePrint("removeTransformerFromManager fTransformerIndex decremented to: " +161fTransformerIndex);162}163}164165/**166* verify transformer by asserting that the number of transforms that occured167* is the same as the number of valid transformers added to the list.168* @param manager169*/170protected void171verifyTransformers(Instrumentation manager)172{173File f = new File(System.getProperty("test.classes", "."), redefinedClassName + ".class");174System.out.println("Reading test class from " + f);175try176{177InputStream redefineStream = new FileInputStream(f);178byte[] bytes = NamedBuffer.loadBufferFromStream(redefineStream);179ClassDefinition cd = new ClassDefinition(DummyClass.class, bytes);180fInst.redefineClasses(new ClassDefinition[]{ cd });181verbosePrint("verifyTransformers redefined " + redefinedClassName);182}183catch (IOException e)184{185fail("Could not load the class: " + redefinedClassName);186}187catch (ClassNotFoundException e)188{189fail("Could not find the class: " + redefinedClassName);190}191catch (UnmodifiableClassException e)192{193fail("Could not modify the class: " + redefinedClassName);194}195196// Report any delayed failures197assertTrue(fDelayedFailure, fDelayedFailure == null);198199assertEquals("The number of transformers that were run does not match the expected number added to manager",200fTransformers.size(), fTransformerIndex);201}202203204/**205* Asserts that the transformer being checked by the manager is the correct206* one (as far as order goes) and updates the number of transformers that have207* been called. Note that since this is being called inside of a transformer,208* a standard assert (which throws an exception) cannot be used since it would209* simply cancel the transformation and otherwise be ignored. Instead, note210* the failure for delayed processing.211* @param ClassFileTransformer212*/213private void214checkInTransformer(ClassFileTransformer transformer)215{216verbosePrint("checkInTransformer: " + transformer);217if (fDelayedFailure == null)218{219if (fTransformers.size() <= fTransformerIndex)220{221String msg = "The number of transformers that have checked in (" +(fTransformerIndex+1) +222") is greater number of tranformers created ("+fTransformers.size()+")";223fDelayedFailure = msg;224System.err.println("Delayed failure: " + msg);225verbosePrint("Delayed failure: " + msg);226}227if (!fTransformers.get(fTransformerIndex).equals(transformer))228{229String msg = "Transformer " + fTransformers.get(fTransformerIndex) +230" should be the same as " + transformer;231fDelayedFailure = msg;232System.err.println("Delayed failure: " + msg);233verbosePrint("Delayed failure: " + msg);234}235fTransformerIndex++;236verbosePrint("fTransformerIndex incremented to: " + fTransformerIndex);237}238}239240/**241* Create a new manager, a new transformer list, and initializes the number of transformers242* indexed to zero.243*/244protected void245setUp()246throws Exception247{248super.setUp();249fTransformers = new ArrayList();250fTransformerIndex = 0;251fDelayedFailure = null;252verbosePrint("setUp completed");253}254255/**256* Sets the manager and transformers to null so that setUp needs to update.257*/258protected void259tearDown()260throws Exception261{262verbosePrint("tearDown beginning");263fTransformers = null;264super.tearDown();265}266267/*268* Simple transformer that registers when it transforms269*/270public class MyClassFileTransformer extends SimpleIdentityTransformer {271private final String fID;272273public MyClassFileTransformer(String id) {274super();275fID = id;276}277278public String toString() {279return MyClassFileTransformer.this.getClass().getName() + fID;280}281282public byte[]283transform(284ClassLoader loader,285String className,286Class<?> classBeingRedefined,287ProtectionDomain protectionDomain,288byte[] classfileBuffer) {289290// The transform testing is triggered by redefine, ignore others291if (classBeingRedefined != null) checkInTransformer(MyClassFileTransformer.this);292293return super.transform( loader,294className,295classBeingRedefined,296protectionDomain,297classfileBuffer);298}299}300301302/**303* Class loader that does nothing304*/305public class MyClassLoader extends ClassLoader306{307/**308* Constructor for MyClassLoader.309*/310public MyClassLoader()311{312super();313}314315}316317public String debug_byteArrayToString(byte[] b) {318if (b == null) return "null";319320StringBuffer buf = new StringBuffer();321buf.append("byte[");322buf.append(b.length);323buf.append("] (");324for (int i = 0; i < b.length; i++)325{326buf.append(b[i]);327buf.append(",");328}329buf.deleteCharAt(buf.length()-1);330buf.append(")");331332return buf.toString();333}334}335336337