Merge "Refactored ExtendedMockitoTestCase into ExtendedMockitoRule" into udc-dev

This commit is contained in:
Felipe Leme
2023-02-24 03:50:57 +00:00
committed by Android (Google) Code Review
13 changed files with 446 additions and 321 deletions

View File

@@ -0,0 +1,181 @@
/*
* 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.server;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Optional;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;
import com.google.common.collect.Table;
import com.google.common.truth.BigDecimalSubject;
import com.google.common.truth.BooleanSubject;
import com.google.common.truth.ClassSubject;
import com.google.common.truth.ComparableSubject;
import com.google.common.truth.DoubleSubject;
import com.google.common.truth.Expect;
import com.google.common.truth.FloatSubject;
import com.google.common.truth.GuavaOptionalSubject;
import com.google.common.truth.IntegerSubject;
import com.google.common.truth.IterableSubject;
import com.google.common.truth.LongSubject;
import com.google.common.truth.MapSubject;
import com.google.common.truth.MultimapSubject;
import com.google.common.truth.MultisetSubject;
import com.google.common.truth.ObjectArraySubject;
import com.google.common.truth.PrimitiveBooleanArraySubject;
import com.google.common.truth.PrimitiveByteArraySubject;
import com.google.common.truth.PrimitiveCharArraySubject;
import com.google.common.truth.PrimitiveDoubleArraySubject;
import com.google.common.truth.PrimitiveFloatArraySubject;
import com.google.common.truth.PrimitiveIntArraySubject;
import com.google.common.truth.PrimitiveLongArraySubject;
import com.google.common.truth.PrimitiveShortArraySubject;
import com.google.common.truth.StandardSubjectBuilder;
import com.google.common.truth.StringSubject;
import com.google.common.truth.Subject;
import com.google.common.truth.TableSubject;
import com.google.common.truth.ThrowableSubject;
import org.junit.Rule;
import java.math.BigDecimal;
import java.util.Map;
// NOTE: it could be a more generic AbstractTruthTestCase that provide similar methods
// for assertThat() / assertWithMessage(), but then we'd need to remove all static import imports
// from classes that indirectly extend it.
/**
* Base class to make it easier to use {@code Truth} {@link Expect} assertions.
*/
public abstract class ExpectableTestCase {
@Rule
public final Expect mExpect = Expect.create();
protected final StandardSubjectBuilder expectWithMessage(String msg) {
return mExpect.withMessage(msg);
}
protected final StandardSubjectBuilder expectWithMessage(String format, Object...args) {
return mExpect.withMessage(format, args);
}
protected final <ComparableT extends Comparable<?>> ComparableSubject<ComparableT> expectThat(
ComparableT actual) {
return mExpect.that(actual);
}
protected final BigDecimalSubject expectThat(BigDecimal actual) {
return mExpect.that(actual);
}
protected final Subject expectThat(Object actual) {
return mExpect.that(actual);
}
@GwtIncompatible("ClassSubject.java")
protected final ClassSubject expectThat(Class<?> actual) {
return mExpect.that(actual);
}
protected final ThrowableSubject expectThat(Throwable actual) {
return mExpect.that(actual);
}
protected final LongSubject expectThat(Long actual) {
return mExpect.that(actual);
}
protected final DoubleSubject expectThat(Double actual) {
return mExpect.that(actual);
}
protected final FloatSubject expectThat(Float actual) {
return mExpect.that(actual);
}
protected final IntegerSubject expectThat(Integer actual) {
return mExpect.that(actual);
}
protected final BooleanSubject expectThat(Boolean actual) {
return mExpect.that(actual);
}
protected final StringSubject expectThat(String actual) {
return mExpect.that(actual);
}
protected final IterableSubject expectThat(Iterable<?> actual) {
return mExpect.that(actual);
}
protected final <T> ObjectArraySubject<T> expectThat(T[] actual) {
return mExpect.that(actual);
}
protected final PrimitiveBooleanArraySubject expectThat(boolean[] actual) {
return mExpect.that(actual);
}
protected final PrimitiveShortArraySubject expectThat(short[] actual) {
return mExpect.that(actual);
}
protected final PrimitiveIntArraySubject expectThat(int[] actual) {
return mExpect.that(actual);
}
protected final PrimitiveLongArraySubject expectThat(long[] actual) {
return mExpect.that(actual);
}
protected final PrimitiveCharArraySubject expectThat(char[] actual) {
return mExpect.that(actual);
}
protected final PrimitiveByteArraySubject expectThat(byte[] actual) {
return mExpect.that(actual);
}
protected final PrimitiveFloatArraySubject expectThat(float[] actual) {
return mExpect.that(actual);
}
protected final PrimitiveDoubleArraySubject expectThat(double[] actual) {
return mExpect.that(actual);
}
protected final GuavaOptionalSubject expectThat(Optional<?> actual) {
return mExpect.that(actual);
}
protected final MapSubject expectThat(Map<?, ?> actual) {
return mExpect.that(actual);
}
protected final MultimapSubject expectThat(Multimap<?, ?> actual) {
return mExpect.that(actual);
}
protected final MultisetSubject expectThat(Multiset<?> actual) {
return mExpect.that(actual);
}
protected final TableSubject expectThat(Table<?, ?, ?> actual) {
return mExpect.that(actual);
}
}

