summaryrefslogtreecommitdiff
path: root/service/src/AdapterStateTest.kt
blob: d61138438a42203b826867fd631fcd773dfd870b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * 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 {
    @get:Rule val testName = TestName()

    lateinit var mState: BluetoothAdapterState

    @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()
    }
}