1 /*
   2  * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  *  @test
  26  *  @bug 4409582
  27  *  @summary Test all info returned by modification watchpoints
  28  *
  29  *  @author Daniel Prusa (or someone in the FFJ group)
  30  *  @author Robert Field (modified to JDIScaffold)
  31  *
  32  *  @library scaffold
  33  *  @run build JDIScaffold VMConnection
  34  *  @run compile -g ModificationWatchpoints.java
  35  *  @run driver ModificationWatchpoints
  36  */
  37 import com.sun.jdi.*;
  38 import com.sun.jdi.event.*;
  39 import com.sun.jdi.request.*;
  40 import java.util.*;
  41 
  42     /********** target program **********/
  43 
  44 class ModificationWatchpointsTarg {
  45     public static final int RepeatCount = 3;
  46 
  47     public static final byte ByteVal = -17;
  48     public static final char CharVal = 'Y';
  49     public static final short ShortVal = -412;
  50     public static final int IntVal = -711618;
  51     public static final long LongVal = 0x1234567890123456L;
  52     public static final float FloatVal = 7.986f;
  53     public static final double DoubleVal = 3.14159265358979d;
  54     public static final String StringVal = "OnceMore";
  55     public static final Object ObjectVal = new Object();
  56 
  57     static byte sByte;
  58     static char sChar;
  59     static short sShort;
  60     static int sInt;
  61     static long sLong;
  62     static float sFloat;
  63     static double sDouble;
  64     static String sString;
  65     static Object sObject;
  66 
  67     byte iByte;
  68     char iChar;
  69     short iShort;
  70     int iInt;
  71     long iLong;
  72     float iFloat;
  73     double iDouble;
  74     String iString;
  75     Object iObject;
  76 
  77     void iByteSet() {
  78         iByte = ByteVal;
  79     }
  80 
  81     void iCharSet() {
  82         iChar = CharVal;
  83     }
  84 
  85     void iShortSet() {
  86         iShort = ShortVal;
  87     }
  88 
  89     void iIntSet() {
  90         iInt = IntVal;
  91     }
  92 
  93     void iLongSet() {
  94         iLong = LongVal;
  95     }
  96 
  97     void iFloatSet() {
  98         iFloat = FloatVal;
  99     }
 100 
 101     void iDoubleSet() {
 102         iDouble = DoubleVal;
 103     }
 104 
 105     void iStringSet() {
 106         iString = StringVal;
 107     }
 108 
 109     void iObjectSet() {
 110         iObject = ObjectVal;
 111     }
 112 
 113     static void sByteSet() {
 114         sByte = ByteVal;
 115     }
 116 
 117     static void sCharSet() {
 118         sChar = CharVal;
 119     }
 120 
 121     static void sShortSet() {
 122         sShort = ShortVal;
 123     }
 124 
 125     static void sIntSet() {
 126         sInt = IntVal;
 127     }
 128 
 129     static void sLongSet() {
 130         sLong = LongVal;
 131     }
 132 
 133     static void sFloatSet() {
 134         sFloat = FloatVal;
 135     }
 136 
 137     static void sDoubleSet() {
 138         sDouble = DoubleVal;
 139     }
 140 
 141     static void sStringSet() {
 142         sString = StringVal;
 143     }
 144 
 145     static void sObjectSet() {
 146         sObject = ObjectVal;
 147     }
 148 
 149     void iUpdate(){
 150         iByteSet();
 151         iCharSet();
 152         iShortSet();
 153         iIntSet();
 154         iLongSet();
 155         iFloatSet();
 156         iDoubleSet();
 157         iStringSet();
 158         iObjectSet();
 159     }
 160 
 161     static void sUpdate(){
 162         sByteSet();
 163         sCharSet();
 164         sShortSet();
 165         sIntSet();
 166         sLongSet();
 167         sFloatSet();
 168         sDoubleSet();
 169         sStringSet();
 170         sObjectSet();
 171     }
 172 
 173     public static void main(String[] args){
 174         ModificationWatchpointsTarg targ = new ModificationWatchpointsTarg();
 175         for (int i = RepeatCount; i > 0; i--) {
 176             sUpdate();
 177             targ.iUpdate();
 178         }
 179     }
 180 }
 181 
 182 public class ModificationWatchpoints extends TestScaffold {
 183     ReferenceType targ;
 184     List allMWP = new ArrayList();
 185 
 186     ModificationWatchpoints (String args[]) {
 187         super(args);
 188     }
 189 
 190     public static void main(String[] args)      throws Exception {
 191         new ModificationWatchpoints(args).startTests();
 192     }
 193 
 194     /********** event handlers **********/
 195 
 196     public void fieldModified(ModificationWatchpointEvent event) {
 197         MWP mwp = (MWP)event.request().getProperty("executor");
 198         mwp.fieldModified(event);
 199     }
 200 
 201 
 202     /********** test core **********/
 203 
 204     void set(String fieldName, String valString) {
 205         Value val = targ.getValue(targ.fieldByName(valString));
 206         MWP mwp = new MWP("ModificationWatchpointsTarg", fieldName, val);
 207         allMWP.add(mwp);
 208         mwp.set();
 209     }
 210 
 211     protected void runTests() throws Exception {
 212         /*
 213          * Get to the top of main():
 214          */
 215         BreakpointEvent bpe = startToMain("ModificationWatchpointsTarg");
 216         targ = bpe.location().declaringType();
 217 
 218         /*
 219          * Set watchpoints
 220          */
 221         set("iByte", "ByteVal");
 222         set("iChar", "CharVal");
 223         set("iShort", "ShortVal");
 224         set("iInt", "IntVal");
 225         set("iLong", "LongVal");
 226         set("iFloat", "FloatVal");
 227         set("iDouble", "DoubleVal");
 228         set("iString", "StringVal");
 229         set("iObject", "ObjectVal");
 230 
 231         set("sByte", "ByteVal");
 232         set("sChar", "CharVal");
 233         set("sShort", "ShortVal");
 234         set("sInt", "IntVal");
 235         set("sLong", "LongVal");
 236         set("sFloat", "FloatVal");
 237         set("sDouble", "DoubleVal");
 238         set("sString", "StringVal");
 239         set("sObject", "ObjectVal");
 240 
 241         listenUntilVMDisconnect();
 242 
 243         if (!testFailed) {
 244             for (Iterator it = allMWP.iterator(); it.hasNext();) {
 245                 MWP mwp = (MWP)it.next();
 246                 mwp.checkEventCounts(ModificationWatchpointsTarg.RepeatCount);
 247             }
 248         }
 249 
 250         if (!testFailed) {
 251             println("ModificationWatchpoints: passed");
 252         } else {
 253             throw new Exception("ModificationWatchpoints: failed");
 254         }
 255     }
 256 
 257     /********** request wrapper **********/
 258 
 259     class MWP {
 260         private final String className;
 261         private final String fieldName;
 262         private final Value expectedValue;
 263         public int eventCount = 0;
 264         public boolean failed = false;
 265 
 266         public MWP(String className, String fieldName, Value value) {
 267             this.className = className;
 268             this.fieldName = fieldName;
 269             this.expectedValue = value;
 270         }
 271 
 272         /*
 273          * Sets watchpoint with specified properties.
 274          */
 275         public void set() {
 276             List classes = vm().classesByName(className);
 277             if (classes.size() != 1) {
 278                 failure("Expected one class named " + className + " got " + classes.size());
 279             }
 280 
 281             set ((ReferenceType)classes.get(0));
 282         }
 283 
 284         /**
 285          * Sets watchpoint for given class.
 286          */
 287         public void set(ReferenceType clazz) {
 288             Field f = clazz.fieldByName(fieldName);
 289             ModificationWatchpointRequest mwr =
 290                        eventRequestManager().createModificationWatchpointRequest(f);
 291             mwr.putProperty("executor", this);
 292             mwr.enable();
 293             println("set watchpoint: " + className +"." + f);
 294         }
 295 
 296         public void fieldModified(ModificationWatchpointEvent event) {
 297             Value val = event.valueToBe();
 298            println("Watchpoint reached: " + className + "." + fieldName +
 299                    ", new value: " + val);
 300             if (!val.equals(expectedValue)) {
 301                 failure("FAILURE: value should be: " +
 302                         expectedValue.getClass() + ":" + expectedValue +
 303                         " has - " + val.getClass() + ":" + val);
 304             }
 305             if (!event.location().method().name().equals(fieldName + "Set")) {
 306                 failure("FAILURE: occurred in wrong place: " + event.location());
 307             }
 308             eventCount++;
 309         }
 310 
 311         public void checkEventCounts(int expectedCount) {
 312             if (eventCount != expectedCount) {
 313                 failure(className + "." + fieldName +
 314                         " - only got " + eventCount + " events");
 315             }
 316         }
 317 
 318     } // MWP inner class .................
 319 }