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 package org.apache.harmony.jpda.tests.jdwp.ThreadReference; 20 21 import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket; 22 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands; 23 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; 24 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket; 25 import org.apache.harmony.jpda.tests.framework.jdwp.TaggedObject; 26 import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase; 27 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; 28 29 /** 30 * JDWP Unit test for ThreadReference.OwnedMonitorsStackDepthInfo command. 31 */ 32 public class OwnedMonitorsStackDepthInfoTest extends JDWPSyncTestCase { 33 34 static final String thisCommandName = "ThreadReference.OwnedMonitorsStackDepthInfo command "; 35 36 @Override 37 protected String getDebuggeeClassName() { 38 return "org.apache.harmony.jpda.tests.jdwp.ThreadReference.OwnedMonitorsStackDepthInfoDebuggee"; 39 } 40 41 private int jdwpGetFrameCount(long threadID) { 42 CommandPacket packet = new CommandPacket(JDWPCommands.ThreadReferenceCommandSet.CommandSetID, 43 JDWPCommands.ThreadReferenceCommandSet.FrameCountCommand); 44 packet.setNextValueAsThreadID(threadID); 45 46 ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet); 47 checkReplyPacket(reply, "ThreadReference::FrameCount command"); 48 return reply.getNextValueAsInt(); 49 } 50 51 /** 52 * This testcase exercises ThreadReference.OwnedMonitorsStackDepthInfo 53 * command. <BR> 54 * At first the test starts OwnedMonitorsStackDepthInfoDebuggee which runs 55 * the tested thread 'TESTED_THREAD'. <BR> 56 * Then the test performs the ThreadReference.OwnedMonitorsStackDepthInfo 57 * command for the tested thread and gets list of monitor objects. 58 * The returned monitor objects are equal to expected count and their stack depth are 59 * equal to expected depth. This test will perform MonitorInfo to guarrantee that returend 60 * monitors do belong to the test thread. 61 */ 62 public void testOwnedMonitorsStackDepthInfo() { 63 String thisTestName = "testOwnedMonitorsStackDepthInfo"; 64 logWriter.println("==> " + thisTestName + " for " + thisCommandName + ": START..."); 65 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 66 67 // Ensure we signal the debuggee to continue at the end of the test. 68 finalSyncMessage = JPDADebuggeeSynchronizer.SGNL_CONTINUE; 69 70 // Getting ID of the tested thread 71 logWriter.println("==> testedThreadName = " 72 + OwnedMonitorsStackDepthInfoDebuggee.TESTED_THREAD); 73 logWriter.println("==> Get testedThreadID..."); 74 long testedThreadID = debuggeeWrapper.vmMirror 75 .getThreadID(OwnedMonitorsStackDepthInfoDebuggee.TESTED_THREAD); 76 77 // Compose the OwnedMonitorsStackDepthInfo command 78 CommandPacket stackDepthPacket = new CommandPacket( 79 JDWPCommands.ThreadReferenceCommandSet.CommandSetID, 80 JDWPCommands.ThreadReferenceCommandSet.OwnedMonitorsStackDepthInfoCommand); 81 stackDepthPacket.setNextValueAsThreadID(testedThreadID); 82 83 // Suspend the VM before perform command 84 logWriter.println("==> testedThreadID = " + testedThreadID); 85 logWriter.println("==> suspend testedThread..."); 86 debuggeeWrapper.vmMirror.suspendThread(testedThreadID); 87 88 // There are various monitors held in the outermost frames, but there may be 89 // implementation-specific locks held below that (since the thread will actually be 90 // suspended somewhere in I/O code). See OwnedMonitorsStackDepthInfoDebuggee.run(). 91 int frameCount = jdwpGetFrameCount(testedThreadID); 92 int expectedMonitorCount = 3; 93 int[] expectedStackDepth = new int[] { frameCount - 4, frameCount - 4, frameCount - 2 }; 94 95 // Perform the command and attain the reply package 96 ReplyPacket stackDepthReply = debuggeeWrapper.vmMirror.performCommand(stackDepthPacket); 97 checkReplyPacket(stackDepthReply, "ThreadReference::OwnedMonitorsStackDepthInfo command"); 98 99 // Analyze the reply package 100 int actualMonitorCount = stackDepthReply.getNextValueAsInt(); 101 logWriter.println("==> Owned monitors: " + actualMonitorCount); 102 assertTrue(actualMonitorCount >= expectedMonitorCount); 103 logWriter.println("==> CHECK: PASSED: actualMonitorCount >= expectedMonitorCount"); 104 105 int currentMonitor = 0; 106 for (int i = 0; i < actualMonitorCount; ++i) { 107 // Attain monitor object ID 108 TaggedObject monitorObject = stackDepthReply.getNextValueAsTaggedObject(); 109 110 // Attain monitor stack depth 111 int actualStackDepth = stackDepthReply.getNextValueAsInt(); 112 logWriter.println("==> Stack depth: " + actualStackDepth); 113 if (expectedStackDepth[currentMonitor] != actualStackDepth) { 114 continue; 115 } 116 117 /* 118 * Test the returned monitor object does belong to the test thread by MonitorInfo Command 119 */ 120 // Compose the MonitorInfo Command 121 CommandPacket monitorInfoPacket = new CommandPacket( 122 JDWPCommands.ObjectReferenceCommandSet.CommandSetID, 123 JDWPCommands.ObjectReferenceCommandSet.MonitorInfoCommand); 124 monitorInfoPacket.setNextValueAsObjectID(monitorObject.objectID); 125 126 // Perform the command and attain the reply package 127 ReplyPacket monitorInfoReply = debuggeeWrapper.vmMirror.performCommand(monitorInfoPacket); 128 checkReplyPacket(monitorInfoReply, "ObjectReference::MonitorInfo command"); 129 130 // Attain thread id from monitor info 131 long ownerThreadID = monitorInfoReply.getNextValueAsThreadID(); 132 assertEquals(thisCommandName + "returned monitor is not owned by test thread", ownerThreadID, testedThreadID, null, null); 133 134 logWriter.println("==> CHECK: PASSED: returned monitor does belong to the test thread."); 135 logWriter.println("==> Monitor owner thread ID: " + ownerThreadID); 136 137 ++currentMonitor; 138 } 139 140 assertAllDataRead(stackDepthReply); 141 } 142 143 144 public void testOwnedMonitorsStackDepthInfo_Unsuspended() { 145 String thisTestName = "testOwnedMonitorsStackDepthInfo"; 146 logWriter.println("==> " + thisTestName + " for " + thisCommandName 147 + ": START..."); 148 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 149 150 // Ensure we signal the debuggee to continue at the end of the test. 151 finalSyncMessage = JPDADebuggeeSynchronizer.SGNL_CONTINUE; 152 153 // Getting ID of the tested thread 154 logWriter.println("==> testedThreadName = " 155 + OwnedMonitorsStackDepthInfoDebuggee.TESTED_THREAD); 156 logWriter.println("==> Get testedThreadID..."); 157 long testedThreadID = debuggeeWrapper.vmMirror 158 .getThreadID(OwnedMonitorsStackDepthInfoDebuggee.TESTED_THREAD); 159 160 // Compose the OwnedMonitorsStackDepthInfo command 161 CommandPacket stackDepthPacket = new CommandPacket( 162 JDWPCommands.ThreadReferenceCommandSet.CommandSetID, 163 JDWPCommands.ThreadReferenceCommandSet.OwnedMonitorsStackDepthInfoCommand); 164 stackDepthPacket.setNextValueAsThreadID(testedThreadID); 165 166 // Perform the command and attain the reply package 167 ReplyPacket checkedReply = debuggeeWrapper.vmMirror 168 .performCommand(stackDepthPacket); 169 short errorCode = checkedReply.getErrorCode(); 170 if (errorCode != JDWPConstants.Error.NONE) { 171 if (errorCode == JDWPConstants.Error.THREAD_NOT_SUSPENDED) { 172 logWriter.println("=> CHECK PASSED: Expected error (THREAD_NOT_SUSPENDED) is returned"); 173 return; 174 } 175 } 176 printErrorAndFail(thisCommandName + " should throw exception when VM is not suspended."); 177 } 178 } 179