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.ArrayReference.getValue; 25 26 import nsk.share.*; 27 import nsk.share.jpda.*; 28 import nsk.share.jdi.*; 29 30 import com.sun.jdi.*; 31 import java.io.*; 32 import java.util.*; 33 34 public class getvalue003 { 35 36 // exit code when test failed 37 public final static int TEST_FAILED = 2; 38 // exit code when test passed 39 public final static int TEST_PASSED = 0; 40 // shift of exit code 41 public final static int JCK_STATUS_BASE = 95; 42 43 private final static String prefix = "nsk.jdi.ArrayReference.getValue."; 44 private final static String className = "getvalue003"; 45 private final static String debuggerName = prefix + className; 46 private final static String debugeeName = debuggerName + "a"; 47 private final static String fieldToCheck = "testedObj"; 48 49 private int exitStatus; 50 private Log log; 51 private Debugee debugee; 52 private IOPipe pipe; 53 getvalue003()54 private getvalue003() { 55 log = null; 56 debugee = null; 57 pipe = null; 58 } 59 main(String argv[])60 public static void main(String argv[]) { 61 System.exit(JCK_STATUS_BASE + run(argv, System.out)); 62 } 63 run(String argv[], PrintStream out)64 public static int run(String argv[], PrintStream out) { 65 66 getvalue003 tstObj = new getvalue003(); 67 68 if ( tstObj.prepareDebugee(argv, out) ) { 69 tstObj.execTest(); 70 tstObj.disposeOfDebugee(); 71 } 72 73 if ( tstObj.exitStatus == TEST_FAILED ) 74 tstObj.complain("run:: TEST FAILED"); 75 else 76 tstObj.display("run:: TEST PASSED"); 77 return tstObj.exitStatus; 78 } 79 prepareDebugee(String argv[], PrintStream out)80 private boolean prepareDebugee(String argv[], PrintStream out) { 81 ArgumentHandler argHandler = new ArgumentHandler(argv); 82 log = new Log(out, argHandler); 83 Binder binder = new Binder(argHandler, log); 84 display("prepareDebugee:: binder created."); 85 86 debugee = binder.bindToDebugee(debugeeName); 87 log.display("prepareDebugee:: binded to debugee."); 88 pipe = debugee.createIOPipe(); 89 log.display("prepareDebugee:: pipe created."); 90 91 debugee.redirectStderr(out); 92 debugee.resume(); 93 94 String line = pipe.readln(); 95 if ( line == null ) { 96 complain("prepareDebugee:: UNEXPECTED debugee's signal - null"); 97 return false; 98 } 99 if ( !line.equals("ready") ) { 100 complain("prepareDebugee:: UNEXPECTED debugee's signal - " 101 + line); 102 return false; 103 } 104 105 display("prepareDebugee:: debugee's \"ready\" signal recieved."); 106 return true; 107 } 108 disposeOfDebugee()109 private boolean disposeOfDebugee() { 110 pipe.println("quit"); 111 debugee.waitFor(); 112 int status = debugee.getStatus(); 113 114 if ( status != JCK_STATUS_BASE ) { 115 complain("disposeOfDebugee:: UNEXPECTED Debugee's exit " 116 + "status (not " + JCK_STATUS_BASE + ") - " + status); 117 return false; 118 } 119 display("disposeOfDebugee:: expected Debugee's exit " 120 + "status - " + status); 121 return true; 122 } 123 display(String msg)124 private void display(String msg) { 125 if ( log != null ) 126 log.display("debugger> " + msg); 127 } 128 complain(String msg)129 private void complain(String msg) { 130 if ( log != null ) 131 log.complain("debugger FAILURE> " + msg); 132 } 133 execTest()134 private boolean execTest() { 135 exitStatus = TEST_FAILED; 136 137 ReferenceType refType = debugee.classByName(debugeeName); 138 if ( refType == null ) { 139 complain("eventHandler:: Class '" + debugeeName + "' not found."); 140 return false; 141 } 142 143 Field field = refType.fieldByName(fieldToCheck); 144 if ( field == null ) { 145 complain("eventHandler:: Field '" + fieldToCheck + "' not found."); 146 return false; 147 } 148 149 Value value = refType.getValue(field); 150 if ( value == null ) { 151 complain("eventHandler:: Field '" + fieldToCheck + "' not initialized."); 152 return false; 153 } 154 155 return checkObjectFields(value); 156 } 157 checkObjectFields(Value value)158 public boolean checkObjectFields(Value value) { 159 List fieldList; 160 if ( ! (value instanceof ObjectReference) ) 161 return false; 162 163 fieldList = ((ClassType)value.type()).allFields(); 164 165 // Check all array fields from debugee 166 Field field; 167 display("\ncheckObjectFields:: Tests starts >>>"); 168 for (int i = 0; i < fieldList.size(); i++) { 169 field = (Field)fieldList.get(i); 170 171 display(""); 172 display("checkObjectFields:: <" + field.name() + "> field is being " 173 + " checked."); 174 175 // Check getting of item from field-array 176 if ( !checkFieldValue((ObjectReference)value, field) ) 177 return false; 178 } 179 exitStatus = TEST_PASSED; 180 return true; 181 } 182 checkFieldValue(ObjectReference object, Field field)183 private boolean checkFieldValue(ObjectReference object, Field field) { 184 Value value; 185 ArrayReference arrayRef; 186 String fieldName = field.name(); 187 try { 188 value = object.getValue(field); 189 } catch (IllegalArgumentException e) { 190 complain("checkFieldValue:: can not get value for field " + fieldName); 191 complain("checkFieldValue:: " + e); 192 return false; 193 } 194 195 display("checkFieldValue:: ***" + fieldName + " = " + value); 196 197 boolean checkNULL = false; 198 // scaning of non-initialized arrays 199 for ( int i = 0; i < getvalue003a.NON_INIT_FIELDS.length; i++ ) 200 { 201 if ( fieldName.compareTo(getvalue003a.NON_INIT_FIELDS[i]) == 0 ) { 202 checkNULL = true; 203 break; 204 } 205 } 206 207 // checking of field value 208 if ( checkNULL ) { 209 210 // value is not null, but array has not to be initialized. 211 if ( value != null ) { 212 complain("checkFieldValue:: Value of '" + fieldName + "' is " + value 213 + ", but IndexOutOfBoundsException expected."); 214 return false; 215 216 // array is not initialized. Expected value is null 217 } else { 218 display("checkFieldValue:: Expected value is null."); 219 return true; 220 } 221 } else { 222 223 // value is null, but array has to be initialized. 224 if ( value == null ) { 225 complain("checkFieldValue:: Unexpected value of '" + fieldName 226 + "'" + value); 227 return false; 228 } 229 } 230 231 display("checkFieldValue:: *** type of " + fieldName + " = " + value.type()); 232 233 // check up type of value. it has to be ArrayType 234 if ( ! (value.type() instanceof ArrayType) ) { 235 display("checkFieldValue:: type of value is not ArrayType."); 236 return false; 237 } 238 239 // Cast to ArrayReference. All fields in debugee are 240 // arrays, so ClassCastException should not be thrown 241 return checkValue(0, fieldName, (ArrayReference )value, ((ArrayReference )value).length() + 1) && 242 checkValue(0, fieldName, (ArrayReference )value, Integer.MAX_VALUE) && 243 checkValue(0, fieldName, (ArrayReference )value, Integer.MAX_VALUE + 1); 244 } 245 checkValue(int depth, String name, ArrayReference arrayRef, long itemIndex)246 private boolean checkValue(int depth, String name, ArrayReference arrayRef, 247 long itemIndex) { 248 249 Value itemValue; 250 int length = arrayRef.length(); 251 try { 252 itemValue = arrayRef.getValue(0); 253 if ( itemValue != null ) { 254 if ( itemValue.type() instanceof ArrayType ) { 255 256 // itemValue has array type, check it by the same way 257 long index = (length + 1 != itemIndex) ? itemIndex : 258 ((ArrayReference )itemValue).length() + 1; 259 if ( !checkValue(depth + 1, name, (ArrayReference )itemValue, index) ) 260 return false; 261 } 262 } 263 itemValue = arrayRef.getValue((int)itemIndex); 264 if ( itemIndex > length || itemIndex < 0 ) { 265 complain("checkValue[" + depth + "]:: " + name + "[" + itemIndex + "] = " 266 + itemValue + ", but IndexOutOfBoundsException expected."); 267 return false; 268 } 269 270 } catch (IndexOutOfBoundsException e) { 271 /* Index is always out of bounds, so 272 * IndexOutOfBoundsException is expected 273 */ 274 display("checkValue[" + depth + "]:: expected IndexOutOfBoundsException " + 275 "is thrown for " + itemIndex + " item."); 276 } catch (Exception e) { 277 complain("checkValue[" + depth + "]:: Unexpected exception: " + e); 278 return false; 279 } 280 return true; 281 } 282 283 } 284