diff --git a/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/AUTHORS.md b/third_party/python/glean_parser/glean_parser-14.1.2.dist-info/AUTHORS.md similarity index 100% rename from third_party/python/glean_parser/glean_parser-14.0.1.dist-info/AUTHORS.md rename to third_party/python/glean_parser/glean_parser-14.1.2.dist-info/AUTHORS.md diff --git a/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/LICENSE b/third_party/python/glean_parser/glean_parser-14.1.2.dist-info/LICENSE similarity index 100% rename from third_party/python/glean_parser/glean_parser-14.0.1.dist-info/LICENSE rename to third_party/python/glean_parser/glean_parser-14.1.2.dist-info/LICENSE diff --git a/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/METADATA b/third_party/python/glean_parser/glean_parser-14.1.2.dist-info/METADATA similarity index 98% rename from third_party/python/glean_parser/glean_parser-14.0.1.dist-info/METADATA rename to third_party/python/glean_parser/glean_parser-14.1.2.dist-info/METADATA index 65030fd86ba7..ad9ec1e090b4 100644 --- a/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/METADATA +++ b/third_party/python/glean_parser/glean_parser-14.1.2.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: glean_parser -Version: 14.0.1 +Version: 14.1.2 Summary: Parser tools for Mozilla's Glean telemetry Home-page: https://github.com/mozilla/glean_parser Author: The Glean Team @@ -77,6 +77,20 @@ $ glean_parser check < ping.json # Changelog +## Unreleased + +## 14.1.2 + +- ping schedule: Gracefully handle missing ping ([#705](https://github.com/mozilla/glean_parser/pull/705)) + +## 14.1.1 + +- Replace deprecated methods and package ([#699](https://github.com/mozilla/glean_parser/pull/699)) + +## 14.1.0 + +- Add Go log outputter support for datetime (`go_server`) ([#693](https://github.com/mozilla/glean_parser/pull/693)) + ## 14.0.1 - BUGFIX: Fix missing `ping_arg` in util.py ([#687](https://github.com/mozilla/glean_parser/pull/687)) diff --git a/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/RECORD b/third_party/python/glean_parser/glean_parser-14.1.2.dist-info/RECORD similarity index 77% rename from third_party/python/glean_parser/glean_parser-14.0.1.dist-info/RECORD rename to third_party/python/glean_parser/glean_parser-14.1.2.dist-info/RECORD index 700ca80797fb..fa638878e555 100644 --- a/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/RECORD +++ b/third_party/python/glean_parser/glean_parser-14.1.2.dist-info/RECORD @@ -1,15 +1,15 @@ -glean_parser/__init__.py,sha256=bJljD052_0y-efcBhYpllICVCXOMHLcXRLNyrvfgt5A,533 +glean_parser/__init__.py,sha256=mB3nXWXhV9zJXymgmeGCjUnPFzQgcexx0Klw0XvLkS8,515 glean_parser/__main__.py,sha256=Rw0PpuQtAvdHJMK1YLozeZkc6x1yjeNZwidu4faovdk,8633 glean_parser/coverage.py,sha256=2IwC4XMDtDamMkBFoYilmqJzW4gyypq65YVCur8SNas,4405 glean_parser/data_review.py,sha256=BweeeTkNNS6HrIDkztawhbDByrk_-Avxpg7YeST3VAs,2152 -glean_parser/go_server.py,sha256=s6lxK9IAFY55pNl3Rv4MHlV-nQwSoyhO9ppTQE9VCik,5346 +glean_parser/go_server.py,sha256=VaPymy5bxAM9jlD0UkkzOndRxT3Wqym193pMMrfBYz0,5421 glean_parser/javascript.py,sha256=w4ZhNBHBKWYk0h3t7G0Ud2tR__hRqzn9dlEXNKLdQrA,11230 glean_parser/javascript_server.py,sha256=PZSTl63TR3cY8Y99jXMOLu-8rzgQarymzjnHJm9aYK0,8389 glean_parser/kotlin.py,sha256=5nXnen4s2YOj503Z77HVTUgDHWdulB8BMl8vOie38o4,13365 glean_parser/lint.py,sha256=STqdgyOhR4Q3fHivSizgn9bOOyqrNHhzjaqyJxz6qzI,19948 glean_parser/markdown.py,sha256=GkCr1CrV6mnRQseT6FO1-JJ7Eup8X3lxUfRMBTxXpe4,9066 glean_parser/metrics.py,sha256=YAO8wPuRHTLkdT9M4zh9ZwoFI1_VS8O9oQqwZNYyDp0,14612 -glean_parser/parser.py,sha256=3-uF-Hi5LlvdFc1NxZOKX0EoEyekZGnZV094eTIJut0,16361 +glean_parser/parser.py,sha256=eIlXYUOeeqy6-Ec2V-XFf4dFc2gnRhkgd9ZXjp1RYvU,16366 glean_parser/pings.py,sha256=-CIiMBVOTFULmNybV8YTFI7vmfOYOGQ5TD9hEfYPUII,3435 glean_parser/python_server.py,sha256=ERpYcbSwF19xKFagxX0mZAvlR1y6D7Ah5DSvW8LipCY,4791 glean_parser/ruby_server.py,sha256=e5lkfcLQAUMUBQDCjqNU82LkdUzT5x-G6HOnsUInbsU,5190 @@ -18,7 +18,7 @@ glean_parser/swift.py,sha256=paUzF6tItdktFwIQYCKsYpqXfn8zxR2coU_jMYrmwlc,8957 glean_parser/tags.py,sha256=bemKYvcbMO4JrghiNSe-A4BNNDtx_FlUPkgrPPJy84Y,1391 glean_parser/translate.py,sha256=luKQoraARZ2tjenHs0SVtCxflnYaMkzPYFfKEdKdSqQ,8403 glean_parser/translation_options.py,sha256=Lxzr6G7MP0tC_ZYlZXftS4j0SLiqO-5mGVTEc7ggXis,2037 -glean_parser/util.py,sha256=wftmoWBUQM_o7pUwdhBp3HuDCVHIBw1PXtrfxwPLD0Q,16187 +glean_parser/util.py,sha256=xECYZVlcVzmUn7PT4zp5hVa0iYW2Qh3ik71iPgjeQvY,16223 glean_parser/validate_ping.py,sha256=0TNvILH6dtzJDys3W8Kqorw6kk03me73OCUDtpoHcXU,2118 glean_parser/schemas/metrics.1-0-0.schema.yaml,sha256=cND3cvi6iBfPUVmtfIBQfGJV9AALpbvN7nu8E33_J-o,19566 glean_parser/schemas/metrics.2-0-0.schema.yaml,sha256=wx1q0L4C0-Vcwk1SPU6t8OfjDEQvgrwwEG6xfSHO1MI,26365 @@ -26,7 +26,7 @@ glean_parser/schemas/pings.1-0-0.schema.yaml,sha256=hwCnsKpEysmrmVp-QHGBArEkVY3v glean_parser/schemas/pings.2-0-0.schema.yaml,sha256=f8PClAlMoLTmX6ANq8Ai0CpiE74i3LOgU5SoTJpoh0M,6149 glean_parser/schemas/tags.1-0-0.schema.yaml,sha256=OGXIJlvvVW1vaqB_NVZnwKeZ-sLlfH57vjBSHbj6DNI,1231 glean_parser/templates/data_review.jinja2,sha256=jeYU29T1zLSyu9fKBBFu5BFPfIw8_hmOUXw8RXhRXK8,3287 -glean_parser/templates/go_server.jinja2,sha256=Jy1e0uQqr_WZNoj-AWnygRmygX2jyj_GQMMV8mSah2k,6825 +glean_parser/templates/go_server.jinja2,sha256=EHf4KBKNPzC1sLugN9yS6_vPNlSl3YCxcoVQGWGL6aM,7039 glean_parser/templates/javascript.buildinfo.jinja2,sha256=4mXiZCQIk9if4lxlA05kpSIL4a95IdwGwqle2OqqNAs,474 glean_parser/templates/javascript.jinja2,sha256=cT_bG-jC6m4afECXmcsqHwiiHjRuVtJnfv90OD2Mwxw,2669 glean_parser/templates/javascript_server.jinja2,sha256=k-XI3QIhHQ1vbIPqSMTmCu93b1oZhm7KLmx9LfO3IJ0,9472 @@ -37,12 +37,12 @@ glean_parser/templates/markdown.jinja2,sha256=vAHHGGm28HRDPd3zO_wQMAUZIuxE9uQ7hl glean_parser/templates/python_server.jinja2,sha256=gu2C1rkn760IqBCG2SWaK7o32T1ify94wDEsudLPUg8,7260 glean_parser/templates/qmldir.jinja2,sha256=m6IGsp-tgTiOfQ7VN8XW6GqX0gJqJkt3B6Pkaul6FVo,156 glean_parser/templates/ruby_server.jinja2,sha256=vm4BEenOqzomQNTLFfMOzlWHARnsWUjTBbnR-v2cadI,6247 -glean_parser/templates/rust.jinja2,sha256=Ir_JqWRIUs1KLoYNDolgTRjWfWdzzBfouCP-YeTJa-c,5495 +glean_parser/templates/rust.jinja2,sha256=sNphecHKehGOzwtIz-Q54Zz1mHcNXFsIPn7BaK78ln4,5517 glean_parser/templates/swift.jinja2,sha256=4f993l_zZk_Tz1efiz3nbvDK1H3Uq3dWQ2T6glT9XQ4,6695 -glean_parser-14.0.1.dist-info/AUTHORS.md,sha256=yxgj8MioO4wUnrh0gmfb8l3DJJrf-l4HmmEDbQsbbNI,455 -glean_parser-14.0.1.dist-info/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725 -glean_parser-14.0.1.dist-info/METADATA,sha256=Ghvw-Y7woQUJ38P8TYT5TFt8sL61GJoZPBajaB0WLeQ,32276 -glean_parser-14.0.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92 -glean_parser-14.0.1.dist-info/entry_points.txt,sha256=mf9d3sv8BwSjjR58x9KDnpVkONCnv3fPQC2NjJl15Xg,68 -glean_parser-14.0.1.dist-info/top_level.txt,sha256=q7T3duD-9tYZFyDry6Wv2LcdMsK2jGnzdDFhxWcT2Z8,13 -glean_parser-14.0.1.dist-info/RECORD,, +glean_parser-14.1.2.dist-info/AUTHORS.md,sha256=yxgj8MioO4wUnrh0gmfb8l3DJJrf-l4HmmEDbQsbbNI,455 +glean_parser-14.1.2.dist-info/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725 +glean_parser-14.1.2.dist-info/METADATA,sha256=rS3vTnQHptZNwin6HEKOZoeBiiPFi8Dq4G2TjPDbs5Q,32651 +glean_parser-14.1.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92 +glean_parser-14.1.2.dist-info/entry_points.txt,sha256=mf9d3sv8BwSjjR58x9KDnpVkONCnv3fPQC2NjJl15Xg,68 +glean_parser-14.1.2.dist-info/top_level.txt,sha256=q7T3duD-9tYZFyDry6Wv2LcdMsK2jGnzdDFhxWcT2Z8,13 +glean_parser-14.1.2.dist-info/RECORD,, diff --git a/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/WHEEL b/third_party/python/glean_parser/glean_parser-14.1.2.dist-info/WHEEL similarity index 100% rename from third_party/python/glean_parser/glean_parser-14.0.1.dist-info/WHEEL rename to third_party/python/glean_parser/glean_parser-14.1.2.dist-info/WHEEL diff --git a/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/entry_points.txt b/third_party/python/glean_parser/glean_parser-14.1.2.dist-info/entry_points.txt similarity index 100% rename from third_party/python/glean_parser/glean_parser-14.0.1.dist-info/entry_points.txt rename to third_party/python/glean_parser/glean_parser-14.1.2.dist-info/entry_points.txt diff --git a/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/top_level.txt b/third_party/python/glean_parser/glean_parser-14.1.2.dist-info/top_level.txt similarity index 100% rename from third_party/python/glean_parser/glean_parser-14.0.1.dist-info/top_level.txt rename to third_party/python/glean_parser/glean_parser-14.1.2.dist-info/top_level.txt diff --git a/third_party/python/glean_parser/glean_parser/__init__.py b/third_party/python/glean_parser/glean_parser/__init__.py index ddca930c7973..2433db8b0b5a 100644 --- a/third_party/python/glean_parser/glean_parser/__init__.py +++ b/third_party/python/glean_parser/glean_parser/__init__.py @@ -6,11 +6,11 @@ """Top-level package for Glean parser.""" -from pkg_resources import get_distribution, DistributionNotFound +import importlib.metadata try: - __version__ = get_distribution(__name__).version -except DistributionNotFound: + __version__ = importlib.metadata.version(__name__) +except importlib.metadata.PackageNotFoundError: # package is not installed pass diff --git a/third_party/python/glean_parser/glean_parser/go_server.py b/third_party/python/glean_parser/glean_parser/go_server.py index 03abb7281943..becc4898787f 100644 --- a/third_party/python/glean_parser/glean_parser/go_server.py +++ b/third_party/python/glean_parser/glean_parser/go_server.py @@ -32,7 +32,7 @@ from . import util # Adding a metric here will require updating the `generate_metric_type` function # and require adjustments to `metrics` variables the the template. -SUPPORTED_METRIC_TYPES = ["string", "quantity", "event"] +SUPPORTED_METRIC_TYPES = ["string", "quantity", "event", "datetime"] def generate_event_type_name(metric: metrics.Metric) -> str: @@ -58,6 +58,8 @@ def generate_metric_type(metric_type: str) -> str: return "string" elif metric_type == "boolean": return "bool" + elif metric_type == "datetime": + return "time.Time" else: print("❌ Unable to generate Go type from metric type: " + metric_type) exit diff --git a/third_party/python/glean_parser/glean_parser/parser.py b/third_party/python/glean_parser/glean_parser/parser.py index 158676be7356..da0c3867af64 100644 --- a/third_party/python/glean_parser/glean_parser/parser.py +++ b/third_party/python/glean_parser/glean_parser/parser.py @@ -299,8 +299,6 @@ def _instantiate_pings( ping_schedule_reverse_map[ping_schedule] = set() ping_schedule_reverse_map[ping_schedule].add(ping_key) - del ping_val["metadata"]["ping_schedule"] - try: ping_obj = Ping( defined_in=getattr(ping_val, "defined_in", None), @@ -331,7 +329,9 @@ def _instantiate_pings( sources[ping_key] = filepath for scheduler, scheduled in ping_schedule_reverse_map.items(): - if isinstance(all_objects["pings"][scheduler], Ping): + if scheduler in all_objects["pings"] and isinstance( + all_objects["pings"][scheduler], Ping + ): scheduler_obj: Ping = cast(Ping, all_objects["pings"][scheduler]) scheduler_obj.schedules_pings = sorted(list(scheduled)) diff --git a/third_party/python/glean_parser/glean_parser/templates/go_server.jinja2 b/third_party/python/glean_parser/glean_parser/templates/go_server.jinja2 index 0a26831b0fca..21aaf108833e 100644 --- a/third_party/python/glean_parser/glean_parser/templates/go_server.jinja2 +++ b/third_party/python/glean_parser/glean_parser/templates/go_server.jinja2 @@ -10,7 +10,7 @@ package glean // required imports import ( "encoding/json" - "fmt" + "fmt" "strconv" "time" @@ -185,7 +185,11 @@ func (g GleanEventsLogger) Record{{ event|event_type_name }}( {% if metric_type != 'event' %} "{{ metric_type }}": { {% for metric in metrics %} - "{{ metric|metric_name }}": params.{{ metric|metric_argument_name }}, + {% if metric_type =='datetime' %} + "{{ metric|metric_name }}": params.{{ metric|metric_argument_name }}.Format("2006-01-02T15:04:05.000Z"), + {% else %} + "{{ metric|metric_name }}": params.{{ metric|metric_argument_name }}, + {% endif %} {% endfor %} }, {% endif %} diff --git a/third_party/python/glean_parser/glean_parser/templates/rust.jinja2 b/third_party/python/glean_parser/glean_parser/templates/rust.jinja2 index 269a007ac5da..e8f2796930c0 100644 --- a/third_party/python/glean_parser/glean_parser/templates/rust.jinja2 +++ b/third_party/python/glean_parser/glean_parser/templates/rust.jinja2 @@ -24,7 +24,7 @@ Jinja2 template is not. Please file bugs! #} #[serde(skip_serializing_if = "Option::is_none")] pub {{itemname|snake_case}}: Option<{{ name ~ "Item" ~ itemname|Camelize ~ "Object" }}>, {% elif val.type == "array" %} - #[serde(skip_serializing_if = "Vec::is_empty")] + #[serde(skip_serializing_if = "Vec::is_empty", default = "Vec::new")] pub {{itemname|snake_case}}: {{ name ~ "Item" ~ itemname|Camelize }}, {% else %} #[serde(skip_serializing_if = "Option::is_none")] diff --git a/third_party/python/glean_parser/glean_parser/util.py b/third_party/python/glean_parser/glean_parser/util.py index a61e318dbeae..0d483e24f20d 100644 --- a/third_party/python/glean_parser/glean_parser/util.py +++ b/third_party/python/glean_parser/glean_parser/util.py @@ -406,7 +406,7 @@ def is_expired(expires: str, major_version: Optional[int] = None) -> bool: return parse_expiration_version(expires) <= major_version else: date = parse_expiration_date(expires) - return date <= datetime.datetime.utcnow().date() + return date <= datetime.datetime.now(datetime.timezone.utc).date() def validate_expires(expires: str, major_version: Optional[int] = None) -> None: @@ -458,7 +458,7 @@ def build_date(date: Optional[str]) -> datetime.datetime: else: ts = datetime_fromisoformat(date).replace(tzinfo=datetime.timezone.utc) else: - ts = datetime.datetime.utcnow() + ts = datetime.datetime.now(datetime.timezone.utc) return ts diff --git a/third_party/python/poetry.lock b/third_party/python/poetry.lock index 0547486b27e8..03f48f9823e2 100644 --- a/third_party/python/poetry.lock +++ b/third_party/python/poetry.lock @@ -592,14 +592,14 @@ files = [ [[package]] name = "glean-parser" -version = "14.0.1" +version = "14.1.2" description = "Parser tools for Mozilla's Glean telemetry" category = "main" optional = false python-versions = "*" files = [ - {file = "glean_parser-14.0.1-py3-none-any.whl", hash = "sha256:3275ca235885c99da659fa7d9bf929b8fb020df79d26fcbec317328c369cd039"}, - {file = "glean_parser-14.0.1.tar.gz", hash = "sha256:3e9e5f99ad8592300e364b70d6247b21c445774a73a2ad274677fb58a0065809"}, + {file = "glean_parser-14.1.2-py3-none-any.whl", hash = "sha256:c3e87165fe0a0fcbcb28b76bbad025601a86eb447c5779472b62915c46cd44ab"}, + {file = "glean_parser-14.1.2.tar.gz", hash = "sha256:38be7d4e0fab0f83340e3427914e08a8631c7fab088a8c60e9b543cab6ea830c"}, ] [package.dependencies] @@ -1161,6 +1161,7 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -1624,4 +1625,4 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=4.6)", "pytest-black ( [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "8e72dc9ba9b4f08d27d90f99666459a814d1bb293c68de222614ea57db5b70ef" +content-hash = "a683c725217ca4a2d61b56b43b137217b5f8630ee0715e44637fd29599e0b0a2" diff --git a/third_party/python/requirements.in b/third_party/python/requirements.in index abcfc79239ff..6f7ece131516 100644 --- a/third_party/python/requirements.in +++ b/third_party/python/requirements.in @@ -22,7 +22,7 @@ fluent.migrate==0.13.0 fluent.syntax==0.19.0 # Pin `frozenlist` as it is required for `aiohttp`. Use minimum required version. frozenlist==1.1.1 -glean_parser==14.0.1 +glean_parser==14.1.2 importlib-metadata==6.0.0 # required for compatibility with Flask >= 2 in tools/tryselect/selectors/chooser jinja2==3.1.2 diff --git a/third_party/python/requirements.txt b/third_party/python/requirements.txt index 3b8c897e8a2c..14a0514f4383 100644 --- a/third_party/python/requirements.txt +++ b/third_party/python/requirements.txt @@ -275,9 +275,9 @@ frozenlist==1.1.1 ; python_version >= "3.8" and python_version < "4.0" \ giturlparse==0.10.0 ; python_version >= "3.8" and python_version < "4.0" \ --hash=sha256:04ba1a3a099c3093fa8d24a422913c6a9b2c2cd22bcffc939cf72e3e98f672d7 \ --hash=sha256:2595ab291d30717cda8474b874c9fd509f1b9802ad7f6968c36a45e4b13eb337 -glean-parser==14.0.1 ; python_version >= "3.8" and python_version < "4.0" \ - --hash=sha256:3275ca235885c99da659fa7d9bf929b8fb020df79d26fcbec317328c369cd039 \ - --hash=sha256:3e9e5f99ad8592300e364b70d6247b21c445774a73a2ad274677fb58a0065809 +glean-parser==14.1.2 ; python_version >= "3.8" and python_version < "4.0" \ + --hash=sha256:38be7d4e0fab0f83340e3427914e08a8631c7fab088a8c60e9b543cab6ea830c \ + --hash=sha256:c3e87165fe0a0fcbcb28b76bbad025601a86eb447c5779472b62915c46cd44ab idna==2.10 ; python_version >= "3.8" and python_version < "4.0" \ --hash=sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6 \ --hash=sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0 @@ -492,6 +492,7 @@ pyyaml==6.0.1 ; python_version >= "3.8" and python_version < "4.0" \ --hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \ --hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \ --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \ + --hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \ --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \ --hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \ --hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \ diff --git a/toolkit/components/glean/api/src/private/ping.rs b/toolkit/components/glean/api/src/private/ping.rs index 5defa9b5c63e..baea10bed878 100644 --- a/toolkit/components/glean/api/src/private/ping.rs +++ b/toolkit/components/glean/api/src/private/ping.rs @@ -11,7 +11,7 @@ use crate::ipc::need_ipc; /// See [Glean Pings](https://mozilla.github.io/glean/book/user/pings/index.html). #[derive(Clone)] pub enum Ping { - Parent(glean::private::PingType), + Parent(glean::private::PingType, String), Child, } @@ -38,16 +38,20 @@ impl Ping { if need_ipc() { Ping::Child } else { - Ping::Parent(glean::private::PingType::new( + let name = name.into(); + Ping::Parent( + glean::private::PingType::new( + name.clone(), + include_client_id, + send_if_empty, + precise_timestamps, + include_info_sections, + enabled, + schedules_pings, + reason_codes, + ), name, - include_client_id, - send_if_empty, - precise_timestamps, - include_info_sections, - enabled, - schedules_pings, - reason_codes, - )) + ) } } @@ -61,7 +65,7 @@ impl Ping { /// `send_if_empty` is `false`). pub fn test_before_next_submit(&self, cb: impl FnOnce(Option<&str>) + Send + 'static) { match self { - Ping::Parent(p) => p.test_before_next_submit(cb), + Ping::Parent(p, _) => p.test_before_next_submit(cb), Ping::Child => { panic!("Cannot use ping test API from non-parent process!"); } @@ -79,8 +83,9 @@ impl glean::traits::Ping for Ping { /// `ping_info.reason` part of the payload. pub fn submit(&self, reason: Option<&str>) { match self { - Ping::Parent(p) => { + Ping::Parent(p, name) => { p.submit(reason); + crate::pings::schedule_pings(&name, reason); } Ping::Child => { log::error!( diff --git a/toolkit/components/glean/build_scripts/glean_parser_ext/rust.py b/toolkit/components/glean/build_scripts/glean_parser_ext/rust.py index 4b2b35886b2c..5a9d07ac989f 100644 --- a/toolkit/components/glean/build_scripts/glean_parser_ext/rust.py +++ b/toolkit/components/glean/build_scripts/glean_parser_ext/rust.py @@ -174,6 +174,22 @@ def extra_keys(allowed_extra_keys): return "&[" + ", ".join(map(lambda key: '"' + key + '"', allowed_extra_keys)) + "]" +def get_schedule_reverse_map(objs): + ping_schedule_reverse_map = dict() + if "pings" in objs: + for ping_key, ping_val in objs["pings"].items(): + for ping_schedule in ping_val.metadata.get("ping_schedule", []): + if ping_schedule not in ping_schedule_reverse_map: + ping_schedule_reverse_map[ping_schedule] = set() + ping_schedule_reverse_map[ping_schedule].add(ping_key) + + for ping, schedules in ping_schedule_reverse_map.items(): + sorted_schedule = sorted(schedules) + ping_schedule_reverse_map[ping] = sorted_schedule + + return ping_schedule_reverse_map + + def output_rust(objs, output_fd, ping_names_by_app_id, options={}): """ Given a tree of objects, output Rust code to the file-like object `output_fd`. @@ -205,6 +221,7 @@ def output_rust(objs, output_fd, ping_names_by_app_id, options={}): util.get_jinja2_template = get_local_template get_metric_id = generate_metric_ids(objs) get_ping_id = generate_ping_ids(objs) + ping_schedule_reverse_map = get_schedule_reverse_map(objs) # Map from a tuple (const, typ) to an array of tuples (id, path) # where: @@ -311,6 +328,7 @@ def output_rust(objs, output_fd, ping_names_by_app_id, options={}): labeleds_by_id_by_type=labeleds_by_id_by_type, submetric_bit=ID_BITS - ID_SIGNAL_BITS, ping_names_by_app_id=ping_names_by_app_id, + ping_schedule_reverse_map=ping_schedule_reverse_map, ) ) output_fd.write("\n") diff --git a/toolkit/components/glean/build_scripts/glean_parser_ext/templates/rust_pings.jinja2 b/toolkit/components/glean/build_scripts/glean_parser_ext/templates/rust_pings.jinja2 index 1a95b8f25ca2..b85019a55d30 100644 --- a/toolkit/components/glean/build_scripts/glean_parser_ext/templates/rust_pings.jinja2 +++ b/toolkit/components/glean/build_scripts/glean_parser_ext/templates/rust_pings.jinja2 @@ -54,6 +54,37 @@ pub fn register_pings(application_id: Option<&str>) { } } +/// Schedule pings alongside a parent ping. +/// +/// Should be called in `submit` of the parent ping +/// to also submit pings that should ride along. +/// +/// # Arguments +/// +/// `submitted_ping`: The parent ping that is submitted +/// `reason`: The original reason for the submitted ping. +/// Will be used for the ride-along ping too. +#[doc(hidden)] +pub fn schedule_pings(submitted_ping: &str, reason: Option<&str>) { + {% if ping_schedule_reverse_map|length %} + match submitted_ping { + {% for ping, schedule in ping_schedule_reverse_map.items() %} + "{{ping}}" => { + log::info!("Submitting pings {{ schedule|join(', ') }} along with {{ping}}"); + {% for ping_name in schedule %} + let _ = {{ ping_name|snake_case }}.submit(reason); + {% endfor %} + }, + {% endfor %} + _ => {}, + } + {% else %} + // Ignore arguments. + _ = submitted_ping; + _ = reason; + {% endif %} +} + #[cfg(feature = "with_gecko")] pub(crate) fn submit_ping_by_id(id: u32, reason: Option<&str>) { if id & (1 << crate::factory::DYNAMIC_PING_BIT) > 0 { diff --git a/toolkit/components/glean/tests/gtest/TestFog.cpp b/toolkit/components/glean/tests/gtest/TestFog.cpp index f90a73f8bc5e..5a898837a3d8 100644 --- a/toolkit/components/glean/tests/gtest/TestFog.cpp +++ b/toolkit/components/glean/tests/gtest/TestFog.cpp @@ -493,3 +493,6 @@ TEST_F(FOGFixture, TestRustInGTest) { Rust_TestRustInGTest(); } extern "C" void Rust_TestJogfile(); TEST_F(FOGFixture, TestJogfile) { Rust_TestJogfile(); } + +extern "C" void Rust_TestRideAlongPing(); +TEST_F(FOGFixture, TestRustRideAlongPing) { Rust_TestRideAlongPing(); } diff --git a/toolkit/components/glean/tests/gtest/test.rs b/toolkit/components/glean/tests/gtest/test.rs index 90ad67aebbc9..722d3996cf55 100644 --- a/toolkit/components/glean/tests/gtest/test.rs +++ b/toolkit/components/glean/tests/gtest/test.rs @@ -1,8 +1,11 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; + extern crate firefox_on_glean; -use firefox_on_glean::metrics; +use firefox_on_glean::{metrics, pings}; extern crate nsstring; use nsstring::nsString; @@ -53,3 +56,33 @@ pub extern "C" fn Rust_TestJogfile() { // If it can't, that's perhaps a sign that the inner workings need to be updated. expect!(jog::jog_load_jogfile(&nsString::from("jogfile_output"))); } + +#[no_mangle] +pub extern "C" fn Rust_TestRideAlongPing() { + // A similar test exists in `xpcshell/test_Glean.js`. + // But here we can test that the `test_before_next_submit` callback + // is correctly called. + + let test_submitted = Arc::new(AtomicBool::new(false)); + let ride_along_submitted = Arc::new(AtomicBool::new(false)); + + { + let test_submitted = Arc::clone(&test_submitted); + pings::test_ping.test_before_next_submit(move |_reason| { + test_submitted.store(true, Ordering::Release); + }); + } + + { + let ride_along_submitted = Arc::clone(&ride_along_submitted); + pings::ride_along_ping.test_before_next_submit(move |_reason| { + ride_along_submitted.store(true, Ordering::Release); + }); + } + + // Submit only a single ping, the other will ride along. + pings::test_ping.submit(None); + + expect!(test_submitted.load(Ordering::Acquire)); + expect!(ride_along_submitted.load(Ordering::Acquire)); +} diff --git a/toolkit/components/glean/tests/pytest/pings_test_output b/toolkit/components/glean/tests/pytest/pings_test_output index 7214cd175671..b72736d0a706 100644 --- a/toolkit/components/glean/tests/pytest/pings_test_output +++ b/toolkit/components/glean/tests/pytest/pings_test_output @@ -119,6 +119,23 @@ pub fn register_pings(application_id: Option<&str>) { } } +/// Schedule pings alongside a parent ping. +/// +/// Should be called in `submit` of the parent ping +/// to also submit pings that should ride along. +/// +/// # Arguments +/// +/// `submitted_ping`: The parent ping that is submitted +/// `reason`: The original reason for the submitted ping. +/// Will be used for the ride-along ping too. +#[doc(hidden)] +pub fn schedule_pings(submitted_ping: &str, reason: Option<&str>) { + // Ignore arguments. + _ = submitted_ping; + _ = reason; +} + #[cfg(feature = "with_gecko")] pub(crate) fn submit_ping_by_id(id: u32, reason: Option<&str>) { if id & (1 << crate::factory::DYNAMIC_PING_BIT) > 0 { diff --git a/toolkit/components/glean/tests/test_metrics.yaml b/toolkit/components/glean/tests/test_metrics.yaml index 7e9992424f99..a2c0b951ab4c 100644 --- a/toolkit/components/glean/tests/test_metrics.yaml +++ b/toolkit/components/glean/tests/test_metrics.yaml @@ -24,6 +24,7 @@ test_only: expires: never send_in_pings: - test-ping + - ride-along-ping can_we_time_it: type: timespan diff --git a/toolkit/components/glean/tests/test_pings.yaml b/toolkit/components/glean/tests/test_pings.yaml index 8bae13215ebd..addbf9fc1882 100644 --- a/toolkit/components/glean/tests/test_pings.yaml +++ b/toolkit/components/glean/tests/test_pings.yaml @@ -59,3 +59,20 @@ test-ohttp-ping: - glean-team@mozilla.com no_lint: - REDUNDANT_PING + +ride-along-ping: + description: | + This ping is for tests only. + include_client_id: false + send_if_empty: true + bugs: + - https://bugzilla.mozilla.org/1894270 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1894270#c1 + notification_emails: + - glean-team@mozilla.com + no_lint: + - REDUNDANT_PING + metadata: + ping_schedule: + - test-ping diff --git a/toolkit/components/glean/tests/xpcshell/test_Glean.js b/toolkit/components/glean/tests/xpcshell/test_Glean.js index f5661f91b6c7..22c08bf324a5 100644 --- a/toolkit/components/glean/tests/xpcshell/test_Glean.js +++ b/toolkit/components/glean/tests/xpcshell/test_Glean.js @@ -628,3 +628,31 @@ add_task(async function test_fog_complex_object_works() { result = Glean.testOnly.crashStack.testGetValue(); Assert.deepEqual(stack, result); }); + +add_task(function test_fog_ride_along_pings() { + Assert.equal(null, Glean.testOnly.badCode.testGetValue("test-ping")); + Assert.equal(null, Glean.testOnly.badCode.testGetValue("ride-along-ping")); + + Glean.testOnly.badCode.add(37); + Assert.equal(37, Glean.testOnly.badCode.testGetValue("test-ping")); + Assert.equal(37, Glean.testOnly.badCode.testGetValue("ride-along-ping")); + + let testPingSubmitted = false; + + GleanPings.testPing.testBeforeNextSubmit(() => { + testPingSubmitted = true; + }); + // FIXME(bug 1896356): + // We can't use `testBeforeNextSubmit` for `ride-along-ping` + // because it's triggered internally, but the callback would only be available + // in the C++ bits, not in the internal Rust parts. + + // Submit only a single ping, the other will ride along. + GleanPings.testPing.submit(); + + Assert.ok(testPingSubmitted, "Test ping was submitted, callback was called."); + + // Both pings have been submitted, so the values should be cleared. + Assert.equal(null, Glean.testOnly.badCode.testGetValue("test-ping")); + Assert.equal(null, Glean.testOnly.badCode.testGetValue("ride-along-ping")); +});