1 /* 2 * Copyright (c) 2001, 2019, 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.jdi.ThreadGroupReference.suspend; 25 26 import nsk.share.*; 27 import nsk.share.jpda.*; 28 import nsk.share.jdi.*; 29 30 import com.sun.jdi.*; 31 import java.util.*; 32 import java.io.*; 33 34 /** 35 * The test for the implementation of an object of the type <BR> 36 * ThreadGroupReference. <BR> 37 * <BR> 38 * The test checks up that results of the method <BR> 39 * <code>com.sun.jdi.ThreadGroupReference.suspend()</code> <BR> 40 * complies with its spec. <BR> 41 * <BR> 42 * The case for testing includes four ThreadGroup objects defined <BR> 43 * in a debuggee and their mirrors in a debugger. <BR> 44 * Parenthood relationships between the objects are as follows: <BR> 45 * threadGroups 2&3 are subgroups of threadGroup1 <BR> 46 * threadGroup4 is a subgroup of threadGroup3 <BR> 47 * The objects are created together with three threads, Thread 2,3,4, <BR> 48 * belonging to the corresponding subgroups. <BR> 49 * The test works as follows. After being started up, <BR> <BR> 50 * the debuggee creates a 'lockingObject' for synchronizing threads, <BR> 51 * enters a synchronized block in which it creates the threads, <BR> 52 * informs the debugger of the threads creation, <BR> 53 * and is waiting for reply. <BR> 54 * Since the threads use the same locking object in their 'run' methods <BR> 55 * they are locked up until main thread leaves the synchronized block. <BR> 56 * Upon the receiption a message from the debuggee, <BR> 57 * the debugger gets mirrors of threadGroups and checks up that: <BR> 58 * - group4.suspend(); suspends only Thread4; <BR> 59 * - group3.suspend(); suspends Thread3 and Thread4; <BR> 60 * - group2.suspend(); suspends only Thread2; <BR> 61 * - group1.suspend(); suspends Thread2, Thread3 and Thread4. <BR> 62 */ 63 64 public class suspend001 { 65 66 //----------------------------------------------------- templete section 67 static final int PASSED = 0; 68 static final int FAILED = 2; 69 static final int PASS_BASE = 95; 70 71 //----------------------------------------------------- templete parameters 72 static final String 73 sHeader1 = "\n==> nsk/jdi/ThreadGroupReference/suspend/suspend001 ", 74 sHeader2 = "--> debugger: ", 75 sHeader3 = "##> debugger: "; 76 77 //----------------------------------------------------- main method 78 main(String argv[])79 public static void main (String argv[]) { 80 int result = run(argv, System.out); 81 System.exit(result + PASS_BASE); 82 } 83 run(String argv[], PrintStream out)84 public static int run (String argv[], PrintStream out) { 85 return new suspend001().runThis(argv, out); 86 } 87 88 //-------------------------------------------------- log procedures 89 90 private static Log logHandler; 91 log1(String message)92 private static void log1(String message) { 93 logHandler.display(sHeader1 + message); 94 } log2(String message)95 private static void log2(String message) { 96 logHandler.display(sHeader2 + message); 97 } log3(String message)98 private static void log3(String message) { 99 logHandler.complain(sHeader3 + message); 100 } 101 102 // ************************************************ test parameters 103 104 private String debuggeeName = 105 "nsk.jdi.ThreadGroupReference.suspend.suspend001a"; 106 107 private String testedClassName = 108 "nsk.jdi.ThreadGroupReference.suspend.Threadsuspend001a"; 109 110 //String mName = "nsk.jdi.ThreadGroupReference.suspend"; 111 112 //====================================================== test program 113 //------------------------------------------------------ common section 114 115 static ArgumentHandler argsHandler; 116 117 static int waitTime; 118 119 static VirtualMachine vm = null; 120 121 ReferenceType testedclass = null; 122 ThreadReference thread2 = null; 123 ThreadReference mainThread = null; 124 125 static int testExitCode = PASSED; 126 127 static final int returnCode0 = 0; 128 static final int returnCode1 = 1; 129 static final int returnCode2 = 2; 130 static final int returnCode3 = 3; 131 static final int returnCode4 = 4; 132 133 //------------------------------------------------------ methods 134 runThis(String argv[], PrintStream out)135 private int runThis (String argv[], PrintStream out) { 136 137 Debugee debuggee; 138 139 argsHandler = new ArgumentHandler(argv); 140 logHandler = new Log(out, argsHandler); 141 Binder binder = new Binder(argsHandler, logHandler); 142 143 if (argsHandler.verbose()) { 144 debuggee = binder.bindToDebugee(debuggeeName + " -vbs"); 145 } else { 146 debuggee = binder.bindToDebugee(debuggeeName); 147 } 148 149 waitTime = argsHandler.getWaitTime(); 150 151 152 IOPipe pipe = new IOPipe(debuggee); 153 154 debuggee.redirectStderr(out); 155 log2(debuggeeName + " debuggee launched"); 156 debuggee.resume(); 157 158 String line = pipe.readln(); 159 if ((line == null) || !line.equals("ready")) { 160 log3("signal received is not 'ready' but: " + line); 161 return FAILED; 162 } else { 163 log2("'ready' recieved"); 164 } 165 166 vm = debuggee.VM(); 167 168 //------------------------------------------------------ testing section 169 log1(" TESTING BEGINS"); 170 171 for (int i = 0; ; i++) { 172 173 pipe.println("newcheck"); 174 line = pipe.readln(); 175 176 if (line.equals("checkend")) { 177 log2(" : returned string is 'checkend'"); 178 break ; 179 } else if (!line.equals("checkready")) { 180 log3("ERROR: returned string is not 'checkready'"); 181 testExitCode = FAILED; 182 break ; 183 } 184 185 log1("new checkready: #" + i); 186 187 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ variable part 188 189 int expresult = returnCode0; 190 191 List classes = null; 192 193 ThreadGroupReference groups[] = { null, null, null, null }; 194 195 String groupNames [] = { "threadGroup1Obj", 196 "threadGroup2Obj", 197 "threadGroup3Obj", 198 "threadGroup4Obj" }; 199 200 List threads; 201 ListIterator iterator; 202 int flag; 203 String threadName; 204 ThreadReference thread; 205 206 String threadNames [] = { "Thread2", "Thread3", "Thread4" }; 207 208 ReferenceType mainthreadClass = null; 209 ReferenceType thread2Class = null; 210 211 label0: { 212 213 log2("getting ThreadReference objects"); 214 try { 215 classes = vm.classesByName(testedClassName); 216 thread2Class = (ReferenceType) classes.get(0); 217 classes = vm.classesByName(debuggeeName); 218 mainthreadClass = (ReferenceType) classes.get(0); 219 } catch ( Exception e) { 220 log3("ERROR: Exception at very beginning !? : " + e); 221 expresult = returnCode1; 222 break label0; 223 } 224 225 log2(" getting a List of all threadGroups"); 226 for (int i1 = 0; i1 < 4; i1++) { 227 groups[i1] = (ThreadGroupReference) 228 mainthreadClass.getValue(mainthreadClass.fieldByName(groupNames[i1])); 229 } 230 231 log2(" getting a List of all running threads"); 232 threads = vm.allThreads(); 233 234 235 log2("......checking up threads suspended with groups[3].suspend()"); 236 log2(" expected: 'Thread4'"); 237 groups[3].suspend(); 238 239 iterator = threads.listIterator(); 240 flag = 0; 241 for ( int i2 = 0; iterator.hasNext(); i2++ ) { 242 thread = (ThreadReference) iterator.next(); 243 if (!thread.isSuspended()) 244 continue; 245 threadName = thread.name(); 246 if (threadName.equals(threadNames[0])) 247 flag |= 1; 248 else if (threadName.equals(threadNames[1])) 249 flag |= 2; 250 else if (threadName.equals(threadNames[2])) 251 flag |= 4; 252 else flag |= 8; 253 } 254 if (flag != 4) { 255 expresult = returnCode1; 256 if (flag == 0) 257 log3("ERROR: no threads suspunded"); 258 if ((flag & 4) == 0) 259 log3("ERROR: 'Thread4' is not among suspended threads"); 260 if ((flag & 2) != 0) 261 log3("ERROR: 'Thread3' is also suspended"); 262 if ((flag & 1) != 0) 263 log3("ERROR: 'Thread2' is also suspended"); 264 if (flag >= 8) 265 log3("ERROR: some extra thread(s) is also suspended"); 266 } 267 vm.resume(); 268 269 270 log2("......checking up threads suspended with groups[2].suspend()"); 271 log2(" expected: 'Thread3' and 'Thread4'"); 272 groups[2].suspend(); 273 274 iterator = threads.listIterator(); 275 flag = 0; 276 for ( int i2 = 0; iterator.hasNext(); i2++ ) { 277 thread = (ThreadReference) iterator.next(); 278 if (!thread.isSuspended()) 279 continue; 280 threadName = thread.name(); 281 if (threadName.equals(threadNames[0])) 282 flag |= 1; 283 else if (threadName.equals(threadNames[1])) 284 flag |= 2; 285 else if (threadName.equals(threadNames[2])) 286 flag |= 4; 287 else flag |= 8; 288 } 289 if (flag != 6) { 290 expresult = returnCode1; 291 if (flag == 0) 292 log3("ERROR: no threads suspunded"); 293 if ((flag & 4) == 0) 294 log3("ERROR: 'Thread4' is not among suspended threads"); 295 if ((flag & 2) == 0) 296 log3("ERROR: 'Thread3' is not among suspended threads"); 297 if ((flag & 1) != 0) 298 log3("ERROR: 'Thread2' is also suspended"); 299 if (flag >= 8) 300 log3("ERROR: some extra thread(s) is also suspended"); 301 } 302 vm.resume(); 303 304 305 log2("......checking up threads suspended with groups[1].suspend()"); 306 log2(" expected: 'Thread2'"); 307 groups[1].suspend(); 308 309 iterator = threads.listIterator(); 310 flag = 0; 311 for ( int i2 = 0; iterator.hasNext(); i2++ ) { 312 thread = (ThreadReference) iterator.next(); 313 if (!thread.isSuspended()) 314 continue; 315 threadName = thread.name(); 316 if (threadName.equals(threadNames[0])) 317 flag |= 1; 318 else if (threadName.equals(threadNames[1])) 319 flag |= 2; 320 else if (threadName.equals(threadNames[2])) 321 flag |= 4; 322 else flag |= 8; 323 } 324 if (flag != 1) { 325 expresult = returnCode1; 326 if (flag == 0) 327 log3("ERROR: no threads suspunded"); 328 if ((flag & 4) != 0) 329 log3("ERROR: 'Thread4' is among suspended threads"); 330 if ((flag & 2) != 0) 331 log3("ERROR: 'Thread3' is among suspended threads"); 332 if ((flag & 1) == 0) 333 log3("ERROR: 'Thread2' is not among suspended threads"); 334 if (flag >= 8) 335 log3("ERROR: some extra thread(s) is also suspended"); 336 } 337 vm.resume(); 338 339 log2("......checking up threads suspended with groups[0].suspend()"); 340 log2(" expected: 'Thread2', 'Thread3', and 'Thread4'"); 341 groups[0].suspend(); 342 343 iterator = threads.listIterator(); 344 flag = 0; 345 for ( int i2 = 0; iterator.hasNext(); i2++ ) { 346 thread = (ThreadReference) iterator.next(); 347 if (!thread.isSuspended()) 348 continue; 349 threadName = thread.name(); 350 if (threadName.equals(threadNames[0])) 351 flag |= 1; 352 else if (threadName.equals(threadNames[1])) 353 flag |= 2; 354 else if (threadName.equals(threadNames[2])) 355 flag |= 4; 356 else flag |= 8; 357 } 358 if (flag != 7) { 359 expresult = returnCode1; 360 if (flag == 0) 361 log3("ERROR: no threads suspunded"); 362 if ((flag & 4) == 0) 363 log3("ERROR: 'Thread4' is not among suspended threads"); 364 if ((flag & 2) == 0) 365 log3("ERROR: 'Thread3' is not among suspended threads"); 366 if ((flag & 1) == 0) 367 log3("ERROR: 'Thread2' is not among suspended threads"); 368 if (flag >= 8) 369 log3("ERROR: some extra thread(s) is also suspended"); 370 } 371 vm.resume(); 372 373 374 375 376 log2("......instructing mainThread to leave synchronized block"); 377 pipe.println("continue"); 378 line = pipe.readln(); 379 if (!line.equals("docontinue")) { 380 log3("ERROR: returned string is not 'docontinue'"); 381 expresult = returnCode4; 382 } 383 } 384 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 385 log2(" the end of testing"); 386 if (expresult != returnCode0) 387 testExitCode = FAILED; 388 } 389 log1(" TESTING ENDS"); 390 391 //-------------------------------------------------- test summary section 392 //------------------------------------------------- standard end section 393 394 pipe.println("quit"); 395 log2("waiting for the debuggee to finish ..."); 396 debuggee.waitFor(); 397 398 int status = debuggee.getStatus(); 399 if (status != PASSED + PASS_BASE) { 400 log3("debuggee returned UNEXPECTED exit status: " + 401 status + " != PASS_BASE"); 402 testExitCode = FAILED; 403 } else { 404 log2("debuggee returned expected exit status: " + 405 status + " == PASS_BASE"); 406 } 407 408 if (testExitCode != PASSED) { 409 logHandler.complain("TEST FAILED"); 410 } 411 return testExitCode; 412 } 413 } 414