Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a80df6b8 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

[Ravenwood] Relax the test method name validator

Previously, the validator didn't allow this:

@Before public testSetUp() {...}

It'd say "testSetUp() should have @Test".

But I see this naming pattern in ICU, so let's allow it.

Bug: 292141694
Test: $ANDROID_BUILD_TOP/frameworks/base/ravenwood/scripts/run-ravenwood-tests.sh
Flag: EXEMPT host side test change only
Change-Id: Ifef932cb07816bac9edb624a725accbbf8e7d63d
parent 88d75700
Loading
Loading
Loading
Loading
+51 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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 com.android.ravenwoodtest.coretest.methodvalidation;

import android.platform.test.ravenwood.RavenwoodRule;

import androidx.test.runner.AndroidJUnit4;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;

/**
 * RavenwoodRule has a validator to ensure "test-looking" methods have valid JUnit annotations.
 * This class contains tests for this validator.
 */
@RunWith(AndroidJUnit4.class)
public class RavenwoodTestMethodValidation_Fail01_Test {
    private ExpectedException mThrown = ExpectedException.none();
    private final RavenwoodRule mRavenwood = new RavenwoodRule();

    @Rule
    public final RuleChain chain = RuleChain.outerRule(mThrown).around(mRavenwood);

    public RavenwoodTestMethodValidation_Fail01_Test() {
        mThrown.expectMessage("Method setUp() doesn't have @Before");
    }

    @SuppressWarnings("JUnit4SetUpNotRun")
    public void setUp() {
    }

    @Test
    public void testEmpty() {
    }
}
+51 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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 com.android.ravenwoodtest.coretest.methodvalidation;

import android.platform.test.ravenwood.RavenwoodRule;

import androidx.test.runner.AndroidJUnit4;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;

/**
 * RavenwoodRule has a validator to ensure "test-looking" methods have valid JUnit annotations.
 * This class contains tests for this validator.
 */
@RunWith(AndroidJUnit4.class)
public class RavenwoodTestMethodValidation_Fail02_Test {
    private ExpectedException mThrown = ExpectedException.none();
    private final RavenwoodRule mRavenwood = new RavenwoodRule();

    @Rule
    public final RuleChain chain = RuleChain.outerRule(mThrown).around(mRavenwood);

    public RavenwoodTestMethodValidation_Fail02_Test() {
        mThrown.expectMessage("Method tearDown() doesn't have @After");
    }

    @SuppressWarnings("JUnit4TearDownNotRun")
    public void tearDown() {
    }

    @Test
    public void testEmpty() {
    }
}
+51 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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 com.android.ravenwoodtest.coretest.methodvalidation;

import android.platform.test.ravenwood.RavenwoodRule;

import androidx.test.runner.AndroidJUnit4;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;

/**
 * RavenwoodRule has a validator to ensure "test-looking" methods have valid JUnit annotations.
 * This class contains tests for this validator.
 */
@RunWith(AndroidJUnit4.class)
public class RavenwoodTestMethodValidation_Fail03_Test {
    private ExpectedException mThrown = ExpectedException.none();
    private final RavenwoodRule mRavenwood = new RavenwoodRule();

    @Rule
    public final RuleChain chain = RuleChain.outerRule(mThrown).around(mRavenwood);

    public RavenwoodTestMethodValidation_Fail03_Test() {
        mThrown.expectMessage("Method testFoo() doesn't have @Test");
    }

    @SuppressWarnings("JUnit4TestNotRun")
    public void testFoo() {
    }

    @Test
    public void testEmpty() {
    }
}
+56 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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 com.android.ravenwoodtest.coretest.methodvalidation;

import android.platform.test.ravenwood.RavenwoodRule;

import androidx.test.runner.AndroidJUnit4;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
 * RavenwoodRule has a validator to ensure "test-looking" methods have valid JUnit annotations.
 * This class contains tests for this validator.
 */
@RunWith(AndroidJUnit4.class)
public class RavenwoodTestMethodValidation_OkTest {
    @Rule
    public final RavenwoodRule mRavenwood = new RavenwoodRule();

    @Before
    public void setUp() {
    }

    @Before
    public void testSetUp() {
    }

    @After
    public void tearDown() {
    }

    @After
    public void testTearDown() {
    }

    @Test
    public void testEmpty() {
    }
}
+19 −3
Original line number Diff line number Diff line
@@ -33,14 +33,17 @@ import com.android.internal.os.RuntimeInit;
import com.android.server.LocalServices;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runners.model.Statement;

import java.io.PrintStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
@@ -230,6 +233,18 @@ public class RavenwoodRuleImpl {
        }
    }

    /**
     * @return if a method has any of annotations.
     */
    private static boolean hasAnyAnnotations(Method m, Class<? extends Annotation>... annotations) {
        for (var anno : annotations) {
            if (m.getAnnotation(anno) != null) {
                return true;
            }
        }
        return false;
    }

    private static void validateTestAnnotations(Statement base, Description description,
            boolean enableOptionalValidation) {
        final var testClass = description.getTestClass();
@@ -239,13 +254,14 @@ public class RavenwoodRuleImpl {
        boolean hasErrors = false;
        for (Method m : collectMethods(testClass)) {
            if (Modifier.isPublic(m.getModifiers()) && m.getName().startsWith("test")) {
                if (m.getAnnotation(Test.class) == null) {
                if (!hasAnyAnnotations(m, Test.class, Before.class, After.class,
                        BeforeClass.class, AfterClass.class)) {
                    message.append("\nMethod " + m.getName() + "() doesn't have @Test");
                    hasErrors = true;
                }
            }
            if ("setUp".equals(m.getName())) {
                if (m.getAnnotation(Before.class) == null) {
                if (!hasAnyAnnotations(m, Before.class)) {
                    message.append("\nMethod " + m.getName() + "() doesn't have @Before");
                    hasErrors = true;
                }
@@ -255,7 +271,7 @@ public class RavenwoodRuleImpl {
                }
            }
            if ("tearDown".equals(m.getName())) {
                if (m.getAnnotation(After.class) == null) {
                if (!hasAnyAnnotations(m, After.class)) {
                    message.append("\nMethod " + m.getName() + "() doesn't have @After");
                    hasErrors = true;
                }