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 org.apache.harmony.luni.tests.java.io; 19 20import java.io.ByteArrayInputStream; 21import java.io.ByteArrayOutputStream; 22import java.io.IOException; 23import java.io.InputStream; 24import java.io.InvalidClassException; 25import java.io.ObjectInputStream; 26import java.io.ObjectOutputStream; 27import java.io.ObjectStreamClass; 28import java.io.ObjectStreamException; 29import java.io.OptionalDataException; 30import java.io.Serializable; 31import java.io.StreamCorruptedException; 32import java.util.ArrayList; 33 34import junit.framework.TestCase; 35 36import org.apache.harmony.testframework.serialization.SerializationTest; 37 38import tests.support.Support_ASimpleInputStream; 39import dalvik.annotation.TestLevel; 40import dalvik.annotation.TestTargetClass; 41import dalvik.annotation.TestTargetNew; 42 43@TestTargetClass(ObjectInputStream.class) 44public class ObjectInputStreamTest extends TestCase { 45 46 ObjectInputStream ois; 47 48 ObjectOutputStream oos; 49 50 ByteArrayOutputStream bao; 51 52 private final String testString = "Lorem ipsum..."; 53 54 protected void setUp() throws Exception { 55 super.setUp(); 56 oos = new ObjectOutputStream(bao = new ByteArrayOutputStream()); 57 } 58 59 @TestTargetNew( 60 level = TestLevel.PARTIAL_COMPLETE, 61 notes = "Checks ObjectStreamException and OptionalDataException.", 62 method = "readUnshared", 63 args = {} 64 ) 65 public void test_readUnshared_1() throws IOException, ClassNotFoundException { 66 oos.writeObject(testString); 67 oos.writeObject(testString); 68 oos.writeInt(42); 69 oos.close(); 70 71 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 72 try { 73 ois.readUnshared(); 74 ois.readObject(); 75 fail("Test 1: ObjectStreamException expected."); 76 } catch (ObjectStreamException e) { 77 // Expected. 78 } 79 80 try { 81 ois.readUnshared(); 82 fail("Test 2: OptionalDataException expected."); 83 } catch (OptionalDataException e) { 84 // Expected. 85 } 86 ois.close(); 87 } 88 89 /** 90 * @tests java.io.ObjectInputStream#readUnshared() 91 */ 92 @TestTargetNew( 93 level = TestLevel.PARTIAL_COMPLETE, 94 notes = "Checks StreamCorruptedException.", 95 method = "readUnshared", 96 args = {} 97 ) 98 public void test_readUnshared_2() throws IOException, ClassNotFoundException { 99 oos.close(); 100 bao.write(testString.getBytes()); 101 102 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 103 try { 104 ois.readUnshared(); 105 fail("Test 1: StreamCorruptedException expected."); 106 } catch (StreamCorruptedException e) { 107 // Expected. 108 } 109 ois.close(); 110 } 111 112 /** 113 * @tests java.io.ObjectInputStream#readUnshared() 114 */ 115 @TestTargetNew( 116 level = TestLevel.PARTIAL_COMPLETE, 117 notes = "Checks IOException.", 118 method = "readUnshared", 119 args = {} 120 ) 121 public void test_readUnshared_3() throws IOException, ClassNotFoundException { 122 bao.write(testString.getBytes()); 123 oos.close(); 124 125 Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray()); 126 ois = new ObjectInputStream(sis); 127 sis.throwExceptionOnNextUse = true; 128 try { 129 ois.readUnshared(); 130 fail("Test 1: IOException expected."); 131 } catch (IOException e) { 132 // Expected. 133 } 134 sis.throwExceptionOnNextUse = false; 135 ois.close(); 136 } 137 138 /** 139 * Micro-scenario of de/serialization of an object with non-serializable superclass. 140 * The super-constructor only should be invoked on the deserialized instance. 141 */ 142 @TestTargetNew( 143 level = TestLevel.PARTIAL_COMPLETE, 144 method = "readObject", 145 args = {} 146 ) 147 public void test_readObject_Hierarchy() throws Exception { 148 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 149 150 ObjectOutputStream oos = new ObjectOutputStream(baos); 151 oos.writeObject(new B()); 152 oos.close(); 153 154 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); 155 B b = (B) ois.readObject(); 156 ois.close(); 157 158 assertTrue("should construct super", A.list.contains(b)); 159 assertFalse("should not construct self", B.list.contains(b)); 160 assertEquals("super field A.s", A.DEFAULT, ((A)b).s); 161 assertNull("transient field B.s", b.s); 162 } 163 164 /** 165 * @tests {@link java.io.ObjectInputStream#readNewLongString()} 166 */ 167 @TestTargetNew( 168 level = TestLevel.COMPLETE, 169 notes = "Verifies serialization.", 170 method = "!SerializationSelf", 171 args = {} 172 ) 173 public void test_readNewLongString() throws Exception { 174 LongString longString = new LongString(); 175 SerializationTest.verifySelf(longString); 176 } 177 178 private static class LongString implements Serializable{ 179 private static final long serialVersionUID = 1L; 180 String lString; 181 182 public LongString() { 183 StringBuilder builder = new StringBuilder(); 184 // construct a string whose length > 64K 185 for (int i = 0; i < 65636; i++) { 186 builder.append('1'); 187 } 188 lString = builder.toString(); 189 } 190 191 @Override 192 public boolean equals(Object o) { 193 if (o == this) { 194 return true; 195 } 196 if (o instanceof LongString) { 197 LongString l = (LongString) o; 198 return l.lString.equals(l.lString); 199 } 200 return true; 201 } 202 203 @Override 204 public int hashCode() { 205 return lString.hashCode(); 206 } 207 } 208 209 static class A { 210 static final ArrayList<A> list = new ArrayList<A>(); 211 String s; 212 public static final String DEFAULT = "aaa"; 213 public A() { 214 s = DEFAULT; 215 list.add(this); 216 } 217 } 218 219 static class B extends A implements Serializable { 220 private static final long serialVersionUID = 1L; 221 static final ArrayList<A> list = new ArrayList<A>(); 222 transient String s; 223 public B() { 224 s = "bbb"; 225 list.add(this); 226 } 227 } 228 229 class OIS extends ObjectInputStream { 230 231 OIS () throws IOException { 232 super(); 233 } 234 235 void test() throws ClassNotFoundException,IOException { 236 readClassDescriptor(); 237 } 238 239 } 240 241 @TestTargetNew( 242 level = TestLevel.PARTIAL_COMPLETE, 243 method = "readClassDescriptor", 244 args = {} 245 ) 246 public void test_readClassDescriptor() throws ClassNotFoundException, IOException { 247 try { 248 new OIS().test(); 249 fail("Test 1: NullPointerException expected."); 250 } catch (NullPointerException e) { 251 // Expected. 252 } 253 } 254 255 static class TestObjectInputStream extends ObjectInputStream { 256 public TestObjectInputStream(InputStream in) throws IOException { 257 super(in); 258 } 259 260 protected Class<?> resolveClass(ObjectStreamClass desc) 261 throws IOException, ClassNotFoundException { 262 if (desc.getName().endsWith("ObjectInputStreamTest$TestClass1")) { 263 return TestClass2.class; 264 } 265 return super.resolveClass(desc); 266 } 267 } 268 269 static class TestClass1 implements Serializable { 270 private static final long serialVersionUID = 11111L; 271 int i = 0; 272 } 273 274 static class TestClass2 implements Serializable { 275 private static final long serialVersionUID = 11111L; 276 int i = 0; 277 } 278 @TestTargetNew( 279 level = TestLevel.PARTIAL_COMPLETE, 280 notes = "Checks InvalidClassException.", 281 method = "resolveClass", 282 args = {java.io.ObjectStreamClass.class} 283 ) 284 public void test_resolveClass_invalidClassName() 285 throws Exception { 286 // Regression test for HARMONY-1920 287 TestClass1 to1 = new TestClass1(); 288 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 289 ObjectOutputStream oos = new ObjectOutputStream(baos); 290 ByteArrayInputStream bais; 291 ObjectInputStream ois; 292 293 to1.i = 555; 294 oos.writeObject(to1); 295 oos.flush(); 296 byte[] bytes = baos.toByteArray(); 297 bais = new ByteArrayInputStream(bytes); 298 ois = new TestObjectInputStream(bais); 299 300 try { 301 ois.readObject(); 302 fail("Test 1: InvalidClassException expected."); 303 } catch (InvalidClassException ice) { 304 // Expected. 305 } 306 } 307} 308 309 310