1 /*
   2  * Copyright (c) 2001, 2015, 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  *  @modules jdk.jdi
  34  *  @run build JDIScaffold VMConnection
  35  *  @run compile -g ModificationWatchpoints.java
  36  *  @run driver ModificationWatchpoints
  37  */
  38 import com.sun.jdi.*;
  39 import com.sun.jdi.event.*;
  40 import com.sun.jdi.request.*;
  41 import java.util.*;
  42 
  43     /********** target program **********/
  44 
  45 class ModificationWatchpointsTarg {
  46     public static final int RepeatCount = 3;
  47 
  48     public static final byte ByteVal = -17;
  49     public static final char CharVal = 'Y';
  50     public static final short ShortVal = -412;
  51     public static final int IntVal = -711618;
  52     public static final long LongVal = 0x1234567890123456L;
  53     public static final float FloatVal = 7.986f;
  54     public static final double DoubleVal = 3.14159265358979d;
  55     public static final String StringVal = "OnceMore";
  56     public static final Object ObjectVal = new Object();
  57 
  58     static byte sByte;
  59     static char sChar;
  60     static short sShort;
  61     static int sInt;
  62     static long sLong;
  63     static float sFloat;
  64     static double sDouble;
  65     static String sString;
  66     static Object sObject;
  67 
  68     byte iByte;
  69     char iChar;
  70     short iShort;
  71     int iInt;
  72     long iLong;
  73     float iFloat;
  74     double iDouble;
  75     String iString;
  76     Object iObject;
  77 
  78     void iByteSet() {
  79         iByte = ByteVal;
  80     }
  81 
  82     void iCharSet() {
  83         iChar = CharVal;
  84     }
  85 
  86     void iShortSet() {
  87         iShort = ShortVal;
  88     }
  89 
  90     void iIntSet() {
  91         iInt = IntVal;
  92     }
  93 
  94     void iLongSet() {
  95         iLong = LongVal;
  96     }
  97 
  98     void iFloatSet() {
  99         iFloat = FloatVal;
 100     }
 101 
 102     void iDoubleSet() {
 103         iDouble = DoubleVal;
 104     }
 105 
 106     void iStringSet() {
 107         iString = StringVal;
 108     }
 109 
 110     void iObjectSet() {
 111         iObject = ObjectVal;
 112     }
 113 
 114     static void sByteSet() {
 115         sByte = ByteVal;
 116     }
 117 
 118     static void sCharSet() {
 119         sChar = CharVal;
 120     }
 121 
 122     static void sShortSet() {
 123         sShort = ShortVal;
 124     }
 125 
 126     static void sIntSet() {
 127         sInt = IntVal;
 128     }
 129 
 130     static void sLongSet() {
 131         sLong = LongVal;
 132     }
 133 
 134     static void sFloatSet() {
 135         sFloat = FloatVal;
 136     }
 137 
 138     static void sDoubleSet() {
 139         sDouble = DoubleVal;
 140     }
 141 
 142     static void sStringSet() {
 143         sString = StringVal;
 144     }
 145 
 146     static void sObjectSet() {
 147         sObject = ObjectVal;
 148     }
 149 
 150     void iUpdate(){
 151         iByteSet();
 152         iCharSet();
 153         iShortSet();
 154         iIntSet();
 155         iLongSet();
 156         iFloatSet();
 157         iDoubleSet();
 158         iStringSet();
 159         iObjectSet();
 160     }
 161 
 162     static void sUpdate(){
 163         sByteSet();
 164         sCharSet();
 165         sShortSet();
 166         sIntSet();
 167         sLongSet();
 168         sFloatSet();
 169         sDoubleSet();
 170         sStringSet();
 171         sObjectSet();
 172     }
 173 
 174     public static void main(String[] args){
 175         ModificationWatchpointsTarg targ = new ModificationWatchpointsTarg();
 176         for (int i = RepeatCount; i > 0; i--) {
 177             sUpdate();
 178             targ.iUpdate();
 179         }
 180     }
 181 }
 182 
 183 public class ModificationWatchpoints extends TestScaffold {
 184     ReferenceType targ;
 185     List allMWP = new ArrayList();
 186 
 187     ModificationWatchpoints (String args[]) {
 188         super(args);
 189     }
 190 
 191     public static void main(String[] args)      throws Exception {
 192         new ModificationWatchpoints(args).startTests();
 193     }
 194 
 195     /********** event handlers **********/
 196 
 197     public void fieldModified(ModificationWatchpointEvent event) {
 198         MWP mwp = (MWP)event.request().getProperty("executor");
 199         mwp.fieldModified(event);
 200     }
 201 
 202 
 203     /********** test core **********/
 204 
 205     void set(String fieldName, String valString) {
 206         Value val = targ.getValue(targ.fieldByName(valString));
 207         MWP mwp = new MWP("ModificationWatchpointsTarg", fieldName, val);
 208         allMWP.add(mwp);
 209         mwp.set();
 210     }
 211 
 212     protected void runTests() throws Exception {
 213         /*
 214          * Get to the top of main():
 215          */
 216         BreakpointEvent bpe = startToMain("ModificationWatchpointsTarg");
 217         targ = bpe.location().declaringType();
 218 
 219         /*
 220          * Set watchpoints
 221          */
 222         set("iByte", "ByteVal");
 223         set("iChar", "CharVal");
 224         set("iShort", "ShortVal");
 225         set("iInt", "IntVal");
 226         set("iLong", "LongVal");
 227         set("iFloat", "FloatVal");
 228         set("iDouble", "DoubleVal");
 229         set("iString", "StringVal");
 230         set("iObject", "ObjectVal");
 231 
 232         set("sByte", "ByteVal");
 233         set("sChar", "CharVal");
 234         set("sShort", "ShortVal");
 235         set("sInt", "IntVal");
 236         set("sLong", "LongVal");
 237         set("sFloat", "FloatVal");
 238         set("sDouble", "DoubleVal");
 239         set("sString", "StringVal");
 240         set("sObject", "ObjectVal");
 241 
 242         listenUntilVMDisconnect();
 243 
 244         if (!testFailed) {
 245             for (Iterator it = allMWP.iterator(); it.hasNext();) {
 246                 MWP mwp = (MWP)it.next();
 247                 mwp.checkEventCounts(ModificationWatchpointsTarg.RepeatCount);
 248             }
 249         }
 250 
 251         if (!testFailed) {
 252             println("ModificationWatchpoints: passed");
 253         } else {
 254             throw new Exception("ModificationWatchpoints: failed");
 255         }
 256     }
 257 
 258     /********** request wrapper **********/
 259 
 260     class MWP {
 261         private final String className;
 262         private final String fieldName;
 263         private final Value expectedValue;
 264         public int eventCount = 0;
 265         public boolean failed = false;
 266 
 267         public MWP(String className, String fieldName, Value value) {
 268             this.className = className;
 269             this.fieldName = fieldName;
 270             this.expectedValue = value;
 271         }
 272 
 273         /*
 274          * Sets watchpoint with specified properties.
 275          */
 276         public void set() {
 277             List classes = vm().classesByName(className);
 278             if (classes.size() != 1) {
 279                 failure("Expected one class named " + className + " got " + classes.size());
 280             }
 281 
 282             set ((ReferenceType)classes.get(0));
 283         }
 284 
 285         /**
 286          * Sets watchpoint for given class.
 287          */
 288         public void set(ReferenceType clazz) {
 289             Field f = clazz.fieldByName(fieldName);
 290             ModificationWatchpointRequest mwr =
 291                        eventRequestManager().createModificationWatchpointRequest(f);
 292             mwr.putProperty("executor", this);
 293             mwr.enable();
 294             println("set watchpoint: " + className +"." + f);
 295         }
 296 
 297         public void fieldModified(ModificationWatchpointEvent event) {
 298             Value val = event.valueToBe();
 299            println("Watchpoint reached: " + className + "." + fieldName +
 300                    ", new value: " + val);
 301             if (!val.equals(expectedValue)) {
 302                 failure("FAILURE: value should be: " +
 303                         expectedValue.getClass() + ":" + expectedValue +
 304                         " has - " + val.getClass() + ":" + val);
 305             }
 306             if (!event.location().method().name().equals(fieldName + "Set")) {
 307                 failure("FAILURE: occurred in wrong place: " + event.location());
 308             }
 309             eventCount++;
 310         }
 311 
 312         public void checkEventCounts(int expectedCount) {
 313             if (eventCount != expectedCount) {
 314                 failure(className + "." + fieldName +
 315                         " - only got " + eventCount + " events");
 316             }
 317         }
 318 
 319     } // MWP inner class .................
 320 }