diff --git a/.buildconfig.yml b/.buildconfig.yml index 2aa74abad2..7f8420851a 100644 --- a/.buildconfig.yml +++ b/.buildconfig.yml @@ -1,4 +1,4 @@ -libraryVersion: 61.1.0 +libraryVersion: 61.2.0 groupId: org.mozilla.telemetry projects: glean: diff --git a/CHANGELOG.md b/CHANGELOG.md index 797d1833e6..f1fb892d20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,15 @@ # Unreleased changes -[Full changelog](https://github.com/mozilla/glean/compare/v61.1.0...main) +[Full changelog](https://github.com/mozilla/glean/compare/v61.2.0...main) + +# v61.2.0 (2024-10-07) + +[Full changelog](https://github.com/mozilla/glean/compare/v61.1.0...v61.2.0) + +* Kotlin + * Accept a ping schedule map on initialize ([#2967](https://github.com/mozilla/glean/pull/2967)) +* Swift + * Accept a ping schedule map on initialize ([#2967](https://github.com/mozilla/glean/pull/2967)) # v61.1.0 (2024-09-24) diff --git a/Cargo.lock b/Cargo.lock index 8387a4fc7e..ac3f0aa302 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -318,7 +318,7 @@ dependencies = [ [[package]] name = "glean" -version = "61.1.0" +version = "61.2.0" dependencies = [ "crossbeam-channel", "env_logger", @@ -359,7 +359,7 @@ dependencies = [ [[package]] name = "glean-core" -version = "61.1.0" +version = "61.2.0" dependencies = [ "android_logger", "bincode", diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index e28136dcf7..ca4be60292 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -4948,9 +4948,9 @@ SOFTWARE. The following text applies to code linked from these dependencies: -* [glean-core 61.1.0]( https://github.com/mozilla/glean ) +* [glean-core 61.2.0]( https://github.com/mozilla/glean ) * [glean-build 15.0.1]( https://github.com/mozilla/glean ) -* [glean 61.1.0]( https://github.com/mozilla/glean ) +* [glean 61.2.0]( https://github.com/mozilla/glean ) * [zeitstempel 0.1.1]( https://github.com/badboy/zeitstempel ) ``` diff --git a/build-scripts/xc-universal-binary.sh b/build-scripts/xc-universal-binary.sh index 5707681ce0..f3cdb4355e 100644 --- a/build-scripts/xc-universal-binary.sh +++ b/build-scripts/xc-universal-binary.sh @@ -21,7 +21,6 @@ if [[ -n "${DEVELOPER_SDK_DIR:-}" ]]; then # # In this case, we need to add an extra library search path for build scripts and proc-macros, # # which run on the host instead of the target. # # (macOS Big Sur does not have linkable libraries in /usr/lib/.) - local libpath libpath="${DEVELOPER_SDK_DIR}/MacOSX.sdk/usr/lib" export LIBRARY_PATH="${libpath}:${LIBRARY_PATH:-}" fi diff --git a/docs/user/user/howto/real-time-events/real-time-events.md b/docs/user/user/howto/real-time-events/real-time-events.md index 6d806048ee..64bed6f6b2 100644 --- a/docs/user/user/howto/real-time-events/real-time-events.md +++ b/docs/user/user/howto/real-time-events/real-time-events.md @@ -1,36 +1,53 @@ # "Real-Time" Events -## Defining "Real-Time" Glean Events +## Defining "real-time" events within the Glean SDK -"Real-Time" in the context of [Glean events](../../../reference/metrics/event.md) directly relates to configuring the Glean SDK to send each event in an ["events" ping](../../pings/events.md) as soon as it is recorded. -This minimizes the time between instrumentation and reporting, but doesn't describe how quickly received data is made available for querying. +For the purposes of the Glean SDK and its capabilities, "real-time" is limited to: minimizing the time between instrumentation and reporting. +It does not imply or describe how quickly received data is made available for querying. -## Configuring Glean For "Real-Time" Events +## Methods to achieve this with Glean -Glean "events" ping submission can either be configured at [initialization](../../../reference/general/initializing.md) or through [Server Knobs](../../../user/server-knobs/other/max-events.md). +### Option 1: Configuring Glean to send all events as soon as they are recorded -Setting the maximum event threshold to a value of `1` will configure the Glean SDK to submit an "events" ping for every event recorded. +Glean ["events" ping](../../pings/events.md) submission can be configured either during [initialization](../../../reference/general/initializing.md) or through [Server Knobs](../../../user/server-knobs/other/max-events.md). + +Setting the maximum event threshold to a value of `1` will configure the Glean SDK to submit an "events" ping for each and every [event](../../../reference/metrics/event.md) as they +are recorded. By default, the Glean SDK will batch 500 events per "events" ping. + +### Option 2: Using a custom ping and submitting it immediately ("Pings-as-Events") + +If it isn't necessary to receive all Glean SDK events that are instrumented in an application in "real-time", it may be preferable to create a +[custom ping](../../pings/custom.md) which contains the relevant information to capture the context around the event and submit it as soon as +the application event occurs. + +This has some additional advantages over using just an event in that custom pings are less restrictive than the extras attached to the event +in what data and Glean SDK metric types can be used. + +If it is important to see the event that is being represented as a custom ping in context with other application events, then you only need to +define an event metric and use the `send_in_pings` parameter to send it in both the custom ping and the Glean built-in "events" ping. It can +then be seen in sequence and within context of all of the application events, and still be sent in "real-time" as needed. ## Considerations -### What "Real-Time" Glean Events Are _Not_ +### What "real-time" Glean events/pings are _not_ -Configuring the Glean SDK to submit events as soon as they are recorded does not mean to imply that the event data is available for analysis in -real time. There are networks to traverse, ingestion pipelines, etl, etc. that are all factors to keep in mind when considering how soon the data -is available for analysis purposes. This documentation only purports to cover configuring the Glean SDK to send the data in a real-time fashion and -does not make any assumptions about the analysis of data in real-time. +Configuring the Glean SDK to submit events as soon as they are recorded or using custom pings to submit data immediately does not mean that the +data is available for analysis in real time. There are networks to traverse, ingestion pipelines, etl, etc. that are all factors to keep in +mind when considering how soon the data is available for analysis purposes. This documentation only purports to cover configuring the Glean SDK +to send the data in a real-time fashion and does not make any assumptions about the analysis of data in real-time. -### More Network Requests +### More network requests -For every event recorded, a network request will be generated when the event is submitted for ingestion. By default, the Glean SDK batches up to -500 events per "events" ping, so this has the potential to generate up to 500 times as many network requests than the current default. +For every event recorded or custom ping submitted, a network request will be generated as the ping is submitted for ingestion. By default, the +Glean SDK batches up to 500 events per "events" ping, so this has the potential to generate up to 500 times as many network requests than the +current defaults for the Glean SDK "events" ping. -### More Ingestion Endpoint Traffic +### More ingestion endpoint traffic As a result of the increased network requests, the ingestion endpoint will need to handle this additional traffic. This increases the load of all the processing steps that are involved with ingesting event data from an application. -### Storage Space +### Storage space requirements Typically the raw dataset for Glean events contains 1-500 events in a single row of the database. This row also includes metadata such as information about the client application and the ping itself. With only a single event per "events" ping, the replication of this metadata diff --git a/glean-core/Cargo.toml b/glean-core/Cargo.toml index 8d2f551f26..1b46816bb0 100644 --- a/glean-core/Cargo.toml +++ b/glean-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "glean-core" -version = "61.1.0" +version = "61.2.0" authors = ["Jan-Erik Rediger ", "The Glean Team "] description = "A modern Telemetry library" repository = "https://github.com/mozilla/glean" diff --git a/glean-core/android/src/main/java/mozilla/telemetry/glean/Glean.kt b/glean-core/android/src/main/java/mozilla/telemetry/glean/Glean.kt index 43dadab988..70692beabe 100644 --- a/glean-core/android/src/main/java/mozilla/telemetry/glean/Glean.kt +++ b/glean-core/android/src/main/java/mozilla/telemetry/glean/Glean.kt @@ -257,7 +257,7 @@ open class GleanInternalAPI internal constructor() { enableEventTimestamps = configuration.enableEventTimestamps, experimentationId = configuration.experimentationId, enableInternalPings = configuration.enableInternalPings, - pingSchedule = emptyMap(), + pingSchedule = configuration.pingSchedule, pingLifetimeThreshold = configuration.pingLifetimeThreshold.toULong(), pingLifetimeMaxTime = configuration.pingLifetimeMaxTime.toULong(), ) diff --git a/glean-core/android/src/main/java/mozilla/telemetry/glean/config/Configuration.kt b/glean-core/android/src/main/java/mozilla/telemetry/glean/config/Configuration.kt index d7537f20ad..ea97cd3418 100644 --- a/glean-core/android/src/main/java/mozilla/telemetry/glean/config/Configuration.kt +++ b/glean-core/android/src/main/java/mozilla/telemetry/glean/config/Configuration.kt @@ -27,6 +27,9 @@ import mozilla.telemetry.glean.net.PingUploader * @property delayPingLifetimeIo Whether Glean should delay persistence of data from metrics with ping lifetime. * @property pingLifetimeThreshold Write count threshold when to auto-flush. `0` disables it. * @property pingLifetimeMaxTime After what time to auto-flush (in milliseconds). 0 disables it. + * @property pingSchedule A ping schedule map. + * Maps a ping name to a list of pings to schedule along with it. + * Only used if the ping's own ping schedule list is empty. */ data class Configuration @JvmOverloads constructor( val serverEndpoint: String = DEFAULT_TELEMETRY_ENDPOINT, @@ -44,6 +47,7 @@ data class Configuration @JvmOverloads constructor( val delayPingLifetimeIo: Boolean = true, val pingLifetimeThreshold: Int = 1000, val pingLifetimeMaxTime: Int = 0, + val pingSchedule: Map> = emptyMap(), ) { companion object { /** diff --git a/glean-core/android/src/test/java/mozilla/telemetry/glean/pings/RidealongPingTest.kt b/glean-core/android/src/test/java/mozilla/telemetry/glean/pings/RidealongPingTest.kt new file mode 100644 index 0000000000..d7933ac6cd --- /dev/null +++ b/glean-core/android/src/test/java/mozilla/telemetry/glean/pings/RidealongPingTest.kt @@ -0,0 +1,89 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package mozilla.telemetry.glean.scheduler + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import mozilla.telemetry.glean.Glean +import mozilla.telemetry.glean.delayMetricsPing +import mozilla.telemetry.glean.getContext +import mozilla.telemetry.glean.getMockWebServer +import mozilla.telemetry.glean.private.NoReasonCodes +import mozilla.telemetry.glean.private.PingType +import mozilla.telemetry.glean.resetGlean +import mozilla.telemetry.glean.testing.GleanTestRule +import mozilla.telemetry.glean.triggerWorkManager +import okhttp3.mockwebserver.MockWebServer +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import java.util.concurrent.TimeUnit + +/** + * Testing behavior of custom pings. + * + * We already rely on the Rust side to test custom pings, + * but this enables us to test the upload mechanism specifically. + * + * Even if this seemingly duplicates some of the testing, this should be kept around. + */ +@RunWith(AndroidJUnit4::class) +class RidealongPingTest { + private val context = getContext() + private lateinit var server: MockWebServer + + @get:Rule + val gleanRule = GleanTestRule(context) + + @Before + fun setup() { + server = getMockWebServer() + } + + @After + fun teardown() { + server.shutdown() + } + + @Test + fun `sends a ride-along custom ping on baseline schedule`() { + delayMetricsPing(context) + resetGlean( + context, + Glean.configuration.copy( + serverEndpoint = "http://" + server.hostName + ":" + server.port, + pingSchedule = mapOf("baseline" to listOf("custom-ping")), + ), + clearStores = true, + uploadEnabled = true, + ) + + // Define a new custom ping inline. + PingType( + name = "custom-ping", + includeClientId = true, + sendIfEmpty = true, + preciseTimestamps = true, + includeInfoSections = true, + enabled = true, + schedulesPings = emptyList(), + reasonCodes = emptyList(), + ) + + Glean.handleBackgroundEvent() + // Trigger it to upload + triggerWorkManager(context) + + var request = server.takeRequest(2L, TimeUnit.SECONDS)!! + var docType = request.path!!.split("/")[3] + assertEquals("baseline", docType) + + request = server.takeRequest(2L, TimeUnit.SECONDS)!! + docType = request.path!!.split("/")[3] + assertEquals("custom-ping", docType) + } +} diff --git a/glean-core/ios/Glean.xcodeproj/project.pbxproj b/glean-core/ios/Glean.xcodeproj/project.pbxproj index babe1c10e2..2a2d53042b 100644 --- a/glean-core/ios/Glean.xcodeproj/project.pbxproj +++ b/glean-core/ios/Glean.xcodeproj/project.pbxproj @@ -62,6 +62,7 @@ CD0CADA427E216810015A997 /* glean.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDD08C8527E21104007C8400 /* glean.swift */; }; CD0F7CC026F0F27900EDA6A4 /* UrlMetric.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD0F7CBF26F0F27900EDA6A4 /* UrlMetric.swift */; }; CD0F7CC226F0F28900EDA6A4 /* UrlMetricTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD0F7CC126F0F28900EDA6A4 /* UrlMetricTests.swift */; }; + CD3682F32CAC110300B02F04 /* RidealongPingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD3682F22CAC10FE00B02F04 /* RidealongPingTests.swift */; }; CD38786D271DCCC700C097D8 /* libglean_ffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CD38786C271DCCC700C097D8 /* libglean_ffi.a */; }; CD70CF932850D69500FC2014 /* Gzip in Frameworks */ = {isa = PBXBuildFile; productRef = CD70CF922850D69500FC2014 /* Gzip */; }; CD70CF982850D77200FC2014 /* OHHTTPStubs in Frameworks */ = {isa = PBXBuildFile; productRef = CD70CF972850D77200FC2014 /* OHHTTPStubs */; }; @@ -144,6 +145,7 @@ CD07A4DD2BC808AE007A0F1C /* ObjectMetric.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectMetric.swift; sourceTree = ""; }; CD0F7CBF26F0F27900EDA6A4 /* UrlMetric.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UrlMetric.swift; sourceTree = ""; }; CD0F7CC126F0F28900EDA6A4 /* UrlMetricTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UrlMetricTests.swift; sourceTree = ""; }; + CD3682F22CAC10FE00B02F04 /* RidealongPingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RidealongPingTests.swift; sourceTree = ""; }; CD387868271D9CD100C097D8 /* glean.udl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = glean.udl; path = ../../src/glean.udl; sourceTree = ""; }; CD38786C271DCCC700C097D8 /* libglean_ffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libglean_ffi.a; path = ../../target/libglean_ffi.a; sourceTree = ""; }; CD81DCF9282A8F9A00347965 /* RateMetric.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RateMetric.swift; sourceTree = ""; }; @@ -301,7 +303,6 @@ isa = PBXGroup; children = ( C27E756429D4B56500C6AADD /* Utils */, - 60691AEA28DD0BF200BDF31A /* BaselinePingTests.swift */, 1F39E7B1239F0741009B13B3 /* Debug */, 1FB8F8392326EBA500618E47 /* Config */, BF43A8CB232A613100545310 /* Metrics */, @@ -372,6 +373,8 @@ BF80AA5923992FFB00A8B172 /* Net */ = { isa = PBXGroup; children = ( + 60691AEA28DD0BF200BDF31A /* BaselinePingTests.swift */, + CD3682F22CAC10FE00B02F04 /* RidealongPingTests.swift */, BF80AA5E2399305200A8B172 /* DeletionRequestPingTests.swift */, BF80AA5A2399301200A8B172 /* HttpPingUploaderTests.swift */, ); @@ -637,6 +640,7 @@ CD0F7CC226F0F28900EDA6A4 /* UrlMetricTests.swift in Sources */, BFCBD6AB246D55CC0032096D /* TestUtils.swift in Sources */, AC06529E26E034BF00D92D5E /* QuantityMetricTypeTest.swift in Sources */, + CD3682F32CAC110300B02F04 /* RidealongPingTests.swift in Sources */, 1F58921223C923C4007D2D80 /* MetricsPingSchedulerTests.swift in Sources */, CD9DA7852BC809BE00E18F31 /* ObjectMetricTests.swift in Sources */, 1FD4527723395EEB00F4C7E8 /* UuidMetricTests.swift in Sources */, diff --git a/glean-core/ios/Glean/Config/Configuration.swift b/glean-core/ios/Glean/Config/Configuration.swift index 7576fc5cea..99f4370be2 100644 --- a/glean-core/ios/Glean/Config/Configuration.swift +++ b/glean-core/ios/Glean/Config/Configuration.swift @@ -15,6 +15,7 @@ public struct Configuration { let enableInternalPings: Bool let pingLifetimeThreshold: Int let pingLifetimeMaxTime: Int + let pingSchedule: [String: [String]] struct Constants { static let defaultTelemetryEndpoint = "https://incoming.telemetry.mozilla.org" @@ -36,6 +37,9 @@ public struct Configuration { /// * enableInternalPings Whether to enable internal pings. /// * pingLifetimeThreshold Write count threshold when to auto-flush. `0` disables it. /// * pingLifetimeMaxTime After what time to auto-flush (in milliseconds). 0 disables it. + /// * pingSchedule A ping schedule map. + /// Maps a ping name to a list of pings to schedule along with it. + /// Only used if the ping's own ping schedule list is empty. public init( maxEvents: Int32? = nil, channel: String? = nil, @@ -46,7 +50,8 @@ public struct Configuration { experimentationId: String? = nil, enableInternalPings: Bool = true, pingLifetimeThreshold: Int = 0, - pingLifetimeMaxTime: Int = 0 + pingLifetimeMaxTime: Int = 0, + pingSchedule: [String: [String]] = [:] ) { self.serverEndpoint = serverEndpoint ?? Constants.defaultTelemetryEndpoint self.maxEvents = maxEvents @@ -58,5 +63,6 @@ public struct Configuration { self.enableInternalPings = enableInternalPings self.pingLifetimeThreshold = pingLifetimeThreshold self.pingLifetimeMaxTime = pingLifetimeMaxTime + self.pingSchedule = pingSchedule } } diff --git a/glean-core/ios/Glean/Glean.swift b/glean-core/ios/Glean/Glean.swift index ea3829c82c..a9bd6664d1 100644 --- a/glean-core/ios/Glean/Glean.swift +++ b/glean-core/ios/Glean/Glean.swift @@ -196,7 +196,7 @@ public class Glean { enableEventTimestamps: configuration.enableEventTimestamps, experimentationId: configuration.experimentationId, enableInternalPings: configuration.enableInternalPings, - pingSchedule: [:], + pingSchedule: configuration.pingSchedule, pingLifetimeThreshold: UInt64(configuration.pingLifetimeThreshold), pingLifetimeMaxTime: UInt64(configuration.pingLifetimeMaxTime) ) diff --git a/glean-core/ios/Glean/Metrics/ObjectMetric.swift b/glean-core/ios/Glean/Metrics/ObjectMetric.swift index 103e7b9466..841f488a79 100644 --- a/glean-core/ios/Glean/Metrics/ObjectMetric.swift +++ b/glean-core/ios/Glean/Metrics/ObjectMetric.swift @@ -13,7 +13,7 @@ extension Array: ObjectSerialize where Element: Codable { public func intoSerializedObject() -> String { let jsonEncoder = JSONEncoder() let jsonData = try! jsonEncoder.encode(self) - let json = String(decoding: jsonData, as: UTF8.self) + let json = String(data: jsonData, encoding: String.Encoding.utf8)! return json } } diff --git a/glean-core/ios/GleanTests/RidealongPingTests.swift b/glean-core/ios/GleanTests/RidealongPingTests.swift new file mode 100644 index 0000000000..26a05783e3 --- /dev/null +++ b/glean-core/ios/GleanTests/RidealongPingTests.swift @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +@testable import Glean +import OHHTTPStubs +import OHHTTPStubsSwift +import XCTest + +final class RidealongPingTests: XCTestCase { + var expectation: XCTestExpectation? + + override func tearDown() { + Glean.shared.testDestroyGleanHandle() + expectation = nil + tearDownStubs() + } + + func testSendRidealongPingWithBaseline() { + + let configuration = Configuration(pingSchedule: ["baseline": ["ridealong"]]) + resetGleanDiscardingInitialPings(testCase: self, tag: "RidealongPingTests", configuration: configuration) + + // Register ping _after_ Glean has been initialized to avoid this being sent multiple times. + _ = Ping( + name: "ridealong", + includeClientId: true, + sendIfEmpty: true, + preciseTimestamps: true, + includeInfoSections: true, + enabled: true, + schedulesPings: [], + reasonCodes: [] + ) + + // We receive a baseline ping, and a ridealong ping. + // The order might vary. + var pingsToReceive = ["baseline", "ridealong"] + + stubServerReceive { pingType, _ in + XCTAssertTrue(!pingsToReceive.isEmpty, "No more pings expected") + XCTAssertTrue(pingsToReceive.contains(pingType), "Expected ping types: \(pingsToReceive), got \(pingType)") + pingsToReceive.removeAll(where: { $0 == pingType }) + + if pingsToReceive.isEmpty { + DispatchQueue.main.async { + // let the response get processed before we mark the expectation fulfilled + self.expectation?.fulfill() + } + } + } + + // Set up the expectation that will be fulfilled by the stub above + expectation = expectation(description: "Pings Received") + + Glean.shared.submitPingByName("baseline") + + waitForExpectations(timeout: 5.0) { error in + XCTAssertNil(error, "Test timed out waiting for upload: \(error!)") + } + } +} diff --git a/glean-core/ios/GleanTests/TestUtils.swift b/glean-core/ios/GleanTests/TestUtils.swift index ead1f6fbb1..12c3bc9db6 100644 --- a/glean-core/ios/GleanTests/TestUtils.swift +++ b/glean-core/ios/GleanTests/TestUtils.swift @@ -49,7 +49,10 @@ func stubServerReceive(callback: @escaping (String, [String: Any]?) -> Void) { /// /// This also prevents outgoing network requests during unit tests while /// still allowing us to use the default telemetry endpoint. -func resetGleanDiscardingInitialPings(testCase: XCTestCase, tag: String, clearStores: Bool = true) { +func resetGleanDiscardingInitialPings(testCase: XCTestCase, + tag: String, + clearStores: Bool = true, + configuration: Configuration = Configuration()) { let expectation = testCase.expectation(description: "\(tag): Ping Received") // We are using OHHTTPStubs combined with an XCTestExpectation in order to capture @@ -85,7 +88,7 @@ func resetGleanDiscardingInitialPings(testCase: XCTestCase, tag: String, clearSt let mps = MetricsPingScheduler(true) mps.updateSentDate(Date()) - Glean.shared.resetGlean(clearStores: clearStores) + Glean.shared.resetGlean(configuration: configuration, clearStores: clearStores) testCase.waitForExpectations(timeout: 5.0) { error in XCTAssertNil(error, "Test timed out waiting for upload: \(error!)") @@ -104,7 +107,9 @@ func tearDownStubs() { func JSONStringify(_ json: Any) -> String { do { let data = try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted) - return String(decoding: data, as: UTF8.self) + if let string = String(data: data, encoding: String.Encoding.utf8) { + return string + } } catch { print(error) } diff --git a/glean-core/python/requirements_dev.txt b/glean-core/python/requirements_dev.txt index 8f86bf94c6..3526752b0b 100644 --- a/glean-core/python/requirements_dev.txt +++ b/glean-core/python/requirements_dev.txt @@ -14,5 +14,5 @@ setuptools-git==1.2 twine==5.0.0 types-pkg_resources==0.1.3 wheel==0.44.0 -maturin==1.7.1 +maturin==1.7.4 patchelf>=0.17; sys_platform == "linux" diff --git a/glean-core/rlb/Cargo.toml b/glean-core/rlb/Cargo.toml index 060a8eaf07..29dbd7470c 100644 --- a/glean-core/rlb/Cargo.toml +++ b/glean-core/rlb/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "glean" -version = "61.1.0" +version = "61.2.0" authors = ["Jan-Erik Rediger ", "The Glean Team "] description = "Glean SDK Rust language bindings" repository = "https://github.com/mozilla/glean" @@ -23,7 +23,7 @@ maintenance = { status = "actively-developed" } [dependencies.glean-core] path = ".." -version = "61.1.0" +version = "61.2.0" [dependencies] inherent = "1" diff --git a/gradle-plugin/src/main/groovy/mozilla/telemetry/glean-gradle-plugin/GleanGradlePlugin.groovy b/gradle-plugin/src/main/groovy/mozilla/telemetry/glean-gradle-plugin/GleanGradlePlugin.groovy index 9bf3ba2563..ec202e9970 100644 --- a/gradle-plugin/src/main/groovy/mozilla/telemetry/glean-gradle-plugin/GleanGradlePlugin.groovy +++ b/gradle-plugin/src/main/groovy/mozilla/telemetry/glean-gradle-plugin/GleanGradlePlugin.groovy @@ -552,7 +552,7 @@ except: void apply(Project project) { isOffline = project.gradle.startParameter.offline - project.ext.glean_version = "61.1.0" + project.ext.glean_version = "61.2.0" def parserVersion = gleanParserVersion(project) // Print the required glean_parser version to the console. This is diff --git a/pyproject.toml b/pyproject.toml index 8c782dc672..b4d5437111 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "glean-sdk" -version = "61.1.0" +version = "61.2.0" requires-python = ">=3.8" classifiers = [ "Intended Audience :: Developers",