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