Test that events in custom pings are flushed at startup.

This also specifically points out in the docs that pings need to be
registered before initialization for this to work.
This commit is contained in:
Jan-Erik Rediger 2020-10-09 15:08:42 +02:00
Родитель eda285fedc
Коммит c5e1bdc576
3 изменённых файлов: 98 добавлений и 20 удалений

Просмотреть файл

@ -1,4 +1,4 @@
personal_ws-1.1 en 195 utf-8
personal_ws-1.1 en 197 utf-8
AAR
AARs
ABI
@ -13,7 +13,6 @@ CODEOWNERS
Cartfile
CircleCI
Ciufo
deterministically
DNS
DOM
Datetime
@ -68,6 +67,7 @@ UTF
UUID
UUIDs
Underflowing
Wasm
WebRender
Xcode
YAML
@ -104,6 +104,7 @@ csh
dataset
datetime
destructor
deterministically
dev
dexter
distributable
@ -191,7 +192,6 @@ und
unhandled
uploader
vendored
Wasm
webpages
xcpretty
yaml

Просмотреть файл

@ -51,17 +51,16 @@ The Glean SDK build generates code from `pings.yaml` in a `Pings` object, which
<div data-lang="Kotlin" class="tab">
In Kotlin, this object must be registered with the Glean SDK from your startup code (such as in your application's `onCreate` method or a function called from that method).
In Kotlin, this object must be registered with the Glean SDK from your startup code before calling `Glean.initialize`
(such as in your application's `onCreate` method or a function called from that method).
```Kotlin
import org.mozilla.yourApplication.GleanMetrics.Pings
...
override fun onCreate() {
...
Glean.registerPings(Pings)
...
Glean.initialize(applicationContext, uploadEnabled = true)
}
```
@ -69,7 +68,7 @@ override fun onCreate() {
<div data-lang="Swift" class="tab">
In Swift, this object must be registered with the Glean SDK from your startup code
In Swift, this object must be registered with the Glean SDK from your startup code before calling `Glean.shared.initialize`
(such as in your application's `UIApplicationDelegate` [`application(_:didFinishLaunchingWithOptions:)`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622921-application) method or a function called from that method).
```swift
@ -77,11 +76,11 @@ import Glean
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// ...
Glean.shared.registerPings(GleanMetrics.Pings)
// ...
}
func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Glean.shared.registerPings(GleanMetrics.Pings)
Glean.shared.initialize(uploadEnabled = true)
}
}
```
@ -91,12 +90,18 @@ func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplicati
For Python, the `pings.yaml` file must be available and loaded at runtime.
If your project is a script (i.e. just Python files in a directory), you can load the `pings.yaml` using:
If your project is a script (i.e. just Python files in a directory), you can load the `pings.yaml` before calling `Glean.initialize` using:
```
```python
from glean import load_pings
pings = load_pings("pings.yaml")
Glean.initialize(
application_id="my-app-id",
application_version="0.1.0",
upload_enabled=True,
)
```
If your project is a distributable Python package, you need to include the `pings.yaml` file using [one of the myriad ways to include data in a Python package](https://setuptools.readthedocs.io/en/latest/setuptools.html#including-data-files) and then use [`pkg_resources.resource_filename()`](https://setuptools.readthedocs.io/en/latest/pkg_resources.html#resource-extraction) to get the filename at runtime.

Просмотреть файл

@ -9,6 +9,9 @@ import mozilla.telemetry.glean.Glean
import mozilla.telemetry.glean.getPlainBody
import mozilla.telemetry.glean.getContextWithMockedInfo
import mozilla.telemetry.glean.getMockWebServer
import mozilla.telemetry.glean.private.EventMetricType
import mozilla.telemetry.glean.private.Lifetime
import mozilla.telemetry.glean.private.NoExtraKeys
import mozilla.telemetry.glean.private.NoReasonCodes
import mozilla.telemetry.glean.private.PingType
import mozilla.telemetry.glean.resetGlean
@ -16,10 +19,13 @@ import mozilla.telemetry.glean.testing.GleanTestRule
import mozilla.telemetry.glean.triggerWorkManager
import mozilla.telemetry.glean.utils.tryGetLong
import mozilla.telemetry.glean.delayMetricsPing
import okhttp3.mockwebserver.MockWebServer
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.After
import org.junit.Before
import org.json.JSONObject
import java.util.concurrent.TimeUnit
@ -34,16 +40,25 @@ import java.util.concurrent.TimeUnit
@RunWith(AndroidJUnit4::class)
class CustomPingTest {
private val context = getContextWithMockedInfo()
private lateinit var server: MockWebServer
@get:Rule
val gleanRule = GleanTestRule(context)
@Before
fun setup() {
server = getMockWebServer()
}
@After
fun teardown() {
server.shutdown()
}
@Test
fun `sends empty custom ping`() {
// a smoke test for custom pings
val server = getMockWebServer()
delayMetricsPing(context)
resetGlean(context, Glean.configuration.copy(
serverEndpoint = "http://" + server.hostName + ":" + server.port
@ -67,8 +82,6 @@ class CustomPingTest {
@Test
fun `multiple pings in one go`() {
val server = getMockWebServer()
delayMetricsPing(context)
resetGlean(context, Glean.configuration.copy(
serverEndpoint = "http://" + server.hostName + ":" + server.port
@ -111,4 +124,64 @@ class CustomPingTest {
pingInfo = pingJson.getJSONObject("ping_info")
assertEquals(1L, pingInfo.tryGetLong("seq")!!)
}
@Test
fun `events for custom pings are flushed at startup`() {
delayMetricsPing(context)
resetGlean(context, Glean.configuration.copy(
serverEndpoint = "http://" + server.hostName + ":" + server.port
), clearStores = true, uploadEnabled = true)
val pingName = "custom-events-1"
// Define a 'click' event
val click = EventMetricType<NoExtraKeys>(
disabled = false,
category = "ui",
lifetime = Lifetime.Ping,
name = "click",
sendInPings = listOf(pingName),
allowedExtraKeys = listOf()
)
// and record it in the currently initialized Glean instance.
click.record()
// We need to simulate that the app is shutdown and all resources are freed.
Glean.testDestroyGleanHandle()
// Define a new custom ping inline.
// This will register the ping as well.
// Ususally this happens in user code by calling `Glean.registerPings(Pings)`
@Suppress("UNUSED_VARIABLE")
val customPing = PingType<NoReasonCodes>(
name = pingName,
includeClientId = true,
sendIfEmpty = false,
reasonCodes = emptyList()
)
// This is equivalent to a consumer calling `Glean.initialize` at startup
resetGlean(context, Glean.configuration.copy(
serverEndpoint = "http://" + server.hostName + ":" + server.port
), clearStores = true, uploadEnabled = true)
// Trigger work manager once.
// This should launch one worker that handles all pending pings.
triggerWorkManager(context)
// Receive the custom events ping.
var request = server.takeRequest(2L, TimeUnit.SECONDS)
var docType = request.path.split("/")[3]
assertEquals(pingName, docType)
val pingJson = JSONObject(request.getPlainBody())
val events = pingJson.getJSONArray("events")
assertEquals(1, events.length())
val event = events.getJSONObject(0)
val category = event.getString("category")
val name = event.getString("name")
assertEquals("ui.click", "$category.$name")
assertEquals(0, event.getLong("timestamp"))
}
}