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

Commit 895e60ab authored by Jack He's avatar Jack He
Browse files

Test: Fix broken tests in HeadsetClientStateMachineTest

* Refactor HeadsetClientStateMachineTest to use looper from
  HandlerThread created in the test
* Refactor the test to use morden Mockito annotations and initializers
* Refactor the test so that bootstrap code is re-used among different
  tests

Bug: 68711696
Test: runtest -i -j40 bluetooth; adb shell am instrument -w -e timeout_msec 300000
      'com.android.bluetooth.tests/android.support.test.runner.AndroidJUnitRunner'

Change-Id: Ic3bafb96273abf065ebab2af6edf36b0ebf519b9
parent 3c49a206
Loading
Loading
Loading
Loading
+73 −88
Original line number Diff line number Diff line
@@ -8,30 +8,57 @@ import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.support.test.InstrumentationRegistry;
import android.os.HandlerThread;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;

import com.android.bluetooth.btservice.AdapterService;

import org.hamcrest.core.IsInstanceOf;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@MediumTest
@RunWith(AndroidJUnit4.class)
public class HeadsetClientStateMachineTest {
    private BluetoothAdapter mAdapter = null;
    private Context mTargetContext;
    private BluetoothAdapter mAdapter;
    private HandlerThread mHandlerThread;
    private HeadsetClientStateMachine mHeadsetClientStateMachine;
    private BluetoothDevice mTestDevice;

    @Mock private HeadsetClientService mHeadsetClientService;
    @Mock private AudioManager mAudioManager;