View File

@@ -0,0 +1,183 @@
/*
* 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.server;
import android.annotation.Nullable;
import android.util.Log;
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
import com.android.internal.util.Preconditions;
import com.android.modules.utils.testing.StaticMockFixture;
import com.android.modules.utils.testing.StaticMockFixtureRule;
import org.mockito.Mockito;
import org.mockito.quality.Strictness;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Rule to make it easier to use Extended Mockito.
*
* <p>It's derived from {@link StaticMockFixtureRule}, with the additional features:
*
* <ul>
* <li>Easier to define which classes must be statically mocked or spied
* <li>Automatically starts mocking (so tests don't need a mockito runner or rule)
* <li>Automatically clears the inlined mocks at the end (to avoid OOM)
* <li>Allows other customization like strictness
* </ul>
*/
public final class ExtendedMockitoRule extends StaticMockFixtureRule {
private static final String TAG = ExtendedMockitoRule.class.getSimpleName();
private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
private final Object mTestClassInstance;
private final Strictness mStrictness;
private ExtendedMockitoRule(Builder builder) {
super(() -> new SimpleStatickMockFixture(builder.mMockedStaticClasses,
builder.mSpiedStaticClasses, builder.mDynamicSessionBuilderConfigurator,
builder.mAfterSessionFinishedCallback));
mTestClassInstance = builder.mTestClassInstance;
mStrictness = builder.mStrictness;
if (VERBOSE) {
Log.v(TAG, "strictness=" + mStrictness + ", testClassInstance" + mTestClassInstance
+ ", mockedStaticClasses=" + builder.mMockedStaticClasses
+ ", spiedStaticClasses=" + builder.mSpiedStaticClasses
+ ", dynamicSessionBuilderConfigurator="
+ builder.mDynamicSessionBuilderConfigurator
+ ", afterSessionFinishedCallback=" + builder.mAfterSessionFinishedCallback);
}
}
@Override
public StaticMockitoSessionBuilder getSessionBuilder() {
StaticMockitoSessionBuilder sessionBuilder = super.getSessionBuilder();
if (mStrictness != null) {
if (VERBOSE) {
Log.v(TAG, "Setting strictness to " + mStrictness + " on " + sessionBuilder);
}
sessionBuilder.strictness(mStrictness);
}
return sessionBuilder.initMocks(mTestClassInstance);
}
public static final class Builder {
private final Object mTestClassInstance;
private @Nullable Strictness mStrictness;
private final List<Class<?>> mMockedStaticClasses = new ArrayList<>();
private final List<Class<?>> mSpiedStaticClasses = new ArrayList<>();
private @Nullable Visitor<StaticMockitoSessionBuilder> mDynamicSessionBuilderConfigurator;
private @Nullable Runnable mAfterSessionFinishedCallback;
public Builder(Object testClassInstance) {
mTestClassInstance = Objects.requireNonNull(testClassInstance);
}
public Builder setStrictness(Strictness strictness) {
mStrictness = Objects.requireNonNull(strictness);
return this;
}
public Builder mockStatic(Class<?> clazz) {
Objects.requireNonNull(clazz);
Preconditions.checkState(!mMockedStaticClasses.contains(clazz),
"class %s already mocked", clazz);
mMockedStaticClasses.add(clazz);
return this;
}
public Builder spyStatic(Class<?> clazz) {
Objects.requireNonNull(clazz);
Preconditions.checkState(!mSpiedStaticClasses.contains(clazz),
"class %s already spied", clazz);
mSpiedStaticClasses.add(clazz);
return this;
}
public Builder dynamiclyConfigureSessionBuilder(
Visitor<StaticMockitoSessionBuilder> dynamicSessionBuilderConfigurator) {
mDynamicSessionBuilderConfigurator = Objects
.requireNonNull(dynamicSessionBuilderConfigurator);
return this;
}
public Builder afterSessionFinished(Runnable runnable) {
mAfterSessionFinishedCallback = Objects.requireNonNull(runnable);
return this;
}
public ExtendedMockitoRule build() {
return new ExtendedMockitoRule(this);
}
}
private static final class SimpleStatickMockFixture implements StaticMockFixture {
private final List<Class<?>> mMockedStaticClasses;
private final List<Class<?>> mSpiedStaticClasses;
@Nullable
private final Visitor<StaticMockitoSessionBuilder> mDynamicSessionBuilderConfigurator;
@Nullable
private final Runnable mAfterSessionFinishedCallback;
private SimpleStatickMockFixture(List<Class<?>> mockedStaticClasses,
List<Class<?>> spiedStaticClasses,
@Nullable Visitor<StaticMockitoSessionBuilder> dynamicSessionBuilderConfigurator,
@Nullable Runnable afterSessionFinishedCallback) {
mMockedStaticClasses = mockedStaticClasses;
mSpiedStaticClasses = spiedStaticClasses;
mDynamicSessionBuilderConfigurator = dynamicSessionBuilderConfigurator;
mAfterSessionFinishedCallback = afterSessionFinishedCallback;
}
@Override
public StaticMockitoSessionBuilder setUpMockedClasses(
StaticMockitoSessionBuilder sessionBuilder) {
mMockedStaticClasses.forEach((c) -> sessionBuilder.mockStatic(c));
mSpiedStaticClasses.forEach((c) -> sessionBuilder.spyStatic(c));
if (mDynamicSessionBuilderConfigurator != null) {
mDynamicSessionBuilderConfigurator.visit(sessionBuilder);
}
return sessionBuilder;
}
@Override
public void setUpMockBehaviors() {
}
@Override
public void tearDown() {
try {
if (mAfterSessionFinishedCallback != null) {
mAfterSessionFinishedCallback.run();
}
} finally {
if (VERBOSE) {
Log.v(TAG, "calling Mockito.framework().clearInlineMocks()");
}
// When using inline mock maker, clean up inline mocks to prevent OutOfMemory
// errors. See https://github.com/mockito/mockito/issues/1614 and b/259280359.
Mockito.framework().clearInlineMocks();
}
}
}
}

