summaryrefslogtreecommitdiffstats
path: root/python/mach/mach/test/test_telemetry.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/mach/mach/test/test_telemetry.py')
-rw-r--r--python/mach/mach/test/test_telemetry.py198
1 files changed, 198 insertions, 0 deletions
diff --git a/python/mach/mach/test/test_telemetry.py b/python/mach/mach/test/test_telemetry.py
new file mode 100644
index 0000000000..ded23420b8
--- /dev/null
+++ b/python/mach/mach/test/test_telemetry.py
@@ -0,0 +1,198 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+from __future__ import absolute_import, print_function
+
+import json
+import os
+import platform
+import subprocess
+import sys
+
+import buildconfig
+import mozunit
+import pytest
+from six import text_type, PY3
+
+from mozboot.bootstrap import update_or_create_build_telemetry_config
+
+TELEMETRY_LOAD_ERROR = """
+Error loading telemetry. mach output:
+=========================================================
+%s
+=========================================================
+"""
+
+
+@pytest.fixture
+def run_mach(tmpdir):
+ """Return a function that runs mach with the provided arguments and then returns
+ a list of the data contained within any telemetry entries generated during the command.
+ """
+ # Use tmpdir as the mozbuild state path, and enable telemetry in
+ # a machrc there.
+ if PY3:
+ update_or_create_build_telemetry_config(str(tmpdir.join("machrc")))
+ else:
+ update_or_create_build_telemetry_config(text_type(tmpdir.join("machrc")))
+ env = dict(os.environ)
+ env["MOZBUILD_STATE_PATH"] = str(tmpdir)
+ env["TEST_MACH_TELEMETRY_NO_SUBMIT"] = "1"
+ mach = os.path.join(buildconfig.topsrcdir, "mach")
+
+ def run(*args, **kwargs):
+ # Let whatever mach command we invoke from tests believe it's the main command.
+ mach_main_pid = env.pop("MACH_MAIN_PID")
+ moz_automation = env.pop("MOZ_AUTOMATION", None)
+ task_id = env.pop("TASK_ID", None)
+
+ # Run mach with the provided arguments
+ out = subprocess.check_output(
+ [sys.executable, mach] + list(args),
+ stderr=subprocess.STDOUT,
+ env=env,
+ **kwargs
+ )
+
+ env["MACH_MAIN_PID"] = mach_main_pid
+ env["MOZ_AUTOMATION"] = moz_automation
+ env["TASK_ID"] = task_id
+ # Load any telemetry data that was written
+ path = tmpdir.join("telemetry", "outgoing")
+ try:
+ if PY3:
+ read_mode = "r"
+ else:
+ read_mode = "rb"
+ return [json.load(f.open(read_mode)) for f in path.listdir()]
+ except EnvironmentError:
+ print(TELEMETRY_LOAD_ERROR % out, file=sys.stderr)
+ for p in path.parts(reverse=True):
+ if not p.check(dir=1):
+ print('Path does not exist: "%s"' % p, file=sys.stderr)
+ raise
+
+ return run
+
+
+def test_simple(run_mach, tmpdir):
+ data = run_mach("python", "-c", "pass")
+ assert len(data) == 1
+ d = data[0]
+ assert d["command"] == "python"
+ assert d["argv"] == ["-c", "pass"]
+ if PY3:
+ read_mode = "r"
+ else:
+ read_mode = "rb"
+ client_id_data = json.load(tmpdir.join("telemetry_client_id.json").open(read_mode))
+ assert "client_id" in client_id_data
+ assert client_id_data["client_id"] == d["client_id"]
+
+
+@pytest.mark.xfail(
+ platform.system() == "Windows" and PY3,
+ reason="Windows and Python3 mozpath filtering issues",
+)
+def test_path_filtering(run_mach, tmpdir):
+ srcdir_path = os.path.join(buildconfig.topsrcdir, "a")
+ srcdir_path_2 = os.path.join(buildconfig.topsrcdir, "a/b/c")
+ objdir_path = os.path.join(buildconfig.topobjdir, "x")
+ objdir_path_2 = os.path.join(buildconfig.topobjdir, "x/y/z")
+ home_path = os.path.join(os.path.expanduser("~"), "something_in_home")
+ other_path = str(tmpdir.join("other"))
+ data = run_mach(
+ "python",
+ "-c",
+ "pass",
+ srcdir_path,
+ srcdir_path_2,
+ objdir_path,
+ objdir_path_2,
+ home_path,
+ other_path,
+ cwd=buildconfig.topsrcdir,
+ )
+ assert len(data) == 1
+ d = data[0]
+ expected = [
+ "-c",
+ "pass",
+ "a",
+ "a/b/c",
+ "$topobjdir/x",
+ "$topobjdir/x/y/z",
+ "$HOME/something_in_home",
+ "<path omitted>",
+ ]
+ assert d["argv"] == expected
+
+
+@pytest.mark.xfail(
+ platform.system() == "Windows" and PY3,
+ reason="Windows and Python3 mozpath filtering issues",
+)
+def test_path_filtering_in_objdir(run_mach, tmpdir):
+ srcdir_path = os.path.join(buildconfig.topsrcdir, "a")
+ srcdir_path_2 = os.path.join(buildconfig.topsrcdir, "a/b/c")
+ objdir_path = os.path.join(buildconfig.topobjdir, "x")
+ objdir_path_2 = os.path.join(buildconfig.topobjdir, "x/y/z")
+ other_path = str(tmpdir.join("other"))
+ data = run_mach(
+ "python",
+ "-c",
+ "pass",
+ srcdir_path,
+ srcdir_path_2,
+ objdir_path,
+ objdir_path_2,
+ other_path,
+ cwd=buildconfig.topobjdir,
+ )
+ assert len(data) == 1
+ d = data[0]
+ expected = [
+ "-c",
+ "pass",
+ "$topsrcdir/a",
+ "$topsrcdir/a/b/c",
+ "x",
+ "x/y/z",
+ "<path omitted>",
+ ]
+ assert d["argv"] == expected
+
+
+def test_path_filtering_other_cwd(run_mach, tmpdir):
+ srcdir_path = os.path.join(buildconfig.topsrcdir, "a")
+ srcdir_path_2 = os.path.join(buildconfig.topsrcdir, "a/b/c")
+ other_path = str(tmpdir.join("other"))
+ data = run_mach(
+ "python", "-c", "pass", srcdir_path, srcdir_path_2, other_path, cwd=str(tmpdir)
+ )
+ assert len(data) == 1
+ d = data[0]
+ expected = [
+ # non-path arguments should escape unscathed
+ "-c",
+ "pass",
+ "$topsrcdir/a",
+ "$topsrcdir/a/b/c",
+ # cwd-relative paths should be relativized
+ "other",
+ ]
+ assert d["argv"] == expected
+
+
+def test_zero_microseconds(run_mach):
+ data = run_mach(
+ "python",
+ "--exec-file",
+ os.path.join(os.path.dirname(__file__), "zero_microseconds.py"),
+ )
+ d = data[0]
+ assert d["command"] == "python"
+
+
+if __name__ == "__main__":
+ mozunit.main()