Bug 1933939 - Update to Glean v63.0.0 r=supply-chain-reviewers,mach-reviewers,android-reviewers,twhite,chutten

Differential Revision: https://phabricator.services.mozilla.com/D230526
This commit is contained in:
Jan-Erik Rediger
2024-12-12 20:14:32 +00:00
parent d0e26a60d3
commit 82b5eb9dff
57 changed files with 1342 additions and 249 deletions

9
Cargo.lock generated
View File

@@ -2536,10 +2536,11 @@ dependencies = [
[[package]]
name = "glean"
version = "62.0.0"
version = "63.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8e7570fa2e6eb6065e3f119e227f9c269742c9132cc954c9c05e371d07d14ab"
checksum = "6edc2134eac59587dc100b301eeba2dd473d74d6ecd51d635419a1865cc92496"
dependencies = [
"crossbeam-channel",
"glean-core",
"inherent",
"log",
@@ -2549,9 +2550,9 @@ dependencies = [
[[package]]
name = "glean-core"
version = "62.0.0"
version = "63.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "079266eabbb238c8b76bad5869c89db93932ecfe6ea6086daef6aa909b4cf10d"
checksum = "b840b5177e3e102332cfa09bbbe57ae69f939a180d73cb02351b2ddf4cb1fbee"
dependencies = [
"android_logger",
"bincode",

View File

@@ -63,7 +63,7 @@ uniffi_bindgen = "0.28.2"
# Shared across multiple application-services consumers.
rusqlite = "0.31.0"
# Shared across multiple glean consumers.
glean = "=62.0.0"
glean = "=63.0.0"
# Explicitly specify what our profiles use. The opt-level setting here is
# a total fiction; see the setup of MOZ_RUST_DEFAULT_FLAGS for what the

9
gfx/wr/Cargo.lock generated
View File

@@ -1040,10 +1040,11 @@ dependencies = [
[[package]]
name = "glean"
version = "62.0.0"
version = "63.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8e7570fa2e6eb6065e3f119e227f9c269742c9132cc954c9c05e371d07d14ab"
checksum = "6edc2134eac59587dc100b301eeba2dd473d74d6ecd51d635419a1865cc92496"
dependencies = [
"crossbeam-channel",
"glean-core",
"inherent",
"log",
@@ -1053,9 +1054,9 @@ dependencies = [
[[package]]
name = "glean-core"
version = "62.0.0"
version = "63.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "079266eabbb238c8b76bad5869c89db93932ecfe6ea6086daef6aa909b4cf10d"
checksum = "b840b5177e3e102332cfa09bbbe57ae69f939a180d73cb02351b2ddf4cb1fbee"
dependencies = [
"android_logger",
"bincode",

View File

@@ -9,7 +9,7 @@ members = [
resolver = "2"
[workspace.dependencies]
glean = "=62.0.0"
glean = "=63.0.0"
[profile.release]
debug = true

View File

@@ -19,7 +19,7 @@ object Versions {
const val serialization = "1.6.3"
const val python_envs_plugin = "0.0.31"
const val mozilla_glean = "62.0.0"
const val mozilla_glean = "63.0.0"
const val maven_ant_tasks = "2.1.3"
const val jacoco = "0.8.12"

View File

@@ -102,7 +102,7 @@ vendored:third_party/python/wheel
vendored:third_party/python/zipp
# glean-sdk may not be installable if a wheel isn't available
# and it has to be built from source.
pypi-optional:glean-sdk==62.0.0:telemetry will not be collected
pypi-optional:glean-sdk==63.0.0:telemetry will not be collected
# Mach gracefully handles the case where `psutil` is unavailable.
# We aren't (yet) able to pin packages in automation, so we have to
# support down to the oldest locally-installed version (5.4.2).

View File

@@ -3,7 +3,7 @@
[[unpublished.allocator-api2]]
version = "0.2.999"
audited_as = "0.2.18"
audited_as = "0.2.20"
[[publisher.aho-corasick]]
version = "1.1.0"
@@ -258,15 +258,15 @@ user-login = "jrmuizel"
user-name = "Jeff Muizelaar"
[[publisher.glean]]
version = "62.0.0"
when = "2024-11-05"
version = "63.0.0"
when = "2024-11-28"
user-id = 48
user-login = "badboy"
user-name = "Jan-Erik Rediger"
[[publisher.glean-core]]
version = "62.0.0"
when = "2024-11-05"
version = "63.0.0"
when = "2024-11-28"
user-id = 48
user-login = "badboy"
user-name = "Jan-Erik Rediger"
@@ -957,6 +957,15 @@ Shuffling of features in this update and while there are updates to `unsafe`
code it's no different than before and the usage remains the same.
"""
[[audits.bytecode-alliance.audits.allocator-api2]]
who = "Chris Fallin <chris@cfallin.org>"
criteria = "safe-to-deploy"
delta = "0.2.18 -> 0.2.20"
notes = """
The changes appear to be reasonable updates from Rust's stdlib imported into
`allocator-api2`'s copy of this code.
"""
[[audits.bytecode-alliance.audits.arrayref]]
who = "Nick Fitzgerald <fitzgen@gmail.com>"
criteria = "safe-to-deploy"
@@ -1554,20 +1563,6 @@ criteria = "safe-to-run"
version = "0.2.3"
aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT"
[[audits.google.audits.unicode-linebreak]]
who = "Lukasz Anforowicz <lukasza@chromium.org>"
criteria = "safe-to-deploy"
version = "0.1.5"
notes = """
Grepped for `-i cipher`, `-i crypto`, `'\bfs\b'``, `'\bnet\b'``, `'\bunsafe\b'``
and there were no hits.
Version `0.1.2` of this crate has been added to Chromium in
https://source.chromium.org/chromium/chromium/src/+/591a0f30c5eac93b6a3d981c2714ffa4db28dbcb
The CL description contains a link to a Google-internal document with audit details.
"""
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
[[audits.google.audits.version_check]]
who = "George Burgess IV <gbiv@google.com>"
criteria = "safe-to-deploy"

File diff suppressed because one or more lines are too long

View File

@@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.76"
name = "glean-core"
version = "62.0.0"
version = "63.0.0"
authors = [
"Jan-Erik Rediger <jrediger@mozilla.com>",
"The Glean Team <glean-team@mozilla.com>",
@@ -40,7 +40,7 @@ license = "MPL-2.0"
repository = "https://github.com/mozilla/glean"
[package.metadata.glean]
glean-parser = "15.2.0"
glean-parser = "16.1.0"
[lib]
name = "glean_core"
@@ -50,6 +50,10 @@ path = "src/lib.rs"
name = "boolean"
path = "tests/boolean.rs"
[[test]]
name = "collection_enabled"
path = "tests/collection_enabled.rs"
[[test]]
name = "counter"
path = "tests/counter.rs"

View File

@@ -127,7 +127,7 @@ where
/// ping_lifetime_max_time: 2000,
/// };
/// let mut glean = Glean::new(cfg).unwrap();
/// let ping = PingType::new("sample", true, false, true, true, true, vec![], vec![]);
/// let ping = PingType::new("sample", true, false, true, true, true, vec![], vec![], true);
/// glean.register_ping_type(&ping);
///
/// let call_counter: CounterMetric = CounterMetric::new(CommonMetricData {
@@ -428,7 +428,16 @@ impl Glean {
/// # Returns
///
/// Whether the "events" ping was submitted.
pub fn on_ready_to_submit_pings(&self, trim_data_to_registered_pings: bool) -> bool {
pub fn on_ready_to_submit_pings(&mut self, trim_data_to_registered_pings: bool) -> bool {
// When upload is disabled on init we already clear out metrics.
// However at that point not all pings are registered and so we keep that data around.
// By the time we would be ready to submit we try again cleaning out metrics from
// now-known pings.
if !self.upload_enabled {
log::debug!("on_ready_to_submit_pings. let's clear pings once again.");
self.clear_metrics();
}
self.event_data_store
.flush_pending_events_on_startup(self, trim_data_to_registered_pings)
}
@@ -467,6 +476,29 @@ impl Glean {
}
}
/// Enable or disable a ping.
///
/// Disabling a ping causes all data for that ping to be removed from storage
/// and all pending pings of that type to be deleted.
///
/// **Note**: Do not use directly. Call `PingType::set_enabled` instead.
#[doc(hidden)]
pub fn set_ping_enabled(&mut self, ping: &PingType, enabled: bool) {
ping.store_enabled(enabled);
if !enabled {
if let Some(data) = self.data_store.as_ref() {
_ = data.clear_ping_lifetime_storage(ping.name());
_ = data.clear_lifetime_storage(Lifetime::User, ping.name());
_ = data.clear_lifetime_storage(Lifetime::Application, ping.name());
}
let ping_maker = PingMaker::new();
let disabled_pings = &[ping.name()][..];
if let Err(err) = ping_maker.clear_pending_pings(self.get_data_path(), disabled_pings) {
log::warn!("Error clearing pending pings: {}", err);
}
}
}
/// Determines whether upload is enabled.
///
/// When upload is disabled, no data will be recorded.
@@ -474,6 +506,36 @@ impl Glean {
self.upload_enabled
}
/// Check if a ping is enabled.
///
/// Note that some internal "ping" names are considered to be always enabled.
///
/// If a ping is not known to Glean ("unregistered") it is always considered disabled.
/// If a ping is known, it can be enabled/disabled at any point.
/// Only data for enabled pings is recorded.
/// Disabled pings are never submitted.
pub fn is_ping_enabled(&self, ping: &str) -> bool {
// We "abuse" pings/storage names for internal data.
const DEFAULT_ENABLED: &[&str] = &[
"glean_client_info",
"glean_internal_info",
// for `experimentation_id`.
// That should probably have gone into `glean_internal_info` instead.
"all-pings",
];
// `client_info`-like stuff is always enabled.
if DEFAULT_ENABLED.contains(&ping) {
return true;
}
let Some(ping) = self.ping_registry.get(ping) else {
return false;
};
ping.enabled(self)
}
/// Handles the changing of state from upload disabled to enabled.
///
/// Should only be called when the state actually changes.
@@ -526,9 +588,15 @@ impl Glean {
.first_run_date
.get_value(self, "glean_client_info");
// Clear any pending pings.
// Clear any pending pings that follow `collection_enabled`.
let ping_maker = PingMaker::new();
if let Err(err) = ping_maker.clear_pending_pings(self.get_data_path()) {
let disabled_pings = self
.ping_registry
.iter()
.filter(|&(_ping_name, ping)| ping.follows_collection_enabled())
.map(|(ping_name, _ping)| &ping_name[..])
.collect::<Vec<_>>();
if let Err(err) = ping_maker.clear_pending_pings(self.get_data_path(), &disabled_pings) {
log::warn!("Error clearing pending pings: {}", err);
}
@@ -536,7 +604,16 @@ impl Glean {
// Note that this also includes the ping sequence numbers, so it has
// the effect of resetting those to their initial values.
if let Some(data) = self.data_store.as_ref() {
data.clear_all()
_ = data.clear_lifetime_storage(Lifetime::User, "glean_internal_info");
_ = data.clear_lifetime_storage(Lifetime::User, "glean_client_info");
_ = data.clear_lifetime_storage(Lifetime::Application, "glean_client_info");
for (ping_name, ping) in &self.ping_registry {
if ping.follows_collection_enabled() {
_ = data.clear_ping_lifetime_storage(ping_name);
_ = data.clear_lifetime_storage(Lifetime::User, ping_name);
_ = data.clear_lifetime_storage(Lifetime::Application, ping_name);
}
}
}
if let Err(err) = self.event_data_store.clear_all() {
log::warn!("Error clearing pending events: {}", err);
@@ -724,6 +801,15 @@ impl Glean {
.insert(ping.name().to_string(), ping.clone());
}
/// Gets a list of currently registered ping names.
///
/// # Returns
///
/// The list of ping names that are currently registered.
pub fn get_registered_ping_names(&self) -> Vec<&str> {
self.ping_registry.keys().map(String::as_str).collect()
}
/// Get create time of the Glean object.
pub(crate) fn start_time(&self) -> DateTime<FixedOffset> {
self.start_time
@@ -860,8 +946,8 @@ impl Glean {
/// Return the value for the debug view tag or [`None`] if it hasn't been set.
///
/// The `debug_view_tag` may be set from an environment variable
/// (`GLEAN_DEBUG_VIEW_TAG`) or through the [`set_debug_view_tag`] function.
pub(crate) fn debug_view_tag(&self) -> Option<&String> {
/// (`GLEAN_DEBUG_VIEW_TAG`) or through the `set_debug_view_tag` function.
pub fn debug_view_tag(&self) -> Option<&String> {
self.debug.debug_view_tag.get()
}
@@ -902,11 +988,11 @@ impl Glean {
self.debug.log_pings.set(value)
}
/// Return the value for the log pings debug option or [`None`] if it hasn't been set.
/// Return the value for the log pings debug option or `false` if it hasn't been set.
///
/// The `log_pings` option may be set from an environment variable (`GLEAN_LOG_PINGS`)
/// or through the [`set_log_pings`] function.
pub(crate) fn log_pings(&self) -> bool {
/// or through the `set_log_pings` function.
pub fn log_pings(&self) -> bool {
self.debug.log_pings.get().copied().unwrap_or(false)
}

View File

@@ -448,21 +448,19 @@ impl Database {
/// Records a metric in the underlying storage system.
pub fn record(&self, glean: &Glean, data: &CommonMetricDataInternal, value: &Metric) {
// If upload is disabled we don't want to record.
if !glean.is_upload_enabled() {
return;
}
let name = data.identifier(glean);
for ping_name in data.storage_names() {
if let Err(e) = self.record_per_lifetime(data.inner.lifetime, ping_name, &name, value) {
log::error!(
"Failed to record metric '{}' into {}: {:?}",
data.base_identifier(),
ping_name,
e
);
if glean.is_ping_enabled(ping_name) {
if let Err(e) =
self.record_per_lifetime(data.inner.lifetime, ping_name, &name, value)
{
log::error!(
"Failed to record metric '{}' into {}: {:?}",
data.base_identifier(),
ping_name,
e
);
}
}
}
}
@@ -518,22 +516,22 @@ impl Database {
where
F: FnMut(Option<Metric>) -> Metric,
{
// If upload is disabled we don't want to record.
if !glean.is_upload_enabled() {
return;
}
let name = data.identifier(glean);
for ping_name in data.storage_names() {
if let Err(e) =
self.record_per_lifetime_with(data.inner.lifetime, ping_name, &name, &mut transform)
{
log::error!(
"Failed to record metric '{}' into {}: {:?}",
data.base_identifier(),
if glean.is_ping_enabled(ping_name) {
if let Err(e) = self.record_per_lifetime_with(
data.inner.lifetime,
ping_name,
e
);
&name,
&mut transform,
) {
log::error!(
"Failed to record metric '{}' into {}: {:?}",
data.base_identifier(),
ping_name,
e
);
}
}
}
}
@@ -658,6 +656,34 @@ impl Database {
})
}
pub fn clear_lifetime_storage(&self, lifetime: Lifetime, storage_name: &str) -> Result<()> {
self.write_with_store(lifetime, |mut writer, store| {
let mut metrics = Vec::new();
{
let mut iter = store.iter_from(&writer, storage_name)?;
while let Some(Ok((metric_id, _))) = iter.next() {
if let Ok(metric_id) = std::str::from_utf8(metric_id) {
if !metric_id.starts_with(storage_name) {
break;
}
metrics.push(metric_id.to_owned());
}
}
}
let mut res = Ok(());
for to_delete in metrics {
if let Err(e) = store.delete(&mut writer, to_delete) {
log::warn!("Can't delete from store: {:?}", e);
res = Err(e);
}
}
measure_commit!(self, writer.commit())?;
Ok(res?)
})
}
/// Removes a single metric from the storage.
///
/// # Arguments

View File

@@ -284,6 +284,10 @@ impl EventDatabase {
{
let mut db = self.event_stores.write().unwrap(); // safe unwrap, only error case is poisoning
for store_name in meta.inner.send_in_pings.iter() {
if !glean.is_ping_enabled(store_name) {
continue;
}
let store = db.entry(store_name.to_string()).or_default();
let execution_counter = CounterMetric::new(CommonMetricData {
name: "execution_counter".into(),
@@ -455,7 +459,7 @@ impl EventDatabase {
.event
.extra
.as_ref()
.map_or(false, |extra| extra.is_empty())
.is_some_and(|extra| extra.is_empty())
{
// Small optimization to save us sending empty dicts.
event.event.extra = None;
@@ -758,7 +762,7 @@ mod test {
let (mut glean, dir) = new_glean(None);
let db = EventDatabase::new(dir.path()).unwrap();
let test_storage = "test-storage";
let test_storage = "store1";
let test_category = "category";
let test_name = "name";
let test_timestamp = 2;

View File

@@ -50,8 +50,11 @@ namespace glean {
void glean_apply_server_knobs_config(string json);
boolean glean_set_debug_view_tag(string tag);
string? glean_get_debug_view_tag();
boolean glean_set_source_tags(sequence<string> tags);
void glean_set_log_pings(boolean value);
boolean glean_get_log_pings();
sequence<string> glean_get_registered_ping_names();
void glean_persist_ping_lifetime_data();
@@ -297,8 +300,20 @@ enum ErrorType {
};
interface PingType {
constructor(string name, boolean include_client_id, boolean send_if_empty, boolean precise_timestamps, boolean include_info_sections, boolean enabled, sequence<string> schedules_pings, sequence<string> reason_codes);
constructor(
string name,
boolean include_client_id,
boolean send_if_empty,
boolean precise_timestamps,
boolean include_info_sections,
boolean enabled,
sequence<string> schedules_pings,
sequence<string> reason_codes,
boolean follows_collection_enabled
);
void submit(optional string? reason = null);
void set_enabled(boolean enabled);
};
// The common set of data shared across all different metric types.

View File

@@ -34,6 +34,7 @@ impl InternalPings {
"dirty_startup".to_string(),
"inactive".to_string(),
],
true,
),
metrics: PingType::new(
"metrics",
@@ -50,6 +51,7 @@ impl InternalPings {
"tomorrow".to_string(),
"upgrade".to_string(),
],
true,
),
events: PingType::new(
"events",
@@ -64,6 +66,7 @@ impl InternalPings {
"inactive".to_string(),
"max_capacity".to_string(),
],
true,
),
deletion_request: PingType::new(
"deletion-request",
@@ -74,6 +77,7 @@ impl InternalPings {
true, // The deletion-request should not be disabled
vec![],
vec!["at_init".to_string(), "set_upload_enabled".to_string()],
true,
),
}
}

View File

@@ -99,6 +99,7 @@ static PRE_INIT_SOURCE_TAGS: Mutex<Vec<String>> = Mutex::new(Vec::new());
/// Keep track of pings registered before Glean is initialized.
static PRE_INIT_PING_REGISTRATION: Mutex<Vec<metrics::PingType>> = Mutex::new(Vec::new());
static PRE_INIT_PING_ENABLED: Mutex<Vec<(metrics::PingType, bool)>> = Mutex::new(Vec::new());
/// Global singleton of the handles of the glean.init threads.
/// For joining. For tests.
@@ -441,6 +442,10 @@ fn initialize_inner(
for ping in pings.iter() {
glean.register_ping_type(ping);
}
let pings = PRE_INIT_PING_ENABLED.lock().unwrap();
for (ping, enabled) in pings.iter() {
glean.set_ping_enabled(ping, *enabled);
}
// If this is the first time ever the Glean SDK runs, make sure to set
// some initial core metrics in case we need to generate early pings.
@@ -819,7 +824,10 @@ pub extern "C" fn glean_enable_logging() {
}
}
/// Sets whether upload is enabled or not.
/// **DEPRECATED** Sets whether upload is enabled or not.
///
/// **DEPRECATION NOTICE**:
/// This API is deprecated. Use `set_collection_enabled` instead.
pub fn glean_set_upload_enabled(enabled: bool) {
if !was_initialize_called() {
return;
@@ -852,6 +860,28 @@ pub fn glean_set_upload_enabled(enabled: bool) {
})
}
/// Sets whether collection is enabled or not.
///
/// This replaces `set_upload_enabled`.
pub fn glean_set_collection_enabled(enabled: bool) {
glean_set_upload_enabled(enabled)
}
/// Enable or disable a ping.
///
/// Disabling a ping causes all data for that ping to be removed from storage
/// and all pending pings of that type to be deleted.
pub fn set_ping_enabled(ping: &PingType, enabled: bool) {
let ping = ping.clone();
if was_initialize_called() {
crate::launch_with_glean_mut(move |glean| glean.set_ping_enabled(&ping, enabled));
} else {
let m = &PRE_INIT_PING_ENABLED;
let mut lock = m.lock().unwrap();
lock.push((ping, enabled));
}
}
/// Register a new [`PingType`](PingType).
pub(crate) fn register_ping_type(ping: &PingType) {
// If this happens after Glean.initialize is called (and returns),
@@ -874,6 +904,22 @@ pub(crate) fn register_ping_type(ping: &PingType) {
}
}
/// Gets a list of currently registered ping names.
///
/// # Returns
///
/// The list of ping names that are currently registered.
pub fn glean_get_registered_ping_names() -> Vec<String> {
block_on_dispatcher();
core::with_glean(|glean| {
glean
.get_registered_ping_names()
.iter()
.map(|ping| ping.to_string())
.collect()
})
}
/// Indicate that an experiment is running. Glean will then add an
/// experiment annotation to the environment which is sent with pings. This
/// infomration is not persisted between runs.
@@ -972,6 +1018,16 @@ pub fn glean_set_debug_view_tag(tag: String) -> bool {
}
}
/// Gets the currently set debug view tag.
///
/// # Returns
///
/// Return the value for the debug view tag or [`None`] if it hasn't been set.
pub fn glean_get_debug_view_tag() -> Option<String> {
block_on_dispatcher();
core::with_glean(|glean| glean.debug_view_tag().map(|tag| tag.to_string()))
}
/// Sets source tags.
///
/// Overrides any existing source tags.
@@ -1018,6 +1074,16 @@ pub fn glean_set_log_pings(value: bool) {
}
}
/// Gets the current log pings value.
///
/// # Returns
///
/// Return the value for the log pings debug option.
pub fn glean_get_log_pings() -> bool {
block_on_dispatcher();
core::with_glean(|glean| glean.log_pings())
}
/// Performs the collection/cleanup operations required by becoming active.
///
/// This functions generates a baseline ping with reason `active`

View File

@@ -7,6 +7,7 @@
use std::collections::HashSet;
use internal_pings::InternalPings;
use serde_json::json;
use super::*;
@@ -19,7 +20,35 @@ pub fn new_glean(tempdir: Option<tempfile::TempDir>) -> (Glean, tempfile::TempDi
None => tempfile::tempdir().unwrap(),
};
let tmpname = dir.path().display().to_string();
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true, true);
let mut glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true, true);
// Register the builtin pings as enabled.
_ = InternalPings::new(true);
// store{1, 2} is used throughout tests
let ping = PingType::new_internal(
"store1",
true,
false,
true,
true,
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping);
let ping = PingType::new_internal(
"store2",
true,
false,
true,
true,
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping);
(glean, dir)
}
@@ -617,6 +646,7 @@ fn test_first_run() {
#[test]
fn test_dirty_bit() {
let _ = env_logger::builder().try_init();
let dir = tempfile::tempdir().unwrap();
let tmpname = dir.path().display().to_string();
{
@@ -1187,6 +1217,7 @@ fn disabled_pings_are_not_submitted() {
false,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping);
@@ -1239,6 +1270,7 @@ fn pings_are_controllable_from_remote_settings_config() {
false,
vec![],
vec![],
true,
);
glean.register_ping_type(&disabled_ping);
let enabled_ping = PingType::new(
@@ -1250,6 +1282,7 @@ fn pings_are_controllable_from_remote_settings_config() {
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&enabled_ping);

View File

@@ -178,10 +178,6 @@ pub trait MetricType {
/// This depends on the metrics own state, as determined by its metadata,
/// and whether upload is enabled on the Glean object.
fn should_record(&self, glean: &Glean) -> bool {
if !glean.is_upload_enabled() {
return false;
}
// Technically nothing prevents multiple calls to should_record() to run in parallel,
// meaning both are reading self.meta().disabled and later writing it. In between it can
// also read remote_settings_config, which also could be modified in between those 2 reads.

View File

@@ -3,6 +3,7 @@
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use std::fmt;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use crate::ping::PingMaker;
@@ -30,11 +31,15 @@ struct InnerPing {
/// Whether to include the {client|ping}_info sections on assembly.
pub include_info_sections: bool,
/// Whether this ping is enabled.
pub enabled: bool,
pub enabled: AtomicBool,
/// Other pings that should be scheduled when this ping is sent.
pub schedules_pings: Vec<String>,
/// The "reason" codes that this ping can send
pub reason_codes: Vec<String>,
/// True when it follows the `collection_enabled` flag (aka `upload_enabled`) flag.
/// Otherwise it needs to be enabled through `enabled_pings`.
follows_collection_enabled: AtomicBool,
}
impl fmt::Debug for PingType {
@@ -45,9 +50,13 @@ impl fmt::Debug for PingType {
.field("send_if_empty", &self.0.send_if_empty)
.field("precise_timestamps", &self.0.precise_timestamps)
.field("include_info_sections", &self.0.include_info_sections)
.field("enabled", &self.0.enabled)
.field("enabled", &self.0.enabled.load(Ordering::Relaxed))
.field("schedules_pings", &self.0.schedules_pings)
.field("reason_codes", &self.0.reason_codes)
.field(
"follows_collection_enabled",
&self.0.follows_collection_enabled.load(Ordering::Relaxed),
)
.finish()
}
}
@@ -80,6 +89,7 @@ impl PingType {
enabled: bool,
schedules_pings: Vec<String>,
reason_codes: Vec<String>,
follows_collection_enabled: bool,
) -> Self {
Self::new_internal(
name,
@@ -90,6 +100,7 @@ impl PingType {
enabled,
schedules_pings,
reason_codes,
follows_collection_enabled,
)
}
@@ -103,6 +114,7 @@ impl PingType {
enabled: bool,
schedules_pings: Vec<String>,
reason_codes: Vec<String>,
follows_collection_enabled: bool,
) -> Self {
let this = Self(Arc::new(InnerPing {
name: name.into(),
@@ -110,9 +122,10 @@ impl PingType {
send_if_empty,
precise_timestamps,
include_info_sections,
enabled,
enabled: AtomicBool::new(enabled),
schedules_pings,
reason_codes,
follows_collection_enabled: AtomicBool::new(follows_collection_enabled),
}));
// Register this ping.
@@ -142,16 +155,47 @@ impl PingType {
self.0.include_info_sections
}
pub(crate) fn enabled(&self, glean: &Glean) -> bool {
let remote_settings_config = &glean.remote_settings_config.lock().unwrap();
/// Enable or disable a ping.
///
/// Disabling a ping causes all data for that ping to be removed from storage
/// and all pending pings of that type to be deleted.
pub fn set_enabled(&self, enabled: bool) {
crate::set_ping_enabled(self, enabled)
}
if !remote_settings_config.pings_enabled.is_empty() {
if let Some(remote_enabled) = remote_settings_config.pings_enabled.get(self.name()) {
return *remote_enabled;
/// Store whether this ping is enabled or not.
///
/// **Note**: For internal use only. Only stores the flag. Does not touch any stored data.
/// Use the public API `PingType::set_enabled` instead.
pub(crate) fn store_enabled(&self, enabled: bool) {
self.0.enabled.store(enabled, Ordering::Release);
}
pub(crate) fn enabled(&self, glean: &Glean) -> bool {
if self.0.follows_collection_enabled.load(Ordering::Relaxed) {
// if this follows collection_enabled:
// 1. check that first. if disabled, we're done
// 2. if enabled, check server-knobs
// 3. If that is not set, fall-through checking the ping
if !glean.is_upload_enabled() {
return false;
}
let remote_settings_config = &glean.remote_settings_config.lock().unwrap();
if !remote_settings_config.pings_enabled.is_empty() {
if let Some(remote_enabled) = remote_settings_config.pings_enabled.get(self.name())
{
return *remote_enabled;
}
}
}
self.0.enabled
self.0.enabled.load(Ordering::Relaxed)
}
pub(crate) fn follows_collection_enabled(&self) -> bool {
self.0.follows_collection_enabled.load(Ordering::Relaxed)
}
pub(crate) fn schedules_pings(&self) -> &[String] {
@@ -194,8 +238,12 @@ impl PingType {
/// Whether the ping was succesfully assembled and queued.
#[doc(hidden)]
pub fn submit_sync(&self, glean: &Glean, reason: Option<&str>) -> bool {
if !glean.is_upload_enabled() {
log::info!("Glean disabled: not submitting any pings.");
if !self.enabled(glean) {
log::info!(
"The ping '{}' is disabled and will be discarded and not submitted",
self.0.name
);
return false;
}

View File

@@ -65,10 +65,6 @@ impl TimespanMetric {
/// Set start time synchronously.
#[doc(hidden)]
pub fn set_start(&self, glean: &Glean, start_time: u64) {
if !self.should_record(glean) {
return;
}
let mut lock = self
.start_time
.write()

View File

@@ -4,8 +4,8 @@
//! Ping collection, assembly & submission.
use std::fs::{create_dir_all, File};
use std::io::Write;
use std::fs::{self, create_dir_all, File};
use std::io::{BufRead, BufReader, Write};
use std::path::{Path, PathBuf};
use log::info;
@@ -66,6 +66,11 @@ impl PingMaker {
/// Gets, and then increments, the sequence number for a given ping.
fn get_ping_seq(&self, glean: &Glean, storage_name: &str) -> usize {
// Don't attempt to increase sequence number for disabled ping
if !glean.is_ping_enabled(storage_name) {
return 0;
}
// Sequence numbers are stored as a counter under a name that includes the storage name
let seq = CounterMetric::new(CommonMetricData {
name: format!("{}#sequence", storage_name),
@@ -404,11 +409,45 @@ impl PingMaker {
}
/// Clears any pending pings in the queue.
pub fn clear_pending_pings(&self, data_path: &Path) -> Result<()> {
pub fn clear_pending_pings(&self, data_path: &Path, ping_names: &[&str]) -> Result<()> {
let pings_dir = self.get_pings_dir(data_path, None)?;
std::fs::remove_dir_all(&pings_dir)?;
create_dir_all(&pings_dir)?;
// TODO(bug 1932909): Refactor this into its own function
// and share it with `upload::directory`.
let entries = pings_dir.read_dir()?;
for entry in entries.filter_map(|entry| entry.ok()) {
if let Ok(file_type) = entry.file_type() {
if !file_type.is_file() {
continue;
}
} else {
continue;
}
let file = match File::open(entry.path()) {
Ok(file) => file,
Err(_) => {
continue;
}
};
let mut lines = BufReader::new(file).lines();
if let (Some(Ok(path)), Some(Ok(_body)), Ok(metadata)) =
(lines.next(), lines.next(), lines.next().transpose())
{
let PingMetadata { ping_name, .. } = metadata
.and_then(|m| crate::upload::process_metadata(&path, &m))
.unwrap_or_default();
let ping_name =
ping_name.unwrap_or_else(|| path.split('/').nth(3).unwrap_or("").into());
if ping_names.contains(&&ping_name[..]) {
_ = fs::remove_file(entry.path());
}
} else {
continue;
}
}
log::debug!("All pending pings deleted");
@@ -426,15 +465,15 @@ mod test {
let (mut glean, _t) = new_glean(None);
let ping_maker = PingMaker::new();
assert_eq!(0, ping_maker.get_ping_seq(&glean, "custom"));
assert_eq!(1, ping_maker.get_ping_seq(&glean, "custom"));
assert_eq!(0, ping_maker.get_ping_seq(&glean, "store1"));
assert_eq!(1, ping_maker.get_ping_seq(&glean, "store1"));
glean.set_upload_enabled(false);
assert_eq!(0, ping_maker.get_ping_seq(&glean, "custom"));
assert_eq!(0, ping_maker.get_ping_seq(&glean, "custom"));
assert_eq!(0, ping_maker.get_ping_seq(&glean, "store1"));
assert_eq!(0, ping_maker.get_ping_seq(&glean, "store1"));
glean.set_upload_enabled(true);
assert_eq!(0, ping_maker.get_ping_seq(&glean, "custom"));
assert_eq!(1, ping_maker.get_ping_seq(&glean, "custom"));
assert_eq!(0, ping_maker.get_ping_seq(&glean, "store1"));
assert_eq!(1, ping_maker.get_ping_seq(&glean, "store1"));
}
}

View File

@@ -134,7 +134,7 @@ fn schedule_internal(
// 3. The ping was NOT collected on the current calendar day BUT we still have
// some time to the due time; schedule for submitting the current calendar day.
let already_sent_today = last_sent_time.map_or(false, |d| d.date() == now.date());
let already_sent_today = last_sent_time.is_some_and(|d| d.date() == now.date());
if already_sent_today {
// Case #1
log::info!("The 'metrics' ping was already sent today, {}", now);

View File

@@ -94,7 +94,7 @@ pub struct PingMetadata {
/// currently it contains only additonal headers to be added to each ping request.
/// Therefore, we will process the contents of this line
/// and return a HeaderMap of the persisted headers.
fn process_metadata(path: &str, metadata: &str) -> Option<PingMetadata> {
pub fn process_metadata(path: &str, metadata: &str) -> Option<PingMetadata> {
if let Ok(metadata) = serde_json::from_str::<PingMetadata>(metadata) {
return Some(metadata);
} else {
@@ -337,7 +337,7 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
let ping_type = PingType::new("test", true, true, true, true, true, vec![], vec![]);
let ping_type = PingType::new("test", true, true, true, true, true, vec![], vec![], true);
glean.register_ping_type(&ping_type);
// Submit the ping to populate the pending_pings directory
@@ -364,7 +364,7 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
let ping_type = PingType::new("test", true, true, true, true, true, vec![], vec![]);
let ping_type = PingType::new("test", true, true, true, true, true, vec![], vec![], true);
glean.register_ping_type(&ping_type);
// Submit the ping to populate the pending_pings directory
@@ -400,7 +400,7 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
let ping_type = PingType::new("test", true, true, true, true, true, vec![], vec![]);
let ping_type = PingType::new("test", true, true, true, true, true, vec![], vec![], true);
glean.register_ping_type(&ping_type);
// Submit the ping to populate the pending_pings directory

View File

@@ -25,6 +25,7 @@ use chrono::Utc;
use crate::error::ErrorKind;
use crate::TimerId;
use crate::{internal_metrics::UploadMetrics, Glean};
pub use directory::process_metadata;
use directory::{PingDirectoryManager, PingPayloadsByDirectory};
use policy::Policy;
use request::create_date_header_value;
@@ -1034,6 +1035,7 @@ mod test {
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping_type);
@@ -1075,6 +1077,7 @@ mod test {
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping_type);
@@ -1114,6 +1117,7 @@ mod test {
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping_type);
@@ -1153,6 +1157,7 @@ mod test {
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping_type);
@@ -1192,6 +1197,7 @@ mod test {
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping_type);
@@ -1233,6 +1239,7 @@ mod test {
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping_type);
@@ -1350,6 +1357,7 @@ mod test {
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping_type);
@@ -1425,6 +1433,7 @@ mod test {
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping_type);
@@ -1484,6 +1493,7 @@ mod test {
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping_type);
@@ -1564,6 +1574,7 @@ mod test {
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping_type);
@@ -1645,6 +1656,7 @@ mod test {
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping_type);
@@ -1728,6 +1740,7 @@ mod test {
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping_type);

View File

@@ -0,0 +1,223 @@
// 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 https://mozilla.org/MPL/2.0/.
mod common;
use crate::common::*;
use glean_core::metrics::*;
use glean_core::CommonMetricData;
use glean_core::Glean;
use glean_core::Lifetime;
fn nofollows_ping(glean: &mut Glean) -> PingType {
// When `follows_collection_enabled=false` then by default `enabled=false`
let ping = PingType::new(
"nofollows",
/* include_client_id */ false,
/* send_if_empty */ true,
/* precise_timestamps */ true,
/* include_info_sections */ false,
/* enabled */ false,
vec![],
vec![],
/* follows_collection_enabled */ false,
);
glean.register_ping_type(&ping);
ping
}
fn manual_ping(glean: &mut Glean) -> PingType {
let ping = PingType::new(
"manual",
/* include_client_id */ true,
/* send_if_empty */ false,
/* precise_timestamps */ true,
/* include_info_sections */ true,
/* enabled */ true,
vec![],
vec![],
/* collection_enabled */ true,
);
glean.register_ping_type(&ping);
ping
}
#[test]
fn pings_with_follows_false_are_exempt() {
let (mut glean, _t) = new_glean(None);
let ping = nofollows_ping(&mut glean);
// We need to store a metric as an empty ping is not stored.
let counter = CounterMetric::new(CommonMetricData {
name: "counter".into(),
category: "local".into(),
send_in_pings: vec!["nofollows".into()],
..Default::default()
});
counter.add_sync(&glean, 1);
assert!(!ping.submit_sync(&glean, None));
glean.set_ping_enabled(&ping, true);
counter.add_sync(&glean, 2);
assert!(ping.submit_sync(&glean, None));
let mut queued_pings = get_queued_pings(glean.get_data_path()).unwrap();
assert_eq!(1, queued_pings.len());
let json = queued_pings.pop().unwrap().1;
let counter_val = json["metrics"]["counter"]["local.counter"]
.as_i64()
.unwrap();
assert_eq!(2, counter_val);
glean.set_upload_enabled(false);
assert_eq!(1, get_queued_pings(glean.get_data_path()).unwrap().len());
// Disabling upload generates a deletion ping
assert_eq!(1, get_deletion_pings(glean.get_data_path()).unwrap().len());
// Regardless, the `nofollows` ping is still enabled.
counter.add_sync(&glean, 10);
assert!(ping.submit_sync(&glean, None));
let queued_pings = get_queued_pings(glean.get_data_path()).unwrap();
// both `nofollows` pings remain in the queue
assert_eq!(2, queued_pings.len());
let mut values = vec![2, 10];
for ping in queued_pings {
let json = ping.1;
let counter_val = json["metrics"]["counter"]["local.counter"]
.as_i64()
.unwrap();
assert!(values.contains(&counter_val));
values.retain(|&x| x != counter_val);
}
}
#[test]
fn nofollows_ping_can_ride_along() {
let (mut glean, _t) = new_glean(None);
let nofollows_ping = nofollows_ping(&mut glean);
// Basically `manual_ping` but with a ride-along
let manual_ping = PingType::new(
"manual",
/* include_client_id */ true,
/* send_if_empty */ false,
/* precise_timestamps */ true,
/* include_info_sections */ true,
/* enabled */ true,
vec!["nofollows".to_string()],
vec![],
/* collection_enabled */ true,
);
glean.register_ping_type(&manual_ping);
// We need to store a metric as an empty ping is not stored.
let counter = CounterMetric::new(CommonMetricData {
name: "counter".into(),
category: "local".into(),
send_in_pings: vec!["manual".into(), "nofollows".into()],
lifetime: Lifetime::Application,
..Default::default()
});
// Trigger a ping with data.
counter.add_sync(&glean, 1);
assert!(manual_ping.submit_sync(&glean, None));
assert_eq!(1, get_queued_pings(glean.get_data_path()).unwrap().len());
// Enable one more ping, trigger it with more data
glean.set_ping_enabled(&nofollows_ping, true);
counter.add_sync(&glean, 2);
assert!(manual_ping.submit_sync(&glean, None));
// The previous one, plus 2 new ones
let queued_pings = get_queued_pings(glean.get_data_path()).unwrap();
assert_eq!(3, queued_pings.len());
for (_url, json, info) in queued_pings {
let Some(obj) = info else {
panic!("no ping info")
};
let counter_val = json["metrics"]["counter"]["local.counter"]
.as_i64()
.unwrap();
if obj["ping_name"].as_str().unwrap() == "nofollows" {
assert_eq!(2, counter_val, "{:?}", json);
} else {
let seq = json["ping_info"]["seq"].as_i64().unwrap();
match seq {
0 => assert_eq!(1, counter_val),
1 => assert_eq!(3, counter_val),
2 => assert_eq!(8, counter_val),
_ => panic!("unexpected sequence number: {}", seq),
}
}
}
// Disable it again
glean.set_ping_enabled(&nofollows_ping, false);
counter.add_sync(&glean, 5);
assert!(manual_ping.submit_sync(&glean, None));
let queued_pings = get_queued_pings(glean.get_data_path()).unwrap();
// The 2 previous `manual` pings, the `nofollows` was removed, plus the new `manual` one
assert_eq!(3, queued_pings.len());
// Check that all follows are as expected.
// We cannot guarantee order, so we need to look at some values
for (_url, json, info) in queued_pings {
let Some(obj) = info else {
panic!("no ping info")
};
let counter_val = json["metrics"]["counter"]["local.counter"]
.as_i64()
.unwrap();
assert_ne!("nofollows", obj["ping_name"].as_str().unwrap());
let seq = json["ping_info"]["seq"].as_i64().unwrap();
match seq {
0 => assert_eq!(1, counter_val),
1 => assert_eq!(3, counter_val),
2 => assert_eq!(8, counter_val),
_ => panic!("unexpected sequence number: {}", seq),
}
}
}
#[test]
fn queued_nofollows_pings_are_not_removed() {
let (mut glean, t) = new_glean(None);
let nofollows_ping = nofollows_ping(&mut glean);
let manual_ping = manual_ping(&mut glean);
glean.set_ping_enabled(&nofollows_ping, true);
// We need to store a metric as an empty ping is not stored.
let counter = CounterMetric::new(CommonMetricData {
name: "counter".into(),
category: "local".into(),
send_in_pings: vec!["manual".into(), "nofollows".into()],
lifetime: Lifetime::Application,
..Default::default()
});
// Trigger a ping with data.
counter.add_sync(&glean, 1);
assert!(manual_ping.submit_sync(&glean, None));
assert!(nofollows_ping.submit_sync(&glean, None));
assert_eq!(2, get_queued_pings(glean.get_data_path()).unwrap().len());
glean.set_upload_enabled(false);
assert_eq!(1, get_queued_pings(glean.get_data_path()).unwrap().len());
// Ping is still there after a Glean restart
let (glean, _t) = new_glean(Some(t));
assert_eq!(1, get_queued_pings(glean.get_data_path()).unwrap().len());
}

View File

@@ -5,7 +5,7 @@
// #[allow(dead_code)] is required on this module as a workaround for
// https://github.com/rust-lang/rust/issues/46379
#![allow(dead_code)]
use glean_core::{Glean, Result};
use glean_core::{Glean, PingType, Result};
use std::fs::{read_dir, File};
use std::io::{BufRead, BufReader};
@@ -68,11 +68,21 @@ pub fn new_glean(tempdir: Option<tempfile::TempDir>) -> (Glean, tempfile::TempDi
ping_lifetime_threshold: 0,
ping_lifetime_max_time: 0,
};
let glean = Glean::new(cfg).unwrap();
let mut glean = Glean::new(cfg).unwrap();
// store{1,2} is used throughout tests
_ = new_test_ping(&mut glean, "store1");
_ = new_test_ping(&mut glean, "store2");
(glean, dir)
}
pub fn new_test_ping(glean: &mut Glean, name: &str) -> PingType {
let ping = PingType::new(name, true, false, true, true, true, vec![], vec![], true);
glean.register_ping_type(&ping);
ping
}
/// Converts an iso8601::DateTime to a chrono::DateTime<FixedOffset>
pub fn iso8601_to_chrono(datetime: &iso8601::DateTime) -> chrono::DateTime<chrono::FixedOffset> {
if let YMD { year, month, day } = datetime.date {

View File

@@ -10,10 +10,10 @@ use std::fs;
use serde_json::json;
use glean_core::metrics::*;
use glean_core::{
get_timestamp_ms, test_get_num_recorded_errors, CommonMetricData, ErrorType, Lifetime,
};
use glean_core::{metrics::*, Glean};
#[test]
fn record_properly_records_without_optional_arguments() {
@@ -172,6 +172,7 @@ fn test_sending_of_event_ping_when_it_fills_up() {
true,
vec![],
vec!["max_capacity".to_string()],
true,
));
}
@@ -239,6 +240,7 @@ fn test_server_knobs_config_changing_max_events() {
true,
vec![],
vec!["max_capacity".to_string()],
true,
));
}
@@ -396,7 +398,7 @@ fn snapshot_sorts_the_timestamps() {
fn ensure_custom_ping_events_dont_overflow() {
let (glean, _dir) = new_glean(None);
let store_name = "store-name";
let store_name = "store1";
let event_meta = CommonMetricData {
name: "name".into(),
category: "category".into(),
@@ -441,7 +443,7 @@ fn ensure_custom_ping_events_dont_overflow() {
fn ensure_custom_ping_events_from_multiple_runs_work() {
let (mut tempdir, _) = tempdir();
let store_name = "store-name";
let store_name = "store1";
let event = EventMetric::new(
CommonMetricData {
name: "name".into(),
@@ -507,27 +509,12 @@ fn event_storage_trimming() {
},
vec![],
);
// First, record the event in the two pings.
// Successfully records just fine because nothing's checking on record that these pings
// exist and are registered.
{
let (glean, dir) = new_glean(Some(tempdir));
tempdir = dir;
event.record_sync(&glean, 10, HashMap::new(), 0);
assert_eq!(1, event.get_value(&glean, store_name).unwrap().len());
assert_eq!(1, event.get_value(&glean, store_name_2).unwrap().len());
}
// Second, construct (but don't init) Glean over again.
// Register exactly one of the two pings.
// Then process the part of init that does the trimming (`on_ready_to_submit_pings`).
// This ought to load the data from the registered ping and trim the data from the unregistered one.
{
let (mut glean, _dir) = new_glean(Some(tempdir));
let new_ping = |glean: &mut Glean, ping: &str| {
// In Rust, pings are registered via construction.
// But that's done asynchronously, so we do it synchronously here:
glean.register_ping_type(&PingType::new(
store_name.to_string(),
ping.to_string(),
true,
false,
true,
@@ -535,7 +522,29 @@ fn event_storage_trimming() {
true,
vec![],
vec![],
true,
));
};
// First, register both pings, so that we can record the event in the two pings.
{
let (mut glean, dir) = new_glean(Some(tempdir));
tempdir = dir;
new_ping(&mut glean, store_name);
new_ping(&mut glean, store_name_2);
event.record_sync(&glean, 10, HashMap::new(), 0);
assert_eq!(1, event.get_value(&glean, store_name).unwrap().len());
assert_eq!(1, event.get_value(&glean, store_name_2).unwrap().len());
}
// Second, construct (but don't init) Glean again.
// Register exactly one of the two pings.
// Then process the part of init that does the trimming (`on_ready_to_submit_pings`).
{
let (mut glean, _dir) = new_glean(Some(tempdir));
new_ping(&mut glean, store_name);
glean.on_ready_to_submit_pings(true);
@@ -568,9 +577,21 @@ fn with_event_timestamps() {
ping_lifetime_threshold: 0,
ping_lifetime_max_time: 0,
};
let glean = Glean::new(cfg).unwrap();
let mut glean = Glean::new(cfg).unwrap();
let ping = PingType::new(
"store1",
true,
false,
true,
true,
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping);
let store_name = "store-name";
let store_name = "store1";
let event = EventMetric::new(
CommonMetricData {
name: "name".into(),

View File

@@ -16,14 +16,13 @@ use glean_core::Lifetime;
fn write_ping_to_disk() {
let (mut glean, _temp) = new_glean(None);
let ping = PingType::new("metrics", true, false, true, true, true, vec![], vec![]);
glean.register_ping_type(&ping);
let ping = new_test_ping(&mut glean, "store1");
// We need to store a metric as an empty ping is not stored.
let counter = CounterMetric::new(CommonMetricData {
name: "counter".into(),
category: "local".into(),
send_in_pings: vec!["metrics".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
});
counter.add_sync(&glean, 1);
@@ -37,14 +36,13 @@ fn write_ping_to_disk() {
fn disabling_upload_clears_pending_pings() {
let (mut glean, _t) = new_glean(None);
let ping = PingType::new("metrics", true, false, true, true, true, vec![], vec![]);
glean.register_ping_type(&ping);
let ping = new_test_ping(&mut glean, "store1");
// We need to store a metric as an empty ping is not stored.
let counter = CounterMetric::new(CommonMetricData {
name: "counter".into(),
category: "local".into(),
send_in_pings: vec!["metrics".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
});
@@ -106,7 +104,17 @@ fn deletion_request_only_when_toggled_from_on_to_off() {
fn empty_pings_with_flag_are_sent() {
let (mut glean, _t) = new_glean(None);
let ping1 = PingType::new("custom-ping1", true, true, true, true, true, vec![], vec![]);
let ping1 = PingType::new(
"custom-ping1",
true,
true,
true,
true,
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping1);
let ping2 = PingType::new(
"custom-ping2",
@@ -117,6 +125,7 @@ fn empty_pings_with_flag_are_sent() {
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping2);
@@ -151,11 +160,8 @@ fn test_pings_submitted_metric() {
None,
);
let metrics_ping = PingType::new("metrics", true, false, true, true, true, vec![], vec![]);
glean.register_ping_type(&metrics_ping);
let baseline_ping = PingType::new("baseline", true, false, true, true, true, vec![], vec![]);
glean.register_ping_type(&baseline_ping);
let metrics_ping = new_test_ping(&mut glean, "metrics");
let baseline_ping = new_test_ping(&mut glean, "baseline");
// We need to store a metric as an empty ping is not stored.
let counter = CounterMetric::new(CommonMetricData {
@@ -230,8 +236,7 @@ fn test_pings_submitted_metric() {
fn events_ping_with_metric_but_no_events_is_not_sent() {
let (mut glean, _t) = new_glean(None);
let events_ping = PingType::new("events", true, true, true, true, true, vec![], vec![]);
glean.register_ping_type(&events_ping);
let events_ping = new_test_ping(&mut glean, "events");
let counter = CounterMetric::new(CommonMetricData {
name: "counter".into(),
category: "local".into(),
@@ -264,7 +269,17 @@ fn events_ping_with_metric_but_no_events_is_not_sent() {
fn test_scheduled_pings_are_sent() {
let (mut glean, _t) = new_glean(None);
let piggyback_ping = PingType::new("piggyback", true, true, true, true, true, vec![], vec![]);
let piggyback_ping = PingType::new(
"piggyback",
true,
true,
true,
true,
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&piggyback_ping);
let trigger_ping = PingType::new(
@@ -276,6 +291,7 @@ fn test_scheduled_pings_are_sent() {
true,
vec!["piggyback".into()],
vec![],
true,
);
glean.register_ping_type(&trigger_ping);
@@ -288,7 +304,7 @@ fn test_scheduled_pings_are_sent() {
fn database_write_timings_get_recorded() {
let (mut glean, _t) = new_glean(None);
let metrics_ping = PingType::new("metrics", true, false, true, true, true, vec![], vec![]);
let metrics_ping = new_test_ping(&mut glean, "metrics");
glean.register_ping_type(&metrics_ping);
// We need to store a metric to record something.

View File

@@ -13,8 +13,7 @@ fn set_up_basic_ping() -> (Glean, PingMaker, PingType, tempfile::TempDir) {
let (tempdir, _) = tempdir();
let (mut glean, t) = new_glean(Some(tempdir));
let ping_maker = PingMaker::new();
let ping_type = PingType::new("store1", true, false, true, true, true, vec![], vec![]);
glean.register_ping_type(&ping_type);
let ping_type = new_test_ping(&mut glean, "store1");
// Record something, so the ping will have data
let metric = BooleanMetric::new(CommonMetricData {
@@ -98,7 +97,17 @@ fn test_metrics_must_report_experimentation_id() {
})
.unwrap();
let ping_maker = PingMaker::new();
let ping_type = PingType::new("store1", true, false, true, true, true, vec![], vec![]);
let ping_type = PingType::new(
"store1",
true,
false,
true,
true,
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping_type);
// Record something, so the ping will have data
@@ -155,7 +164,17 @@ fn experimentation_id_is_removed_if_send_if_empty_is_false() {
.unwrap();
let ping_maker = PingMaker::new();
let unknown_ping_type = PingType::new("unknown", true, false, true, true, true, vec![], vec![]);
let unknown_ping_type = PingType::new(
"unknown",
true,
false,
true,
true,
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&unknown_ping_type);
assert!(ping_maker
@@ -171,7 +190,17 @@ fn collect_must_report_none_when_no_data_is_stored() {
let (mut glean, ping_maker, ping_type, _t) = set_up_basic_ping();
let unknown_ping_type = PingType::new("unknown", true, false, true, true, true, vec![], vec![]);
let unknown_ping_type = PingType::new(
"unknown",
true,
false,
true,
true,
true,
vec![],
vec![],
true,
);
glean.register_ping_type(&ping_type);
assert!(ping_maker
@@ -181,7 +210,7 @@ fn collect_must_report_none_when_no_data_is_stored() {
#[test]
fn seq_number_must_be_sequential() {
let (glean, ping_maker, _ping_type, _t) = set_up_basic_ping();
let (mut glean, ping_maker, _ping_type, _t) = set_up_basic_ping();
let metric = BooleanMetric::new(CommonMetricData {
name: "boolean_metric".into(),
@@ -195,8 +224,17 @@ fn seq_number_must_be_sequential() {
for i in 0..=1 {
for ping_name in ["store1", "store2"].iter() {
let ping_type =
PingType::new(*ping_name, true, false, true, true, true, vec![], vec![]);
let ping_type = PingType::new(
*ping_name,
true,
false,
true,
true,
true,
vec![],
vec![],
true,
);
let ping = ping_maker
.collect(&glean, &ping_type, None, "", "")
.unwrap();
@@ -209,7 +247,7 @@ fn seq_number_must_be_sequential() {
// Test that ping sequence numbers increase independently.
{
let ping_type = PingType::new("store1", true, false, true, true, true, vec![], vec![]);
let ping_type = new_test_ping(&mut glean, "store1");
// 3rd ping of store1
let ping = ping_maker
@@ -227,7 +265,7 @@ fn seq_number_must_be_sequential() {
}
{
let ping_type = PingType::new("store2", true, false, true, true, true, vec![], vec![]);
let ping_type = new_test_ping(&mut glean, "store2");
// 3rd ping of store2
let ping = ping_maker
@@ -238,7 +276,7 @@ fn seq_number_must_be_sequential() {
}
{
let ping_type = PingType::new("store1", true, false, true, true, true, vec![], vec![]);
let ping_type = new_test_ping(&mut glean, "store1");
// 5th ping of store1
let ping = ping_maker
@@ -253,8 +291,7 @@ fn seq_number_must_be_sequential() {
fn clear_pending_pings() {
let (mut glean, _t) = new_glean(None);
let ping_maker = PingMaker::new();
let ping_type = PingType::new("store1", true, false, true, true, true, vec![], vec![]);
glean.register_ping_type(&ping_type);
let ping_type = new_test_ping(&mut glean, "store1");
// Record something, so the ping will have data
let metric = BooleanMetric::new(CommonMetricData {
@@ -270,8 +307,9 @@ fn clear_pending_pings() {
assert!(ping_type.submit_sync(&glean, None));
assert_eq!(1, get_queued_pings(glean.get_data_path()).unwrap().len());
let disabled_pings = &["store1"][..];
assert!(ping_maker
.clear_pending_pings(glean.get_data_path())
.clear_pending_pings(glean.get_data_path(), disabled_pings)
.is_ok());
assert_eq!(0, get_queued_pings(glean.get_data_path()).unwrap().len());
}
@@ -281,7 +319,7 @@ fn no_pings_submitted_if_upload_disabled() {
// Regression test, bug 1603571
let (mut glean, _t) = new_glean(None);
let ping_type = PingType::new("store1", true, true, true, true, true, vec![], vec![]);
let ping_type = PingType::new("store1", true, true, true, true, true, vec![], vec![], true);
glean.register_ping_type(&ping_type);
assert!(ping_type.submit_sync(&glean, None));
@@ -299,7 +337,7 @@ fn no_pings_submitted_if_upload_disabled() {
fn metadata_is_correctly_added_when_necessary() {
let (mut glean, _t) = new_glean(None);
glean.set_debug_view_tag("valid-tag");
let ping_type = PingType::new("store1", true, true, true, true, true, vec![], vec![]);
let ping_type = PingType::new("store1", true, true, true, true, true, vec![], vec![], true);
glean.register_ping_type(&ping_type);
assert!(ping_type.submit_sync(&glean, None));

View File

@@ -16,7 +16,7 @@ fn rate_smoke() {
let metric: RateMetric = RateMetric::new(CommonMetricData {
name: "rate".into(),
category: "test".into(),
send_in_pings: vec!["test1".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
});
@@ -52,7 +52,7 @@ fn numerator_smoke() {
let metric: NumeratorMetric = NumeratorMetric::new(CommonMetricData {
name: "rate".into(),
category: "test".into(),
send_in_pings: vec!["test1".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
});
@@ -89,14 +89,14 @@ fn denominator_smoke() {
let meta1 = CommonMetricData {
name: "rate1".into(),
category: "test".into(),
send_in_pings: vec!["test1".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
};
let meta2 = CommonMetricData {
name: "rate2".into(),
category: "test".into(),
send_in_pings: vec!["test1".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
};
@@ -105,7 +105,7 @@ fn denominator_smoke() {
CommonMetricData {
name: "counter".into(),
category: "test".into(),
send_in_pings: vec!["test1".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
},
vec![meta1.clone(), meta2.clone()],

View File

@@ -26,14 +26,14 @@ fn can_snapshot() {
let local_metric = StringMetric::new(CommonMetricData {
name: "can_snapshot_local_metric".into(),
category: "local".into(),
send_in_pings: vec!["store".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
});
local_metric.set_sync(&glean, "snapshot 42");
assert!(StorageManager
.snapshot(glean.storage(), "store", true)
.snapshot(glean.storage(), "store1", true)
.is_some())
}
@@ -77,7 +77,7 @@ fn storage_is_thread_safe() {
let threadsafe_metric = CounterMetric::new(CommonMetricData {
name: "threadsafe".into(),
category: "global".into(),
send_in_pings: vec!["core".into(), "metrics".into()],
send_in_pings: vec!["store1".into(), "metrics".into()],
..Default::default()
});
let threadsafe_metric = Arc::new(threadsafe_metric);
@@ -99,7 +99,7 @@ fn storage_is_thread_safe() {
child.join().unwrap();
let snapshot = StorageManager
.snapshot_as_json(glean.lock().unwrap().storage(), "core", true)
.snapshot_as_json(glean.lock().unwrap().storage(), "store1", true)
.unwrap();
assert_eq!(json!({"counter": { "global.threadsafe": 4 }}), snapshot);
}

View File

@@ -18,25 +18,25 @@ fn list_can_store_multiple_items() {
let list: StringListMetric = StringListMetric::new(CommonMetricData {
name: "list".into(),
category: "local".into(),
send_in_pings: vec!["core".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
});
list.add_sync(&glean, "first");
assert_eq!(list.get_value(&glean, "core").unwrap(), vec!["first"]);
assert_eq!(list.get_value(&glean, "store1").unwrap(), vec!["first"]);
list.add_sync(&glean, "second");
assert_eq!(
list.get_value(&glean, "core").unwrap(),
list.get_value(&glean, "store1").unwrap(),
vec!["first", "second"]
);
list.set_sync(&glean, vec!["third".into()]);
assert_eq!(list.get_value(&glean, "core").unwrap(), vec!["third"]);
assert_eq!(list.get_value(&glean, "store1").unwrap(), vec!["third"]);
list.add_sync(&glean, "fourth");
assert_eq!(
list.get_value(&glean, "core").unwrap(),
list.get_value(&glean, "store1").unwrap(),
vec!["third", "fourth"]
);
}

View File

@@ -284,7 +284,7 @@ fn set_raw_time_does_nothing_when_timer_running() {
}
#[test]
fn timespan_is_not_tracked_across_upload_toggle() {
fn timespan_is_tracked_across_upload_toggle() {
let (mut glean, _t) = new_glean(None);
let metric = TimespanMetric::new(
@@ -307,23 +307,20 @@ fn timespan_is_not_tracked_across_upload_toggle() {
// We should clear internal state as upload is disabled.
metric.set_stop(&glean, 40);
assert_eq!(None, metric.get_value(&glean, "store1"));
// App code eventually starts the timer again.
// Upload is disabled, so this should not have any effect.
metric.set_start(&glean, 100);
// User enables telemetry upload again.
glean.set_upload_enabled(true);
// App code eventually stops the timer.
// None should be running.
// The full timespan is recorded.
metric.set_stop(&glean, 200);
// Nothing should have been recorded.
assert_eq!(None, metric.get_value(&glean, "store1"));
assert_eq!(Some(100), metric.get_value(&glean, "store1"));
// Make sure that the error has been recorded
assert_eq!(
Ok(1),
test_get_num_recorded_errors(&glean, metric.meta(), ErrorType::InvalidState)
);
// No errors have been recorded.
assert!(test_get_num_recorded_errors(&glean, metric.meta(), ErrorType::InvalidState).is_err());
}
#[test]
@@ -334,7 +331,7 @@ fn time_cannot_go_backwards() {
CommonMetricData {
name: "raw_timespan".into(),
category: "test".into(),
send_in_pings: vec!["test1".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
},
TimeUnit::Millisecond,
@@ -343,7 +340,7 @@ fn time_cannot_go_backwards() {
// Time cannot go backwards.
metric.set_start(&glean, 10);
metric.set_stop(&glean, 0);
assert!(metric.get_value(&glean, "test1").is_none());
assert!(metric.get_value(&glean, "store1").is_none());
assert_eq!(
Ok(1),
test_get_num_recorded_errors(&glean, metric.meta(), ErrorType::InvalidValue),

View File

@@ -427,3 +427,49 @@ fn raw_samples_api_error_cases() {
test_get_num_recorded_errors(&glean, metric.meta(), ErrorType::InvalidOverflow)
);
}
#[test]
fn timing_distribution_is_tracked_across_upload_toggle() {
let (mut glean, _t) = new_glean(None);
let metric = TimingDistributionMetric::new(
CommonMetricData {
name: "distribution".into(),
category: "telemetry".into(),
send_in_pings: vec!["store1".into()],
disabled: false,
lifetime: Lifetime::Ping,
..Default::default()
},
TimeUnit::Nanosecond,
);
let id = 4u64.into();
let duration = 100;
// Timer is started.
metric.set_start(id, 0);
// User disables telemetry upload.
glean.set_upload_enabled(false);
// App code eventually stops the timer.
// We should clear internal state as upload is disabled.
metric.set_stop_and_accumulate(&glean, id, duration);
assert_eq!(None, metric.get_value(&glean, "store1"));
// App code eventually starts the timer again.
// Upload is disabled, so this should not have any effect.
metric.set_start(id, 100);
// User enables telemetry upload again.
glean.set_upload_enabled(true);
// App code eventually stops the timer.
// The full timespan is recorded.
metric.set_stop_and_accumulate(&glean, id, 100 + duration);
let data = metric.get_value(&glean, "store1").unwrap();
assert_eq!(1, data.count);
assert_eq!(100, data.sum);
// Make sure that the error has been recorded
assert!(test_get_num_recorded_errors(&glean, metric.meta(), ErrorType::InvalidState).is_err());
}

View File

@@ -18,19 +18,19 @@ fn uuid_is_generated_and_stored() {
let uuid: UuidMetric = UuidMetric::new(CommonMetricData {
name: "uuid".into(),
category: "local".into(),
send_in_pings: vec!["core".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
});
uuid.generate_and_set_sync(&glean);
let snapshot = glean.snapshot("core", false);
let snapshot = glean.snapshot("store1", false);
assert!(
snapshot.contains(r#""local.uuid": ""#),
"Snapshot 1: {snapshot}"
);
uuid.generate_and_set_sync(&glean);
let snapshot = glean.snapshot("core", false);
let snapshot = glean.snapshot("store1", false);
assert!(
snapshot.contains(r#""local.uuid": ""#),
"Snapshot 2: {snapshot}"

View File

@@ -1 +1 @@
{"files":{"Cargo.toml":"7782cf096165d157ec0bdcee7cd1ee413bef18b9538715143f20c04f47982ebe","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"5627cc81e6187ab6c2b4dff061af16d559edcab64ba786bac39daa69c703c595","src/common_test.rs":"de47b53dcca37985c0a2b8c02daecbf32309aa54f5a4dd9290719c2c1fd0fa55","src/configuration.rs":"de65ab99a26b4547be20803bc195cb50a6ab40b1a3f49a2e6230fed5a9d7a8d8","src/core_metrics.rs":"fef8fb4e5fa57c179836c6eb2cf59278fe3b8b036dbe57b0ff02971b4acd822f","src/lib.rs":"23a99cf0fc4f39d079257b03092fd89c5150a87659e8ad70d6a3c6868c372c6b","src/net/http_uploader.rs":"01ad5bd91384411a12c74434cd1c5cd585078cb34faba4615c70bdb669a9bccb","src/net/mod.rs":"f47b96bb878f1a6c771cedbaeaeefb270bc87fb1d1bbbed1b282dddca16216ed","src/private/event.rs":"d7c70c02648584c19c73af89e5180d3c6153c911f2c6830f7d1599b18d6150eb","src/private/mod.rs":"66e90c41de74d1e80c5d3f49b8f1a86b8396be0b8c4a80f1a28903fe6d105ecf","src/private/object.rs":"0926261074af905c775494b42217f636548e74c3ad798478481bc0cd2fdf5c48","src/private/ping.rs":"31d33d7f661a7a17ccb69351328700b4d7b80024d1e128f406c3534f9d163475","src/system.rs":"6eae5b41c15eba9cad6dbd116abe3519ee3e1fe034e79bdd692b029829a8c384","src/test.rs":"d7ad78bd853b2b22e3740fb8d3c15675286d3a050a7bfb586dbbe7003f74c388","tests/common/mod.rs":"08fb9483d9b6ed9fe873b4395245166ae8a15263be750c7a8e298c41d9604745","tests/custom_distribution_buffered.rs":"be8d9465dbcc222ecc6b00922feb36e659a2a32187a271ecb3f8855e6651a925","tests/init_fails.rs":"46d7064bba9386c3065635434e17ac9212c6c2236b3cd12bd985fc3229e659a3","tests/memory_distribution_buffered.rs":"44246a5ef00b28da3446ae3705169f9d7f87f54514798880a8a447f2055929c8","tests/never_init.rs":"7a6e8a011fbd945f2544f204367eeceff3f6039c99d98799477e3b2352ae6227","tests/no_time_to_init.rs":"4a5bdddc2f8226d2ad17038229e8767a6dd195977af49527fbb84a9f6b0154bb","tests/overflowing_preinit.rs":"985e140460a100986fd051ce901b787a3a7a9747a856cd06066b740ac7d2381c","tests/persist_ping_lifetime_nopanic.rs":"18379d3ffbf4a2c8c684c04ff7a0660b86dfbbb447db2d24dfed6073cb7ddf8f","tests/schema.rs":"dde65bce8a715ca3bd9c54b2466d831dd5e0d559e0773fe7657827f22a66bb44","tests/simple.rs":"1835b5df6f76ff894b45805bd54eaab23ca2d9d2b0694ec64af3aa6132baf30e","tests/test-delayed-ping-data.sh":"4a6db98b4df6b77898ace6a8b4e8b4c60d3e5c44873bbf38c62e83583e27a3ff","tests/test-ping-lifetime-flush.sh":"e8f118ea2f6fd973809e38d5e828a03cfccfe0b0f497ccde5ec92d6d1380c071","tests/test-shutdown-blocking.sh":"a44d8d4bbe2ee3ede9e48121150ae7a5386025160c5cef2181ca142232c5fb27","tests/test-thread-crashing.sh":"f3cd0cc8a7b4fe82bef0fe6fbfbbe45fbad6da3afe0f82578bc5cfb2d6527ac6","tests/timing_distribution_buffered.rs":"c895988e56d285a9eeb6a0b7c4e2d7c622961f2896bdee4c0809246d02ea92ef","tests/timing_distribution_single_sample.rs":"fddf2f13f1620a8808029d250a64e4c822828bf80b4bb4f9e3b645ab70643f9b","tests/upload_timing.rs":"6a97aa355d808123af0914ffecf1da0ecb2cc441c95c63c600b14f97ce0d45a0"},"package":"a8e7570fa2e6eb6065e3f119e227f9c269742c9132cc954c9c05e371d07d14ab"}
{"files":{"Cargo.toml":"c6e036285c5bea054fb7c00aea547325ad9eaee16ca56fad28f15439438dcd81","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"5627cc81e6187ab6c2b4dff061af16d559edcab64ba786bac39daa69c703c595","src/common_test.rs":"997f5331b719f82d86bb5e2f8e711da9cfb9433403e233c04a0ff39c3de5f7d0","src/configuration.rs":"de65ab99a26b4547be20803bc195cb50a6ab40b1a3f49a2e6230fed5a9d7a8d8","src/core_metrics.rs":"fef8fb4e5fa57c179836c6eb2cf59278fe3b8b036dbe57b0ff02971b4acd822f","src/lib.rs":"aac38f06ca2f98ff566d901fea8a4709e79fa15a4978b178026af49dcfd3f871","src/net/http_uploader.rs":"01ad5bd91384411a12c74434cd1c5cd585078cb34faba4615c70bdb669a9bccb","src/net/mod.rs":"5dff006240a6522e1db988514f22fb9361b3dece0c22fcf9eb8ff1b3308dd8f0","src/private/event.rs":"9dbfa7ca57e39e2679c43783afea7f573c1cbac0e4ebda04553b0f91a69f2801","src/private/mod.rs":"66e90c41de74d1e80c5d3f49b8f1a86b8396be0b8c4a80f1a28903fe6d105ecf","src/private/object.rs":"2fc159521facf66e6a27237ad17acd0b27ba48c2688e36eeca8cbb0bd1e15d60","src/private/ping.rs":"86dea260ed298dc74c9f2d35b82782203e0212af3125e3ce0194064c759c916f","src/system.rs":"6eae5b41c15eba9cad6dbd116abe3519ee3e1fe034e79bdd692b029829a8c384","src/test.rs":"7c5f67bdce46bdb14b77cde0b716c2c2e0ab831e6c01b2e417c348c562289cac","tests/common/mod.rs":"68b0fca253f5c773cdb54d10a02d324d7c74ed5e16d4ba96387e4b643af2c0f3","tests/custom_distribution_buffered.rs":"47c13d1f39adf3881e10caa19e0c08235f08958809e234bf37a79d37d7322cd5","tests/init_fails.rs":"073b8c244ecbcae8e9cfc12cffd0629038bd978a4a4337073dbed6866023317b","tests/interruptible_shutdown.rs":"17b674c5960f3787ba0c51dc54f0c3759403427ad819985ad85f254e261002ab","tests/memory_distribution_buffered.rs":"db487475a5cf17a0864ccf150984ebdd28bf616573772cf678246cc1bdbcbc0f","tests/never_init.rs":"fcbba9034f829eef0f54ff650f6442ad75cdd609bdd02f45472fd4456f8e3a66","tests/no_time_to_init.rs":"0a2027de97188a82f97ba6a45c75c740917eea4e1f4bd4b947b6da3da7c354ed","tests/overflowing_preinit.rs":"985e140460a100986fd051ce901b787a3a7a9747a856cd06066b740ac7d2381c","tests/persist_ping_lifetime_nopanic.rs":"18379d3ffbf4a2c8c684c04ff7a0660b86dfbbb447db2d24dfed6073cb7ddf8f","tests/schema.rs":"da8f808f7cfd42b0cefd5dd04ca87d514392476ba268a32c140d3293c9332caf","tests/simple.rs":"4991afdbd037e789af2325fb87dc4a1e0fbbfa63aa54f1f22dc8bf01190473c7","tests/test-delayed-ping-data.sh":"4a6db98b4df6b77898ace6a8b4e8b4c60d3e5c44873bbf38c62e83583e27a3ff","tests/test-enabled-pings.sh":"06656e38f63e65475006b107dd6bd179b0cbaa1fad1470de38e679e91a9315a3","tests/test-pending-gets-removed.sh":"e335f2f00fa97a61b6d94e0005fb3b9de8c8db8076111a67ca47d85392039ea9","tests/test-ping-lifetime-flush.sh":"e8f118ea2f6fd973809e38d5e828a03cfccfe0b0f497ccde5ec92d6d1380c071","tests/test-shutdown-blocking.sh":"a44d8d4bbe2ee3ede9e48121150ae7a5386025160c5cef2181ca142232c5fb27","tests/test-thread-crashing.sh":"f3cd0cc8a7b4fe82bef0fe6fbfbbe45fbad6da3afe0f82578bc5cfb2d6527ac6","tests/timing_distribution_buffered.rs":"501f7289c0c28f0ab83838c88b058999b19436d0f2b693be0787513d7b67e06d","tests/timing_distribution_single_sample.rs":"4f9498b6ef29913da0356027efe5f572c81d2f426e8538c068b54a1cfa33c1b8","tests/upload_timing.rs":"8b9ed65eaba3d51faf3cb62d1280d2737f234e0332615bfe6d9c60aab44b6560"},"package":"6edc2134eac59587dc100b301eeba2dd473d74d6ecd51d635419a1865cc92496"}

View File

@@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.76"
name = "glean"
version = "62.0.0"
version = "63.0.0"
authors = [
"Jan-Erik Rediger <jrediger@mozilla.com>",
"The Glean Team <glean-team@mozilla.com>",
@@ -51,6 +51,10 @@ path = "tests/custom_distribution_buffered.rs"
name = "init_fails"
path = "tests/init_fails.rs"
[[test]]
name = "interruptible_shutdown"
path = "tests/interruptible_shutdown.rs"
[[test]]
name = "memory_distribution_buffered"
path = "tests/memory_distribution_buffered.rs"
@@ -91,8 +95,11 @@ path = "tests/timing_distribution_single_sample.rs"
name = "upload_timing"
path = "tests/upload_timing.rs"
[dependencies.crossbeam-channel]
version = "0.5"
[dependencies.glean-core]
version = "62.0.0"
version = "63.0.0"
[dependencies.inherent]
version = "1"
@@ -106,9 +113,6 @@ version = "1.18.0"
[dependencies.whatsys]
version = "0.3.0"
[dev-dependencies.crossbeam-channel]
version = "0.5"
[dev-dependencies.env_logger]
version = "0.10.0"
features = ["humantime"]

View File

@@ -2,6 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use crate::private::PingType;
use crate::ClientInfoMetrics;
use crate::{Configuration, ConfigurationBuilder};
use std::sync::{Mutex, MutexGuard};
@@ -45,6 +46,8 @@ pub(crate) fn new_glean(
.build(),
};
_ = PingType::new("store1", true, true, true, true, true, vec![], vec![], true);
crate::test_reset_glean(cfg, ClientInfoMetrics::unknown(), clear_stores);
dir
}

View File

@@ -23,7 +23,7 @@
//! let cfg = ConfigurationBuilder::new(true, "/tmp/data", "org.mozilla.glean_core.example").build();
//! glean::initialize(cfg, ClientInfoMetrics::unknown());
//!
//! let prototype_ping = PingType::new("prototype", true, true, true, true, true, vec!(), vec!());
//! let prototype_ping = PingType::new("prototype", true, true, true, true, true, vec!(), vec!(), true);
//!
//! prototype_ping.submit(None);
//! ```
@@ -137,13 +137,23 @@ pub fn shutdown() {
glean_core::shutdown()
}
/// Sets whether upload is enabled or not.
/// **DEPRECATED** Sets whether upload is enabled or not.
///
/// **DEPRECATION NOTICE**:
/// This API is deprecated. Use `set_collection_enabled` instead.
///
/// See [`glean_core::Glean::set_upload_enabled`].
pub fn set_upload_enabled(enabled: bool) {
glean_core::glean_set_upload_enabled(enabled)
}
/// Sets whether upload is enabled or not.
///
/// See [`glean_core::Glean::set_upload_enabled`].
pub fn set_collection_enabled(enabled: bool) {
glean_core::glean_set_collection_enabled(enabled)
}
/// Collects and submits a ping for eventual uploading by name.
///
/// Note that this needs to be public in order for RLB consumers to
@@ -259,6 +269,21 @@ pub fn set_debug_view_tag(tag: &str) -> bool {
glean_core::glean_set_debug_view_tag(tag.to_string())
}
/// Gets the currently set debug view tag.
///
/// The `debug_view_tag` may be set from an environment variable
/// (`GLEAN_DEBUG_VIEW_TAG`) or through the [`set_debug_view_tag`] function.
///
/// **WARNING** This function will block if Glean hasn't been initialized and
/// should only be used for debug purposes.
///
/// # Returns
///
/// Return the value for the debug view tag or [`None`] if it hasn't been set.
pub fn glean_get_debug_view_tag() -> Option<String> {
glean_core::glean_get_debug_view_tag()
}
/// Sets the log pings debug option.
///
/// When the log pings debug option is `true`,
@@ -271,6 +296,21 @@ pub fn set_log_pings(value: bool) {
glean_core::glean_set_log_pings(value)
}
/// Gets the current log pings value.
///
/// The `log_pings` option may be set from an environment variable (`GLEAN_LOG_PINGS`)
/// or through the [`set_log_pings`] function.
///
/// **WARNING** This function will block if Glean hasn't been initialized and
/// should only be used for debug purposes.
///
/// # Returns
///
/// Return the value for the log pings debug option.
pub fn glean_get_log_pings() -> bool {
glean_core::glean_get_log_pings()
}
/// Sets source tags.
///
/// Overrides any existing source tags.
@@ -301,5 +341,17 @@ pub fn persist_ping_lifetime_data() {
glean_core::glean_persist_ping_lifetime_data();
}
/// Gets a list of currently registered ping names.
///
/// **WARNING** This function will block if Glean hasn't been initialized and
/// should only be used for debug purposes.
///
/// # Returns
///
/// The list of ping names that are currently registered.
pub fn get_registered_ping_names() -> Vec<String> {
glean_core::glean_get_registered_ping_names()
}
#[cfg(test)]
mod test;

View File

@@ -7,6 +7,7 @@
//! This doesn't perform the actual upload but rather handles
//! retries, upload limitations and error tracking.
use crossbeam_channel::{Receiver, Sender};
use std::sync::{atomic::Ordering, Arc, Mutex};
use std::thread::{self, JoinHandle};
use std::time::Duration;
@@ -59,6 +60,8 @@ struct Inner {
uploader: Box<dyn PingUploader + 'static>,
thread_running: AtomicState,
handle: Mutex<Option<JoinHandle<()>>>,
rx: Receiver<()>,
tx: Sender<()>,
}
impl UploadManager {
@@ -72,12 +75,15 @@ impl UploadManager {
server_endpoint: String,
new_uploader: Box<dyn PingUploader + 'static>,
) -> Self {
let (tx, rx) = crossbeam_channel::bounded(1);
Self {
inner: Arc::new(Inner {
server_endpoint,
uploader: new_uploader,
thread_running: AtomicState::new(State::Stopped),
handle: Mutex::new(None),
rx,
tx,
}),
}
}
@@ -141,7 +147,13 @@ impl UploadManager {
}
PingUploadTask::Wait { time } => {
log::trace!("Instructed to wait for {:?}ms", time);
thread::sleep(Duration::from_millis(time));
let _ = inner.rx.recv_timeout(Duration::from_millis(time));
let status = inner.thread_running.load(Ordering::SeqCst);
// asked to shut down. let's do it.
if status == State::ShuttingDown {
break;
}
}
PingUploadTask::Done { .. } => {
log::trace!("Received PingUploadTask::Done. Exiting.");
@@ -192,6 +204,9 @@ impl UploadManager {
let thread = handle.take();
if let Some(thread) = thread {
// poke the thread in case it's in `Wait`.
let _ = self.inner.tx.send(());
thread
.join()
.expect("couldn't join on the uploader thread.");

View File

@@ -96,7 +96,7 @@ mod test {
let metric: EventMetric<traits::NoExtraKeys> = EventMetric::new(CommonMetricData {
name: "event".into(),
category: "test".into(),
send_in_pings: vec!["test1".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
});
@@ -133,7 +133,7 @@ mod test {
let metric: EventMetric<SomeExtra> = EventMetric::new(CommonMetricData {
name: "event".into(),
category: "test".into(),
send_in_pings: vec!["test1".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
});
@@ -188,7 +188,7 @@ mod test {
CommonMetricData {
name: "event".into(),
category: "test".into(),
send_in_pings: vec!["test1".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
},
vec!["key1".into(), "key2".into()],

View File

@@ -110,7 +110,7 @@ mod test {
let metric: ObjectMetric<SimpleArray> = ObjectMetric::new(CommonMetricData {
name: "object".into(),
category: "test".into(),
send_in_pings: vec!["test1".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
});
@@ -144,7 +144,7 @@ mod test {
let metric: ObjectMetric<BalloonsObject> = ObjectMetric::new(CommonMetricData {
name: "object".into(),
category: "test".into(),
send_in_pings: vec!["test1".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
});
@@ -178,7 +178,7 @@ mod test {
let metric: ObjectMetric<SimpleArray> = ObjectMetric::new(CommonMetricData {
name: "object".into(),
category: "test".into(),
send_in_pings: vec!["test1".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
});
@@ -225,7 +225,7 @@ mod test {
let metric: ObjectMetric<StackTrace> = ObjectMetric::new(CommonMetricData {
name: "object".into(),
category: "test".into(),
send_in_pings: vec!["test1".into()],
send_in_pings: vec!["store1".into()],
..Default::default()
});

View File

@@ -44,6 +44,7 @@ impl PingType {
enabled: bool,
schedules_pings: Vec<String>,
reason_codes: Vec<String>,
follows_collection_enabled: bool,
) -> Self {
let inner = glean_core::metrics::PingType::new(
name.into(),
@@ -54,6 +55,7 @@ impl PingType {
enabled,
schedules_pings,
reason_codes,
follows_collection_enabled,
);
Self {
@@ -62,6 +64,14 @@ impl PingType {
}
}
/// Enable or disable a ping.
///
/// Disabling a ping causes all data for that ping to be removed from storage
/// and all pending pings of that type to be deleted.
pub fn set_enabled(&self, enabled: bool) {
self.inner.set_enabled(enabled)
}
/// Submits the ping for eventual uploading.
///
/// The ping content is assembled as soon as possible, but upload is not

View File

@@ -18,6 +18,10 @@ use crate::private::{BooleanMetric, CounterMetric, EventMetric, StringMetric, Te
use super::*;
use crate::common_test::{lock_test, new_glean, GLOBAL_APPLICATION_ID};
fn new_test_ping(name: &str) -> PingType {
PingType::new(name, true, true, true, true, true, vec![], vec![], true)
}
#[test]
fn send_a_ping() {
let _lock = lock_test();
@@ -49,8 +53,7 @@ fn send_a_ping() {
// Define a new ping and submit it.
const PING_NAME: &str = "test-ping";
let custom_ping =
private::PingType::new(PING_NAME, true, true, true, true, true, vec![], vec![]);
let custom_ping = new_test_ping(PING_NAME);
custom_ping.submit(None);
// Wait for the ping to arrive.
@@ -91,8 +94,17 @@ fn send_a_ping_without_info_sections() {
// Define a new ping and submit it.
const PING_NAME: &str = "noinfo-ping";
let custom_ping =
private::PingType::new(PING_NAME, true, true, true, false, true, vec![], vec![]);
let custom_ping = PingType::new(
PING_NAME,
true,
true,
true,
/* include_info_sections */ false,
true,
vec![],
vec![],
true,
);
custom_ping.submit(None);
// Wait for the ping to arrive.
@@ -596,7 +608,7 @@ fn ping_collection_must_happen_after_concurrently_scheduled_metrics_recordings()
);
let ping_name = "custom_ping_1";
let ping = private::PingType::new(ping_name, true, false, true, true, true, vec![], vec![]);
let ping = new_test_ping(ping_name);
let metric = private::StringMetric::new(CommonMetricData {
name: "string_metric".into(),
category: "telemetry".into(),
@@ -629,7 +641,7 @@ fn basic_metrics_should_be_cleared_when_disabling_uploading() {
let metric = private::StringMetric::new(CommonMetricData {
name: "string_metric".into(),
category: "telemetry".into(),
send_in_pings: vec!["default".into()],
send_in_pings: vec!["store1".into()],
lifetime: Lifetime::Ping,
disabled: false,
..Default::default()
@@ -1099,16 +1111,7 @@ fn flipping_upload_enabled_respects_order_of_events() {
.build();
// We create a ping and a metric before we initialize Glean
let sample_ping = PingType::new(
"sample-ping-1",
true,
false,
true,
true,
true,
vec![],
vec![],
);
let sample_ping = new_test_ping("sample-ping-1");
let metric = private::StringMetric::new(CommonMetricData {
name: "string_metric".into(),
category: "telemetry".into(),
@@ -1152,7 +1155,7 @@ fn registering_pings_before_init_must_work() {
}
// Create a custom ping and attempt its registration.
let sample_ping = PingType::new("pre-register", true, true, true, true, true, vec![], vec![]);
let sample_ping = new_test_ping("pre-register");
// Create a custom configuration to use a fake uploader.
let dir = tempfile::tempdir().unwrap();
@@ -1165,7 +1168,7 @@ fn registering_pings_before_init_must_work() {
let _t = new_glean(Some(cfg), true);
// Submit a baseline ping.
// Submit a test ping.
sample_ping.submit(None);
// Wait for the ping to arrive.
@@ -1204,7 +1207,7 @@ fn test_a_ping_before_submission() {
let _t = new_glean(Some(cfg), true);
// Create a custom ping and register it.
let sample_ping = PingType::new("custom1", true, true, true, true, true, vec![], vec![]);
let sample_ping = new_test_ping("custom1");
let metric = CounterMetric::new(CommonMetricData {
name: "counter_metric".into(),
@@ -1321,8 +1324,7 @@ fn signaling_done() {
// Define a new ping and submit it.
const PING_NAME: &str = "test-ping";
let custom_ping =
private::PingType::new(PING_NAME, true, true, true, true, true, vec![], vec![]);
let custom_ping = new_test_ping(PING_NAME);
custom_ping.submit(None);
custom_ping.submit(None);
@@ -1393,8 +1395,7 @@ fn configure_ping_throttling() {
// Define a new ping.
const PING_NAME: &str = "test-ping";
let custom_ping =
private::PingType::new(PING_NAME, true, true, true, true, true, vec![], vec![]);
let custom_ping = new_test_ping(PING_NAME);
// Submit and receive it `pings_per_interval` times.
for _ in 0..pings_per_interval {
@@ -1457,9 +1458,7 @@ fn pings_ride_along_builtin_pings() {
let _t = new_glean(Some(cfg), true);
let reasons = vec!["active".to_string()];
let _ride_along_ping =
private::PingType::new("ride-along", true, true, true, true, true, vec![], reasons);
let _ride_along_ping = new_test_ping("ride-along");
// Simulate becoming active.
handle_client_active();

View File

@@ -8,7 +8,7 @@
use std::{panic, process};
use glean::{ClientInfoMetrics, Configuration};
use glean::{private::PingType, ClientInfoMetrics, Configuration};
/// Initialize the env logger for a test environment.
///
@@ -48,5 +48,6 @@ pub fn initialize(cfg: Configuration) {
locale: Some("xx-XX".to_string()),
};
_ = PingType::new("store1", true, true, true, true, true, vec![], vec![], true);
glean::initialize(cfg, client_info);
}

View File

@@ -24,7 +24,7 @@ mod metrics {
CommonMetricData {
name: "measure".into(),
category: "sample".into(),
send_in_pings: vec!["validation".into()],
send_in_pings: vec!["store1".into()],
lifetime: Lifetime::Ping,
disabled: false,
..Default::default()

View File

@@ -43,7 +43,17 @@ mod pings {
#[allow(non_upper_case_globals)]
pub static validation: Lazy<PingType> = Lazy::new(|| {
glean::private::PingType::new("validation", true, true, true, true, true, vec![], vec![])
glean::private::PingType::new(
"validation",
true,
true,
true,
true,
true,
vec![],
vec![],
true,
)
});
}
@@ -60,6 +70,7 @@ fn init_fails() {
let dir = tempfile::tempdir().unwrap();
let tmpname = dir.path().to_path_buf();
_ = &*pings::validation;
let cfg = ConfigurationBuilder::new(true, tmpname, "")
.with_server_endpoint("invalid-test-host")
.build();

View File

@@ -0,0 +1,156 @@
// 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 https://mozilla.org/MPL/2.0/.
//! This integration test should model how the RLB is used when embedded in another Rust application
//! (e.g. FOG/Firefox Desktop).
//!
//! We write a single test scenario per file to avoid any state keeping across runs
//! (different files run as different processes).
mod common;
use std::io::Read;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Instant;
use crossbeam_channel::{bounded, Sender};
use flate2::read::GzDecoder;
use serde_json::Value as JsonValue;
use glean::net;
use glean::{ConfigurationBuilder, PingRateLimit};
mod metrics {
#![allow(non_upper_case_globals)]
use glean::{private::BooleanMetric, CommonMetricData, Lifetime};
use once_cell::sync::Lazy;
pub static sample_boolean: Lazy<BooleanMetric> = Lazy::new(|| {
BooleanMetric::new(CommonMetricData {
name: "sample_boolean".into(),
category: "test.metrics".into(),
send_in_pings: vec!["validation".into()],
disabled: false,
lifetime: Lifetime::Ping,
..Default::default()
})
});
}
mod pings {
use glean::private::PingType;
use once_cell::sync::Lazy;
#[allow(non_upper_case_globals)]
pub static validation: Lazy<PingType> = Lazy::new(|| {
glean::private::PingType::new(
"validation",
true,
true,
true,
true,
true,
vec![],
vec![],
true,
)
});
}
// Define a fake uploader that reports when and what it uploads.
#[derive(Debug)]
struct ReportingUploader {
calls: AtomicUsize,
sender: Sender<JsonValue>,
}
impl net::PingUploader for ReportingUploader {
fn upload(&self, upload_request: net::PingUploadRequest) -> net::UploadResult {
let calls = self.calls.fetch_add(1, Ordering::SeqCst);
let body = upload_request.body;
let decode = |body: Vec<u8>| {
let mut gzip_decoder = GzDecoder::new(&body[..]);
let mut s = String::with_capacity(body.len());
gzip_decoder
.read_to_string(&mut s)
.ok()
.map(|_| &s[..])
.or_else(|| std::str::from_utf8(&body).ok())
.and_then(|payload| serde_json::from_str(payload).ok())
.unwrap()
};
match calls {
// First goes through immediately.
0 => {
self.sender.send(decode(body)).unwrap();
net::UploadResult::http_status(200)
}
// Second SHOULD NEVER SEND
1 => panic!("We should shutdown before getting to the second ping"),
// Any others ought to be impossible.
_ => panic!("Wat."),
}
}
}
/// Test scenario: We can interrupt a long glean.upload Wait during shutdown.
///
/// The app is initialized, in turn Glean gets initialized without problems.
/// A custom ping is submitted once, triggering ping throttling.
/// It is submitted a second time to convince `glean.upload` to be in a `Wait` task.
/// From this position we ask for Glean to promptly shut down.
/// We expect this to happen reasonably quickly (within 2s) instead of waiting for the
/// entire throttling interval _or_ for uploader_shutdown's last-ditch timeout.
#[test]
fn interruptible_shutdown() {
common::enable_test_logging();
// Create a custom configuration to use our reporting uploader.
let dir = tempfile::tempdir().unwrap();
let tmpname = dir.path().to_path_buf();
let (tx, rx) = bounded(1);
let mut cfg = ConfigurationBuilder::new(true, tmpname.clone(), "glean-interruptible-shutdown")
.with_server_endpoint("invalid-test-host")
.with_use_core_mps(false)
.with_uploader(ReportingUploader {
calls: AtomicUsize::new(0),
sender: tx,
})
.build();
cfg.rate_limit = Some(PingRateLimit {
seconds_per_interval: 600, // Needs only be longer than the timeout in `glean::uploader_shutdown()`.
pings_per_interval: 1, // throttle thyself immediately.
});
common::initialize(cfg);
// Wait for init to finish,
// otherwise we might be to quick with calling `shutdown`.
let _ = metrics::sample_boolean.test_get_value(None);
// fast
pings::validation.submit(None);
// wait for it to be uploaded
let _body = rx.recv().unwrap();
// Now we're in throttling territory.
pings::validation.submit(None);
// Now we shut down.
// This should complete really fast because we'll interrupt the `glean.upload` thread
// from its 600-second Wait task.
// ...so long as everything's working properly. So let's time it.
let pre_shutdown = Instant::now();
glean::shutdown();
let shutdown_elapsed = pre_shutdown.elapsed();
assert!(
shutdown_elapsed.as_secs() < 2,
"We shouldn't have been slow on shutdown."
);
}

View File

@@ -24,7 +24,7 @@ mod metrics {
CommonMetricData {
name: "measure".into(),
category: "sample".into(),
send_in_pings: vec!["validation".into()],
send_in_pings: vec!["store1".into()],
lifetime: Lifetime::Ping,
disabled: false,
..Default::default()

View File

@@ -39,7 +39,17 @@ mod pings {
#[allow(non_upper_case_globals)]
pub static validation: Lazy<PingType> = Lazy::new(|| {
glean::private::PingType::new("validation", true, true, true, true, true, vec![], vec![])
glean::private::PingType::new(
"validation",
true,
true,
true,
true,
true,
vec![],
vec![],
true,
)
});
}

View File

@@ -41,7 +41,17 @@ mod pings {
#[allow(non_upper_case_globals)]
pub static validation: Lazy<PingType> = Lazy::new(|| {
glean::private::PingType::new("validation", true, true, true, true, true, vec![], vec![])
glean::private::PingType::new(
"validation",
true,
true,
true,
true,
true,
vec![],
vec![],
true,
)
});
}

View File

@@ -170,8 +170,17 @@ fn validate_against_schema() {
text_metric.set("loooooong text".repeat(100));
// Define a new ping and submit it.
let custom_ping =
glean::private::PingType::new(PING_NAME, true, true, true, true, true, vec![], vec![]);
let custom_ping = glean::private::PingType::new(
PING_NAME,
true,
true,
true,
true,
true,
vec![],
vec![],
true,
);
custom_ping.submit(None);
// Wait for the ping to arrive.

View File

@@ -41,7 +41,17 @@ mod pings {
#[allow(non_upper_case_globals)]
pub static validation: Lazy<PingType> = Lazy::new(|| {
glean::private::PingType::new("validation", true, true, true, true, true, vec![], vec![])
glean::private::PingType::new(
"validation",
true,
true,
true,
true,
true,
vec![],
vec![],
true,
)
});
}
@@ -60,6 +70,7 @@ fn simple_lifecycle() {
let dir = tempfile::tempdir().unwrap();
let tmpname = dir.path().to_path_buf();
_ = &*pings::validation;
let cfg = ConfigurationBuilder::new(true, tmpname, "firefox-desktop")
.with_server_endpoint("invalid-test-host")
.build();

View File

@@ -0,0 +1,60 @@
#!/bin/bash
# Test harness for testing the RLB processes from the outside.
#
# Some behavior can only be observed when properly exiting the process running Glean,
# e.g. when an uploader runs in another thread.
# On exit the threads will be killed, regardless of their state.
# Remove the temporary data path on all exit conditions
cleanup() {
if [ -n "$datapath" ]; then
rm -r "$datapath"
fi
}
trap cleanup INT ABRT TERM EXIT
tmp="${TMPDIR:-/tmp}"
datapath=$(mktemp -d "${tmp}/glean_enabled_pings.XXXX")
# Build it once
cargo build -p glean --example enabled-pings
cmd="cargo run -q -p glean --example enabled-pings -- $datapath"
$cmd default
count=$(ls -1q "$datapath/sent_pings" | wc -l)
if [[ "$count" -ne 1 ]]; then
echo "1: test result: FAILED."
exit 101
fi
if ! grep -q "invalid-test-host/submit/glean-enabled-pings/one/" "$datapath/sent_pings"/*; then
echo "2: test result: FAILED."
exit 101
fi
rm -r $datapath
$cmd enable-both
count=$(ls -1q "$datapath/sent_pings" | wc -l)
if [[ "$count" -ne 2 ]]; then
echo "3: test result: FAILED."
exit 101
fi
rm -r $datapath
$cmd enable-only-two
count=$(ls -1q "$datapath/sent_pings" | wc -l)
if [[ "$count" -ne 1 ]]; then
echo "4: test result: FAILED."
exit 101
fi
if ! grep -q "invalid-test-host/submit/glean-enabled-pings/two/" "$datapath/sent_pings"/*; then
echo "5: test result: FAILED."
exit 101
fi
echo "test result: ok."
exit 0

View File

@@ -0,0 +1,54 @@
#!/bin/bash
# Test harness for testing the RLB processes from the outside.
#
# Some behavior can only be observed when properly exiting the process running Glean,
# e.g. when an uploader runs in another thread.
# On exit the threads will be killed, regardless of their state.
# Remove the temporary data path on all exit conditions
cleanup() {
if [ -n "$datapath" ]; then
rm -r "$datapath"
fi
}
trap cleanup INT ABRT TERM EXIT
set -e
tmp="${TMPDIR:-/tmp}"
datapath=$(mktemp -d "${tmp}/pending-gets-removed.XXXX")
# Build it once
cargo build -p glean --example pending-gets-removed
cmd="cargo run -q -p glean --example pending-gets-removed -- $datapath"
$cmd 1
count=$(ls -1q "$datapath/pending_pings" | wc -l)
if [[ "$count" -ne 2 ]]; then
echo "1: test result: FAILED."
exit 101
fi
$cmd 2
count=$(ls -1q "$datapath/pending_pings" | wc -l)
if [[ "$count" -ne 1 ]]; then
echo "2: test result: FAILED."
exit 101
fi
if ! grep -q "/submit/glean-pending-removed/nofollows/" "$datapath/pending_pings"/*; then
echo "3: test result: FAILED."
exit 101
fi
$cmd 3
count=$(ls -1q "$datapath/pending_pings" | wc -l)
if [[ "$count" -ne 0 ]]; then
echo "4: test result: FAILED."
exit 101
fi
echo "test result: ok."
exit 0

View File

@@ -25,7 +25,7 @@ mod metrics {
CommonMetricData {
name: "boo".into(),
category: "sample".into(),
send_in_pings: vec!["validation".into()],
send_in_pings: vec!["store1".into()],
lifetime: Lifetime::Ping,
disabled: false,
..Default::default()

View File

@@ -26,7 +26,7 @@ mod metrics {
CommonMetricData {
name: "boo".into(),
category: "sample".into(),
send_in_pings: vec!["validation".into()],
send_in_pings: vec!["store1".into()],
lifetime: Lifetime::Ping,
disabled: false,
..Default::default()

View File

@@ -97,7 +97,17 @@ mod pings {
#[allow(non_upper_case_globals)]
pub static validation: Lazy<PingType> = Lazy::new(|| {
glean::private::PingType::new("validation", true, true, true, true, true, vec![], vec![])
glean::private::PingType::new(
"validation",
true,
true,
true,
true,
true,
vec![],
vec![],
true,
)
});
}