1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.server.bluetooth.test
17 
18 import android.bluetooth.BluetoothAdapter.STATE_OFF
19 import com.android.server.bluetooth.BluetoothAdapterState
20 import com.android.server.bluetooth.Log
21 import com.google.common.truth.Truth.assertThat
22 import kotlin.time.Duration.Companion.days
23 import kotlinx.coroutines.CoroutineStart
24 import kotlinx.coroutines.async
25 import kotlinx.coroutines.runBlocking
26 import kotlinx.coroutines.test.runTest
27 import kotlinx.coroutines.yield
28 import org.junit.Before
29 import org.junit.Rule
30 import org.junit.Test
31 import org.junit.rules.TestName
32 import org.junit.runner.RunWith
33 import org.robolectric.RobolectricTestRunner
34 
35 @RunWith(RobolectricTestRunner::class)
36 @kotlinx.coroutines.ExperimentalCoroutinesApi
37 class BluetoothAdapterStateTest {
38 
39     lateinit var mState: BluetoothAdapterState
40     @JvmField @Rule val testName = TestName()
41 
42     @Before
setUpnull43     fun setUp() {
44         Log.i("BluetoothAdapterStateTest", "\t--> setup of " + testName.getMethodName())
45         mState = BluetoothAdapterState()
46     }
47 
48     @Test
init_isStateOffnull49     fun init_isStateOff() {
50         Log.d("BluetoothAdapterStateTest", "Initial state is " + mState)
51         assertThat(mState.get()).isEqualTo(STATE_OFF)
52     }
53 
54     @Test
get_afterBusy_returnLastValuenull55     fun get_afterBusy_returnLastValue() {
56         val max = 10
57         for (i in 0..max) mState.set(i)
58         assertThat(mState.get()).isEqualTo(max)
59     }
60 
61     @Test
<lambda>null62     fun immediateReturn_whenStateIsAlreadyCorrect() = runTest {
63         val state = 10
64         mState.set(state)
65         assertThat(runBlocking { mState.waitForState(100.days, state) }).isTrue()
66     }
67 
<lambda>null68     @Test fun expectTimeout() = runTest { assertThat(mState.waitForState(100.days, -1)).isFalse() }
69 
70     @Test
<lambda>null71     fun expectTimeout_CalledJavaApi() = runTest {
72         assertThat(mState.waitForState(java.time.Duration.ofMillis(10), -1)).isFalse()
73     }
74 
75     @Test
<lambda>null76     fun setState_whileWaiting() = runTest {
77         val state = 42
78         val waiter = async { mState.waitForState(100.days, state) }
79         mState.set(state)
80         assertThat(waiter.await()).isTrue()
81     }
82 
83     @Test
<lambda>null84     fun concurrentWaiter_NoStateMissed() = runTest {
85         val state0 = 42
86         val state1 = 50
87         val state2 = 65
88         val waiter0 =
89             async(start = CoroutineStart.UNDISPATCHED) { mState.waitForState(100.days, state0) }
90         val waiter1 =
91             async(start = CoroutineStart.UNDISPATCHED) { mState.waitForState(100.days, state1) }
92         val waiter2 =
93             async(start = CoroutineStart.UNDISPATCHED) { mState.waitForState(100.days, state2) }
94         val waiter3 =
95             async(start = CoroutineStart.UNDISPATCHED) { mState.waitForState(100.days, -1) }
96         mState.set(state0)
97         yield()
98         mState.set(state1)
99         yield()
100         mState.set(state2)
101         assertThat(waiter0.await()).isTrue()
102         assertThat(waiter1.await()).isTrue()
103         assertThat(waiter2.await()).isTrue()
104         assertThat(waiter3.await()).isFalse()
105     }
106 
107     @Test
<lambda>null108     fun expectTimeout_waitAfterOverride() = runTest {
109         val state0 = 42
110         val state1 = 50
111         mState.set(state0)
112         yield()
113         mState.set(state1)
114         val waiter =
115             async(start = CoroutineStart.UNDISPATCHED) { mState.waitForState(100.days, state0) }
116         assertThat(waiter.await()).isFalse()
117     }
118 
119     @Test
oneOf_expectMatchnull120     fun oneOf_expectMatch() {
121         val state0 = 42
122         val state1 = 50
123         mState.set(state0)
124         assertThat(mState.oneOf(state0, state1)).isTrue()
125     }
126 
127     @Test
oneOf_expectNotMatchnull128     fun oneOf_expectNotMatch() {
129         val state0 = 42
130         val state1 = 50
131         val state2 = 65
132         mState.set(state0)
133         assertThat(mState.oneOf(state1, state2)).isFalse()
134     }
135 }
136