File tree Expand file tree Collapse file tree 10 files changed +159
-19
lines changed
components/service/glean/src
main/java/mozilla/components/service/glean
test/java/mozilla/components/service/glean Expand file tree Collapse file tree 10 files changed +159
-19
lines changed Original file line number Diff line number Diff line change
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
+
5
+ package mozilla.components.service.glean
6
+
7
+ import kotlinx.coroutines.CoroutineScope
8
+ import kotlinx.coroutines.ObsoleteCoroutinesApi
9
+ import kotlinx.coroutines.newSingleThreadContext
10
+
11
+ @ObsoleteCoroutinesApi
12
+ internal object Dispatchers {
13
+ /* *
14
+ * A coroutine scope to make it easy to dispatch API calls off the main thread.
15
+ * This needs to be a `var` so that our tests can override this.
16
+ */
17
+ var API = CoroutineScope (newSingleThreadContext(" GleanAPIPool" ))
18
+ }
Original file line number Diff line number Diff line change 4
4
5
5
package mozilla.components.service.glean
6
6
7
+ import kotlinx.coroutines.launch
7
8
import mozilla.components.service.glean.storages.EventsStorageEngine
8
9
import mozilla.components.support.base.log.logger.Logger
9
10
@@ -101,14 +102,16 @@ data class EventMetricType(
101
102
eventKeys
102
103
}
103
104
104
- // Delegate storing the event to the storage engine.
105
- EventsStorageEngine .record(
106
- stores = getStorageNames(),
107
- category = category,
108
- name = name,
109
- objectId = objectId,
110
- value = truncatedValue,
111
- extra = truncatedExtraKeys
112
- )
105
+ Dispatchers .API .launch {
106
+ // Delegate storing the event to the storage engine.
107
+ EventsStorageEngine .record(
108
+ stores = getStorageNames(),
109
+ category = category,
110
+ name = name,
111
+ objectId = objectId,
112
+ value = truncatedValue,
113
+ extra = truncatedExtraKeys
114
+ )
115
+ }
113
116
}
114
117
}
Original file line number Diff line number Diff line change 4
4
5
5
package mozilla.components.service.glean
6
6
7
+ import kotlinx.coroutines.launch
7
8
import mozilla.components.service.glean.storages.StringsStorageEngine
8
9
import mozilla.components.support.base.log.logger.Logger
9
10
@@ -54,10 +55,12 @@ data class StringMetricType(
54
55
it
55
56
}
56
57
57
- // Delegate storing the string to the storage engine.
58
- StringsStorageEngine .record(
59
- this ,
60
- value = truncatedValue
61
- )
58
+ Dispatchers .API .launch {
59
+ // Delegate storing the string to the storage engine.
60
+ StringsStorageEngine .record(
61
+ this @StringMetricType,
62
+ value = truncatedValue
63
+ )
64
+ }
62
65
}
63
66
}
Original file line number Diff line number Diff line change 4
4
5
5
package mozilla.components.service.glean
6
6
7
+ import kotlinx.coroutines.launch
7
8
import java.util.UUID
8
9
9
10
import mozilla.components.service.glean.storages.UuidsStorageEngine
@@ -31,15 +32,26 @@ data class UuidMetricType(
31
32
32
33
/* *
33
34
* Generate a new UUID value and set it in the metric store.
35
+ *
36
+ * @return a [UUID] or [null] if we're not allowed to record.
34
37
*/
35
- fun generateAndSet (): UUID {
38
+ fun generateAndSet (): UUID ? {
39
+ // Even if `set` is already checking if we're allowed to record,
40
+ // we need to check here as well otherwise we'd return a `UUID`
41
+ // that won't be stored anywhere.
42
+ if (! shouldRecord(logger)) {
43
+ return null
44
+ }
45
+
36
46
val uuid = UUID .randomUUID()
37
47
set(uuid)
38
48
return uuid
39
49
}
40
50
41
51
/* *
42
52
* Explicitly set an existing UUID value
53
+ *
54
+ * @param value a valid [UUID] to set the metric to
43
55
*/
44
56
fun set (value : UUID ) {
45
57
// TODO report errors through other special metrics handled by the SDK. See bug 1499761.
@@ -48,10 +60,12 @@ data class UuidMetricType(
48
60
return
49
61
}
50
62
51
- // Delegate storing the event to the storage engine.
52
- UuidsStorageEngine .record(
53
- this ,
63
+ Dispatchers .API .launch {
64
+ // Delegate storing the event to the storage engine.
65
+ UuidsStorageEngine .record(
66
+ this @UuidMetricType,
54
67
value = value
55
- )
68
+ )
69
+ }
56
70
}
57
71
}
Original file line number Diff line number Diff line change
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
+
5
+ package mozilla.components.service.glean
6
+
7
+ import kotlinx.coroutines.launch
8
+ import kotlinx.coroutines.runBlocking
9
+ import org.junit.Test
10
+
11
+ import org.junit.Assert.assertEquals
12
+ import org.junit.Assert.assertNotSame
13
+ import org.junit.Assert.assertSame
14
+
15
+ class DispatchersTest {
16
+
17
+ @Test
18
+ fun `API scope runs off the main thread` () {
19
+ val mainThread = Thread .currentThread()
20
+ var threadCanary = false
21
+
22
+ runBlocking {
23
+ Dispatchers .API .launch {
24
+ assertNotSame(mainThread, Thread .currentThread())
25
+ // Use the canary bool to make sure this is getting called before
26
+ // the test completes.
27
+ assertEquals(false , threadCanary)
28
+ threadCanary = true
29
+ }.join()
30
+ }
31
+
32
+ assertEquals(true , threadCanary)
33
+ assertSame(mainThread, Thread .currentThread())
34
+ }
35
+ }
Original file line number Diff line number Diff line change 5
5
package mozilla.components.service.glean
6
6
7
7
import android.os.SystemClock
8
+ import kotlinx.coroutines.ExperimentalCoroutinesApi
9
+ import kotlinx.coroutines.ObsoleteCoroutinesApi
8
10
import mozilla.components.service.glean.storages.EventsStorageEngine
9
11
import org.junit.Assert.assertEquals
10
12
import org.junit.Assert.assertNull
11
13
import org.junit.Assert.assertTrue
12
14
import org.junit.Test
13
15
14
16
import org.junit.Before
17
+ import org.junit.Rule
15
18
import org.junit.runner.RunWith
16
19
import org.robolectric.RobolectricTestRunner
17
20
21
+ @ObsoleteCoroutinesApi
22
+ @ExperimentalCoroutinesApi
18
23
@RunWith(RobolectricTestRunner ::class )
19
24
class EventMetricTypeTest {
20
25
26
+ @get:Rule
27
+ val fakeDispatchers = FakeDispatchersInTest ()
28
+
21
29
@Before
22
30
fun setUp () {
23
31
EventsStorageEngine .clearAllStores()
Original file line number Diff line number Diff line change
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
+
5
+ package mozilla.components.service.glean
6
+
7
+ import kotlinx.coroutines.CoroutineScope
8
+ import kotlinx.coroutines.ExperimentalCoroutinesApi
9
+ import kotlinx.coroutines.ObsoleteCoroutinesApi
10
+ import org.junit.rules.ExternalResource
11
+
12
+ /* *
13
+ * A class that stubs the coroutine scopes in [Dispatchers] to allow blocking
14
+ * on async API calls when running tests.
15
+ *
16
+ * Note: according to [kotlinx.coroutines.Dispatchers.Unconfined], this will work
17
+ * as long as the API doesn't use any suspending function.
18
+ */
19
+ @ExperimentalCoroutinesApi @ObsoleteCoroutinesApi
20
+ class FakeDispatchersInTest : ExternalResource () {
21
+ companion object {
22
+ private val testMainScope = CoroutineScope (kotlinx.coroutines.Dispatchers .Unconfined )
23
+ private val originalAPIScope = Dispatchers .API
24
+ }
25
+
26
+ override fun before () {
27
+ Dispatchers .API = testMainScope
28
+ }
29
+
30
+ override fun after () {
31
+ Dispatchers .API = originalAPIScope
32
+ }
33
+ }
Original file line number Diff line number Diff line change @@ -6,6 +6,8 @@ package mozilla.components.service.glean
6
6
7
7
import android.content.Context
8
8
import androidx.test.core.app.ApplicationProvider
9
+ import kotlinx.coroutines.ExperimentalCoroutinesApi
10
+ import kotlinx.coroutines.ObsoleteCoroutinesApi
9
11
import kotlinx.coroutines.runBlocking
10
12
import mozilla.components.service.glean.net.HttpPingUploader
11
13
import mozilla.components.service.glean.storages.EventsStorageEngine
@@ -18,6 +20,7 @@ import org.junit.Assert.assertNotNull
18
20
import org.junit.Assert.assertNull
19
21
import org.junit.Assert.assertTrue
20
22
import org.junit.Before
23
+ import org.junit.Rule
21
24
import org.junit.Test
22
25
import org.junit.runner.RunWith
23
26
import org.mockito.ArgumentMatchers.anyString
@@ -27,8 +30,14 @@ import org.robolectric.RobolectricTestRunner
27
30
import java.io.File
28
31
import java.util.UUID
29
32
33
+ @ObsoleteCoroutinesApi
34
+ @ExperimentalCoroutinesApi
30
35
@RunWith(RobolectricTestRunner ::class )
31
36
class GleanTest {
37
+
38
+ @get:Rule
39
+ val fakeDispatchers = FakeDispatchersInTest ()
40
+
32
41
@Before
33
42
fun setup () {
34
43
Glean .initialize(
Original file line number Diff line number Diff line change @@ -6,17 +6,25 @@ package mozilla.components.service.glean
6
6
7
7
import android.content.Context
8
8
import androidx.test.core.app.ApplicationProvider
9
+ import kotlinx.coroutines.ExperimentalCoroutinesApi
10
+ import kotlinx.coroutines.ObsoleteCoroutinesApi
9
11
import mozilla.components.service.glean.storages.StringsStorageEngine
10
12
import org.junit.Assert.assertEquals
11
13
import org.junit.Assert.assertNull
12
14
import org.junit.Before
15
+ import org.junit.Rule
13
16
import org.junit.Test
14
17
import org.junit.runner.RunWith
15
18
import org.robolectric.RobolectricTestRunner
16
19
20
+ @ObsoleteCoroutinesApi
21
+ @ExperimentalCoroutinesApi
17
22
@RunWith(RobolectricTestRunner ::class )
18
23
class StringMetricTypeTest {
19
24
25
+ @get:Rule
26
+ val fakeDispatchers = FakeDispatchersInTest ()
27
+
20
28
@Before
21
29
fun setUp () {
22
30
StringsStorageEngine .applicationContext = ApplicationProvider .getApplicationContext()
Original file line number Diff line number Diff line change @@ -6,18 +6,26 @@ package mozilla.components.service.glean
6
6
7
7
import android.content.Context
8
8
import androidx.test.core.app.ApplicationProvider
9
+ import kotlinx.coroutines.ExperimentalCoroutinesApi
10
+ import kotlinx.coroutines.ObsoleteCoroutinesApi
9
11
import mozilla.components.service.glean.storages.UuidsStorageEngine
10
12
import org.junit.Assert.assertEquals
11
13
import org.junit.Assert.assertNull
12
14
import org.junit.Before
15
+ import org.junit.Rule
13
16
import org.junit.Test
14
17
import org.junit.runner.RunWith
15
18
import org.robolectric.RobolectricTestRunner
16
19
import java.util.UUID
17
20
21
+ @ObsoleteCoroutinesApi
22
+ @ExperimentalCoroutinesApi
18
23
@RunWith(RobolectricTestRunner ::class )
19
24
class UuidMetricTypeTest {
20
25
26
+ @get:Rule
27
+ val fakeDispatchers = FakeDispatchersInTest ()
28
+
21
29
@Before
22
30
fun setUp () {
23
31
UuidsStorageEngine .applicationContext = ApplicationProvider .getApplicationContext()
@@ -52,6 +60,7 @@ class UuidMetricTypeTest {
52
60
53
61
val uuid2 = UUID .fromString(" ce2adeb8-843a-4232-87a5-a099ed1e7bb3" )
54
62
uuidMetric.set(uuid2)
63
+
55
64
// Check that data was properly recorded.
56
65
val snapshot2 = UuidsStorageEngine .getSnapshot(storeName = " store1" , clearStore = false )
57
66
assertEquals(1 , snapshot2!! .size)
You can’t perform that action at this time.
0 commit comments