View File

@@ -1,249 +0,0 @@
/*
* Copyright (C) 2022 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.server;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import android.annotation.Nullable;
import android.util.Log;
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
import com.google.common.truth.Expect;
import com.google.common.truth.StandardSubjectBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.RuleChain;
import org.mockito.Mockito;
import org.mockito.MockitoSession;
import org.mockito.quality.Strictness;
import java.lang.reflect.Constructor;
/**
* Base class to make it easier to write tests that uses {@code ExtendedMockito}.
*
*/
public abstract class ExtendedMockitoTestCase {
private static final String TAG = ExtendedMockitoTestCase.class.getSimpleName();
private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
/**
* Number of invocations, used to force a failure on {@link #forceFailure(int, Class, String)}.
*/
private static int sInvocationsCounter;
/**
* Sessions follow the "Highlander Rule": There can be only one!
*
* <p>So, we keep track of that and force-close it if needed.
*/
@Nullable
private static MockitoSession sHighlanderSession;
/**
* Points to where the current session was created.
*/
private static Exception sSessionCreationLocation;
private MockitoSession mSession;
protected final Expect mExpect = Expect.create();
protected final DumpableDumperRule mDumpableDumperRule = new DumpableDumperRule();
@Rule
public final RuleChain mTwoRingsOfPowerAndOneChainToRuleThemAll = RuleChain
.outerRule(mDumpableDumperRule)
.around(mExpect);
public ExtendedMockitoTestCase() {
sInvocationsCounter++;
}
@Before
public final void startSession() {
if (VERBOSE) {
Log.v(TAG, "startSession() for " + getTestName() + " on thread "
+ Thread.currentThread() + "; sHighlanderSession=" + sHighlanderSession);
}
createSessionLocation();
finishHighlanderSessionIfNeeded("startSession()");
StaticMockitoSessionBuilder builder = mockitoSession()
.initMocks(this)
.strictness(getSessionStrictness());
initializeSession(builder);
sHighlanderSession = mSession = builder.startMocking();
}
private void createSessionLocation() {
try {
sSessionCreationLocation = new Exception(getTestName());
} catch (Exception e) {
// Better safe than sorry...
Log.e(TAG, "Could not create sSessionCreationLocation with " + getTestName()
+ " on thread " + Thread.currentThread(), e);
sSessionCreationLocation = e;
}
}
/**
* Gets the session strictness.
*
* @return {@link Strictness.LENIENT} by default; subclasses can override.
*/
protected Strictness getSessionStrictness() {
return Strictness.LENIENT;
}
/**
* Initializes the mockito session.
*
* <p>Typically used to define which classes should have static methods mocked or spied.
*/
protected void initializeSession(StaticMockitoSessionBuilder builder) {
if (VERBOSE) {
Log.v(TAG, "initializeSession()");
}
}
@After
public final void finishSession() throws Exception {
if (false) { // For obvious reasons, should NEVER be merged as true
forceFailure(1, RuntimeException.class, "to simulate an unfinished session");
}
// mSession.finishMocking() must ALWAYS be called (hence the over-protective try/finally
// statements), otherwise it would cause failures on future tests as mockito
// cannot start a session when a previous one is not finished
try {
if (VERBOSE) {
Log.v(TAG, "finishSession() for " + getTestName() + " on thread "
+ Thread.currentThread() + "; sHighlanderSession=" + sHighlanderSession);
}
} finally {
sHighlanderSession = null;
finishSessionMocking();
afterSessionFinished();
}
}
/**
* Called after the mockito session was finished
*
* <p>This method should be used by subclasses that MUST do their cleanup after the session is
* finished (as methods marked with {@link After} in the subclasses would be called BEFORE
* that).
*/
protected void afterSessionFinished() {
if (VERBOSE) {
Log.v(TAG, "afterSessionFinished()");
}
}
private void finishSessionMocking() {
if (mSession == null) {
Log.w(TAG, getClass().getSimpleName() + ".finishSession(): no session");
return;
}
try {
mSession.finishMocking();
} finally {
// Shouldn't need to set mSession to null as JUnit always instantiate a new object,
// but it doesn't hurt....
mSession = null;
// When using inline mock maker, clean up inline mocks to prevent OutOfMemory
// errors. See https://github.com/mockito/mockito/issues/1614 and b/259280359.
Mockito.framework().clearInlineMocks();
}
}
private void finishHighlanderSessionIfNeeded(String where) {
if (sHighlanderSession == null) {
if (VERBOSE) {
Log.v(TAG, "finishHighlanderSessionIfNeeded(): sHighlanderSession already null");
}
return;
}
if (sSessionCreationLocation != null) {
if (VERBOSE) {
Log.e(TAG, where + ": There can be only one! Closing unfinished session, "
+ "created at", sSessionCreationLocation);
} else {
Log.e(TAG, where + ": There can be only one! Closing unfinished session, "
+ "created at " + sSessionCreationLocation);
}
} else {
Log.e(TAG, where + ": There can be only one! Closing unfinished session created at "
+ "unknown location");
}
try {
sHighlanderSession.finishMocking();
} catch (Throwable t) {
if (VERBOSE) {
Log.e(TAG, "Failed to close unfinished session on " + getTestName(), t);
} else {
Log.e(TAG, "Failed to close unfinished session on " + getTestName() + ": " + t);
}
} finally {
if (VERBOSE) {
Log.v(TAG, "Resetting sHighlanderSession at finishHighlanderSessionIfNeeded()");
}
sHighlanderSession = null;
}
}
/**
* Forces a failure at the given invocation of a test method by throwing an exception.
*/
protected final <T extends Throwable> void forceFailure(int invocationCount,
Class<T> failureClass, String reason) throws T {
if (sInvocationsCounter != invocationCount) {
Log.d(TAG, "forceFailure(" + invocationCount + "): no-op on invocation #"
+ sInvocationsCounter);
return;
}
String message = "Throwing on invocation #" + sInvocationsCounter + ": " + reason;
Log.e(TAG, message);
T throwable;
try {
Constructor<T> constructor = failureClass.getConstructor(String.class);
throwable = constructor.newInstance("Throwing on invocation #" + sInvocationsCounter
+ ": " + reason);
} catch (Exception e) {
throw new IllegalArgumentException("Could not create exception of class " + failureClass
+ " using msg='" + message + "' as constructor");
}
throw throwable;
}
protected final @Nullable String getTestName() {
return mDumpableDumperRule.getTestName();
}
protected final StandardSubjectBuilder expectWithMessage(String msg) {
return mExpect.withMessage(msg);
}
protected final StandardSubjectBuilder expectWithMessage(String format, Object...args) {
return mExpect.withMessage(format, args);
}
}

