1 /* 2 * Copyright (c) 2002, 2018, 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 package nsk.jdi.ObjectReference.setValue; 25 26 import com.sun.jdi.*; 27 28 import java.util.Iterator; 29 import java.util.List; 30 import java.io.*; 31 32 import nsk.share.*; 33 import nsk.share.jpda.*; 34 import nsk.share.jdi.*; 35 36 /** 37 * The test checks that the JDI method 38 * <code>com.sun.jdi.ObjectReference.setValue()</code> 39 * properly throws <i>InvalidTypeException</i> - if the Field is valid 40 * for this ObjectReference, but there is no a widening reference 41 * conversion from this object to the field's type.<br> 42 * The debuggee part of the test has set of static and instance fields 43 * of different types. The debugger part provokes the <i>InvalidTypeException</i> 44 * trying to set value of: 45 * <li>type not matched with the field's one, and without the widening 46 * reference conversion as well 47 * <li>boolean type which can be converted only to boolean.<br> 48 */ 49 public class setvalue003 { 50 static final String DEBUGGEE_CLASS = 51 "nsk.jdi.ObjectReference.setValue.setvalue003t"; 52 53 // name of debuggee's main thread 54 static final String DEBUGGEE_THRNAME = "setvalue003tThr"; 55 56 // debuggee's local var used to find needed stack frame 57 static final String DEBUGGEE_LOCALVAR = "setvalue003tPipe"; 58 59 static final int ATTEMPTS = 5; 60 61 static final String COMMAND_READY = "ready"; 62 static final String COMMAND_QUIT = "quit"; 63 64 static final int FLDS_NUM = 34; 65 // list of debuggee's fields used to set values and ones 66 // used only to get their wrong non-conversionable values, 67 // see section "5.1.2 Widening Primitive Conversion" in the JLS 68 static final String DEBUGGEE_FLDS[][] = { 69 {"byteFld", "sStrFld"}, 70 {"shortFld", "intFld"}, 71 {"intFld", "longFld"}, 72 {"longFld", "floatFld"}, 73 {"floatFld", "doubleFld"}, 74 {"doubleFld", "sBooleanFld"}, 75 {"charFld", "strFld"}, 76 {"booleanFld", "byteFld"}, 77 {"strFld", "sCharFld"}, 78 {"sByteFld", "sIntFld"}, 79 {"sShortFld", "doubleFld"}, 80 {"sIntFld", "sStrFld"}, 81 {"sLongFld", "sFloatFld"}, 82 {"sFloatFld", "sDoubleFld"}, 83 {"sDoubleFld", "strFld"}, 84 {"sCharFld", "sDoubleFld"}, 85 {"sBooleanFld", "doubleFld"}, 86 {"sStrFld", "sDoubleFld"}, 87 // see section "5.1.1 Identity Conversions" in the JLS: 88 // "the only permitted conversion that involves the type boolean is 89 // the identity conversion from boolean to boolean" 90 {"byteFld", "booleanFld"}, 91 {"shortFld", "booleanFld"}, 92 {"intFld", "booleanFld"}, 93 {"longFld", "booleanFld"}, 94 {"floatFld", "booleanFld"}, 95 {"doubleFld", "booleanFld"}, 96 {"charFld", "booleanFld"}, 97 {"strFld", "booleanFld"}, 98 {"sByteFld", "booleanFld"}, 99 {"sShortFld", "booleanFld"}, 100 {"sIntFld", "booleanFld"}, 101 {"sLongFld", "booleanFld"}, 102 {"sFloatFld", "booleanFld"}, 103 {"sDoubleFld", "booleanFld"}, 104 {"sCharFld", "booleanFld"}, 105 {"sStrFld", "booleanFld"} 106 }; 107 108 private Log log; 109 private IOPipe pipe; 110 private Debugee debuggee; 111 private ThreadReference thrRef = null; 112 private int tot_res = Consts.TEST_PASSED; 113 main(String argv[])114 public static void main (String argv[]) { 115 System.exit(run(argv,System.out) + Consts.JCK_STATUS_BASE); 116 } 117 run(String argv[], PrintStream out)118 public static int run(String argv[], PrintStream out) { 119 return new setvalue003().runIt(argv, out); 120 } 121 runIt(String args[], PrintStream out)122 private int runIt(String args[], PrintStream out) { 123 ArgumentHandler argHandler = new ArgumentHandler(args); 124 log = new Log(out, argHandler); 125 Binder binder = new Binder(argHandler, log); 126 ObjectReference objRef; 127 ReferenceType rType; 128 String cmd; 129 int num = 0; 130 131 debuggee = binder.bindToDebugee(DEBUGGEE_CLASS); 132 pipe = debuggee.createIOPipe(); 133 debuggee.redirectStderr(log, "setvalue003t.err> "); 134 debuggee.resume(); 135 cmd = pipe.readln(); 136 if (!cmd.equals(COMMAND_READY)) { 137 log.complain("TEST BUG: unknown debuggee's command: " + cmd); 138 tot_res = Consts.TEST_FAILED; 139 return quitDebuggee(); 140 } 141 142 if ((thrRef = 143 debuggee.threadByName(DEBUGGEE_THRNAME)) == null) { 144 log.complain("TEST FAILURE: Method Debugee.threadByName() returned null for debuggee's thread " 145 + DEBUGGEE_THRNAME); 146 tot_res = Consts.TEST_FAILED; 147 return quitDebuggee(); 148 } 149 thrRef.suspend(); 150 while(!thrRef.isSuspended()) { 151 num++; 152 if (num > ATTEMPTS) { 153 log.complain("TEST FAILED: Unable to suspend debuggee's thread"); 154 tot_res = Consts.TEST_FAILED; 155 return quitDebuggee(); 156 } 157 log.display("Waiting for debuggee's thread suspension ..."); 158 try { 159 Thread.sleep(1000); 160 } catch(InterruptedException ie) { 161 ie.printStackTrace(); 162 log.complain("TEST FAILED: caught: " + ie); 163 tot_res = Consts.TEST_FAILED; 164 return quitDebuggee(); 165 } 166 } 167 168 // Check the tested assertion 169 try { 170 objRef = findObjRef(DEBUGGEE_LOCALVAR); 171 rType = objRef.referenceType(); 172 173 // provoke the InvalidTypeException 174 for (int i=0; i<FLDS_NUM; i++) { 175 Field fld = rType.fieldByName(DEBUGGEE_FLDS[i][0]); 176 try { 177 log.display("\nTrying to set value for the field \"" 178 + fld.name() + "\"\n\tfrom the object reference \"" 179 + objRef 180 + "\"\n\tusing not matched value's type \"" 181 + objRef.getValue(rType.fieldByName(DEBUGGEE_FLDS[i][1])).type() + "\" ..."); 182 objRef.setValue(fld, 183 objRef.getValue(rType.fieldByName(DEBUGGEE_FLDS[i][1]))); 184 log.complain("TEST FAILED: expected InvalidTypeException was not thrown" 185 + "\n\twhen attempted to set value for the " 186 + fld.type() + " field \"" 187 + fld.name() + "\"\n\tfrom the debuggee's object reference \"" 188 + objRef 189 + "\"\n\tusing not matched value's type \"" 190 + objRef.getValue(rType.fieldByName(DEBUGGEE_FLDS[i][1])).type() + "\""); 191 tot_res = Consts.TEST_FAILED; 192 } catch (InvalidTypeException ie) { 193 log.display("CHECK PASSED: caught expected " + ie); 194 } catch (Exception e) { 195 e.printStackTrace(); 196 log.complain("TEST FAILED: ObjectReference.setValue(): caught unexpected " 197 + e + "\n\tinstead of expected InvalidTypeException" 198 + "\n\twhen attempted to set value for the " 199 + fld.type() + " field \"" 200 + fld.name() + "\"\n\tfrom the debuggee's object reference \"" 201 + objRef 202 + "\"\n\tusing not matched value's type \"" 203 + objRef.getValue(rType.fieldByName(DEBUGGEE_FLDS[i][1])).type() + "\""); 204 tot_res = Consts.TEST_FAILED; 205 } 206 } 207 } catch (Exception e) { 208 e.printStackTrace(); 209 log.complain("TEST FAILURE: caught unexpected exception: " + e); 210 tot_res = Consts.TEST_FAILED; 211 return quitDebuggee(); 212 } 213 214 // Finish the test 215 return quitDebuggee(); 216 } 217 findObjRef(String varName)218 private ObjectReference findObjRef(String varName) { 219 try { 220 List frames = thrRef.frames(); 221 Iterator iter = frames.iterator(); 222 while (iter.hasNext()) { 223 StackFrame stackFr = (StackFrame) iter.next(); 224 try { 225 LocalVariable locVar = stackFr.visibleVariableByName(varName); 226 227 if (locVar == null) continue; 228 229 // return reference to the debuggee class' object 230 return stackFr.thisObject(); 231 } catch(AbsentInformationException e) { 232 // this is not needed stack frame, ignoring 233 } catch(NativeMethodException ne) { 234 // current method is native, also ignoring 235 } 236 } 237 } catch (Exception e) { 238 e.printStackTrace(); 239 tot_res = Consts.TEST_FAILED; 240 throw new Failure("findObjRef: caught unexpected exception: " + e); 241 } 242 throw new Failure("findObjRef: needed debuggee's stack frame not found"); 243 } 244 quitDebuggee()245 private int quitDebuggee() { 246 if (thrRef != null) { 247 if (thrRef.isSuspended()) 248 thrRef.resume(); 249 } 250 pipe.println(COMMAND_QUIT); 251 debuggee.waitFor(); 252 int debStat = debuggee.getStatus(); 253 if (debStat != (Consts.JCK_STATUS_BASE + Consts.TEST_PASSED)) { 254 log.complain("TEST FAILED: debuggee's process finished with status: " 255 + debStat); 256 tot_res = Consts.TEST_FAILED; 257 } else 258 log.display("Debuggee's process finished with the status: " 259 + debStat); 260 261 return tot_res; 262 } 263 264 } 265