Adding old unit tests to test suite.
These tests are copied straight over. They'll still run, but they're
using the old system.
Change-Id: If494519e52ddf858a9febfc55bdae830468cb3c8
diff --git a/test/064-field-access/src/Main.java b/test/064-field-access/src/Main.java
new file mode 100644
index 0000000..c068d23
--- /dev/null
+++ b/test/064-field-access/src/Main.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import other.OtherPackage;
+
+import java.lang.reflect.Field;
+
+/*
+ * Test field access through reflection.
+ */
+public class Main {
+ public static void main(String[] args) {
+ SubOther.main(null);
+
+ try {
+ GetNonexistent.main(null);
+ System.err.println("Not expected to succeed");
+ } catch (VerifyError fe) {
+ // dalvik
+ System.out.println("Got expected failure");
+ } catch (NoSuchFieldError nsfe) {
+ // reference
+ System.out.println("Got expected failure");
+ }
+ }
+
+ /*
+ * Get the field specified by "field" from "obj".
+ *
+ * "type" determines which "get" call is made, e.g. 'B' turns into
+ * field.getByte().
+ *
+ * The "expectedException" must match the class of the exception thrown,
+ * or be null if no exception was expected.
+ *
+ * On success, the boxed value retrieved is returned.
+ */
+ public Object getValue(Field field, Object obj, char type,
+ Class expectedException) {
+
+ Object result = null;
+ try {
+ switch (type) {
+ case 'Z':
+ result = new Boolean(field.getBoolean(obj));
+ break;
+ case 'B':
+ result = new Byte(field.getByte(obj));
+ break;
+ case 'S':
+ result = new Short(field.getShort(obj));
+ break;
+ case 'C':
+ result = new Character(field.getChar(obj));
+ break;
+ case 'I':
+ result = new Integer(field.getInt(obj));
+ break;
+ case 'J':
+ result = new Long(field.getLong(obj));
+ break;
+ case 'F':
+ result = new Float(field.getFloat(obj));
+ break;
+ case 'D':
+ result = new Double(field.getDouble(obj));
+ break;
+ case 'L':
+ result = field.get(obj);
+ break;
+ default:
+ throw new RuntimeException("bad type '" + type + "'");
+ }
+
+ /* success; expected? */
+ if (expectedException != null) {
+ Throwable th = new Throwable();
+ System.err.println("ERROR: call succeeded, was expecting "
+ + expectedException);
+ th.printStackTrace();
+ }
+ } catch (Exception ex) {
+ if (expectedException == null) {
+ System.err.println("ERROR: call failed unexpectedly: "
+ + ex.getClass());
+ ex.printStackTrace();
+ } else {
+ if (!expectedException.equals(ex.getClass())) {
+ System.err.println("ERROR: incorrect exception: wanted "
+ + expectedException.getName() + ", got "
+ + ex.getClass());
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ return result;
+ }
+}
+
+/*
+ * Local class with some fields.
+ */
+class SamePackage {
+ public byte pubByteField;
+
+ protected byte protByteField;
+ protected Object protObjectField;
+
+ private float privFloatField;
+}
+
+/*
+ * This is a sub-class of OtherPackage, which should be allowed to access
+ * the various protected fields.
+ */
+class SubOther extends OtherPackage {
+
+ protected long protLongField = 0x1122334455667788L;
+
+ /*
+ * Perform the various tests.
+ *
+ * localInst.getValue() is performed using an instance of Main as the
+ * source of the reflection call. otherInst.getValue() uses a subclass
+ * of OtherPackage as the source.
+ */
+ public static void main(String[] args) {
+ SubOther subOther = new SubOther();
+ subOther.doTests();
+ }
+
+ public void doTests() {
+ Class localClass = SamePackage.class;
+ Class otherClass = OtherPackage.class;
+ Field localPubByteField, localProtByteField, localProtObjectField,
+ localPrivFloatField;
+ Field otherPubCharField, otherProtShortField, otherProtObjectField,
+ otherPkgDoubleField;
+ Field subProtLongField;
+ Main localInst = new Main();
+ SamePackage samePkgInst = new SamePackage();
+ OtherPackage otherPkgInst = new OtherPackage();
+ Object plainObj = new Object();
+
+ /*
+ * Locate the various fields.
+ */
+ try {
+ localPubByteField = localClass.getDeclaredField("pubByteField");
+ localProtByteField = localClass.getDeclaredField("protByteField");
+ localProtObjectField = localClass.getDeclaredField("protObjectField");
+ localPrivFloatField = localClass.getDeclaredField("privFloatField");
+
+ otherPubCharField = otherClass.getDeclaredField("pubCharField");
+ otherProtShortField = otherClass.getDeclaredField("protShortField");
+ otherProtObjectField = otherClass.getDeclaredField("protObjectField");
+ otherPkgDoubleField = otherClass.getDeclaredField("pkgDoubleField");
+
+ subProtLongField = getClass().getDeclaredField("protLongField");
+ } catch (NoSuchFieldException nsfe) {
+ throw new RuntimeException(nsfe);
+ }
+
+ /*
+ * Get a public field from a class in the same package.
+ */
+ localInst.getValue(localPubByteField, samePkgInst, 'B', null);
+
+ /*
+ * Get a protected field from a class in the same package.
+ */
+ this.getValue(localProtByteField, samePkgInst, 'B', null);
+
+ /*
+ * Get a private field from a class in the same package.
+ */
+ this.getValue(localPrivFloatField, samePkgInst, 'F',
+ IllegalAccessException.class);
+
+ /*
+ * Get a protected field from otherInst's superclass.
+ *
+ * We can get at "this.protShortField" but not
+ * "otherPkgInst.protShortField" because we can only access
+ * protected fields in instances of our class -- being a subclass
+ * of OtherPackage does not allow us to modify protected fields in
+ * all other subclasses of OtherPackage.
+ */
+ this.getValue(otherProtShortField, this, 'S',
+ null);
+ this.getValue(otherProtShortField, otherPkgInst, 'S',
+ IllegalAccessException.class);
+ this.getValue(otherPkgDoubleField, otherPkgInst, 'D',
+ IllegalAccessException.class);
+
+ /*
+ * Null object. Different exceptions based on which package
+ * we would be trying to access and whether or not our object
+ * has the correct type.
+ */
+ localInst.getValue(localPubByteField, null, 'B',
+ NullPointerException.class);
+
+ this.getValue(subProtLongField, null, 'J',
+ NullPointerException.class);
+
+ this.getValue(localPrivFloatField, null, 'F',
+ IllegalAccessException.class);
+
+ localInst.getValue(otherProtShortField, null, 'S',
+ IllegalAccessException.class);
+ this.getValue(otherProtShortField, null, 'S',
+ IllegalAccessException.class);
+ this.getValue(otherPkgDoubleField, null, 'D',
+ IllegalAccessException.class);
+
+ localInst.getValue(otherProtShortField, null, 'Z',
+ IllegalAccessException.class);
+ /* -- Dalvik VM currently throws NPE
+ this.getValue(subProtLongField, null, 'Z',
+ IllegalArgumentException.class);
+ */
+
+ /*
+ * Valid object, wrong field type.
+ */
+ this.getValue(subProtLongField, this, 'J',
+ null);
+ this.getValue(localProtByteField, samePkgInst, 'Z',
+ IllegalArgumentException.class);
+ this.getValue(subProtLongField, this, 'Z',
+ IllegalArgumentException.class);
+ this.getValue(localPrivFloatField, this, 'Z',
+ IllegalAccessException.class);
+ this.getValue(localPrivFloatField, this, 'Z',
+ IllegalAccessException.class);
+ localInst.getValue(otherProtShortField, otherPkgInst, 'Z',
+ IllegalAccessException.class);
+ this.getValue(otherProtShortField, otherPkgInst, 'Z',
+ IllegalAccessException.class);
+
+ /*
+ * Wrong object.
+ */
+ this.getValue(subProtLongField, plainObj, 'J',
+ IllegalArgumentException.class);
+
+ /* wrong object + private field */
+ this.getValue(localPrivFloatField, plainObj, 'F',
+ IllegalAccessException.class);
+
+ /* wrong object + wrong field type */
+ this.getValue(subProtLongField, plainObj, 'Z',
+ IllegalArgumentException.class);
+
+ /* wrong object + invalid access */
+ localInst.getValue(otherProtShortField, plainObj, 'S',
+ IllegalAccessException.class);
+ this.getValue(otherProtShortField, plainObj, 'S',
+ IllegalAccessException.class);
+
+ System.out.println("good");
+ }
+
+ /*
+ * [this is a clone of Main.getValue() -- the class issuing the
+ * reflection call is significant]
+ */
+ public Object getValue(Field field, Object obj, char type,
+ Class expectedException) {
+
+ Object result = null;
+ try {
+ switch (type) {
+ case 'Z':
+ result = new Boolean(field.getBoolean(obj));
+ break;
+ case 'B':
+ result = new Byte(field.getByte(obj));
+ break;
+ case 'S':
+ result = new Short(field.getShort(obj));
+ break;
+ case 'C':
+ result = new Character(field.getChar(obj));
+ break;
+ case 'I':
+ result = new Integer(field.getInt(obj));
+ break;
+ case 'J':
+ result = new Long(field.getLong(obj));
+ break;
+ case 'F':
+ result = new Float(field.getFloat(obj));
+ break;
+ case 'D':
+ result = new Double(field.getDouble(obj));
+ break;
+ case 'L':
+ result = field.get(obj);
+ break;
+ default:
+ throw new RuntimeException("bad type '" + type + "'");
+ }
+
+ /* success; expected? */
+ if (expectedException != null) {
+ Throwable th = new Throwable();
+ System.err.println("ERROR: call succeeded, was expecting "
+ + expectedException);
+ th.printStackTrace();
+ }
+ } catch (Exception ex) {
+ if (expectedException == null) {
+ System.err.println("ERROR: call failed unexpectedly: "
+ + ex.getClass());
+ ex.printStackTrace();
+ } else {
+ if (!expectedException.equals(ex.getClass())) {
+ System.err.println("ERROR: incorrect exception: wanted "
+ + expectedException.getName() + ", got "
+ + ex.getClass());
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ return result;
+ }
+
+}