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