1 /*
2  * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 package nsk.jdwp.ReferenceType.MethodsWithGeneric;
25 
26 import java.io.*;
27 import java.util.*;
28 
29 import nsk.share.*;
30 import nsk.share.jpda.*;
31 import nsk.share.jdwp.*;
32 
33 /**
34  * This test checks that the JDWP command <code>MethodsWithGeneric</code>
35  * from the <code>ReferenceType</code> command set returns generic signature
36  * information properly.<br>
37  * Debuggee part of the test creates instances of several tested classes with
38  * methods to be checked. Some of the classes are generic and accordingly
39  * contain generic methods. Debugger part obtains information for each method
40  * in a reference type of a tested class. Proper generic signature should be
41  * returned for the generic methods, or an empty string for non-generic ones.
42  */
43 public class methwithgeneric001 {
44     static final String DEBUGGEE_CLASS =
45         "nsk.jdwp.ReferenceType.MethodsWithGeneric.methwithgeneric001t";
46 
47     static final String JDWP_COMMAND_NAME = "ReferenceType.MethodsWithGeneric";
48     static final int JDWP_COMMAND_ID =
49         JDWP.Command.ReferenceType.MethodsWithGeneric;
50 
51     static final String COMMAND_READY = "ready";
52     static final String COMMAND_QUIT = "quit";
53 
54     static final String[][][] methods = {
55        {{"<init>",
56             "()V",
57             "NULL"},
58         {"methwithgeneric001bMeth",
59             "(Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b;)Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b;",
60             "<L:Ljava/lang/String;>(Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b<TL;>;)Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b<Ljava/lang/String;>;"},
61         {"methwithgeneric001bMethSt",
62             "(Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b;)Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b;",
63             "<T:Ljava/lang/String;>(Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b<TT;>;)Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b<Ljava/lang/String;>;"}},
64 
65        {{"<init>",
66             "()V",
67             "NULL"},
68         {"methwithgeneric001cMeth",
69             "(Ljava/lang/Class;)Ljava/lang/Object;",
70             "<U:Ljava/lang/Object;>(Ljava/lang/Class<TU;>;)TU;"},
71          {"methwithgeneric001cMethSt",
72             "(Ljava/lang/Class;)Ljava/lang/Object;",
73             "<U:Ljava/lang/Object;>(Ljava/lang/Class<TU;>;)TU;"}},
74 
75        {{"<init>",
76             "()V",
77             "NULL"},
78         {"methwithgeneric001eMeth",
79            "(Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001e;)V",
80            "NULL"},
81         {"methwithgeneric001eMethSt",
82            "(Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001e;)V",
83            "NULL"}},
84 
85        {{"methwithgeneric001ifMeth",
86             "()I",
87             "NULL"},
88         {"methwithgeneric001ifMeth2",
89             "(Ljava/lang/Object;)I",
90             "<I:Ljava/lang/Object;>(TI;)I"}},
91 
92        {{"<init>",
93             "()V",
94             "NULL"},
95         {"methwithgeneric001gMeth",
96             "(Ljava/lang/Byte;Ljava/lang/Double;[Ljava/lang/Class;)V",
97             "<A:Ljava/lang/Byte;B:Ljava/lang/Double;>(TA;TB;[Ljava/lang/Class<*>;)V"},
98         {"methwithgeneric001gMethSt",
99             "(Ljava/lang/Byte;Ljava/lang/Double;)V",
100             "<A:Ljava/lang/Byte;B:Ljava/lang/Double;>(TA;TB;)V"}}
101     };
102 
103     static final String[][] classes = {
104         {"Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b;", "3"},
105         {"Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001c;", "3"},
106         {"Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001e;", "3"},
107         {"Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001if;", "2"},
108         {"Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001g;", "3"}
109     };
110 
111     static final int CLS_NUM = classes.length;
112 
main(String argv[])113     public static void main(String argv[]) {
114         System.exit(run(argv,System.out) + Consts.JCK_STATUS_BASE);
115     }
116 
run(String argv[], PrintStream out)117     public static int run(String argv[], PrintStream out) {
118         return new methwithgeneric001().runThis(argv, out);
119     }
120 
runThis(String argv[], PrintStream out)121     public int runThis(String argv[], PrintStream out) {
122         ArgumentHandler argumentHandler = new ArgumentHandler(argv);
123         Log log = new Log(out, argumentHandler);
124         boolean result = true;
125 
126         try {
127             Binder binder = new Binder(argumentHandler, log);
128 
129             log.display("Starting debuggee VM ...");
130             Debugee debuggee = binder.bindToDebugee(DEBUGGEE_CLASS);
131 
132             Transport transport = debuggee.getTransport();
133             IOPipe pipe = debuggee.createIOPipe();
134 
135             log.display("Waiting for VM_INIT event ...");
136             debuggee.waitForVMInit();
137 
138             log.display("Querying for IDSizes ...");
139             debuggee.queryForIDSizes();
140 
141             log.display("Resuming debuggee VM ...");
142             debuggee.resume();
143 
144             log.display("Waiting for command: " + COMMAND_READY
145                 + " ...");
146             String cmd = pipe.readln();
147             log.display(" ... Received command: " + cmd);
148 
149             try {
150                 for (int i=0; i<CLS_NUM; i++) {
151                     long typeID = debuggee.getReferenceTypeID(classes[i][0]);
152 
153                     /////// begin test of JDWP command
154                     log.display("\n>>>>>> Create command " + JDWP_COMMAND_NAME
155                         + "\n\twith ReferenceTypeID: " + typeID
156                         + "\n\tof the class: " + classes[i][0]);
157                     CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
158                     command.addReferenceTypeID(typeID);
159                     command.setLength();
160 
161                     log.display("Sending command packet:\n" + command);
162                     transport.write(command);
163 
164                     log.display("\nWaiting for reply packet ...");
165                     ReplyPacket reply = new ReplyPacket();
166                     transport.read(reply);
167                     log.display(" ... Reply packet received:\n" + reply);
168 
169                     log.display("\nChecking reply packet header");
170                     reply.checkHeader(command.getPacketID());
171 
172                  /* parsing of reply data:
173                      int declared - Number of declared methods
174 
175                      ---- Repeated 'declared' times:
176                      methodID methodID - Method ID
177                      string nam - The name of the field
178                      string signature - The JNI signature of the field.
179                      string genericSignature - The generic signature of the field,
180                                                  or an empty string if there is none.
181                      int modBits - The modifier bit flags (also known as access flags)
182                      ----
183                  */
184                     log.display("\nParsing reply packet:");
185                     reply.resetPosition();
186 
187                     long declared = reply.getInt();
188                     log.display("\tdeclared: " + declared);
189                     int meth_num = Integer.parseInt(classes[i][1]);
190                     if (declared != meth_num) {
191                         log.complain("TEST FAILED: Unexpected number of declared methods in the reply packet:"
192                             + "\n\tGot: " + declared
193                             + "\n\tExpected: " + meth_num + "\n");
194                         result = false;
195                     }
196 
197                     for (int j=0; j<declared; j++) {
198                         log.display("\t--> method #" + j);
199 
200                         long methodID = reply.getMethodID();
201                         log.display("\t\tmethodID: " + methodID);
202 
203                         String name = reply.getString();
204                         log.display("\t\tname: " + name);
205                         if (!name.equals(methods[i][j][0])) {
206                             log.complain("TEST FAILED: Unexpected name of method #" + i
207                                 + " in the reply packet:"
208                                 + "\n\tGot: " + name
209                                 + "\n\tExpected: " + methods[i][j][0] + "\n");
210                             result = false;
211                         }
212 
213                         String signature = reply.getString();
214                         log.display("\t\tsignature: " + signature);
215                         if (!signature.equals(methods[i][j][1])) {
216                             log.complain("TEST FAILED: Unexpected type signature of field #" + i
217                                 + " in the reply packet:"
218                                 + "\n\tGot: " + signature
219                                 + "\n\tExpected: " + methods[i][j][1] + "\n");
220                             result = false;
221                         }
222 
223                         String genSignature = reply.getString();
224                         log.display("\t\tgeneric signature: " + genSignature);
225                         if (genSignature.length() == 0) // a non-generic field
226                             genSignature = "NULL";
227                         if (!genSignature.equals(methods[i][j][2])) {
228                             log.complain("TEST FAILED: Unexpected generic signature of field #" + i
229                                 + " in the reply packet:"
230                                 + "\n\tGot: " + genSignature
231                                 + "\n\tExpected: " + methods[i][j][2] + "\n");
232                             result = false;
233                         }
234 
235                         int modBits = reply.getInt();
236                         String modBitsString = "0x" + Packet.toHexString(modBits, 8);
237                         log.display("\t\tmodBits: " + modBitsString);
238                     }
239 
240                     if (!reply.isParsed()) {
241                         log.complain("TEST FAILED: Extra trailing bytes found in reply packet at: "
242                             + reply.currentPosition());
243                         result = false;
244                     } else
245                         log.display("\n<<<<<< Reply packet parsed");
246                     /////// end test of JDWP command
247                 }
248 
249             } catch (Exception e) {
250                 e.printStackTrace(out);
251                 log.complain("Caught exception while testing JDWP command: "
252                     + e);
253                 result = false;
254             } finally {
255                 log.display("Sending command: " + COMMAND_QUIT + " ...");
256                 pipe.println(COMMAND_QUIT);
257 
258                 log.display("Waiting for debuggee exits ...");
259                 int code = debuggee.waitFor();
260                 if (code == Consts.JCK_STATUS_BASE + Consts.TEST_PASSED) {
261                     log.display(" ... Debuggee PASSED with the exit code: "
262                         + code);
263                 } else {
264                     log.complain(" ... Debuggee FAILED with the exit code: "
265                         + code);
266                     result = false;
267                 }
268             }
269 
270         } catch (Exception e) {
271             e.printStackTrace(out);
272             log.complain("Caught unexpected exception while communicating with debugee: "
273                 + e);
274             result = false;
275         }
276 
277         if (!result)
278             return Consts.TEST_FAILED;
279 
280         return Consts.TEST_PASSED;
281     }
282 
283 }
284