View File

@@ -0,0 +1,23 @@
/*
* 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.server;
/**
* Generic visitor.
*/
public interface Visitor<V> {
void visit(V visitee);
}

View File

@@ -159,7 +159,6 @@ import android.util.SparseArray;
import androidx.test.runner.AndroidJUnit4; import androidx.test.runner.AndroidJUnit4;
import com.android.dx.mockito.inline.extended.MockedVoidMethod; import com.android.dx.mockito.inline.extended.MockedVoidMethod;
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsCallback;
import com.android.internal.app.IAppOpsService; import com.android.internal.app.IAppOpsService;
@@ -168,7 +167,7 @@ import com.android.server.AlarmManagerInternal;
import com.android.server.AppStateTracker; import com.android.server.AppStateTracker;
import com.android.server.AppStateTrackerImpl; import com.android.server.AppStateTrackerImpl;
import com.android.server.DeviceIdleInternal; import com.android.server.DeviceIdleInternal;
import com.android.server.ExtendedMockitoTestCase; import com.android.server.ExtendedMockitoRule;
import com.android.server.LocalServices; import com.android.server.LocalServices;
import com.android.server.SystemClockTime.TimeConfidence; import com.android.server.SystemClockTime.TimeConfidence;
import com.android.server.SystemService; import com.android.server.SystemService;
@@ -182,6 +181,7 @@ import com.android.server.usage.AppStandbyInternal;
import libcore.util.EmptyArray; import libcore.util.EmptyArray;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Answers; import org.mockito.Answers;
@@ -204,7 +204,7 @@ import java.util.function.LongConsumer;
@Presubmit @Presubmit
@SuppressWarnings("GuardedBy") // This test enforces synchronous behavior. @SuppressWarnings("GuardedBy") // This test enforces synchronous behavior.
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public final class AlarmManagerServiceTest extends ExtendedMockitoTestCase { public final class AlarmManagerServiceTest {
private static final String TAG = AlarmManagerServiceTest.class.getSimpleName(); private static final String TAG = AlarmManagerServiceTest.class.getSimpleName();
private static final int SYSTEM_UI_UID = 12345; private static final int SYSTEM_UI_UID = 12345;
private static final int TEST_CALLING_USER = UserHandle.getUserId(TEST_CALLING_UID); private static final int TEST_CALLING_USER = UserHandle.getUserId(TEST_CALLING_UID);
@@ -411,14 +411,9 @@ public final class AlarmManagerServiceTest extends ExtendedMockitoTestCase {
} }
} }
@Override @Rule
protected Strictness getSessionStrictness() { public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
return Strictness.WARN; .setStrictness(Strictness.WARN)
}
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
builder
.spyStatic(ActivityManager.class) .spyStatic(ActivityManager.class)
.mockStatic(CompatChanges.class) .mockStatic(CompatChanges.class)
.spyStatic(DateFormat.class) .spyStatic(DateFormat.class)
@@ -431,8 +426,10 @@ public final class AlarmManagerServiceTest extends ExtendedMockitoTestCase {
.mockStatic(ServiceManager.class) .mockStatic(ServiceManager.class)
.mockStatic(Settings.Global.class) .mockStatic(Settings.Global.class)
.mockStatic(SystemProperties.class) .mockStatic(SystemProperties.class)
.spyStatic(UserHandle.class); .spyStatic(UserHandle.class)
} .afterSessionFinished(
() -> LocalServices.removeServiceForTest(AlarmManagerInternal.class))
.build();
@Before @Before
public final void setUp() { public final void setUp() {
@@ -3805,9 +3802,4 @@ public final class AlarmManagerServiceTest extends ExtendedMockitoTestCase {
mListener.removeListenerAlarmsForCachedUid(TEST_CALLING_UID_2); mListener.removeListenerAlarmsForCachedUid(TEST_CALLING_UID_2);
assertEquals(2, mService.mAlarmsPerUid.get(TEST_CALLING_UID_2)); assertEquals(2, mService.mAlarmsPerUid.get(TEST_CALLING_UID_2));
} }
@Override
public void afterSessionFinished() {
LocalServices.removeServiceForTest(AlarmManagerInternal.class);
}
} }

