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.EventModifiers; 20 21 import org.apache.harmony.jpda.tests.framework.Breakpoint; 22 import org.apache.harmony.jpda.tests.framework.jdwp.Event; 23 import org.apache.harmony.jpda.tests.framework.jdwp.EventBuilder; 24 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; 25 import org.apache.harmony.jpda.tests.framework.jdwp.Value; 26 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; 27 28 /** 29 * JDWP Unit test for Count event modifier. 30 */ 31 public class CountModifierTest extends JDWPEventModifierTestCase { 32 private static final 33 String DEBUGGEE_SIGNATURE = "Lorg/apache/harmony/jpda/tests/jdwp/EventModifiers/CountModifierDebuggee;"; 34 private static final 35 String TEST_CLASS_SIGNATURE = "Lorg/apache/harmony/jpda/tests/jdwp/EventModifiers/CountModifierDebuggee$TestClass;"; 36 private static final 37 String TEST_CLASS_NAME = "org.apache.harmony.jpda.tests.jdwp.EventModifiers.CountModifierDebuggee$TestClass"; 38 private static final 39 String EXCEPTION_SIGNATURE = "Lorg/apache/harmony/jpda/tests/jdwp/EventModifiers/CountModifierDebuggee$TestException;"; 40 41 // The name of the test method where we set our event requests. 42 private static final String METHOD_NAME = "eventTestMethod"; 43 44 // The name of the test method where we set our event requests. 45 private static final String WATCHED_FIELD_NAME = "watchedField"; 46 47 // Fields for verifying events count. 48 private static final String 49 LOCATION_COUNT_FIELD_NAME = "locationEventCount"; 50 private static final String 51 EXCEPTION_EVENT_COUNT_FIELD_NAME = "exceptionEventCount"; 52 private static final String THREAD_RUN_COUNT_FIELD_NAME = "threadRunCount"; 53 private static final String 54 FIELD_READ_WRITE_COUNT_FIELD_NAME = "fieldReadWriteCount"; 55 56 @Override getDebuggeeClassName()57 protected String getDebuggeeClassName() { 58 return CountModifierDebuggee.class.getName(); 59 } 60 61 /** 62 * This testcase is for BREAKPOINT event with Count modifier. 63 * <BR>It runs CountModifierDebuggee and sets BREAKPOINT to its 64 * {@link CountModifierDebuggee.TestClass#eventTestMethod()} method. 65 * <BR>Then calls this method multiple times and verifies that requested 66 * BREAKPOINT event occurs once after having called the method (count - 1) 67 * times. We check this by looking at the value in the field 68 * {@link CountModifierDebuggee#locationEventCount}. 69 */ testBreakpoint()70 public void testBreakpoint() { 71 logWriter.println("testBreakpoint started"); 72 73 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 74 75 // Breakpoint at start of test method. 76 byte typeTag = JDWPConstants.TypeTag.CLASS; 77 Breakpoint breakpoint = new Breakpoint(TEST_CLASS_SIGNATURE, 78 METHOD_NAME, 0); 79 EventBuilder builder = createBreakpointEventBuilder(typeTag, 80 breakpoint); 81 testEventWithCountModifier(builder, LOCATION_COUNT_FIELD_NAME); 82 83 logWriter.println("testBreakpoint done"); 84 } 85 86 /** 87 * This testcase is for METHOD_ENTRY event with Count modifier. 88 * <BR>It runs CountModifierDebuggee and sets METHOD_ENTRY to the 89 * {@link CountModifierDebuggee.TestClass} class. 90 * <BR>Then calls {@link CountModifierDebuggee.TestClass#eventTestMethod()} 91 * method multiple times and verifies that requested METHOD_ENTRY event 92 * occurs once after having called the method (count - 1) times. We check 93 * this by looking at the value in the field 94 * {@link CountModifierDebuggee#locationEventCount}. 95 */ testMethodEntry()96 public void testMethodEntry() { 97 logWriter.println("testMethodEntry started"); 98 99 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 100 EventBuilder builder = createMethodEntryEventBuilder(TEST_CLASS_NAME); 101 testEventWithCountModifier(builder, LOCATION_COUNT_FIELD_NAME); 102 103 logWriter.println("testMethodEntry done"); 104 } 105 106 /** 107 * This testcase is for METHOD_EXIT event with Count modifier. 108 * <BR>It runs CountModifierDebuggee and sets METHOD_EXIT to the 109 * {@link CountModifierDebuggee.TestClass} class. 110 * <BR>Then calls {@link CountModifierDebuggee.TestClass#eventTestMethod()} 111 * method multiple times and verifies that requested METHOD_EXIT event 112 * occurs once after having called the method (count - 1) times. We check 113 * this by looking at the value in the field 114 * {@link CountModifierDebuggee#locationEventCount}. 115 */ testMethodExit()116 public void testMethodExit() { 117 logWriter.println("testMethodExit started"); 118 119 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 120 EventBuilder builder = createMethodExitEventBuilder(TEST_CLASS_NAME); 121 testEventWithCountModifier(builder, LOCATION_COUNT_FIELD_NAME); 122 123 logWriter.println("testMethodExit done"); 124 } 125 126 127 /** 128 * This testcase is for METHOD_EXIT_WITH_RETURN_VALUE event with Count 129 * modifier. 130 * <BR>It runs CountModifierDebuggee and sets METHOD_EXIT_WITH_RETURN_VALUE 131 * to the {@link CountModifierDebuggee.TestClass} class. 132 * <BR>Then calls {@link CountModifierDebuggee.TestClass#eventTestMethod()} 133 * method multiple times and verifies that requested 134 * METHOD_EXIT_WITH_RETURN_VALUE event occurs once after having called the 135 * method (count - 1) times. We check this by looking at the value in the 136 * field {@link CountModifierDebuggee#locationEventCount}. 137 */ testMethodExitWithReturnValue()138 public void testMethodExitWithReturnValue() { 139 logWriter.println("testMethodExitWithReturnValue started"); 140 141 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 142 EventBuilder builder = createMethodExitWithReturnValueEventBuilder(TEST_CLASS_NAME); 143 testEventWithCountModifier(builder, LOCATION_COUNT_FIELD_NAME); 144 145 logWriter.println("testMethodExitWithReturnValue done"); 146 } 147 148 /** 149 * This testcase is for EXCEPTION event with Count modifier. 150 * <BR>It runs CountModifierDebuggee and sets EXCEPTION to the 151 * {@link CountModifierDebuggee.TestException} class but only for caught 152 * exceptions. 153 * <BR>Then calls {@link CountModifierDebuggee.TestClass#throwException} 154 * method multiple times and verifies that requested EXCEPTION event 155 * occurs once after having called the method (count - 1) times. We check 156 * this by looking at the value in the field 157 * {@link CountModifierDebuggee#exceptionEventCount}. 158 */ testException()159 public void testException() { 160 logWriter.println("testException started"); 161 162 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 163 EventBuilder builder = createExceptionEventBuilder(EXCEPTION_SIGNATURE, 164 true, false); 165 testEventWithCountModifier(builder, 166 EXCEPTION_EVENT_COUNT_FIELD_NAME); 167 168 logWriter.println("testException done"); 169 } 170 171 /** 172 * This testcase is for FIELD_ACCESS event with Count modifier. 173 * <BR>It runs CountModifierDebuggee and requests FIELD_ACCESS event for 174 * {@link CountModifierDebuggee#watchedField}. 175 * <BR>Then calls {@link CountModifierDebuggee#readAndWriteField()} 176 * method multiple times and verifies that requested FIELD_ACCESS event 177 * occurs once after having called the method (count - 1) times. We check 178 * this by looking at the value in the field 179 * {@link CountModifierDebuggee#fieldReadWriteCount}. 180 * <BR>Note: if the VM does not support the canWatchFieldAccess capability, 181 * the test succeeds. 182 */ testFieldAccess()183 public void testFieldAccess() { 184 logWriter.println("testFieldAccess started"); 185 186 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 187 188 if (!canWatchFieldAccessCapability()) { 189 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 190 return; 191 } 192 193 EventBuilder builder = createFieldAccessEventBuilder( 194 JDWPConstants.TypeTag.CLASS, DEBUGGEE_SIGNATURE, 195 WATCHED_FIELD_NAME); 196 testEventWithCountModifier(builder, FIELD_READ_WRITE_COUNT_FIELD_NAME); 197 198 logWriter.println("testFieldAccess done"); 199 } 200 201 /** 202 * This testcase is for FIELD_MODIFICATION event with Count modifier. 203 * <BR>It runs CountModifierDebuggee and requests FIELD_MODIFICATION event 204 * for {@link CountModifierDebuggee#watchedField}. 205 * <BR>Then calls {@link CountModifierDebuggee#readAndWriteField()} 206 * method multiple times and verifies that requested FIELD_MODIFICATION 207 * event occurs once after having called the method (count - 1) times. We 208 * check this by looking at the value in the field 209 * {@link CountModifierDebuggee#fieldReadWriteCount}. 210 * <BR>Note: if the VM does not support the canWatchFieldModification 211 * capability, the test succeeds. 212 */ testFieldModification()213 public void testFieldModification() { 214 logWriter.println("testFieldModification started"); 215 216 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 217 218 if (!canWatchFieldModificationCapability()) { 219 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 220 return; 221 } 222 223 EventBuilder builder = createFieldModificationEventBuilder( 224 JDWPConstants.TypeTag.CLASS, DEBUGGEE_SIGNATURE, 225 WATCHED_FIELD_NAME); 226 testEventWithCountModifier(builder, FIELD_READ_WRITE_COUNT_FIELD_NAME); 227 228 logWriter.println("testFieldModification done"); 229 } 230 testEventWithCountModifier(EventBuilder builder, String countFieldName)231 private void testEventWithCountModifier(EventBuilder builder, 232 String countFieldName) { 233 // Add count modifier and build the event. 234 builder.setCount(CountModifierDebuggee.EVENT_COUNT); 235 Event event = builder.build(); 236 int requestID = requestEvent(event); 237 238 waitForEvent(event.eventKind, requestID); 239 240 // Check we properly ignore the (count - 1) previous events. 241 int expectedCount = CountModifierDebuggee.EVENT_COUNT; 242 int actualCount = getStaticIntField(DEBUGGEE_SIGNATURE, countFieldName); 243 assertEquals("Invalid event count", expectedCount, actualCount); 244 245 clearAndResume(event.eventKind, requestID); 246 } 247 getStaticIntField(String classSignature, String fieldName)248 private int getStaticIntField(String classSignature, String fieldName) { 249 Value fieldValue = getFieldValue(classSignature, fieldName); 250 assertEquals("Invalid field value tag", JDWPConstants.Tag.INT_TAG, 251 fieldValue.getTag()); 252 return fieldValue.getIntValue(); 253 } 254 255 } 256