-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Python: Add various kinds of extractor telemetry #22502
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| x = 1 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| match 1: | ||
| case 1: | ||
| pass |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| #!/bin/bash | ||
|
|
||
| set -Eeuo pipefail # see https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/ | ||
|
|
||
| set -x | ||
|
|
||
| CODEQL=${CODEQL:-codeql} | ||
|
|
||
| SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" | ||
| cd "$SCRIPTDIR" | ||
|
|
||
| rm -rf db | ||
|
|
||
| $CODEQL database create db --language python --source-root repo_dir/ | ||
| python3 test_parser_telemetry.py db | ||
|
|
||
| rm -rf db |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import glob | ||
| import json | ||
| import os | ||
| import sys | ||
|
|
||
|
|
||
| database = sys.argv[1] | ||
| diagnostics = [] | ||
| diagnostic_dir = os.path.join(database, "diagnostic", "extractors", "python") | ||
| for path in glob.glob(os.path.join(diagnostic_dir, "*.jsonl")): | ||
| with open(path) as diagnostic_file: | ||
| diagnostics.extend(json.loads(line) for line in diagnostic_file) | ||
| parser_statistics = [ | ||
| diagnostic | ||
| for diagnostic in diagnostics | ||
| if diagnostic["source"]["id"] == "py/extractor/parser-statistics" | ||
| ] | ||
| actual = ( | ||
| sum(diagnostic["attributes"]["old_parser_file_count"] for diagnostic in parser_statistics), | ||
| sum( | ||
| diagnostic["attributes"]["tree_sitter_parser_file_count"] | ||
| for diagnostic in parser_statistics | ||
| ), | ||
| ) | ||
| assert actual == (1, 1), actual |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -161,3 +161,24 @@ | |
| "telemetry": true | ||
| } | ||
| } | ||
| { | ||
| "attributes": { | ||
| "extractor_flags": "default", | ||
| "extractor_version": "7.1.10", | ||
| "python_analysis_version": "3.12", | ||
| "python_runtime_version": "3.12.3" | ||
| }, | ||
| "markdownMessage": "Internal telemetry for the Python extractor.\n\nNo action needed.", | ||
| "severity": "note", | ||
| "source": { | ||
| "extractorName": "python", | ||
| "id": "py/extractor/summary", | ||
| "name": "Python extractor telemetry" | ||
| }, | ||
| "timestamp": "2026-09-01T13:41:33.056818Z", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm somewhat amazed that the test passes with this being present in the diagnostic output.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| "visibility": { | ||
| "cliSummaryTable": false, | ||
| "statusPage": false, | ||
| "telemetry": true | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,28 @@ | ||
| import os | ||
| import sys | ||
| import glob | ||
| import json | ||
| sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "..", "..", "..", "integration-tests")) | ||
| import diagnostics_test_utils | ||
|
|
||
| test_db = "db" | ||
| diagnostics_test_utils.check_diagnostics(".", test_db, skip_attributes=True) | ||
| diagnostics = [] | ||
| diagnostic_dir = os.path.join(test_db, "diagnostic", "extractors", "python") | ||
| for path in glob.glob(os.path.join(diagnostic_dir, "*.jsonl")): | ||
| with open(path) as diagnostic_file: | ||
| diagnostics.extend(json.loads(line) for line in diagnostic_file) | ||
| summary = [ | ||
| diagnostic | ||
| for diagnostic in diagnostics | ||
| if diagnostic["source"]["id"] == "py/extractor/summary" | ||
| ] | ||
| assert len(summary) == 1 | ||
| assert summary[0]["attributes"]["extractor_flags"] == "default" | ||
| diagnostics_test_utils.check_diagnostics( | ||
| ".", | ||
| test_db, | ||
| skip_attributes=True, | ||
| replacements={ | ||
| r'"py/extractor/parser-statistics"': '"cli/py/extractor/parser-statistics"' | ||
| }, | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| from semmle import cmdline | ||
|
|
||
|
|
||
| def test_records_flags_without_values(): | ||
| options, args = cmdline.parse( | ||
| [ | ||
| "--verbosity=3", | ||
| "-zall", | ||
| "-R", | ||
| "/src", | ||
| "-vv", | ||
| "--path", | ||
| "/lib", | ||
| "-p", | ||
| "/other-lib", | ||
| "module", | ||
| ] | ||
| ) | ||
|
|
||
| assert options.extractor_flags == ["p"] | ||
| assert args == ["module"] | ||
|
|
||
|
|
||
| def test_records_flags_from_option_file(tmp_path): | ||
| options_file = tmp_path / "extractor-options" | ||
| options_file.write_text("--colorize --max-import-depth 2") | ||
|
|
||
| options, _ = cmdline.parse(["-f", str(options_file)]) | ||
|
|
||
| assert options.extractor_flags == [ | ||
| "colorize", | ||
| "f", | ||
| "max-import-depth", | ||
| ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How robust is this going to be under extractor changes and runner updates? Would we need to update the test each time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is robust, because the
skip_attributes=Trueargument tocheck_diagnosticsautomatically skips the object this field is on. Admittedly that also means we're not really testing these fields, but this.expectedfile was generated from an actual run, so at the very least it worked when the test was generated.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the clarification.