View File

@@ -31,11 +31,11 @@ import android.os.UserManager;
import android.util.Log; import android.util.Log;
import android.view.Display; import android.view.Display;
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder; import com.android.server.ExtendedMockitoRule;
import com.android.server.ExtendedMockitoTestCase;
import com.android.server.am.ActivityManagerService.Injector; import com.android.server.am.ActivityManagerService.Injector;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mock; import org.mockito.Mock;
@@ -45,7 +45,7 @@ import java.util.Arrays;
* Run as {@code atest * Run as {@code atest
* FrameworksMockingServicesTests:com.android.server.am.ActivityManagerServiceInjectorTest} * FrameworksMockingServicesTests:com.android.server.am.ActivityManagerServiceInjectorTest}
*/ */
public final class ActivityManagerServiceInjectorTest extends ExtendedMockitoTestCase { public final class ActivityManagerServiceInjectorTest {
private static final String TAG = ActivityManagerServiceInjectorTest.class.getSimpleName(); private static final String TAG = ActivityManagerServiceInjectorTest.class.getSimpleName();
@@ -63,10 +63,10 @@ public final class ActivityManagerServiceInjectorTest extends ExtendedMockitoTes
when(mContext.getSystemService(DisplayManager.class)).thenReturn(mDisplayManager); when(mContext.getSystemService(DisplayManager.class)).thenReturn(mDisplayManager);
} }
@Override @Rule
protected void initializeSession(StaticMockitoSessionBuilder builder) { public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
builder.spyStatic(UserManager.class); .spyStatic(UserManager.class)
} .build();
@Test @Test
public void testGetDisplayIdsForStartingBackgroundUsers_notSupported() { public void testGetDisplayIdsForStartingBackgroundUsers_notSupported() {

View File

@@ -78,18 +78,15 @@ import android.util.Pair;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.FrameworkStatsLog;
import com.android.server.ExtendedMockitoTestCase; import com.android.server.ExtendedMockitoRule;
import com.android.server.am.BroadcastQueueTest.SyncBarrier; import com.android.server.am.BroadcastQueueTest.SyncBarrier;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.PrintWriter; import java.io.PrintWriter;
@@ -98,8 +95,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
@SmallTest @SmallTest
@RunWith(MockitoJUnitRunner.class) public final class BroadcastQueueModernImplTest {
public class BroadcastQueueModernImplTest extends ExtendedMockitoTestCase {
private static final int TEST_UID = android.os.Process.FIRST_APPLICATION_UID; private static final int TEST_UID = android.os.Process.FIRST_APPLICATION_UID;
private static final int TEST_UID2 = android.os.Process.FIRST_APPLICATION_UID + 1; private static final int TEST_UID2 = android.os.Process.FIRST_APPLICATION_UID + 1;
@@ -118,15 +114,13 @@ public class BroadcastQueueModernImplTest extends ExtendedMockitoTestCase {
BroadcastProcessQueue mHead; BroadcastProcessQueue mHead;
@Override @Rule
protected void initializeSession(StaticMockitoSessionBuilder builder) { public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
builder.spyStatic(FrameworkStatsLog.class); .spyStatic(FrameworkStatsLog.class)
} .build();
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mHandlerThread = new HandlerThread(getClass().getSimpleName()); mHandlerThread = new HandlerThread(getClass().getSimpleName());
mHandlerThread.start(); mHandlerThread.start();

View File

@@ -40,9 +40,8 @@ import android.text.TextUtils;
import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.platform.app.InstrumentationRegistry;
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
import com.android.modules.utils.testing.TestableDeviceConfig; import com.android.modules.utils.testing.TestableDeviceConfig;
import com.android.server.ExtendedMockitoTestCase; import com.android.server.ExtendedMockitoRule;
import com.android.server.LocalServices; import com.android.server.LocalServices;
import com.android.server.ServiceThread; import com.android.server.ServiceThread;
import com.android.server.appop.AppOpsService; import com.android.server.appop.AppOpsService;
@@ -69,7 +68,7 @@ import java.util.concurrent.TimeUnit;
* atest FrameworksMockingServicesTests:CachedAppOptimizerTest * atest FrameworksMockingServicesTests:CachedAppOptimizerTest
*/ */
@Presubmit @Presubmit
public final class CachedAppOptimizerTest extends ExtendedMockitoTestCase { public final class CachedAppOptimizerTest {
private ServiceThread mThread; private ServiceThread mThread;
@@ -93,10 +92,11 @@ public final class CachedAppOptimizerTest extends ExtendedMockitoTestCase {
public final ApplicationExitInfoTest.ServiceThreadRule public final ApplicationExitInfoTest.ServiceThreadRule
mServiceThreadRule = new ApplicationExitInfoTest.ServiceThreadRule(); mServiceThreadRule = new ApplicationExitInfoTest.ServiceThreadRule();
@Override @Rule
protected void initializeSession(StaticMockitoSessionBuilder builder) { public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
mDeviceConfig.setUpMockedClasses(builder); .dynamiclyConfigureSessionBuilder(
} sessionBuilder -> mDeviceConfig.setUpMockedClasses(sessionBuilder))
.build();
@Before @Before
public void setUp() { public void setUp() {

View File

@@ -29,7 +29,7 @@ import android.content.res.AssetManager;
import android.util.Log; import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import com.android.server.ExtendedMockitoTestCase; import com.android.server.ExpectableTestCase;
import libcore.io.Streams; import libcore.io.Streams;
@@ -44,7 +44,7 @@ import java.io.OutputStream;
import java.util.Objects; import java.util.Objects;
/** This class contains unit tests for the {@link CpuInfoReader}. */ /** This class contains unit tests for the {@link CpuInfoReader}. */
public final class CpuInfoReaderTest extends ExtendedMockitoTestCase { public final class CpuInfoReaderTest extends ExpectableTestCase {
private static final String TAG = CpuInfoReaderTest.class.getSimpleName(); private static final String TAG = CpuInfoReaderTest.class.getSimpleName();
private static final String ROOT_DIR_NAME = "CpuInfoReaderTest"; private static final String ROOT_DIR_NAME = "CpuInfoReaderTest";
private static final String VALID_CPUSET_DIR = "valid_cpuset"; private static final String VALID_CPUSET_DIR = "valid_cpuset";
@@ -426,7 +426,7 @@ public final class CpuInfoReaderTest extends ExtendedMockitoTestCase {
.isNull(); .isNull();
} }
private static void compareCpuInfos(String message, private void compareCpuInfos(String message,
SparseArray<CpuInfoReader.CpuInfo> expected, SparseArray<CpuInfoReader.CpuInfo> expected,
SparseArray<CpuInfoReader.CpuInfo> actual) { SparseArray<CpuInfoReader.CpuInfo> actual) {
assertWithMessage("%s. Total CPU infos", message).that(actual.size()) assertWithMessage("%s. Total CPU infos", message).that(actual.size())
@@ -435,7 +435,7 @@ public final class CpuInfoReaderTest extends ExtendedMockitoTestCase {
int cpuCoreId = expected.keyAt(i); int cpuCoreId = expected.keyAt(i);
CpuInfoReader.CpuInfo expectedCpuInfo = expected.valueAt(i); CpuInfoReader.CpuInfo expectedCpuInfo = expected.valueAt(i);
CpuInfoReader.CpuInfo actualCpuInfo = actual.get(cpuCoreId); CpuInfoReader.CpuInfo actualCpuInfo = actual.get(cpuCoreId);
assertWithMessage("%s. Core %d's CPU info", message, cpuCoreId).that(actualCpuInfo) expectWithMessage("%s. Core %s's CPU info", message, cpuCoreId).that(actualCpuInfo)
.isEqualTo(expectedCpuInfo); .isEqualTo(expectedCpuInfo);
} }
} }

View File

@@ -32,16 +32,16 @@ import android.os.HandlerExecutor;
import android.os.Looper; import android.os.Looper;
import android.os.ServiceManager; import android.os.ServiceManager;
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder; import com.android.server.ExtendedMockitoRule;
import com.android.server.ExtendedMockitoTestCase;
import com.android.server.LocalServices; import com.android.server.LocalServices;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mock; import org.mockito.Mock;
public final class CpuMonitorServiceTest extends ExtendedMockitoTestCase { public final class CpuMonitorServiceTest {
private static final CpuAvailabilityMonitoringConfig TEST_CPU_AVAILABILITY_MONITORING_CONFIG = private static final CpuAvailabilityMonitoringConfig TEST_CPU_AVAILABILITY_MONITORING_CONFIG =
new CpuAvailabilityMonitoringConfig.Builder(CPUSET_ALL) new CpuAvailabilityMonitoringConfig.Builder(CPUSET_ALL)
.addThreshold(30).addThreshold(70).build(); .addThreshold(30).addThreshold(70).build();
@@ -56,10 +56,10 @@ public final class CpuMonitorServiceTest extends ExtendedMockitoTestCase {
private HandlerExecutor mHandlerExecutor; private HandlerExecutor mHandlerExecutor;
private CpuMonitorInternal mLocalService; private CpuMonitorInternal mLocalService;
@Override @Rule
protected void initializeSession(StaticMockitoSessionBuilder builder) { public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
builder.mockStatic(ServiceManager.class); .mockStatic(ServiceManager.class)
} .build();
@Before @Before
public void setUp() { public void setUp() {

View File

@@ -40,9 +40,8 @@ import android.util.SparseArray;
import androidx.test.annotation.UiThreadTest; import androidx.test.annotation.UiThreadTest;
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
import com.android.internal.widget.LockSettingsInternal; import com.android.internal.widget.LockSettingsInternal;
import com.android.server.ExtendedMockitoTestCase; import com.android.server.ExtendedMockitoRule;
import com.android.server.LocalServices; import com.android.server.LocalServices;
import com.android.server.am.UserState; import com.android.server.am.UserState;
import com.android.server.pm.UserManagerService.UserData; import com.android.server.pm.UserManagerService.UserData;
@@ -50,13 +49,14 @@ import com.android.server.storage.DeviceStorageMonitorInternal;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mock; import org.mockito.Mock;
/** /**
* Run as {@code atest FrameworksMockingServicesTests:com.android.server.pm.UserManagerServiceTest} * Run as {@code atest FrameworksMockingServicesTests:com.android.server.pm.UserManagerServiceTest}
*/ */
public final class UserManagerServiceTest extends ExtendedMockitoTestCase { public final class UserManagerServiceTest {
private static final String TAG = UserManagerServiceTest.class.getSimpleName(); private static final String TAG = UserManagerServiceTest.class.getSimpleName();
@@ -84,6 +84,13 @@ public final class UserManagerServiceTest extends ExtendedMockitoTestCase {
*/ */
private static final int PROFILE_USER_ID = 643; private static final int PROFILE_USER_ID = 643;
@Rule
public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
.spyStatic(UserManager.class)
.spyStatic(LocalServices.class)
.mockStatic(Settings.Global.class)
.build();
private final Object mPackagesLock = new Object(); private final Object mPackagesLock = new Object();
private final Context mRealContext = androidx.test.InstrumentationRegistry.getInstrumentation() private final Context mRealContext = androidx.test.InstrumentationRegistry.getInstrumentation()
.getTargetContext(); .getTargetContext();
@@ -109,14 +116,6 @@ public final class UserManagerServiceTest extends ExtendedMockitoTestCase {
*/ */
private UserManagerInternal mUmi; private UserManagerInternal mUmi;
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
builder
.spyStatic(UserManager.class)
.spyStatic(LocalServices.class)
.mockStatic(Settings.Global.class);
}
@Before @Before
@UiThreadTest // Needed to initialize main handler @UiThreadTest // Needed to initialize main handler
public void setFixtures() { public void setFixtures() {

View File

@@ -20,8 +20,6 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY; import static android.view.Display.INVALID_DISPLAY;
import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_FAILURE; import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_FAILURE;
import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_ALREADY_VISIBLE;
import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE;
import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE; import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE;
import static com.android.server.pm.UserVisibilityChangedEvent.onInvisible; import static com.android.server.pm.UserVisibilityChangedEvent.onInvisible;
import static com.android.server.pm.UserVisibilityChangedEvent.onVisible; import static com.android.server.pm.UserVisibilityChangedEvent.onVisible;
@@ -128,7 +126,8 @@ public final class UserVisibilityMediatorMUPANDTest
listener.verify(); listener.verify();
} }
/* TODO: re-add
/* TODO(b/261538337): re-add after the reverted CL is merged again
@Test @Test
public void public void

View File

@@ -45,7 +45,8 @@ import android.util.IntArray;
import android.util.Log; import android.util.Log;
import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions;
import com.android.server.ExtendedMockitoTestCase; import com.android.server.DumpableDumperRule;
import com.android.server.ExpectableTestCase;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -64,7 +65,7 @@ import java.util.Arrays;
* is visible, display associated to the user, etc...) for each scenario (full user started on fg, * is visible, display associated to the user, etc...) for each scenario (full user started on fg,
* profile user started on bg, etc...). * profile user started on bg, etc...).
*/ */
abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase { abstract class UserVisibilityMediatorTestCase extends ExpectableTestCase {
private static final String TAG = UserVisibilityMediatorTestCase.class.getSimpleName(); private static final String TAG = UserVisibilityMediatorTestCase.class.getSimpleName();
@@ -125,6 +126,8 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
mBackgroundUserOnDefaultDisplayAllowed = backgroundUserOnDefaultDisplayAllowed; mBackgroundUserOnDefaultDisplayAllowed = backgroundUserOnDefaultDisplayAllowed;
} }
protected final DumpableDumperRule mDumpableDumperRule = new DumpableDumperRule();
@Before @Before
public final void setFixtures() { public final void setFixtures() {
mHandler = Handler.getMain(); mHandler = Handler.getMain();