SerializationStressTest5.java revision 5d709784bbf5001012d7f25172927d46f6c1abe1
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.TestLevel;
21import dalvik.annotation.TestTargetClass;
22import dalvik.annotation.TestTargetNew;
23
24import java.io.File;
25import java.io.FileInputStream;
26import java.io.FileNotFoundException;
27import java.io.IOException;
28import java.lang.reflect.Constructor;
29import java.lang.reflect.InvocationTargetException;
30import java.util.Vector;
31import java.util.zip.ZipEntry;
32import java.util.zip.ZipInputStream;
33
34@TestTargetClass(java.io.Serializable.class)
35public class SerializationStressTest5 extends SerializationStressTest {
36
37    transient Throwable current;
38
39    // Use this for retrieving a list of any Throwable Classes that did not get
40    // tested.
41    transient Vector missedV = new Vector();
42
43    transient Class[][] params = new Class[][] { { String.class },
44            { Throwable.class }, { Exception.class },
45            { String.class, Exception.class }, { String.class, int.class },
46            { String.class, String.class, String.class },
47            { String.class, Error.class },
48            { int.class, boolean.class, boolean.class, int.class, int.class },
49            {} };
50
51    transient Object[][] args = new Object[][] {
52            { "message" },
53            { new Throwable() },
54            { new Exception("exception") },
55            { "message", new Exception("exception") },
56            { "message", new Integer(5) },
57            { "message", "message", "message" },
58            { "message", new Error("error") },
59            { new Integer(5), new Boolean(false), new Boolean(false),
60                    new Integer(5), new Integer(5) }, {} };
61
62    @TestTargetNew(
63        level = TestLevel.ADDITIONAL,
64        notes = "",
65        method = "!Serialization:test ThrowableClasses",
66        args = {}
67    )
68    public void _test_writeObject_Throwables() {
69        try {
70            oos.close();
71        } catch (IOException e) {
72        }
73
74        File javaDir = findJavaDir();
75
76        Vector classFilesVector = new Vector();
77        if (javaDir != null)
78            findClassFiles(javaDir, classFilesVector);
79        else
80            findClassFilesFromZip(classFilesVector);
81
82        if (classFilesVector.size() == 0) {
83            fail("No Class Files Found.");
84        }
85
86        File[] classFilesArray = new File[classFilesVector.size()];
87        classFilesVector.copyInto(classFilesArray);
88
89        Class[] throwableClasses = findThrowableClasses(classFilesArray);
90        findParam(throwableClasses);
91
92        // Use this to print out the list of Throwable classes that weren't
93        // tested.
94        /*
95         * System.out.println(); Class[] temp = new Class[missedV.size()];
96         * missedV.copyInto(temp); for (int i = 0; i < temp.length; i++)
97         * System.out.println(i+1 + ": " + temp[i].getName());
98         */
99    }
100
101    private File[] makeClassPathArray() {
102        String classPath;
103        // if (System.getProperty("java.vendor").startsWith("IBM"))
104        //     classPath = System.getProperty("org.apache.harmony.boot.class.path");
105        // else
106        //     classPath = System.getProperty("sun.boot.class.path");
107        classPath = System.getProperty("java.boot.class.path");
108        int instanceOfSep = -1;
109        int nextInstance = classPath.indexOf(File.pathSeparatorChar,
110                instanceOfSep + 1);
111        Vector elms = new Vector();
112        while (nextInstance != -1) {
113            elms.add(new File(classPath.substring(instanceOfSep + 1,
114                    nextInstance)));
115            instanceOfSep = nextInstance;
116            nextInstance = classPath.indexOf(File.pathSeparatorChar,
117                    instanceOfSep + 1);
118        }
119        elms.add(new File(classPath.substring(instanceOfSep + 1)));
120        File[] result = new File[elms.size()];
121        elms.copyInto(result);
122        return result;
123    }
124
125    private File findJavaDir() {
126        File[] files = makeClassPathArray();
127        for (int i = 0; i < files.length; i++) {
128            if (files[i].isDirectory()) {
129                String[] tempFileNames = files[i].list();
130                for (int j = 0; j < tempFileNames.length; j++) {
131                    File tempfile = new File(files[i], tempFileNames[j]);
132                    if (tempfile.isDirectory()
133                            && tempFileNames[j].equals("java")) {
134                        String[] subdirNames = tempfile.list();
135                        for (int k = 0; k < subdirNames.length; k++) {
136                            File subdir = new File(tempfile, subdirNames[k]);
137                            if (subdir.isDirectory()
138                                    && subdirNames[k].equals("lang")) {
139                                return tempfile;
140                            }
141                        }
142                    }
143                }
144            }
145        }
146        return null;
147    }
148
149    private void findClassFiles(File dir, Vector v) {
150        String[] classFileNames = dir.list();
151        for (int i = 0; i < classFileNames.length; i++) {
152            File file = new File(dir, classFileNames[i]);
153            if (file.isDirectory())
154                findClassFiles(file, v);
155            else if (classFileNames[i].endsWith(".class"))
156                v.add(file);
157        }
158    }
159
160    private Class[] findThrowableClasses(File[] files) {
161        Class thrClass = Throwable.class;
162        Vector resultVector = new Vector();
163        String slash = System.getProperty("file.separator");
164        String begTarget = slash + "java" + slash;
165        String endTarget = ".class";
166        for (int i = 0; i < files.length; i++) {
167            String fileName = files[i].getPath();
168            int instOfBegTarget = fileName.indexOf(begTarget);
169            int instOfEndTarget = fileName.indexOf(endTarget);
170            fileName = fileName.substring(instOfBegTarget + 1, instOfEndTarget);
171            fileName = fileName.replace(slash.charAt(0), '.');
172            try {
173                Class theClass = Class.forName(fileName, false, ClassLoader
174                        .getSystemClassLoader());
175                if (thrClass.isAssignableFrom(theClass)) {
176                    // java.lang.VirtualMachineError is abstract.
177                    // java.io.ObjectStreamException is abstract
178                    // java.beans.PropertyVetoException needs a
179                    // java.beans.PropertyChangeEvent as a parameter
180                    if (!fileName.equals("java.lang.VirtualMachineError")
181                            && !fileName
182                                    .equals("java.io.ObjectStreamException")
183                            && !fileName
184                                    .equals("java.beans.PropertyVetoException"))
185                        resultVector.add(theClass);
186                }
187            } catch (ClassNotFoundException e) {
188                fail("ClassNotFoundException : " + fileName);
189            }
190        }
191        Class[] result = new Class[resultVector.size()];
192        resultVector.copyInto(result);
193        return result;
194    }
195
196    private void initClass(Class thrC, int num) {
197        Constructor[] cons = thrC.getConstructors();
198        for (int i = 0; i < cons.length; i++) {
199            try {
200                Throwable obj = (Throwable) cons[i].newInstance(args[num]);
201                t_Class(obj, num);
202                break;
203            } catch (IllegalArgumentException e) {
204                // This error should be caught until the correct args is hit.
205            } catch (IllegalAccessException e) {
206                fail(
207                        "IllegalAccessException while creating instance of: "
208                                + thrC.getName());
209            } catch (InstantiationException e) {
210                fail(
211                        "InstantiationException while creating instance of: "
212                                + thrC.getName());
213            } catch (InvocationTargetException e) {
214                fail(
215                        "InvocationTargetException while creating instance of: "
216                                + thrC.getName());
217            }
218            if (i == cons.length - 1) {
219                fail(
220                        "Failed to create newInstance of: " + thrC.getName());
221            }
222        }
223    }
224
225    public String getDumpName() {
226        if (current == null) {
227            dumpCount++;
228            return getName();
229        }
230        return getName() + "_" + current.getClass().getName();
231    }
232
233    private void t_Class(Throwable objToSave, int argsNum) {
234        current = objToSave;
235        Object objLoaded = null;
236        try {
237            if (DEBUG)
238                System.out.println("Obj = " + objToSave);
239            try {
240                objLoaded = dumpAndReload(objToSave);
241            } catch (FileNotFoundException e) {
242                // Must be using xload, ignore missing Throwables
243                System.out.println("Ignoring: "
244                        + objToSave.getClass().getName());
245                return;
246            }
247
248            // Has to have worked
249            boolean equals;
250            equals = objToSave.getClass().equals(objLoaded.getClass());
251            assertTrue(MSG_TEST_FAILED + objToSave, equals);
252            if (argsNum == 0 || (argsNum >= 3 && argsNum <= 7)) {
253                equals = ((Throwable) objToSave).getMessage().equals(
254                        ((Throwable) objLoaded).getMessage());
255                assertTrue("Message Test: " + MSG_TEST_FAILED + objToSave,
256                        equals);
257            } else {
258                // System.out.println(((Throwable)objToSave).getMessage());
259                equals = ((Throwable) objToSave).getMessage() == null;
260                assertTrue("Null Test 1: (args=" + argsNum + ") "
261                        + MSG_TEST_FAILED + objToSave, equals);
262                equals = ((Throwable) objLoaded).getMessage() == null;
263                assertTrue("Null Test 2: (args=" + argsNum + ") "
264                        + MSG_TEST_FAILED + objToSave, equals);
265            }
266        } catch (IOException e) {
267            fail("Unexpected IOException in checkIt() : " + e.getMessage());
268        } catch (ClassNotFoundException e) {
269            fail(e.toString() + " - testing " + objToSave.getClass().getName());
270        }
271    }
272
273    private void findParam(Class[] thrC) {
274        for (int i = 0; i < thrC.length; i++) {
275            Constructor con = null;
276            for (int j = 0; j < params.length; j++) {
277                try {
278                    con = thrC[i].getConstructor(params[j]);
279                } catch (NoSuchMethodException e) {
280                    // This Error will be caught until the right param is found.
281                }
282
283                if (con != null) {
284                    // If the param was found, initialize the Class
285                    initClass(thrC[i], j);
286                    break;
287                }
288                // If the param not found then add to missed Vector.
289                if (j == params.length - 1)
290                    missedV.add(thrC[i]);
291            }
292        }
293    }
294
295    private void findClassFilesFromZip(Vector v) {
296        String slash = System.getProperty("file.separator");
297        String javaHome = System.getProperty("java.home");
298        if (!javaHome.endsWith(slash))
299            javaHome += slash;
300
301        String[] wanted = { "java" + slash + "io", "java" + slash + "lang",
302                "java" + slash + "math", "java" + slash + "net",
303                "java" + slash + "security", "java" + slash + "text",
304                "java" + slash + "util", "java" + slash + "beans",
305                "java" + slash + "rmi",
306                // One or more class files in awt make the VM hang after being
307                // loaded.
308                // "java" + slash + "awt",
309                "java" + slash + "sql",
310        // These are (possibly) all of the throwable classes in awt
311        /*
312         * "java\\awt\\AWTError", "java\\awt\\AWTException",
313         * "java\\awt\\color\\CMMException",
314         * "java\\awt\\color\\ProfileDataException",
315         * "java\\awt\\datatransfer\\MimeTypeParseException",
316         * "java\\awt\\datatransfer\\UnsupportedFlavorException",
317         * "java\\awt\\dnd\\InvalidDnDOperationException",
318         * "java\\awt\\FontFormatException",
319         * "java\\awt\\geom\\IllegalPathStateException",
320         * "java\\awt\\geom\\NoninvertibleTransformException",
321         * "java\\awt\\IllegalComponentStateException",
322         * "java\\awt\\image\\ImagingOpException",
323         * "java\\awt\\image\\RasterFormatException",
324         * "java\\awt\\print\\PrinterAbortException",
325         * "java\\awt\\print\\PrinterException",
326         * "java\\awt\\print\\PrinterIOException"
327         */
328        };
329
330        File[] files = makeClassPathArray();
331        FileInputStream fis = null;
332        ZipInputStream zis = null;
333        ZipEntry ze = null;
334        for (int i = 0; i < files.length; i++) {
335            String fileName = files[i].getPath();
336            if (files[i].exists() && files[i].isFile()
337                    && fileName.endsWith(".jar") || fileName.endsWith(".zip")) {
338                try {
339                    fis = new FileInputStream(files[i].getPath());
340                } catch (FileNotFoundException e) {
341                    fail("FileNotFoundException trying to open "
342                            + files[i].getPath());
343                }
344                zis = new ZipInputStream(fis);
345                while (true) {
346                    try {
347                        ze = zis.getNextEntry();
348                    } catch (IOException e) {
349                        fail("IOException while getting next zip entry: "
350                                + e);
351                    }
352                    if (ze == null)
353                        break;
354                    String zeName = ze.getName();
355                    if (zeName.endsWith(".class")) {
356                        zeName = zeName.replace('/', slash.charAt(0));
357                        for (int j = 0; j < wanted.length; j++) {
358                            if (zeName.startsWith(wanted[j])) {
359                                // When finding class files from directories the
360                                // program saves them as files.
361                                // To stay consistent we will turn the ZipEntry
362                                // classes into instances of files.
363                                File tempF = new File(javaHome + zeName);
364                                // Making sure that the same class is not added
365                                // twice.
366                                boolean duplicate = false;
367                                for (int k = 0; k < v.size(); k++) {
368                                    if (v.get(k).equals(tempF))
369                                        duplicate = true;
370                                }
371                                if (!duplicate)
372                                    v.add(tempF);
373                                break;
374                            }
375                        }
376                    }
377                }
378                ;
379                try {
380                    zis.close();
381                    fis.close();
382                } catch (IOException e) {
383                    fail(
384                            "IOException while trying to close InputStreams: "
385                                    + e);
386                }
387            }
388        }
389    }
390}
391