blob: 61aeec400b332032366f93b8519b6d4a8733a4b2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Vitaly A. Provodin, Anatoly F. Bondarenko
*/
/**
* Created on 10.02.2005
*/
package org.apache.harmony.jpda.tests.jdwp.VirtualMachine;
import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
import org.apache.harmony.jpda.tests.framework.jdwp.exceptions.ReplyErrorCodeException;
import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
import java.util.ArrayList;
import java.util.List;
/**
* JDWP Unit test for VirtualMachine.Resume command.
*/
public class ResumeTest extends JDWPSyncTestCase {
static final String debuggeeSignature =
"Lorg/apache/harmony/jpda/tests/jdwp/VirtualMachine/ResumeDebuggee;";
protected String getDebuggeeClassName() {
return ResumeDebuggee.class.getName();
}
@Override
protected void internalTearDown() {
// We need to finish the tested threads before detaching.
logWriter.println("Finish debuggee tested threads");
setStaticIntField(debuggeeSignature,
ResumeDebuggee.TO_FINISH_DEBUGGEE_FIELD_NAME, 99);
super.internalTearDown();
}
/**
* This testcase exercises VirtualMachine.Resume command.
* <BR>At first the test starts ResumeDebuggee which starts and runs some tested threads.
* <BR> Then the test performs VirtualMachine.Suspend command and checks with help of
* ThreadReference.Status command that all debuggee tested threads are suspended.
* <BR> Then the test performs VirtualMachine.Resume command and checks with help of
* ThreadReference.Status command that all debuggee tested threads are resumed.
*/
public void testResume001() {
logWriter.println("==> testResume001: START...");
// The error messages in case of test failure.
List<String> errorMessages = new ArrayList<String>();
// All the threads we're interested in.
ThreadInfo[] threadInfos = createThreadInfos();
// Suspend all threads with VirtualMachine.Suspend command.
suspendAll();
// Check all threads are suspended now.
logWriter.println("\n==> Check that all tested threads are suspended " +
"after VirtualMachine.Suspend command...");
checkThreadStatus(threadInfos, true, errorMessages);
// Resume all threads with VirtualMachine.Resume command.
resumeAll();
// Check all threads are NOT suspended anymore.
logWriter.println("\n==> Check that all tested threads are resumed " +
"after VirtualMachine.Resume command...");
checkThreadStatus(threadInfos, false, errorMessages);
if (!errorMessages.isEmpty()) {
// Print error messages first.
for (String errorMessage : errorMessages) {
logWriter.printError(errorMessage + "\n");
}
printErrorAndFail("\ntestResume001 FAILED");
} else {
logWriter.println("\n==> testResume001 - OK!");
}
}
/**
* This testcase exercises VirtualMachine.Resume command.
* <BR>At first the test starts ResumeDebuggee which starts and runs some
* tested threads.
* <BR> Then the test performs VirtualMachine.Suspend command twice and
* checks, with help of ThreadReference.Status command, that all debuggee
* tested threads are suspended.
* <BR> Then the test performs VirtualMachine.Resume command and checks
* that all debuggee tested threads are still suspended.
* <BR> Then the test performs VirtualMachine.Resume command again and
* checks that all debuggee tested threads are resumed.
*/
public void testResume002() {
logWriter.println("==> testResume002: START...");
// The error messages in case of test failure.
List<String> errorMessages = new ArrayList<String>();
// All the threads we're interested in.
ThreadInfo[] threadInfos = createThreadInfos();
// Suspend all threads with VirtualMachine.Suspend command.
suspendAll();
// Check all threads are suspended now.
logWriter.println("\n==> Check that all tested threads are suspended " +
"after VirtualMachine.Suspend command...");
checkThreadStatus(threadInfos, true, errorMessages);
// Suspend all threads again.
suspendAll();
// Check all threads are still suspended.
logWriter.println("\n==> Check that all tested threads are still " +
"suspended after another VirtualMachine.Suspend command...");
checkThreadStatus(threadInfos, true, errorMessages);
// Resume all threads with VirtualMachine.Resume command.
resumeAll();
// Check all threads are still suspended.
logWriter.println("\n==> Check that all tested threads are still " +
"suspended after VirtualMachine.Resume command...");
checkThreadStatus(threadInfos, true, errorMessages);
// Resume all threads again.
resumeAll();
// Check all threads are NOT suspended anymore.
logWriter.println("\n==> Check that all tested threads are resumed " +
"after VirtualMachine.Resume command...");
checkThreadStatus(threadInfos, false, errorMessages);
if (!errorMessages.isEmpty()) {
// Print error messages first.
for (String errorMessage : errorMessages) {
logWriter.printError(errorMessage + "\n");
}
printErrorAndFail("\ntestResume002 FAILED");
} else {
logWriter.println("\n==> testResume002 - OK!");
}
}
/**
* This testcase exercises VirtualMachine.Resume command.
* <BR>At first the test starts ResumeDebuggee which starts and runs some
* tested threads.
* <BR> Then the test performs VirtualMachine.Resume command and checks it
* does not cause any error if we do not perform VirtualMachine.Suspend
* before.
* <BR> Then the test performs VirtualMachine.Suspend command and checks
* that all debuggee tested threads are suspended.
* <BR> Then the test performs VirtualMachine.Resume command and checks
* that all debuggee tested threads are resumed.
*/
public void testResume003() {
logWriter.println("==> testResume002: START...");
// The error messages in case of test failure.
List<String> errorMessages = new ArrayList<String>();
// All the threads we're interested in.
ThreadInfo[] threadInfos = createThreadInfos();
// Resume all threads: should be a no-op.
resumeAll();
// Check all threads are NOT suspended.
logWriter.println("\n==> Check that no tested thread is suspended " +
"after VirtualMachine.Resume command...");
checkThreadStatus(threadInfos, false, errorMessages);
// Suspend all threads with VirtualMachine.Suspend command.
suspendAll();
// Check all threads are suspended now.
logWriter.println("\n==> Check that all tested threads are suspended " +
"after VirtualMachine.Suspend command...");
checkThreadStatus(threadInfos, true, errorMessages);
// Resume all threads with VirtualMachine.Resume command.
resumeAll();
// Check all threads are NOT suspended anymore.
logWriter.println("\n==> Check that all tested threads are resumed " +
"after VirtualMachine.Resume command...");
checkThreadStatus(threadInfos, false, errorMessages);
if (!errorMessages.isEmpty()) {
// Print error messages first.
for (String errorMessage : errorMessages) {
logWriter.printError(errorMessage + "\n");
}
printErrorAndFail("\ntestResume002 FAILED");
} else {
logWriter.println("\n==> testResume002 - OK!");
}
}
private static class ThreadInfo {
final String threadName;
long threadId = 0;
public ThreadInfo(String threadName) {
this.threadName = threadName;
}
}
/**
* Suspends all threads using VirtualMachine.Suspend command.
*/
private void suspendAll() {
logWriter.println("\n==> Send VirtualMachine.Suspend command...");
CommandPacket packet = new CommandPacket(
JDWPCommands.VirtualMachineCommandSet.CommandSetID,
JDWPCommands.VirtualMachineCommandSet.SuspendCommand);
ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
checkReplyPacket(reply, "VirtualMachine.Suspend");
logWriter.println("==> VirtualMachine.Suspend command - OK.");
}
/**
* Resumes all threads using VirtualMachine.Resume command.
*/
private void resumeAll() {
logWriter.println("\n==> Send VirtualMachine.Resume command...");
CommandPacket packet = new CommandPacket(
JDWPCommands.VirtualMachineCommandSet.CommandSetID,
JDWPCommands.VirtualMachineCommandSet.ResumeCommand);
ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
checkReplyPacket(reply, "VirtualMachine.Resume");
logWriter.println("==> VirtualMachine.Resume command - OK.");
}
/**
* Returns the number of threads used in the tests (including the main
* thread).
*/
private int getThreadsNumber() {
String debuggeeMessage = synchronizer.receiveMessage();
int testedThreadsNumber = 0;
try {
testedThreadsNumber = Integer.valueOf(debuggeeMessage).intValue();
} catch (NumberFormatException exception) {
logWriter.println("## FAILURE: Exception while getting number of"
+ " started threads from debuggee = " + exception);
printErrorAndFail("\n## Can NOT get number of started threads "
+ "from debuggee! ");
}
return testedThreadsNumber + 1; // to add debuggee main thread
}
/**
* Creates ThreadInfo array containing information about each tested thread:
* thread name and thread JDWP id.
*/
private ThreadInfo[] createThreadInfos() {
int testedThreadsNumber = getThreadsNumber();
logWriter.println("==> Number of threads in debuggee to test = "
+ testedThreadsNumber);
ThreadInfo[] threadInfos = new ThreadInfo[testedThreadsNumber];
String debuggeeMainThreadName = synchronizer.receiveMessage();
// Initialize all threads
for (int i = 0, e = threadInfos.length - 1; i < e; ++i) {
threadInfos[i] = new ThreadInfo(ResumeDebuggee.THREAD_NAME_PATTERN + i);
}
threadInfos[threadInfos.length - 1] = new ThreadInfo(debuggeeMainThreadName);
// Getting ID of the tested thread using VirtualMachine.AllThreads.
ReplyPacket allThreadIDReply = null;
try {
allThreadIDReply = debuggeeWrapper.vmMirror.getAllThreadID();
} catch (ReplyErrorCodeException exception) {
logWriter.println
("## FAILURE: Exception in vmMirror.getAllThreadID() = " + exception);
printErrorAndFail("\n## Can NOT get all ThreadID in debuggee! ");
}
int threads = allThreadIDReply.getNextValueAsInt();
logWriter.println("==> Number of all threads in debuggee = " + threads);
for (int i = 0; i < threads; i++) {
long threadID = allThreadIDReply.getNextValueAsThreadID();
String threadName = null;
try {
threadName = debuggeeWrapper.vmMirror.getThreadName(threadID);
} catch (ReplyErrorCodeException exception) {
logWriter.println
("==> WARNING: Can NOT get thread name for threadID = " + threadID);
continue;
}
for (ThreadInfo threadInfo : threadInfos) {
if (threadInfo.threadName.equals(threadName) ) {
threadInfo.threadId = threadID;
break;
}
}
}
// Check we found thread id for each thread.
boolean testedThreadNotFound = false;
for (ThreadInfo threadInfo : threadInfos) {
if (threadInfo.threadId == 0) {
logWriter.println("## FAILURE: Tested thread is not found out "
+ "among debuggee threads!");
logWriter.println("## Thread name = "
+ threadInfo.threadName);
testedThreadNotFound = true;
}
}
if (testedThreadNotFound) {
printErrorAndFail("\n## Some of tested threads are not found!");
}
return threadInfos;
}
/**
* Checks suspend status of each tested thread is the expected one.
*
* @param threadInfos
* the thread information
* @param isSuspended
* if true, thread must be suspended; otherwise thread
* must not be suspended.
* @param errorMessages
* a list of String to append error message.
*/
private void checkThreadStatus(ThreadInfo[] threadInfos,
boolean isSuspended, List<String> errorMessages) {
boolean statusCommandFailed = false;
boolean suspendStatusFailed = false;
for (ThreadInfo threadInfo : threadInfos) {
logWriter.println("\n==> Check for Thread: threadID = "
+ threadInfo.threadId
+ " (" + threadInfo.threadName + ")");
logWriter.println("==> Send ThreadReference.Status command...");
CommandPacket packet = new CommandPacket(
JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
JDWPCommands.ThreadReferenceCommandSet.StatusCommand);
packet.setNextValueAsThreadID(threadInfo.threadId);
ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
if (!checkReplyPacketWithoutFail(reply, "ThreadReference.Status command")) {
logWriter.println("Can't get thread status for thread " +
threadInfo.threadId +
" \"" + threadInfo.threadName + "\"");
statusCommandFailed = true;
continue;
}
int threadStatus = reply.getNextValueAsInt();
int suspendStatus = reply.getNextValueAsInt();
logWriter.println("==> threadStatus = " + threadStatus + " ("
+ JDWPConstants.ThreadStatus.getName(threadStatus) + ")");
logWriter.println("==> suspendStatus = " + suspendStatus + " ("
+ JDWPConstants.SuspendStatus.getName(suspendStatus) + ")");
boolean isThreadSuspended =
(suspendStatus == JDWPConstants.SuspendStatus.SUSPEND_STATUS_SUSPENDED);
if (isThreadSuspended != isSuspended) {
logWriter.println("## FAILURE: Unexpected suspendStatus for " +
"checked thread " + threadInfo.threadId +
" \"" + threadInfo.threadName + "\"");
logWriter.println("## Expected suspendStatus = "
+ JDWPConstants.SuspendStatus.SUSPEND_STATUS_SUSPENDED
+ "(" + JDWPConstants.SuspendStatus.getName
(JDWPConstants.SuspendStatus.SUSPEND_STATUS_SUSPENDED) +")");
suspendStatusFailed = true;
continue;
}
}
if (statusCommandFailed) {
errorMessages.add("## Error found out while ThreadReference.Status "
+ "command performing!");
}
if (suspendStatusFailed) {
errorMessages.add("## Unexpected suspendStatus found out!");
}
}
}