215 lines
7.1 KiB
Java
215 lines
7.1 KiB
Java
/*
|
|
* Copyright (C) 2015 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.messaging.util;
|
|
|
|
import android.os.Looper;
|
|
|
|
import java.util.Arrays;
|
|
|
|
public final class Assert {
|
|
public static @interface RunsOnMainThread {}
|
|
public static @interface DoesNotRunOnMainThread {}
|
|
public static @interface RunsOnAnyThread {}
|
|
|
|
private static final String TEST_THREAD_SUBSTRING = "test";
|
|
|
|
private static boolean sIsEngBuild;
|
|
private static boolean sShouldCrash;
|
|
|
|
// Private constructor so no one creates this class.
|
|
private Assert() {
|
|
}
|
|
|
|
// The proguard rules will strip this method out on user/userdebug builds.
|
|
// If you change the method signature you MUST edit proguard-release.flags.
|
|
private static void setIfEngBuild() {
|
|
sShouldCrash = sIsEngBuild = true;
|
|
}
|
|
|
|
private static void refreshGservices(final BugleGservices gservices) {
|
|
sShouldCrash = sIsEngBuild;
|
|
if (!sShouldCrash) {
|
|
sShouldCrash = gservices.getBoolean(
|
|
BugleGservicesKeys.ASSERTS_FATAL,
|
|
BugleGservicesKeys.ASSERTS_FATAL_DEFAULT);
|
|
}
|
|
}
|
|
|
|
// Static initializer block to find out if we're running an eng or
|
|
// release build.
|
|
static {
|
|
setIfEngBuild();
|
|
}
|
|
|
|
// This is called from FactoryImpl once the Gservices class is initialized.
|
|
public static void initializeGservices (final BugleGservices gservices) {
|
|
gservices.registerForChanges(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
refreshGservices(gservices);
|
|
}
|
|
});
|
|
refreshGservices(gservices);
|
|
}
|
|
|
|
/**
|
|
* Halt execution if this is not an eng build.
|
|
* <p>Intended for use in code paths that should be run only for tests and never on
|
|
* a real build.
|
|
* <p>Note that this will crash on a user build even though asserts don't normally
|
|
* crash on a user build.
|
|
*/
|
|
public static void isEngBuild() {
|
|
isTrueReleaseCheck(sIsEngBuild);
|
|
}
|
|
|
|
/**
|
|
* Halt execution if this isn't the case.
|
|
*/
|
|
public static void isTrue(final boolean condition) {
|
|
if (!condition) {
|
|
fail("Expected condition to be true", false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Halt execution if this isn't the case.
|
|
*/
|
|
public static void isFalse(final boolean condition) {
|
|
if (condition) {
|
|
fail("Expected condition to be false", false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Halt execution even in release builds if this isn't the case.
|
|
*/
|
|
public static void isTrueReleaseCheck(final boolean condition) {
|
|
if (!condition) {
|
|
fail("Expected condition to be true", true);
|
|
}
|
|
}
|
|
|
|
public static void equals(final int expected, final int actual) {
|
|
if (expected != actual) {
|
|
fail("Expected " + expected + " but got " + actual, false);
|
|
}
|
|
}
|
|
|
|
public static void equals(final long expected, final long actual) {
|
|
if (expected != actual) {
|
|
fail("Expected " + expected + " but got " + actual, false);
|
|
}
|
|
}
|
|
|
|
public static void equals(final Object expected, final Object actual) {
|
|
if (expected != actual
|
|
&& (expected == null || actual == null || !expected.equals(actual))) {
|
|
fail("Expected " + expected + " but got " + actual, false);
|
|
}
|
|
}
|
|
|
|
public static void oneOf(final int actual, final int ...expected) {
|
|
for (int value : expected) {
|
|
if (actual == value) {
|
|
return;
|
|
}
|
|
}
|
|
fail("Expected value to be one of " + Arrays.toString(expected) + " but was " + actual);
|
|
}
|
|
|
|
public static void inRange(
|
|
final int val, final int rangeMinInclusive, final int rangeMaxInclusive) {
|
|
if (val < rangeMinInclusive || val > rangeMaxInclusive) {
|
|
fail("Expected value in range [" + rangeMinInclusive + ", " +
|
|
rangeMaxInclusive + "], but was " + val, false);
|
|
}
|
|
}
|
|
|
|
public static void inRange(
|
|
final long val, final long rangeMinInclusive, final long rangeMaxInclusive) {
|
|
if (val < rangeMinInclusive || val > rangeMaxInclusive) {
|
|
fail("Expected value in range [" + rangeMinInclusive + ", " +
|
|
rangeMaxInclusive + "], but was " + val, false);
|
|
}
|
|
}
|
|
|
|
public static void isMainThread() {
|
|
if (Looper.myLooper() != Looper.getMainLooper()
|
|
&& !Thread.currentThread().getName().contains(TEST_THREAD_SUBSTRING)) {
|
|
fail("Expected to run on main thread", false);
|
|
}
|
|
}
|
|
|
|
public static void isNotMainThread() {
|
|
if (Looper.myLooper() == Looper.getMainLooper()
|
|
&& !Thread.currentThread().getName().contains(TEST_THREAD_SUBSTRING)) {
|
|
fail("Not expected to run on main thread", false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Halt execution if the value passed in is not null
|
|
* @param obj The object to check
|
|
*/
|
|
public static void isNull(final Object obj) {
|
|
if (obj != null) {
|
|
fail("Expected object to be null", false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Halt execution if the value passed in is not null
|
|
* @param obj The object to check
|
|
* @param failureMessage message to print when halting execution
|
|
*/
|
|
public static void isNull(final Object obj, final String failureMessage) {
|
|
if (obj != null) {
|
|
fail(failureMessage, false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Halt execution if the value passed in is null
|
|
* @param obj The object to check
|
|
*/
|
|
public static void notNull(final Object obj) {
|
|
if (obj == null) {
|
|
fail("Expected value to be non-null", false);
|
|
}
|
|
}
|
|
|
|
public static void fail(final String message) {
|
|
fail("Assert.fail() called: " + message, false);
|
|
}
|
|
|
|
private static void fail(final String message, final boolean crashRelease) {
|
|
LogUtil.e(LogUtil.BUGLE_TAG, message);
|
|
if (crashRelease || sShouldCrash) {
|
|
throw new AssertionError(message);
|
|
} else {
|
|
// Find the method whose assertion failed. We're using a depth of 2, because all public
|
|
// Assert methods delegate to this one (see javadoc on getCaller() for details).
|
|
StackTraceElement caller = DebugUtils.getCaller(2);
|
|
if (caller != null) {
|
|
// This log message can be de-obfuscated by the Proguard retrace tool, just like a
|
|
// full stack trace from a crash.
|
|
LogUtil.e(LogUtil.BUGLE_TAG, "\tat " + caller.toString());
|
|
}
|
|
}
|
|
}
|
|
}
|