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 libcore.java.io;
19
20import java.io.ObjectInputStream;
21import tests.support.Support_GetPutFields;
22import tests.support.Support_GetPutFieldsDefaulted;
23
24
25/**
26 * Tests the methods of {@code ObjectInputStream.GetField}. Three things make
27 * this class somewhat difficult to test:
28 * <ol>
29 * <li>It is a completely abstract class; none of the methods is implemented in
30 * {@code ObjectInputStream.GetField}.</li>
31 * <li>There is no public class that implements
32 * {@code ObjectInputStream.GetField}. The only way to get an implementation is
33 * by calling {@code ObjectInputStream.getFields()}.</li>
34 * <li>Invoking {@code ObjectOutputStream.getFields()} only works from within
35 * the private {@code readObject(ObjectInputStream)} method of a class that
36 * implements {@code Serializable}; an exception is thrown otherwise.</li>
37 * </ol>
38 * <p>
39 * Given these restrictions, an indirect approach is used to test
40 * {@code ObjectInputStream.GetField}: Three serializable helper classes in
41 * package {@code tests.support} ({@code Support_GetPutFields},
42 * {@code Support_GetPutFieldsDeprecated} and
43 * {@code Support_GetPutFieldsDefaulted}) implement
44 * {@code readObject(ObjectInputStream)} to read data from an input stream.
45 * This input stream in turn reads from one of the corresponding files
46 * ({@code testFields.ser}, {@code testFieldsDeprecated.ser} and
47 * {@code testFieldsDefaulted.ser}) that have been created with
48 * {@code tests.util.FieldTestFileGenerator} on a reference platform.
49 * </p>
50 * <p>
51 * The test method in this class expects to find the reference files as a
52 * resource stored at {@code tests/api/java/io}.
53 * </p>
54 */
55public class OldObjectInputStreamGetFieldTest extends junit.framework.TestCase {
56
57    private ObjectInputStream ois = null;
58
59    private final String FILENAME =
60            "/tests/api/java/io/testFields.ser";
61    private final String DEFAULTED_FILENAME =
62            "/tests/api/java/io/testFieldsDefaulted.ser";
63
64    public boolean booleanValue;
65    public byte byteValue;
66    public char charValue;
67    public int intValue;
68
69    public void test_get() throws Exception {
70        initOis(FILENAME);
71        Support_GetPutFields object = (Support_GetPutFields) ois.readObject();
72        Support_GetPutFields newObject = new Support_GetPutFields();
73        newObject.initTestValues();
74
75        assertTrue("Test 1: The object read from the reference file does " +
76                   "not match a locally created instance of the same class.",
77                   object.equals(newObject));
78
79        initOis(DEFAULTED_FILENAME);
80        Support_GetPutFieldsDefaulted defaulted =
81                (Support_GetPutFieldsDefaulted) ois.readObject();
82        Support_GetPutFieldsDefaulted newDefaulted =
83                new Support_GetPutFieldsDefaulted();
84        newDefaulted.initTestValues();
85
86        assertTrue("Test 2: The object read from the reference file does " +
87                   "not match a locally created instance of the same class.",
88                   defaulted.equals(newDefaulted));
89
90        // Executing the same procedure against the file created with the
91        // deprecated ObjectOutputStream.PutFields.write(ObjectOutput) method
92        // is not possible since there is no corresponding read(ObjectInput)
93        // method. When trying to do it as in tests 1 and 2, a
94        // NullPointerException is thrown.
95    }
96
97    public void test_defaultedLjava_lang_String() throws Exception {
98        initOis(FILENAME);
99        Support_GetPutFields object = (Support_GetPutFields) ois.readObject();
100        ObjectInputStream.GetField fields = object.getField;
101
102        try {
103            fields.defaulted("noField");
104            fail("IllegalArgumentException expected.");
105        } catch (IllegalArgumentException e) {}
106
107        assertFalse("The field longValue should not be defaulted.",
108                   fields.defaulted("longValue"));
109
110        // Now the same with defaulted fields.
111        initOis(DEFAULTED_FILENAME);
112        Support_GetPutFieldsDefaulted defaultedObject =
113            (Support_GetPutFieldsDefaulted) ois.readObject();
114        fields = defaultedObject.getField;
115
116        assertTrue("The field longValue should be defaulted.",
117                   fields.defaulted("longValue"));
118
119    }
120
121    public void test_getException() throws Exception {
122        initOis(FILENAME);
123        Support_GetPutFields object = (Support_GetPutFields) ois.readObject();
124        ObjectInputStream.GetField fields = object.getField;
125
126        // Methods called with invalid field name.
127        try {
128            fields.get("noValue", false);
129            fail("IllegalArgumentException expected for not existing name " +
130                 "argument in get(String, boolean).");
131        } catch (IllegalArgumentException e) {}
132
133        try {
134            fields.get("noValue", (byte) 0);
135            fail("IllegalArgumentException expected for not existing name " +
136                 "argument in get(String, byte).");
137        } catch (IllegalArgumentException e) {}
138
139        try {
140            fields.get("noValue", (char) 0);
141            fail("IllegalArgumentException expected for not existing name " +
142                 "argument in get(String, char).");
143        } catch (IllegalArgumentException e) {}
144
145        try {
146            fields.get("noValue", 0.0);
147            fail("IllegalArgumentException expected for not existing name " +
148                 "argument in get(String, double).");
149        } catch (IllegalArgumentException e) {}
150
151        try {
152            fields.get("noValue", 0.0f);
153            fail("IllegalArgumentException expected for not existing name " +
154                 "argument in get(String, float).");
155        } catch (IllegalArgumentException e) {}
156
157        try {
158            fields.get("noValue", (long) 0);
159            fail("IllegalArgumentException expected for not existing name " +
160                 "argument in get(String, long).");
161        } catch (IllegalArgumentException e) {}
162
163        try {
164            fields.get("noValue", 0);
165            fail("IllegalArgumentException expected for not existing name " +
166                 "argument in get(String, int).");
167        } catch (IllegalArgumentException e) {}
168
169        try {
170            fields.get("noValue", new Object());
171            fail("IllegalArgumentException expected for not existing name " +
172                 "argument in get(String, Object).");
173        } catch (IllegalArgumentException e) {}
174
175        try {
176            fields.get("noValue", (short) 0);
177            fail("IllegalArgumentException expected for not existing name " +
178                 "argument in get(String, short).");
179        } catch (IllegalArgumentException e) {}
180
181        // Methods called with correct field name but non-matching type.
182        try {
183            fields.get("byteValue", false);
184            fail("IllegalArgumentException expected for non-matching name " +
185                 "and type arguments in get(String, boolean).");
186        } catch (IllegalArgumentException e) {}
187
188        try {
189            fields.get("booleanValue", (byte) 0);
190            fail("IllegalArgumentException expected for non-matching name " +
191                 "and type arguments in get(String, byte).");
192        } catch (IllegalArgumentException e) {}
193
194        try {
195            fields.get("intValue", (char) 0);
196            fail("IllegalArgumentException expected for non-matching name " +
197                 "and type arguments in get(String, char).");
198        } catch (IllegalArgumentException e) {}
199
200        try {
201            fields.get("floatValue", 0.0);
202            fail("IllegalArgumentException expected for non-matching name " +
203                 "and type arguments in get(String, double).");
204        } catch (IllegalArgumentException e) {}
205
206        try {
207            fields.get("doubleValue", 0.0f);
208            fail("IllegalArgumentException expected for non-matching name " +
209                 "and type arguments in get(String, float).");
210        } catch (IllegalArgumentException e) {}
211
212        try {
213            fields.get("intValue", (long) 0);
214            fail("IllegalArgumentException expected for non-matching name " +
215                 "and type arguments in get(String, long).");
216        } catch (IllegalArgumentException e) {}
217
218        try {
219            fields.get("shortValue", 0);
220            fail("IllegalArgumentException expected for non-matching name " +
221                 "and type arguments in get(String, int).");
222        } catch (IllegalArgumentException e) {}
223
224        try {
225            fields.get("booleanValue", new Object());
226            fail("IllegalArgumentException expected for non-matching name " +
227                 "and type arguments in get(String, Object).");
228        } catch (IllegalArgumentException e) {}
229
230        try {
231            fields.get("longValue", (short) 0);
232            fail("IllegalArgumentException expected for non-matching name " +
233                 "and type arguments in get(String, short).");
234        } catch (IllegalArgumentException e) {}
235    }
236
237    public void test_getObjectStreamClass() throws Exception {
238        initOis(FILENAME);
239        Support_GetPutFields object = (Support_GetPutFields) ois.readObject();
240        assertNotNull("Return value of getObjectStreamClass() should not be null.",
241                      object.getField.getObjectStreamClass());
242    }
243
244    private void initOis(String fileName) throws Exception {
245        if (ois != null) {
246            ois.close();
247        }
248        ois = new ObjectInputStream(
249                    getClass().getResourceAsStream(fileName));
250    }
251
252    protected void tearDown() throws Exception {
253        if (ois != null) {
254            ois.close();
255        }
256        super.tearDown();
257    }
258
259}
260