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 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package tests.api.java.io; 19 20import dalvik.annotation.TestTargets; 21import dalvik.annotation.TestLevel; 22import dalvik.annotation.TestTargetNew; 23import dalvik.annotation.TestTargetClass; 24 25import java.io.ObjectInputStream; 26 27import tests.support.Support_GetPutFields; 28import tests.support.Support_GetPutFieldsDefaulted; 29 30 31/** 32 * Tests the methods of {@code ObjectInputStream.GetField}. Three things make 33 * this class somewhat difficult to test: 34 * <ol> 35 * <li>It is a completely abstract class; none of the methods is implemented in 36 * {@code ObjectInputStream.GetField}.</li> 37 * <li>There is no public class that implements 38 * {@code ObjectInputStream.GetField}. The only way to get an implementation is 39 * by calling {@code ObjectInputStream.getFields()}.</li> 40 * <li>Invoking {@code ObjectOutputStream.getFields()} only works from within 41 * the private {@code readObject(ObjectInputStream)} method of a class that 42 * implements {@code Serializable}; an exception is thrown otherwise.</li> 43 * </ol> 44 * <p> 45 * Given these restrictions, an indirect approach is used to test 46 * {@code ObjectInputStream.GetField}: Three serializable helper classes in 47 * package {@code tests.support} ({@code Support_GetPutFields}, 48 * {@code Support_GetPutFieldsDeprecated} and 49 * {@code Support_GetPutFieldsDefaulted}) implement 50 * {@code readObject(ObjectInputStream)} to read data from an input stream. 51 * This input stream in turn reads from one of the corresponding files 52 * ({@code testFields.ser}, {@code testFieldsDeprecated.ser} and 53 * {@code testFieldsDefaulted.ser}) that have been created with 54 * {@code tests.util.FieldTestFileGenerator} on a reference platform. 55 * </p> 56 * <p> 57 * The test method in this class expects to find the reference files as a 58 * resource stored at {@code tests/api/java/io}. 59 * </p> 60 */ 61@TestTargetClass(ObjectInputStream.GetField.class) 62public class ObjectInputStreamGetFieldTest extends junit.framework.TestCase { 63 64 private ObjectInputStream ois = null; 65 66 private final String FILENAME = 67 "/tests/api/java/io/testFields.ser"; 68 private final String DEFAULTED_FILENAME = 69 "/tests/api/java/io/testFieldsDefaulted.ser"; 70 71 public boolean booleanValue; 72 public byte byteValue; 73 public char charValue; 74 public int intValue; 75 76 77 @TestTargets({ 78 @TestTargetNew( 79 level = TestLevel.PARTIAL_COMPLETE, 80 notes = "Verifies the get(String, X) methods with valid arguments.", 81 method = "get", 82 args = {java.lang.String.class, boolean.class} 83 ), 84 @TestTargetNew( 85 level = TestLevel.PARTIAL_COMPLETE, 86 notes = "Verifies the get(String, X) methods with valid arguments.", 87 method = "get", 88 args = {java.lang.String.class, byte.class} 89 ), 90 @TestTargetNew( 91 level = TestLevel.PARTIAL_COMPLETE, 92 notes = "Verifies the get(String, X) methods with valid arguments.", 93 method = "get", 94 args = {java.lang.String.class, char.class} 95 ), 96 @TestTargetNew( 97 level = TestLevel.PARTIAL_COMPLETE, 98 notes = "Verifies the get(String, X) methods with valid arguments.", 99 method = "get", 100 args = {java.lang.String.class, double.class} 101 ), 102 @TestTargetNew( 103 level = TestLevel.PARTIAL_COMPLETE, 104 notes = "Verifies the get(String, X) methods with valid arguments.", 105 method = "get", 106 args = {java.lang.String.class, float.class} 107 ), 108 @TestTargetNew( 109 level = TestLevel.PARTIAL_COMPLETE, 110 notes = "Verifies the get(String, X) methods with valid arguments.", 111 method = "get", 112 args = {java.lang.String.class, int.class} 113 ), 114 @TestTargetNew( 115 level = TestLevel.PARTIAL_COMPLETE, 116 notes = "Verifies the get(String, X) methods with valid arguments.", 117 method = "get", 118 args = {java.lang.String.class, long.class} 119 ), 120 @TestTargetNew( 121 level = TestLevel.PARTIAL_COMPLETE, 122 notes = "Verifies the get(String, X) methods with valid arguments.", 123 method = "get", 124 args = {java.lang.String.class, java.lang.Object.class} 125 ), 126 @TestTargetNew( 127 level = TestLevel.PARTIAL_COMPLETE, 128 notes = "Verifies the get(String, X) methods with valid arguments.", 129 method = "get", 130 args = {java.lang.String.class, short.class} 131 ) 132 }) 133 public void test_get() throws Exception { 134 135 initOis(FILENAME); 136 Support_GetPutFields object = (Support_GetPutFields) ois.readObject(); 137 Support_GetPutFields newObject = new Support_GetPutFields(); 138 newObject.initTestValues(); 139 140 assertTrue("Test 1: The object read from the reference file does " + 141 "not match a locally created instance of the same class.", 142 object.equals(newObject)); 143 144 initOis(DEFAULTED_FILENAME); 145 Support_GetPutFieldsDefaulted defaulted = 146 (Support_GetPutFieldsDefaulted) ois.readObject(); 147 Support_GetPutFieldsDefaulted newDefaulted = 148 new Support_GetPutFieldsDefaulted(); 149 newDefaulted.initTestValues(); 150 151 assertTrue("Test 2: The object read from the reference file does " + 152 "not match a locally created instance of the same class.", 153 defaulted.equals(newDefaulted)); 154 155 // Executing the same procedure against the file created with the 156 // deprecated ObjectOutputStream.PutFields.write(ObjectOutput) method 157 // is not possible since there is no corresponding read(ObjectInput) 158 // method. When trying to do it as in tests 1 and 2, a 159 // NullPointerException is thrown. 160 } 161 162 163 @TestTargetNew( 164 level = TestLevel.COMPLETE, 165 notes = "Verifies defaulted(String).", 166 method = "defaulted", 167 args = {java.lang.String.class} 168 ) 169 public void test_defaultedLjava_lang_String() throws Exception { 170 171 initOis(FILENAME); 172 Support_GetPutFields object = (Support_GetPutFields) ois.readObject(); 173 ObjectInputStream.GetField fields = object.getField; 174 175 try { 176 fields.defaulted("noField"); 177 fail("IllegalArgumentException expected."); 178 } catch (IllegalArgumentException e) {} 179 180 assertFalse("The field longValue should not be defaulted.", 181 fields.defaulted("longValue")); 182 183 // Now the same with defaulted fields. 184 initOis(DEFAULTED_FILENAME); 185 Support_GetPutFieldsDefaulted defaultedObject = 186 (Support_GetPutFieldsDefaulted) ois.readObject(); 187 fields = defaultedObject.getField; 188 189 assertTrue("The field longValue should be defaulted.", 190 fields.defaulted("longValue")); 191 192 } 193 194 195 @TestTargets({ 196 @TestTargetNew( 197 level = TestLevel.PARTIAL_COMPLETE, 198 notes = "Verifies the get(String, X) methods with invalid arguments.", 199 method = "get", 200 args = {java.lang.String.class, boolean.class} 201 ), 202 @TestTargetNew( 203 level = TestLevel.PARTIAL_COMPLETE, 204 notes = "Verifies the get(String, X) methods with invalid arguments.", 205 method = "get", 206 args = {java.lang.String.class, byte.class} 207 ), 208 @TestTargetNew( 209 level = TestLevel.PARTIAL_COMPLETE, 210 notes = "Verifies the get(String, X) methods with invalid arguments.", 211 method = "get", 212 args = {java.lang.String.class, char.class} 213 ), 214 @TestTargetNew( 215 level = TestLevel.PARTIAL_COMPLETE, 216 notes = "Verifies the get(String, X) methods with invalid arguments.", 217 method = "get", 218 args = {java.lang.String.class, double.class} 219 ), 220 @TestTargetNew( 221 level = TestLevel.PARTIAL_COMPLETE, 222 notes = "Verifies the get(String, X) methods with invalid arguments.", 223 method = "get", 224 args = {java.lang.String.class, float.class} 225 ), 226 @TestTargetNew( 227 level = TestLevel.PARTIAL_COMPLETE, 228 notes = "Verifies the get(String, X) methods with invalid arguments.", 229 method = "get", 230 args = {java.lang.String.class, int.class} 231 ), 232 @TestTargetNew( 233 level = TestLevel.PARTIAL_COMPLETE, 234 notes = "Verifies the get(String, X) methods with invalid arguments.", 235 method = "get", 236 args = {java.lang.String.class, long.class} 237 ), 238 @TestTargetNew( 239 level = TestLevel.PARTIAL_COMPLETE, 240 notes = "Verifies the get(String, X) methods with invalid arguments.", 241 method = "get", 242 args = {java.lang.String.class, java.lang.Object.class} 243 ), 244 @TestTargetNew( 245 level = TestLevel.PARTIAL_COMPLETE, 246 notes = "Verifies the get(String, X) methods with invalid arguments.", 247 method = "get", 248 args = {java.lang.String.class, short.class} 249 ) 250 }) 251 public void test_getException() throws Exception { 252 253 initOis(FILENAME); 254 Support_GetPutFields object = (Support_GetPutFields) ois.readObject(); 255 ObjectInputStream.GetField fields = object.getField; 256 257 // Methods called with invalid field name. 258 try { 259 fields.get("noValue", false); 260 fail("IllegalArgumentException expected for not existing name " + 261 "argument in get(String, boolean)."); 262 } catch (IllegalArgumentException e) {} 263 264 try { 265 fields.get("noValue", (byte) 0); 266 fail("IllegalArgumentException expected for not existing name " + 267 "argument in get(String, byte)."); 268 } catch (IllegalArgumentException e) {} 269 270 try { 271 fields.get("noValue", (char) 0); 272 fail("IllegalArgumentException expected for not existing name " + 273 "argument in get(String, char)."); 274 } catch (IllegalArgumentException e) {} 275 276 try { 277 fields.get("noValue", 0.0); 278 fail("IllegalArgumentException expected for not existing name " + 279 "argument in get(String, double)."); 280 } catch (IllegalArgumentException e) {} 281 282 try { 283 fields.get("noValue", 0.0f); 284 fail("IllegalArgumentException expected for not existing name " + 285 "argument in get(String, float)."); 286 } catch (IllegalArgumentException e) {} 287 288 try { 289 fields.get("noValue", (long) 0); 290 fail("IllegalArgumentException expected for not existing name " + 291 "argument in get(String, long)."); 292 } catch (IllegalArgumentException e) {} 293 294 try { 295 fields.get("noValue", 0); 296 fail("IllegalArgumentException expected for not existing name " + 297 "argument in get(String, int)."); 298 } catch (IllegalArgumentException e) {} 299 300 try { 301 fields.get("noValue", new Object()); 302 fail("IllegalArgumentException expected for not existing name " + 303 "argument in get(String, Object)."); 304 } catch (IllegalArgumentException e) {} 305 306 try { 307 fields.get("noValue", (short) 0); 308 fail("IllegalArgumentException expected for not existing name " + 309 "argument in get(String, short)."); 310 } catch (IllegalArgumentException e) {} 311 312 // Methods called with correct field name but non-matching type. 313 try { 314 fields.get("byteValue", false); 315 fail("IllegalArgumentException expected for non-matching name " + 316 "and type arguments in get(String, boolean)."); 317 } catch (IllegalArgumentException e) {} 318 319 try { 320 fields.get("booleanValue", (byte) 0); 321 fail("IllegalArgumentException expected for non-matching name " + 322 "and type arguments in get(String, byte)."); 323 } catch (IllegalArgumentException e) {} 324 325 try { 326 fields.get("intValue", (char) 0); 327 fail("IllegalArgumentException expected for non-matching name " + 328 "and type arguments in get(String, char)."); 329 } catch (IllegalArgumentException e) {} 330 331 try { 332 fields.get("floatValue", 0.0); 333 fail("IllegalArgumentException expected for non-matching name " + 334 "and type arguments in get(String, double)."); 335 } catch (IllegalArgumentException e) {} 336 337 try { 338 fields.get("doubleValue", 0.0f); 339 fail("IllegalArgumentException expected for non-matching name " + 340 "and type arguments in get(String, float)."); 341 } catch (IllegalArgumentException e) {} 342 343 try { 344 fields.get("intValue", (long) 0); 345 fail("IllegalArgumentException expected for non-matching name " + 346 "and type arguments in get(String, long)."); 347 } catch (IllegalArgumentException e) {} 348 349 try { 350 fields.get("shortValue", 0); 351 fail("IllegalArgumentException expected for non-matching name " + 352 "and type arguments in get(String, int)."); 353 } catch (IllegalArgumentException e) {} 354 355 try { 356 fields.get("booleanValue", new Object()); 357 fail("IllegalArgumentException expected for non-matching name " + 358 "and type arguments in get(String, Object)."); 359 } catch (IllegalArgumentException e) {} 360 361 try { 362 fields.get("longValue", (short) 0); 363 fail("IllegalArgumentException expected for non-matching name " + 364 "and type arguments in get(String, short)."); 365 } catch (IllegalArgumentException e) {} 366 } 367 368 369 @TestTargetNew( 370 level = TestLevel.COMPLETE, 371 notes = "Verifies that getObjectStreamClass() does not return null.", 372 method = "getObjectStreamClass", 373 args = {} 374 ) 375 public void test_getObjectStreamClass() throws Exception { 376 377 initOis(FILENAME); 378 Support_GetPutFields object = (Support_GetPutFields) ois.readObject(); 379 assertNotNull("Return value of getObjectStreamClass() should not be null.", 380 object.getField.getObjectStreamClass()); 381 } 382 383 384 private void initOis(String fileName) throws Exception { 385 if (ois != null) { 386 ois.close(); 387 } 388 ois = new ObjectInputStream( 389 getClass().getResourceAsStream(fileName)); 390 } 391 392 protected void tearDown() throws Exception { 393 394 if (ois != null) { 395 ois.close(); 396 } 397 super.tearDown(); 398 } 399 400} 401