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.share;
20 
21 import org.apache.harmony.jpda.tests.framework.jdwp.Location;
22 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
23 import org.apache.harmony.jpda.tests.framework.jdwp.Value;
24 import org.apache.harmony.jpda.tests.jdwp.share.debuggee.ProxyDebuggee;
25 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
26 
27 public abstract class JDWPProxyTestCase extends JDWPSyncTestCase {
28 
29     @Override
getDebuggeeClassName()30     protected String getDebuggeeClassName() {
31         return ProxyDebuggee.class.getName();
32     }
33 
34     protected static class EventContext {
35         private final long threadId;
36         private final long frameId;
37         private final Location location;
38 
EventContext(long threadId, long frameId, Location location)39         public EventContext(long threadId, long frameId, Location location) {
40             this.threadId = threadId;
41             this.frameId = frameId;
42             this.location = location;
43         }
44 
getThreadId()45         public long getThreadId() {
46             return threadId;
47         }
48 
getFrameId()49         public long getFrameId() {
50             return frameId;
51         }
52 
getLocation()53         public Location getLocation() {
54             return location;
55         }
56     }
57 
stopInProxyMethod()58     protected EventContext stopInProxyMethod() {
59         synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
60 
61         // Set breakpoint.
62         String debuggeeSignature = getDebuggeeClassSignature();
63         long classId = getClassIDBySignature(debuggeeSignature);
64         int requestId = debuggeeWrapper.vmMirror.setBreakpointAtMethodBegin(
65                 classId, "breakpointMethodFromProxy");
66 
67         // Signal debuggee to continue execution.
68         synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
69 
70         long eventThreadId = debuggeeWrapper.vmMirror.waitForBreakpoint(
71                 requestId);
72 
73         String proxyClassSignature = "Ljava/lang/reflect/Proxy;";
74         long proxyClassId = getClassIDBySignature(proxyClassSignature);
75         assertTrue("No class " + proxyClassSignature, proxyClassId != -1);
76 
77         EventContext context = getFirstProxyFrameId(eventThreadId, proxyClassId);
78         assertNotNull("Failed to find proxy frame", context);
79 
80         return context;
81     }
82 
getFirstProxyFrameId(long eventThreadId, long proxyClassId)83     private EventContext getFirstProxyFrameId(long eventThreadId, long proxyClassId) {
84         int framesCount = debuggeeWrapper.vmMirror.getFrameCount(eventThreadId);
85         ReplyPacket reply = debuggeeWrapper.vmMirror.getThreadFrames(eventThreadId, 0, framesCount);
86         framesCount = reply.getNextValueAsInt();
87         for (int i = 0; i < framesCount; ++i) {
88             long frameId = reply.getNextValueAsFrameID();
89             Location location = reply.getNextValueAsLocation();
90             // TODO dump frame for context.
91             String className = getClassSignature(location.classID);
92             String methodName = getMethodName(location.classID, location.methodID);
93             logWriter.println("Frame #" + i + ": " + className + "." + methodName + "@" + location.index);
94             if (location.classID != proxyClassId &&
95                     IsProxy(location.classID, proxyClassId)) {
96                 return new EventContext(eventThreadId, frameId, location);
97             }
98         }
99         return null;
100     }
101 
IsProxy(long typeId, long proxyClassId)102     private boolean IsProxy(long typeId, long proxyClassId) {
103         if (typeId == proxyClassId) {
104             return true;
105         } else if (typeId == 0) {
106             return false;
107         } else {
108             return IsProxy(debuggeeWrapper.vmMirror.getSuperclassId(typeId),
109                     proxyClassId);
110         }
111     }
112 
getExpectedProxyObjectValue()113     protected Value getExpectedProxyObjectValue() {
114         String debuggeeSignature = getDebuggeeClassSignature();
115         long classId = getClassIDBySignature(debuggeeSignature);
116         long checkedProxyObjectFieldId = checkField(classId, "checkedProxyObject");
117         long[] fieldIDs = new long[] { checkedProxyObjectFieldId };
118         Value[] fieldValues = debuggeeWrapper.vmMirror.getReferenceTypeValues(classId, fieldIDs);
119         Value value = fieldValues[0];
120         logWriter.println("Proxy object is " + value.toString());
121         return value;
122     }
123 }
124