blob: 90dada9e1bc1111ba9c4f0d435ecaa1b317dfca6 [file] [log] [blame]
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.signature.cts.tests;
import android.signature.cts.AnnotationChecker;
import android.signature.cts.ClassProvider;
import android.signature.cts.FailureType;
import android.signature.cts.JDiffClassDescription;
import android.signature.cts.ResultObserver;
import android.signature.cts.tests.data.ApiAnnotation;
import java.lang.reflect.Modifier;
import org.junit.Test;
import org.junit.runners.JUnit4;
import org.junit.runner.RunWith;
/**
* Test class for {@link android.signature.cts.AnnotationChecker}.
*/
@RunWith(JUnit4.class)
public class AnnotationCheckerTest extends AbstractApiCheckerTest<AnnotationChecker> {
@Override
protected AnnotationChecker createChecker(ResultObserver resultObserver,
ClassProvider provider) {
return new AnnotationChecker(resultObserver, provider,
"@android.signature.cts.tests.data.ApiAnnotation()");
}
private static void addConstructor(JDiffClassDescription clz, String... paramTypes) {
JDiffClassDescription.JDiffConstructor constructor = new JDiffClassDescription.JDiffConstructor(
clz.getShortClassName(), Modifier.PUBLIC);
if (paramTypes != null) {
for (String type : paramTypes) {
constructor.addParam(type);
}
}
clz.addConstructor(constructor);
}
private static void addPublicVoidMethod(JDiffClassDescription clz, String name) {
clz.addMethod(method(name, Modifier.PUBLIC, "void"));
}
private static void addPublicBooleanField(JDiffClassDescription clz, String name) {
JDiffClassDescription.JDiffField field = new JDiffClassDescription.JDiffField(
name, "boolean", Modifier.PUBLIC, VALUE);
clz.addField(field);
}
/**
* Documented API and runtime classes are exactly matched.
*/
@Test
public void testExactApiMatch() {
JDiffClassDescription clz = createClass("SystemApiClass");
addConstructor(clz);
addPublicVoidMethod(clz, "apiMethod");
addPublicBooleanField(clz, "apiField");
checkSignatureCompliance(clz,
"android.signature.cts.tests.data.PublicApiClass",
"android.signature.cts.tests.data.ForciblyPublicizedPrivateClass");
clz = createClass("PublicApiClass");
addConstructor(clz);
addPublicVoidMethod(clz, "apiMethod");
addPublicBooleanField(clz, "apiField");
checkSignatureCompliance(clz,
"android.signature.cts.tests.data.SystemApiClass",
"android.signature.cts.tests.data.ForciblyPublicizedPrivateClass");
}
/**
* A constructor is found in the runtime class, but not in the documented API
*/
@Test
public void testDetectUnauthorizedConstructorApi() {
ExpectFailure observer = new ExpectFailure(FailureType.EXTRA_METHOD);
JDiffClassDescription clz = createClass("SystemApiClass");
// (omitted) addConstructor(clz);
addPublicVoidMethod(clz, "apiMethod");
addPublicBooleanField(clz, "apiField");
checkSignatureCompliance(clz, observer,
"android.signature.cts.tests.data.PublicApiClass",
"android.signature.cts.tests.data.ForciblyPublicizedPrivateClass");
observer.validate();
observer = new ExpectFailure(FailureType.EXTRA_METHOD);
clz = createClass("PublicApiClass");
// (omitted) addConstructor(clz);
addPublicVoidMethod(clz, "apiMethod");
addPublicBooleanField(clz, "apiField");
checkSignatureCompliance(clz, observer,
"android.signature.cts.tests.data.SystemApiClass",
"android.signature.cts.tests.data.ForciblyPublicizedPrivateClass");
observer.validate();
}
/**
* A method is found in the runtime class, but not in the documented API
*/
@Test
public void testDetectUnauthorizedMethodApi() {
ExpectFailure observer = new ExpectFailure(FailureType.EXTRA_METHOD);
JDiffClassDescription clz = createClass("SystemApiClass");
addConstructor(clz);
// (omitted) addPublicVoidMethod(clz, "apiMethod");
addPublicBooleanField(clz, "apiField");
checkSignatureCompliance(clz, observer,
"android.signature.cts.tests.data.PublicApiClass",
"android.signature.cts.tests.data.ForciblyPublicizedPrivateClass");
observer.validate();
observer = new ExpectFailure(FailureType.EXTRA_METHOD);
clz = createClass("PublicApiClass");
addConstructor(clz);
// (omitted) addPublicVoidMethod(clz, "apiMethod");
addPublicBooleanField(clz, "apiField");
checkSignatureCompliance(clz, observer,
"android.signature.cts.tests.data.SystemApiClass",
"android.signature.cts.tests.data.ForciblyPublicizedPrivateClass");
observer.validate();
}
/**
* A field is found in the runtime class, but not in the documented API
*/
@Test
public void testDetectUnauthorizedFieldApi() {
ExpectFailure observer = new ExpectFailure(FailureType.EXTRA_FIELD);
JDiffClassDescription clz = createClass("SystemApiClass");
addConstructor(clz);
addPublicVoidMethod(clz, "apiMethod");
// (omitted) addPublicBooleanField(clz, "apiField");
checkSignatureCompliance(clz, observer,
"android.signature.cts.tests.data.PublicApiClass",
"android.signature.cts.tests.data.ForciblyPublicizedPrivateClass");
observer.validate();
observer = new ExpectFailure(FailureType.EXTRA_FIELD);
clz = createClass("PublicApiClass");
addConstructor(clz);
addPublicVoidMethod(clz, "apiMethod");
// (omitted) addPublicBooleanField(clz, "apiField");
checkSignatureCompliance(clz, observer,
"android.signature.cts.tests.data.SystemApiClass",
"android.signature.cts.tests.data.ForciblyPublicizedPrivateClass");
observer.validate();
}
/**
* A class is found in the runtime classes, but not in the documented API
*/
@Test
public void testDetectUnauthorizedClassApi() {
ExpectFailure observer = new ExpectFailure(FailureType.EXTRA_CLASS);
JDiffClassDescription clz = createClass("SystemApiClass");
addConstructor(clz);
addPublicVoidMethod(clz, "apiMethod");
addPublicBooleanField(clz, "apiField");
checkSignatureCompliance(clz, observer,
"android.signature.cts.tests.data.PublicApiClass");
// Note that ForciblyPublicizedPrivateClass is now included in the runtime classes
observer.validate();
observer = new ExpectFailure(FailureType.EXTRA_CLASS);
clz = createClass("PublicApiClass");
addConstructor(clz);
addPublicVoidMethod(clz, "apiMethod");
addPublicBooleanField(clz, "apiField");
checkSignatureCompliance(clz, observer,
"android.signature.cts.tests.data.SystemApiClass");
// Note that ForciblyPublicizedPrivateClass is now included in the runtime classes
observer.validate();
}
/**
* A member which is declared in an annotated class is currently recognized as an API.
*/
@Test
public void testB71630695() {
// TODO(b/71630695): currently, some API members are not annotated, because
// a member is automatically added to the API set if it is in a class with
// annotation and it is not @hide. This should be fixed, but until then,
// CTS should respect the existing behavior.
JDiffClassDescription clz = createClass("SystemApiClass");
addConstructor(clz);
addPublicVoidMethod(clz, "apiMethod");
addPublicBooleanField(clz, "apiField");
addConstructor(clz, "float"); // this is not annotated
checkSignatureCompliance(clz,
"android.signature.cts.tests.data.PublicApiClass",
"android.signature.cts.tests.data.ForciblyPublicizedPrivateClass");
clz = createClass("SystemApiClass");
addConstructor(clz);
addPublicVoidMethod(clz, "apiMethod");
addPublicBooleanField(clz, "apiField");
addPublicVoidMethod(clz, "unannotatedApiMethod"); // this is not annotated
checkSignatureCompliance(clz,
"android.signature.cts.tests.data.PublicApiClass",
"android.signature.cts.tests.data.ForciblyPublicizedPrivateClass");
clz = createClass("SystemApiClass");
addConstructor(clz);
addPublicVoidMethod(clz, "apiMethod");
addPublicBooleanField(clz, "apiField");
addPublicBooleanField(clz, "unannotatedApiField"); // this is not annotated
checkSignatureCompliance(clz,
"android.signature.cts.tests.data.PublicApiClass",
"android.signature.cts.tests.data.ForciblyPublicizedPrivateClass");
}
/**
* An API is documented, but isn't annotated in the runtime class. But, due to b/71630695, this
* test can only be done for public API classes.
*/
@Test
public void testDetectMissingAnnotation() {
ExpectFailure observer = new ExpectFailure(FailureType.MISSING_ANNOTATION);
JDiffClassDescription clz = createClass("PublicApiClass");
addConstructor(clz);
addPublicVoidMethod(clz, "apiMethod");
addPublicBooleanField(clz, "apiField");
addConstructor(clz, "int"); // this is not annotated
checkSignatureCompliance(clz, observer,
"android.signature.cts.tests.data.SystemApiClass",
"android.signature.cts.tests.data.ForciblyPublicizedPrivateClass");
observer.validate();
observer = new ExpectFailure(FailureType.MISSING_ANNOTATION);
clz = createClass("PublicApiClass");
addConstructor(clz);
addPublicVoidMethod(clz, "apiMethod");
addPublicBooleanField(clz, "apiField");
addPublicVoidMethod(clz, "privateMethod"); // this is not annotated
checkSignatureCompliance(clz, observer,
"android.signature.cts.tests.data.SystemApiClass",
"android.signature.cts.tests.data.ForciblyPublicizedPrivateClass");
observer.validate();
observer = new ExpectFailure(FailureType.MISSING_ANNOTATION);
clz = createClass("PublicApiClass");
addConstructor(clz);
addPublicVoidMethod(clz, "apiMethod");
addPublicBooleanField(clz, "apiField");
addPublicBooleanField(clz, "privateField"); // this is not annotated
checkSignatureCompliance(clz, observer,
"android.signature.cts.tests.data.SystemApiClass",
"android.signature.cts.tests.data.ForciblyPublicizedPrivateClass");
observer.validate();
}
/**
* A <code>@hide</code> method should be recognized as API though it is not annotated, if it is
* overriding a method which is already an API.
*/
@Test
public void testOverriddenHidenMethodIsApi() {
JDiffClassDescription clz = createClass("PublicApiClass");
addConstructor(clz);
addPublicVoidMethod(clz, "apiMethod");
addPublicBooleanField(clz, "apiField");
addPublicVoidMethod(clz, "anOverriddenMethod"); // not annotated and @hide, but is API
checkSignatureCompliance(clz,
"android.signature.cts.tests.data.SystemApiClass",
"android.signature.cts.tests.data.ForciblyPublicizedPrivateClass");
}
}