From 352ca08211f43a7a5e10450bdece24693be2321c Mon Sep 17 00:00:00 2001 From: Travis Long Date: Fri, 23 Sep 2022 15:08:53 -0500 Subject: [PATCH] Adds Glean back in the iOS megazord to enable Glean-Rust for Nimbus This includes conditional compilation for this feature only on iOS, Android will still need to record things in Kotlin for the time being. --- .circleci/config.yml | 1 + Cargo.lock | 162 ++++++++++++- DEPENDENCIES.md | 166 +++++++++++-- components/external/glean | 2 +- .../logins/ios/Logins/LoginsStorage.swift | 4 +- components/nimbus/Cargo.toml | 4 +- components/nimbus/build.rs | 4 +- .../nimbus/ios/Nimbus/FeatureHolder.swift | 7 - .../nimbus/ios/Nimbus/GleanPlumbHelpers.swift | 2 +- components/nimbus/ios/Nimbus/Nimbus.swift | 94 ++------ components/nimbus/ios/Nimbus/NimbusApi.swift | 2 +- components/nimbus/metrics.yaml | 19 ++ components/nimbus/src/dbcache.rs | 18 +- components/nimbus/src/enrollment.rs | 101 ++++++-- components/nimbus/src/glean_metrics.rs | 10 + components/nimbus/src/lib.rs | 55 +++++ components/nimbus/src/nimbus.udl | 7 + components/nimbus/tests/test_telemetry.rs | 221 ++++++++++++++++++ megazords/full/DEPENDENCIES.md | 35 +-- .../full/android/dependency-licenses.xml | 12 - megazords/ios-rust/Cargo.toml | 4 + megazords/ios-rust/DEPENDENCIES.md | 127 ++++++++-- megazords/ios-rust/MozillaRustComponents.h | 1 + .../project.pbxproj | 39 +--- .../xcshareddata/swiftpm/Package.resolved | 16 -- .../LoginsTests.swift | 2 - .../NimbusTests.swift | 217 ----------------- megazords/ios-rust/build-xcframework.sh | 4 +- megazords/ios-rust/focus/Cargo.toml | 5 +- megazords/ios-rust/focus/DEPENDENCIES.md | 127 ++++++++-- .../ios-rust/focus/MozillaRustComponents.h | 1 + megazords/ios-rust/focus/src/lib.rs | 1 + megazords/ios-rust/src/lib.rs | 1 + 33 files changed, 978 insertions(+), 493 deletions(-) create mode 100644 components/nimbus/src/glean_metrics.rs create mode 100644 components/nimbus/tests/test_telemetry.rs delete mode 100644 megazords/ios-rust/MozillaTestServices/MozillaTestServices.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/.circleci/config.yml b/.circleci/config.yml index 3f8af3bf5a..d99f38365d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -120,6 +120,7 @@ commands: - run: sudo apt-get update - run: sudo apt-get install python tcl - run: sudo apt-get install python3-venv + - run: sudo apt-get install python3-pip - run: name: Install NSS build system dependencies command: sudo apt-get install ninja-build gyp zlib1g-dev diff --git a/Cargo.lock b/Cargo.lock index e3605cd827..cc93cb5c70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,6 +38,24 @@ dependencies = [ "memchr", ] +[[package]] +name = "android_log-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85965b6739a430150bdd138e2374a98af0c3ee0d030b3bb7fc3bddff58d0102e" + +[[package]] +name = "android_logger" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b74b7ddf197de32e415d197aa21c1c0cb36e01e4794fd801302280ac7847ee02" +dependencies = [ + "android_log-sys", + "env_logger 0.9.0", + "log", + "once_cell", +] + [[package]] name = "ansi_term" version = "0.11.0" @@ -456,16 +474,16 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.8" +version = "3.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190814073e85d238f31ff738fcb0bf6910cedeb73376c87cd69291028966fd83" +checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" dependencies = [ "atty", "bitflags", "clap_derive", "clap_lex", "indexmap", - "once_cell", + "lazy_static", "strsim 0.10.0", "termcolor", "textwrap 0.15.0", @@ -473,9 +491,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.2.7" +version = "3.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759bf187376e1afa7b85b959e6a664a3e7a95203415dba952ad19139e798f902" +checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" dependencies = [ "heck 0.4.0", "proc-macro-error", @@ -598,6 +616,15 @@ dependencies = [ "uniffi_macros", ] +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "criterion" version = "0.3.6" @@ -732,6 +759,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "dashmap" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" +dependencies = [ + "cfg-if 1.0.0", + "num_cpus", +] + [[package]] name = "dialoguer" version = "0.6.2" @@ -868,6 +905,18 @@ dependencies = [ "termcolor", ] +[[package]] +name = "env_logger" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +dependencies = [ + "atty", + "humantime 2.1.0", + "log", + "termcolor", +] + [[package]] name = "error-support" version = "0.1.0" @@ -1064,6 +1113,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" +[[package]] +name = "flate2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1269,6 +1328,24 @@ version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" +[[package]] +name = "glean" +version = "51.2.0" +dependencies = [ + "chrono", + "crossbeam-channel", + "glean-core", + "inherent", + "log", + "once_cell", + "serde", + "serde_json", + "thiserror", + "time 0.1.44", + "uuid", + "whatsys", +] + [[package]] name = "glean-build" version = "6.1.2" @@ -1276,6 +1353,32 @@ dependencies = [ "xshell-venv", ] +[[package]] +name = "glean-core" +version = "51.2.0" +dependencies = [ + "android_logger", + "bincode", + "chrono", + "crossbeam-channel", + "env_logger 0.9.0", + "flate2", + "log", + "once_cell", + "oslog", + "rkv", + "serde", + "serde_json", + "thiserror", + "time 0.1.44", + "uniffi", + "uniffi_build", + "uniffi_macros", + "uuid", + "whatsys", + "zeitstempel", +] + [[package]] name = "glob" version = "0.3.0" @@ -1505,6 +1608,17 @@ dependencies = [ "hashbrown 0.12.1", ] +[[package]] +name = "inherent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daa5135cb6aa90ee17b4f0a0fb2908059b0830f90fda333f12816f275b21820c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "instant" version = "0.1.12" @@ -1788,6 +1902,7 @@ name = "megazord_focus" version = "0.1.0" dependencies = [ "error-support", + "glean-core", "nimbus-sdk", "rc_log_ffi", "viaduct", @@ -1802,6 +1917,7 @@ dependencies = [ "crashtest", "error-support", "fxa-client", + "glean-core", "logins", "nimbus-sdk", "places", @@ -1985,6 +2101,7 @@ dependencies = [ "chrono", "clap 2.34.0", "env_logger 0.7.1", + "glean", "glean-build", "hex", "jexl-eval", @@ -2299,6 +2416,17 @@ version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" +[[package]] +name = "oslog" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8343ce955f18e7e68c0207dd0ea776ec453035685395ababd2ea651c569728b3" +dependencies = [ + "cc", + "dashmap", + "log", +] + [[package]] name = "output_vt100" version = "0.1.3" @@ -3686,7 +3814,7 @@ dependencies = [ "askama 0.11.1", "bincode", "camino", - "clap 3.2.8", + "clap 3.1.18", "fs-err", "goblin", "heck 0.4.0", @@ -3976,6 +4104,17 @@ dependencies = [ "nom 7.1.1", ] +[[package]] +name = "whatsys" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c24fff5aa1e0973964ba23a995e8b10fa2cdeae507e0cbbbd36f8403242a765d" +dependencies = [ + "cc", + "cfg-if 1.0.0", + "libc", +] + [[package]] name = "which" version = "4.2.5" @@ -4139,3 +4278,14 @@ checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" dependencies = [ "linked-hash-map", ] + +[[package]] +name = "zeitstempel" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeea3eb6a30ed24e374f59368d3917c5180a845fdd4ed6f1b2278811a9e826f8" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "once_cell", +] diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index 598b68857d..c97373771b 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -13,6 +13,7 @@ the details of which are reproduced below. * [MIT License: bytes](#mit-license-bytes) * [MIT License: cargo_metadata](#mit-license-cargo_metadata) * [MIT License: caseless](#mit-license-caseless) +* [MIT License: dashmap](#mit-license-dashmap) * [MIT License: generic-array](#mit-license-generic-array) * [MIT License: goblin](#mit-license-goblin) * [MIT License: h2](#mit-license-h2) @@ -21,10 +22,12 @@ the details of which are reproduced below. * [MIT License: libsqlite3-sys, rusqlite](#mit-license-libsqlite3-sys-rusqlite) * [MIT License: matches](#mit-license-matches) * [MIT License: mime_guess](#mit-license-mime_guess) +* [MIT License: miniz_oxide](#mit-license-miniz_oxide) * [MIT License: mio](#mit-license-mio) * [MIT License: nom](#mit-license-nom) * [MIT License: openssl-sys](#mit-license-openssl-sys) * [MIT License: ordered-float](#mit-license-ordered-float) +* [MIT License: oslog](#mit-license-oslog) * [MIT License: schannel](#mit-license-schannel) * [MIT License: scroll](#mit-license-scroll) * [MIT License: scroll_derive](#mit-license-scroll_derive) @@ -37,8 +40,9 @@ the details of which are reproduced below. * [MIT License: try-lock](#mit-license-try-lock) * [MIT License: want](#mit-license-want) * [MIT License: weedle2](#mit-license-weedle2) +* [MIT License: whatsys](#mit-license-whatsys) +* [MIT License: winapi-util](#mit-license-winapi-util) * [MIT License: winreg](#mit-license-winreg) -* [MIT License: xshell-venv](#mit-license-xshell-venv) * [CC0-1.0 License: base16](#cc0-10-license-base16) * [ISC License: ring](#isc-license-ring) * [BSD-2-Clause License: arrayref](#bsd-2-clause-license-arrayref) @@ -61,7 +65,8 @@ The following text applies to code linked from these dependencies: [uniffi_bindgen](https://github.com/mozilla/uniffi-rs), [uniffi_build](https://github.com/mozilla/uniffi-rs), [uniffi_macros](https://github.com/mozilla/uniffi-rs), -[uniffi_meta](https://github.com/mozilla/uniffi-rs) +[uniffi_meta](https://github.com/mozilla/uniffi-rs), +[zeitstempel](https://github.com/badboy/zeitstempel) ``` Mozilla Public License Version 2.0 @@ -443,7 +448,10 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice ## Apache License 2.0 The following text applies to code linked from these dependencies: +[adler](https://github.com/jonas-schievink/adler.git), [ahash](https://github.com/tkaitchuck/ahash), +[android_log-sys](https://github.com/nercury/android_log-sys-rs), +[android_logger](https://github.com/Nercury/android_logger-rs), [anyhow](https://github.com/dtolnay/anyhow), [askama](https://github.com/djc/askama), [askama_derive](https://github.com/djc/askama), @@ -464,13 +472,18 @@ The following text applies to code linked from these dependencies: [core-foundation-sys](https://github.com/servo/core-foundation-rs), [core-foundation](https://github.com/servo/core-foundation-rs), [cpufeatures](https://github.com/RustCrypto/utils), +[crc32fast](https://github.com/srijs/rust-crc32fast), +[crossbeam-channel](https://github.com/crossbeam-rs/crossbeam), +[crossbeam-utils](https://github.com/crossbeam-rs/crossbeam), [digest](https://github.com/RustCrypto/traits), [dogear](https://github.com/mozilla/dogear), [either](https://github.com/bluss/either), +[env_logger](https://github.com/env-logger-rs/env_logger/), [fallible-iterator](https://github.com/sfackler/rust-fallible-iterator), [fallible-streaming-iterator](https://github.com/sfackler/fallible-streaming-iterator), [fastrand](https://github.com/smol-rs/fastrand), [ffi-support](https://github.com/mozilla/ffi-support), +[flate2](https://github.com/rust-lang/flate2-rs), [fnv](https://github.com/servo/rust-fnv), [foreign-types-shared](https://github.com/sfackler/foreign-types), [foreign-types](https://github.com/sfackler/foreign-types), @@ -490,6 +503,7 @@ The following text applies to code linked from these dependencies: [http](https://github.com/hyperium/http), [httparse](https://github.com/seanmonstar/httparse), [httpdate](https://github.com/pyfisch/httpdate), +[humantime](https://github.com/tailhook/humantime), [hyper-tls](https://github.com/hyperium/hyper-tls), [id-arena](https://github.com/fitzgen/id-arena), [idna](https://github.com/servo/rust-url/), @@ -577,14 +591,12 @@ The following text applies to code linked from these dependencies: [winapi](https://github.com/retep998/winapi-rs), [windows-sys](https://github.com/microsoft/windows-rs), [windows_x86_64_gnu](https://github.com/microsoft/windows-rs), -[windows_x86_64_msvc](https://github.com/microsoft/windows-rs), -[xshell-macros](https://github.com/matklad/xshell), -[xshell](https://github.com/matklad/xshell) +[windows_x86_64_msvc](https://github.com/microsoft/windows-rs) ``` Apache License Version 2.0, January 2004 - http://www.apache.org/licenses/ + https://www.apache.org/licenses/LICENSE-2.0 TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION @@ -776,7 +788,7 @@ 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 + https://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, @@ -1004,6 +1016,36 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` +------------- +## MIT License: dashmap + +The following text applies to code linked from these dependencies: +[dashmap](https://github.com/xacrimon/dashmap) + +``` +MIT License + +Copyright (c) 2019 Acrimon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ``` ------------- ## MIT License: generic-array @@ -1253,6 +1295,36 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` +------------- +## MIT License: miniz_oxide + +The following text applies to code linked from these dependencies: +[miniz_oxide](https://github.com/Frommi/miniz_oxide/tree/master/miniz_oxide) + +``` +MIT License + +Copyright (c) 2017 Frommi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ``` ------------- ## MIT License: mio @@ -1378,6 +1450,36 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` +------------- +## MIT License: oslog + +The following text applies to code linked from these dependencies: +[oslog](https://github.com/steven-joruk/oslog) + +``` +MIT License + +Copyright (c) 2020 Steven Joruk + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ``` ------------- ## MIT License: schannel @@ -1741,13 +1843,15 @@ DEALINGS IN THE SOFTWARE. ``` ------------- -## MIT License: winreg +## MIT License: whatsys The following text applies to code linked from these dependencies: -[winreg](https://github.com/gentoo90/winreg-rs) +[whatsys](https://github.com/badboy/whatsys) ``` -Copyright (c) 2015 Igor Shaula +The MIT License (MIT) + +Copyright (c) 2021 Jan-Erik Rediger Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -1769,15 +1873,15 @@ THE SOFTWARE. ``` ------------- -## MIT License: xshell-venv +## MIT License: winapi-util The following text applies to code linked from these dependencies: -[xshell-venv](https://github.com/badboy/xshell-venv) +[winapi-util](https://github.com/BurntSushi/winapi-util) ``` The MIT License (MIT) -Copyright (c) 2022 Jan-Erik Rediger +Copyright (c) 2017 Andrew Gallant Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -1786,16 +1890,44 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +``` +------------- +## MIT License: winreg + +The following text applies to code linked from these dependencies: +[winreg](https://github.com/gentoo90/winreg-rs) + +``` +Copyright (c) 2015 Igor Shaula + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. ``` ------------- diff --git a/components/external/glean b/components/external/glean index ecc334c6b5..62c92d42ae 160000 --- a/components/external/glean +++ b/components/external/glean @@ -1 +1 @@ -Subproject commit ecc334c6b527e3501e5c34f7c2f4a51736f98d6d +Subproject commit 62c92d42ae78d46d82a30c6aa6d0cf6d0767f90d diff --git a/components/logins/ios/Logins/LoginsStorage.swift b/components/logins/ios/Logins/LoginsStorage.swift index 1e42813197..2b3f7d7d38 100644 --- a/components/logins/ios/Logins/LoginsStorage.swift +++ b/components/logins/ios/Logins/LoginsStorage.swift @@ -3,8 +3,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import Foundation -import Glean import UIKit +#if canImport(MozillaRustComponents) + import MozillaRustComponents +#endif typealias LoginsStoreError = LoginsStorageError diff --git a/components/nimbus/Cargo.toml b/components/nimbus/Cargo.toml index bbf162a6b7..2a4ca6439a 100644 --- a/components/nimbus/Cargo.toml +++ b/components/nimbus/Cargo.toml @@ -16,6 +16,7 @@ name = "nimbus" default=["rkv-safe-mode", "uniffi-bindings"] rkv-safe-mode = [] uniffi-bindings = ["uniffi", "uniffi_build"] +builtin-glean = ["glean", "glean-build"] [dependencies] anyhow = "1" @@ -35,10 +36,11 @@ once_cell = "1" uniffi = { version = "^0.20", optional = true } chrono = { version = "0.4", features = ["serde"]} unicode-segmentation = "1.8.0" +glean = { path = "../external/glean/glean-core/rlb", optional = true } [build-dependencies] uniffi_build = { version = "^0.20", features = [ "builtin-bindgen" ], optional = true } -glean-build = { path = "../external/glean/glean-core/build" } +glean-build = { path = "../external/glean/glean-core/build", optional = true } [dev-dependencies] viaduct-reqwest = { path = "../support/viaduct-reqwest" } diff --git a/components/nimbus/build.rs b/components/nimbus/build.rs index 2530ea5ef8..c76a7ca8b0 100644 --- a/components/nimbus/build.rs +++ b/components/nimbus/build.rs @@ -2,16 +2,18 @@ * 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/. */ +#[cfg(feature = "builtin-glean")] use glean_build::Builder; pub fn main() { #[cfg(feature = "uniffi-bindings")] uniffi_build::generate_scaffolding("./src/nimbus.udl").unwrap(); + #[cfg(feature = "builtin-glean")] Builder::default() .file("./metrics.yaml") .generate() - .unwrap(); + .expect("Error generating Glean Rust bindings"); println!("cargo:rerun-if-changed=./metrics.yaml"); } diff --git a/components/nimbus/ios/Nimbus/FeatureHolder.swift b/components/nimbus/ios/Nimbus/FeatureHolder.swift index 5416f1c2d1..f33edb5fa3 100644 --- a/components/nimbus/ios/Nimbus/FeatureHolder.swift +++ b/components/nimbus/ios/Nimbus/FeatureHolder.swift @@ -2,7 +2,6 @@ * 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/. */ import Foundation -import Glean public typealias GetSdk = () -> FeaturesInterface? @@ -46,12 +45,6 @@ public class FeatureHolder { var variables: Variables = NilVariables.instance if let sdk = getSdk() { variables = sdk.getVariables(featureId: featureId, sendExposureEvent: false) - } else { - GleanMetrics.NimbusHealth.sdkUnavailableForFeature.record( - GleanMetrics.NimbusHealth.SdkUnavailableForFeatureExtra( - featureId: featureId - ) - ) } let v = create(variables) cachedValue = v diff --git a/components/nimbus/ios/Nimbus/GleanPlumbHelpers.swift b/components/nimbus/ios/Nimbus/GleanPlumbHelpers.swift index 5fe6c53b4f..c39d5a3c60 100644 --- a/components/nimbus/ios/Nimbus/GleanPlumbHelpers.swift +++ b/components/nimbus/ios/Nimbus/GleanPlumbHelpers.swift @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import Foundation -import Glean +import MozillaRustComponents /** * Instances of this class are useful for implementing a messaging service based upon diff --git a/components/nimbus/ios/Nimbus/Nimbus.swift b/components/nimbus/ios/Nimbus/Nimbus.swift index dc65106cd8..8dccb367ff 100644 --- a/components/nimbus/ios/Nimbus/Nimbus.swift +++ b/components/nimbus/ios/Nimbus/Nimbus.swift @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import Foundation -import Glean +import MozillaRustComponents public class Nimbus: NimbusApi { private let nimbusClient: NimbusClientProtocol @@ -58,74 +58,15 @@ private extension Nimbus { extension Nimbus: FeaturesInterface { public func recordExposureEvent(featureId: String) { - // First we need a list of the active experiments that are enrolled. - let activeExperiments = getActiveExperiments() - - // Next, we search for any experiment that has a matching featureId. This depends on the - // fact that we can only be enrolled in a single experiment per feature, so there should - // only ever be zero or one experiments for a given featureId. - if let experiment = activeExperiments.first(where: { $0.featureIds.contains(featureId) }) { - // Finally, if we do have an experiment for the given featureId, we will record the - // exposure event in Glean. This is to protect against accidentally recording an event - // for an experiment without an active enrollment. - GleanMetrics.NimbusEvents.exposure.record(GleanMetrics.NimbusEvents.ExposureExtra( - branch: experiment.branchSlug, - enrollmentId: experiment.enrollmentId, - experiment: experiment.slug - )) - } + catchAll { try nimbusClient.recordExposureEvent(featureId: featureId) } } - internal func postEnrollmentCalculation(_ events: [EnrollmentChangeEvent]) { - // We need to update the experiment enrollment annotations in Glean - // regardless of whether we recieved any events. Calling the - // `setExperimentActive` function multiple times with the same - // experiment id is safe so nothing bad should happen in case we do. - let experiments = getActiveExperiments() - recordExperimentTelemetry(experiments) - - // Record enrollment change events, if any - recordExperimentEvents(events) - + internal func postEnrollmentCalculation() { // Inform any listeners that we're done here. + let experiments = getActiveExperiments() notifyOnExperimentsApplied(experiments) } - internal func recordExperimentTelemetry(_ experiments: [EnrolledExperiment]) { - for experiment in experiments { - Glean.shared.setExperimentActive( - experiment.slug, - branch: experiment.branchSlug, - extra: ["enrollmentId": experiment.enrollmentId] - ) - } - } - - internal func recordExperimentEvents(_ events: [EnrollmentChangeEvent]) { - for event in events { - switch event.change { - case .enrollment: - GleanMetrics.NimbusEvents.enrollment.record(GleanMetrics.NimbusEvents.EnrollmentExtra( - branch: event.branchSlug, - enrollmentId: event.enrollmentId, - experiment: event.experimentSlug - )) - case .disqualification: - GleanMetrics.NimbusEvents.disqualification.record(GleanMetrics.NimbusEvents.DisqualificationExtra( - branch: event.branchSlug, - enrollmentId: event.enrollmentId, - experiment: event.experimentSlug - )) - case .unenrollment: - GleanMetrics.NimbusEvents.unenrollment.record(GleanMetrics.NimbusEvents.UnenrollmentExtra( - branch: event.branchSlug, - enrollmentId: event.enrollmentId, - experiment: event.experimentSlug - )) - } - } - } - internal func getFeatureConfigVariablesJson(featureId: String) -> [String: Any]? { do { if let string = try nimbusClient.getFeatureConfigVariables(featureId: featureId), @@ -135,13 +76,6 @@ extension Nimbus: FeaturesInterface { } else { return nil } - } catch NimbusError.DatabaseNotReady { - GleanMetrics.NimbusHealth.cacheNotReadyForFeature.record( - GleanMetrics.NimbusHealth.CacheNotReadyForFeatureExtra( - featureId: featureId - ) - ) - return nil } catch { errorReporter(error) return nil @@ -176,8 +110,8 @@ private extension Nimbus { */ internal extension Nimbus { func setGlobalUserParticipationOnThisThread(_ value: Bool) throws { - let changes = try nimbusClient.setGlobalUserParticipation(optIn: value) - postEnrollmentCalculation(changes) + _ = try nimbusClient.setGlobalUserParticipation(optIn: value) + postEnrollmentCalculation() } func initializeOnThisThread() throws { @@ -190,8 +124,8 @@ internal extension Nimbus { } func applyPendingExperimentsOnThisThread() throws { - let changes = try nimbusClient.applyPendingExperiments() - postEnrollmentCalculation(changes) + _ = try nimbusClient.applyPendingExperiments() + postEnrollmentCalculation() } func setExperimentsLocallyOnThisThread(_ experimentsJson: String) throws { @@ -199,18 +133,18 @@ internal extension Nimbus { } func optOutOnThisThread(_ experimentId: String) throws { - let changes = try nimbusClient.optOut(experimentSlug: experimentId) - postEnrollmentCalculation(changes) + _ = try nimbusClient.optOut(experimentSlug: experimentId) + postEnrollmentCalculation() } func optInOnThisThread(_ experimentId: String, branch: String) throws { - let changes = try nimbusClient.optInWithBranch(experimentSlug: experimentId, branch: branch) - postEnrollmentCalculation(changes) + _ = try nimbusClient.optInWithBranch(experimentSlug: experimentId, branch: branch) + postEnrollmentCalculation() } func resetTelemetryIdentifiersOnThisThread(_ identifiers: AvailableRandomizationUnits) throws { - let changes = try nimbusClient.resetTelemetryIdentifiers(newRandomizationUnits: identifiers) - postEnrollmentCalculation(changes) + _ = try nimbusClient.resetTelemetryIdentifiers(newRandomizationUnits: identifiers) + postEnrollmentCalculation() } } diff --git a/components/nimbus/ios/Nimbus/NimbusApi.swift b/components/nimbus/ios/Nimbus/NimbusApi.swift index c067d7082c..cc8090558f 100644 --- a/components/nimbus/ios/Nimbus/NimbusApi.swift +++ b/components/nimbus/ios/Nimbus/NimbusApi.swift @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import Foundation -import Glean +import MozillaRustComponents /// This is the main experiments API, which is exposed through the global [Nimbus] object. /// diff --git a/components/nimbus/metrics.yaml b/components/nimbus/metrics.yaml index e211b7a2a9..e62caf23d3 100644 --- a/components/nimbus/metrics.yaml +++ b/components/nimbus/metrics.yaml @@ -80,6 +80,9 @@ nimbus_events: enrollment_id: type: string description: A unique identifier generated at enrollment time + reason: + type: string + description: The reason for the disqualification bugs: - https://jira.mozilla.com/browse/SDK-126 data_reviews: @@ -153,3 +156,19 @@ nimbus_health: notification_emails: - tlong@mozilla.com expires: never + network_request: + type: timing_distribution + time_unit: millisecond + description: > + The time in milliseconds that the Nimbus SDK takes to fetch experiments + from remote-settings + bugs: + - https://mozilla-hub.atlassian.net/browse/EXP-2063 + data_reviews: + - https://github.com/mozilla-mobile/android-components/pull/9168#issuecomment-743461975 + data_sensitivity: + - technical + notification_emails: + - tlong@mozilla.com + - nimbus-team@mozilla.com + expires: never diff --git a/components/nimbus/src/dbcache.rs b/components/nimbus/src/dbcache.rs index e3d593dc18..acb49c1e30 100644 --- a/components/nimbus/src/dbcache.rs +++ b/components/nimbus/src/dbcache.rs @@ -10,6 +10,9 @@ use crate::{enrollment::ExperimentEnrollment, Experiment}; use std::collections::HashMap; use std::sync::RwLock; +#[cfg(feature = "builtin-glean")] +use crate::glean_metrics::nimbus_health; + // This module manages an in-memory cache of the database, so that some // functions exposed by nimbus can return results without blocking on any // IO. Consumers are expected to call our public `update()` function whenever @@ -124,14 +127,25 @@ impl DatabaseCache { // This gives access to the feature JSON. We pass it as a string because uniffi doesn't // support JSON yet. pub fn get_feature_config_variables(&self, feature_id: &str) -> Result> { - self.get_data(|data| { + match self.get_data(|data| { if let Some(enrolled_feature) = data.features_by_feature_id.get(feature_id) { let string = serde_json::to_string(&enrolled_feature.feature.value).unwrap(); Some(string) } else { None } - }) + }) { + Ok(res) => Ok(res), + Err(e) => { + #[cfg(feature = "builtin-glean")] + nimbus_health::cache_not_ready_for_feature.record( + nimbus_health::CacheNotReadyForFeatureExtra { + feature_id: Some(feature_id.to_string()), + }, + ); + Err(e) + } + } } pub fn get_active_experiments(&self) -> Result> { diff --git a/components/nimbus/src/enrollment.rs b/components/nimbus/src/enrollment.rs index b236290c67..7e039386e1 100644 --- a/components/nimbus/src/enrollment.rs +++ b/components/nimbus/src/enrollment.rs @@ -8,6 +8,9 @@ use crate::persistence::{Database, StoreId, Writer}; use crate::{evaluator::evaluate_enrollment, persistence::Readable}; use crate::{AvailableRandomizationUnits, EnrolledExperiment, Experiment, FeatureConfig}; +#[cfg(feature = "builtin-glean")] +use crate::glean_metrics::nimbus_events; + use ::uuid::Uuid; use serde_derive::*; use std::{ @@ -373,40 +376,88 @@ impl ExperimentEnrollment { enrollment_id, branch, .. - } => EnrollmentChangeEvent::new( - &self.slug, - enrollment_id, - branch, - None, - EnrollmentChangeEventType::Enrollment, - ), + } => { + #[cfg(feature = "builtin-glean")] + nimbus_events::enrollment.record(nimbus_events::EnrollmentExtra { + branch: Some(branch.to_string()), + enrollment_id: Some(enrollment_id.to_string()), + experiment: Some(self.slug.to_string()), + }); + + let mut extra = HashMap::new(); + extra.insert("enrollment_id".to_string(), enrollment_id.to_string()); + + #[cfg(feature = "builtin-glean")] + glean::set_experiment_active( + enrollment_id.to_string(), + branch.to_string(), + Some(extra), + ); + + EnrollmentChangeEvent::new( + &self.slug, + enrollment_id, + branch, + None, + EnrollmentChangeEventType::Enrollment, + ) + } EnrollmentStatus::WasEnrolled { enrollment_id, branch, .. - } => EnrollmentChangeEvent::new( - &self.slug, - enrollment_id, - branch, - None, - EnrollmentChangeEventType::Unenrollment, - ), + } => { + #[cfg(feature = "builtin-glean")] + nimbus_events::unenrollment.record(nimbus_events::UnenrollmentExtra { + branch: Some(branch.to_string()), + enrollment_id: Some(enrollment_id.to_string()), + experiment: Some(self.slug.to_string()), + }); + + #[cfg(feature = "builtin-glean")] + glean::set_experiment_inactive(enrollment_id.to_string()); + + EnrollmentChangeEvent::new( + &self.slug, + enrollment_id, + branch, + None, + EnrollmentChangeEventType::Unenrollment, + ) + } EnrollmentStatus::Disqualified { enrollment_id, branch, reason, .. - } => EnrollmentChangeEvent::new( - &self.slug, - enrollment_id, - branch, - match reason { - DisqualifiedReason::NotTargeted => Some("targeting"), - DisqualifiedReason::OptOut => Some("optout"), - DisqualifiedReason::Error => Some("error"), - }, - EnrollmentChangeEventType::Disqualification, - ), + } => { + #[cfg(feature = "builtin-glean")] + nimbus_events::disqualification.record(nimbus_events::DisqualificationExtra { + branch: Some(branch.to_string()), + enrollment_id: Some(enrollment_id.to_string()), + experiment: Some(self.slug.to_string()), + reason: match reason { + DisqualifiedReason::NotTargeted => Some("targeting".to_string()), + DisqualifiedReason::OptOut => Some("optout".to_string()), + DisqualifiedReason::Error => Some("error".to_string()), + }, + }); + + #[cfg(feature = "builtin-glean")] + glean::set_experiment_inactive(enrollment_id.to_string()); + + EnrollmentChangeEvent::new( + &self.slug, + enrollment_id, + branch, + match reason { + DisqualifiedReason::NotTargeted => Some("targeting"), + DisqualifiedReason::OptOut => Some("optout"), + DisqualifiedReason::Error => Some("error"), + }, + EnrollmentChangeEventType::Disqualification, + ) + } EnrollmentStatus::NotEnrolled { .. } | EnrollmentStatus::Error { .. } => unreachable!(), } } diff --git a/components/nimbus/src/glean_metrics.rs b/components/nimbus/src/glean_metrics.rs new file mode 100644 index 0000000000..487fae5ac6 --- /dev/null +++ b/components/nimbus/src/glean_metrics.rs @@ -0,0 +1,10 @@ +/* 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/. */ +#[cfg(feature = "builtin-glean")] +use std::env; + +// This includes the generated Glean Rust bindings, which get exposed +// via the `mod glean_metrics` include in lib.rs +#[cfg(feature = "builtin-glean")] +include!(concat!(env!("OUT_DIR"), "/glean_metrics.rs")); diff --git a/components/nimbus/src/lib.rs b/components/nimbus/src/lib.rs index 54db7aa596..cdd6121e3d 100644 --- a/components/nimbus/src/lib.rs +++ b/components/nimbus/src/lib.rs @@ -34,6 +34,12 @@ use evaluator::is_experiment_available; // Exposed for Example only pub use evaluator::TargetingAttributes; +// Expose generated Glean Rust metrics +#[cfg(feature = "builtin-glean")] +pub mod glean_metrics; +#[cfg(feature = "builtin-glean")] +use crate::glean_metrics::{nimbus_events, nimbus_health}; + // We only use this in a test, and with --no-default-features, we don't use it // at all #[allow(unused_imports)] @@ -68,6 +74,9 @@ struct InternalMutableState { available_randomization_units: AvailableRandomizationUnits, // Application level targeting attributes targeting_attributes: TargetingAttributes, + // Whether or not the SDK has completed initialization + #[cfg(feature = "builtin-glean")] + is_initialized: bool, } /// Nimbus is the main struct representing the experiments state @@ -98,6 +107,8 @@ impl NimbusClient { let mutable_state = Mutex::new(InternalMutableState { available_randomization_units, targeting_attributes: app_context.clone().into(), + #[cfg(feature = "builtin-glean")] + is_initialized: false, }); Ok(Self { settings_client, @@ -127,6 +138,11 @@ impl NimbusClient { self.begin_initialize(db, &mut writer)?; self.end_initialize(db, writer)?; + if cfg!(feature = "builtin-glean") { + let mut state = self.mutable_state.lock().unwrap(); + state.is_initialized = true; + } + Ok(()) } @@ -150,6 +166,16 @@ impl NimbusClient { } pub fn get_feature_config_variables(&self, feature_id: String) -> Result> { + #[cfg(feature = "builtin-glean")] + let state = self.mutable_state.lock().unwrap(); + #[cfg(feature = "builtin-glean")] + if !state.is_initialized { + nimbus_health::sdk_unavailable_for_feature.record( + nimbus_health::SdkUnavailableForFeatureExtra { + feature_id: Some(feature_id.clone()), + }, + ); + } self.database_cache .get_feature_config_variables(&feature_id) } @@ -240,7 +266,15 @@ impl NimbusClient { pub fn fetch_experiments(&self) -> Result<()> { log::info!("fetching experiments"); let settings_client = self.settings_client.lock().unwrap(); + + #[cfg(feature = "builtin-glean")] + let timer_id = nimbus_health::network_request.start(); + let new_experiments = settings_client.fetch_experiments()?; + + #[cfg(feature = "builtin-glean")] + nimbus_health::network_request.stop_and_accumulate(timer_id); + let db = self.db()?; let mut writer = db.write()?; write_pending_experiments(db, &mut writer, new_experiments)?; @@ -507,6 +541,27 @@ impl NimbusClient { let helper = NimbusStringHelper::new(context.as_object().unwrap().to_owned()); Ok(Arc::new(helper)) } + + #[allow(unused_variables)] + pub fn record_exposure_event(&self, feature_id: String) -> Result<()> { + // Next, we search for any experiment that has a matching featureId. This depends on the + // fact that we can only be enrolled in a single experiment per feature, so there should + // only ever be zero or one experiments for a given featureId. + #[cfg(feature = "builtin-glean")] + if let Some(exp) = self + .get_active_experiments()? + .iter() + .find(|exp| exp.feature_ids.contains(&feature_id)) + { + nimbus_events::exposure.record(nimbus_events::ExposureExtra { + branch: Some(exp.branch_slug.clone()), + enrollment_id: Some(exp.enrollment_id.clone()), + experiment: Some(exp.slug.clone()), + }); + } + + Ok(()) + } } #[derive(Debug, Clone)] diff --git a/components/nimbus/src/nimbus.udl b/components/nimbus/src/nimbus.udl index a391442092..36bf1475f1 100644 --- a/components/nimbus/src/nimbus.udl +++ b/components/nimbus/src/nimbus.udl @@ -197,6 +197,13 @@ interface NimbusClient { // It's first use is in GleanPlumb message helper, to add extra parameters to URLs. [Throws=NimbusError] NimbusStringHelper create_string_helper(optional JsonObject? additional_context = null); + + // If an active experiment exists with the provided feature_id, then an exposure event will be + // recorded. If there is no active experiment, then nothing happens. This makes this function + // safe to call at the point of exposure for the feature regardless of whether an experiment is + // active or not. + [Throws=NimbusError] + void record_exposure_event(string feature_id); }; [Custom] diff --git a/components/nimbus/tests/test_telemetry.rs b/components/nimbus/tests/test_telemetry.rs new file mode 100644 index 0000000000..df14a4caf9 --- /dev/null +++ b/components/nimbus/tests/test_telemetry.rs @@ -0,0 +1,221 @@ +/* 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/. */ + +mod common; +#[cfg(all(feature = "rkv-safe-mode", feature = "builtin-glean"))] +#[cfg(test)] +mod test { + + use super::common::new_test_client_with_db; + + #[cfg(feature = "builtin-glean")] + use glean::{test_reset_glean, ClientInfoMetrics, Configuration, RecordedEvent}; + #[cfg(feature = "builtin-glean")] + use nimbus::glean_metrics; + + use nimbus::error::Result; + use serde_json::json; + + #[test] + fn test_enrollment_telemetry() -> Result<()> { + // First, a little setup with a matching and non-matching experiment for testing + // the enrollment telemetry + let temp_dir = tempfile::tempdir()?; + let client = new_test_client_with_db(&temp_dir)?; + client.initialize()?; + let experiment_json = serde_json::to_string(&json!({ + "data": [{ + "schemaVersion": "1.0.0", + "slug": "secure-gold", + "endDate": null, + "featureIds": ["some-feature"], + "branches": [ + { + "slug": "control", + "ratio": 1 + }, + { + "slug": "treatment", + "ratio": 1 + } + ], + "channel": "nightly", + "probeSets": [], + "startDate": null, + "appName": "fenix", + "appId": "org.mozilla.fenix", + "bucketConfig": { + "count": 10000, + "start": 0, + "total": 10000, + "namespace": "secure-gold", + "randomizationUnit": "nimbus_id" + }, + "targeting": "false", + "userFacingName": "Diagnostic test experiment", + "referenceBranch": "control", + "isEnrollmentPaused": false, + "proposedEnrollment": 7, + "userFacingDescription": "This is a test experiment for diagnostic purposes.", + "id": "secure-copper", + "last_modified": 1_602_197_324_372i64, + }, + { + "schemaVersion": "1.0.0", + "slug": "secure-silver", + "endDate": null, + "featureIds": ["some-feature"], + "branches": [ + { + "slug": "control", + "ratio": 1 + }, + { + "slug": "treatment", + "ratio": 1 + } + ], + "channel": "nightly", + "probeSets": [], + "startDate": null, + "appName": "fenix", + "appId": "org.mozilla.fenix", + "bucketConfig": { + "count": 10000, + "start": 0, + "total": 10000, + "namespace": "secure-silver", + "randomizationUnit": "nimbus_id" + }, + "userFacingName": "Diagnostic test experiment", + "referenceBranch": "control", + "isEnrollmentPaused": false, + "proposedEnrollment": 7, + "userFacingDescription": "This is a test experiment for diagnostic purposes.", + "id": "secure-copper", + "last_modified": 1_602_197_324_372i64, + } + ] + }))?; + + let tmp_glean_dir = temp_dir.path().join("glean_data"); + test_reset_glean( + Configuration { + data_path: tmp_glean_dir, + application_id: "org.mozilla.fenix".into(), + upload_enabled: true, + max_events: None, + delay_ping_lifetime_io: false, + server_endpoint: Some("invalid-test-host".into()), + uploader: None, + use_core_mps: false, + }, + ClientInfoMetrics::unknown(), + false, + ); + + client.set_experiments_locally(experiment_json)?; + let change_events = client.apply_pending_experiments()?; + + // Check for Glean enrollment event + let events: Option> = + glean_metrics::nimbus_events::enrollment.test_get_value("events"); + assert!(events.is_some()); + assert_eq!(1, events.clone().unwrap().len()); + let event_extra = events.unwrap()[0].extra.to_owned().unwrap(); + assert_eq!("secure-silver", event_extra["experiment"]); + assert_eq!(change_events[0].branch_slug, event_extra["branch"]); + assert_eq!(change_events[0].enrollment_id, event_extra["enrollment_id"]); + + let experiment_json = serde_json::to_string(&json!({ + "data": [{ + "schemaVersion": "1.0.0", + "slug": "secure-gold", + "endDate": null, + "featureIds": ["some-feature"], + "branches": [ + { + "slug": "control", + "ratio": 1 + }, + { + "slug": "treatment", + "ratio": 1 + } + ], + "channel": "nightly", + "probeSets": [], + "startDate": null, + "appName": "fenix", + "appId": "org.mozilla.fenix", + "bucketConfig": { + "count": 10000, + "start": 0, + "total": 10000, + "namespace": "secure-gold", + "randomizationUnit": "nimbus_id" + }, + "targeting": "false", + "userFacingName": "Diagnostic test experiment", + "referenceBranch": "control", + "isEnrollmentPaused": false, + "proposedEnrollment": 7, + "userFacingDescription": "This is a test experiment for diagnostic purposes.", + "id": "secure-copper", + "last_modified": 1_602_197_324_372i64, + }] + }))?; + + // Drop the NimbusClient to terminate the underlying database connection and restart + drop(client); + let client = new_test_client_with_db(&temp_dir)?; + client.initialize()?; + client.set_experiments_locally(experiment_json)?; + let change_events = client.apply_pending_experiments()?; + + // Check for Glean unenrollment event with the correct `reason` + let events: Option> = + glean_metrics::nimbus_events::unenrollment.test_get_value("events"); + assert!(events.is_some()); + assert_eq!(1, events.clone().unwrap().len()); + let event_extra = events.unwrap()[0].extra.to_owned().unwrap(); + assert_eq!("secure-silver", event_extra["experiment"]); + assert_eq!(change_events[0].branch_slug, event_extra["branch"]); + assert_eq!(change_events[0].enrollment_id, event_extra["enrollment_id"]); + + // Now let's opt into the secure-gold experiment and check for the enrollment event + let change_events = + client.opt_in_with_branch("secure-gold".to_string(), "control".to_string())?; + + // Check for Glean enrollment event + let events: Option> = + glean_metrics::nimbus_events::enrollment.test_get_value("events"); + assert!(events.is_some()); + // This is the second enrollment. Because we didn't reset Glean and didn't send an + // events ping yet, the enrollment from above should still be there. + assert_eq!(2, events.clone().unwrap().len()); + let event_extra = events.unwrap()[1].extra.to_owned().unwrap(); + assert_eq!("secure-gold", event_extra["experiment"]); + assert_eq!(change_events[0].branch_slug, event_extra["branch"]); + assert_eq!(change_events[0].enrollment_id, event_extra["enrollment_id"]); + + // Next we will opt out of the secure-gold experiment and check for unenrollment telemetry + let change_events = client.opt_out("secure-gold".to_string())?; + + // Check for Glean disqualification event with the correct `reason` of opt-out + let events: Option> = + glean_metrics::nimbus_events::disqualification.test_get_value("events"); + assert!(events.is_some()); + assert_eq!(1, events.clone().unwrap().len()); + let event_extra = events.unwrap()[0].extra.to_owned().unwrap(); + assert_eq!("secure-gold", event_extra["experiment"]); + assert_eq!(change_events[0].branch_slug, event_extra["branch"]); + assert_eq!(change_events[0].enrollment_id, event_extra["enrollment_id"]); + assert_eq!( + *change_events[0].reason.as_ref().unwrap(), + event_extra["reason"] + ); + Ok(()) + } +} diff --git a/megazords/full/DEPENDENCIES.md b/megazords/full/DEPENDENCIES.md index 04d4d2eba2..589840d6f3 100644 --- a/megazords/full/DEPENDENCIES.md +++ b/megazords/full/DEPENDENCIES.md @@ -24,7 +24,6 @@ the details of which are reproduced below. * [MIT License: strsim](#mit-license-strsim) * [MIT License: textwrap](#mit-license-textwrap) * [MIT License: weedle2](#mit-license-weedle2) -* [MIT License: xshell-venv](#mit-license-xshell-venv) * [CC0-1.0 License: base16](#cc0-10-license-base16) * [ISC License: ring](#isc-license-ring) * [BSD-2-Clause License: arrayref](#bsd-2-clause-license-arrayref) @@ -532,9 +531,7 @@ The following text applies to code linked from these dependencies: [winapi](https://github.com/retep998/winapi-rs), [windows-sys](https://github.com/microsoft/windows-rs), [windows_x86_64_gnu](https://github.com/microsoft/windows-rs), -[windows_x86_64_msvc](https://github.com/microsoft/windows-rs), -[xshell-macros](https://github.com/matklad/xshell), -[xshell](https://github.com/matklad/xshell) +[windows_x86_64_msvc](https://github.com/microsoft/windows-rs) ``` Apache License @@ -1291,36 +1288,6 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -``` -------------- -## MIT License: xshell-venv - -The following text applies to code linked from these dependencies: -[xshell-venv](https://github.com/badboy/xshell-venv) - -``` -The MIT License (MIT) - -Copyright (c) 2022 Jan-Erik Rediger - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ``` ------------- ## CC0-1.0 License: base16 diff --git a/megazords/full/android/dependency-licenses.xml b/megazords/full/android/dependency-licenses.xml index 793bf76a42..b094c8510f 100644 --- a/megazords/full/android/dependency-licenses.xml +++ b/megazords/full/android/dependency-licenses.xml @@ -484,14 +484,6 @@ the details of which are reproduced below. Apache License 2.0: windows_x86_64_msvc https://github.com/microsoft/windows-rs/blob/master/license-mit - - Apache License 2.0: xshell - https://github.com/matklad/xshell/blob/master/LICENSE-APACHE - - - Apache License 2.0: xshell-macros - https://github.com/matklad/xshell/blob/master/LICENSE-APACHE - MIT License: aho-corasick https://github.com/BurntSushi/aho-corasick/blob/master/LICENSE-MIT @@ -580,10 +572,6 @@ the details of which are reproduced below. MIT License: weedle2 https://github.com/mozilla/uniffi-rs/blob/main/weedle2/LICENSE.md - - MIT License: xshell-venv - https://github.com/badboy/xshell-venv/blob/main/LICENSE - CC0-1.0 License: base16 https://github.com/thomcc/rust-base16/blob/master/LICENSE-CC0 diff --git a/megazords/ios-rust/Cargo.toml b/megazords/ios-rust/Cargo.toml index cb01efaf90..0c9b8ee8fa 100644 --- a/megazords/ios-rust/Cargo.toml +++ b/megazords/ios-rust/Cargo.toml @@ -8,6 +8,9 @@ license = "MPL-2.0" [lib] crate-type = ["staticlib"] +[features] +builtin-glean = ["nimbus-sdk/builtin-glean"] + [dependencies] rc_log_ffi = { path = "../../components/rc_log" } viaduct = { path = "../../components/viaduct" } @@ -20,5 +23,6 @@ autofill = { path = "../../components/autofill" } push = { path = "../../components/push" } tabs = { path = "../../components/tabs", features = ["full-sync"] } places = {path = "../../components/places" } +glean-core = { path = "../../components/external/glean/glean-core" } sync15 = {path = "../../components/sync15"} error-support = { path = "../../components/support/error" } diff --git a/megazords/ios-rust/DEPENDENCIES.md b/megazords/ios-rust/DEPENDENCIES.md index f4f035b7f6..041013f930 100644 --- a/megazords/ios-rust/DEPENDENCIES.md +++ b/megazords/ios-rust/DEPENDENCIES.md @@ -13,6 +13,7 @@ the details of which are reproduced below. * [MIT License: bytes](#mit-license-bytes) * [MIT License: cargo_metadata](#mit-license-cargo_metadata) * [MIT License: caseless](#mit-license-caseless) +* [MIT License: dashmap](#mit-license-dashmap) * [MIT License: generic-array](#mit-license-generic-array) * [MIT License: goblin](#mit-license-goblin) * [MIT License: h2](#mit-license-h2) @@ -21,9 +22,11 @@ the details of which are reproduced below. * [MIT License: libsqlite3-sys, rusqlite](#mit-license-libsqlite3-sys-rusqlite) * [MIT License: matches](#mit-license-matches) * [MIT License: mime_guess](#mit-license-mime_guess) +* [MIT License: miniz_oxide](#mit-license-miniz_oxide) * [MIT License: mio](#mit-license-mio) * [MIT License: nom](#mit-license-nom) * [MIT License: ordered-float](#mit-license-ordered-float) +* [MIT License: oslog](#mit-license-oslog) * [MIT License: scroll](#mit-license-scroll) * [MIT License: scroll_derive](#mit-license-scroll_derive) * [MIT License: slab](#mit-license-slab) @@ -35,7 +38,7 @@ the details of which are reproduced below. * [MIT License: try-lock](#mit-license-try-lock) * [MIT License: want](#mit-license-want) * [MIT License: weedle2](#mit-license-weedle2) -* [MIT License: xshell-venv](#mit-license-xshell-venv) +* [MIT License: whatsys](#mit-license-whatsys) * [CC0-1.0 License: base16](#cc0-10-license-base16) * [ISC License: ring](#isc-license-ring) * [BSD-2-Clause License: arrayref](#bsd-2-clause-license-arrayref) @@ -56,7 +59,8 @@ The following text applies to code linked from these dependencies: [uniffi_bindgen](https://github.com/mozilla/uniffi-rs), [uniffi_build](https://github.com/mozilla/uniffi-rs), [uniffi_macros](https://github.com/mozilla/uniffi-rs), -[uniffi_meta](https://github.com/mozilla/uniffi-rs) +[uniffi_meta](https://github.com/mozilla/uniffi-rs), +[zeitstempel](https://github.com/badboy/zeitstempel) ``` Mozilla Public License Version 2.0 @@ -438,6 +442,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice ## Apache License 2.0 The following text applies to code linked from these dependencies: +[adler](https://github.com/jonas-schievink/adler.git), [ahash](https://github.com/tkaitchuck/ahash), [anyhow](https://github.com/dtolnay/anyhow), [askama](https://github.com/djc/askama), @@ -459,13 +464,18 @@ The following text applies to code linked from these dependencies: [core-foundation-sys](https://github.com/servo/core-foundation-rs), [core-foundation](https://github.com/servo/core-foundation-rs), [cpufeatures](https://github.com/RustCrypto/utils), +[crc32fast](https://github.com/srijs/rust-crc32fast), +[crossbeam-channel](https://github.com/crossbeam-rs/crossbeam), +[crossbeam-utils](https://github.com/crossbeam-rs/crossbeam), [digest](https://github.com/RustCrypto/traits), [dogear](https://github.com/mozilla/dogear), [either](https://github.com/bluss/either), +[env_logger](https://github.com/env-logger-rs/env_logger/), [fallible-iterator](https://github.com/sfackler/rust-fallible-iterator), [fallible-streaming-iterator](https://github.com/sfackler/fallible-streaming-iterator), [fastrand](https://github.com/smol-rs/fastrand), [ffi-support](https://github.com/mozilla/ffi-support), +[flate2](https://github.com/rust-lang/flate2-rs), [fnv](https://github.com/servo/rust-fnv), [form_urlencoded](https://github.com/servo/rust-url), [fs-err](https://github.com/andrewhickman/fs-err), @@ -483,6 +493,7 @@ The following text applies to code linked from these dependencies: [http](https://github.com/hyperium/http), [httparse](https://github.com/seanmonstar/httparse), [httpdate](https://github.com/pyfisch/httpdate), +[humantime](https://github.com/tailhook/humantime), [hyper-tls](https://github.com/hyperium/hyper-tls), [id-arena](https://github.com/fitzgen/id-arena), [idna](https://github.com/servo/rust-url/), @@ -560,14 +571,12 @@ The following text applies to code linked from these dependencies: [url](https://github.com/servo/rust-url), [uuid](https://github.com/uuid-rs/uuid), [vcpkg](https://github.com/mcgoo/vcpkg-rs), -[version_check](https://github.com/SergioBenitez/version_check), -[xshell-macros](https://github.com/matklad/xshell), -[xshell](https://github.com/matklad/xshell) +[version_check](https://github.com/SergioBenitez/version_check) ``` Apache License Version 2.0, January 2004 - http://www.apache.org/licenses/ + https://www.apache.org/licenses/LICENSE-2.0 TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION @@ -759,7 +768,7 @@ 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 + https://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, @@ -987,6 +996,36 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` +------------- +## MIT License: dashmap + +The following text applies to code linked from these dependencies: +[dashmap](https://github.com/xacrimon/dashmap) + +``` +MIT License + +Copyright (c) 2019 Acrimon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ``` ------------- ## MIT License: generic-array @@ -1236,6 +1275,36 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` +------------- +## MIT License: miniz_oxide + +The following text applies to code linked from these dependencies: +[miniz_oxide](https://github.com/Frommi/miniz_oxide/tree/master/miniz_oxide) + +``` +MIT License + +Copyright (c) 2017 Frommi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ``` ------------- ## MIT License: mio @@ -1327,6 +1396,36 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` +------------- +## MIT License: oslog + +The following text applies to code linked from these dependencies: +[oslog](https://github.com/steven-joruk/oslog) + +``` +MIT License + +Copyright (c) 2020 Steven Joruk + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ``` ------------- ## MIT License: scroll @@ -1674,15 +1773,15 @@ DEALINGS IN THE SOFTWARE. ``` ------------- -## MIT License: xshell-venv +## MIT License: whatsys The following text applies to code linked from these dependencies: -[xshell-venv](https://github.com/badboy/xshell-venv) +[whatsys](https://github.com/badboy/whatsys) ``` The MIT License (MIT) -Copyright (c) 2022 Jan-Erik Rediger +Copyright (c) 2021 Jan-Erik Rediger Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -1691,16 +1790,16 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. ``` ------------- diff --git a/megazords/ios-rust/MozillaRustComponents.h b/megazords/ios-rust/MozillaRustComponents.h index 786874ced9..dd41616b8d 100644 --- a/megazords/ios-rust/MozillaRustComponents.h +++ b/megazords/ios-rust/MozillaRustComponents.h @@ -10,6 +10,7 @@ #import "autofillFFI.h" #import "crashtestFFI.h" #import "fxa_clientFFI.h" +#import "gleanFFI.h" #import "loginsFFI.h" #import "nimbusFFI.h" #import "placesFFI.h" diff --git a/megazords/ios-rust/MozillaTestServices/MozillaTestServices.xcodeproj/project.pbxproj b/megazords/ios-rust/MozillaTestServices/MozillaTestServices.xcodeproj/project.pbxproj index b2f2863bb2..852fcc8e29 100644 --- a/megazords/ios-rust/MozillaTestServices/MozillaTestServices.xcodeproj/project.pbxproj +++ b/megazords/ios-rust/MozillaTestServices/MozillaTestServices.xcodeproj/project.pbxproj @@ -35,7 +35,6 @@ 1B5CB50E27B202B600C31B56 /* MozillaRustComponents.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1B5CB50D27B202B600C31B56 /* MozillaRustComponents.xcframework */; }; 1BB64C7A27B1FA0400A4247F /* GleanPlumbTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BBAC54227AE065300DAFEF2 /* GleanPlumbTests.swift */; }; 1BBAC4FC27AE049500DAFEF2 /* MozillaTestServicesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BBAC4FB27AE049500DAFEF2 /* MozillaTestServicesApp.swift */; }; - 1BBAC55127AE06FD00DAFEF2 /* Glean in Frameworks */ = {isa = PBXBuildFile; productRef = 1BBAC55027AE06FD00DAFEF2 /* Glean */; }; 1BBAC59C27AE0BB600DAFEF2 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BBAC4FD27AE049500DAFEF2 /* ContentView.swift */; }; 1BE9B60D27C9CD770029D11A /* crashtest.udl in Sources */ = {isa = PBXBuildFile; fileRef = 1B3BC99127B1DAA300229CF6 /* crashtest.udl */; }; 1BE9B60E27C9CD770029D11A /* nimbus.udl in Sources */ = {isa = PBXBuildFile; fileRef = 1B3BC98E27B1D9D600229CF6 /* nimbus.udl */; }; @@ -57,7 +56,6 @@ 1BF50F1827B1E18000A9C8A5 /* KeychainWrapperSubscript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BBAC56527AE085F00DAFEF2 /* KeychainWrapperSubscript.swift */; }; 1BF50F1927B1E19500A9C8A5 /* FxAccountManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BBAC54127AE065300DAFEF2 /* FxAccountManagerTests.swift */; }; 1BF50F1A27B1E19800A9C8A5 /* FxAccountMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BBAC53C27AE065300DAFEF2 /* FxAccountMocks.swift */; }; - 1BFC469827C99F250034E0A5 /* Metrics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BFC469627C99F250034E0A5 /* Metrics.swift */; }; 45CC574A28AD9C86006D55AA /* errorsupport.udl in Sources */ = {isa = PBXBuildFile; fileRef = 45CC574828AD9C31006D55AA /* errorsupport.udl */; }; /* End PBXBuildFile section */ @@ -165,7 +163,6 @@ 1BF50F1C27B1E1DF00A9C8A5 /* fxa_clientFFI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fxa_clientFFI.h; path = "../../../components/fxa-client/ios/Generated/fxa_clientFFI.h"; sourceTree = SOURCE_ROOT; }; 1BF50F1D27B1E1DF00A9C8A5 /* fxa_client.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = fxa_client.swift; path = "../../../components/fxa-client/ios/Generated/fxa_client.swift"; sourceTree = SOURCE_ROOT; }; 1BF50F2327B1E53E00A9C8A5 /* metrics.yaml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.yaml; name = metrics.yaml; path = ../../../components/nimbus/metrics.yaml; sourceTree = SOURCE_ROOT; }; - 1BF50F2B27B1EB7D00A9C8A5 /* sdk_generator.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = sdk_generator.sh; path = "../../../../../components/external/glean/glean-core/ios/sdk_generator.sh"; sourceTree = SOURCE_ROOT; }; 1BFC469627C99F250034E0A5 /* Metrics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Metrics.swift; path = MozillaTestServices/Generated/Metrics.swift; sourceTree = SOURCE_ROOT; }; 45CC574528AD9C0B006D55AA /* errorFFI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = errorFFI.h; path = ../../../../components/support/error/ios/Generated/errorFFI.h; sourceTree = ""; }; 45CC574628AD9C0B006D55AA /* errorsupport.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = errorsupport.swift; path = ../../../../components/support/error/ios/Generated/errorsupport.swift; sourceTree = ""; }; @@ -178,7 +175,6 @@ buildActionMask = 2147483647; files = ( 1B5CB50E27B202B600C31B56 /* MozillaRustComponents.xcframework in Frameworks */, - 1BBAC55127AE06FD00DAFEF2 /* Glean in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -269,7 +265,6 @@ 45CC574328AD9BC8006D55AA /* ErrorSupport */, 1BFC469427C99F250034E0A5 /* Generated */, 1BB64C7B27B1FF9F00A4247F /* TestClient */, - 1BF50F0327B1DFC900A9C8A5 /* Glean */, 1B3BC99027B1DA8700229CF6 /* Crashtest */, 1B3BC97427B1D99A00229CF6 /* Nimbus */, 1BBAC5A427AE0EF900DAFEF2 /* Places */, @@ -421,14 +416,6 @@ path = ../../../components/logins/ios/Generated; sourceTree = SOURCE_ROOT; }; - 1BF50F0327B1DFC900A9C8A5 /* Glean */ = { - isa = PBXGroup; - children = ( - 1BF50F2B27B1EB7D00A9C8A5 /* sdk_generator.sh */, - ); - path = Glean; - sourceTree = ""; - }; 1BF50F0527B1E06700A9C8A5 /* Generated */ = { isa = PBXGroup; children = ( @@ -496,7 +483,6 @@ ); name = MozillaTestServices; packageProductDependencies = ( - 1BBAC55027AE06FD00DAFEF2 /* Glean */, ); productName = MozillaTestServices; productReference = 1BBAC4F827AE049500DAFEF2 /* MozillaTestServices.app */; @@ -551,7 +537,6 @@ ); mainGroup = 1BBAC4EF27AE049500DAFEF2; packageReferences = ( - 1BBAC54F27AE06FD00DAFEF2 /* XCRemoteSwiftPackageReference "glean-swift" */, ); productRefGroup = 1BBAC4F927AE049500DAFEF2 /* Products */; projectDirPath = ""; @@ -589,17 +574,15 @@ inputFileListPaths = ( ); inputPaths = ( - "$(SRCROOT)/../../../components/nimbus/metrics.yaml", ); name = "Generate Glean Metrics"; outputFileListPaths = ( ); outputPaths = ( - "$(SRCROOT)/MozillaTestServices/Generated/Metrics.swift", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "rm -rf .venv; bash $PWD/../../../components/external/glean/glean-core/ios/sdk_generator.sh -g Glean\n"; + shellScript = "rm -rf .venv; bash $PWD/../../../components/external/glean/glean-core/ios/sdk_generator.sh -g MozillaRustComponents\n\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -614,7 +597,6 @@ 1BE9B60F27C9CD770029D11A /* places.udl in Sources */, 1BE9B61027C9CD770029D11A /* logins.udl in Sources */, 1BE9B61127C9CD770029D11A /* fxa_client.udl in Sources */, - 1BFC469827C99F250034E0A5 /* Metrics.swift in Sources */, 1B3BC98627B1D9B800229CF6 /* FeatureVariables.swift in Sources */, 1BBAC59C27AE0BB600DAFEF2 /* ContentView.swift in Sources */, 1B3BC98B27B1D9B800229CF6 /* Sysctl.swift in Sources */, @@ -931,25 +913,6 @@ defaultConfigurationName = Debug; }; /* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 1BBAC54F27AE06FD00DAFEF2 /* XCRemoteSwiftPackageReference "glean-swift" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/mozilla/glean-swift"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 51.2.0; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 1BBAC55027AE06FD00DAFEF2 /* Glean */ = { - isa = XCSwiftPackageProductDependency; - package = 1BBAC54F27AE06FD00DAFEF2 /* XCRemoteSwiftPackageReference "glean-swift" */; - productName = Glean; - }; -/* End XCSwiftPackageProductDependency section */ }; rootObject = 1BBAC4F027AE049500DAFEF2 /* Project object */; } diff --git a/megazords/ios-rust/MozillaTestServices/MozillaTestServices.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/megazords/ios-rust/MozillaTestServices/MozillaTestServices.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index 8e43c3d60f..0000000000 --- a/megazords/ios-rust/MozillaTestServices/MozillaTestServices.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,16 +0,0 @@ -{ - "object": { - "pins": [ - { - "package": "Glean", - "repositoryURL": "https://github.com/mozilla/glean-swift", - "state": { - "branch": null, - "revision": "5b810598dbe39579703af99af4afe4de92811d0c", - "version": "51.2.0" - } - } - ] - }, - "version": 1 -} diff --git a/megazords/ios-rust/MozillaTestServices/MozillaTestServicesTests/LoginsTests.swift b/megazords/ios-rust/MozillaTestServices/MozillaTestServicesTests/LoginsTests.swift index 1e1afbcf2b..1c1547de0c 100644 --- a/megazords/ios-rust/MozillaTestServices/MozillaTestServicesTests/LoginsTests.swift +++ b/megazords/ios-rust/MozillaTestServices/MozillaTestServicesTests/LoginsTests.swift @@ -4,7 +4,6 @@ @testable import MozillaTestServices -import Glean import XCTest class LoginsTests: XCTestCase { @@ -12,7 +11,6 @@ class LoginsTests: XCTestCase { override func setUp() { super.setUp() - Glean.shared.resetGlean(clearStores: true) } override func tearDown() { diff --git a/megazords/ios-rust/MozillaTestServices/MozillaTestServicesTests/NimbusTests.swift b/megazords/ios-rust/MozillaTestServices/MozillaTestServicesTests/NimbusTests.swift index 7c5aff5713..8e20ea8c15 100644 --- a/megazords/ios-rust/MozillaTestServices/MozillaTestServicesTests/NimbusTests.swift +++ b/megazords/ios-rust/MozillaTestServices/MozillaTestServicesTests/NimbusTests.swift @@ -4,35 +4,10 @@ @testable import MozillaTestServices -import Glean import UIKit import XCTest class NimbusTests: XCTestCase { - override func setUp() { - Glean.shared.resetGlean(clearStores: true) - Glean.shared.enableTestingMode() - let buildDate = DateComponents( - calendar: Calendar.current, - timeZone: TimeZone(abbreviation: "UTC"), - year: 2019, - month: 10, - day: 23, - hour: 12, - minute: 52, - second: 8 - ) - let buildInfo = BuildInfo(buildDate: buildDate) - Glean.shared.initialize( - uploadEnabled: true, - configuration: Configuration( - channel: "test", - serverEndpoint: "https://example.com" - ), - buildInfo: buildInfo - ) - } - func emptyExperimentJSON() -> String { return """ { "data": [] } @@ -183,198 +158,6 @@ class NimbusTests: XCTestCase { XCTAssertEqual(appContext.deviceModel, "x86_64") } } - - func testRecordExperimentTelemetry() throws { - let appSettings = NimbusAppSettings(appName: "NimbusUnitTest", channel: "test") - let nimbus = try Nimbus.create(nil, appSettings: appSettings, dbPath: createDatabasePath()) as! Nimbus - - let enrolledExperiments = [EnrolledExperiment( - featureIds: [], - slug: "test-experiment", - userFacingName: "Test Experiment", - userFacingDescription: "A test experiment for testing experiments", - branchSlug: "test-branch", - enrollmentId: "enrollment-id" - )] - - nimbus.recordExperimentTelemetry(enrolledExperiments) - XCTAssertTrue(Glean.shared.testIsExperimentActive("test-experiment"), - "Experiment should be active") - // TODO: Below fails due to branch and extra being private members Glean - // We will need to change this if we want to remove glean as a submodule and instead - // consume it as a swift package https://github.com/mozilla/application-services/issues/4864 - - // let experimentData = Glean.shared.testGetExperimentData(experimentId: "test-experiment")! - // XCTAssertEqual("test-branch", experimentData.branch, "Experiment branch must match") - // XCTAssertEqual("enrollment-id", experimentData.extra["enrollmentId"], "Enrollment id must match") - } - - func testRecordExperimentEvents() throws { - let appSettings = NimbusAppSettings(appName: "NimbusUnitTest", channel: "test") - let nimbus = try Nimbus.create(nil, appSettings: appSettings, dbPath: createDatabasePath()) as! Nimbus - - // Create a list of events to record, one of each type, all associated with the same - // experiment - let events = [ - EnrollmentChangeEvent( - experimentSlug: "test-experiment", - branchSlug: "test-branch", - enrollmentId: "test-enrollment-id", - reason: "test-reason", - change: .enrollment - ), - EnrollmentChangeEvent( - experimentSlug: "test-experiment", - branchSlug: "test-branch", - enrollmentId: "test-enrollment-id", - reason: "test-reason", - change: .unenrollment - ), - EnrollmentChangeEvent( - experimentSlug: "test-experiment", - branchSlug: "test-branch", - enrollmentId: "test-enrollment-id", - reason: "test-reason", - change: .disqualification - ), - ] - - // Record the experiment events in Glean - nimbus.recordExperimentEvents(events) - - // Use the Glean test API to check the recorded events - - // Enrollment - XCTAssertNotNil(GleanMetrics.NimbusEvents.enrollment.testGetValue(), "Enrollment event must exist") - let enrollmentEvents = GleanMetrics.NimbusEvents.enrollment.testGetValue()! - XCTAssertEqual(1, enrollmentEvents.count, "Enrollment event count must match") - let enrollmentEventExtras = enrollmentEvents.first!.extra - XCTAssertEqual("test-experiment", enrollmentEventExtras!["experiment"], "Enrollment event experiment must match") - XCTAssertEqual("test-branch", enrollmentEventExtras!["branch"], "Enrollment event branch must match") - XCTAssertEqual("test-enrollment-id", enrollmentEventExtras!["enrollment_id"], "Enrollment event enrollment id must match") - - // Unenrollment - XCTAssertNotNil(GleanMetrics.NimbusEvents.unenrollment.testGetValue(), "Unenrollment event must exist") - let unenrollmentEvents = GleanMetrics.NimbusEvents.unenrollment.testGetValue()! - XCTAssertEqual(1, unenrollmentEvents.count, "Unenrollment event count must match") - let unenrollmentEventExtras = unenrollmentEvents.first!.extra - XCTAssertEqual("test-experiment", unenrollmentEventExtras!["experiment"], "Unenrollment event experiment must match") - XCTAssertEqual("test-branch", unenrollmentEventExtras!["branch"], "Unenrollment event branch must match") - XCTAssertEqual("test-enrollment-id", unenrollmentEventExtras!["enrollment_id"], "Unenrollment event enrollment id must match") - - // Disqualification - XCTAssertNotNil(GleanMetrics.NimbusEvents.disqualification.testGetValue(), "Disqualification event must exist") - let disqualificationEvents = GleanMetrics.NimbusEvents.disqualification.testGetValue()! - XCTAssertEqual(1, disqualificationEvents.count, "Disqualification event count must match") - let disqualificationEventExtras = disqualificationEvents.first!.extra - XCTAssertEqual("test-experiment", disqualificationEventExtras!["experiment"], "Disqualification event experiment must match") - XCTAssertEqual("test-branch", disqualificationEventExtras!["branch"], "Disqualification event branch must match") - XCTAssertEqual("test-enrollment-id", disqualificationEventExtras!["enrollment_id"], "Disqualification event enrollment id must match") - } - - func testRecordExposure() throws { - let appSettings = NimbusAppSettings(appName: "NimbusUnitTest", channel: "test") - let nimbus = try Nimbus.create(nil, appSettings: appSettings, dbPath: createDatabasePath()) as! Nimbus - - // Load an experiment in nimbus that we will record an event in. The experiment bucket configuration - // is set so that it will be guaranteed to be active. This is necessary because the SDK checks for - // active experiments before recording. - try nimbus.setExperimentsLocallyOnThisThread(minimalExperimentJSON()) - try nimbus.applyPendingExperimentsOnThisThread() - - // Assert that there are no events to start with - XCTAssertNil(GleanMetrics.NimbusEvents.exposure.testGetValue(), "Event must not have a value") - - // Record a valid exposure event in Glean that matches the featureId from the test experiment - nimbus.recordExposureEvent(featureId: "aboutwelcome") - - // Use the Glean test API to check that the valid event is present - XCTAssertNotNil(GleanMetrics.NimbusEvents.exposure.testGetValue(), "Event must have a value") - let enrollmentEvents = GleanMetrics.NimbusEvents.exposure.testGetValue()! - XCTAssertEqual(1, enrollmentEvents.count, "Event count must match") - let enrollmentEventExtras = enrollmentEvents.first!.extra - XCTAssertEqual("secure-gold", enrollmentEventExtras!["experiment"], "Experiment slug must match") - XCTAssertTrue( - enrollmentEventExtras!["branch"] == "control" || enrollmentEventExtras!["branch"] == "treatment", - "Experiment branch must match" - ) - XCTAssertNotNil(enrollmentEventExtras!["enrollment_id"], "Experiment enrollment id must not be nil") - - // Attempt to record an event for a non-existent or feature we are not enrolled in an - // experiment in to ensure nothing is recorded. - nimbus.recordExposureEvent(featureId: "not-a-feature") - - // Verify the invalid event was ignored by checking again that the valid event is still the only - // event, and that it hasn't changed any of its extra properties. - let enrollmentEventsTryTwo = GleanMetrics.NimbusEvents.exposure.testGetValue()! - XCTAssertEqual(1, enrollmentEventsTryTwo.count, "Event count must match") - let enrollmentEventExtrasTryTwo = enrollmentEventsTryTwo.first!.extra - XCTAssertEqual("secure-gold", enrollmentEventExtrasTryTwo!["experiment"], "Experiment slug must match") - XCTAssertTrue( - enrollmentEventExtrasTryTwo!["branch"] == "control" || enrollmentEventExtrasTryTwo!["branch"] == "treatment", - "Experiment branch must match" - ) - XCTAssertNotNil(enrollmentEventExtrasTryTwo!["enrollment_id"], "Experiment enrollment id must not be nil") - } - - func testRecordDisqualificationOnOptOut() throws { - let appSettings = NimbusAppSettings(appName: "NimbusUnitTest", channel: "test") - let nimbus = try Nimbus.create(nil, appSettings: appSettings, dbPath: createDatabasePath()) as! Nimbus - - // Load an experiment in nimbus that we will record an event in. The experiment bucket configuration - // is set so that it will be guaranteed to be active. This is necessary because the SDK checks for - // active experiments before recording. - try nimbus.setExperimentsLocallyOnThisThread(minimalExperimentJSON()) - try nimbus.applyPendingExperimentsOnThisThread() - - // Assert that there are no events to start with - XCTAssertNil(GleanMetrics.NimbusEvents.exposure.testGetValue(), "Event must not have a value") - - // Opt out of the experiment, which should generate a "disqualification" event - try nimbus.optOutOnThisThread("secure-gold") - - // Use the Glean test API to check that the valid event is present - XCTAssertNotNil(GleanMetrics.NimbusEvents.disqualification.testGetValue(), "Event must have a value") - let disqualificationEvents = GleanMetrics.NimbusEvents.disqualification.testGetValue()! - XCTAssertEqual(1, disqualificationEvents.count, "Event count must match") - let disqualificationEventExtras = disqualificationEvents.first!.extra - XCTAssertEqual("secure-gold", disqualificationEventExtras!["experiment"], "Experiment slug must match") - XCTAssertTrue( - disqualificationEventExtras!["branch"] == "control" || disqualificationEventExtras!["branch"] == "treatment", - "Experiment branch must match" - ) - XCTAssertNotNil(disqualificationEventExtras!["enrollment_id"], "Experiment enrollment id must not be nil") - } - - func testRecordDisqualificationOnGlobalOptOut() throws { - let appSettings = NimbusAppSettings(appName: "NimbusUnitTest", channel: "test") - let nimbus = try Nimbus.create(nil, appSettings: appSettings, dbPath: createDatabasePath()) as! Nimbus - - // Load an experiment in nimbus that we will record an event in. The experiment bucket configuration - // is set so that it will be guaranteed to be active. This is necessary because the SDK checks for - // active experiments before recording. - try nimbus.setExperimentsLocallyOnThisThread(minimalExperimentJSON()) - try nimbus.applyPendingExperimentsOnThisThread() - - // Assert that there are no events to start with - XCTAssertNil(GleanMetrics.NimbusEvents.exposure.testGetValue(), "Event must not have a value") - - // Opt out of all experiments, which should generate a "disqualification" event for the enrolled - // experiment - try nimbus.setGlobalUserParticipationOnThisThread(false) - - // Use the Glean test API to check that the valid event is present - XCTAssertNotNil(GleanMetrics.NimbusEvents.disqualification.testGetValue(), "Event must have a value") - let disqualificationEvents = GleanMetrics.NimbusEvents.disqualification.testGetValue()! - XCTAssertEqual(1, disqualificationEvents.count, "Event count must match") - let disqualificationEventExtras = disqualificationEvents.first!.extra - XCTAssertEqual("secure-gold", disqualificationEventExtras!["experiment"], "Experiment slug must match") - XCTAssertTrue( - disqualificationEventExtras!["branch"] == "control" || disqualificationEventExtras!["branch"] == "treatment", - "Experiment branch must match" - ) - XCTAssertNotNil(disqualificationEventExtras!["enrollment_id"], "Experiment enrollment id must not be nil") - } } private extension Device { diff --git a/megazords/ios-rust/build-xcframework.sh b/megazords/ios-rust/build-xcframework.sh index a642a626c7..a741b0a09d 100755 --- a/megazords/ios-rust/build-xcframework.sh +++ b/megazords/ios-rust/build-xcframework.sh @@ -59,7 +59,7 @@ CARGO="$HOME/.cargo/bin/cargo" LIBS_DIR="$REPO_ROOT/libs" DEFAULT_RUSTFLAGS="" -BUILD_ARGS=(build --manifest-path "$MANIFEST_PATH" --lib) +BUILD_ARGS=(build --manifest-path "$MANIFEST_PATH" --lib --features "builtin-glean") case $BUILD_PROFILE in debug) ;; release) @@ -147,7 +147,7 @@ cp "$REPO_ROOT/components/rc_log/ios/RustLogFFI.h" "$COMMON/Headers" cp "$REPO_ROOT/components/viaduct/ios/RustViaductFFI.h" "$COMMON/Headers" $CARGO uniffi-bindgen generate "$REPO_ROOT/components/nimbus/src/nimbus.udl" -l swift -o "$COMMON/Headers" $CARGO uniffi-bindgen generate "$REPO_ROOT/components/support/error/src/errorsupport.udl" -l swift -o "$COMMON/Headers" - +$CARGO uniffi-bindgen generate "$REPO_ROOT/components/external/glean/glean-core/src/glean.udl" -l swift -o "$COMMON/Headers" # We now only move/generate the rest of the headers if we are generating a full # iOS megazord diff --git a/megazords/ios-rust/focus/Cargo.toml b/megazords/ios-rust/focus/Cargo.toml index 293e197650..58456d0963 100644 --- a/megazords/ios-rust/focus/Cargo.toml +++ b/megazords/ios-rust/focus/Cargo.toml @@ -8,10 +8,13 @@ license = "MPL-2.0" [lib] crate-type = ["staticlib"] +[features] +builtin-glean = ["nimbus-sdk/builtin-glean"] + [dependencies] rc_log_ffi = { path = "../../../components/rc_log" } viaduct = { path = "../../../components/viaduct" } viaduct-reqwest = { path = "../../../components/support/viaduct-reqwest" } nimbus-sdk = { path = "../../../components/nimbus" } error-support = { path = "../../../components/support/error" } - +glean-core = { path = "../../../components/external/glean/glean-core" } diff --git a/megazords/ios-rust/focus/DEPENDENCIES.md b/megazords/ios-rust/focus/DEPENDENCIES.md index a2bbbe64ff..f78c2125e2 100644 --- a/megazords/ios-rust/focus/DEPENDENCIES.md +++ b/megazords/ios-rust/focus/DEPENDENCIES.md @@ -12,6 +12,7 @@ the details of which are reproduced below. * [MIT License: bincode](#mit-license-bincode) * [MIT License: bytes](#mit-license-bytes) * [MIT License: cargo_metadata](#mit-license-cargo_metadata) +* [MIT License: dashmap](#mit-license-dashmap) * [MIT License: generic-array](#mit-license-generic-array) * [MIT License: goblin](#mit-license-goblin) * [MIT License: h2](#mit-license-h2) @@ -19,9 +20,11 @@ the details of which are reproduced below. * [MIT License: hyper](#mit-license-hyper) * [MIT License: matches](#mit-license-matches) * [MIT License: mime_guess](#mit-license-mime_guess) +* [MIT License: miniz_oxide](#mit-license-miniz_oxide) * [MIT License: mio](#mit-license-mio) * [MIT License: nom](#mit-license-nom) * [MIT License: ordered-float](#mit-license-ordered-float) +* [MIT License: oslog](#mit-license-oslog) * [MIT License: scroll](#mit-license-scroll) * [MIT License: scroll_derive](#mit-license-scroll_derive) * [MIT License: slab](#mit-license-slab) @@ -33,7 +36,7 @@ the details of which are reproduced below. * [MIT License: try-lock](#mit-license-try-lock) * [MIT License: want](#mit-license-want) * [MIT License: weedle2](#mit-license-weedle2) -* [MIT License: xshell-venv](#mit-license-xshell-venv) +* [MIT License: whatsys](#mit-license-whatsys) * [BSD-2-Clause License: arrayref](#bsd-2-clause-license-arrayref) * [(Apache-2.0 OR MIT) AND BSD-3-Clause License: encoding_rs](#(apache-20-or-mit)-and-bsd-3-clause-license-encoding_rs) ------------- @@ -46,7 +49,8 @@ The following text applies to code linked from these dependencies: [uniffi_bindgen](https://github.com/mozilla/uniffi-rs), [uniffi_build](https://github.com/mozilla/uniffi-rs), [uniffi_macros](https://github.com/mozilla/uniffi-rs), -[uniffi_meta](https://github.com/mozilla/uniffi-rs) +[uniffi_meta](https://github.com/mozilla/uniffi-rs), +[zeitstempel](https://github.com/badboy/zeitstempel) ``` Mozilla Public License Version 2.0 @@ -428,6 +432,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice ## Apache License 2.0 The following text applies to code linked from these dependencies: +[adler](https://github.com/jonas-schievink/adler.git), [anyhow](https://github.com/dtolnay/anyhow), [askama](https://github.com/djc/askama), [askama_derive](https://github.com/djc/askama), @@ -448,10 +453,15 @@ The following text applies to code linked from these dependencies: [core-foundation-sys](https://github.com/servo/core-foundation-rs), [core-foundation](https://github.com/servo/core-foundation-rs), [cpufeatures](https://github.com/RustCrypto/utils), +[crc32fast](https://github.com/srijs/rust-crc32fast), +[crossbeam-channel](https://github.com/crossbeam-rs/crossbeam), +[crossbeam-utils](https://github.com/crossbeam-rs/crossbeam), [digest](https://github.com/RustCrypto/traits), [either](https://github.com/bluss/either), +[env_logger](https://github.com/env-logger-rs/env_logger/), [fastrand](https://github.com/smol-rs/fastrand), [ffi-support](https://github.com/mozilla/ffi-support), +[flate2](https://github.com/rust-lang/flate2-rs), [fnv](https://github.com/servo/rust-fnv), [form_urlencoded](https://github.com/servo/rust-url), [fs-err](https://github.com/andrewhickman/fs-err), @@ -468,6 +478,7 @@ The following text applies to code linked from these dependencies: [http](https://github.com/hyperium/http), [httparse](https://github.com/seanmonstar/httparse), [httpdate](https://github.com/pyfisch/httpdate), +[humantime](https://github.com/tailhook/humantime), [hyper-tls](https://github.com/hyperium/hyper-tls), [id-arena](https://github.com/fitzgen/id-arena), [idna](https://github.com/servo/rust-url/), @@ -534,14 +545,12 @@ The following text applies to code linked from these dependencies: [unicode-segmentation](https://github.com/unicode-rs/unicode-segmentation), [url](https://github.com/servo/rust-url), [uuid](https://github.com/uuid-rs/uuid), -[version_check](https://github.com/SergioBenitez/version_check), -[xshell-macros](https://github.com/matklad/xshell), -[xshell](https://github.com/matklad/xshell) +[version_check](https://github.com/SergioBenitez/version_check) ``` Apache License Version 2.0, January 2004 - http://www.apache.org/licenses/ + https://www.apache.org/licenses/LICENSE-2.0 TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION @@ -733,7 +742,7 @@ 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 + https://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, @@ -930,6 +939,36 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` +------------- +## MIT License: dashmap + +The following text applies to code linked from these dependencies: +[dashmap](https://github.com/xacrimon/dashmap) + +``` +MIT License + +Copyright (c) 2019 Acrimon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ``` ------------- ## MIT License: generic-array @@ -1150,6 +1189,36 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` +------------- +## MIT License: miniz_oxide + +The following text applies to code linked from these dependencies: +[miniz_oxide](https://github.com/Frommi/miniz_oxide/tree/master/miniz_oxide) + +``` +MIT License + +Copyright (c) 2017 Frommi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ``` ------------- ## MIT License: mio @@ -1241,6 +1310,36 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` +------------- +## MIT License: oslog + +The following text applies to code linked from these dependencies: +[oslog](https://github.com/steven-joruk/oslog) + +``` +MIT License + +Copyright (c) 2020 Steven Joruk + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ``` ------------- ## MIT License: scroll @@ -1588,15 +1687,15 @@ DEALINGS IN THE SOFTWARE. ``` ------------- -## MIT License: xshell-venv +## MIT License: whatsys The following text applies to code linked from these dependencies: -[xshell-venv](https://github.com/badboy/xshell-venv) +[whatsys](https://github.com/badboy/whatsys) ``` The MIT License (MIT) -Copyright (c) 2022 Jan-Erik Rediger +Copyright (c) 2021 Jan-Erik Rediger Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -1605,16 +1704,16 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. ``` ------------- diff --git a/megazords/ios-rust/focus/MozillaRustComponents.h b/megazords/ios-rust/focus/MozillaRustComponents.h index 7283edfb34..6b9c91227b 100644 --- a/megazords/ios-rust/focus/MozillaRustComponents.h +++ b/megazords/ios-rust/focus/MozillaRustComponents.h @@ -9,3 +9,4 @@ #import "RustViaductFFI.h" #import "nimbusFFI.h" #import "errorFFI.h" +#import "gleanFFI.h" diff --git a/megazords/ios-rust/focus/src/lib.rs b/megazords/ios-rust/focus/src/lib.rs index 91cbedbc9f..08fc06869e 100644 --- a/megazords/ios-rust/focus/src/lib.rs +++ b/megazords/ios-rust/focus/src/lib.rs @@ -6,6 +6,7 @@ #![warn(rust_2018_idioms)] pub use error_support; +pub use glean_core; pub use nimbus; pub use rc_log_ffi; pub use viaduct_reqwest; diff --git a/megazords/ios-rust/src/lib.rs b/megazords/ios-rust/src/lib.rs index eaa0230c3b..f67ee97cdc 100644 --- a/megazords/ios-rust/src/lib.rs +++ b/megazords/ios-rust/src/lib.rs @@ -9,6 +9,7 @@ pub use autofill; pub use crashtest; pub use error_support; pub use fxa_client; +pub use glean_core; pub use logins; pub use nimbus; pub use places;