1# BumbleBluetoothTests 2 3Bumble Bluetooth tests are instrumented Android-specific multi-device tests using a reference 4peer device implementing the Pandora APIs. 5 6## Architecture 7 8BumbleBluetoothTests is an Android APK that offers enhanced control over Android compared to Avatar 9by interacting directly with the Device Under Test (DUT) via Android APIs. Instead of mocking every 10API call, it communicates with actual reference devices using gRPC and limits peer device interactions 11to the Pandora APIs. 12 13Here is an overview of the BumbleBluetoothTests architecture: 14 15 16A simple LE connection test looks like this: 17 18```kotlin 19// Setup a Bumble Pandora device for the duration of the test. 20// Acting as a Pandora client, it can be interacted with through the Pandora APIs. 21@Rule @JvmField val mBumble = PandoraDevice() 22 23/** 24 * Tests the Bluetooth GATT connection process with a mock callback. 25 * This verifies both successful connection and disconnection events for a 26 * remote Bluetooth device. 27 * 28 * @throws Exception if there's an unexpected error during the test execution. 29 */ 30@Test 31fun testGattConnect() { 32 // 1. Advertise the host's Bluetooth capabilities using another 33 // gRPC call: 34 // - `hostBlocking()` accesses another gRPC service related to the host. 35 // The following `advertise(...)` sends an advertise request to the server, setting 36 // specific attributes. 37 mBumble 38 .hostBlocking() 39 .advertise( 40 AdvertiseRequest.newBuilder() 41 .setLegacy(true) 42 .setConnectable(true) 43 .setOwnAddressType(OwnAddressType.RANDOM) 44 .build() 45 ) 46 47 // 2. Create a mock callback to handle Bluetooth GATT (Generic Attribute Profile) related events. 48 val gattCallback = mock(BluetoothGattCallback::class.java) 49 50 // 3. Fetch a remote Bluetooth device instance (here, Bumble). 51 val bumbleDevice = 52 bluetoothAdapter.getRemoteLeDevice( 53 Utils.BUMBLE_RANDOM_ADDRESS, 54 BluetoothDevice.ADDRESS_TYPE_RANDOM // Specify address type as RANDOM because the device advertises with this address type. 55 ) 56 57 // 4. Connect to the Bumble device and expect a successful connection callback. 58 var bumbleGatt = bumbleDevice.connectGatt(context, false, gattCallback) 59 verify(gattCallback, timeout(TIMEOUT)) 60 .onConnectionStateChange( 61 any(), 62 eq(BluetoothGatt.GATT_SUCCESS), 63 eq(BluetoothProfile.STATE_CONNECTED) 64 ) 65 66 // 5. Disconnect from the Bumble device and expect a successful disconnection callback. 67 bumbleGatt.disconnect() 68 verify(gattCallback, timeout(TIMEOUT)) 69 .onConnectionStateChange( 70 any(), 71 eq(BluetoothGatt.GATT_SUCCESS), 72 eq(BluetoothProfile.STATE_DISCONNECTED) 73 ) 74} 75``` 76