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

Commit 6903f9bd authored by Hieu Dang's avatar Hieu Dang
Browse files

Add more tests for BluetoothOppService

Test: atest BluetoothOppServiceTest --rerun-until-failure=100
Bug: 281311423
Bug: 266459454
Tag: #refactor
Change-Id: I0779eb81f336eeba911bbdf574b9671eaf7f90ab
Merged-In: 23705062
parent 216cf453
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -135,8 +135,8 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti

    private boolean mUpdateThreadRunning;

    private ArrayList<BluetoothOppShareInfo> mShares;
    private ArrayList<BluetoothOppBatch> mBatches;
    @VisibleForTesting ArrayList<BluetoothOppShareInfo> mShares;
    @VisibleForTesting ArrayList<BluetoothOppBatch> mBatches;

    private BluetoothOppTransfer mTransfer;

@@ -180,7 +180,8 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti
                    + BluetoothShare.USER_CONFIRMATION + "="
                    + BluetoothShare.USER_CONFIRMATION_PENDING;

    private static final String WHERE_INVISIBLE_UNCONFIRMED =
    @VisibleForTesting
    static final String WHERE_INVISIBLE_UNCONFIRMED =
            "("
                    + BluetoothShare.STATUS
                    + " > "
@@ -993,7 +994,8 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti
    }

    /** Removes the local copy of the info about a share. */
    private void deleteShare(int arrayPos) {
    @VisibleForTesting
    void deleteShare(int arrayPos) {
        BluetoothOppShareInfo info = mShares.get(arrayPos);

        /*
@@ -1117,7 +1119,8 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti
    }

    // Run in a background thread at boot.
    private static void trimDatabase(ContentResolver contentResolver) {
    @VisibleForTesting
    static void trimDatabase(ContentResolver contentResolver) {
        // Try-catch is important because trimDatabase can run even when the OPP_PROVIDER is
        // disabled (by OPP service, shell command, etc.).
        // At the sametime, it's ok to retry trimDatabase later when the service restart
+101 −5
Original line number Diff line number Diff line
@@ -15,14 +15,24 @@
 */
package com.android.bluetooth.opp;

import static com.android.bluetooth.opp.BluetoothOppService.WHERE_INVISIBLE_UNCONFIRMED;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

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

import android.bluetooth.BluetoothAdapter;
import android.content.ContentResolver;
import android.database.MatrixCursor;

import androidx.test.filters.MediumTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ServiceTestRule;
import androidx.test.runner.AndroidJUnit4;

@@ -39,26 +49,24 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;


@MediumTest
@RunWith(AndroidJUnit4.class)
public class BluetoothOppServiceTest {
    private BluetoothOppService mService = null;
    private BluetoothAdapter mAdapter = null;

    @Rule
    public final ServiceTestRule mServiceRule = new ServiceTestRule();
    @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();

    @Mock BluetoothMethodProxy mBluetoothMethodProxy;

    @Mock
    private AdapterService mAdapterService;
    @Mock private AdapterService mAdapterService;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);

        BluetoothMethodProxy.setInstanceForTesting(mBluetoothMethodProxy);

        // BluetoothOppService can create a UpdateThread, which will call
        // BluetoothOppNotification#updateNotification(), which in turn create a new
        // NotificationUpdateThread. Both threads may cause the tests to fail because they try to
@@ -70,6 +78,7 @@ public class BluetoothOppServiceTest {
        doReturn(true, false).when(mAdapterService).isStartedProfile(anyString());
        TestUtils.startService(mServiceRule, BluetoothOppService.class);
        mService = BluetoothOppService.getBluetoothOppService();

        Assert.assertNotNull(mService);
        // Try getting the Bluetooth adapter
        mAdapter = BluetoothAdapter.getDefaultAdapter();
@@ -91,5 +100,92 @@ public class BluetoothOppServiceTest {
    public void testInitialize() {
        Assert.assertNotNull(BluetoothOppService.getBluetoothOppService());
    }

    @Test
    public void deleteShare_deleteShareAndCorrespondingBatch() {
        int infoTimestamp = 123456789;
        int infoTimestamp2 = 123489;

        BluetoothOppShareInfo shareInfo = mock(BluetoothOppShareInfo.class);
        shareInfo.mTimestamp = infoTimestamp;
        shareInfo.mDestination = "AA:BB:CC:DD:EE:FF";
        BluetoothOppShareInfo shareInfo2 = mock(BluetoothOppShareInfo.class);
        shareInfo2.mTimestamp = infoTimestamp2;
        shareInfo2.mDestination = "00:11:22:33:44:55";

        mService.mShares.clear();
        mService.mShares.add(shareInfo);
        mService.mShares.add(shareInfo2);

        // batch1 will be removed
        BluetoothOppBatch batch1 = new BluetoothOppBatch(mService, shareInfo);
        BluetoothOppBatch batch2 = new BluetoothOppBatch(mService, shareInfo2);
        batch2.mStatus = Constants.BATCH_STATUS_FINISHED;
        mService.mBatches.clear();
        mService.mBatches.add(batch1);
        mService.mBatches.add(batch2);

        mService.deleteShare(0);
        assertThat(mService.mShares.size()).isEqualTo(1);
        assertThat(mService.mBatches.size()).isEqualTo(1);
        assertThat(mService.mShares.get(0)).isEqualTo(shareInfo2);
        assertThat(mService.mBatches.get(0)).isEqualTo(batch2);
    }

    @Test
    public void dump_shouldNotThrow() {
        BluetoothOppShareInfo info = mock(BluetoothOppShareInfo.class);

        mService.mShares.add(info);

        // should not throw
        mService.dump(new StringBuilder());
    }

    @Test
    public void trimDatabase_trimsOldOrInvisibleRecords() {
        ContentResolver contentResolver =
                InstrumentationRegistry.getInstrumentation()
                        .getTargetContext()
                        .getContentResolver();

        doReturn(1 /* any int is Ok */)
                .when(mBluetoothMethodProxy)
                .contentResolverDelete(
                        eq(contentResolver), eq(BluetoothShare.CONTENT_URI), anyString(), any());

        MatrixCursor cursor = new MatrixCursor(new String[] {BluetoothShare._ID}, 500);
        for (long i = 0; i < Constants.MAX_RECORDS_IN_DATABASE + 20; i++) {
            cursor.addRow(new Object[] {i});
        }

        doReturn(cursor)
                .when(mBluetoothMethodProxy)
                .contentResolverQuery(
                        eq(contentResolver),
                        eq(BluetoothShare.CONTENT_URI),
                        any(),
                        any(),
                        any(),
                        any());

        BluetoothOppService.trimDatabase(contentResolver);

        // check trimmed invisible records
        verify(mBluetoothMethodProxy)
                .contentResolverDelete(
                        eq(contentResolver),
                        eq(BluetoothShare.CONTENT_URI),
                        eq(WHERE_INVISIBLE_UNCONFIRMED),
                        any());

        // check trimmed old records
        verify(mBluetoothMethodProxy)
                .contentResolverDelete(
                        eq(contentResolver),
                        eq(BluetoothShare.CONTENT_URI),
                        eq(BluetoothShare._ID + " < " + 20),
                        any());
    }
}