1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package org.apache.harmony.jpda.tests.jdwp.ClassType; 20 21 import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket; 22 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands; 23 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; 24 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket; 25 import org.apache.harmony.jpda.tests.framework.jdwp.TaggedObject; 26 import org.apache.harmony.jpda.tests.framework.jdwp.Value; 27 import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase; 28 import org.apache.harmony.jpda.tests.jdwp.share.JDWPTestConstants; 29 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; 30 31 import java.util.ArrayList; 32 import java.util.List; 33 34 /** 35 * Base class to test ClassType.NewInstance for specific reference types. 36 */ 37 public abstract class AbstractNewInstanceTestCase extends JDWPSyncTestCase { 38 39 protected static final String CONSTRUCTOR_NAME = "<init>"; 40 41 /** 42 * A provider is responsible for giving the arguments passed to the tested 43 * constructor. 44 */ 45 protected static interface ConstructorArgumentsProvider { 46 /** 47 * This method is called to provide the arguments to the constructor 48 * called to create the java.lang.String instance. This is called when 49 * the debuggee is suspended on a breakpoint. 50 * 51 * @param constructorArguments 52 * the list of arguments passed to the constructor 53 */ provideConstructorArguments(List<Value> constructorArguments)54 public void provideConstructorArguments(List<Value> constructorArguments); 55 } 56 57 /** 58 * Default implementation for constructor without argument. 59 */ 60 protected static class NoConstructorArgumentProvider implements ConstructorArgumentsProvider { 61 @Override provideConstructorArguments(List<Value> constructorArguments)62 public void provideConstructorArguments(List<Value> constructorArguments) { 63 } 64 } 65 66 /** 67 * Checks that ClassType.NewInstance command for the given type and constructor returns the 68 * expected tag. 69 * At first, the test starts the debuggee. Then request a breakpoint and wait for it. 70 * Once the debuggee is suspended on the breakpoint, send ClassType.NewInstance command 71 * for the given type using the constructor whose signature is given as parameter. A 72 * provider is responsible to provide the arguments for the specified 73 * constructor as JDWP values. 74 * Finally, the test verifies that the returned object is not null, the exception object 75 * is null and the returned object tag is the expected one. 76 * 77 * @param typeSignature the type signature of the created object 78 * @param constructorSignature the constructor signature 79 * @param provider the arguments provider 80 * @param checker the checker that verifies the construction of the object. 81 */ checkNewInstanceTag(String typeSignature, String constructorSignature, ConstructorArgumentsProvider provider, Checker checker)82 protected void checkNewInstanceTag(String typeSignature, String constructorSignature, 83 ConstructorArgumentsProvider provider, Checker checker) { 84 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 85 86 long debuggeeClassId = getClassIDBySignature(getDebuggeeClassSignature()); 87 logWriter.println("Debuggee class: " + getDebuggeeClassSignature()); 88 logWriter.println("Debuggee class ID: " + debuggeeClassId); 89 90 // Request breakpoint. 91 int breakpointRequestId = debuggeeWrapper.vmMirror 92 .setBreakpointAtMethodBegin(debuggeeClassId, "breakpointMethod"); 93 94 // Continue debuggee. 95 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 96 97 // Wait for breakpoint. 98 long threadId = debuggeeWrapper.vmMirror.waitForBreakpoint(breakpointRequestId); 99 100 // Clear breakpoint 101 debuggeeWrapper.vmMirror.clearBreakpoint(breakpointRequestId); 102 103 long referenceTypeId = getClassIDBySignature(typeSignature); 104 assertTrue("Failed to find " + typeSignature, referenceTypeId != -1); 105 logWriter.println(typeSignature + " class ID: " + referenceTypeId); 106 107 final String methodName = CONSTRUCTOR_NAME; 108 final String methodSignature = constructorSignature; 109 final String fullMethodName = methodName + methodSignature; 110 long constructorId = getMethodID(referenceTypeId, methodName, methodSignature); 111 assertTrue("Failed to find constructor " + fullMethodName, constructorId != -1); 112 logWriter.println(fullMethodName + " method ID: " + constructorId); 113 114 // Request provider to fill the arguments list. 115 List<Value> argumentsList = new ArrayList<Value>(); 116 provider.provideConstructorArguments(argumentsList); 117 118 logWriter 119 .println("Sending ClassType.NewInstance command for constructor " + fullMethodName); 120 CommandPacket packet = new CommandPacket(JDWPCommands.ClassTypeCommandSet.CommandSetID, 121 JDWPCommands.ClassTypeCommandSet.NewInstanceCommand); 122 packet.setNextValueAsReferenceTypeID(referenceTypeId); 123 packet.setNextValueAsThreadID(threadId); 124 packet.setNextValueAsMethodID(constructorId); 125 packet.setNextValueAsInt(argumentsList.size()); // argCount 126 for (Value value : argumentsList) { 127 packet.setNextValueAsValue(value); 128 } 129 packet.setNextValueAsInt(0); // invoke options 130 ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet); 131 checkReplyPacket(reply, "ClassType.NewInstance command"); 132 133 // Check result. 134 TaggedObject objectResult = reply.getNextValueAsTaggedObject(); 135 TaggedObject exceptionResult = reply.getNextValueAsTaggedObject(); 136 assertAllDataRead(reply); 137 checker.check(objectResult, exceptionResult); 138 139 // Debuggee is suspended on the breakpoint: resume it now. 140 resumeDebuggee(); 141 } 142 143 /** 144 * Checks that the constructed object has the right tag. 145 */ 146 protected class Checker { 147 private final byte expectedTag; 148 Checker(byte expectedTag)149 public Checker(byte expectedTag) { 150 this.expectedTag = expectedTag; 151 } 152 check(TaggedObject objectResult, TaggedObject exceptionResult)153 public void check(TaggedObject objectResult, TaggedObject exceptionResult) { 154 assertNotNull("objectResult is null", objectResult); 155 assertNotNull("exceptionResult is null", exceptionResult); 156 assertTrue(objectResult.objectID != JDWPTestConstants.NULL_OBJECT_ID); 157 assertTrue(exceptionResult.tag == JDWPConstants.Tag.OBJECT_TAG); 158 assertEquals(exceptionResult.objectID, JDWPTestConstants.NULL_OBJECT_ID); 159 assertTagEquals("Invalid tag", expectedTag, objectResult.tag); 160 } 161 } 162 } 163