Refactored ExtendedMockitoTestCase into ExtendedMockitoRule
ExtendedMockitoTestCase was created mostly for session management
(to make sure tests properly closed the session and to clear some
internal mockito state that could cause OOM), but to be really
effective, all classes would have to extend it.
Given that constraint - and the fact that there is already a rule
to facilitate session management - this CL gets rid of that super
class and provide another rule instead (which's built on top of the
existing one).
Also fixed CpuInfoReaderTest, which was using %d instead of %s on
assertWithMessage() and replace those calls by expectWithMessage()).
Bug:
Test: atest \
FrameworksMockingServicesTests:AlarmManagerServiceTest \
FrameworksMockingServicesTests:ActivityManagerServiceInjectorTest \
FrameworksMockingServicesTests:BroadcastQueueModernImplTest \
FrameworksMockingServicesTests:CachedAppOptimizerTest \
FrameworksMockingServicesTests:CpuInfoReaderTest \
FrameworksMockingServicesTests:CpuMonitorServiceTest \
FrameworksMockingServicesTests:UserManagerServiceTest \
FrameworksMockingServicesTests:UserVisibilityMediatorMUMDTest \
FrameworksMockingServicesTests:UserVisibilityMediatorMUPANDTest \
FrameworksMockingServicesTests:UserVisibilityMediatorSUSDTest
Bug: 268515318
Change-Id: I59f3ee693cbad01e9289cf069b7d039840f7c811
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -159,7 +159,6 @@ import android.util.SparseArray;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
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.app.IAppOpsCallback;
|
||||
import com.android.internal.app.IAppOpsService;
|
||||
@@ -168,7 +167,7 @@ import com.android.server.AlarmManagerInternal;
|
||||
import com.android.server.AppStateTracker;
|
||||
import com.android.server.AppStateTrackerImpl;
|
||||
import com.android.server.DeviceIdleInternal;
|
||||
import com.android.server.ExtendedMockitoTestCase;
|
||||
import com.android.server.ExtendedMockitoRule;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemClockTime.TimeConfidence;
|
||||
import com.android.server.SystemService;
|
||||
@@ -182,6 +181,7 @@ import com.android.server.usage.AppStandbyInternal;
|
||||
import libcore.util.EmptyArray;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
@@ -204,7 +204,7 @@ import java.util.function.LongConsumer;
|
||||
@Presubmit
|
||||
@SuppressWarnings("GuardedBy") // This test enforces synchronous behavior.
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public final class AlarmManagerServiceTest extends ExtendedMockitoTestCase {
|
||||
public final class AlarmManagerServiceTest {
|
||||
private static final String TAG = AlarmManagerServiceTest.class.getSimpleName();
|
||||
private static final int SYSTEM_UI_UID = 12345;
|
||||
private static final int TEST_CALLING_USER = UserHandle.getUserId(TEST_CALLING_UID);
|
||||
@@ -411,14 +411,9 @@ public final class AlarmManagerServiceTest extends ExtendedMockitoTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Strictness getSessionStrictness() {
|
||||
return Strictness.WARN;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeSession(StaticMockitoSessionBuilder builder) {
|
||||
builder
|
||||
@Rule
|
||||
public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
|
||||
.setStrictness(Strictness.WARN)
|
||||
.spyStatic(ActivityManager.class)
|
||||
.mockStatic(CompatChanges.class)
|
||||
.spyStatic(DateFormat.class)
|
||||
@@ -431,8 +426,10 @@ public final class AlarmManagerServiceTest extends ExtendedMockitoTestCase {
|
||||
.mockStatic(ServiceManager.class)
|
||||
.mockStatic(Settings.Global.class)
|
||||
.mockStatic(SystemProperties.class)
|
||||
.spyStatic(UserHandle.class);
|
||||
}
|
||||
.spyStatic(UserHandle.class)
|
||||
.afterSessionFinished(
|
||||
() -> LocalServices.removeServiceForTest(AlarmManagerInternal.class))
|
||||
.build();
|
||||
|
||||
@Before
|
||||
public final void setUp() {
|
||||
@@ -3805,9 +3802,4 @@ public final class AlarmManagerServiceTest extends ExtendedMockitoTestCase {
|
||||
mListener.removeListenerAlarmsForCachedUid(TEST_CALLING_UID_2);
|
||||
assertEquals(2, mService.mAlarmsPerUid.get(TEST_CALLING_UID_2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterSessionFinished() {
|
||||
LocalServices.removeServiceForTest(AlarmManagerInternal.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,11 +31,11 @@ import android.os.UserManager;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
|
||||
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
|
||||
import com.android.server.ExtendedMockitoTestCase;
|
||||
import com.android.server.ExtendedMockitoRule;
|
||||
import com.android.server.am.ActivityManagerService.Injector;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
|
||||
@@ -45,7 +45,7 @@ import java.util.Arrays;
|
||||
* Run as {@code atest
|
||||
* FrameworksMockingServicesTests:com.android.server.am.ActivityManagerServiceInjectorTest}
|
||||
*/
|
||||
public final class ActivityManagerServiceInjectorTest extends ExtendedMockitoTestCase {
|
||||
public final class ActivityManagerServiceInjectorTest {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeSession(StaticMockitoSessionBuilder builder) {
|
||||
builder.spyStatic(UserManager.class);
|
||||
}
|
||||
@Rule
|
||||
public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
|
||||
.spyStatic(UserManager.class)
|
||||
.build();
|
||||
|
||||
@Test
|
||||
public void testGetDisplayIdsForStartingBackgroundUsers_notSupported() {
|
||||
|
||||
@@ -78,18 +78,15 @@ import android.util.Pair;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
|
||||
import com.android.internal.util.FrameworkStatsLog;
|
||||
import com.android.server.ExtendedMockitoTestCase;
|
||||
import com.android.server.ExtendedMockitoRule;
|
||||
import com.android.server.am.BroadcastQueueTest.SyncBarrier;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
@@ -98,8 +95,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class BroadcastQueueModernImplTest extends ExtendedMockitoTestCase {
|
||||
public final class BroadcastQueueModernImplTest {
|
||||
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;
|
||||
|
||||
@@ -118,15 +114,13 @@ public class BroadcastQueueModernImplTest extends ExtendedMockitoTestCase {
|
||||
|
||||
BroadcastProcessQueue mHead;
|
||||
|
||||
@Override
|
||||
protected void initializeSession(StaticMockitoSessionBuilder builder) {
|
||||
builder.spyStatic(FrameworkStatsLog.class);
|
||||
}
|
||||
@Rule
|
||||
public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
|
||||
.spyStatic(FrameworkStatsLog.class)
|
||||
.build();
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mHandlerThread = new HandlerThread(getClass().getSimpleName());
|
||||
mHandlerThread.start();
|
||||
|
||||
|
||||
@@ -40,9 +40,8 @@ import android.text.TextUtils;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
|
||||
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
|
||||
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.ServiceThread;
|
||||
import com.android.server.appop.AppOpsService;
|
||||
@@ -69,7 +68,7 @@ import java.util.concurrent.TimeUnit;
|
||||
* atest FrameworksMockingServicesTests:CachedAppOptimizerTest
|
||||
*/
|
||||
@Presubmit
|
||||
public final class CachedAppOptimizerTest extends ExtendedMockitoTestCase {
|
||||
public final class CachedAppOptimizerTest {
|
||||
|
||||
private ServiceThread mThread;
|
||||
|
||||
@@ -93,10 +92,11 @@ public final class CachedAppOptimizerTest extends ExtendedMockitoTestCase {
|
||||
public final ApplicationExitInfoTest.ServiceThreadRule
|
||||
mServiceThreadRule = new ApplicationExitInfoTest.ServiceThreadRule();
|
||||
|
||||
@Override
|
||||
protected void initializeSession(StaticMockitoSessionBuilder builder) {
|
||||
mDeviceConfig.setUpMockedClasses(builder);
|
||||
}
|
||||
@Rule
|
||||
public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
|
||||
.dynamiclyConfigureSessionBuilder(
|
||||
sessionBuilder -> mDeviceConfig.setUpMockedClasses(sessionBuilder))
|
||||
.build();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
@@ -29,7 +29,7 @@ import android.content.res.AssetManager;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.server.ExtendedMockitoTestCase;
|
||||
import com.android.server.ExpectableTestCase;
|
||||
|
||||
import libcore.io.Streams;
|
||||
|
||||
@@ -44,7 +44,7 @@ import java.io.OutputStream;
|
||||
import java.util.Objects;
|
||||
|
||||
/** 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 ROOT_DIR_NAME = "CpuInfoReaderTest";
|
||||
private static final String VALID_CPUSET_DIR = "valid_cpuset";
|
||||
@@ -426,7 +426,7 @@ public final class CpuInfoReaderTest extends ExtendedMockitoTestCase {
|
||||
.isNull();
|
||||
}
|
||||
|
||||
private static void compareCpuInfos(String message,
|
||||
private void compareCpuInfos(String message,
|
||||
SparseArray<CpuInfoReader.CpuInfo> expected,
|
||||
SparseArray<CpuInfoReader.CpuInfo> actual) {
|
||||
assertWithMessage("%s. Total CPU infos", message).that(actual.size())
|
||||
@@ -435,7 +435,7 @@ public final class CpuInfoReaderTest extends ExtendedMockitoTestCase {
|
||||
int cpuCoreId = expected.keyAt(i);
|
||||
CpuInfoReader.CpuInfo expectedCpuInfo = expected.valueAt(i);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,16 +32,16 @@ import android.os.HandlerExecutor;
|
||||
import android.os.Looper;
|
||||
import android.os.ServiceManager;
|
||||
|
||||
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
|
||||
import com.android.server.ExtendedMockitoTestCase;
|
||||
import com.android.server.ExtendedMockitoRule;
|
||||
import com.android.server.LocalServices;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
|
||||
public final class CpuMonitorServiceTest extends ExtendedMockitoTestCase {
|
||||
public final class CpuMonitorServiceTest {
|
||||
private static final CpuAvailabilityMonitoringConfig TEST_CPU_AVAILABILITY_MONITORING_CONFIG =
|
||||
new CpuAvailabilityMonitoringConfig.Builder(CPUSET_ALL)
|
||||
.addThreshold(30).addThreshold(70).build();
|
||||
@@ -56,10 +56,10 @@ public final class CpuMonitorServiceTest extends ExtendedMockitoTestCase {
|
||||
private HandlerExecutor mHandlerExecutor;
|
||||
private CpuMonitorInternal mLocalService;
|
||||
|
||||
@Override
|
||||
protected void initializeSession(StaticMockitoSessionBuilder builder) {
|
||||
builder.mockStatic(ServiceManager.class);
|
||||
}
|
||||
@Rule
|
||||
public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
|
||||
.mockStatic(ServiceManager.class)
|
||||
.build();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
@@ -40,9 +40,8 @@ import android.util.SparseArray;
|
||||
|
||||
import androidx.test.annotation.UiThreadTest;
|
||||
|
||||
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
|
||||
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.am.UserState;
|
||||
import com.android.server.pm.UserManagerService.UserData;
|
||||
@@ -50,13 +49,14 @@ import com.android.server.storage.DeviceStorageMonitorInternal;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
@@ -84,6 +84,13 @@ public final class UserManagerServiceTest extends ExtendedMockitoTestCase {
|
||||
*/
|
||||
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 Context mRealContext = androidx.test.InstrumentationRegistry.getInstrumentation()
|
||||
.getTargetContext();
|
||||
@@ -109,14 +116,6 @@ public final class UserManagerServiceTest extends ExtendedMockitoTestCase {
|
||||
*/
|
||||
private UserManagerInternal mUmi;
|
||||
|
||||
@Override
|
||||
protected void initializeSession(StaticMockitoSessionBuilder builder) {
|
||||
builder
|
||||
.spyStatic(UserManager.class)
|
||||
.spyStatic(LocalServices.class)
|
||||
.mockStatic(Settings.Global.class);
|
||||
}
|
||||
|
||||
@Before
|
||||
@UiThreadTest // Needed to initialize main handler
|
||||
public void setFixtures() {
|
||||
|
||||
@@ -20,8 +20,6 @@ import static android.view.Display.DEFAULT_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_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.UserVisibilityChangedEvent.onInvisible;
|
||||
import static com.android.server.pm.UserVisibilityChangedEvent.onVisible;
|
||||
@@ -128,7 +126,8 @@ public final class UserVisibilityMediatorMUPANDTest
|
||||
|
||||
listener.verify();
|
||||
}
|
||||
/* TODO: re-add
|
||||
|
||||
/* TODO(b/261538337): re-add after the reverted CL is merged again
|
||||
|
||||
@Test
|
||||
public void
|
||||
|
||||
@@ -45,7 +45,8 @@ import android.util.IntArray;
|
||||
import android.util.Log;
|
||||
|
||||
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.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,
|
||||
* profile user started on bg, etc...).
|
||||
*/
|
||||
abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
|
||||
abstract class UserVisibilityMediatorTestCase extends ExpectableTestCase {
|
||||
|
||||
private static final String TAG = UserVisibilityMediatorTestCase.class.getSimpleName();
|
||||
|
||||
@@ -125,6 +126,8 @@ abstract class UserVisibilityMediatorTestCase extends ExtendedMockitoTestCase {
|
||||
mBackgroundUserOnDefaultDisplayAllowed = backgroundUserOnDefaultDisplayAllowed;
|
||||
}
|
||||
|
||||
protected final DumpableDumperRule mDumpableDumperRule = new DumpableDumperRule();
|
||||
|
||||
@Before
|
||||
public final void setFixtures() {
|
||||
mHandler = Handler.getMain();
|
||||
|
||||
Reference in New Issue
Block a user