* tests/regression/resolving: Added resolving test suite. These tests
authoredwin <none@none>
Fri, 2 Mar 2007 19:42:13 +0000 (19:42 +0000)
committeredwin <none@none>
Fri, 2 Mar 2007 19:42:13 +0000 (19:42 +0000)
check lazy loading, classloader handling, loading & subtype constraints.

24 files changed:
tests/regression/Makefile.am
tests/regression/resolving/Makefile.am [new file with mode: 0644]
tests/regression/resolving/TestController.java [new file with mode: 0644]
tests/regression/resolving/TestLoader.java [new file with mode: 0644]
tests/regression/resolving/classes1/BarPassFoo.java [new file with mode: 0644]
tests/regression/resolving/classes1/BarUseFoo.java [new file with mode: 0644]
tests/regression/resolving/classes1/Foo.java [new file with mode: 0644]
tests/regression/resolving/classes1/Makefile.am [new file with mode: 0644]
tests/regression/resolving/classes2/BarPassFoo.java [new file with mode: 0644]
tests/regression/resolving/classes2/BarUseFoo.java [new file with mode: 0644]
tests/regression/resolving/classes2/DerivedFoo.java [new file with mode: 0644]
tests/regression/resolving/classes2/Foo.java [new file with mode: 0644]
tests/regression/resolving/classes2/Makefile.am [new file with mode: 0644]
tests/regression/resolving/classes3/BarPassFoo.java [new file with mode: 0644]
tests/regression/resolving/classes3/BarUseFoo.java [new file with mode: 0644]
tests/regression/resolving/classes3/DerivedFoo.java [new file with mode: 0644]
tests/regression/resolving/classes3/Foo.java [new file with mode: 0644]
tests/regression/resolving/classes3/Makefile.am [new file with mode: 0644]
tests/regression/resolving/test_instance_subtype_violated.java [new file with mode: 0644]
tests/regression/resolving/test_param_loading_constraint_violated.java [new file with mode: 0644]
tests/regression/resolving/test_param_loading_constraint_violated_derived.java [new file with mode: 0644]
tests/regression/resolving/test_param_subtype_violated.java [new file with mode: 0644]
tests/regression/resolving/test_retval_loading_constraint_violated.java [new file with mode: 0644]
tests/regression/resolving/test_simple_lazy_load.java [new file with mode: 0644]

index b65c6eed48f1ba6378997394e7c24bb12d09bfc0..c02f75e31cb44e9ccb4ec15f13e749b5d18988c1 100644 (file)
 ##
 ## Authors: Christian Thalinger
 ##
-## $Id: Makefile.am 6257 2006-12-28 13:43:06Z twisti $
+## $Id: Makefile.am 7433 2007-03-02 19:42:13Z edwin $
 
 ## Process this file with automake to produce Makefile.in
 
 SUBDIRS = \
        codepatching \
        jasmin \
-       native
+       native \
+       resolving
 
 JAVA      = $(top_builddir)/src/cacao/cacao
 
