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 /** 20 * @author Anatoly F. Bondarenko 21 */ 22 23 /** 24 * Created on 19.06.2006 25 */ 26 package org.apache.harmony.jpda.tests.jdwp.ThreadReference; 27 28 import org.apache.harmony.jpda.tests.framework.jdwp.exceptions.*; 29 import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket; 30 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands; 31 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; 32 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket; 33 import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase; 34 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; 35 36 /** 37 * JDWP Unit test for ThreadReference.ThreadGroup command. 38 */ 39 public class ThreadGroup002Test extends JDWPSyncTestCase { 40 41 static final int testStatusPassed = 0; 42 static final int testStatusFailed = -1; 43 static final String debuggeeSignature = 44 "Lorg/apache/harmony/jpda/tests/jdwp/ThreadReference/ThreadGroup002Debuggee;"; 45 getDebuggeeClassName()46 protected String getDebuggeeClassName() { 47 return "org.apache.harmony.jpda.tests.jdwp.ThreadReference.ThreadGroup002Debuggee"; 48 } 49 50 /** 51 * This testcase exercises ThreadReference.ThreadGroup command. 52 * <BR>At first the test starts ThreadGroup002Debuggee which creates some thread 53 * groups and starts some tested threads which belong to different created thread groups. 54 * <BR>After the tested threads start, at first the test wait for the some first 55 * tested threads to finish. 56 * <BR> Then the test for every tested thread does: 57 * <BR> - performs ThreadReference.Status command; 58 * <BR> - performs the ThreadReference.ThreadGroup command; 59 * <BR> - performs the ThreadGroupReference.name command; 60 * <BR>It is expected that 61 * <BR> - all threads with status ZOMBIE are only finished tested threads; 62 * <BR> - all threads without status ZOMBIE are only NOT finished tested threads; 63 * <BR> - if status of thread is ZOMBIE then returned groupID must be null; 64 * <BR> - if status of thread is not ZOMBIE then returned groupID must not be null; 65 * <BR> - thread group name should be expected name for thread which is not ZOMBIE; 66 */ testThreadGroup002()67 public void testThreadGroup002() { 68 logWriter.println("==> testThreadGroup002: START..."); 69 String debuggeeMessage = synchronizer.receiveMessage(); 70 int testedThreadsNumber = 0; 71 try { 72 testedThreadsNumber = Integer.valueOf(debuggeeMessage).intValue(); 73 } catch (NumberFormatException exception) { 74 logWriter.println 75 ("## FAILURE: Exception while getting number of started threads from debuggee = " + exception); 76 synchronizer.sendMessage("FINISH"); 77 printErrorAndFail("\n## Can NOT get number of started threads from debuggee! "); 78 } 79 testedThreadsNumber++; // to add debuggee main thread 80 logWriter.println("==> Number of threads in debuggee to test = " + testedThreadsNumber); 81 String[] testedThreadsNames = new String[testedThreadsNumber]; 82 String[] testedThreadGroupsNames = new String[testedThreadsNumber]; 83 long[] testedThreadsIDs = new long[testedThreadsNumber]; 84 String debuggeeMainThreadName = synchronizer.receiveMessage(); 85 String debuggeeMainThreadGroupName = synchronizer.receiveMessage(); 86 for (int i = 0; i < testedThreadsNumber; i++) { 87 if ( i < (testedThreadsNumber-1) ) { 88 testedThreadsNames[i] = ThreadGroup002Debuggee.THREAD_NAME_PATTERN + i; 89 testedThreadGroupsNames[i] = ThreadGroup002Debuggee.THREAD_GROUP_NAME_PATTERN + (i%2); 90 } else { 91 testedThreadsNames[i] = debuggeeMainThreadName; 92 testedThreadGroupsNames[i] = debuggeeMainThreadGroupName; 93 } 94 testedThreadsIDs[i] = 0; 95 } 96 97 // getting ID of the tested thread 98 ReplyPacket allThreadIDReply = null; 99 try { 100 allThreadIDReply = debuggeeWrapper.vmMirror.getAllThreadID(); 101 } catch (ReplyErrorCodeException exception) { 102 logWriter.println 103 ("## FAILURE: Exception in vmMirror.getAllThreadID() = " + exception); 104 synchronizer.sendMessage("FINISH"); 105 printErrorAndFail("\n## Can NOT get all ThreadID in debuggee! "); 106 } 107 int threads = allThreadIDReply.getNextValueAsInt(); 108 logWriter.println("==> Number of all threads in debuggee = " + threads); 109 for (int i = 0; i < threads; i++) { 110 long threadID = allThreadIDReply.getNextValueAsThreadID(); 111 String threadName = null; 112 try { 113 threadName = debuggeeWrapper.vmMirror.getThreadName(threadID); 114 } catch (ReplyErrorCodeException exception) { 115 logWriter.println 116 ("==> WARNING: Can NOT get thread name for threadID = " + threadID); 117 continue; 118 } 119 int k = 0; 120 for (; k < testedThreadsNumber; k++) { 121 if ( threadName.equals(testedThreadsNames[k]) ) { 122 testedThreadsIDs[k] = threadID; 123 break; 124 } 125 } 126 } 127 128 boolean testedThreadNotFound = false; 129 for (int i = 0; i < testedThreadsNumber; i++) { 130 if ( testedThreadsIDs[i] == 0 ) { 131 logWriter.println("## FAILURE: Tested thread is not found out among debuggee threads!"); 132 logWriter.println("## Thread name = " + testedThreadsNames[i]); 133 testedThreadNotFound = true; 134 } 135 } 136 if ( testedThreadNotFound ) { 137 synchronizer.sendMessage("FINISH"); 138 printErrorAndFail("\n## Some of tested threads are not found!"); 139 } 140 141 logWriter.println("==> Send signal to debuggee to continue and to finish some first threads..."); 142 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 143 144 logWriter.println("==> Wait signal from the debuggee that some first threads finished..."); 145 String messageFromDebuggee = synchronizer.receiveMessageWithoutException("testThreadGroup002"); 146 if ( ! JPDADebuggeeSynchronizer.SGNL_READY.equals(messageFromDebuggee) ) { 147 logWriter.println("## FAILURE: Could NOT receive expected signal from debuggee!"); 148 printErrorAndFail("\n## Could NOT receive expected signal from debuggee! "); 149 } 150 int finishedTestedThreadsNumber = testedThreadsNumber/2; 151 logWriter.println 152 ("==> Number of debuggee's finished threads = " + finishedTestedThreadsNumber); 153 154 CommandPacket packet = null; 155 ReplyPacket reply = null; 156 String errorMessage = ""; 157 158 boolean statusCommandFailed = false; 159 boolean threadStatusFailed = false; 160 boolean groupIDFailed = false; 161 boolean threadGroupCommandFailed = false; 162 boolean groupNameFailed = false; 163 164 logWriter.println 165 ("\n==> Check that ThreadReference.ThreadGroup command returns expected thread group for each tsted thread..."); 166 167 for (int threadCount = 0; threadCount < testedThreadsNumber; threadCount++) { 168 logWriter.println("\n==> Check for Thread: threadID = " + testedThreadsIDs[threadCount] 169 + "; threadName = " + testedThreadsNames[threadCount]); 170 logWriter.println("==> Send ThreadReference.Status command..."); 171 packet = new CommandPacket( 172 JDWPCommands.ThreadReferenceCommandSet.CommandSetID, 173 JDWPCommands.ThreadReferenceCommandSet.StatusCommand); 174 packet.setNextValueAsReferenceTypeID(testedThreadsIDs[threadCount]); 175 reply = debuggeeWrapper.vmMirror.performCommand(packet); 176 if ( ! checkReplyPacketWithoutFail(reply, "ThreadReference.Status command") ) { 177 statusCommandFailed = true; 178 continue; 179 } 180 181 int threadStatus = reply.getNextValueAsInt(); 182 //int suspendStatus = 183 reply.getNextValueAsInt(); 184 185 logWriter.println("==> thread status of checked thread = " + threadStatus + "(" 186 + JDWPConstants.ThreadStatus.getName(threadStatus) + ")"); 187 188 logWriter.println("==> Send ThreadReference.ThreadGroup command..."); 189 packet = new CommandPacket( 190 JDWPCommands.ThreadReferenceCommandSet.CommandSetID, 191 JDWPCommands.ThreadReferenceCommandSet.ThreadGroupCommand); 192 packet.setNextValueAsThreadID(testedThreadsIDs[threadCount]); 193 194 reply = debuggeeWrapper.vmMirror.performCommand(packet); 195 if ( ! checkReplyPacketWithoutFail(reply, "ThreadReference.ThreadGroup command") ) { 196 threadGroupCommandFailed = true; 197 continue; 198 } 199 200 long threadGroupID = reply.getNextValueAsThreadGroupID(); 201 logWriter.println("==> thread groupID for checked thread = " + threadGroupID); 202 if (threadStatus == JDWPConstants.ThreadStatus.ZOMBIE) { 203 if ( threadCount >= finishedTestedThreadsNumber ) { 204 logWriter.println("## FAILURE: Unexpected status for checked thread!"); 205 logWriter.println("## Thread witn number = " + threadCount + 206 " should NOT be ZOMBIE!"); 207 threadStatusFailed = true; 208 continue; 209 } 210 // according to JVMTI spec groupID is NULL if the thread has died 211 if ( threadGroupID != 0 ) { 212 logWriter.println("## FAILURE: Unexpected thread groupID for checked thread with status = ZOMBIE!"); 213 logWriter.println("## Expected thread groupID = 0"); 214 groupIDFailed = true; 215 } 216 continue; 217 } else { 218 if ( threadCount < finishedTestedThreadsNumber ) { 219 logWriter.println("## FAILURE: Unexpected status for checked thread!"); 220 logWriter.println("## Thread witn number = " + threadCount + 221 " should be ZOMBIE!"); 222 threadStatusFailed = true; 223 continue; 224 } 225 if ( threadGroupID == 0 ) { 226 logWriter.println("## FAILURE: Unexpected thread groupID for checked thread with status != ZOMBIE!"); 227 logWriter.println("## Expected thread groupID != 0"); 228 groupIDFailed = true; 229 continue; 230 } 231 } 232 233 logWriter.println("==> Getting thread group name by ThreadGroupReference.Name command..."); 234 packet = new CommandPacket( 235 JDWPCommands.ThreadGroupReferenceCommandSet.CommandSetID, 236 JDWPCommands.ThreadGroupReferenceCommandSet.NameCommand); 237 packet.setNextValueAsThreadID(threadGroupID); 238 239 reply = debuggeeWrapper.vmMirror.performCommand(packet); 240 if ( ! checkReplyPacketWithoutFail(reply, "ThreadReference.ThreadGroup command") ) { 241 threadGroupCommandFailed = true; 242 continue; 243 } 244 245 String threadGroupName = reply.getNextValueAsString(); 246 logWriter.println("==> thread group name for checked thread = '" + threadGroupName + "'"); 247 248 if ( ! testedThreadGroupsNames[threadCount].equals(threadGroupName) ) { 249 logWriter.println("## FAILURE: Unexpected thread group name for checked thread!"); 250 logWriter.println("## Expected thread group name = '" + 251 testedThreadGroupsNames[threadCount] + "'"); 252 groupNameFailed = true; 253 } 254 } 255 256 if ( statusCommandFailed ) { 257 errorMessage = errorMessage + 258 "## Error found out while ThreadReference.Status command performing!\n"; 259 } 260 261 if ( threadStatusFailed ) { 262 errorMessage = errorMessage + 263 "## Unexpected thread status found out for some tested threads!\n"; 264 } 265 266 if ( groupIDFailed ) { 267 errorMessage = errorMessage + 268 "## Unexpected thread groupID found out for some tested threads!\n"; 269 } 270 271 if ( threadGroupCommandFailed ) { 272 errorMessage = errorMessage + 273 "## Error found out while ThreadReference.ThreadGroup command performing!\n"; 274 } 275 276 if ( groupNameFailed ) { 277 errorMessage = errorMessage + 278 "## Unexpected thread group name found out for some tested threads!\n"; 279 } 280 281 logWriter.println("==> Send signal to debuggee to finish..."); 282 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 283 284 if ( ! errorMessage.equals("") ) { 285 printErrorAndFail("\ntestThreadGroup002 FAILED:\n" + errorMessage); 286 } 287 288 logWriter.println("\n==> testThreadGroup002 - OK!"); 289 } 290 } 291