• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.signature.cts.tests;
18 
19 import android.signature.cts.FailureType;
20 import android.signature.cts.JDiffClassDescription;
21 import android.signature.cts.ResultObserver;
22 
23 import junit.framework.Assert;
24 import junit.framework.TestCase;
25 
26 import java.lang.reflect.Modifier;
27 
28 /**
29  * Test class for JDiffClassDescription.
30  */
31 public class JDiffClassDescriptionTest extends TestCase {
32 
33     private class NoFailures implements ResultObserver {
34         @Override
notifyFailure(FailureType type, String name, String errmsg)35         public void notifyFailure(FailureType type, String name, String errmsg) {
36             Assert.fail("Saw unexpected test failure: " + name + " failure type: " + type);
37         }
38     }
39 
40     private class ExpectFailure implements ResultObserver {
41         private FailureType expectedType;
42         private boolean failureSeen;
43 
ExpectFailure(FailureType expectedType)44         public ExpectFailure(FailureType expectedType) {
45             this.expectedType = expectedType;
46         }
47 
48         @Override
notifyFailure(FailureType type, String name, String errMsg)49         public void notifyFailure(FailureType type, String name, String errMsg) {
50             if (type == expectedType) {
51                 if (failureSeen) {
52                     Assert.fail("Saw second test failure: " + name + " failure type: " + type);
53                 } else {
54                     // We've seen the error, mark it and keep going
55                     failureSeen = true;
56                 }
57             } else {
58                 Assert.fail("Saw unexpected test failure: " + name + " failure type: " + type);
59             }
60         }
61 
validate()62         public void validate() {
63             Assert.assertTrue(failureSeen);
64         }
65     }
66 
67     /**
68      * Create the JDiffClassDescription for "NormalClass".
69      *
70      * @return the new JDiffClassDescription
71      */
createNormalClass()72     private JDiffClassDescription createNormalClass() {
73         return createNormalClass(new NoFailures());
74     }
75 
76     /**
77      * Create the JDiffClassDescription for "NormalClass".
78      *
79      * @return the new JDiffClassDescription
80      */
createNormalClass(ResultObserver observer)81     private JDiffClassDescription createNormalClass(ResultObserver observer) {
82         JDiffClassDescription clz = new JDiffClassDescription(
83                 "android.signature.cts.tests.data", "NormalClass", observer);
84         clz.setType(JDiffClassDescription.JDiffType.CLASS);
85         clz.setModifier(Modifier.PUBLIC);
86         return clz;
87     }
88 
testNormalClassCompliance()89     public void testNormalClassCompliance() {
90         JDiffClassDescription clz = createNormalClass();
91         clz.checkSignatureCompliance();
92         assertEquals(clz.toSignatureString(), "public class NormalClass");
93     }
94 
testMissingClass()95     public void testMissingClass() {
96         ExpectFailure observer = new ExpectFailure(FailureType.MISSING_CLASS);
97         JDiffClassDescription clz = new JDiffClassDescription(
98                 "android.signature.cts.tests.data", "NoSuchClass", observer);
99         clz.setType(JDiffClassDescription.JDiffType.CLASS);
100         clz.checkSignatureCompliance();
101         observer.validate();
102     }
103 
testSimpleConstructor()104     public void testSimpleConstructor() {
105         JDiffClassDescription clz = createNormalClass();
106         JDiffClassDescription.JDiffConstructor constructor =
107                 new JDiffClassDescription.JDiffConstructor("NormalClass", Modifier.PUBLIC);
108         clz.addConstructor(constructor);
109         clz.checkSignatureCompliance();
110         assertEquals(constructor.toSignatureString(), "public NormalClass()");
111     }
112 
testOneArgConstructor()113     public void testOneArgConstructor() {
114         JDiffClassDescription clz = createNormalClass();
115         JDiffClassDescription.JDiffConstructor constructor =
116                 new JDiffClassDescription.JDiffConstructor("NormalClass", Modifier.PRIVATE);
117         constructor.addParam("java.lang.String");
118         clz.addConstructor(constructor);
119         clz.checkSignatureCompliance();
120         assertEquals(constructor.toSignatureString(), "private NormalClass(java.lang.String)");
121     }
122 
testConstructorThrowsException()123     public void testConstructorThrowsException() {
124         JDiffClassDescription clz = createNormalClass();
125         JDiffClassDescription.JDiffConstructor constructor =
126                 new JDiffClassDescription.JDiffConstructor("NormalClass", Modifier.PROTECTED);
127         constructor.addParam("java.lang.String");
128         constructor.addParam("java.lang.String");
129         constructor.addException("android.signature.cts.tests.data.NormalException");
130         clz.addConstructor(constructor);
131         clz.checkSignatureCompliance();
132         assertEquals(constructor.toSignatureString(),
133                 "protected NormalClass(java.lang.String, java.lang.String) " +
134                 "throws android.signature.cts.tests.data.NormalException");
135     }
136 
testPackageProtectedConstructor()137     public void testPackageProtectedConstructor() {
138         JDiffClassDescription clz = createNormalClass();
139         JDiffClassDescription.JDiffConstructor constructor =
140                 new JDiffClassDescription.JDiffConstructor("NormalClass", 0);
141         constructor.addParam("java.lang.String");
142         constructor.addParam("java.lang.String");
143         constructor.addParam("java.lang.String");
144         clz.addConstructor(constructor);
145         clz.checkSignatureCompliance();
146         assertEquals(constructor.toSignatureString(),
147                 "NormalClass(java.lang.String, java.lang.String, java.lang.String)");
148     }
149 
testStaticMethod()150     public void testStaticMethod() {
151         JDiffClassDescription clz = createNormalClass();
152         JDiffClassDescription.JDiffMethod method = new JDiffClassDescription.JDiffMethod(
153                 "staticMethod", Modifier.STATIC | Modifier.PUBLIC, "void");
154         clz.addMethod(method);
155         clz.checkSignatureCompliance();
156         assertEquals(method.toSignatureString(), "public static void staticMethod()");
157     }
158 
testSyncMethod()159     public void testSyncMethod() {
160         JDiffClassDescription clz = createNormalClass();
161         JDiffClassDescription.JDiffMethod method = new JDiffClassDescription.JDiffMethod(
162                 "syncMethod", Modifier.SYNCHRONIZED | Modifier.PUBLIC, "void");
163         clz.addMethod(method);
164         clz.checkSignatureCompliance();
165         assertEquals(method.toSignatureString(), "public synchronized void syncMethod()");
166     }
167 
testPackageProtectMethod()168     public void testPackageProtectMethod() {
169         JDiffClassDescription clz = createNormalClass();
170         JDiffClassDescription.JDiffMethod method = new JDiffClassDescription.JDiffMethod(
171                 "packageProtectedMethod", 0, "boolean");
172         clz.addMethod(method);
173         clz.checkSignatureCompliance();
174         assertEquals(method.toSignatureString(), "boolean packageProtectedMethod()");
175     }
176 
testPrivateMethod()177     public void testPrivateMethod() {
178         JDiffClassDescription clz = createNormalClass();
179         JDiffClassDescription.JDiffMethod method = new JDiffClassDescription.JDiffMethod(
180                 "privateMethod", Modifier.PRIVATE, "void");
181         clz.addMethod(method);
182         clz.checkSignatureCompliance();
183         assertEquals(method.toSignatureString(), "private void privateMethod()");
184     }
185 
testProtectedMethod()186     public void testProtectedMethod() {
187         JDiffClassDescription clz = createNormalClass();
188         JDiffClassDescription.JDiffMethod method = new JDiffClassDescription.JDiffMethod(
189                 "protectedMethod", Modifier.PROTECTED, "java.lang.String");
190         clz.addMethod(method);
191         clz.checkSignatureCompliance();
192         assertEquals(method.toSignatureString(), "protected java.lang.String protectedMethod()");
193     }
194 
testThrowsMethod()195     public void testThrowsMethod() {
196         JDiffClassDescription clz = createNormalClass();
197         JDiffClassDescription.JDiffMethod method = new JDiffClassDescription.JDiffMethod(
198                 "throwsMethod", Modifier.PUBLIC, "void");
199         method.addException("android.signature.cts.tests.data.NormalException");
200         clz.addMethod(method);
201         clz.checkSignatureCompliance();
202         assertEquals(method.toSignatureString(), "public void throwsMethod() " +
203                 "throws android.signature.cts.tests.data.NormalException");
204     }
205 
testNativeMethod()206     public void testNativeMethod() {
207         JDiffClassDescription clz = createNormalClass();
208         JDiffClassDescription.JDiffMethod method = new JDiffClassDescription.JDiffMethod(
209                 "nativeMethod", Modifier.PUBLIC | Modifier.NATIVE, "void");
210         clz.addMethod(method);
211         clz.checkSignatureCompliance();
212         assertEquals(method.toSignatureString(), "public native void nativeMethod()");
213     }
214 
testFinalField()215     public void testFinalField() {
216         JDiffClassDescription clz = createNormalClass();
217         JDiffClassDescription.JDiffField field = new JDiffClassDescription.JDiffField(
218                 "FINAL_FIELD", "java.lang.String", Modifier.PUBLIC | Modifier.FINAL);
219         clz.addField(field);
220         clz.checkSignatureCompliance();
221         assertEquals(field.toSignatureString(), "public final java.lang.String FINAL_FIELD");
222     }
223 
testStaticField()224     public void testStaticField() {
225         JDiffClassDescription clz = createNormalClass();
226         JDiffClassDescription.JDiffField field = new JDiffClassDescription.JDiffField(
227                 "STATIC_FIELD", "java.lang.String", Modifier.PUBLIC | Modifier.STATIC);
228         clz.addField(field);
229         clz.checkSignatureCompliance();
230         assertEquals(field.toSignatureString(), "public static java.lang.String STATIC_FIELD");
231     }
232 
testVolatileFiled()233     public void testVolatileFiled() {
234         JDiffClassDescription clz = createNormalClass();
235         JDiffClassDescription.JDiffField field = new JDiffClassDescription.JDiffField(
236                 "VOLATILE_FIELD", "java.lang.String", Modifier.PUBLIC | Modifier.VOLATILE);
237         clz.addField(field);
238         clz.checkSignatureCompliance();
239         assertEquals(field.toSignatureString(), "public volatile java.lang.String VOLATILE_FIELD");
240     }
241 
testTransientField()242     public void testTransientField() {
243         JDiffClassDescription clz = createNormalClass();
244         JDiffClassDescription.JDiffField field = new JDiffClassDescription.JDiffField(
245                 "TRANSIENT_FIELD", "java.lang.String", Modifier.PUBLIC | Modifier.TRANSIENT);
246         clz.addField(field);
247         clz.checkSignatureCompliance();
248         assertEquals(field.toSignatureString(),
249                 "public transient java.lang.String TRANSIENT_FIELD");
250     }
251 
testPacakgeField()252     public void testPacakgeField() {
253         JDiffClassDescription clz = createNormalClass();
254         JDiffClassDescription.JDiffField field = new JDiffClassDescription.JDiffField(
255                 "PACAKGE_FIELD", "java.lang.String", 0);
256         clz.addField(field);
257         clz.checkSignatureCompliance();
258         assertEquals(field.toSignatureString(), "java.lang.String PACAKGE_FIELD");
259     }
260 
testPrivateField()261     public void testPrivateField() {
262         JDiffClassDescription clz = createNormalClass();
263         JDiffClassDescription.JDiffField field = new JDiffClassDescription.JDiffField(
264                 "PRIVATE_FIELD", "java.lang.String", Modifier.PRIVATE);
265         clz.addField(field);
266         clz.checkSignatureCompliance();
267         assertEquals(field.toSignatureString(), "private java.lang.String PRIVATE_FIELD");
268     }
269 
testProtectedField()270     public void testProtectedField() {
271         JDiffClassDescription clz = createNormalClass();
272         JDiffClassDescription.JDiffField field = new JDiffClassDescription.JDiffField(
273                 "PROTECTED_FIELD", "java.lang.String", Modifier.PROTECTED);
274         clz.addField(field);
275         clz.checkSignatureCompliance();
276         assertEquals(field.toSignatureString(), "protected java.lang.String PROTECTED_FIELD");
277     }
278 
testInnerClass()279     public void testInnerClass() {
280         JDiffClassDescription clz = new JDiffClassDescription(
281                 "android.signature.cts.tests.data", "NormalClass.InnerClass", new NoFailures());
282         clz.setType(JDiffClassDescription.JDiffType.CLASS);
283         clz.setModifier(Modifier.PUBLIC);
284         JDiffClassDescription.JDiffField field = new JDiffClassDescription.JDiffField(
285                 "innerClassData", "java.lang.String", Modifier.PRIVATE);
286         clz.addField(field);
287         clz.checkSignatureCompliance();
288         assertEquals(clz.toSignatureString(), "public class NormalClass.InnerClass");
289     }
290 
testInnerInnerClass()291     public void testInnerInnerClass() {
292         JDiffClassDescription clz = new JDiffClassDescription(
293                 "android.signature.cts.tests.data", "NormalClass.InnerClass.InnerInnerClass",
294                 new NoFailures());
295         clz.setType(JDiffClassDescription.JDiffType.CLASS);
296         clz.setModifier(Modifier.PUBLIC);
297         JDiffClassDescription.JDiffField field = new JDiffClassDescription.JDiffField(
298                 "innerInnerClassData", "java.lang.String", Modifier.PRIVATE);
299         clz.addField(field);
300         clz.checkSignatureCompliance();
301         assertEquals(clz.toSignatureString(),
302                 "public class NormalClass.InnerClass.InnerInnerClass");
303     }
304 
testInnerInterface()305     public void testInnerInterface() {
306         JDiffClassDescription clz = new JDiffClassDescription(
307                 "android.signature.cts.tests.data", "NormalClass.InnerInterface", new NoFailures());
308         clz.setType(JDiffClassDescription.JDiffType.INTERFACE);
309         clz.setModifier(Modifier.PUBLIC | Modifier.STATIC | Modifier.ABSTRACT);
310         clz.addMethod(
311                 new JDiffClassDescription.JDiffMethod("doSomething", Modifier.PUBLIC, "void"));
312         clz.checkSignatureCompliance();
313         assertEquals(clz.toSignatureString(), "public interface NormalClass.InnerInterface");
314     }
315 
testInterface()316     public void testInterface() {
317         JDiffClassDescription clz = new JDiffClassDescription(
318                 "android.signature.cts.tests.data", "NormalInterface", new NoFailures());
319         clz.setType(JDiffClassDescription.JDiffType.INTERFACE);
320         clz.setModifier(Modifier.PUBLIC | Modifier.ABSTRACT);
321         clz.addMethod(
322                 new JDiffClassDescription.JDiffMethod("doSomething", Modifier.PUBLIC, "void"));
323         clz.checkSignatureCompliance();
324         assertEquals(clz.toSignatureString(), "public interface NormalInterface");
325     }
326 
testFinalClass()327     public void testFinalClass() {
328         JDiffClassDescription clz = new JDiffClassDescription(
329                 "android.signature.cts.tests.data", "FinalClass", new NoFailures());
330         clz.setType(JDiffClassDescription.JDiffType.CLASS);
331         clz.setModifier(Modifier.PUBLIC | Modifier.FINAL);
332         clz.checkSignatureCompliance();
333         assertEquals(clz.toSignatureString(), "public final class FinalClass");
334     }
335 
336     /**
337      * Test the case where the API declares the method not synchronized, but it
338      * actually is.
339      */
testAddingSync()340     public void testAddingSync() {
341         ExpectFailure observer = new ExpectFailure(FailureType.MISMATCH_METHOD);
342         JDiffClassDescription clz = createNormalClass(observer);
343         JDiffClassDescription.JDiffMethod method = new JDiffClassDescription.JDiffMethod(
344                 "syncMethod", Modifier.PUBLIC, "void");
345         clz.addMethod(method);
346         clz.checkSignatureCompliance();
347         observer.validate();
348     }
349 
350     /**
351      * Test the case where the API declares the method is synchronized, but it
352      * actually is not.
353      */
testRemovingSync()354     public void testRemovingSync() {
355         JDiffClassDescription clz = createNormalClass();
356         JDiffClassDescription.JDiffMethod method = new JDiffClassDescription.JDiffMethod(
357                 "notSyncMethod", Modifier.SYNCHRONIZED | Modifier.PUBLIC, "void");
358         clz.addMethod(method);
359         clz.checkSignatureCompliance();
360     }
361 
362     /**
363      * API says method is not native, but it actually is. http://b/1839558
364      */
testAddingNative()365     public void testAddingNative() {
366         JDiffClassDescription clz = createNormalClass();
367         JDiffClassDescription.JDiffMethod method = new JDiffClassDescription.JDiffMethod(
368                 "nativeMethod", Modifier.PUBLIC, "void");
369         clz.addMethod(method);
370         clz.checkSignatureCompliance();
371     }
372 
373     /**
374      * API says method is native, but actually isn't. http://b/1839558
375      */
testRemovingNative()376     public void testRemovingNative() {
377         JDiffClassDescription clz = createNormalClass();
378         JDiffClassDescription.JDiffMethod method = new JDiffClassDescription.JDiffMethod(
379                 "notNativeMethod", Modifier.NATIVE | Modifier.PUBLIC, "void");
380         clz.addMethod(method);
381         clz.checkSignatureCompliance();
382     }
383 
testAbstractClass()384     public void testAbstractClass() {
385         JDiffClassDescription clz = new JDiffClassDescription(
386                 "android.signature.cts.tests.data", "AbstractClass", new NoFailures());
387         clz.setType(JDiffClassDescription.JDiffType.CLASS);
388         clz.setModifier(Modifier.PUBLIC | Modifier.ABSTRACT);
389         clz.checkSignatureCompliance();
390         assertEquals(clz.toSignatureString(), "public abstract class AbstractClass");
391     }
392 
393     /**
394      * API lists class as abstract, reflection does not. http://b/1839622
395      */
testRemovingAbstractFromAClass()396     public void testRemovingAbstractFromAClass() {
397         JDiffClassDescription clz = new JDiffClassDescription(
398                 "android.signature.cts.tests.data", "NormalClass", new NoFailures());
399         clz.setType(JDiffClassDescription.JDiffType.CLASS);
400         clz.setModifier(Modifier.PUBLIC | Modifier.ABSTRACT);
401         clz.checkSignatureCompliance();
402     }
403 
404     /**
405      * reflection lists class as abstract, api does not. http://b/1839622
406      */
testAddingAbstractToAClass()407     public void testAddingAbstractToAClass() {
408         ExpectFailure observer = new ExpectFailure(FailureType.MISMATCH_CLASS);
409         JDiffClassDescription clz = new JDiffClassDescription(
410                 "android.signature.cts.tests.data", "AbstractClass", observer);
411         clz.setType(JDiffClassDescription.JDiffType.CLASS);
412         clz.setModifier(Modifier.PUBLIC);
413         clz.checkSignatureCompliance();
414         observer.validate();
415     }
416 
testFinalMethod()417     public void testFinalMethod() {
418         JDiffClassDescription clz = createNormalClass();
419         JDiffClassDescription.JDiffMethod method = new JDiffClassDescription.JDiffMethod(
420                 "finalMethod", Modifier.PUBLIC | Modifier.FINAL, "void");
421         clz.addMethod(method);
422         clz.checkSignatureCompliance();
423         assertEquals(method.toSignatureString(), "public final void finalMethod()");
424     }
425 
426     /**
427      * Final Class, API lists methods as non-final, reflection has it as final.
428      * http://b/1839589
429      */
testAddingFinalToAMethodInAFinalClass()430     public void testAddingFinalToAMethodInAFinalClass() {
431         JDiffClassDescription clz = new JDiffClassDescription(
432                 "android.signature.cts.tests.data", "FinalClass", new NoFailures());
433         clz.setType(JDiffClassDescription.JDiffType.CLASS);
434         clz.setModifier(Modifier.PUBLIC | Modifier.FINAL);
435         JDiffClassDescription.JDiffMethod method = new JDiffClassDescription.JDiffMethod(
436                 "finalMethod", Modifier.PUBLIC, "void");
437         clz.addMethod(method);
438         clz.checkSignatureCompliance();
439     }
440 
441     /**
442      * Final Class, API lists methods as final, reflection has it as non-final.
443      * http://b/1839589
444      */
testRemovingFinalToAMethodInAFinalClass()445     public void testRemovingFinalToAMethodInAFinalClass() {
446         JDiffClassDescription clz = new JDiffClassDescription(
447                 "android.signature.cts.tests.data", "FinalClass", new NoFailures());
448         clz.setType(JDiffClassDescription.JDiffType.CLASS);
449         clz.setModifier(Modifier.PUBLIC | Modifier.FINAL);
450         JDiffClassDescription.JDiffMethod method = new JDiffClassDescription.JDiffMethod(
451                 "nonFinalMethod", Modifier.PUBLIC | Modifier.FINAL, "void");
452         clz.addMethod(method);
453         clz.checkSignatureCompliance();
454     }
455 
456     /**
457      * non-final Class, API lists methods as non-final, reflection has it as
458      * final. http://b/1839589
459      */
testAddingFinalToAMethodInANonFinalClass()460     public void testAddingFinalToAMethodInANonFinalClass() {
461         ExpectFailure observer = new ExpectFailure(FailureType.MISMATCH_METHOD);
462         JDiffClassDescription clz = new JDiffClassDescription(
463                 "android.signature.cts.tests.data", "NormalClass", observer);
464         clz.setType(JDiffClassDescription.JDiffType.CLASS);
465         clz.setModifier(Modifier.PUBLIC);
466         JDiffClassDescription.JDiffMethod method = new JDiffClassDescription.JDiffMethod(
467                 "finalMethod", Modifier.PUBLIC, "void");
468         clz.addMethod(method);
469         clz.checkSignatureCompliance();
470         observer.validate();
471     }
472 }
473