| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.harmony.jpda.tests.jdwp.ClassType; |
| |
| import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket; |
| import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands; |
| import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; |
| import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket; |
| import org.apache.harmony.jpda.tests.framework.jdwp.TaggedObject; |
| import org.apache.harmony.jpda.tests.framework.jdwp.Value; |
| import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase; |
| import org.apache.harmony.jpda.tests.jdwp.share.JDWPTestConstants; |
| import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** |
| * Base class to test ClassType.NewInstance for specific reference types. |
| */ |
| public abstract class AbstractNewInstanceTestCase extends JDWPSyncTestCase { |
| |
| protected static final String CONSTRUCTOR_NAME = "<init>"; |
| |
| /** |
| * A provider is responsible for giving the arguments passed to the tested |
| * constructor. |
| */ |
| protected static interface ConstructorArgumentsProvider { |
| /** |
| * This method is called to provide the arguments to the constructor |
| * called to create the java.lang.String instance. This is called when |
| * the debuggee is suspended on a breakpoint. |
| * |
| * @param constructorArguments |
| * the list of arguments passed to the constructor |
| */ |
| public void provideConstructorArguments(List<Value> constructorArguments); |
| } |
| |
| /** |
| * Default implementation for constructor without argument. |
| */ |
| protected static class NoConstructorArgumentProvider implements ConstructorArgumentsProvider { |
| @Override |
| public void provideConstructorArguments(List<Value> constructorArguments) { |
| } |
| } |
| |
| /** |
| * Checks that ClassType.NewInstance command for the given type and constructor returns the |
| * expected tag. |
| * At first, the test starts the debuggee. Then request a breakpoint and wait for it. |
| * Once the debuggee is suspended on the breakpoint, send ClassType.NewInstance command |
| * for the given type using the constructor whose signature is given as parameter. A |
| * provider is responsible to provide the arguments for the specified |
| * constructor as JDWP values. |
| * Finally, the test verifies that the returned object is not null, the exception object |
| * is null and the returned object tag is the expected one. |
| * |
| * @param typeSignature the type signature of the created object |
| * @param constructorSignature the constructor signature |
| * @param provider the arguments provider |
| * @param checker the checker that verifies the construction of the object. |
| */ |
| protected void checkNewInstanceTag(String typeSignature, String constructorSignature, |
| ConstructorArgumentsProvider provider, Checker checker) { |
| synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); |
| |
| long debuggeeClassId = getClassIDBySignature(getDebuggeeClassSignature()); |
| logWriter.println("Debuggee class: " + getDebuggeeClassSignature()); |
| logWriter.println("Debuggee class ID: " + debuggeeClassId); |
| |
| // Request breakpoint. |
| int breakpointRequestId = debuggeeWrapper.vmMirror |
| .setBreakpointAtMethodBegin(debuggeeClassId, "breakpointMethod"); |
| |
| // Continue debuggee. |
| synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); |
| |
| // Wait for breakpoint. |
| long threadId = debuggeeWrapper.vmMirror.waitForBreakpoint(breakpointRequestId); |
| |
| // Clear breakpoint |
| debuggeeWrapper.vmMirror.clearBreakpoint(breakpointRequestId); |
| |
| long referenceTypeId = getClassIDBySignature(typeSignature); |
| assertTrue("Failed to find " + typeSignature, referenceTypeId != -1); |
| logWriter.println(typeSignature + " class ID: " + referenceTypeId); |
| |
| final String methodName = CONSTRUCTOR_NAME; |
| final String methodSignature = constructorSignature; |
| final String fullMethodName = methodName + methodSignature; |
| long constructorId = getMethodID(referenceTypeId, methodName, methodSignature); |
| assertTrue("Failed to find constructor " + fullMethodName, constructorId != -1); |
| logWriter.println(fullMethodName + " method ID: " + constructorId); |
| |
| // Request provider to fill the arguments list. |
| List<Value> argumentsList = new ArrayList<Value>(); |
| provider.provideConstructorArguments(argumentsList); |
| |
| logWriter |
| .println("Sending ClassType.NewInstance command for constructor " + fullMethodName); |
| CommandPacket packet = new CommandPacket(JDWPCommands.ClassTypeCommandSet.CommandSetID, |
| JDWPCommands.ClassTypeCommandSet.NewInstanceCommand); |
| packet.setNextValueAsReferenceTypeID(referenceTypeId); |
| packet.setNextValueAsThreadID(threadId); |
| packet.setNextValueAsMethodID(constructorId); |
| packet.setNextValueAsInt(argumentsList.size()); // argCount |
| for (Value value : argumentsList) { |
| packet.setNextValueAsValue(value); |
| } |
| packet.setNextValueAsInt(0); // invoke options |
| ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet); |
| checkReplyPacket(reply, "ClassType.NewInstance command"); |
| |
| // Check result. |
| TaggedObject objectResult = reply.getNextValueAsTaggedObject(); |
| TaggedObject exceptionResult = reply.getNextValueAsTaggedObject(); |
| assertAllDataRead(reply); |
| checker.check(objectResult, exceptionResult); |
| |
| // Debuggee is suspended on the breakpoint: resume it now. |
| resumeDebuggee(); |
| } |
| |
| /** |
| * Checks that the constructed object has the right tag. |
| */ |
| protected class Checker { |
| private final byte expectedTag; |
| |
| public Checker(byte expectedTag) { |
| this.expectedTag = expectedTag; |
| } |
| |
| public void check(TaggedObject objectResult, TaggedObject exceptionResult) { |
| assertNotNull("objectResult is null", objectResult); |
| assertNotNull("exceptionResult is null", exceptionResult); |
| assertTrue(objectResult.objectID != JDWPTestConstants.NULL_OBJECT_ID); |
| assertTrue(exceptionResult.tag == JDWPConstants.Tag.OBJECT_TAG); |
| assertEquals(exceptionResult.objectID, JDWPTestConstants.NULL_OBJECT_ID); |
| assertTagEquals("Invalid tag", expectedTag, objectResult.tag); |
| } |
| } |
| } |