    @Before
    public void setUp() throws Exception {
        mTargetContext = InstrumentationRegistry.getTargetContext();
        AdapterService inst = mock(AdapterService.class);
        Assert.assertTrue(inst != null);
    public void setUp() {
        // Setup mocks and test assets
        MockitoAnnotations.initMocks(this);
        // Set a valid volume
        when(mAudioManager.getStreamVolume(anyInt())).thenReturn(2);
        when(mAudioManager.getStreamMaxVolume(anyInt())).thenReturn(10);
        when(mAudioManager.getStreamMinVolume(anyInt())).thenReturn(1);
        when(mHeadsetClientService.getSystemService(Context.AUDIO_SERVICE)).thenReturn(
                mAudioManager);
        // This line must be called to make sure relevant objects are initialized properly
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        // Get a device for testing
        mTestDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05");

        // Setup thread and looper
        mHandlerThread = new HandlerThread("HeadsetClientStateMachineTestHandlerThread");
        mHandlerThread.start();
        // Manage looper execution in main test thread explicitly to guarantee timing consistency
        mHeadsetClientStateMachine =
                new HeadsetClientStateMachine(mHeadsetClientService, mHandlerThread.getLooper());
    }

    @After
    public void tearDown() {
        mHandlerThread.quit();
    }

    /**
@@ -39,14 +66,7 @@ public class HeadsetClientStateMachineTest {
     */
    @Test
    public void testDefaultDisconnectedState() {
        HeadsetClientService mockService = mock(HeadsetClientService.class);
        AudioManager mockAudioManager = mock(AudioManager.class);

        when(mockService.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mockAudioManager);

        HeadsetClientStateMachine mockSM =
                new HeadsetClientStateMachine(mockService, mTargetContext.getMainLooper());
        Assert.assertEquals(mockSM.getConnectionState((BluetoothDevice) null),
        Assert.assertEquals(mHeadsetClientStateMachine.getConnectionState(null),
                BluetoothProfile.STATE_DISCONNECTED);
    }

@@ -55,33 +75,23 @@ public class HeadsetClientStateMachineTest {
     */
    @Test
    public void testIncomingPriorityReject() {
        HeadsetClientService mockService = mock(HeadsetClientService.class);
        AudioManager mockAudioManager = mock(AudioManager.class);
        BluetoothDevice device = mAdapter.getRemoteDevice("00:01:02:03:04:05");

        when(mockService.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mockAudioManager);

        HeadsetClientStateMachine mockSM =
                new HeadsetClientStateMachine(mockService, mTargetContext.getMainLooper());
        mockSM.start();
        mHeadsetClientStateMachine.start();

        // Return false for priority.
        when(mockService.getPriority(any(BluetoothDevice.class))).thenReturn(
        when(mHeadsetClientService.getPriority(any(BluetoothDevice.class))).thenReturn(
                BluetoothProfile.PRIORITY_OFF);

        // Inject an event for when incoming connection is requested
        StackEvent connStCh = new StackEvent(StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
        connStCh.valueInt = HeadsetClientHalConstants.CONNECTION_STATE_CONNECTED;
        connStCh.valueInt2 = 0;
        connStCh.valueInt3 = 0;
        connStCh.device = device;
        mockSM.sendMessage(StackEvent.STACK_EVENT, connStCh);
        connStCh.device = mTestDevice;
        mHeadsetClientStateMachine.sendMessage(StackEvent.STACK_EVENT, connStCh);

        // Verify that no connection state broadcast is executed
        verify(mockService, never()).sendBroadcast(any(Intent.class), anyString());
        verify(mHeadsetClientService, never()).sendBroadcast(any(Intent.class), anyString());
        // Check we are in disconnected state still.
        Assert.assertTrue(
                mockSM.getCurrentState() instanceof HeadsetClientStateMachine.Disconnected);
        Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(),
                IsInstanceOf.instanceOf(HeadsetClientStateMachine.Disconnected.class));
    }

    /**
@@ -89,58 +99,45 @@ public class HeadsetClientStateMachineTest {
     */
    @Test
    public void testIncomingPriorityAccept() {
        HeadsetClientService mockService = mock(HeadsetClientService.class);
        AudioManager mockAudioManager = mock(AudioManager.class);
        BluetoothDevice device = mAdapter.getRemoteDevice("00:01:02:03:04:05");

        when(mockService.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mockAudioManager);
        // Set a valid volume
        when(mockAudioManager.getStreamVolume(anyInt())).thenReturn(2);
        when(mockAudioManager.getStreamMaxVolume(anyInt())).thenReturn(10);
        when(mockAudioManager.getStreamMinVolume(anyInt())).thenReturn(1);
        mHeadsetClientStateMachine.start();


        HeadsetClientStateMachine mockSM =
                new HeadsetClientStateMachine(mockService, mTargetContext.getMainLooper());
        mockSM.start();

        // Return false for priority.
        when(mockService.getPriority(any(BluetoothDevice.class))).thenReturn(
        // Return true for priority.
        when(mHeadsetClientService.getPriority(any(BluetoothDevice.class))).thenReturn(
                BluetoothProfile.PRIORITY_ON);

        // Inject an event for when incoming connection is requested
        StackEvent connStCh = new StackEvent(StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
        connStCh.valueInt = HeadsetClientHalConstants.CONNECTION_STATE_CONNECTED;
        connStCh.valueInt2 = 0;
        connStCh.valueInt3 = 0;
        connStCh.device = device;
        mockSM.sendMessage(StackEvent.STACK_EVENT, connStCh);
        connStCh.device = mTestDevice;
        mHeadsetClientStateMachine.sendMessage(StackEvent.STACK_EVENT, connStCh);

        // Verify that one connection state broadcast is executed
        ArgumentCaptor<Intent> intentArgument1 = ArgumentCaptor.forClass(Intent.class);
        verify(mockService, timeout(1000)).sendBroadcast(intentArgument1.capture(), anyString());
        verify(mHeadsetClientService, timeout(1000)).sendBroadcast(intentArgument1.capture(),
                anyString());
        Assert.assertEquals(BluetoothProfile.STATE_CONNECTING,
                intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));

        // Check we are in connecting state now.
        Assert.assertTrue(mockSM.getCurrentState() instanceof HeadsetClientStateMachine.Connecting);
        Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(),
                IsInstanceOf.instanceOf(HeadsetClientStateMachine.Connecting.class));

        // Send a message to trigger SLC connection
        StackEvent slcEvent = new StackEvent(StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
        slcEvent.valueInt = HeadsetClientHalConstants.CONNECTION_STATE_SLC_CONNECTED;
        slcEvent.valueInt2 = HeadsetClientHalConstants.PEER_FEAT_ECS;
        slcEvent.valueInt3 = 0;
        slcEvent.device = device;
        mockSM.sendMessage(StackEvent.STACK_EVENT, slcEvent);
        slcEvent.device = mTestDevice;
        mHeadsetClientStateMachine.sendMessage(StackEvent.STACK_EVENT, slcEvent);

        // Verify that one connection state broadcast is executed
        ArgumentCaptor<Intent> intentArgument2 = ArgumentCaptor.forClass(Intent.class);
        verify(mockService, timeout(1000).times(2)).sendBroadcast(intentArgument2.capture(),
                anyString());
        verify(mHeadsetClientService, timeout(1000).times(2)).sendBroadcast(
                intentArgument2.capture(), anyString());
        Assert.assertEquals(BluetoothProfile.STATE_CONNECTED,
                intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
        // Check we are in connecting state now.
        Assert.assertTrue(mockSM.getCurrentState() instanceof HeadsetClientStateMachine.Connected);
        Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(),
                IsInstanceOf.instanceOf(HeadsetClientStateMachine.Connected.class));
    }

    /**
@@ -148,51 +145,39 @@ public class HeadsetClientStateMachineTest {
     */
    @Test
    public void testIncomingTimeout() {
        HeadsetClientService mockService = mock(HeadsetClientService.class);
        AudioManager mockAudioManager = mock(AudioManager.class);
        BluetoothDevice device = mAdapter.getRemoteDevice("00:01:02:03:04:05");
        mHeadsetClientStateMachine.start();

        when(mockService.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mockAudioManager);
        // Set a valid volume
        when(mockAudioManager.getStreamVolume(anyInt())).thenReturn(2);
        when(mockAudioManager.getStreamMaxVolume(anyInt())).thenReturn(10);
        when(mockAudioManager.getStreamMinVolume(anyInt())).thenReturn(1);


        HeadsetClientStateMachine mockSM =
                new HeadsetClientStateMachine(mockService, mTargetContext.getMainLooper());
        mockSM.start();

        // Return false for priority.
        when(mockService.getPriority(any(BluetoothDevice.class))).thenReturn(
        // Return true for priority.
        when(mHeadsetClientService.getPriority(any(BluetoothDevice.class))).thenReturn(
                BluetoothProfile.PRIORITY_ON);

        // Inject an event for when incoming connection is requested
        StackEvent connStCh = new StackEvent(StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
        connStCh.valueInt = HeadsetClientHalConstants.CONNECTION_STATE_CONNECTED;
        connStCh.valueInt2 = 0;
        connStCh.valueInt3 = 0;
        connStCh.device = device;
        mockSM.sendMessage(StackEvent.STACK_EVENT, connStCh);
        connStCh.device = mTestDevice;
        mHeadsetClientStateMachine.sendMessage(StackEvent.STACK_EVENT, connStCh);

        // Verify that one connection state broadcast is executed
        ArgumentCaptor<Intent> intentArgument1 = ArgumentCaptor.forClass(Intent.class);
        verify(mockService, timeout(1000)).sendBroadcast(intentArgument1.capture(), anyString());
        verify(mHeadsetClientService, timeout(1000)).sendBroadcast(intentArgument1.capture(),
                anyString());
        Assert.assertEquals(BluetoothProfile.STATE_CONNECTING,
                intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));

        // Check we are in connecting state now.
        Assert.assertTrue(mockSM.getCurrentState() instanceof HeadsetClientStateMachine.Connecting);
        Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(),
                IsInstanceOf.instanceOf(HeadsetClientStateMachine.Connecting.class));

        // Verify that one connection state broadcast is executed
        ArgumentCaptor<Intent> intentArgument2 = ArgumentCaptor.forClass(Intent.class);
        verify(mockService, timeout(HeadsetClientStateMachine.CONNECTING_TIMEOUT_MS * 2).times(
        verify(mHeadsetClientService,
                timeout(HeadsetClientStateMachine.CONNECTING_TIMEOUT_MS * 2).times(
                        2)).sendBroadcast(intentArgument2.capture(), anyString());
        Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED,
                intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));

        // Check we are in connecting state now.
        Assert.assertTrue(
                mockSM.getCurrentState() instanceof HeadsetClientStateMachine.Disconnected);
        Assert.assertThat(mHeadsetClientStateMachine.getCurrentState(),
                IsInstanceOf.instanceOf(HeadsetClientStateMachine.Disconnected.class));
    }
}