1 /*
2  * Copyright (c) 2001, 2020, 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 
25 /*
26  * @test
27  *
28  * @summary converted from VM Testbase nsk/jdi/VoidValue/hashCode/hashcode001.
29  * VM Testbase keywords: [quick, jpda, jdi]
30  * VM Testbase readme:
31  * DESCRIPTION:
32  *     The test for the implementation of an object of the type
33  *     VoidValue.
34  *     The test checks up that a result of the method
35  *     com.sun.jdi.VoidValue.hashCode()
36  *     complies with its spec:
37  *     public int hashCode()
38  *     Returns the hash code value for this VoidValue.
39  *     Returns: the hash code
40  *     Overrides: hashCode in class java.lang.Object
41  *     The test works as follows:
42  *     A debugger program - nsk.jdi.VoidValue.hashCode.hashcode001;
43  *     a debuggee program - nsk.jdi.VoidValue.hashCode.hashcode001a.
44  *     Using nsk.jdi.share classes,
45  *     the debugger gets the debuggee running on another JavaVM,
46  *     creates the object debuggee.VM,
47  *     establishes a pipe with the debuggee program, and then
48  *     send to the programm commands, to which the debuggee replies
49  *     via the pipe. Upon getting reply,
50  *     the debugger calls corresponding debuggee.VM methods to get
51  *     needed data and compares the data got to the data expected.
52  *     In case of mismatch the test produces the return value 97 and
53  *     a corresponding error message(s).
54  *     Otherwise, the test is passed and produces
55  *     the return value 95 and no message.
56  * COMMENTS:
57  *
58  * @library /vmTestbase
59  *          /test/lib
60  * @build nsk.jdi.VoidValue.hashCode.hashcode001.hashcode001
61  *        nsk.jdi.VoidValue.hashCode.hashcode001.hashcode001a
62  * @run main/othervm
63  *      nsk.jdi.VoidValue.hashCode.hashcode001.hashcode001
64  *      -verbose
65  *      -arch=${os.family}-${os.simpleArch}
66  *      -waittime=5
67  *      -debugee.vmkind=java
68  *      -transport.address=dynamic
69  *      -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
70  */
71 
72 package nsk.jdi.VoidValue.hashCode.hashcode001;
73 
74 import nsk.share.*;
75 import nsk.share.jpda.*;
76 import nsk.share.jdi.*;
77 
78 import com.sun.jdi.*;
79 import com.sun.jdi.event.*;
80 import com.sun.jdi.request.*;
81 import java.util.*;
82 import java.io.*;
83 
84 /**
85  * The test for the implementation of an object of the type     <BR>
86  * VoidValue.                                                   <BR>
87  *                                                              <BR>
88  * The test checks up that results of the method                <BR>
89  * <code>com.sun.jdi.VoidValue.hashCode()</code>                <BR>
90  * complies with its spec.                                      <BR>
91  * <BR>
92  * The cases for testing are as follows :               <BR>
93  *                                                      <BR>
94  * when a gebuggee is suspended at a breakpoint         <BR>
95  * set by a debugger,                                   <BR>
96  * the debugger invokes debuggee's methods:             <BR>
97  *    void vdValue1(); void vdValue1(); void vdValue2();<BR>
98  * to form the follwing objects:  Value returnvdValue1, <BR>
99  *    Value returnvdValue2, and Value returnvdValue3;   <BR>
100  *                                                      <BR>
101  * performs following casts:                            <BR>
102  *    VoidValue vdValue1 = (VoidValue) returnvdValue1;  <BR>
103  *    VoidValue vdValue2 = (VoidValue) returnvdValue2;  <BR>
104  *    VoidValue vdValue3 = (VoidValue) returnvdValue3;  <BR>
105  *                                                      <BR>
106  * and checks up that each of the following is true:    <BR>
107  *                                                      <BR>
108  *     vdValue1.hashCode() == vdValue2.hashCode()       <BR>
109  *     vdValue1.hashCode() == vdValue3.hashCode()       <BR>
110  * <BR>
111  */
112 
113 public class hashcode001 {
114 
115     //----------------------------------------------------- templete section
116     static final int PASSED = 0;
117     static final int FAILED = 2;
118     static final int PASS_BASE = 95;
119 
120     //----------------------------------------------------- templete parameters
121     static final String
122     sHeader1 = "\n==> nsk/jdi/VoidValue/hashCode/hashcode001",
123     sHeader2 = "--> debugger: ",
124     sHeader3 = "##> debugger: ";
125 
126     //----------------------------------------------------- main method
127 
main(String argv[])128     public static void main (String argv[]) {
129         int result = run(argv, System.out);
130         System.exit(result + PASS_BASE);
131     }
132 
run(String argv[], PrintStream out)133     public static int run (String argv[], PrintStream out) {
134         return new hashcode001().runThis(argv, out);
135     }
136 
137      //--------------------------------------------------   log procedures
138 
139     //private static boolean verbMode = false;
140 
141     private static Log  logHandler;
142 
log1(String message)143     private static void log1(String message) {
144         logHandler.display(sHeader1 + message);
145     }
log2(String message)146     private static void log2(String message) {
147         logHandler.display(sHeader2 + message);
148     }
log3(String message)149     private static void log3(String message) {
150         logHandler.complain(sHeader3 + message);
151     }
152 
153     //  ************************************************    test parameters
154 
155     private String debuggeeName =
156         "nsk.jdi.VoidValue.hashCode.hashcode001.hashcode001a";
157 
158     private String testedClassName =
159         "nsk.jdi.VoidValue.hashCode.hashcode001.Threadhashcode001a";
160 
161     //====================================================== test program
162     //------------------------------------------------------ common section
163     static ArgumentHandler      argsHandler;
164 
165     static int waitTime;
166 
167     static VirtualMachine      vm            = null;
168     static EventRequestManager eventRManager = null;
169     static EventQueue          eventQueue    = null;
170     static EventSet            eventSet      = null;
171 
172     ReferenceType     testedclass  = null;
173     ThreadReference   thread2      = null;
174     ThreadReference   mainThread   = null;
175 
176     static int  testExitCode = PASSED;
177 
178     static final int returnCode0 = 0;
179     static final int returnCode1 = 1;
180     static final int returnCode2 = 2;
181     static final int returnCode3 = 3;
182     static final int returnCode4 = 4;
183 
184     //------------------------------------------------------ methods
185 
runThis(String argv[], PrintStream out)186     private int runThis (String argv[], PrintStream out) {
187 
188         Debugee debuggee;
189 
190         argsHandler     = new ArgumentHandler(argv);
191         logHandler      = new Log(out, argsHandler);
192         Binder binder   = new Binder(argsHandler, logHandler);
193 
194         if (argsHandler.verbose()) {
195             debuggee = binder.bindToDebugee(debuggeeName + " -vbs");  // *** tp
196         } else {
197             debuggee = binder.bindToDebugee(debuggeeName);            // *** tp
198         }
199 
200         waitTime = argsHandler.getWaitTime();
201 
202 
203         IOPipe pipe     = new IOPipe(debuggee);
204 
205         debuggee.redirectStderr(out);
206         log2(debuggeeName + " debuggee launched");
207         debuggee.resume();
208 
209         String line = pipe.readln();
210         if ((line == null) || !line.equals("ready")) {
211             log3("signal received is not 'ready' but: " + line);
212             return FAILED;
213         } else {
214             log2("'ready' recieved");
215         }
216 
217         VirtualMachine vm = debuggee.VM();
218 
219     //------------------------------------------------------  testing section
220         log1("      TESTING BEGINS");
221 
222         for (int i = 0; ; i++) {
223             pipe.println("newcheck");
224             line = pipe.readln();
225 
226             if (line.equals("checkend")) {
227                 log2("     : returned string is 'checkend'");
228                 break ;
229             } else if (!line.equals("checkready")) {
230                 log3("ERROR: returned string is not 'checkready'");
231                 testExitCode = FAILED;
232                 break ;
233             }
234 
235             log1("new check: #" + i);
236 
237             //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ variable part
238 
239             int expresult = returnCode0;
240 
241             eventRManager = vm.eventRequestManager();
242             eventQueue    = vm.eventQueue();
243 
244             List            allThreads   = null;
245             ListIterator    listIterator = null;
246             List            classes      = null;
247 
248             String threadName = "Thread2";
249 
250             String breakpointMethod1 = "run";
251             String bpLine1          = "breakpointLineNumber1";
252 
253             BreakpointRequest breakpRequest1 = null;
254 
255 
256             label0: {
257 
258                 log2("getting ThreadReference object");
259                 try {
260                     allThreads  = vm.allThreads();
261                     classes     = vm.classesByName(testedClassName);
262                     testedclass = (ReferenceType) classes.get(0);
263                 } catch ( Exception e) {
264                     log3("ERROR: Exception at very beginning !? : " + e);
265                     expresult = returnCode1;
266                     break label0;
267                 }
268 
269                 listIterator = allThreads.listIterator();
270                 for (;;) {
271                     try {
272                         thread2 = (ThreadReference) listIterator.next();
273                         if (thread2.name().equals(threadName))
274                             break ;
275                     } catch ( NoSuchElementException e ) {
276                         log3("ERROR: NoSuchElementException for listIterator.next()");
277                         log3("ERROR: NO THREAD2 ?????????!!!!!!!");
278                         expresult = returnCode1;
279                         break label0;
280                     }
281                 }
282 
283                 log2("setting up breakpoint");
284 
285                 breakpRequest1 = settingBreakpoint(breakpointMethod1, bpLine1, "one");
286                 if (breakpRequest1 == null) {
287                     expresult = returnCode1;
288                     break label0;
289                 }
290             }
291 
292             label1: {
293 
294                 if (expresult != returnCode0)
295                        break label1;
296 
297                 log2("     enabling breakpRequest1");
298                 breakpRequest1.enable();
299 
300                 log2("       forcing the main thread to leave synchronized block");
301                 pipe.println("continue");
302                 line = pipe.readln();
303                 if (!line.equals("docontinue")) {
304                     log3("ERROR: returned string is not 'docontinue'");
305                     expresult = returnCode4;
306                     break label1;
307                 }
308 
309                 log2("      getting a breakpoint event");
310                 expresult = breakpoint();
311                 if (expresult != returnCode0)
312                     break label1;
313 
314 
315                 Value returnvdValue1 = null;
316                 Value returnvdValue2 = null;
317                 Value returnvdValue3 = null;
318                 List  invokeMethods  = null;
319                 Method invokeMethod  = null;
320                 List<Value> argumentList    = null;
321 
322 
323                 invokeMethods  =  testedclass.methodsByName("vdValue1");
324                 invokeMethod = (Method) invokeMethods.get(0);
325 
326                 argumentList = Collections.<Value>emptyList();
327 
328                 try {
329                     log2("      1st invoking hashcode001a.vdValue1();  no Exception expected");
330                     returnvdValue1 = thread2.invokeMethod(thread2,
331                                       invokeMethod, argumentList, 0);
332                     log2("      2nd invoking hashcode001a.vdValue1();  no Exception expected");
333                     returnvdValue2 = thread2.invokeMethod(thread2,
334                                      invokeMethod, argumentList, 0);
335                 } catch ( Exception e ) {
336                      log3("ERROR: Exception: " + e);
337                      expresult = returnCode1;
338                      break label1;
339                 }
340 
341                         //  invoking hashcode001a.vdValue2()
342 
343                 invokeMethods = testedclass.methodsByName("vdValue2");
344                 invokeMethod  = (Method) invokeMethods.get(0);
345 
346                 try {
347                     log2("      invoking hashcode001a.vdValue2();  no Exception expected");
348                     returnvdValue3 = thread2.invokeMethod(thread2,
349                                      invokeMethod, argumentList, 0);
350                 } catch ( Exception e ) {
351                      log3("ERROR: Exception: " + e);
352                      expresult = returnCode1;
353                      break label1;
354                 }
355 
356 
357                 VoidValue vdValue1 = null;
358                 VoidValue vdValue2 = null;
359                 VoidValue vdValue3 = null;
360 
361                 try {
362                     log2("     checking up cast: vdValue1 = (VoidValue) returnvdValue1; no Exception expected");
363                     vdValue1 = (VoidValue) returnvdValue1;
364                 } catch ( ClassCastException e ) {
365                     log3("ERROR : ClassCastException");
366                     expresult = returnCode1;
367                     break label1;
368                 }
369 
370                 try {
371                     log2("     checking up cast: vdValue2 = (VoidValue) returnvdValue2; no Exception expected");
372                     vdValue2 = (VoidValue) returnvdValue2;
373                 } catch ( ClassCastException e ) {
374                     log3("ERROR : ClassCastException");
375                     expresult = returnCode1;
376                     break label1;
377                 }
378 
379                 try {
380                     log2("     checking up cast: vdValue3 = (VoidValue) returnvdValue3; no Exception expected");
381                     vdValue3 = (VoidValue) returnvdValue3;
382                 } catch ( ClassCastException e ) {
383                     log3("ERROR : ClassCastException");
384                     expresult = returnCode1;
385                     break label1;
386                 }
387 
388                 log2("     checking up: dValue1.hashCode() == vdValue2.hashCode()");
389                 if (vdValue1.hashCode() != vdValue2.hashCode() ) {
390                     log3("ERROR: vdValue1.hashCode() != vdValue2.hashCode()");
391                     expresult = returnCode1;
392                 }
393                 log2("     checking up: dValue1.hashCode() == vdValue3.hashCode()");
394                 if (vdValue1.hashCode() != vdValue3.hashCode() ) {
395                     log3("ERROR: vdValue1.hashCode() != vdValue3.hashCode()");
396                     expresult = returnCode1;
397                 }
398             }
399             log2("      resuming the vm");
400             vm.resume();
401             //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
402             log2("     the end of testing");
403             if (expresult != returnCode0)
404                 testExitCode = FAILED;
405         }
406         log1("      TESTING ENDS");
407 
408     //--------------------------------------------------   test summary section
409     //-------------------------------------------------    standard end section
410 
411         pipe.println("quit");
412         log2("waiting for the debuggee to finish ...");
413         debuggee.waitFor();
414 
415         int status = debuggee.getStatus();
416         if (status != PASSED + PASS_BASE) {
417             log3("debuggee returned UNEXPECTED exit status: " +
418                    status + " != PASS_BASE");
419             testExitCode = FAILED;
420         } else {
421             log2("debuggee returned expected exit status: " +
422                    status + " == PASS_BASE");
423         }
424 
425         if (testExitCode != PASSED) {
426             System.out.println("TEST FAILED");
427         }
428         return testExitCode;
429     }
430 
431 
432 
433    /*
434     * private BreakpointRequest settingBreakpoint(String, String, String)
435     *
436     * It sets up a breakpoint within a given method at given line number
437     * for the thread2 only.
438     * Third parameter is required for any case in future debugging, as if.
439     *
440     * Return codes:
441     *  = BreakpointRequest object  in case of success
442     *  = null   in case of an Exception thrown within the method
443     */
444 
settingBreakpoint( String methodName, String bpLine, String property)445     private BreakpointRequest settingBreakpoint ( String methodName,
446                                                   String bpLine,
447                                                   String property) {
448 
449         log2("setting up a breakpoint: method: '" + methodName + "' line: " + bpLine );
450 
451         List              alllineLocations = null;
452         Location          lineLocation     = null;
453         BreakpointRequest breakpRequest    = null;
454 
455         try {
456             Method  method  = (Method) testedclass.methodsByName(methodName).get(0);
457 
458             alllineLocations = method.allLineLocations();
459 
460             int n =
461                 ( (IntegerValue) testedclass.getValue(testedclass.fieldByName(bpLine) ) ).value();
462             if (n > alllineLocations.size()) {
463                 log3("ERROR:  TEST_ERROR_IN_settingBreakpoint(): number is out of bound of method's lines");
464             } else {
465                 lineLocation = (Location) alllineLocations.get(n);
466                 try {
467                     breakpRequest = eventRManager.createBreakpointRequest(lineLocation);
468                     breakpRequest.putProperty("number", property);
469                     breakpRequest.addThreadFilter(thread2);
470                     breakpRequest.setSuspendPolicy( EventRequest.SUSPEND_EVENT_THREAD);
471                 } catch ( Exception e1 ) {
472                     log3("ERROR: inner Exception within settingBreakpoint() : " + e1);
473                     breakpRequest    = null;
474                 }
475             }
476         } catch ( Exception e2 ) {
477             log3("ERROR: ATTENTION:  outer Exception within settingBreakpoint() : " + e2);
478             breakpRequest    = null;
479         }
480 
481         if (breakpRequest == null)
482             log2("      A BREAKPOINT HAS NOT BEEN SET UP");
483         else
484             log2("      a breakpoint has been set up");
485 
486         return breakpRequest;
487     }
488 
489 
490     /*
491      * private int breakpoint ()
492      *
493      * It removes events from EventQueue until gets first BreakpointEvent.
494      * To get next EventSet value, it uses the method
495      *    EventQueue.remove(int timeout)
496      * The timeout argument passed to the method, is "waitTime*60000".
497      * Note: the value of waitTime is set up with
498      *       the method ArgumentHandler.getWaitTime() at the beginning of the test.
499      *
500      * Return codes:
501      *  = returnCode0 - success;
502      *  = returnCode2 - Exception when "eventSet = eventQueue.remove()" is executed
503      *  = returnCode3 - default case when loop of processing an event, that is,
504      *                  an unspecified event was taken from the EventQueue
505      */
506 
breakpoint()507     private int breakpoint () {
508 
509         int returnCode = returnCode0;
510 
511         log2("       waiting for BreakpointEvent");
512 
513         labelBP:
514             for (;;) {
515 
516                 log2("       new:  eventSet = eventQueue.remove();");
517                 try {
518                     eventSet = eventQueue.remove(waitTime*60000);
519                     if (eventSet == null) {
520                         log3("ERROR:  timeout for waiting for a BreakpintEvent");
521                         returnCode = returnCode3;
522                         break labelBP;
523                     }
524                 } catch ( Exception e ) {
525                     log3("ERROR: Exception for  eventSet = eventQueue.remove(); : " + e);
526                     returnCode = 1;
527                     break labelBP;
528                 }
529 
530                 if (eventSet != null) {
531 
532                     log2("     :  eventSet != null;  size == " + eventSet.size());
533 
534                     EventIterator eIter = eventSet.eventIterator();
535                     Event         ev    = null;
536 
537                     for (; eIter.hasNext(); ) {
538 
539                         if (returnCode != returnCode0)
540                             break;
541 
542                         ev = eIter.nextEvent();
543 
544                     ll: for (int ifor =0;  ; ifor++) {
545 
546                         try {
547                           switch (ifor) {
548 
549                           case 0:  AccessWatchpointEvent awe = (AccessWatchpointEvent) ev;
550                                    log2("      AccessWatchpointEvent removed");
551                                    break ll;
552                           case 1:  BreakpointEvent be = (BreakpointEvent) ev;
553                                    log2("      BreakpointEvent removed");
554                                    break labelBP;
555                           case 2:  ClassPrepareEvent cpe = (ClassPrepareEvent) ev;
556                                    log2("      ClassPreparEvent removed");
557                                    break ll;
558                           case 3:  ClassUnloadEvent cue = (ClassUnloadEvent) ev;
559                                    log2("      ClassUnloadEvent removed");
560                                    break ll;
561                           case 4:  ExceptionEvent ee = (ExceptionEvent) ev;
562                                    log2("      ExceptionEvent removed");
563                                    break ll;
564                           case 5:  MethodEntryEvent mene = (MethodEntryEvent) ev;
565                                    log2("      MethodEntryEvent removed");
566                                    break ll;
567                           case 6:  MethodExitEvent mexe = (MethodExitEvent) ev;
568                                    log2("      MethodExiEvent removed");
569                                    break ll;
570                           case 7:  ModificationWatchpointEvent mwe = (ModificationWatchpointEvent) ev;
571                                    log2("      ModificationWatchpointEvent removed");
572                                    break ll;
573                           case 8:  StepEvent se = (StepEvent) ev;
574                                    log2("      StepEvent removed");
575                                    break ll;
576                           case 9:  ThreadDeathEvent tde = (ThreadDeathEvent) ev;
577                                    log2("      ThreadDeathEvent removed");
578                                    break ll;
579                           case 10: ThreadStartEvent tse = (ThreadStartEvent) ev;
580                                    log2("      ThreadStartEvent removed");
581                                    break ll;
582                           case 11: VMDeathEvent vmde = (VMDeathEvent) ev;
583                                    log2("      VMDeathEvent removed");
584                                    break ll;
585                           case 12: VMStartEvent vmse = (VMStartEvent) ev;
586                                    log2("      VMStartEvent removed");
587                                    break ll;
588                           case 13: WatchpointEvent we = (WatchpointEvent) ev;
589                                    log2("      WatchpointEvent removed");
590                                    break ll;
591 
592                           default: log3("ERROR:  default case for casting event");
593                                    returnCode = returnCode3;
594                                    break ll;
595                           } // switch
596                         } catch ( ClassCastException e ) {
597                         }   // try
598                     }       // ll: for (int ifor =0;  ; ifor++)
599                 }           // for (; ev.hasNext(); )
600             }
601         }
602         if (returnCode == returnCode0)
603             log2("     :  eventSet == null:  EventQueue is empty");
604 
605         return returnCode;
606     }
607 
608 }
609