1 /* 2 * Copyright (C) 2023 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 com.android.modules.testing.utils; 18 19 import static java.lang.annotation.ElementType.ANNOTATION_TYPE; 20 import static java.lang.annotation.ElementType.CONSTRUCTOR; 21 import static java.lang.annotation.ElementType.FIELD; 22 import static java.lang.annotation.ElementType.METHOD; 23 import static java.lang.annotation.ElementType.PACKAGE; 24 import static java.lang.annotation.ElementType.TYPE; 25 26 import com.android.internal.annotations.VisibleForTesting; 27 28 import org.junit.AssumptionViolatedException; 29 import org.junit.rules.TestRule; 30 import org.junit.runner.Description; 31 import org.junit.runners.model.Statement; 32 33 import java.lang.annotation.Retention; 34 import java.lang.annotation.RetentionPolicy; 35 import java.lang.annotation.Target; 36 37 /** 38 * A JUnit Rule to skip tests that rely on <pre>@FlaggedApi</pre> symbols, if those symbols have 39 * been configured to be hidden. 40 * 41 * <p>This rule prevents the tests from breaking when public symbols are made hidden because of 42 * <pre>@FlaggedApi</pre>. To tell the JUnit framework which tests that rely on 43 * <pre>@FlaggedApi</pre> symbols, annotate the test with <pre>@FlaggedApiRule.UsesFlaggedApi</pre>. 44 * 45 * <p>Example usage: 46 * 47 * <pre> 48 * @RunWith(AndroidJUnit4.class) 49 * public class Test { 50 * @Rule 51 * public final FlaggedApiRule mFlaggedApiRule = FlaggedApiRule.getInstance(); 52 * 53 * @Test 54 * @FlaggedApiRule.UsesFlaggedApi 55 * public void testFlaggedApiSymbol() throws Exception { 56 * // test that calls a @FlaggedApi method 57 * } 58 * 59 * @Test 60 * public void testThatWillAlwaysRun() throws Eception { 61 * // test that calls a non-@FlaggedApi method 62 * } 63 * } 64 * </pre> 65 * 66 * <p>Note: because <pre>@FlaggedApiRule.UsesFlaggedApi</pre> can be completely skipped, make sure 67 * to have other tests that verify the non-<pre>@FlaggedApi</pre> parts of your code, or your test 68 * coverage may be smaller than expected. 69 * 70 * <p>Note: requires JUnit 4. 71 * 72 * @see android.annotation.FlaggedApi 73 */ 74 public abstract class FlaggedApiRule implements TestRule { 75 private static final boolean SKIP_TESTS_ANNOTATED_FLAGGED_API = false; 76 77 private static final FlaggedApiRule sInstance; 78 79 static { 80 if (SKIP_TESTS_ANNOTATED_FLAGGED_API) { 81 sInstance = new SkipTestsAnnotatedWithUsesFlaggedApiRule(); 82 } else { 83 sInstance = new DoNothingRule(); 84 } 85 } 86 getInstance()87 public static FlaggedApiRule getInstance() { 88 return sInstance; 89 } 90 91 @VisibleForTesting 92 protected static final class SkipTestsAnnotatedWithUsesFlaggedApiRule extends FlaggedApiRule { 93 @Override apply(Statement statement, Description description)94 public Statement apply(Statement statement, Description description) { 95 return new Statement() { 96 @Override 97 public void evaluate() throws Throwable { 98 if (description.getAnnotation(UsesFlaggedApi.class) != null) { 99 throw new AssumptionViolatedException("Skip @UsesFlaggedApi annotated test"); 100 } 101 statement.evaluate(); 102 } 103 }; 104 } 105 } 106 107 @VisibleForTesting 108 protected static final class DoNothingRule extends FlaggedApiRule { 109 @Override 110 public Statement apply(Statement statement, Description description) { 111 return statement; 112 } 113 } 114 115 @Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE, PACKAGE}) 116 @Retention(RetentionPolicy.RUNTIME) 117 public @interface UsesFlaggedApi {} 118 } 119