Initial import
[jpf-core.git] / src / tests / gov / nasa / jpf / test / java / lang / ClassTest.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18 /**
19  * This is a raw test class, which produces AssertionErrors for all
20  * cases we want to catch. Make double-sure we don't refer to any
21  * JPF class in here, or we start to check JPF recursively.
22  * To turn this into a Junt test, you have to write a wrapper
23  * TestCase, which just calls the testXX() methods.
24  * The Junit test cases run JPF.main explicitly by means of specifying
25  * which test case to run, but be aware of this requiring proper
26  * state clean up in JPF !
27  *
28  * KEEP IT SIMPLE - it's already bad enough we have to mimic unit tests
29  * by means of system tests (use whole JPF to check if it works), we don't
30  * want to make the observer problem worse by means of enlarging the scope
31  * JPF has to look at
32  *
33  * Note that we don't use assert expressions, because those would already
34  * depend on working java.lang.Class APIs
35  */
36 package gov.nasa.jpf.test.java.lang;
37
38 import gov.nasa.jpf.util.test.TestJPF;
39 import gov.nasa.jpf.vm.Verify;
40
41 import java.io.Serializable;
42 import java.lang.annotation.Inherited;
43 import java.lang.annotation.Retention;
44 import java.lang.annotation.RetentionPolicy;
45 import java.lang.reflect.Method;
46 import java.util.ArrayList;
47
48 import org.junit.Test;
49
50 /**
51  * test of java.lang.Class API
52  */
53 public class ClassTest extends TestJPF implements Cloneable, Serializable {
54   
55   /**************************** tests **********************************/
56   static String clsName = ClassTest.class.getName();
57
58   int data = 42; // that creates a default ctor for our newInstance test
59
60
61   @Test 
62   public void testClassForName () throws ClassNotFoundException {
63     if (verifyNoPropertyViolation()) {
64
65       Class<?> clazz = Class.forName(clsName);
66       System.out.println("loaded " + clazz.getName());
67
68       if (clazz == null) {
69         throw new RuntimeException("Class.forName() returned null object");
70       }
71
72       if (!clsName.equals(clazz.getName())) {
73         throw new RuntimeException(
74                 "getName() wrong for Class.forName() acquired class");
75       }
76     }
77   }
78   
79   @Test
80   public void testClassForNameException () throws ClassNotFoundException {
81     if (verifyUnhandledException("java.lang.ClassNotFoundException")) {
82       Class<?> clazz = Class.forName("x.y.NonExisting");
83     }
84   }
85
86   
87   static class X {
88     static {
89       System.out.println("ClassTest$X initialized");
90       Verify.incrementCounter(0);
91     }
92   }
93   
94   @Test 
95   public void testClassForNameInit () throws ClassNotFoundException {
96     if (!isJPFRun()){
97       Verify.resetCounter(0);
98     }
99     
100     if (verifyNoPropertyViolation()) {
101       Class<?> cls = Class.forName( "gov.nasa.jpf.test.java.lang.ClassTest$X", true,  this.getClass().getClassLoader());
102       System.out.println("Class.forName() returned");
103     }
104     
105     if (!isJPFRun()){
106       assertTrue( Verify.getCounter(0) == 1);
107     }
108   }
109   
110   
111   @Test 
112   public void testGetClass () {
113     if (verifyNoPropertyViolation()) {
114       Class<?> clazz = this.getClass();
115
116       if (clazz == null) {
117         throw new RuntimeException("Object.getClass() failed");
118       }
119
120       if (!clsName.equals(clazz.getName())) {
121         throw new RuntimeException(
122                 "getName() wrong for getClass() acquired class");
123       }
124     }
125   }
126
127   @Test 
128   public void testIdentity () {
129     if (verifyNoPropertyViolation()) {
130       Class<?> clazz1 = null;
131       Class<?> clazz2 = ClassTest.class;
132       Class<?> clazz3 = this.getClass();
133
134       try {
135         clazz1 = Class.forName(clsName);
136       } catch (Throwable x) {
137         x = null;  // Get rid of IDE warning
138       }
139
140       if (clazz1 != clazz2) {
141         throw new RuntimeException(
142                 "Class.forName() and class field not identical");
143       }
144
145       if (clazz2 != clazz3) {
146         throw new RuntimeException(
147                 "Object.getClass() and class field not identical");
148       }
149     }
150   }
151   
152   @Test 
153   public void testNewInstance () throws InstantiationException, IllegalAccessException {
154     if (verifyNoPropertyViolation()) {
155       Class<?> clazz = ClassTest.class;
156       ClassTest o = (ClassTest) clazz.newInstance();
157       
158       System.out.println("new instance: " + o);
159       
160       if (o.data != 42) {
161         throw new RuntimeException(
162           "Class.newInstance() failed to call default ctor");        
163       }
164     }
165   }
166   
167   static class InAccessible {
168     private InAccessible() {}
169   }
170   
171   @Test 
172   public void testNewInstanceFailAccess () throws IllegalAccessException, InstantiationException {
173     if (verifyUnhandledException("java.lang.IllegalAccessException")){
174       Class<?> clazz = InAccessible.class;
175       clazz.newInstance();
176     }
177   }
178   
179   static abstract class AbstractClass {
180   }
181     
182   @Test 
183   public void testNewInstanceFailAbstract () throws IllegalAccessException, InstantiationException {
184     if (verifyUnhandledException("java.lang.InstantiationException")){
185       Class<?> clazz = AbstractClass.class;
186       clazz.newInstance();
187     }
188   }
189   
190   
191   @Test 
192   public void testIsAssignableFrom () {
193     if (verifyNoPropertyViolation()) {
194       Class<?> clazz1 = Integer.class;
195       Class<?> clazz2 = Object.class;
196     
197       assert clazz2.isAssignableFrom(clazz1);
198   
199       assert !clazz1.isAssignableFrom(clazz2); 
200     }
201   }  
202   
203   @Test 
204   public void testInstanceOf () {
205     if (verifyNoPropertyViolation()) {
206       assert this instanceof Cloneable;
207       assert this instanceof TestJPF;
208       assert this instanceof Object;
209
210       if (this instanceof Runnable) {
211         assert false : "negative instanceof test failed";
212       }
213     }
214   }
215   
216   @Test
217   public void testAsSubclass () {
218     if (verifyNoPropertyViolation()) {
219       Class<?> clazz1 = Float.class;
220     
221       Class<? extends Number> clazz2 = clazz1.asSubclass(Number.class); 
222       assert clazz2 != null;
223       
224       try {
225         clazz1.asSubclass(String.class);
226         assert false : "testAsSubclass() failed to throw ClassCastException";
227       } catch (ClassCastException ccx) {
228         ccx = null;  // Get rid of IDE warning
229       } 
230     }    
231   }
232   
233   @SuppressWarnings("null")
234   @Test 
235   public void testClassField () {
236     if (verifyNoPropertyViolation()) {
237
238       Class<?> clazz = ClassTest.class;
239
240       if (clazz == null) {
241         throw new RuntimeException("class field not set");
242       }
243
244       if (!clsName.equals(clazz.getName())) {
245         throw new RuntimeException("getName() wrong for class field");
246       }
247     }
248   }
249
250   @Test 
251   public void testInterfaces () {
252     if (verifyNoPropertyViolation()) {
253       Class<?>[] ifc = ClassTest.class.getInterfaces();
254       if (ifc.length != 2) {
255         throw new RuntimeException("wrong number of interfaces: " + ifc.length);
256       }
257
258       int n = ifc.length;
259       String[] ifcs = {Cloneable.class.getName(), Serializable.class.getName()};
260       for (int i = 0; i < ifcs.length; i++) {
261         for (int j = 0; j < ifc.length; j++) {
262           if (ifc[j].getName().equals(ifcs[i])) {
263             n--;
264             break;
265           }
266         }
267       }
268
269       if (n != 0) {
270         throw new RuntimeException("wrong interface types: " + ifc[0].getName() + ',' + ifc[1].getName());
271       }
272     }
273   }
274   
275   
276   static class TestClassBase {
277     protected TestClassBase() {}
278     public void foo () {}
279   }
280   
281   interface TestIfc {
282     void boo();                        // 4
283     void foo();
284   }
285   
286   static abstract class TestClass extends TestClassBase implements TestIfc {
287     static {
288       System.out.println("why is TestClass.<clinit>() executed?");
289     }
290     public TestClass() {}
291     public TestClass (int a) {a = 0;}
292     @Override
293         public void foo() {}               // 1
294     void bar() {}                      // 2
295     public static void baz () {}       // 3
296     
297   }
298   
299   @Test
300   public void testMethods() {
301     if (verifyNoPropertyViolation()) {
302
303       Class<?> cls = TestClass.class;
304       Method[] methods = cls.getMethods();
305
306       boolean fooSeen=false, bazSeen=false, booSeen=false;
307
308       for (int i = 0; i < methods.length; i++) {
309         Method m = methods[i];
310         Class<?> declCls = m.getDeclaringClass();
311         String mname = m.getName();
312
313         // we don't care about the Object methods
314         if (declCls == Object.class) {
315           methods[i] = null;
316           continue;
317         }
318
319         // non-publics, <clinit> and <init> are filtered out
320
321         if (declCls == TestClass.class) {
322           if (mname.equals("foo")) {
323             methods[i] = null;
324             fooSeen = true;
325             continue;
326           }
327           if (mname.equals("baz")) {
328             methods[i] = null;
329             bazSeen = true;
330             continue;
331           }
332         }
333
334         // TestClass is abstract and doesn't implement TestIfc.boo()
335         if (declCls == TestIfc.class) {
336           if (mname.equals("boo")) {
337             methods[i] = null;
338             booSeen = true;
339             continue;
340           }
341         }
342       }
343
344       assert fooSeen : "no TestClass.foo() seen";
345       assert bazSeen : "no TestClass.baz() seen";
346       assert booSeen : "no TestIfc.boo() seen";
347
348       for (int i = 0; i < methods.length; i++) {
349         assert (methods[i] == null) : ("unexpected method in getMethods(): " +
350                   methods[i].getDeclaringClass().getName() + " : " + methods[i]);
351       }
352     }
353   }
354
355   private static class NestedClass {}
356
357   @Test 
358   public void testGetEnclosingClassExist() {
359     if (verifyNoPropertyViolation()) {
360       Class<?> clz = NestedClass.class;
361       Class<?> enclosingClass = clz.getEnclosingClass();
362       assert enclosingClass == ClassTest.class;
363     }
364   }
365
366   @Test
367   public void testGetEnclosingClassNotExist() {
368     if (verifyNoPropertyViolation()) {
369       Class<?> clz = this.getClass();
370       Class<?> enclosingClass = clz.getEnclosingClass();
371       assert enclosingClass == null;
372     }
373   }
374   
375   @Retention(RetentionPolicy.RUNTIME)
376   @Inherited
377   public @interface TestAnnotation {
378   }
379
380   @TestAnnotation()
381   public static class ParentAnnotated<E> {
382   }
383
384   public static class ChildAnnotated<E> extends ParentAnnotated {
385   }
386
387   public enum TestEnum{
388     item;
389   }
390
391   @TestAnnotation()
392   public static class TestEnclosedClass {
393     public Object foo;
394
395     public TestEnclosedClass () {
396       class LocalClass {
397       }
398       ;
399       foo = new LocalClass();
400     }
401
402     public static class MemberClass {
403     }
404
405     public Object getLocalClassObj (){
406
407       class LocalClass {
408       }
409       ;
410
411       return new LocalClass();
412     }
413
414     public Object getAnonymousClassObj (){
415       return new Object() {
416       };
417     }
418   }
419
420   @Test
421   public void localClassEnclosingClassTest (){
422     if (verifyNoPropertyViolation()){
423       TestEnclosedClass testObj = new ClassTest.TestEnclosedClass();
424       assertEquals(testObj.foo.getClass().getEnclosingClass(), TestEnclosedClass.class);
425     }
426   }
427
428   @Test
429   public void getCanonicalNameTest (){
430     if (verifyNoPropertyViolation()){
431       assertEquals(ArrayList.class.getCanonicalName(), "java.util.ArrayList");
432       assertEquals(Class.class.getCanonicalName(), "java.lang.Class");
433       assertEquals(String.class.getCanonicalName(), "java.lang.String");
434       assertEquals((new Object[0]).getClass().getCanonicalName(), "java.lang.Object[]");
435     }
436   }
437
438   @Test
439   public void getDeclaredAnnotationsTest (){
440     if (verifyNoPropertyViolation()){
441       assertTrue(ClassTest.ParentAnnotated.class.getDeclaredAnnotations().length == 1);
442       assertTrue(ChildAnnotated.class.getDeclaredAnnotations().length == 0);
443       assertTrue(ClassTest.ParentAnnotated.class.getAnnotations().length == 1);
444       assertTrue(ChildAnnotated.class.getAnnotations().length == 1);
445     }
446   }
447
448   @Test
449   public void getEnclosingConstructor () throws SecurityException, NoSuchMethodException{
450     if (verifyNoPropertyViolation()){
451       Class cls = (new ClassTest.TestEnclosedClass()).foo.getClass();
452       assertTrue(cls.getEnclosingConstructor().getDeclaringClass() == ClassTest.TestEnclosedClass.class);
453       assertEquals(cls.getEnclosingConstructor().getName(), "<init>");
454       assertNull(cls.getEnclosingMethod());
455     }
456   }
457
458   @Test
459   public void getEnclosingMethod () throws SecurityException, NoSuchMethodException{
460     if (verifyNoPropertyViolation()){
461       Class cls = (new ClassTest.TestEnclosedClass()).getLocalClassObj().getClass();
462       assertTrue(cls.getEnclosingMethod().getDeclaringClass() == ClassTest.TestEnclosedClass.class);
463       assertNull(cls.getEnclosingConstructor());
464       assertEquals(cls.getEnclosingMethod().getName(), "getLocalClassObj");
465       Method m1 = ClassTest.TestEnclosedClass.class.getMethod("getLocalClassObj", new Class[0]);
466       Method m2 = cls.getEnclosingMethod();
467       assertEquals(m1, m2);
468       assertTrue(cls.getEnclosingMethod().equals(ClassTest.TestEnclosedClass.class.getMethod("getLocalClassObj", new Class[0])));
469     }
470   }
471
472   @Test
473   public void isAnonymousClassTest (){
474     if (verifyNoPropertyViolation()){
475       Class cls = (new ClassTest.TestEnclosedClass()).getAnonymousClassObj().getClass();
476       assertTrue(cls.isAnonymousClass());
477       assertFalse(Class.class.isAnonymousClass());
478     }
479   }
480
481   @Test
482   public void isEnumTest (){
483     if (verifyNoPropertyViolation()){
484       assertTrue(TestEnum.class.isEnum());
485       assertFalse(Class.class.isEnum());
486     }
487   }
488
489   @Test
490   public void getDeclaringClassTest (){
491     if (verifyNoPropertyViolation()){
492       assertTrue(TestEnclosedClass.class.getDeclaringClass() == ClassTest.class);
493       assertNull(Class.class.getDeclaringClass());
494       Class anonymousCls = (new ClassTest.TestEnclosedClass()).getAnonymousClassObj().getClass();
495       assertNull(anonymousCls.getDeclaringClass());
496       Class localCls = (new ClassTest.TestEnclosedClass()).foo.getClass();
497       assertNull(localCls.getDeclaringClass());
498     }
499   }
500
501   @Test
502   public void isLocalClassTest (){
503     if (verifyNoPropertyViolation()){
504       TestEnclosedClass testObj = new ClassTest.TestEnclosedClass();
505       assertTrue(testObj.foo.getClass().isLocalClass());
506       assertTrue(testObj.getLocalClassObj().getClass().isLocalClass());
507       assertFalse(Class.class.isLocalClass());
508     }
509   }
510
511   @Test
512   public void isMemberClassTest (){
513     if (verifyNoPropertyViolation()){
514       assertTrue(TestEnclosedClass.MemberClass.class.isMemberClass());
515       assertFalse(Class.class.isMemberClass());
516       assertFalse(((new TestEnclosedClass()).getLocalClassObj().getClass().isMemberClass()));
517     }
518   }
519
520   @Test
521   public void isSyntheticTest (){
522     if (verifyNoPropertyViolation()){
523       assertFalse(Class.class.isSynthetic());
524     }
525   }
526
527   @Retention(RetentionPolicy.RUNTIME)
528   @Inherited
529   public @interface A9 {
530   }
531
532   @Retention(RetentionPolicy.RUNTIME)
533   public @interface A10 {
534   }
535
536   @A9()
537   public static class Parent {
538   }
539
540   @A10
541   public static class Child1 extends Parent {
542   }
543
544   public static class Child2 extends Child1 {
545   }
546
547   @Test
548   public void getAnnotationsTest (){
549     if (verifyNoPropertyViolation()){
550       assertTrue(Parent.class.getAnnotations().length == 1);
551       assertTrue(Child1.class.getAnnotations().length == 2);
552       assertTrue(Child2.class.getAnnotations().length == 1);
553     }
554   }
555   
556   @Test
557   public void testIsAnnotation(){
558     if (verifyNoPropertyViolation()){
559       assertFalse( Child2.class.isAnnotation());
560       assertTrue( A9.class.isAnnotation());
561     }
562   }
563   
564   @Test
565   public void testIsAnnotationPresent(){
566     if (verifyNoPropertyViolation()){
567       assertFalse( Child2.class.isAnnotationPresent(SuppressWarnings.class));
568       assertTrue( Child1.class.isAnnotationPresent(A10.class));
569       assertTrue( Child1.class.isAnnotationPresent(A9.class));
570       assertTrue( Child2.class.isAnnotationPresent(A9.class));
571     }    
572   }
573
574   @Test
575   public void getResourceTest() {
576     if (verifyNoPropertyViolation()){
577       Class c = ClassLoader.class;
578       assertNotNull(c.getResource("Class.class"));
579       assertNotNull(c.getResource("/java/lang/Class.class"));
580       assertNull(c.getResource("java/lang/Class.class"));
581       assertEquals(c.getResource("Class.class"),c.getResource("/java/lang/Class.class"));
582       assertNull(c.getResource("not_existing_resources"));
583     }
584   }  
585 }