blob: 3a3938e12c8e90e6e6429807da5ae27a92f94857 [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.
*/
package org.apache.harmony.jpda.tests.jdwp.EventModifiers;
import org.apache.harmony.jpda.tests.framework.Breakpoint;
import org.apache.harmony.jpda.tests.framework.jdwp.Event;
import org.apache.harmony.jpda.tests.framework.jdwp.EventBuilder;
import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
import org.apache.harmony.jpda.tests.framework.jdwp.Value;
import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
/**
* JDWP Unit test for Count event modifier.
*/
public class CountModifierTest extends JDWPEventModifierTestCase {
private static final
String DEBUGGEE_SIGNATURE = "Lorg/apache/harmony/jpda/tests/jdwp/EventModifiers/CountModifierDebuggee;";
private static final
String TEST_CLASS_SIGNATURE = "Lorg/apache/harmony/jpda/tests/jdwp/EventModifiers/CountModifierDebuggee$TestClass;";
private static final
String TEST_CLASS_NAME = "org.apache.harmony.jpda.tests.jdwp.EventModifiers.CountModifierDebuggee$TestClass";
private static final
String EXCEPTION_SIGNATURE = "Lorg/apache/harmony/jpda/tests/jdwp/EventModifiers/CountModifierDebuggee$TestException;";
// The name of the test method where we set our event requests.
private static final String METHOD_NAME = "eventTestMethod";
// The name of the test method where we set our event requests.
private static final String WATCHED_FIELD_NAME = "watchedField";
// Fields for verifying events count.
private static final String
LOCATION_COUNT_FIELD_NAME = "locationEventCount";
private static final String
EXCEPTION_EVENT_COUNT_FIELD_NAME = "exceptionEventCount";
private static final String THREAD_RUN_COUNT_FIELD_NAME = "threadRunCount";
private static final String
FIELD_READ_WRITE_COUNT_FIELD_NAME = "fieldReadWriteCount";
@Override
protected String getDebuggeeClassName() {
return CountModifierDebuggee.class.getName();
}
/**
* This testcase is for BREAKPOINT event with Count modifier.
* <BR>It runs CountModifierDebuggee and sets BREAKPOINT to its
* {@link CountModifierDebuggee.TestClass#eventTestMethod()} method.
* <BR>Then calls this method multiple times and verifies that requested
* BREAKPOINT event occurs once after having called the method (count - 1)
* times. We check this by looking at the value in the field
* {@link CountModifierDebuggee#locationEventCount}.
*/
public void testBreakpoint() {
logWriter.println("testBreakpoint started");
synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
// Breakpoint at start of test method.
byte typeTag = JDWPConstants.TypeTag.CLASS;
Breakpoint breakpoint = new Breakpoint(TEST_CLASS_SIGNATURE,
METHOD_NAME, 0);
EventBuilder builder = createBreakpointEventBuilder(typeTag,
breakpoint);
testEventWithCountModifier(builder, LOCATION_COUNT_FIELD_NAME);
logWriter.println("testBreakpoint done");
}
/**
* This testcase is for METHOD_ENTRY event with Count modifier.
* <BR>It runs CountModifierDebuggee and sets METHOD_ENTRY to the
* {@link CountModifierDebuggee.TestClass} class.
* <BR>Then calls {@link CountModifierDebuggee.TestClass#eventTestMethod()}
* method multiple times and verifies that requested METHOD_ENTRY event
* occurs once after having called the method (count - 1) times. We check
* this by looking at the value in the field
* {@link CountModifierDebuggee#locationEventCount}.
*/
public void testMethodEntry() {
logWriter.println("testMethodEntry started");
synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
EventBuilder builder = createMethodEntryEventBuilder(TEST_CLASS_NAME);
testEventWithCountModifier(builder, LOCATION_COUNT_FIELD_NAME);
logWriter.println("testMethodEntry done");
}
/**
* This testcase is for METHOD_EXIT event with Count modifier.
* <BR>It runs CountModifierDebuggee and sets METHOD_EXIT to the
* {@link CountModifierDebuggee.TestClass} class.
* <BR>Then calls {@link CountModifierDebuggee.TestClass#eventTestMethod()}
* method multiple times and verifies that requested METHOD_EXIT event
* occurs once after having called the method (count - 1) times. We check
* this by looking at the value in the field
* {@link CountModifierDebuggee#locationEventCount}.
*/
public void testMethodExit() {
logWriter.println("testMethodExit started");
synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
EventBuilder builder = createMethodExitEventBuilder(TEST_CLASS_NAME);
testEventWithCountModifier(builder, LOCATION_COUNT_FIELD_NAME);
logWriter.println("testMethodExit done");
}
/**
* This testcase is for METHOD_EXIT_WITH_RETURN_VALUE event with Count
* modifier.
* <BR>It runs CountModifierDebuggee and sets METHOD_EXIT_WITH_RETURN_VALUE
* to the {@link CountModifierDebuggee.TestClass} class.
* <BR>Then calls {@link CountModifierDebuggee.TestClass#eventTestMethod()}
* method multiple times and verifies that requested
* METHOD_EXIT_WITH_RETURN_VALUE event occurs once after having called the
* method (count - 1) times. We check this by looking at the value in the
* field {@link CountModifierDebuggee#locationEventCount}.
*/
public void testMethodExitWithReturnValue() {
logWriter.println("testMethodExitWithReturnValue started");
synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
EventBuilder builder = createMethodExitWithReturnValueEventBuilder(TEST_CLASS_NAME);
testEventWithCountModifier(builder, LOCATION_COUNT_FIELD_NAME);
logWriter.println("testMethodExitWithReturnValue done");
}
/**
* This testcase is for EXCEPTION event with Count modifier.
* <BR>It runs CountModifierDebuggee and sets EXCEPTION to the
* {@link CountModifierDebuggee.TestException} class but only for caught
* exceptions.
* <BR>Then calls {@link CountModifierDebuggee.TestClass#throwException}
* method multiple times and verifies that requested EXCEPTION event
* occurs once after having called the method (count - 1) times. We check
* this by looking at the value in the field
* {@link CountModifierDebuggee#exceptionEventCount}.
*/
public void testException() {
logWriter.println("testException started");
synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
EventBuilder builder = createExceptionEventBuilder(EXCEPTION_SIGNATURE,
true, false);
testEventWithCountModifier(builder,
EXCEPTION_EVENT_COUNT_FIELD_NAME);
logWriter.println("testException done");
}
/**
* This testcase is for FIELD_ACCESS event with Count modifier.
* <BR>It runs CountModifierDebuggee and requests FIELD_ACCESS event for
* {@link CountModifierDebuggee#watchedField}.
* <BR>Then calls {@link CountModifierDebuggee#readAndWriteField()}
* method multiple times and verifies that requested FIELD_ACCESS event
* occurs once after having called the method (count - 1) times. We check
* this by looking at the value in the field
* {@link CountModifierDebuggee#fieldReadWriteCount}.
* <BR>Note: if the VM does not support the canWatchFieldAccess capability,
* the test succeeds.
*/
public void testFieldAccess() {
logWriter.println("testFieldAccess started");
synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
if (!canWatchFieldAccessCapability()) {
synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
return;
}
EventBuilder builder = createFieldAccessEventBuilder(
JDWPConstants.TypeTag.CLASS, DEBUGGEE_SIGNATURE,
WATCHED_FIELD_NAME);
testEventWithCountModifier(builder, FIELD_READ_WRITE_COUNT_FIELD_NAME);
logWriter.println("testFieldAccess done");
}
/**
* This testcase is for FIELD_MODIFICATION event with Count modifier.
* <BR>It runs CountModifierDebuggee and requests FIELD_MODIFICATION event
* for {@link CountModifierDebuggee#watchedField}.
* <BR>Then calls {@link CountModifierDebuggee#readAndWriteField()}
* method multiple times and verifies that requested FIELD_MODIFICATION
* event occurs once after having called the method (count - 1) times. We
* check this by looking at the value in the field
* {@link CountModifierDebuggee#fieldReadWriteCount}.
* <BR>Note: if the VM does not support the canWatchFieldModification
* capability, the test succeeds.
*/
public void testFieldModification() {
logWriter.println("testFieldModification started");
synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
if (!canWatchFieldModificationCapability()) {
synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
return;
}
EventBuilder builder = createFieldModificationEventBuilder(
JDWPConstants.TypeTag.CLASS, DEBUGGEE_SIGNATURE,
WATCHED_FIELD_NAME);
testEventWithCountModifier(builder, FIELD_READ_WRITE_COUNT_FIELD_NAME);
logWriter.println("testFieldModification done");
}
private void testEventWithCountModifier(EventBuilder builder,
String countFieldName) {
// Add count modifier and build the event.
builder.setCount(CountModifierDebuggee.EVENT_COUNT);
Event event = builder.build();
int requestID = requestEvent(event);
waitForEvent(event.eventKind, requestID);
// Check we properly ignore the (count - 1) previous events.
int expectedCount = CountModifierDebuggee.EVENT_COUNT;
int actualCount = getStaticIntField(DEBUGGEE_SIGNATURE, countFieldName);
assertEquals("Invalid event count", expectedCount, actualCount);
clearAndResume(event.eventKind, requestID);
}
private int getStaticIntField(String classSignature, String fieldName) {
Value fieldValue = getFieldValue(classSignature, fieldName);
assertEquals("Invalid field value tag", JDWPConstants.Tag.INT_TAG,
fieldValue.getTag());
return fieldValue.getIntValue();
}
}