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.ParsedEvent.EventThread; 26 import org.apache.harmony.jpda.tests.framework.jdwp.Value; 27 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; 28 29 /** 30 * JDWP Unit test for ThreadOnly event modifier. 31 */ 32 public class ThreadOnlyModifierTest extends JDWPEventModifierTestCase { 33 34 private static final 35 String DEBUGGEE_SIGNATURE = "Lorg/apache/harmony/jpda/tests/jdwp/EventModifiers/ThreadOnlyModifierDebuggee;"; 36 private static final 37 String TEST_CLASS_SIGNATURE = "Lorg/apache/harmony/jpda/tests/jdwp/EventModifiers/ThreadOnlyModifierDebuggee$TestClass;"; 38 private static final 39 String TEST_CLASS_NAME = "org.apache.harmony.jpda.tests.jdwp.EventModifiers.ThreadOnlyModifierDebuggee$TestClass"; 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 private static final String THREAD_FIELD_NAME = "THREAD_ONLY"; 48 49 @Override getDebuggeeClassName()50 protected String getDebuggeeClassName() { 51 return ThreadOnlyModifierDebuggee.class.getName(); 52 } 53 54 /** 55 * This testcase is for BREAKPOINT event with ThreadOnly modifier. 56 * <BR>It runs ThreadOnlyModifierDebuggee and sets BREAKPOINT to its 57 * {@link ThreadOnlyModifierDebuggee.TestClass#eventTestMethod} method. 58 * <BR>Then calls this method multiple times and verifies that requested 59 * BREAKPOINT event occurs only in the 60 * {@link ThreadOnlyModifierDebuggee#THREAD_ONLY} thread. 61 */ testBreakpoint()62 public void testBreakpoint() { 63 logWriter.println("testBreakpoint started"); 64 65 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 66 67 byte typeTag = JDWPConstants.TypeTag.CLASS; 68 Breakpoint breakpoint = new Breakpoint(TEST_CLASS_SIGNATURE, 69 METHOD_NAME, 0); 70 EventBuilder builder = createBreakpointEventBuilder(typeTag, 71 breakpoint); 72 testEventWithThreadOnlyModifier(builder); 73 74 logWriter.println("testBreakpoint done"); 75 } 76 77 /** 78 * This testcase is for METHOD_ENTRY event with ThreadOnly modifier. 79 * <BR>It runs ThreadOnlyModifierDebuggee and sets METHOD_ENTRY to the 80 * {@link ThreadOnlyModifierDebuggee.TestClass} class. 81 * <BR>Then calls 82 * {@link ThreadOnlyModifierDebuggee.TestClass#eventTestMethod} method 83 * multiple times and verifies that requested METHOD_ENTRY event occurs 84 * only in the {@link ThreadOnlyModifierDebuggee#THREAD_ONLY} thread. 85 */ testMethodEntry()86 public void testMethodEntry() { 87 logWriter.println("testMethodEntry started"); 88 89 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 90 EventBuilder builder = createMethodEntryEventBuilder(TEST_CLASS_NAME); 91 testEventWithThreadOnlyModifier(builder); 92 93 logWriter.println("testMethodEntry done"); 94 } 95 96 /** 97 * This testcase is for METHOD_EXIT event with ThreadOnly modifier. 98 * <BR>It runs ThreadOnlyModifierDebuggee and sets METHOD_EXIT to the 99 * {@link ThreadOnlyModifierDebuggee.TestClass} class. 100 * <BR>Then calls 101 * {@link ThreadOnlyModifierDebuggee.TestClass#eventTestMethod} method 102 * multiple times and verifies that requested METHOD_EXIT event occurs only 103 * in the {@link ThreadOnlyModifierDebuggee#THREAD_ONLY} thread. 104 */ testMethodExit()105 public void testMethodExit() { 106 logWriter.println("testMethodExit started"); 107 108 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 109 EventBuilder builder = createMethodExitEventBuilder(TEST_CLASS_NAME); 110 testEventWithThreadOnlyModifier(builder); 111 112 logWriter.println("testMethodExit done"); 113 } 114 115 /** 116 * This testcase is for METHOD_EXIT_WITH_RETURN_VALUE event with ThreadOnly 117 * modifier. 118 * <BR>It runs ThreadOnlyModifierDebuggee and sets 119 * METHOD_EXIT_WITH_RETURN_VALUE to the 120 * {@link ThreadOnlyModifierDebuggee.TestClass} class. 121 * <BR>Then calls 122 * {@link ThreadOnlyModifierDebuggee.TestClass#eventTestMethod} method 123 * multiple times and verifies that requested METHOD_EXIT_WITH_RETURN_VALUE 124 * event occurs only in the {@link ThreadOnlyModifierDebuggee#THREAD_ONLY} 125 * thread. 126 */ testMethodExitWithReturnValue()127 public void testMethodExitWithReturnValue() { 128 logWriter.println("testMethodExitWithReturnValue started"); 129 130 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 131 EventBuilder builder = createMethodExitWithReturnValueEventBuilder(TEST_CLASS_NAME); 132 testEventWithThreadOnlyModifier(builder); 133 134 logWriter.println("testMethodExitWithReturnValue done"); 135 } 136 137 /** 138 * This testcase is for EXCEPTION event with ThreadOnly modifier. 139 * <BR>It runs ThreadOnlyModifierDebuggee and sets EXCEPTION to the 140 * {@link ThreadOnlyModifierDebuggee.TestException} class but only for 141 * caught exceptions. 142 * <BR>Then calls 143 * {@link ThreadOnlyModifierDebuggee.TestThread#throwException} method 144 * multiple times and verifies that requested EXCEPTION event occurs only 145 * in the {@link ThreadOnlyModifierDebuggee#THREAD_ONLY} thread. 146 */ testException()147 public void testException() { 148 logWriter.println("testException started"); 149 150 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 151 EventBuilder builder = createExceptionEventBuilder( 152 "Lorg/apache/harmony/jpda/tests/jdwp/EventModifiers/ThreadOnlyModifierDebuggee$TestException;", 153 true, false); 154 testEventWithThreadOnlyModifier(builder); 155 156 logWriter.println("testException done"); 157 } 158 159 /** 160 * This testcase is for THREAD_START event with ThreadOnly modifier. 161 * <BR>It runs ThreadOnlyModifierDebuggee and requests THREAD_START event. 162 * <BR>Then calls {@link ThreadOnlyModifierDebuggee#runThread} method 163 * multiple times and verifies that requested THREAD_START event occurs 164 * only in the {@link ThreadOnlyModifierDebuggee#THREAD_ONLY} thread. 165 */ testThreadStart()166 public void testThreadStart() { 167 logWriter.println("testThreadStart started"); 168 169 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 170 171 EventBuilder builder = createThreadStartBuilder(); 172 testEventWithThreadOnlyModifier(builder); 173 174 logWriter.println("testThreadStart done"); 175 } 176 177 /** 178 * This testcase is for THREAD_END event with ThreadOnly modifier. 179 * <BR>It runs ThreadOnlyModifierDebuggee and requests THREAD_END event. 180 * <BR>Then calls {@link ThreadOnlyModifierDebuggee#runThread} method 181 * multiple times and verifies that requested THREAD_END event occurs only 182 * in the {@link ThreadOnlyModifierDebuggee#THREAD_ONLY} thread. 183 */ testThreadEnd()184 public void testThreadEnd() { 185 logWriter.println("testThreadEnd started"); 186 187 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 188 189 EventBuilder builder = createThreadEndBuilder(); 190 testEventWithThreadOnlyModifier(builder); 191 192 logWriter.println("testThreadEnd done"); 193 } 194 195 /** 196 * This testcase is for FIELD_ACCESS event with ThreadOnly modifier. 197 * <BR>It runs ThreadOnlyModifierDebuggee and requests FIELD_ACCESS event 198 * for {@link ThreadOnlyModifierDebuggee#watchedField}. 199 * <BR>Then calls 200 * {@link ThreadOnlyModifierDebuggee.TestThread#readAndWriteField} method 201 * multiple times and verifies that requested FIELD_ACCESS event occurs 202 * only in the {@link ThreadOnlyModifierDebuggee#THREAD_ONLY} thread. 203 * <BR>Note: if the VM does not support the canWatchFieldAccess capability, 204 * the test succeeds. 205 */ testFieldAccess()206 public void testFieldAccess() { 207 logWriter.println("testFieldAccess started"); 208 209 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 210 211 if (!canWatchFieldAccessCapability()) { 212 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 213 return; 214 } 215 216 EventBuilder builder = createFieldAccessEventBuilder( 217 JDWPConstants.TypeTag.CLASS, DEBUGGEE_SIGNATURE, 218 WATCHED_FIELD_NAME); 219 testEventWithThreadOnlyModifier(builder); 220 221 logWriter.println("testFieldAccess done"); 222 } 223 224 /** 225 * This testcase is for FIELD_MODIFICATION event with ThreadOnly modifier. 226 * <BR>It runs ThreadOnlyModifierDebuggee and requests FIELD_MODIFICATION 227 * event for {@link ThreadOnlyModifierDebuggee#watchedField}. 228 * <BR>Then calls 229 * {@link ThreadOnlyModifierDebuggee.TestThread#readAndWriteField} method 230 * multiple times and verifies that requested FIELD_MODIFICATION event 231 * occurs only in the {@link ThreadOnlyModifierDebuggee#THREAD_ONLY} thread. 232 * <BR>Note: if the VM does not support the canWatchFieldModification 233 * capability, the test succeeds. 234 */ testFieldModification()235 public void testFieldModification() { 236 logWriter.println("testFieldModification started"); 237 238 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 239 240 if (!canWatchFieldModificationCapability()) { 241 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 242 return; 243 } 244 245 EventBuilder builder = createFieldModificationEventBuilder( 246 JDWPConstants.TypeTag.CLASS, DEBUGGEE_SIGNATURE, 247 WATCHED_FIELD_NAME); 248 testEventWithThreadOnlyModifier(builder); 249 250 logWriter.println("testFieldModification done"); 251 } 252 getFilteredThreadId()253 private long getFilteredThreadId() { 254 Value fieldValue = getFieldValue(DEBUGGEE_SIGNATURE, THREAD_FIELD_NAME); 255 assertEquals("Invalid field value tag", JDWPConstants.Tag.THREAD_TAG, 256 fieldValue.getTag()); 257 return fieldValue.getLongValue(); 258 } 259 testEventWithThreadOnlyModifier(EventBuilder builder)260 private void testEventWithThreadOnlyModifier(EventBuilder builder) { 261 long threadID = getFilteredThreadId(); 262 Event event = builder.setThreadOnly(threadID).build(); 263 int requestID = requestEvent(event); 264 265 EventThread eventThread = waitForEvent(event.eventKind, requestID); 266 assertEquals(threadID, eventThread.getThreadID()); 267 268 clearAndResume(event.eventKind, requestID); 269 } 270 } 271