blob: 0b73558b6c3530ba149fba7948fd6468314cba3f [file] [log] [blame]
/*
* Copyright (C) 2023 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.server.bluetooth.test
import android.bluetooth.BluetoothAdapter.STATE_OFF
import com.android.server.bluetooth.BluetoothAdapterState
import com.android.server.bluetooth.Log
import com.google.common.truth.Truth.assertThat
import kotlin.time.Duration.Companion.days
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.yield
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TestName
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
@RunWith(RobolectricTestRunner::class)
@kotlinx.coroutines.ExperimentalCoroutinesApi
class BluetoothAdapterStateTest {
lateinit var mState: BluetoothAdapterState
@JvmField @Rule val testName = TestName()
@Before
fun setUp() {
Log.i("BluetoothAdapterStateTest", "\t--> setup of " + testName.getMethodName())
mState = BluetoothAdapterState()
}
@Test
fun init_isStateOff() {
Log.d("BluetoothAdapterStateTest", "Initial state is " + mState)
assertThat(mState.get()).isEqualTo(STATE_OFF)
}
@Test
fun get_afterBusy_returnLastValue() {
val max = 10
for (i in 0..max) mState.set(i)
assertThat(mState.get()).isEqualTo(max)
}
@Test
fun immediateReturn_whenStateIsAlreadyCorrect() = runTest {
val state = 10
mState.set(state)
assertThat(runBlocking { mState.waitForState(100.days, state) }).isTrue()
}
@Test fun expectTimeout() = runTest { assertThat(mState.waitForState(100.days, -1)).isFalse() }
@Test
fun expectTimeout_CalledJavaApi() = runTest {
assertThat(mState.waitForState(java.time.Duration.ofMillis(10), -1)).isFalse()
}
@Test
fun setState_whileWaiting() = runTest {
val state = 42
val waiter = async { mState.waitForState(100.days, state) }
mState.set(state)
assertThat(waiter.await()).isTrue()
}
@Test
fun concurrentWaiter_NoStateMissed() = runTest {
val state0 = 42
val state1 = 50
val state2 = 65
val waiter0 =
async(start = CoroutineStart.UNDISPATCHED) { mState.waitForState(100.days, state0) }
val waiter1 =
async(start = CoroutineStart.UNDISPATCHED) { mState.waitForState(100.days, state1) }
val waiter2 =
async(start = CoroutineStart.UNDISPATCHED) { mState.waitForState(100.days, state2) }
val waiter3 =
async(start = CoroutineStart.UNDISPATCHED) { mState.waitForState(100.days, -1) }
mState.set(state0)
yield()
mState.set(state1)
yield()
mState.set(state2)
assertThat(waiter0.await()).isTrue()
assertThat(waiter1.await()).isTrue()
assertThat(waiter2.await()).isTrue()
assertThat(waiter3.await()).isFalse()
}
@Test
fun expectTimeout_waitAfterOverride() = runTest {
val state0 = 42
val state1 = 50
mState.set(state0)
yield()
mState.set(state1)
val waiter =
async(start = CoroutineStart.UNDISPATCHED) { mState.waitForState(100.days, state0) }
assertThat(waiter.await()).isFalse()
}
@Test
fun oneOf_expectMatch() {
val state0 = 42
val state1 = 50
mState.set(state0)
assertThat(mState.oneOf(state0, state1)).isTrue()
}
@Test
fun oneOf_expectNotMatch() {
val state0 = 42
val state1 = 50
val state2 = 65
mState.set(state0)
assertThat(mState.oneOf(state1, state2)).isFalse()
}
}