diff options
author | 2020-12-08 14:53:10 -0800 | |
---|---|---|
committer | 2021-01-29 08:05:07 -0800 | |
commit | 6518347e5be66cbc6f6638e597f70ebcf3ff472f (patch) | |
tree | 59c56b0bf36d07efcd2595c3df744dbe080b57fe | |
parent | 2bcb84048b2396fb2539e9dfed87a3a1faaec364 (diff) |
Add telephony-common-testing
This is a library for testing related logic used by telephony unit and
CTS tests.
Bug: 154363919
Test: atest TeleServiceTests:SimPhonebookProviderTest
Change-Id: I584150dd8352dbb49d70ea28c6d064a6336d018d
-rw-r--r-- | testing/Android.bp | 23 | ||||
-rw-r--r-- | testing/AndroidManifest.xml | 26 | ||||
-rw-r--r-- | testing/src/com/android/internal/telephony/testing/CursorSubject.java | 161 | ||||
-rw-r--r-- | testing/src/com/android/internal/telephony/testing/TelephonyAssertions.java | 51 |
4 files changed, 261 insertions, 0 deletions
diff --git a/testing/Android.bp b/testing/Android.bp new file mode 100644 index 0000000000..527abc850b --- /dev/null +++ b/testing/Android.bp @@ -0,0 +1,23 @@ +android_library { + name: "telephony-common-testing", + + srcs: ["**/*.java"], + + static_libs: [ + "androidx.annotation_annotation", + "guava", + "junit", + "mockito-target-minus-junit4", + "telephony-common", + "truth-prebuilt", + ], + + sdk_version: "test_current", + + visibility: [ + "//cts/tests/tests/simphonebookprovider", + "//cts/tests/tests/simphonebookprovider/nosim", + "//frameworks/opt/telephony/tests", + "//packages/services/Telephony/tests", + ], +} diff --git a/testing/AndroidManifest.xml b/testing/AndroidManifest.xml new file mode 100644 index 0000000000..6be665b2c6 --- /dev/null +++ b/testing/AndroidManifest.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2020 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. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="android.telephony.testing"> + + <application> + + </application> + +</manifest> + diff --git a/testing/src/com/android/internal/telephony/testing/CursorSubject.java b/testing/src/com/android/internal/telephony/testing/CursorSubject.java new file mode 100644 index 0000000000..999e92cce0 --- /dev/null +++ b/testing/src/com/android/internal/telephony/testing/CursorSubject.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2020 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.internal.telephony.testing; + +import static com.google.common.truth.Truth.assertAbout; + +import android.content.ContentValues; +import android.database.Cursor; +import android.database.CursorWrapper; +import android.database.DatabaseUtils; + +import androidx.annotation.Nullable; + +import com.google.common.truth.FailureMetadata; +import com.google.common.truth.IntegerSubject; +import com.google.common.truth.IterableSubject; +import com.google.common.truth.StringSubject; +import com.google.common.truth.Subject; +import com.google.common.truth.Truth; + +import java.util.ArrayList; +import java.util.List; + +/** Truth subject for making assertions about {@link Cursor}s. */ +public final class CursorSubject extends Subject { + + private final Cursor mActual; + + private CursorSubject(FailureMetadata metadata, @Nullable Cursor actual) { + super(metadata, new StringableCursor(actual)); + this.mActual = new StringableCursor(actual); + } + + /** Returns the factory for this subject. */ + public static Factory<CursorSubject, Cursor> cursors() { + return CursorSubject::new; + } + + /** Starts an assertion. */ + public static CursorSubject assertThat(Cursor cursor) { + return assertAbout(cursors()).that(cursor); + } + + /** Asserts {@link Cursor#getCount()} has the specified value. */ + public void hasCount(int count) { + check("getCount()").that(mActual.getCount()).isEqualTo(count); + } + + /** Asserts {@link Cursor#getColumnNames()} match those specified. */ + public void hasColumnNames(String... columnNames) { + check("getColumnNames()").that(mActual.getColumnNames()).asList() + .containsExactlyElementsIn(columnNames).inOrder(); + } + + /** Positions the cursor under test at the specified row to make an assertion about it. */ + public CursorSubject atRow(int position) { + check("moveToPosition").that(mActual.moveToPosition(position)).isTrue(); + return this; + } + + /** Asserts that the row at the cursor's current position has the specified values. */ + public CursorSubject hasRowValues(Object... values) { + check("getColumnCount()").that(mActual.getColumnCount()).isEqualTo(values.length); + ContentValues expectedValues = new ContentValues(); + for (int i = 0; i < values.length; i++) { + expectedValues.put(mActual.getColumnName(i), values[i].toString()); + } + + ContentValues actualValues = new ContentValues(); + DatabaseUtils.cursorRowToContentValues(mActual, actualValues); + + check("Row: %s", mActual.getPosition()).that(actualValues).isEqualTo(expectedValues); + return this; + } + + /** Asserts that the cursor has a single row with the specified values. */ + public void hasSingleRow(Object... values) { + hasCount(1); + atRow(0).hasRowValues(values); + } + + /** + * Asserts that the row at the cursor's current position has the specified value for the + * specified column. + */ + public CursorSubject hasRowValue(String columnName, Object value) { + int index = mActual.getColumnIndex(columnName); + check("getColumnIndex()").that(index).isNotEqualTo(-1); + + check("Row[%s]: %s", columnName, index).that(mActual.getString(index)) + .isEqualTo(value.toString()); + return this; + } + + /** Starts an assertion about the value of the specified column for the current row. */ + public IntegerSubject intField(String columnName) { + int index = mActual.getColumnIndex(columnName); + check("getColumnIndex()").that(index).isNotEqualTo(-1); + check("getType()").that(mActual.getType(index)).isEqualTo(Cursor.FIELD_TYPE_INTEGER); + + return check("getInt()").that(mActual.getInt(index)); + } + + /** Starts an assertion about the value of the specified column for the current row. */ + public StringSubject stringField(String columnName) { + int index = mActual.getColumnIndex(columnName); + check("getColumnIndex()").that(index).isNotEqualTo(-1); + check("getType()").that(mActual.getType(index)).isEqualTo(Cursor.FIELD_TYPE_STRING); + + return check("getString()").that(mActual.getString(index)); + } + + /** Asserts that the cursor rows match the data specified. */ + public void hasData(Object[][] rows) { + hasCount(rows.length); + for (int i = 0; i < rows.length; i++) { + atRow(i).hasRowValues(rows[i]); + } + } + + /** Starts an assertion about the cursor's rows. */ + public IterableSubject asLists() { + List<List<String>> result = new ArrayList<>(); + mActual.moveToPosition(-1); + while (mActual.moveToNext()) { + List<String> row = new ArrayList<>(); + for (int i = 0; i < mActual.getColumnCount(); i++) { + row.add(mActual.getString(i)); + } + result.add(row); + } + return Truth.assertThat(result); + } + + private static class StringableCursor extends CursorWrapper { + + StringableCursor(Cursor cursor) { + super(cursor); + } + + @Override + public String toString() { + return DatabaseUtils.dumpCursorToString(getWrappedCursor()); + } + } + +} diff --git a/testing/src/com/android/internal/telephony/testing/TelephonyAssertions.java b/testing/src/com/android/internal/telephony/testing/TelephonyAssertions.java new file mode 100644 index 0000000000..d18a5cf30a --- /dev/null +++ b/testing/src/com/android/internal/telephony/testing/TelephonyAssertions.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 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.internal.telephony.testing; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Assert; + +/** Assertions used by telephony tests. */ +public class TelephonyAssertions { + + /** + * Asserts that the provided action throws the specified exception. + * + * <p>TODO: Replace with org.junit.Assert.assertThrows when Android upgrades to JUnit 4.12 + * + * @return the exception that was thrown when the assertion passes. + */ + public static <T extends Throwable> T assertThrows( + Class<T> throwableClass, ThrowingRunnable action) { + try { + action.run(); + } catch (Throwable t) { + assertThat(t).isInstanceOf(throwableClass); + return throwableClass.cast(t); + } + Assert.fail("Expected " + throwableClass.getSimpleName() + " but no exception was thrown"); + // This is unreachable but needed to compile. + return null; + } + + /** Runnable that can throw a checked exception. */ + public interface ThrowingRunnable { + /** Method with code that may throw a checked exception. */ + void run() throws Exception; + } +} |