diff --git a/tests/regression/resolving/Makefile.am b/tests/regression/resolving/Makefile.am
new file mode 100644 (file)
index 0000000..6d6dbf0
--- /dev/null
@@ -0,0 +1,48 @@
+SUBDIRS = \
+    classes1 \
+       classes2 \
+       classes3
+
+HARNESS_SOURCE_FILES = \
+       TestController.java \
+       TestLoader.java
+
+HARNESS_CLASS_FILES = \
+       TestController.class \
+       TestLoader.class
+
+TEST_SOURCE_FILES = \
+       test_instance_subtype_violated.java \
+       test_param_loading_constraint_violated_derived.java \
+       test_param_loading_constraint_violated.java \
+       test_param_subtype_violated.java \
+       test_retval_loading_constraint_violated.java \
+       test_simple_lazy_load.java
+
+TEST_NAMES = \
+       test_instance_subtype_violated \
+       test_param_loading_constraint_violated_derived \
+       test_param_loading_constraint_violated \
+       test_param_subtype_violated \
+       test_retval_loading_constraint_violated \
+       test_simple_lazy_load
+
+EXTRA_DIST = $(HARNESS_SOURCE_FILES) $(TEST_SOURCE_FILES)
+
+CLEANFILES = \
+       *.class
+
+JAVA      = $(top_builddir)/src/cacao/cacao
+
+if WITH_CLASSPATH_GNU
+JAVAFLAGS = -Xbootclasspath:$(top_builddir)/src/lib/classes/:$(CLASSPATH_CLASSES)
+else
+JAVAFLAGS = -Xbootclasspath:$(CLASSPATH_CLASSES)
+endif
+
+check: $(HARNESS_CLASS_FILES)
+       for t in $(TEST_NAMES) ; do echo "TEST $$t" ; { $(JAVAC) $$t.java && $(JAVA) $$t ; } || exit 1 ; done
+
+$(HARNESS_CLASS_FILES): $(HARNESS_SOURCE_FILES)
+       $(JAVAC) $(HARNESS_SOURCE_FILES)
+
diff --git a/tests/regression/resolving/TestController.java b/tests/regression/resolving/TestController.java
new file mode 100644 (file)
index 0000000..478482c
--- /dev/null
@@ -0,0 +1,273 @@
+import java.util.Vector;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+public class TestController {
+
+    boolean report_class_ids_ = false;
+    Vector expectations_ = new Vector();
+    boolean failed_ = false;
+
+    class Expectation {
+        String tag_;
+        String loader1_;
+        String loader2_;
+        String class_;
+
+        public Expectation(String tag, String ld1, String ld2, String cls) {
+            tag_ = tag;
+            loader1_ = ld1;
+            loader2_ = ld2;
+            class_ = cls;
+        }
+
+        public Expectation(String tag, String ld1, String cls) {
+            this(tag, ld1, null, cls);
+        }
+
+        public boolean matches(String tag, String ld1, String ld2, String cls) {
+            return tag_.equals(tag)
+                && loader1_.equals(ld1)
+                && ((loader2_ == ld2) || ((loader2_ != null) && (ld2 != null) && loader2_.equals(ld2)))
+                && class_.equals(cls);
+        }
+    }
+
+    public void setReportClassIDs(boolean rep) {
+        report_class_ids_ = rep;
+    }
+
+    void expect(Expectation exp) {
+        expectations_.add(exp);
+    }
+
+    void expect(String tag, String loader, String classname) {
+        expect(new Expectation(tag, loader, classname));
+    }
+
+    void expect(String tag, String loader1, String loader2, String classname) {
+        expect(new Expectation(tag, loader1, loader2, classname));
+    }
+
+    public void expect(String tag, ClassLoader loader, String classname) {
+        expect(tag, loaderName(loader), classname);
+    }
+
+    public void expect(String tag, ClassLoader loader1, ClassLoader loader2, String classname) {
+        expect(tag, loaderName(loader1), loaderName(loader2), classname);
+    }
+
+    public void expectLoadFromSystem(ClassLoader loader, String classname) {
+        expect("requested", loader, classname);
+        expect("delegated", loader, ClassLoader.getSystemClassLoader(), classname);
+        expect("loaded", loader, "<" + classname + ">");
+    }
+
+    public void expectDelegationAndDefinition(ClassLoader loader1, ClassLoader loader2, String classname) {
+        expect("requested", loader1, classname);
+        expect("delegated", loader1, loader2, classname);
+        expect("requested", loader2, classname);
+        expect("defined", loader2, "<" + classname + ">");
+        expect("loaded", loader1, "<" + classname + ">");
+    }
+
+    public void expectDelegationAndFound(ClassLoader loader1, ClassLoader loader2, String classname) {
+        expect("requested", loader1, classname);
+        expect("delegated", loader1, loader2, classname);
+        expect("requested", loader2, classname);
+        expect("found", loader2, "<" + classname + ">");
+        expect("loaded", loader1, "<" + classname + ">");
+    }
+
+    void fail(String message) {
+        log("FAIL: " + message);
+        failed_ = true;
+    }
+
+    void ok(String message) {
+        log("ok: " + message);
+    }
+
+    void fail(String message, String tag, String ld1, String ld2, String cls) {
+        fail(message + ": " + tag + " " + ld1 + " " + ld2 + " class=" + cls);
+    }
+
+    void ok(String tag, String ld1, String ld2, String cls) {
+        ok(tag + " " + ld1 + " " + ld2 + " class=" + cls);
+    }
+
+    public void expectEnd() {
+        if (expectations_.size() != 0)
+            fail("missing reports");
+        else
+            ok("got all expected reports");
+    }
+
+    public void checkStringGetter(Class cls, String methodname, String expected) {
+        String id = invokeStringGetter(cls, methodname);
+        if (id == null)
+            fail("could not get return value of " + methodname + "()");
+        else if (id.equals(expected))
+            ok("returned string matches: " + id);
+        else
+            fail("wrong string returned: " + id + ", expected: " + expected);
+    }
+
+    public void checkStringGetterMustFail(Class cls, String methodname) {
+        String id = invokeStringGetter(cls, methodname);
+        if (id == null)
+            ok("method invocation failed as expected: " + methodname + "()");
+        else 
+            fail("method invocation did not fail as expected: " + methodname + "()");
+    }
+
+    public void checkClassId(Class cls, String expected) {
+        String id = getClassId(cls);
+        if (id == null)
+            fail("could not get class id");
+        else if (id.equals(expected))
+            ok("class id matches: " + id);
+        else
+            fail("wrong class id: " + id + ", expected: " + expected);
+    }
+
+    public synchronized void match(String tag, String ld1, String ld2, String cls) {
+        if (expectations_.size() == 0) {
+            fail("unexpected", tag, ld1, ld2, cls);
+        }
+        else {
+            Expectation exp = (Expectation) expectations_.firstElement();
+
+            if (exp.matches(tag, ld1, ld2, cls)) {
+                expectations_.remove(0);
+                ok(tag, ld1, ld2, cls);
+            }
+            else {
+                fail("unexpected", tag, ld1, ld2, cls);
+            }
+        }
+    }
+
+    void report(String tag, String loader, String classname) {
+        match(tag, loader, null, classname);
+    }
+
+    void report(String tag, String loader1, String loader2, String classname) {
+        match(tag, loader1, loader2, classname);
+    }
+
+    void report(String tag, ClassLoader loader, String classname) {
+        report(tag, loaderName(loader), classname);
+    }
+
+    void report(String tag, ClassLoader loader, Class cls) {
+        report(tag, loaderName(loader), className(cls));
+    }
+
+    void report(String tag, ClassLoader loader1, ClassLoader loader2, String classname) {
+        report(tag, loaderName(loader1), loaderName(loader2), classname);
+    }
+
+    public void reportRequest(ClassLoader loader, String classname) {
+        report("requested", loader, classname);
+    }
+
+    public void reportUnexpectedClassRequested(ClassLoader loader, String classname) {
+        report("unexpected class requested", loader, classname);
+    }
+
+    public void reportDelegation(ClassLoader loader, ClassLoader delegate, String classname) {
+        report("delegated", loaderName(loader), loaderName(delegate), classname);
+    }
+
+    public void reportDefinition(ClassLoader loader, Class cls) {
+        report("defined", loaderName(loader), className(cls));
+    }
+
+    public void reportFoundLoaded(ClassLoader loader, Class cls) {
+        report("found", loaderName(loader), className(cls));
+    }
+
+    public void reportLoaded(ClassLoader loader, Class cls) {
+        report("loaded", loaderName(loader), className(cls));
+    }
+
+    public void reportClassNotFound(ClassLoader loader, String classname, ClassNotFoundException e) {
+        report("class not found", loaderName(loader), classname);
+    }
+
+    public void reportException(Class cls, Throwable ex) {
+        report("exception", ex.getClass().getName(), className(cls));
+        log("exception was: " + ex);
+        // ex.printStackTrace(System.out);
+    }
+
+    public Class loadClass(ClassLoader loader, String classname) {
+        try {
+            Class cls = loader.loadClass(classname);
+
+            reportLoaded(loader, cls);
+
+            return cls;
+        }
+        catch (ClassNotFoundException e) {
+            reportClassNotFound(loader, classname, e);
+        }
+
+        return null;
+    }
+
+    public void log(String str) {
+        System.out.println(str);
+    }
+
+    public String loaderName(ClassLoader loader) {
+        if (loader == ClassLoader.getSystemClassLoader())
+            return "<SystemClassLoader>";
+
+        return (loader == null) ? "<null>" : loader.toString();
+    }
+
+    public String invokeStringGetter(Class cls, String methodname) {
+        try {
+            Method mid = cls.getMethod(methodname, null);
+
+            String id = (String) mid.invoke(null, null);
+
+            return id;
+        }
+        catch (NoSuchMethodException e) {
+            return null;
+        }
+        catch (InvocationTargetException e) {
+            reportException(cls, e.getCause());
+            return null;
+        }
+        catch (Exception e) {
+            reportException(cls, e);
+            return null;
+        }
+    }
+
+    public String getClassId(Class cls) {
+        return invokeStringGetter(cls, "id");
+    }
+
+    public String className(Class cls) {
+        if (report_class_ids_) {
+            String id = getClassId(cls);
+            if (id != null)
+                return "<" + cls.getName() + ":" + id + ">";
+        }
+
+        return "<" + cls.getName() + ">";
+    }
+
+    public void exit() {
+        expectEnd();
+        System.exit(failed_ ? 1 : 0);
+    }
+
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/TestLoader.java b/tests/regression/resolving/TestLoader.java
new file mode 100644 (file)
index 0000000..157eef8
--- /dev/null
@@ -0,0 +1,123 @@
+import java.util.Hashtable;
+import java.io.*;
+
+public class TestLoader extends ClassLoader {
+
+    Hashtable registry_;
+    String name_;
+    TestController controller_;
+
+    class Entry {
+    }
+
+    class ClassfileEntry extends Entry {
+        public String filename_;
+        public ClassfileEntry(String filename) { filename_ = filename; }
+    }
+
+    class DelegationEntry extends Entry {
+        public ClassLoader loader_;
+        public DelegationEntry(ClassLoader loader) { loader_ = loader; }
+    }
+
+    class SuperDelegationEntry extends Entry {
+    }
+
+    public TestLoader(ClassLoader parent, String name, TestController controller) {
+        super(parent);
+        name_ = name;
+        controller_ = controller;
+        registry_ = new Hashtable();
+    }
+
+    public void addClassfile(String classname, String filename) {
+        registry_.put(classname, new ClassfileEntry(filename));
+    }
+
+    public void addDelegation(String classname, ClassLoader loader) {
+        registry_.put(classname, new DelegationEntry(loader));
+    }
+
+    public void addParentDelegation(String classname) {
+        registry_.put(classname, new DelegationEntry(getParent()));
+    }
+
+    public void addSuperDelegation(String classname) {
+        registry_.put(classname, new SuperDelegationEntry());
+    }
+
+    public String toString() {
+        return "TestLoader<" + name_ + ">";
+    }
+
+    public Class loadClass(String classname) throws ClassNotFoundException {
+        controller_.reportRequest(this, classname);
+
+        Entry entry = (Entry) registry_.get(classname);
+
+        if (entry == null) {
+            controller_.reportUnexpectedClassRequested(this, classname);
+            throw new ClassNotFoundException(this + " does not know how to load class " + classname);
+        }
+
+        if (entry instanceof ClassfileEntry) {
+            Class cls = findLoadedClass(classname);
+
+            if (cls != null) {
+                controller_.reportFoundLoaded(this, cls);
+                return cls;
+            }
+
+            String filename = ((ClassfileEntry)entry).filename_;
+
+            try {
+                byte[] bytes = slurpFile(filename);
+
+                cls = defineClass(classname, bytes, 0, bytes.length);
+
+                controller_.reportDefinition(this, cls);
+
+                return cls;
+            }
+            catch (Exception e) {
+                throw new ClassNotFoundException(e.toString());
+            }
+        }
+        else if (entry instanceof DelegationEntry) {
+            ClassLoader delegate = ((DelegationEntry)entry).loader_;
+
+            controller_.reportDelegation(this, delegate, classname);
+
+            Class cls = delegate.loadClass(classname);
+
+            controller_.reportLoaded(this, cls);
+
+            return cls;
+        }
+
+        throw new ClassNotFoundException("unknown TestLoader entry: " + entry);
+    }
+
+    byte[] slurpFile(String filename) throws IOException {
+        File file = new File(filename);
+        InputStream is = new FileInputStream(file);
+        long len = file.length();
+        if (len > Integer.MAX_VALUE)
+            throw new IOException("file " + file.getName() + " is too large");
+        byte[] bytes = new byte[(int) len];
+
+        int ofs = 0;
+        int read = 0;
+        while ((ofs < len) && (read = is.read(bytes, ofs, bytes.length - ofs)) >= 0)
+            ofs += read;
+
+        if (ofs < len)
+            throw new IOException("error reading file " + file.getName());
+
+        is.close();
+        return bytes;
+    }
+}
+
+// vim: et sw=4
+
diff --git a/tests/regression/resolving/classes1/BarPassFoo.java b/tests/regression/resolving/classes1/BarPassFoo.java
new file mode 100644 (file)
index 0000000..b5aba27
--- /dev/null
@@ -0,0 +1,11 @@
+public class BarPassFoo {
+    public static String id() {
+        return "classes1/BarPassFoo";
+    }
+
+    public Foo createFoo() {
+        return null;
+    }
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/classes1/BarUseFoo.java b/tests/regression/resolving/classes1/BarUseFoo.java
new file mode 100644 (file)
index 0000000..df1923b
--- /dev/null
@@ -0,0 +1,22 @@
+public class BarUseFoo {
+    public static String id() {
+        return "classes1/BarUseFoo";
+    }
+
+    public static String idOfFoo() {
+        return Foo.id();
+    }
+
+    public String useFoo(Foo foo) {
+        return foo.virtualId();
+    }
+
+    public static String useReturnedFoo() {
+        BarPassFoo bpf = new BarPassFoo();
+        Foo foo = bpf.createFoo();
+        return foo.virtualId();
+    }
+}
+
+// vim: et sw=4
+
diff --git a/tests/regression/resolving/classes1/Foo.java b/tests/regression/resolving/classes1/Foo.java
new file mode 100644 (file)
index 0000000..3510eb5
--- /dev/null
@@ -0,0 +1,11 @@
+public class Foo {
+    public static String id() {
+        return "classes1/Foo";
+    }
+
+    public String virtualId() {
+        return id();
+    }
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/classes1/Makefile.am b/tests/regression/resolving/classes1/Makefile.am
new file mode 100644 (file)
index 0000000..320cd8b
--- /dev/null
@@ -0,0 +1,20 @@
+SOURCE_FILES = \
+       BarPassFoo.java \
+       BarUseFoo.java \
+       Foo.java
+
+CLASS_FILES = \
+       BarPassFoo.class \
+       BarUseFoo.class \
+       Foo.class
+
+EXTRA_DIST = $(SOURCE_FILES)
+
+CLEANFILES = \
+       *.class
+
+check: $(CLASS_FILES)
+
+$(CLASS_FILES): $(SOURCE_FILES)
+       $(JAVAC) $(SOURCE_FILES)
+
diff --git a/tests/regression/resolving/classes2/BarPassFoo.java b/tests/regression/resolving/classes2/BarPassFoo.java
new file mode 100644 (file)
index 0000000..23c02c1
--- /dev/null
@@ -0,0 +1,31 @@
+public class BarPassFoo {
+    public static String id() {
+        return "classes2/BarPassFoo";
+    }
+
+    public static String passit() {
+        Foo foo = new Foo();
+        BarUseFoo bar = new BarUseFoo();
+
+        return bar.useFoo(foo);
+    }
+
+    public static String passDerivedFoo() {
+        DerivedFoo dfoo = new DerivedFoo();
+        BarUseFoo bar = new BarUseFoo();
+
+        return bar.useFoo(dfoo);
+    }
+
+    public static String passDerivedFooInstance() {
+        Foo foo = new DerivedFoo();
+
+        return foo.virtualId();
+    }
+
+    public Foo createFoo() {
+        return new Foo();
+    }
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/classes2/BarUseFoo.java b/tests/regression/resolving/classes2/BarUseFoo.java
new file mode 100644 (file)
index 0000000..4b49c25
--- /dev/null
@@ -0,0 +1,16 @@
+public class BarUseFoo {
+    public static String id() {
+        return "classes2/BarUseFoo";
+    }
+
+    public static String idOfFoo() {
+        return Foo.id();
+    }
+
+    public String useFoo(Foo foo) {
+        return "not implemented";
+    }
+}
+
+// vim: et sw=4
+
diff --git a/tests/regression/resolving/classes2/DerivedFoo.java b/tests/regression/resolving/classes2/DerivedFoo.java
new file mode 100644 (file)
index 0000000..8eb6c96
--- /dev/null
@@ -0,0 +1,7 @@
+public class DerivedFoo extends Foo {
+    public static String id() {
+        return "classes2/DerivedFoo";
+    }
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/classes2/Foo.java b/tests/regression/resolving/classes2/Foo.java
new file mode 100644 (file)
index 0000000..c091ec4
--- /dev/null
@@ -0,0 +1,11 @@
+public class Foo {
+    public static String id() {
+        return "classes2/Foo";
+    }
+
+    public String virtualId() {
+        return id();
+    }
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/classes2/Makefile.am b/tests/regression/resolving/classes2/Makefile.am
new file mode 100644 (file)
index 0000000..dc89ae4
--- /dev/null
@@ -0,0 +1,23 @@
+SOURCE_FILES = \
+       BarPassFoo.java \
+       BarUseFoo.java \
+       DerivedFoo.java \
+       Foo.java
+
+CLASS_FILES = \
+       BarPassFoo.class \
+       BarUseFoo.class \
+       DerivedFoo.class \
+       Foo.class
+
+EXTRA_DIST = $(SOURCE_FILES)
+
+CLEANFILES = \
+       *.class
+
+check: $(CLASS_FILES)
+
+$(CLASS_FILES): $(SOURCE_FILES)
+       $(JAVAC) $(SOURCE_FILES)
+
+
diff --git a/tests/regression/resolving/classes3/BarPassFoo.java b/tests/regression/resolving/classes3/BarPassFoo.java
new file mode 100644 (file)
index 0000000..0457cee
--- /dev/null
@@ -0,0 +1,21 @@
+public class BarPassFoo {
+    public static String id() {
+        return "classes3/BarPassFoo";
+    }
+
+    public static String passit() {
+        Foo foo = new Foo();
+        BarUseFoo bar = new BarUseFoo();
+
+        return bar.useFoo(foo);
+    }
+
+    public static String passDerivedFoo() {
+        DerivedFoo dfoo = new DerivedFoo();
+        BarUseFoo bar = new BarUseFoo();
+
+        return bar.useFoo(dfoo);
+    }
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/classes3/BarUseFoo.java b/tests/regression/resolving/classes3/BarUseFoo.java
new file mode 100644 (file)
index 0000000..144c1aa
--- /dev/null
@@ -0,0 +1,16 @@
+public class BarUseFoo {
+    public static String id() {
+        return "classes3/BarUseFoo";
+    }
+
+    public static String idOfFoo() {
+        return Foo.id();
+    }
+
+    public String useFoo(Foo foo) {
+        return "not implemented";
+    }
+}
+
+// vim: et sw=4
+
diff --git a/tests/regression/resolving/classes3/DerivedFoo.java b/tests/regression/resolving/classes3/DerivedFoo.java
new file mode 100644 (file)
index 0000000..01ed83f
--- /dev/null
@@ -0,0 +1,7 @@
+public class DerivedFoo extends Foo {
+    public static String id() {
+        return "classes3/DerivedFoo";
+    }
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/classes3/Foo.java b/tests/regression/resolving/classes3/Foo.java
new file mode 100644 (file)
index 0000000..5702b2d
--- /dev/null
@@ -0,0 +1,11 @@
+public class Foo {
+    public static String id() {
+        return "classes3/Foo";
+    }
+
+    public String virtualId() {
+        return "not implemented";
+    }
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/classes3/Makefile.am b/tests/regression/resolving/classes3/Makefile.am
new file mode 100644 (file)
index 0000000..dc89ae4
--- /dev/null
@@ -0,0 +1,23 @@
+SOURCE_FILES = \
+       BarPassFoo.java \
+       BarUseFoo.java \
+       DerivedFoo.java \
+       Foo.java
+
+CLASS_FILES = \
+       BarPassFoo.class \
+       BarUseFoo.class \
+       DerivedFoo.class \
+       Foo.class
+
+EXTRA_DIST = $(SOURCE_FILES)
+
+CLEANFILES = \
+       *.class
+
+check: $(CLASS_FILES)
+
+$(CLASS_FILES): $(SOURCE_FILES)
+       $(JAVAC) $(SOURCE_FILES)
+
+
diff --git a/tests/regression/resolving/test_instance_subtype_violated.java b/tests/regression/resolving/test_instance_subtype_violated.java
new file mode 100644 (file)
index 0000000..875dd9d
--- /dev/null
@@ -0,0 +1,62 @@
+public class test_instance_subtype_violated {
+
+    public static void main(String[] args) {
+        TestController ct = new TestController();
+
+        TestLoader ld1 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld1", ct);
+        TestLoader ld2 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld2", ct);
+        TestLoader ld3 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld3", ct);
+
+        ld1.addClassfile("BarUseFoo", "classes1/BarUseFoo.class");
+        ld1.addClassfile("Foo", "classes1/Foo.class");
+        ld1.addParentDelegation("java.lang.Object");
+        ld1.addParentDelegation("java.lang.String");
+
+        ld2.addClassfile("BarPassFoo", "classes2/BarPassFoo.class");
+        ld2.addDelegation("BarUseFoo", ld1);
+        ld2.addDelegation("Foo", ld1);
+        ld2.addDelegation("DerivedFoo", ld3);
+        ld2.addParentDelegation("java.lang.Object");
+        ld2.addParentDelegation("java.lang.String");
+
+        ld3.addClassfile("Foo", "classes3/Foo.class");
+        ld3.addClassfile("DerivedFoo", "classes3/DerivedFoo.class");
+        ld3.addParentDelegation("java.lang.Object");
+        ld3.addParentDelegation("java.lang.String");
+
+
+        // loading BarPassFoo
+        ct.expect("requested", ld2, "BarPassFoo");
+        ct.expect("defined", ld2, "<BarPassFoo>");
+        ct.expect("loaded", ld2, "<BarPassFoo>");
+
+        Class cls = ct.loadClass(ld2, "BarPassFoo");
+
+        // linking BarPassFoo
+        ct.expectLoadFromSystem(ld2, "java.lang.Object");
+
+        // executing BarPassFoo.passDerivedFooInstance: new DerivedFoo
+        ct.expectDelegationAndDefinition(ld2, ld3, "DerivedFoo");
+
+        // linking (ld3, DerivedFoo)
+        ct.expect("requested", ld3, "Foo");
+        ct.expect("defined", ld3, "<Foo>");
+        ct.expectLoadFromSystem(ld3, "java.lang.Object");
+
+        // resolving Foo.virtualId
+        // the deferred subtype check ((ld2, DerivedFoo) subtypeof (ld2, Foo)) is done
+        ct.expectDelegationAndDefinition(ld2, ld1, "Foo");
+        // ...linking (ld2, Foo) == (ld1, Foo)
+        ct.expectLoadFromSystem(ld1, "java.lang.Object");
+
+        // the subtype constraint ((ld2, DerivedFoo) subtypeof (ld2, Foo)) is violated
+        ct.expect("exception", "java.lang.LinkageError", "<BarPassFoo>");
+
+        ct.checkStringGetterMustFail(cls, "passDerivedFooInstance");
+
+        ct.exit();
+    }
+
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/test_param_loading_constraint_violated.java b/tests/regression/resolving/test_param_loading_constraint_violated.java
new file mode 100644 (file)
index 0000000..e4c734b
--- /dev/null
@@ -0,0 +1,53 @@
+public class test_param_loading_constraint_violated {
+
+    public static void main(String[] args) {
+        TestController ct = new TestController();
+
+        TestLoader ld1 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld1", ct);
+        TestLoader ld2 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld2", ct);
+
+        ld1.addClassfile("BarUseFoo", "classes1/BarUseFoo.class");
+        ld1.addClassfile("Foo", "classes1/Foo.class");
+        ld1.addParentDelegation("java.lang.Object");
+        ld1.addParentDelegation("java.lang.String");
+
+        ld2.addClassfile("BarPassFoo", "classes2/BarPassFoo.class");
+        ld2.addClassfile("Foo", "classes2/Foo.class");
+        ld2.addDelegation("BarUseFoo", ld1);
+        ld2.addParentDelegation("java.lang.Object");
+        ld2.addParentDelegation("java.lang.String");
+
+
+        // loading BarPassFoo
+        ct.expect("requested", ld2, "BarPassFoo");
+        ct.expect("defined", ld2, "<BarPassFoo>");
+        ct.expect("loaded", ld2, "<BarPassFoo>");
+
+        Class cls = ct.loadClass(ld2, "BarPassFoo");
+
+        // linking BarPassFoo
+        ct.expectLoadFromSystem(ld2, "java.lang.Object");
+
+        // executing BarPassFoo.passit: new Foo
+        ct.expect("requested", ld2, "Foo");
+        ct.expect("defined", ld2, "<Foo>");
+
+        // executing BarPassFoo.passit: new BarUseFoo
+        ct.expectDelegationAndDefinition(ld2, ld1, "BarUseFoo");
+        // ...linking BarUseFoo
+        ct.expectLoadFromSystem(ld1, "java.lang.Object");
+
+        // resolving Foo.virtualId() from BarUseFoo
+        ct.expect("requested", ld1, "Foo");
+
+        // the loading constraing (ld1,ld2,Foo) is violated
+        ct.expect("exception", "java.lang.LinkageError", "<BarPassFoo>");
+
+        ct.checkStringGetterMustFail(cls, "passit");
+
+        ct.exit();
+    }
+
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/test_param_loading_constraint_violated_derived.java b/tests/regression/resolving/test_param_loading_constraint_violated_derived.java
new file mode 100644 (file)
index 0000000..8ed0ec8
--- /dev/null
@@ -0,0 +1,69 @@
+public class test_param_loading_constraint_violated_derived {
+
+    public static void main(String[] args) {
+        TestController ct = new TestController();
+
+        TestLoader ld1 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld1", ct);
+        TestLoader ld2 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld2", ct);
+        TestLoader ld3 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld3", ct);
+
+        ld1.addClassfile("BarUseFoo", "classes1/BarUseFoo.class");
+        ld1.addClassfile("Foo", "classes1/Foo.class");
+        ld1.addParentDelegation("java.lang.Object");
+        ld1.addParentDelegation("java.lang.String");
+
+        ld2.addClassfile("BarPassFoo", "classes2/BarPassFoo.class");
+        ld2.addDelegation("BarUseFoo", ld1);
+        ld2.addDelegation("Foo", ld3);
+        ld2.addDelegation("DerivedFoo", ld3);
+        ld2.addParentDelegation("java.lang.Object");
+        ld2.addParentDelegation("java.lang.String");
+
+        ld3.addClassfile("Foo", "classes3/Foo.class");
+        ld3.addClassfile("DerivedFoo", "classes3/DerivedFoo.class");
+        ld3.addParentDelegation("java.lang.Object");
+        ld3.addParentDelegation("java.lang.String");
+
+
+        // loading BarPassFoo
+        ct.expect("requested", ld2, "BarPassFoo");
+        ct.expect("defined", ld2, "<BarPassFoo>");
+        ct.expect("loaded", ld2, "<BarPassFoo>");
+
+        Class cls = ct.loadClass(ld2, "BarPassFoo");
+
+        // linking BarPassFoo
+        ct.expectLoadFromSystem(ld2, "java.lang.Object");
+
+        // executing BarPassFoo.passDerivedFoo: new DerivedFoo
+        ct.expectDelegationAndDefinition(ld2, ld3, "DerivedFoo");
+
+        // linking (ld3, DerivedFoo)
+        ct.expect("requested", ld3, "Foo");
+        ct.expect("defined", ld3, "<Foo>");
+        ct.expectLoadFromSystem(ld3, "java.lang.Object");
+
+        // executing BarPassFoo.passit: new BarUseFoo
+        ct.expectDelegationAndDefinition(ld2, ld1, "BarUseFoo");
+
+        // linking BarUseFoo
+        ct.expectLoadFromSystem(ld1, "java.lang.Object");
+
+        // resolving BarUseFoo.useFoo
+        // the deferred subtype check ((ld2, DerivedFoo) subtypeof (ld2, Foo)) is done
+        ct.expectDelegationAndFound(ld2, ld3, "Foo");
+
+        // resolving Foo.virtualId() from BarUseFoo
+        ct.expect("requested", ld1, "Foo");
+
+        // the loading constraint (ld1,ld2,Foo) is violated
+        ct.expect("exception", "java.lang.LinkageError", "<BarPassFoo>");
+
+        ct.checkStringGetterMustFail(cls, "passDerivedFoo");
+
+        ct.exit();
+    }
+
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/test_param_subtype_violated.java b/tests/regression/resolving/test_param_subtype_violated.java
new file mode 100644 (file)
index 0000000..254feda
--- /dev/null
@@ -0,0 +1,64 @@
+public class test_param_subtype_violated {
+
+    public static void main(String[] args) {
+        TestController ct = new TestController();
+
+        TestLoader ld1 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld1", ct);
+        TestLoader ld2 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld2", ct);
+        TestLoader ld3 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld3", ct);
+
+        ld1.addClassfile("BarUseFoo", "classes1/BarUseFoo.class");
+        ld1.addClassfile("Foo", "classes1/Foo.class");
+        ld1.addParentDelegation("java.lang.Object");
+        ld1.addParentDelegation("java.lang.String");
+
+        ld2.addClassfile("BarPassFoo", "classes2/BarPassFoo.class");
+        ld2.addDelegation("BarUseFoo", ld1);
+        ld2.addDelegation("Foo", ld1);
+        ld2.addDelegation("DerivedFoo", ld3);
+        ld2.addParentDelegation("java.lang.Object");
+        ld2.addParentDelegation("java.lang.String");
+
+        ld3.addClassfile("Foo", "classes3/Foo.class");
+        ld3.addClassfile("DerivedFoo", "classes3/DerivedFoo.class");
+        ld3.addParentDelegation("java.lang.Object");
+        ld3.addParentDelegation("java.lang.String");
+
+
+        // loading BarPassFoo
+        ct.expect("requested", ld2, "BarPassFoo");
+        ct.expect("defined", ld2, "<BarPassFoo>");
+        ct.expect("loaded", ld2, "<BarPassFoo>");
+
+        Class cls = ct.loadClass(ld2, "BarPassFoo");
+
+        // linking BarPassFoo
+        ct.expectLoadFromSystem(ld2, "java.lang.Object");
+
+        // executing BarPassFoo.passDerivedFoo: new DerivedFoo
+        ct.expectDelegationAndDefinition(ld2, ld3, "DerivedFoo");
+        // ...linking (ld3, DerivedFoo)
+        ct.expect("requested", ld3, "Foo");
+        ct.expect("defined", ld3, "<Foo>");
+        ct.expectLoadFromSystem(ld3, "java.lang.Object");
+
+        // executing BarPassFoo.passDerivedFoo: new BarUseFoo
+        ct.expectDelegationAndDefinition(ld2, ld1, "BarUseFoo");
+        // ...linking BarUseFoo
+        ct.expectLoadFromSystem(ld1, "java.lang.Object");
+
+        // resolving BarUseFoo.useFoo
+        // the deferred subtype check ((ld2, DerivedFoo) subtypeof (ld2, Foo)) is done
+        ct.expectDelegationAndDefinition(ld2, ld1, "Foo");
+
+        // the subtype constraint ((ld2, DerivedFoo) subtypeof (ld2, Foo)) is violated
+        ct.expect("exception", "java.lang.LinkageError", "<BarPassFoo>");
+
+        ct.checkStringGetterMustFail(cls, "passDerivedFoo");
+
+        ct.exit();
+    }
+
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/test_retval_loading_constraint_violated.java b/tests/regression/resolving/test_retval_loading_constraint_violated.java
new file mode 100644 (file)
index 0000000..8893a7f
--- /dev/null
@@ -0,0 +1,50 @@
+public class test_retval_loading_constraint_violated {
+
+    public static void main(String[] args) {
+        TestController ct = new TestController();
+
+        TestLoader ld1 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld1", ct);
+        TestLoader ld2 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld2", ct);
+
+        ld1.addClassfile("BarUseFoo", "classes1/BarUseFoo.class");
+        ld1.addClassfile("Foo", "classes1/Foo.class");
+        ld1.addDelegation("BarPassFoo", ld2);
+        ld1.addParentDelegation("java.lang.Object");
+        ld1.addParentDelegation("java.lang.String");
+
+        ld2.addClassfile("BarPassFoo", "classes2/BarPassFoo.class");
+        ld2.addClassfile("Foo", "classes2/Foo.class");
+        ld2.addParentDelegation("java.lang.Object");
+        ld2.addParentDelegation("java.lang.String");
+
+
+        // loading BarUseFoo
+        ct.expect("requested", ld1, "BarUseFoo");
+        ct.expect("defined", ld1, "<BarUseFoo>");
+        ct.expect("loaded", ld1, "<BarUseFoo>");
+
+        Class cls = ct.loadClass(ld1, "BarUseFoo");
+
+        // linking BarUseFoo
+        ct.expectLoadFromSystem(ld1, "java.lang.Object");
+
+        // executing BarUseFoo.useReturnedFoo: new BarPassFoo
+        ct.expectDelegationAndDefinition(ld1, ld2, "BarPassFoo");
+        // ...linking BarPassFoo
+        ct.expectLoadFromSystem(ld2, "java.lang.Object");
+
+        // resolving BarPassFoo.createFoo
+        ct.expect("requested", ld2, "Foo");
+        ct.expect("defined", ld2, "<Foo>");
+        ct.expect("requested", ld1, "Foo");
+        // ...the loading constraing (ld1,ld2,Foo) is violated
+        ct.expect("exception", "java.lang.LinkageError", "<BarUseFoo>");
+
+        ct.checkStringGetterMustFail(cls, "useReturnedFoo");
+
+        ct.exit();
+    }
+
+}
+
+// vim: et sw=4
diff --git a/tests/regression/resolving/test_simple_lazy_load.java b/tests/regression/resolving/test_simple_lazy_load.java
new file mode 100644 (file)
index 0000000..30ca610
--- /dev/null
@@ -0,0 +1,32 @@
+public class test_simple_lazy_load {
+
+    public static void main(String[] args) {
+        TestController ct = new TestController();
+
+        TestLoader ld1 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld1", ct);
+
+        ld1.addClassfile("BarUseFoo", "classes1/BarUseFoo.class");
+        ct.expect("requested", ld1, "BarUseFoo");
+        ct.expect("defined", ld1, "<BarUseFoo>");
+        ct.expect("loaded", ld1, "<BarUseFoo>");
+        Class cls = ct.loadClass(ld1, "BarUseFoo");
+        ct.expectEnd();
+
+        ld1.addParentDelegation("java.lang.Object");
+        ct.expectLoadFromSystem(ld1, "java.lang.Object");
+        ct.checkClassId(cls, "classes1/BarUseFoo");
+        ct.expectEnd();
+
+        ld1.addClassfile("Foo", "classes1/Foo.class");
+        ct.setReportClassIDs(true);
+        ct.expect("requested", ld1, "Foo");
+        ct.expect("defined", ld1, "<Foo:classes1/Foo>");
+        ct.checkStringGetter(cls, "idOfFoo", "classes1/Foo");
+        ct.expectEnd();
+
+        ct.exit();
+    }
+
+}
+
+// vim: et sw=4