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