SerializationStressTest.java revision cc05ad238516f1303687aba4a978e24e57c0c07a
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.ByteArrayInputStream;
26import java.io.ByteArrayOutputStream;
27import java.io.DataInputStream;
28import java.io.FileInputStream;
29import java.io.FileOutputStream;
30import java.io.IOException;
31import java.io.InputStream;
32import java.io.InvalidObjectException;
33import java.io.NotActiveException;
34import java.io.ObjectInputStream;
35import java.io.ObjectOutputStream;
36import java.io.ObjectStreamClass;
37import java.io.ObjectStreamException;
38import java.io.Serializable;
39import java.io.StreamCorruptedException;
40import java.io.WriteAbortedException;
41import java.security.Permission;
42import java.security.PermissionCollection;
43import java.util.ArrayList;
44import java.util.Arrays;
45import java.util.Calendar;
46import java.util.GregorianCalendar;
47import java.util.HashMap;
48import java.util.HashSet;
49import java.util.Hashtable;
50import java.util.IdentityHashMap;
51import java.util.LinkedHashMap;
52import java.util.LinkedHashSet;
53import java.util.LinkedList;
54import java.util.List;
55import java.util.Map;
56import java.util.PropertyPermission;
57import java.util.Set;
58import java.util.SimpleTimeZone;
59import java.util.SortedMap;
60import java.util.SortedSet;
61import java.util.TimeZone;
62import java.util.TreeMap;
63import java.util.TreeSet;
64import java.util.Vector;
65
66/**
67 * Automated Test Suite for class java.io.ObjectOutputStream
68 *
69 */
70@TestTargetClass(Serializable.class)
71public class SerializationStressTest extends junit.framework.TestCase implements
72        Serializable {
73
74    // protected static final String MODE_XLOAD = "xload";
75
76    // protected static final String MODE_XDUMP = "xdump";
77
78    static final String FOO = "foo";
79
80    static final String MSG_TEST_FAILED = "Failed to write/read/assertion checking: ";
81
82    protected static final boolean DEBUG = false;
83
84    protected static boolean xload = false;
85
86    protected static boolean xdump = false;
87
88    protected static String xFileName = null;
89
90    protected transient int dumpCount = 0;
91
92    protected transient ObjectInputStream ois;
93
94    protected transient ObjectOutputStream oos;
95
96    protected transient ByteArrayOutputStream bao;
97
98    // -----------------------------------------------------------------------------------
99
100    private static class ObjectInputStreamSubclass extends ObjectInputStream {
101        private Vector resolvedClasses = new Vector();
102
103        public ObjectInputStreamSubclass(InputStream in) throws IOException,
104                StreamCorruptedException {
105            super(in);
106        }
107
108        public Class resolveClass(ObjectStreamClass osClass)
109                throws IOException, ClassNotFoundException {
110            Class result = super.resolveClass(osClass);
111            resolvedClasses.addElement(result);
112            return result;
113        }
114
115        public Class[] resolvedClasses() {
116            return (Class[]) resolvedClasses.toArray(new Class[resolvedClasses
117                    .size()]);
118        }
119    }
120
121    static final Map TABLE = new Hashtable();
122
123    static final Map MAP = new HashMap();
124
125    static final SortedMap TREE = new TreeMap();
126
127    static final LinkedHashMap LINKEDMAP = new LinkedHashMap();
128
129    static final LinkedHashSet LINKEDSET = new LinkedHashSet();
130
131    static final IdentityHashMap IDENTITYMAP = new IdentityHashMap();
132
133    static final List ALIST = Arrays.asList(new String[] { "a", "list", "of",
134            "strings" });
135
136    static final List LIST = new ArrayList(ALIST);
137
138    static final Set SET = new HashSet(Arrays.asList(new String[] { "one",
139            "two", "three" }));
140
141    static final Permission PERM = new PropertyPermission("file.encoding",
142            "write");
143
144    static final PermissionCollection PERMCOL = PERM.newPermissionCollection();
145
146    static final SortedSet SORTSET = new TreeSet(Arrays.asList(new String[] {
147            "one", "two", "three" }));
148
149    static final java.text.DateFormat DATEFORM = java.text.DateFormat
150            .getInstance();
151
152    static final java.text.ChoiceFormat CHOICE = new java.text.ChoiceFormat(
153            "1#one|2#two|3#three");
154
155    static final java.text.NumberFormat NUMBERFORM = java.text.NumberFormat
156            .getInstance();
157
158    static final java.text.MessageFormat MESSAGE = new java.text.MessageFormat(
159            "the time: {0,time} and date {0,date}");
160
161    static final LinkedList LINKEDLIST = new LinkedList(Arrays
162            .asList(new String[] { "a", "linked", "list", "of", "strings" }));
163
164    static final SimpleTimeZone TIME_ZONE = new SimpleTimeZone(3600000,
165            "S-TEST");
166
167    static final Calendar CALENDAR = new GregorianCalendar(TIME_ZONE);
168
169    static {
170        TABLE.put("one", "1");
171        TABLE.put("two", "2");
172        TABLE.put("three", "3");
173        MAP.put("one", "1");
174        MAP.put("two", "2");
175        MAP.put("three", "3");
176        LINKEDMAP.put("one", "1");
177        LINKEDMAP.put("two", "2");
178        LINKEDMAP.put("three", "3");
179        IDENTITYMAP.put("one", "1");
180        IDENTITYMAP.put("two", "2");
181        IDENTITYMAP.put("three", "3");
182        LINKEDSET.add("one");
183        LINKEDSET.add("two");
184        LINKEDSET.add("three");
185        TREE.put("one", "1");
186        TREE.put("two", "2");
187        TREE.put("three", "3");
188        PERMCOL.add(PERM);
189        // To make sure they all use the same Calendar
190        CALENDAR.setTimeZone(new SimpleTimeZone(0, "GMT"));
191        CALENDAR.set(1999, Calendar.JUNE, 23, 15, 47, 13);
192        CALENDAR.set(Calendar.MILLISECOND, 553);
193        DATEFORM.setCalendar(CALENDAR);
194        java.text.DateFormatSymbols symbols = new java.text.DateFormatSymbols();
195        symbols.setZoneStrings(new String[][] { { "a", "b", "c", "d" },
196                { "e", "f", "g", "h" } });
197        ((java.text.SimpleDateFormat) DATEFORM).setDateFormatSymbols(symbols);
198        DATEFORM.setNumberFormat(new java.text.DecimalFormat("#.#;'-'#.#"));
199        DATEFORM.setTimeZone(TimeZone.getTimeZone("EST"));
200        ((java.text.DecimalFormat) NUMBERFORM).applyPattern("#.#;'-'#.#");
201        MESSAGE.setFormat(0, DATEFORM);
202        MESSAGE.setFormat(1, DATEFORM);
203    }
204
205    public SerializationStressTest() {
206    }
207
208    public SerializationStressTest(String name) {
209        super(name);
210    }
211
212    public String getDumpName() {
213        return getName() + dumpCount;
214    }
215
216    protected void dump(Object o) throws IOException, ClassNotFoundException {
217        if (dumpCount > 0)
218            setUp();
219        // Dump the object
220        try {
221            oos.writeObject(o);
222        } finally {
223            oos.close();
224        }
225    }
226
227    protected Object dumpAndReload(Object o) throws IOException,
228            ClassNotFoundException {
229        dump(o);
230        return reload();
231    }
232
233    protected InputStream loadStream() throws IOException {
234        // Choose the load stream
235        if (xload || xdump) {
236            // Load from pre-existing file
237            return new FileInputStream(xFileName + "-" + getDumpName() + ".ser");
238        } else {
239            // Just load from memory, we dumped to memory
240            return new ByteArrayInputStream(bao.toByteArray());
241        }
242    }
243
244    protected Object reload() throws IOException, ClassNotFoundException {
245        ois = new ObjectInputStream(loadStream());
246        dumpCount++;
247        try {
248            return ois.readObject();
249        } finally {
250            ois.close();
251        }
252    }
253
254    /**
255     * Sets up the fixture, for example, open a network connection. This method
256     * is called before a test is executed.
257     */
258    protected void setUp() {
259        try {
260            if (xdump) {
261                oos = new ObjectOutputStream(new FileOutputStream(xFileName
262                        + "-" + getDumpName() + ".ser"));
263            } else {
264                oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
265            }
266        } catch (Exception e) {
267            fail("Exception thrown during setup : " + e.getMessage());
268        }
269    }
270
271    /**
272     * Tears down the fixture, for example, close a network connection. This
273     * method is called after a test is executed.
274     */
275    protected void tearDown() {
276        if (oos != null) {
277            try {
278                oos.close();
279            } catch (Exception e) {
280            }
281        }
282    }
283
284    @TestTargetNew(
285        level = TestLevel.COMPLETE,
286        notes = "Verifies serialization.",
287        method = "!Serialization",
288        args = {}
289    )
290    public void test_1_Constructor() {
291        // Test for method java.io.ObjectOutputStream(java.io.OutputStream)
292
293        try {
294            oos.close();
295            oos = new ObjectOutputStream(new ByteArrayOutputStream());
296            oos.close();
297        } catch (Exception e) {
298            fail("Failed to create ObjectOutputStream : " + e.getMessage());
299        }
300    }
301
302    @TestTargetNew(
303        level = TestLevel.COMPLETE,
304        notes = "Verifies serialization.",
305        method = "!Serialization",
306        args = {}
307    )
308    public void test_2_close() {
309        // Test for method void java.io.ObjectOutputStream.close()
310        try {
311            oos.close();
312            oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
313            oos.close();
314            oos.writeChar('T');
315            oos.writeObject(FOO);
316            // Writing to a closed stream does not cause problems. This is
317            // the expected behavior
318        } catch (IOException e) {
319            fail("Operation on closed stream threw IOException : "
320                    + e.getMessage());
321        }
322    }
323
324    @TestTargetNew(
325        level = TestLevel.COMPLETE,
326        notes = "Verifies serialization.",
327        method = "!Serialization",
328        args = {}
329    )
330    public void test_3_defaultWriteObject() {
331        // Test for method void java.io.ObjectOutputStream.defaultWriteObject()
332
333        try {
334            oos.defaultWriteObject();
335        } catch (NotActiveException e) {
336            // Correct
337            return;
338        } catch (IOException e) {
339        }
340        fail(
341                "Failed to throw NotActiveException when invoked outside readObject");
342    }
343
344    @TestTargetNew(
345        level = TestLevel.COMPLETE,
346        notes = "Verifies serialization.",
347        method = "!Serialization",
348        args = {}
349    )
350    public void test_4_flush() {
351        // Test for method void java.io.ObjectOutputStream.flush()
352        try {
353            oos.close();
354            oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
355            int size = bao.size();
356            oos.writeByte(127);
357            assertTrue("Data flushed already", bao.size() == size);
358            oos.flush();
359            assertTrue("Failed to flush data", bao.size() > size);
360            // we don't know how many bytes are actually written for 1 byte,
361            // so we test > <before>
362            oos.close();
363            oos = null;
364        } catch (IOException e) {
365            fail("IOException serializing data : " + e.getMessage());
366        }
367    }
368
369    @TestTargetNew(
370        level = TestLevel.COMPLETE,
371        notes = "Verifies serialization.",
372        method = "!Serialization",
373        args = {}
374    )
375    public void test_5_reset() {
376        // Test for method void java.io.ObjectOutputStream.reset()
377        try {
378            String o = "HelloWorld";
379            oos.writeObject(o);
380            oos.writeObject(o);
381            oos.reset();
382            oos.writeObject(o);
383            ois = new ObjectInputStream(loadStream());
384            ois.close();
385        } catch (IOException e) {
386            fail("IOException serializing data : " + e.getMessage());
387        }
388    }
389
390    @TestTargetNew(
391        level = TestLevel.COMPLETE,
392        notes = "Verifies serialization.",
393        method = "!Serialization",
394        args = {}
395    )
396    public void test_6_write() {
397        // Test for method void java.io.ObjectOutputStream.write(byte [], int,
398        // int)
399        try {
400            byte[] buf = new byte[255];
401            byte[] output = new byte[255];
402            for (int i = 0; i < output.length; i++)
403                output[i] = (byte) i;
404            oos.write(output, 0, output.length);
405            oos.close();
406            ois = new ObjectInputStream(loadStream());
407            ois.readFully(buf);
408            ois.close();
409            for (int i = 0; i < output.length; i++)
410                if (buf[i] != output[i])
411                    fail("Read incorrect byte: " + i);
412        } catch (IOException e) {
413            fail("IOException serializing data : " + e.getMessage());
414        }
415    }
416
417    @TestTargetNew(
418        level = TestLevel.COMPLETE,
419        notes = "Verifies serialization.",
420        method = "!Serialization",
421        args = {}
422    )
423    public void test_6a_write() {
424        // Test for method void java.io.ObjectOutputStream.write(byte [], int,
425        // int)
426        try {
427            byte[] buf = new byte[256];
428            byte[] output = new byte[256];
429            for (int i = 0; i < output.length; i++)
430                output[i] = (byte) (i & 0xff);
431            oos.write(output, 0, output.length);
432            oos.close();
433            ois = new ObjectInputStream(loadStream());
434            ois.readFully(buf);
435            ois.close();
436            for (int i = 0; i < output.length; i++)
437                if (buf[i] != output[i])
438                    fail("Read incorrect byte: " + i);
439        } catch (IOException e) {
440            fail("IOException serializing data : " + e.getMessage());
441        }
442    }
443
444    @TestTargetNew(
445        level = TestLevel.COMPLETE,
446        notes = "Verifies serialization.",
447        method = "!Serialization",
448        args = {}
449    )
450    public void test_7_write() {
451        // Test for method void java.io.ObjectOutputStream.write(int)
452        try {
453            byte[] buf = new byte[10];
454            oos.write('T');
455            oos.close();
456            ois = new ObjectInputStream(loadStream());
457            assertEquals("Read incorrect byte", 'T', ois.read());
458            ois.close();
459        } catch (IOException e) {
460            fail("IOException serializing data : " + e.getMessage());
461        }
462    }
463
464    @TestTargetNew(
465        level = TestLevel.COMPLETE,
466        notes = "Verifies serialization.",
467        method = "!Serialization",
468        args = {}
469    )
470    public void test_8_write() {
471        // Test for method void java.io.ObjectOutputStream.write(byte [])
472        try {
473            byte[] buf = new byte[10];
474            oos.write("HelloWorld".getBytes());
475            oos.close();
476            ois = new ObjectInputStream(loadStream());
477            ois.read(buf, 0, 10);
478            ois.close();
479            assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0, 10)
480                    );
481        } catch (IOException e) {
482            fail("IOException serializing data : " + e.getMessage());
483        }
484    }
485
486    @TestTargetNew(
487        level = TestLevel.COMPLETE,
488        notes = "Verifies serialization.",
489        method = "!Serialization",
490        args = {}
491    )
492    public void test_9_writeBoolean() {
493        // Test for method void java.io.ObjectOutputStream.writeBoolean(boolean)
494        try {
495            oos.writeBoolean(true);
496            oos.close();
497            ois = new ObjectInputStream(loadStream());
498            assertTrue("Wrote incorrect byte value", ois.readBoolean());
499        } catch (IOException e) {
500            fail("IOException serializing data : " + e.getMessage());
501        }
502    }
503
504    @TestTargetNew(
505        level = TestLevel.COMPLETE,
506        notes = "Verifies serialization.",
507        method = "!Serialization",
508        args = {}
509    )
510    public void test_10_writeByte() {
511        // Test for method void java.io.ObjectOutputStream.writeByte(int)
512        try {
513            oos.writeByte(127);
514            oos.close();
515            ois = new ObjectInputStream(loadStream());
516            assertEquals("Wrote incorrect byte value", 127, ois.readByte());
517        } catch (IOException e) {
518            fail("IOException serializing data : " + e.getMessage());
519        }
520    }
521
522    @TestTargetNew(
523        level = TestLevel.COMPLETE,
524        notes = "Verifies serialization.",
525        method = "!Serialization",
526        args = {}
527    )
528    public void test_11_writeBytes() {
529        // Test for method void
530        // java.io.ObjectOutputStream.writeBytes(java.lang.String)
531        try {
532            byte[] buf = new byte[10];
533            oos.writeBytes("HelloWorld");
534            oos.close();
535            ois = new ObjectInputStream(loadStream());
536            ois.readFully(buf);
537            ois.close();
538            assertEquals("Wrote incorrect bytes value", "HelloWorld", new String(buf, 0, 10)
539                    );
540        } catch (IOException e) {
541            fail("IOException serializing data : " + e.getMessage());
542        }
543    }
544
545    @TestTargetNew(
546        level = TestLevel.COMPLETE,
547        notes = "Verifies serialization.",
548        method = "!Serialization",
549        args = {}
550    )
551    public void test_12_writeChar() {
552        // Test for method void java.io.ObjectOutputStream.writeChar(int)
553        try {
554            oos.writeChar('T');
555            oos.close();
556            ois = new ObjectInputStream(loadStream());
557            assertEquals("Wrote incorrect char value", 'T', ois.readChar());
558        } catch (IOException e) {
559            fail("IOException serializing data : " + e.getMessage());
560        }
561    }
562
563    @TestTargetNew(
564        level = TestLevel.COMPLETE,
565        notes = "Verifies serialization.",
566        method = "!Serialization",
567        args = {}
568    )
569    public void test_13_writeChars() {
570        // Test for method void
571        // java.io.ObjectOutputStream.writeChars(java.lang.String)
572        try {
573            int avail = 0;
574            char[] buf = new char[10];
575            oos.writeChars("HelloWorld");
576            oos.close();
577            ois = new ObjectInputStream(loadStream());
578            // Number of prim data bytes in stream / 2 to give char index
579            avail = ois.available() / 2;
580            for (int i = 0; i < avail; ++i)
581                buf[i] = ois.readChar();
582            ois.close();
583            assertEquals("Wrote incorrect chars", "HelloWorld", new String(buf, 0, 10)
584                    );
585        } catch (IOException e) {
586            fail("IOException serializing data : " + e.getMessage());
587        }
588    }
589
590    @TestTargetNew(
591        level = TestLevel.COMPLETE,
592        notes = "Verifies serialization.",
593        method = "!Serialization",
594        args = {}
595    )
596    public void test_14_writeDouble() {
597        // Test for method void java.io.ObjectOutputStream.writeDouble(double)
598        try {
599            oos.writeDouble(Double.MAX_VALUE);
600            oos.close();
601            ois = new ObjectInputStream(loadStream());
602            assertTrue("Wrote incorrect double value",
603                    ois.readDouble() == Double.MAX_VALUE);
604        } catch (IOException e) {
605            fail("IOException serializing data : " + e.getMessage());
606        }
607    }
608
609    @TestTargetNew(
610        level = TestLevel.COMPLETE,
611        notes = "Verifies serialization.",
612        method = "!Serialization",
613        args = {}
614    )
615    public void test_15_writeFloat() {
616        // Test for method void java.io.ObjectOutputStream.writeFloat(float)
617        try {
618            oos.writeFloat(Float.MAX_VALUE);
619            oos.close();
620            ois = new ObjectInputStream(loadStream());
621            assertTrue("Wrote incorrect double value",
622                    ois.readFloat() == Float.MAX_VALUE);
623            ois.close();
624            ois = null;
625        } catch (IOException e) {
626            fail("IOException serializing data : " + e.getMessage());
627        }
628    }
629
630    @TestTargetNew(
631        level = TestLevel.COMPLETE,
632        notes = "Verifies serialization.",
633        method = "!Serialization",
634        args = {}
635    )
636    public void test_16_writeInt() {
637        // Test for method void java.io.ObjectOutputStream.writeInt(int)
638        try {
639            oos.writeInt(Integer.MAX_VALUE);
640            oos.close();
641            ois = new ObjectInputStream(loadStream());
642            assertTrue("Wrote incorrect double value",
643                    ois.readInt() == Integer.MAX_VALUE);
644            ois.close();
645        } catch (IOException e) {
646            fail("IOException serializing data : " + e.getMessage());
647        }
648    }
649
650    @TestTargetNew(
651        level = TestLevel.COMPLETE,
652        notes = "Verifies serialization.",
653        method = "!Serialization",
654        args = {}
655    )
656    public void test_17_writeLong() {
657        // Test for method void java.io.ObjectOutputStream.writeLong(long)
658        try {
659            oos.writeLong(Long.MAX_VALUE);
660            oos.close();
661            ois = new ObjectInputStream(loadStream());
662            assertTrue("Wrote incorrect double value",
663                    ois.readLong() == Long.MAX_VALUE);
664        } catch (IOException e) {
665            fail("IOException serializing data : " + e.getMessage());
666        }
667    }
668
669    @TestTargetNew(
670        level = TestLevel.COMPLETE,
671        notes = "Verifies serialization.",
672        method = "!Serialization",
673        args = {}
674    )
675    public void test_19_writeShort() {
676        // Test for method void java.io.ObjectOutputStream.writeShort(int)
677        try {
678            oos.writeShort(127);
679            oos.close();
680            ois = new ObjectInputStream(loadStream());
681            assertEquals("Wrote incorrect short value", 127, ois.readShort());
682        } catch (IOException e) {
683            fail("IOException serializing data : " + e.getMessage());
684        }
685    }
686
687    @TestTargetNew(
688        level = TestLevel.COMPLETE,
689        notes = "Verifies serialization.",
690        method = "!Serialization",
691        args = {}
692    )
693    public void test_20_writeUTF() {
694        // Test for method void
695        // java.io.ObjectOutputStream.writeUTF(java.lang.String)
696        try {
697            oos.writeUTF("HelloWorld");
698            oos.close();
699            ois = new ObjectInputStream(loadStream());
700            assertEquals("Wrote incorrect UTF value",
701                    "HelloWorld", ois.readUTF());
702        } catch (IOException e) {
703            fail("IOException serializing data : " + e.getMessage());
704        }
705    }
706
707    @TestTargetNew(
708        level = TestLevel.COMPLETE,
709        notes = "Verifies serialization.",
710        method = "!Serialization",
711        args = {}
712    )
713    public void test_25_available() {
714        try {
715            oos.writeObject(FOO);
716            oos.writeObject(FOO);
717            oos.flush();
718            int available1 = 0;
719            int available2 = 0;
720            Object obj1 = null;
721            Object obj2 = null;
722            ObjectInputStream ois = new ObjectInputStream(loadStream());
723            available1 = ois.available();
724            obj1 = ois.readObject();
725            available2 = ois.available();
726            obj2 = ois.readObject();
727
728            assertEquals("available returned incorrect value", 0, available1);
729            assertEquals("available returned incorrect value", 0, available2);
730
731            assertTrue("available caused incorrect reading", FOO.equals(obj1));
732            assertTrue("available returned incorrect value", FOO.equals(obj2));
733
734        } catch (IOException e) {
735            fail("IOException serializing object : " + e.getMessage());
736        } catch (ClassNotFoundException e) {
737            fail("Unable to read Object type : " + e.toString());
738        } catch (Error err) {
739            System.out.println("Error " + err);
740            throw err;
741        }
742
743    }
744
745    protected void t_MixPrimitivesAndObjects() throws IOException,
746            ClassNotFoundException {
747        int i = 7;
748        String s1 = "string 1";
749        String s2 = "string 2";
750        byte[] bytes = { 1, 2, 3 };
751
752        oos.writeInt(i);
753        oos.writeObject(s1);
754        oos.writeUTF(s2);
755        oos.writeObject(bytes);
756        oos.close();
757        try {
758            ois = new ObjectInputStream(loadStream());
759
760            int j = ois.readInt();
761            assertTrue("Wrong int :" + j, i == j);
762
763            String l1 = (String) ois.readObject();
764            assertTrue("Wrong obj String :" + l1, s1.equals(l1));
765
766            String l2 = (String) ois.readUTF();
767            assertTrue("Wrong UTF String :" + l2, s2.equals(l2));
768
769            byte[] bytes2 = (byte[]) ois.readObject();
770            assertTrue("Wrong byte[]", Arrays.equals(bytes, bytes2));
771
772        } finally {
773            ois.close();
774        }
775    }
776
777    @TestTargetNew(
778        level = TestLevel.COMPLETE,
779        notes = "Verifies serialization.",
780        method = "!Serialization",
781        args = {}
782    )
783    public void test_resolveClass() {
784        try {
785            oos.writeObject(new Object[] { Integer.class, new Integer(1) });
786            oos.close();
787
788            ois = new ObjectInputStreamSubclass(loadStream());
789            ois.readObject();
790            ois.close();
791        } catch (IOException e1) {
792            fail("IOException : " + e1.getMessage());
793        } catch (ClassNotFoundException e2) {
794            fail("ClassNotFoundException : " + e2.getMessage());
795        }
796
797        Class[] resolvedClasses = ((ObjectInputStreamSubclass) ois)
798                .resolvedClasses();
799        assertEquals("missing resolved", 3, resolvedClasses.length);
800        assertTrue("resolved class 1", resolvedClasses[0] == Object[].class);
801        assertTrue("resolved class 2", resolvedClasses[1] == Integer.class);
802        assertTrue("resolved class 3", resolvedClasses[2] == Number.class);
803    }
804
805    @TestTargetNew(
806        level = TestLevel.COMPLETE,
807        notes = "Verifies serialization.",
808        method = "!Serialization",
809        args = {}
810    )
811    public void test_reset() {
812        try {
813            oos.reset();
814            oos.writeObject("R");
815            oos.reset();
816            oos.writeByte(24);
817            oos.close();
818
819            DataInputStream dis = new DataInputStream(loadStream());
820            byte[] input = new byte[dis.available()];
821            dis.readFully(input);
822            byte[] result = new byte[] { (byte) 0xac, (byte) 0xed, (byte) 0,
823                    (byte) 5, (byte) 0x79, (byte) 0x74, (byte) 0, (byte) 1,
824                    (byte) 'R', (byte) 0x79, (byte) 0x77, (byte) 1, (byte) 24 };
825            assertTrue("incorrect output", Arrays.equals(input, result));
826
827            ois = new ObjectInputStreamSubclass(loadStream());
828            assertEquals("Wrong result from readObject()", "R", ois.readObject()
829                    );
830            assertEquals("Wrong result from readByte()", 24, ois.readByte());
831            ois.close();
832        } catch (IOException e1) {
833            fail("IOException : " + e1.getMessage());
834        } catch (ClassNotFoundException e2) {
835            fail("ClassNotFoundException : " + e2.getMessage());
836        }
837    }
838
839    @TestTargetNew(
840        level = TestLevel.COMPLETE,
841        notes = "Verifies serialization.",
842        method = "!Serialization",
843        args = {}
844    )
845    public void test_serialVersionUID(Class clazz, long svUID) {
846        final String idWrong = "serialVersionUID is wrong for: ";
847        long reflectedSvUID = 0L;
848        try {
849            reflectedSvUID = clazz.getField("serialVersionUID").getLong(null);
850        } catch (Exception e) {
851            fail("Unable to determine serialVersionUID of " + clazz);
852        }
853        assertTrue(idWrong + clazz + ": " + reflectedSvUID + " does not equal "
854                + svUID, reflectedSvUID == svUID);
855    }
856
857    private static class ResolveObjectTest implements Serializable {
858        Object field1, field2;
859    }
860
861    private static class ResolveObjectInputStream extends ObjectInputStream {
862        ResolveObjectInputStream(InputStream in)
863                throws StreamCorruptedException, IOException {
864            super(in);
865        }
866
867        public void enableResolve() {
868            enableResolveObject(true);
869        }
870
871        public Object resolveObject(Object obj) {
872            if (obj instanceof Vector) // test_1_resolveObject()
873                return new Hashtable();
874            else if ("abc".equals(obj)) // test_2_resolveObject()
875                return "ABC";
876            else if (obj instanceof String) // test_3_resolveObject()
877                return String.valueOf(((String) obj).length());
878            else if (obj instanceof int[]) // test_4_resolveObject()
879                return new Object[1];
880            else if (obj instanceof Object[] && ((Object[]) obj).length == 2) // test_5_resolveObject()
881                return new char[1];
882            return obj;
883        }
884    }
885
886    @TestTargetNew(
887        level = TestLevel.COMPLETE,
888        notes = "Verifies serialization.",
889        method = "!Serialization",
890        args = {}
891    )
892    public void test_1_resolveObject() {
893        try {
894            ResolveObjectTest obj = new ResolveObjectTest();
895            obj.field1 = new Vector();
896            obj.field2 = obj.field1;
897            oos.writeObject(obj);
898            oos.close();
899            ois = new ResolveObjectInputStream(loadStream());
900            ((ResolveObjectInputStream) ois).enableResolve();
901            ResolveObjectTest result = null;
902            try {
903                result = (ResolveObjectTest) ois.readObject();
904            } catch (ClassNotFoundException e) {
905                fail(e.toString());
906            }
907            assertTrue("Object not resolved",
908                    result.field1 instanceof Hashtable);
909            assertTrue("Second reference not resolved",
910                    result.field1 == result.field2);
911        } catch (IOException e) {
912            fail("IOException serializing data : " + e.getMessage());
913        }
914    }
915
916    @TestTargetNew(
917        level = TestLevel.COMPLETE,
918        notes = "Verifies serialization.",
919        method = "!Serialization",
920        args = {}
921    )
922    public void test_2_resolveObject() {
923        try {
924            ResolveObjectTest obj = new ResolveObjectTest();
925            obj.field1 = "abc";
926            obj.field2 = obj.field1;
927            oos.writeObject(obj);
928            oos.close();
929            ois = new ResolveObjectInputStream(loadStream());
930            ((ResolveObjectInputStream) ois).enableResolve();
931            ResolveObjectTest result = null;
932            try {
933                result = (ResolveObjectTest) ois.readObject();
934            } catch (ClassNotFoundException e) {
935                fail(e.toString());
936            }
937            assertEquals("String not resolved", "ABC", result.field1);
938            assertTrue("Second reference not resolved",
939                    result.field1 == result.field2);
940        } catch (IOException e) {
941            fail("IOException serializing data : " + e.getMessage());
942        }
943    }
944
945    @TestTargetNew(
946        level = TestLevel.COMPLETE,
947        notes = "Verifies serialization.",
948        method = "!Serialization",
949        args = {}
950    )
951    public void test_3_resolveObject() {
952        try {
953            ResolveObjectTest obj = new ResolveObjectTest();
954            char[] lchars = new char[70000];
955            obj.field1 = new String(lchars);
956            obj.field2 = obj.field1;
957            oos.writeObject(obj);
958            oos.close();
959            ois = new ResolveObjectInputStream(loadStream());
960            ((ResolveObjectInputStream) ois).enableResolve();
961            ResolveObjectTest result = null;
962            try {
963                result = (ResolveObjectTest) ois.readObject();
964            } catch (ClassNotFoundException e) {
965                fail(e.toString());
966            }
967            assertTrue("Long String not resolved", "70000"
968                    .equals(result.field1));
969            assertTrue("Second reference not resolved",
970                    result.field1 == result.field2);
971        } catch (IOException e) {
972            fail("IOException serializing data : " + e.getMessage());
973        }
974    }
975
976    @TestTargetNew(
977        level = TestLevel.COMPLETE,
978        notes = "Verifies serialization.",
979        method = "!Serialization",
980        args = {}
981    )
982    public void test_4_resolveObject() {
983        try {
984            ResolveObjectTest obj = new ResolveObjectTest();
985            obj.field1 = new int[5];
986            obj.field2 = obj.field1;
987            oos.writeObject(obj);
988            oos.close();
989            ois = new ResolveObjectInputStream(loadStream());
990            ((ResolveObjectInputStream) ois).enableResolve();
991            ResolveObjectTest result = null;
992            try {
993                result = (ResolveObjectTest) ois.readObject();
994            } catch (ClassNotFoundException e) {
995                fail(e.toString());
996            }
997            Class cl = new Object[0].getClass();
998            assertTrue("int[] not resolved", result.field1.getClass() == cl);
999            assertTrue("Second reference not resolved",
1000                    result.field1 == result.field2);
1001        } catch (IOException e) {
1002            fail("IOException serializing data : " + e.getMessage());
1003        }
1004    }
1005
1006    @TestTargetNew(
1007        level = TestLevel.COMPLETE,
1008        notes = "Verifies serialization.",
1009        method = "!Serialization",
1010        args = {}
1011    )
1012    public void test_5_resolveObject() {
1013        try {
1014            ResolveObjectTest obj = new ResolveObjectTest();
1015            obj.field1 = new Object[2];
1016            obj.field2 = obj.field1;
1017            oos.writeObject(obj);
1018            oos.close();
1019            ois = new ResolveObjectInputStream(loadStream());
1020            ((ResolveObjectInputStream) ois).enableResolve();
1021            ResolveObjectTest result = null;
1022            try {
1023                result = (ResolveObjectTest) ois.readObject();
1024            } catch (ClassNotFoundException e) {
1025                fail(e.toString());
1026            }
1027            Class cl = new char[0].getClass();
1028            assertTrue("int[] not resolved", result.field1.getClass() == cl);
1029            assertTrue("Second reference not resolved",
1030                    result.field1 == result.field2);
1031        } catch (IOException e) {
1032            fail("IOException serializing data : " + e.getMessage());
1033        }
1034    }
1035
1036    static class WriteReplaceTestA implements Serializable {
1037        public Object writeReplace() throws ObjectStreamException {
1038            return new ReadResolveTestB();
1039        }
1040    }
1041
1042    static class WriteReplaceTestB extends WriteReplaceTestA {
1043    }
1044
1045    static class WriteReplaceTestC extends WriteReplaceTestA {
1046        public Object writeReplace() throws ObjectStreamException {
1047            return new ReadResolveTestC();
1048        }
1049    }
1050
1051    static class WriteReplaceTestD implements Serializable {
1052        private Object writeReplace() throws ObjectStreamException {
1053            return new ReadResolveTestD();
1054        }
1055    }
1056
1057    static class WriteReplaceTestE extends WriteReplaceTestD {
1058    }
1059
1060    static class WriteReplaceTestF implements Serializable {
1061        int type, readType;
1062
1063        public WriteReplaceTestF(int type, int readType) {
1064            this.type = type;
1065            this.readType = readType;
1066        }
1067
1068        public Object writeReplace() throws ObjectStreamException {
1069            switch (type) {
1070            case 0:
1071                throw new InvalidObjectException("invalid");
1072            case 1:
1073                throw new RuntimeException("runtime");
1074            case 2:
1075                throw new Error("error");
1076            default:
1077                return new ReadResolveTestE(readType);
1078            }
1079        }
1080    }
1081
1082    static class ReadResolveTestA implements Serializable {
1083        public Object readResolve() throws ObjectStreamException {
1084            return new ReadResolveTestA();
1085        }
1086    }
1087
1088    static class ReadResolveTestB extends ReadResolveTestA {
1089    }
1090
1091    static class ReadResolveTestC implements Serializable {
1092        private Object readResolve() throws ObjectStreamException {
1093            return new ReadResolveTestB();
1094        }
1095    }
1096
1097    static class ReadResolveTestD extends ReadResolveTestC {
1098    }
1099
1100    static class ReadResolveTestE implements Serializable {
1101        int type;
1102
1103        public ReadResolveTestE(int type) {
1104            this.type = type;
1105        }
1106
1107        public Object readResolve() throws ObjectStreamException {
1108            switch (type) {
1109            case 0:
1110                throw new InvalidObjectException("invalid");
1111            case 1:
1112                throw new RuntimeException("runtime");
1113            case 2:
1114                throw new Error("error");
1115            case 3:
1116                return this;
1117            default:
1118                return new ReadResolveTestF();
1119            }
1120        }
1121    }
1122
1123    static class ReadResolveTestF implements Serializable {
1124    }
1125
1126    @TestTargetNew(
1127        level = TestLevel.COMPLETE,
1128        notes = "Verifies serialization.",
1129        method = "!Serialization",
1130        args = {}
1131    )
1132    public void test_1_writeReplace() {
1133        try {
1134            Vector v = new Vector();
1135            v.addElement(new WriteReplaceTestA());
1136            v.addElement(new WriteReplaceTestB());
1137            v.addElement(new WriteReplaceTestB());
1138            v.addElement(new WriteReplaceTestC());
1139            v.addElement(new WriteReplaceTestD());
1140            v.addElement(new WriteReplaceTestE());
1141            oos.writeObject(v);
1142            oos.close();
1143            ois = new ObjectInputStream(loadStream());
1144            Vector result = (Vector) ois.readObject();
1145            assertTrue("invalid 0 : " + result.elementAt(0), result
1146                    .elementAt(0).getClass() == ReadResolveTestA.class);
1147            assertTrue("invalid 1 : " + result.elementAt(1), result
1148                    .elementAt(1).getClass() == ReadResolveTestA.class);
1149            assertTrue("invalid 2 : " + result.elementAt(2), result
1150                    .elementAt(2).getClass() == ReadResolveTestA.class);
1151            assertTrue("invalid 3 : " + result.elementAt(3), result
1152                    .elementAt(3).getClass() == ReadResolveTestB.class);
1153            assertTrue("invalid 4 : " + result.elementAt(4), result
1154                    .elementAt(4).getClass() == ReadResolveTestD.class);
1155            assertTrue("invalid 5 : " + result.elementAt(5), result
1156                    .elementAt(5).getClass() == WriteReplaceTestE.class);
1157        } catch (IOException e) {
1158            fail("IOException serializing data : " + e.getMessage());
1159        } catch (ClassNotFoundException e) {
1160            fail("ClassNotFoundException serializing data : " + e.getMessage());
1161        }
1162    }
1163
1164    @TestTargetNew(
1165        level = TestLevel.COMPLETE,
1166        notes = "Verifies serialization.",
1167        method = "!Serialization",
1168        args = {}
1169    )
1170    public void test_2_writeReplace() {
1171        try {
1172            boolean exception = false;
1173            try {
1174                oos.writeObject(new WriteReplaceTestF(0, -1));
1175            } catch (ObjectStreamException e) {
1176                exception = true;
1177            }
1178            assertTrue("Should throw ObjectStreamException", exception);
1179            exception = false;
1180            try {
1181                oos.writeObject(new WriteReplaceTestF(1, -1));
1182            } catch (RuntimeException e) {
1183                exception = true;
1184            }
1185            assertTrue("Should throw RuntimeException", exception);
1186            exception = false;
1187            try {
1188                oos.writeObject(new WriteReplaceTestF(2, -1));
1189            } catch (Error e) {
1190                exception = true;
1191            }
1192            assertTrue("Should throw Error", exception);
1193
1194            oos.writeObject(new WriteReplaceTestF(3, 0));
1195            oos.writeObject(new WriteReplaceTestF(3, 1));
1196            oos.writeObject(new WriteReplaceTestF(3, 2));
1197            WriteReplaceTestF test = new WriteReplaceTestF(3, 3);
1198            oos.writeObject(test);
1199            oos.writeObject(test);
1200            WriteReplaceTestF test2 = new WriteReplaceTestF(3, 4);
1201            oos.writeObject(test2);
1202            oos.writeObject(test2);
1203            oos.close();
1204            ois = new ObjectInputStream(loadStream());
1205            try {
1206                ois.readObject();
1207            } catch (WriteAbortedException e) {
1208            }
1209
1210            exception = false;
1211            try {
1212                ois.readObject();
1213            } catch (ObjectStreamException e) {
1214                exception = true;
1215            }
1216            assertTrue("Expected ObjectStreamException", exception);
1217            exception = false;
1218            try {
1219                ois.readObject();
1220            } catch (RuntimeException e) {
1221                exception = true;
1222            }
1223            assertTrue("Expected RuntimeException", exception);
1224            exception = false;
1225            try {
1226                ois.readObject();
1227            } catch (Error e) {
1228                exception = true;
1229            }
1230            assertTrue("Expected Error", exception);
1231
1232            Object readE1 = ois.readObject();
1233            Object readE2 = ois.readObject();
1234            assertTrue("Replaced objects should be identical", readE1 == readE2);
1235            Object readF1 = ois.readObject();
1236            Object readF2 = ois.readObject();
1237            assertTrue("Replaced resolved objects should be identical: "
1238                    + readF1 + " " + readF2, readF1 == readF2);
1239        } catch (IOException e) {
1240            fail("IOException serializing data : " + e.getMessage());
1241        } catch (ClassNotFoundException e) {
1242            fail("ClassNotFoundException serializing data : " + e.getMessage());
1243        }
1244    }
1245}
1246