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

Commit b9dbeea2 authored by Atneya Nair's avatar Atneya Nair
Browse files

Add mediatestutils and CancelAllFuturesRule

Add new utils library for media tests.

Add a CancelAllFuturesRule which cancels all registered futures on test
completion (regardless of success).

Add unit tests.

Bug: 294636572
Bug: 288333346
Test: atest CancelAllFuturesRuleTest
Change-Id: If270a6b7683515157ef356c41ea53ed872bd85d8
parent d76220ed
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
package {
    // See: http://go/android-license-faq
    // A large-scale-change added 'default_applicable_licenses' to import
    // all of the 'license_kinds' from "frameworks_base_license"
    // to get the below license kinds:
    //   SPDX-license-identifier-Apache-2.0
    default_applicable_licenses: ["frameworks_base_license"],
}

// TODO audio build defaults
java_library {
    name: "mediatestutils_host",
    host_supported: true,
    srcs: [
        "java/com/android/media/mediatestutils/CancelAllFuturesRule.java",
    ],
    static_libs: [
        "junit",
    ],
    visibility: [
        ":__subpackages__",
    ],
}

java_library {
    name: "mediatestutils",
    static_libs: [
        "mediatestutils_host",
        "junit",
    ],
    visibility: [
        "//cts/tests/tests/media:__subpackages__",
        ":__subpackages__",
    ],
}

java_test_host {
    name: "mediatestutilshosttests",
    srcs: ["javatests/**/*.java"],
    static_libs: [
        "mediatestutils_host",
        "junit",
        "truth",
    ],
    test_suites: ["general-tests"],
    test_options: {
        unit_test: true,
    },
}
+4 −0
Original line number Diff line number Diff line
# Bug component: 48436
atneya@google.com
jmtrivi@google.com
elaurent@google.com
+51 −0
Original line number Diff line number Diff line
/*
 * Copyright 2023 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.media.mediatestutils;

import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;

/**
 *
 */
public class CancelAllFuturesRule implements TestRule {
    private List<Future> mRegisteredFutures = new ArrayList<>();

    public <T extends Future<?>> T registerFuture(T future) {
        mRegisteredFutures.add(future);
        return future;
    }

    @Override
    public Statement apply(Statement base, Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                try {
                    base.evaluate();
                } finally {
                    mRegisteredFutures.forEach(f -> f.cancel(false /* shouldInterrupt */));
                }
            }
        };
    }
}
+120 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.media.mediatestutils;

import static com.google.common.truth.Truth.assertThat;

import org.junit.rules.ExpectedException;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;


@RunWith(JUnit4.class)
public class CancelAllFuturesRuleTest {

    public static class TestException extends Throwable { }

    public static class CheckFutureStatusRule implements TestRule {
        private final List<CompletableFuture> mFutures = Arrays.asList(new CompletableFuture<>(),
                new CompletableFuture<>());

        private boolean mCompleted;

        @Override
        public Statement apply(Statement base, Description description) {
            return new Statement() {
                @Override
                public void evaluate() throws Throwable {
                    try {
                        base.evaluate();
                    } finally {
                        // Intentionally suppresses original exception
                        if (mCompleted) {
                            assertThat(mFutures.get(0).isDone())
                                .isTrue();
                            assertThat(mFutures.get(0).isCancelled())
                                .isFalse();
                        } else {
                            assertThat(mFutures.get(0).isCancelled())
                                .isTrue();
                        }
                        assertThat(mFutures.get(1).isCancelled())
                            .isTrue();
                    }
                }
            };
        }

        Future getFuture(int idx) {
            return mFutures.get(idx);
        }

        void completeFirstFuture(boolean exceptionally) {
            assertThat(mFutures.get(0).complete(null))
                .isTrue();
            mCompleted = true;
        }
    }

    @Rule(order = 0)
    public ExpectedException mExpectedThrownRule = ExpectedException.none();

    @Rule(order = 1)
    public CheckFutureStatusRule mRuleVerifyerRule = new CheckFutureStatusRule();

    @Rule(order = 2)
    public CancelAllFuturesRule mCancelRule = new CancelAllFuturesRule();

    @Test
    public void testRuleCancelsFutures_whenFinishesNormally() {
        mCancelRule.registerFuture(mRuleVerifyerRule.getFuture(0));
        mCancelRule.registerFuture(mRuleVerifyerRule.getFuture(1));
        // return normally
    }

    @Test
    public void testRuleCancelsFutures_whenFinishesExceptionally() throws TestException {
        mExpectedThrownRule.expect(TestException.class);
        mCancelRule.registerFuture(mRuleVerifyerRule.getFuture(0));
        mCancelRule.registerFuture(mRuleVerifyerRule.getFuture(1));
        throw new TestException();
    }

    @Test
    public void testRuleDoesNotThrow_whenCompletesNormally() {
        mCancelRule.registerFuture(mRuleVerifyerRule.getFuture(0));
        mCancelRule.registerFuture(mRuleVerifyerRule.getFuture(1));
        mRuleVerifyerRule.completeFirstFuture(false);
    }

    @Test
    public void testRuleDoesNotThrow_whenCompletesExceptionally() {
        mCancelRule.registerFuture(mRuleVerifyerRule.getFuture(0));
        mCancelRule.registerFuture(mRuleVerifyerRule.getFuture(1));
        mRuleVerifyerRule.completeFirstFuture(false);
    }
}