@@ -2,6 +2,8 @@ package arcs.android.storage.handle
2
2
3
3
import android.app.Application
4
4
import androidx.lifecycle.Lifecycle
5
+ import androidx.lifecycle.LifecycleOwner
6
+ import androidx.lifecycle.LifecycleRegistry
5
7
import androidx.test.core.app.ActivityScenario
6
8
import androidx.test.core.app.ApplicationProvider
7
9
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -26,9 +28,10 @@ import arcs.sdk.android.storage.service.DefaultConnectionFactory
26
28
import arcs.sdk.android.storage.service.testutil.TestBindingDelegate
27
29
import com.google.common.truth.Truth.assertThat
28
30
import com.nhaarman.mockitokotlin2.mock
31
+ import kotlinx.coroutines.Dispatchers
32
+ import kotlinx.coroutines.delay
29
33
import kotlinx.coroutines.launch
30
34
import kotlinx.coroutines.runBlocking
31
- import kotlinx.coroutines.test.TestCoroutineScope
32
35
import kotlinx.coroutines.test.runBlockingTest
33
36
import org.junit.Before
34
37
import org.junit.Test
@@ -39,27 +42,32 @@ import org.mockito.Mockito.verify
39
42
40
43
@Suppress(" EXPERIMENTAL_API_USAGE" )
41
44
@RunWith(AndroidJUnit4 ::class )
42
- class AndroidHandleManagerTest {
45
+ class AndroidHandleManagerTest : LifecycleOwner {
46
+ private lateinit var lifecycle: LifecycleRegistry
47
+ override fun getLifecycle () = lifecycle
48
+
43
49
private lateinit var app: Application
44
50
51
+ private lateinit var handleManager: HandleManager
52
+
45
53
val entity1 = RawEntity (
46
54
" entity1" ,
47
- singletons= mapOf (
55
+ singletons = mapOf (
48
56
" name" to " Jason" .toReferencable(),
49
57
" age" to 21 .toReferencable(),
50
58
" is_cool" to false .toReferencable()
51
59
),
52
- collections= emptyMap()
60
+ collections = emptyMap()
53
61
)
54
62
55
63
val entity2 = RawEntity (
56
64
" entity2" ,
57
- singletons= mapOf (
65
+ singletons = mapOf (
58
66
" name" to " Jason" .toReferencable(),
59
67
" age" to 22 .toReferencable(),
60
68
" is_cool" to true .toReferencable()
61
69
),
62
- collections= emptyMap()
70
+ collections = emptyMap()
63
71
)
64
72
65
73
private val schema = Schema (
@@ -88,140 +96,114 @@ class AndroidHandleManagerTest {
88
96
@Before
89
97
fun setUp () {
90
98
RamDisk .clear()
99
+ lifecycle = LifecycleRegistry (this ).apply {
100
+ setCurrentState(Lifecycle .State .CREATED )
101
+ setCurrentState(Lifecycle .State .STARTED )
102
+ setCurrentState(Lifecycle .State .RESUMED )
103
+ }
91
104
app = ApplicationProvider .getApplicationContext()
92
- app.setTheme(R .style.Theme_AppCompat );
93
105
94
106
// Initialize WorkManager for instrumentation tests.
95
107
WorkManagerTestInitHelper .initializeTestWorkManager(app)
96
- }
97
108
98
- fun handleManagerTest (
99
- block : suspend TestCoroutineScope .(HandleManager ) -> Unit
100
- ) = runBlockingTest {
101
- val scenario = ActivityScenario .launch(TestActivity ::class .java)
102
-
103
- scenario.moveToState(Lifecycle .State .STARTED )
104
-
105
- val activityJob = launch {
106
- scenario.onActivity { activity ->
107
- val hf = AndroidHandleManager (
108
- lifecycle = activity.lifecycle,
109
- context = activity,
110
- connectionFactory = DefaultConnectionFactory (activity, TestBindingDelegate (app)),
111
- coroutineContext = coroutineContext
112
- )
113
- runBlocking {
114
- this @runBlockingTest.block(hf)
115
- }
116
- scenario.close()
117
- }
118
- }
119
-
120
- activityJob.join()
109
+ handleManager = AndroidHandleManager (
110
+ lifecycle = lifecycle,
111
+ context = app,
112
+ connectionFactory = DefaultConnectionFactory (app, TestBindingDelegate (app))
113
+ )
121
114
}
122
115
123
116
@Test
124
- fun testCreateSingletonHandle () = runBlockingTest {
125
- handleManagerTest { hm ->
126
- val singletonHandle = hm.singletonHandle(singletonKey, schema)
127
- singletonHandle.store(entity1)
128
-
129
- // Now read back from a different handle
130
- val readbackHandle = hm.singletonHandle(singletonKey, schema)
131
- val readBack = readbackHandle.fetch()
132
- assertThat(readBack).isEqualTo(entity1)
133
- }
117
+ fun singleton_writeAndReadback () = runBlocking {
118
+ val singletonHandle = handleManager.singletonHandle(singletonKey, schema)
119
+ singletonHandle.store(entity1)
120
+
121
+ // Now read back from a different handle
122
+ val readbackHandle = handleManager.singletonHandle(singletonKey, schema)
123
+ val readBack = readbackHandle.fetch()
124
+ assertThat(readBack).isEqualTo(entity1)
125
+
134
126
}
135
127
136
128
@Test
137
- fun testCreateSetHandle () = runBlockingTest {
138
- handleManagerTest { hm ->
139
- val setHandle = hm.setHandle(setKey, schema)
140
- setHandle.store(entity1)
141
- setHandle.store(entity2)
142
-
143
- // Now read back from a different handle
144
- val secondHandle = hm.setHandle(setKey, schema)
145
- val readBack = secondHandle.fetchAll()
146
- assertThat(readBack).containsExactly(entity1, entity2)
147
- }
129
+ fun set_writeAndReadback () = runBlocking<Unit > {
130
+ val setHandle = handleManager.setHandle(setKey, schema)
131
+ setHandle.store(entity1)
132
+ setHandle.store(entity2)
133
+
134
+ // Now read back from a different handle
135
+ val secondHandle = handleManager.setHandle(setKey, schema)
136
+ val readBack = secondHandle.fetchAll()
137
+ assertThat(readBack).containsExactly(entity1, entity2)
148
138
}
149
139
150
140
private fun testMapForKey (key : StorageKey ) = VersionMap (key.toKeyString() to 1 )
151
141
152
142
@Test
153
- fun testSetHandleOnUpdate () = runBlockingTest {
154
- handleManagerTest { hm ->
155
- val testCallback1 = mock<SetCallbacks <RawEntity >>()
156
- val testCallback2 = mock<SetCallbacks <RawEntity >>()
157
- val firstHandle = hm.setHandle(setKey, schema, testCallback1)
158
- val secondHandle = hm.setHandle(setKey, schema, testCallback2)
159
-
160
- val expectedAdd = CrdtSet .Operation .Add (
161
- setKey.toKeyString(),
162
- testMapForKey(setKey),
163
- entity1
164
- )
165
- secondHandle.store(entity1)
166
- verify(testCallback1, times(1 )).onUpdate(firstHandle, expectedAdd)
167
- verify(testCallback2, times(1 )).onUpdate(secondHandle, expectedAdd)
168
-
169
- firstHandle.remove(entity1)
170
- val expectedRemove = CrdtSet .Operation .Remove (
171
- setKey.toKeyString(),
172
- testMapForKey(setKey),
173
- entity1
174
- )
175
- verify(testCallback1, times(1 )).onUpdate(firstHandle, expectedRemove)
176
- verify(testCallback2, times(1 )).onUpdate(secondHandle, expectedRemove)
177
- }
143
+ fun set_onHandleUpdate () = runBlocking<Unit > {
144
+ val testCallback1 = mock<SetCallbacks <RawEntity >>()
145
+ val testCallback2 = mock<SetCallbacks <RawEntity >>()
146
+ val firstHandle = handleManager.setHandle(setKey, schema, testCallback1)
147
+ val secondHandle = handleManager.setHandle(setKey, schema, testCallback2)
148
+
149
+ val expectedAdd = CrdtSet .Operation .Add (
150
+ setKey.toKeyString(),
151
+ testMapForKey(setKey),
152
+ entity1
153
+ )
154
+ secondHandle.store(entity1)
155
+ verify(testCallback1, times(1 )).onUpdate(firstHandle, expectedAdd)
156
+ verify(testCallback2, times(1 )).onUpdate(secondHandle, expectedAdd)
157
+
158
+ firstHandle.remove(entity1)
159
+ val expectedRemove = CrdtSet .Operation .Remove (
160
+ setKey.toKeyString(),
161
+ testMapForKey(setKey),
162
+ entity1
163
+ )
164
+ verify(testCallback1, times(1 )).onUpdate(firstHandle, expectedRemove)
165
+ verify(testCallback2, times(1 )).onUpdate(secondHandle, expectedRemove)
178
166
}
179
167
180
168
@Test
181
- fun testSingletonHandleOnUpdate () = runBlockingTest {
182
- handleManagerTest { hm ->
183
- val testCallback1 = mock<SingletonCallbacks <RawEntity >>()
184
- val testCallback2 = mock<SingletonCallbacks <RawEntity >>()
185
- val firstHandle = hm.singletonHandle(singletonKey, schema, testCallback1)
186
- val secondHandle = hm.singletonHandle(singletonKey, schema, testCallback2)
187
- secondHandle.store(entity1)
188
- val expectedAdd = CrdtSingleton .Operation .Update (
189
- singletonKey.toKeyString(),
190
- testMapForKey(singletonKey),
191
- entity1
192
- )
193
- verify(testCallback1, times(1 )).onUpdate(firstHandle, expectedAdd)
194
- verify(testCallback2, times(1 )).onUpdate(secondHandle, expectedAdd)
195
- firstHandle.clear()
196
-
197
- val expectedRemove = CrdtSingleton .Operation .Clear <RawEntity >(
198
- singletonKey.toKeyString(),
199
- testMapForKey(singletonKey)
200
- )
201
- verify(testCallback1, times(1 )).onUpdate(firstHandle, expectedRemove)
202
- verify(testCallback2, times(1 )).onUpdate(secondHandle, expectedRemove)
203
- }
169
+ fun singleton_OnHandleUpdate () = runBlocking<Unit > {
170
+ val testCallback1 = mock<SingletonCallbacks <RawEntity >>()
171
+ val testCallback2 = mock<SingletonCallbacks <RawEntity >>()
172
+ val firstHandle = handleManager.singletonHandle(singletonKey, schema, testCallback1)
173
+ val secondHandle = handleManager.singletonHandle(singletonKey, schema, testCallback2)
174
+ secondHandle.store(entity1)
175
+ val expectedAdd = CrdtSingleton .Operation .Update (
176
+ singletonKey.toKeyString(),
177
+ testMapForKey(singletonKey),
178
+ entity1
179
+ )
180
+ verify(testCallback1, times(1 )).onUpdate(firstHandle, expectedAdd)
181
+ verify(testCallback2, times(1 )).onUpdate(secondHandle, expectedAdd)
182
+ firstHandle.clear()
183
+
184
+ val expectedRemove = CrdtSingleton .Operation .Clear <RawEntity >(
185
+ singletonKey.toKeyString(),
186
+ testMapForKey(singletonKey)
187
+ )
188
+ verify(testCallback1, times(1 )).onUpdate(firstHandle, expectedRemove)
189
+ verify(testCallback2, times(1 )).onUpdate(secondHandle, expectedRemove)
204
190
}
205
191
206
192
@Test
207
- fun testSetSyncOnRegister () = runBlockingTest {
208
- handleManagerTest { hm ->
209
- val testCallback = mock<SetCallbacks <RawEntity >>()
210
- val firstHandle = hm.setHandle(setKey, schema, testCallback)
211
- verify(testCallback, times(1 )).onSync(firstHandle)
212
- firstHandle.fetchAll()
213
- verify(testCallback, times(1 )).onSync(firstHandle)
214
- }
193
+ fun set_syncOnRegister () = runBlocking<Unit > {
194
+ val testCallback = mock<SetCallbacks <RawEntity >>()
195
+ val firstHandle = handleManager.setHandle(setKey, schema, testCallback)
196
+ verify(testCallback, times(1 )).onSync(firstHandle)
197
+ firstHandle.fetchAll()
198
+ verify(testCallback, times(1 )).onSync(firstHandle)
215
199
}
216
200
217
201
@Test
218
- fun testSingletonSyncOnRegister () = runBlockingTest {
219
- handleManagerTest { hm ->
220
- val testCallback = mock<SingletonCallbacks <RawEntity >>()
221
- val firstHandle = hm.singletonHandle(setKey, schema, testCallback)
222
- verify(testCallback, times(1 )).onSync(firstHandle)
223
- firstHandle.fetch()
224
- verify(testCallback, times(1 )).onSync(firstHandle)
225
- }
202
+ fun testSingletonSyncOnRegister () = runBlocking<Unit > {
203
+ val testCallback = mock<SingletonCallbacks <RawEntity >>()
204
+ val firstHandle = handleManager.singletonHandle(setKey, schema, testCallback)
205
+ verify(testCallback, times(1 )).onSync(firstHandle)
206
+ firstHandle.fetch()
207
+ verify(testCallback, times(1 )).onSync(firstHandle)
226
208
}
227
209
}
0 commit comments