diff options
author | Sebastien Hertz <shertz@google.com> | 2014-12-10 13:16:57 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-12-10 13:16:57 +0000 |
commit | 0c9e67d3b5b0cf803409304797798c57d3c8acd1 (patch) | |
tree | 365327435816949720772560ab8ff857c96c233d | |
parent | 537ad57d762c8e57d847337f377b9606bc2874f7 (diff) | |
parent | 32e3e8da6c42b15c1011f67930b460260704739a (diff) | |
download | apache-harmony-0c9e67d3b5b0cf803409304797798c57d3c8acd1.tar.gz |
Merge "Test StackFrame.ThisObject for proxy method"android-wear-5.0.0_r1lollipop-wear-release
5 files changed, 283 insertions, 0 deletions
diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/StackFrame/ProxyThisObjectTest.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/StackFrame/ProxyThisObjectTest.java new file mode 100644 index 0000000..16d79c3 --- /dev/null +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/StackFrame/ProxyThisObjectTest.java @@ -0,0 +1,61 @@ +/* + * 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.StackFrame; + +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.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.JDWPProxyTestCase; + +/** + * JDWP Unit test for StackFrame.ThisObject command on proxy method. + */ +public class ProxyThisObjectTest extends JDWPProxyTestCase { + + public void testThisObject() { + logWriter.println("testThisObject started"); + + EventContext context = stopInProxyMethod(); + + Value proxyObjectValue = getExpectedProxyObjectValue(); + + logWriter.println("==> Send StackFrame::ThisObject command..."); + CommandPacket packet = new CommandPacket( + JDWPCommands.StackFrameCommandSet.CommandSetID, + JDWPCommands.StackFrameCommandSet.ThisObjectCommand); + packet.setNextValueAsThreadID(context.getThreadId()); + packet.setNextValueAsLong(context.getFrameId()); + ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet); + checkReplyPacket(reply, "StackFrame.ThisObject"); + TaggedObject taggedObject = reply.getNextValueAsTaggedObject(); + assertAllDataRead(reply); + + assertEquals("Unexpected object id", proxyObjectValue.getLongValue(), + taggedObject.objectID); + assertEquals("Unexpected object tag", proxyObjectValue.getTag(), + taggedObject.tag); + + // Resume debuggee before leaving. + resumeDebuggee(); + + logWriter.println("testThisObject finished"); + } +} diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/share/JDWPProxyTestCase.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/share/JDWPProxyTestCase.java new file mode 100644 index 0000000..79c0d2b --- /dev/null +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/share/JDWPProxyTestCase.java @@ -0,0 +1,123 @@ +/* + * 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.share; + +import org.apache.harmony.jpda.tests.framework.jdwp.Location; +import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket; +import org.apache.harmony.jpda.tests.framework.jdwp.Value; +import org.apache.harmony.jpda.tests.jdwp.share.debuggee.ProxyDebuggee; +import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; + +public abstract class JDWPProxyTestCase extends JDWPSyncTestCase { + + @Override + protected String getDebuggeeClassName() { + return ProxyDebuggee.class.getName(); + } + + protected static class EventContext { + private final long threadId; + private final long frameId; + private final Location location; + + public EventContext(long threadId, long frameId, Location location) { + this.threadId = threadId; + this.frameId = frameId; + this.location = location; + } + + public long getThreadId() { + return threadId; + } + + public long getFrameId() { + return frameId; + } + + public Location getLocation() { + return location; + } + } + + protected EventContext stopInProxyMethod() { + synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); + + // Set breakpoint. + String debuggeeSignature = getDebuggeeClassSignature(); + long classId = getClassIDBySignature(debuggeeSignature); + long requestId = debuggeeWrapper.vmMirror.setBreakpointAtMethodBegin( + classId, "breakpointMethodFromProxy"); + + // Signal debuggee to continue execution. + synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); + + long eventThreadId = debuggeeWrapper.vmMirror.waitForBreakpoint( + requestId); + + String proxyClassSignature = "Ljava/lang/reflect/Proxy;"; + long proxyClassId = getClassIDBySignature(proxyClassSignature); + assertTrue("No class " + proxyClassSignature, proxyClassId != -1); + + EventContext context = getFirstProxyFrameId(eventThreadId, proxyClassId); + assertNotNull("Failed to find proxy frame", context); + + return context; + } + + private EventContext getFirstProxyFrameId(long eventThreadId, long proxyClassId) { + int framesCount = debuggeeWrapper.vmMirror.getFrameCount(eventThreadId); + ReplyPacket reply = debuggeeWrapper.vmMirror.getThreadFrames(eventThreadId, 0, framesCount); + framesCount = reply.getNextValueAsInt(); + for (int i = 0; i < framesCount; ++i) { + long frameId = reply.getNextValueAsFrameID(); + Location location = reply.getNextValueAsLocation(); + // TODO dump frame for context. + String className = getClassSignature(location.classID); + String methodName = getMethodName(location.classID, location.methodID); + logWriter.println("Frame #" + i + ": " + className + "." + methodName + "@" + location.index); + if (location.classID != proxyClassId && + IsProxy(location.classID, proxyClassId)) { + return new EventContext(eventThreadId, frameId, location); + } + } + return null; + } + + private boolean IsProxy(long typeId, long proxyClassId) { + if (typeId == proxyClassId) { + return true; + } else if (typeId == 0) { + return false; + } else { + return IsProxy(debuggeeWrapper.vmMirror.getSuperclassId(typeId), + proxyClassId); + } + } + + protected Value getExpectedProxyObjectValue() { + String debuggeeSignature = getDebuggeeClassSignature(); + long classId = getClassIDBySignature(debuggeeSignature); + long checkedProxyObjectFieldId = checkField(classId, "checkedProxyObject"); + long[] fieldIDs = new long[] { checkedProxyObjectFieldId }; + Value[] fieldValues = debuggeeWrapper.vmMirror.getReferenceTypeValues(classId, fieldIDs); + Value value = fieldValues[0]; + logWriter.println("Proxy object is " + value.toString()); + return value; + } +} diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/share/JDWPRawTestCase.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/share/JDWPRawTestCase.java index b5aa5cb..731198d 100644 --- a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/share/JDWPRawTestCase.java +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/share/JDWPRawTestCase.java @@ -59,6 +59,21 @@ public abstract class JDWPRawTestCase extends TestCase { protected abstract String getDebuggeeClassName(); /** + * Returns the signature of the debuggee class. This is computed based on + * {@link #getDebuggeeClassName}. + * + * @return full debuggee class signature. + */ + protected String getDebuggeeClassSignature() { + String debuggeeClassName = getDebuggeeClassName(); + StringBuilder builder = new StringBuilder(); + builder.append('L'); + builder.append(debuggeeClassName.replace('.', '/')); + builder.append(';'); + return builder.toString(); + } + + /** * This method will be invoked before starting each test. * * @throws Exception diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/share/debuggee/ProxyDebuggee.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/share/debuggee/ProxyDebuggee.java new file mode 100644 index 0000000..8315f10 --- /dev/null +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/share/debuggee/ProxyDebuggee.java @@ -0,0 +1,83 @@ +/* + * 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.share.debuggee; + +import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; +import org.apache.harmony.jpda.tests.share.SyncDebuggee; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +public class ProxyDebuggee extends SyncDebuggee { + public static Object checkedProxyObject = null; + + public static final int ARG_INT = 5; + public static final long ARG_LONG = 135l; + public static final String ARG_OBJECT = "a string argument"; + + public void breakpointMethodFromProxy() { + System.out.println("breakpointMethodFromProxy"); + } + + static interface InterfaceForProxy { + public void call(int i, long l, Object obj); + } + + static class ProxyInvocationHandler implements InvocationHandler { + private final ProxyDebuggee mDebuggee; + + public ProxyInvocationHandler(ProxyDebuggee debuggee) { + mDebuggee = debuggee; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { + mDebuggee.breakpointMethodFromProxy(); + return null; + } + } + + public void invokeBreakpointMethodFromProxy() { + checkedProxyObject = Proxy.newProxyInstance(getClass().getClassLoader(), + new Class<?>[] { InterfaceForProxy.class }, + new ProxyInvocationHandler(this)); + InterfaceForProxy proxy = (InterfaceForProxy) checkedProxyObject; + proxy.call(ARG_INT, ARG_LONG, ARG_OBJECT); + } + + @Override + public void run() { + synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_READY); + + logWriter.println("ProxyDebuggee started"); + + synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); + + invokeBreakpointMethodFromProxy(); + + logWriter.println("ProxyDebuggee finished"); + } + + public static void main(String[] args) { + runDebuggee(ProxyDebuggee.class); + } + +} diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/share/AllTests.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/share/AllTests.java index 3f3cade..ffb44e3 100644 --- a/jdwp/src/test/java/org/apache/harmony/jpda/tests/share/AllTests.java +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/share/AllTests.java @@ -154,6 +154,7 @@ public class AllTests { suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.StackFrame.GetValuesTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.StackFrame.PopFrames002Test.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.StackFrame.PopFramesTest.class); + suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.StackFrame.ProxyThisObjectTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.StackFrame.SetValuesTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.StackFrame.ThisObjectTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.StringReference.ValueTest.class); |