Exemplo n.º 1
0
def test_queued_recorded_metrics_correctly_during_init():
    Glean._reset()

    # Enable queueing
    Dispatcher.set_task_queueing(True)

    counter_metric = CounterMetricType(
        disabled=False,
        category="telemetry",
        lifetime=Lifetime.APPLICATION,
        name="counter_metric",
        send_in_pings=["store1"],
    )

    for i in range(2):
        counter_metric.add()

    Glean.initialize(
        application_id=GLEAN_APP_ID,
        application_version=glean_version,
        upload_enabled=True,
    )

    assert counter_metric.test_has_value()
    assert 2 == counter_metric.test_get_value()
Exemplo n.º 2
0
def test_no_sending_deletion_ping_if_unchanged_outside_of_run(safe_httpserver, tmpdir):
    safe_httpserver.serve_content(b"", code=200)
    Glean._reset()
    config = Configuration(server_endpoint=safe_httpserver.url)

    Glean.initialize(
        application_id=GLEAN_APP_ID,
        application_version=glean_version,
        upload_enabled=False,
        data_dir=Path(str(tmpdir)),
        configuration=config,
    )

    assert 0 == len(safe_httpserver.requests)

    Glean._reset()

    Glean.initialize(
        application_id=GLEAN_APP_ID,
        application_version=glean_version,
        upload_enabled=False,
        data_dir=Path(str(tmpdir)),
        configuration=config,
    )

    assert 0 == len(safe_httpserver.requests)
Exemplo n.º 3
0
def test_tempdir_is_cleared_multiprocess(safe_httpserver):
    safe_httpserver.serve_content(b"", code=200)
    Glean._configuration.server_endpoint = safe_httpserver.url

    # This test requires us to write a few files in the pending pings
    # directory, to which language bindings have theoretically no access.
    # Manually create the path to that directory, at the risk of breaking
    # the test in the future, if that changes in the Rust code.
    pings_dir = Glean._data_dir / "pending_pings"
    pings_dir.mkdir()

    for _ in range(10):
        with (pings_dir / str(uuid.uuid4())).open("wb") as fd:
            fd.write(b"/data/path/\n")
            fd.write(b"{}\n")

    # Make sure that resetting while the PingUploadWorker is running doesn't
    # delete the directory out from under the PingUploadWorker.
    p1 = PingUploadWorker._process()
    Glean._reset()

    p1.wait()
    assert p1.returncode == 0

    assert 10 == len(safe_httpserver.requests)
Exemplo n.º 4
0
def reset_glean(*,
                application_id: str,
                application_version: str,
                configuration: Optional[Configuration] = None,
                clear_stores: bool = True):
    """
    Resets the Glean singleton.

    Args:
        application_id (str): The application id to use when sending pings.
        application_version (str): The version of the application sending
            Glean data.
        configuration (glean.config.Configuration): (optional) An object with
            global settings.
    """
    from glean import Glean
    from glean._dispatcher import Dispatcher

    Dispatcher._testing_mode = True

    data_dir = None  # type: Optional[Path]
    if not clear_stores:
        Glean._destroy_data_dir = False
        data_dir = Glean._data_dir

    Glean._reset()
    Glean.initialize(
        application_id=application_id,
        application_version=application_version,
        upload_enabled=True,
        configuration=configuration,
        data_dir=data_dir,
    )
Exemplo n.º 5
0
def test_set_application_id_and_version(safe_httpserver):
    safe_httpserver.serve_content(b"", code=200)
    Glean._reset()

    Glean._initialize_with_tempdir_for_testing(
        application_id="my-id",
        application_version="my-version",
        upload_enabled=True,
        configuration=Configuration(server_endpoint=safe_httpserver.url),
    )

    assert (
        "my-version"
        == _builtins.metrics.glean.internal.metrics.app_display_version.test_get_value()
    )

    Glean._configuration.server_endpoint = safe_httpserver.url

    _builtins.pings.baseline.submit()

    assert 1 == len(safe_httpserver.requests)

    request = safe_httpserver.requests[0]
    assert "baseline" in request.url
    assert "my-id" in request.url
Exemplo n.º 6
0
def test_other_label_without_predefined_labels_before_glean_init():
    labeled_counter_metric = metrics.LabeledCounterMetricType(
        disabled=False,
        category="telemetry",
        lifetime=Lifetime.APPLICATION,
        name="labeled_counter_metric",
        send_in_pings=["metrics"],
    )

    Glean._reset()
    Dispatcher.set_task_queueing(True)

    for i in range(21):
        labeled_counter_metric["label_{}".format(i)].add(1)
    labeled_counter_metric["label_0"].add(1)

    Glean.initialize(
        application_id="glean-python-test",
        application_version=glean_version,
        upload_enabled=True,
    )

    assert 2 == labeled_counter_metric["label_0"].test_get_value()
    for i in range(1, 16):
        assert 1 == labeled_counter_metric["label_{}".format(
            i)].test_get_value()
    assert 5 == labeled_counter_metric["__other__"].test_get_value()
Exemplo n.º 7
0
def test_setting_upload_enabled_before_initialization_should_not_crash():
    Glean._reset()
    Glean.set_upload_enabled(True)
    Glean.initialize(
        application_id=GLEAN_APP_ID,
        application_version=glean_version,
        upload_enabled=True,
    )
Exemplo n.º 8
0
def test_data_dir_is_required():
    Glean._reset()

    with pytest.raises(TypeError):
        Glean.initialize(
            application_id=GLEAN_APP_ID,
            application_version=glean_version,
            upload_enabled=True,
            configuration=Glean._configuration,
        )
Exemplo n.º 9
0
def test_the_app_channel_must_be_correctly_set():
    Glean._reset()
    Glean._initialize_with_tempdir_for_testing(
        application_id=GLEAN_APP_ID,
        application_version=glean_version,
        upload_enabled=True,
        configuration=Configuration(channel="my-test-channel"),
    )
    assert ("my-test-channel" == _builtins.metrics.glean.internal.metrics.
            app_channel.test_get_value())
Exemplo n.º 10
0
def test_set_application_id_and_version():
    Glean._reset()

    Glean.initialize(application_id="my-id",
                     application_version="my-version",
                     upload_enabled=True)

    assert ("my-id" == _builtins.metrics.glean.internal.metrics.app_build.
            test_get_value())
    assert ("my-version" == _builtins.metrics.glean.internal.metrics.
            app_display_version.test_get_value())
Exemplo n.º 11
0
def test_app_display_version_unknown():
    from glean import _builtins

    Glean._reset()
    Glean._initialize_with_tempdir_for_testing(
        application_id=GLEAN_APP_ID,
        application_version=None,
        upload_enabled=True,
    )

    assert ("Unknown" == _builtins.metrics.glean.internal.metrics.
            app_display_version.test_get_value())
Exemplo n.º 12
0
def test_set_application_build_id():
    Glean._reset()

    Glean._initialize_with_tempdir_for_testing(
        application_id="my-id",
        application_version="my-version",
        application_build_id="123ABC",
        upload_enabled=True,
    )

    assert ("123ABC" == _builtins.metrics.glean.internal.metrics.app_build.
            test_get_value())
Exemplo n.º 13
0
def test_recording_upload_errors_doesnt_clobber_database(
        tmpdir, safe_httpserver, monkeypatch):
    """
    Test that running the ping uploader subprocess doesn't clobber the
    database. If, under some bug, the subprocess had "upload_enabled" set to
    True, it could record upload errors in the database, clobbering any metrics
    that might have meanwhile been recorded in the main process.

    This test is known to fail if "upload_enabled" is set to `True` in the
    subprocess.
    """
    tmpdir = Path(tmpdir)

    Glean._reset()
    Glean.initialize(
        application_id=GLEAN_APP_ID,
        application_version=glean_version,
        upload_enabled=True,
        data_dir=tmpdir,
    )

    counter_metric = CounterMetricType(
        disabled=False,
        category="telemetry",
        lifetime=Lifetime.PING,
        name="counter_metric",
        send_in_pings=["baseline"],
    )
    counter_metric.add(10)

    safe_httpserver.serve_content(b"", code=400)

    # Force the ping upload worker into a separate process
    monkeypatch.setattr(PingUploadWorker, "process", PingUploadWorker._process)
    Glean._configuration._server_endpoint = safe_httpserver.url
    Glean._submit_ping_by_name("baseline")
    ProcessDispatcher._wait_for_last_process()

    assert 1 == len(safe_httpserver.requests)

    # Force a reload of the database from disk
    Glean._reset()
    Glean.initialize(
        application_id=GLEAN_APP_ID,
        application_version=glean_version,
        upload_enabled=True,
        data_dir=tmpdir,
    )

    metric = get_upload_failure_metric()
    assert not metric["status_code_4xx"].test_has_value()
Exemplo n.º 14
0
def test_presubmit_makes_a_valid_ping(tmpdir, ping_schema_url, monkeypatch):
    # Bug 1648140: Submitting a ping prior to initialize meant that the core
    # metrics wouldn't yet be set.

    info_path = Path(str(tmpdir)) / "info.txt"

    Glean._reset()

    ping_name = "preinit_ping"
    ping = PingType(name=ping_name,
                    include_client_id=True,
                    send_if_empty=True,
                    reason_codes=[])

    # This test relies on testing mode to be disabled, since we need to prove the
    # real-world async behaviour of this.
    Dispatcher._testing_mode = False
    Dispatcher._queue_initial_tasks = True

    # Submit a ping prior to calling initialize
    ping.submit()
    Glean._initialize_with_tempdir_for_testing(
        application_id=GLEAN_APP_ID,
        application_version=glean_version,
        upload_enabled=True,
        configuration=Glean._configuration,
    )

    monkeypatch.setattr(Glean._configuration, "ping_uploader",
                        _RecordingUploader(info_path))

    # Wait until the work is complete
    Dispatcher._task_worker._queue.join()

    while not info_path.exists():
        time.sleep(0.1)

    with info_path.open("r") as fd:
        url_path = fd.readline()
        serialized_ping = fd.readline()

    print(url_path)
    assert ping_name == url_path.split("/")[3]

    assert 0 == validate_ping.validate_ping(
        io.StringIO(serialized_ping),
        sys.stdout,
        schema_url=ping_schema_url,
    )
Exemplo n.º 15
0
def reset_glean(
    *,
    application_id: str,
    application_version: str,
    configuration: Optional[Configuration] = None,
    clear_stores: bool = True
) -> None:
    """
    Resets the Glean singleton.

    Args:
        application_id (str): The application id to use when sending pings.
        application_version (str): The version of the application sending
            Glean data.
        configuration (glean.config.Configuration): (optional) An object with
            global settings.
    """
    from glean import Glean
    from glean._dispatcher import Dispatcher

    data_dir: Optional[Path] = None
    if not clear_stores:
        Glean._destroy_data_dir = False
        data_dir = Glean._data_dir

    Glean._reset()

    # `_testing_mode` should be changed *after* `Glean._reset()` is run, so
    # that `Glean` properly joins on the worker thread when `_testing_mode` is
    # False.
    Dispatcher._testing_mode = True

    if data_dir is None:
        Glean._initialize_with_tempdir_for_testing(
            application_id=application_id,
            application_version=application_version,
            upload_enabled=True,
            configuration=configuration,
        )
    else:
        Glean.initialize(
            application_id=application_id,
            application_version=application_version,
            upload_enabled=True,
            data_dir=data_dir,
            configuration=configuration,
        )
Exemplo n.º 16
0
def test_sending_deletion_ping_if_disabled_outside_of_run(
        tmpdir, ping_schema_url):
    info_path = Path(str(tmpdir)) / "info.txt"
    data_dir = Path(str(tmpdir)) / "glean"

    Glean._reset()

    Glean.initialize(
        application_id=GLEAN_APP_ID,
        application_version=glean_version,
        upload_enabled=True,
        data_dir=data_dir,
        configuration=Configuration(
            ping_uploader=_RecordingUploader(info_path)),
    )

    Glean._reset()

    Glean.initialize(
        application_id=GLEAN_APP_ID,
        application_version=glean_version,
        upload_enabled=False,
        data_dir=data_dir,
        configuration=Configuration(
            ping_uploader=_RecordingUploader(info_path)),
    )

    while not info_path.exists():
        time.sleep(0.1)

    with info_path.open("r") as fd:
        url_path = fd.readline()
        serialized_ping = fd.readline()

    assert "deletion-request" == url_path.split("/")[3]

    json_content = json.loads(serialized_ping)

    assert 0 == validate_ping.validate_ping(
        io.StringIO(serialized_ping),
        sys.stdout,
        schema_url=ping_schema_url,
    )

    assert not json_content["client_info"]["client_id"].startswith("c0ffee")
Exemplo n.º 17
0
def test_flipping_upload_enabled_respects_order_of_events(tmpdir, monkeypatch):
    Glean._reset()

    info_path = Path(str(tmpdir)) / "info.txt"

    # We create a ping and a metric before we initialize Glean
    ping = PingType(
        name="sample_ping_1",
        include_client_id=True,
        send_if_empty=True,
        reason_codes=[],
    )

    # This test relies on testing mode to be disabled, since we need to prove the
    # real-world async behaviour of this.
    Dispatcher._testing_mode = False
    Dispatcher._queue_initial_tasks = True

    configuration = Glean._configuration
    configuration.ping_uploader = _RecordingUploader(info_path)
    Glean._initialize_with_tempdir_for_testing(
        application_id=GLEAN_APP_ID,
        application_version=glean_version,
        upload_enabled=True,
        configuration=Glean._configuration,
    )

    # Glean might still be initializing. Disable upload.
    Glean.set_upload_enabled(False)
    # Submit a custom ping.
    ping.submit()

    # Wait until the work is complete
    Dispatcher._task_worker._queue.join()

    while not info_path.exists():
        time.sleep(0.1)

    with info_path.open("r") as fd:
        url_path = fd.readline()

    # Validate we got the deletion-request ping
    assert "deletion-request" == url_path.split("/")[3]
Exemplo n.º 18
0
def test_experiments_recording_before_glean_inits():
    # This test relies on Glean not being initialized and task
    # queuing to be on.
    Glean._reset()

    Glean.set_experiment_active("experiment_set_preinit", "branch_a")
    Glean.set_experiment_active("experiment_preinit_disabled", "branch_a")

    Glean.set_experiment_inactive("experiment_preinit_disabled")

    # This will init Glean and flush the dispatcher's queue.
    Glean.initialize(
        application_id=GLEAN_APP_ID,
        application_version=glean_version,
        upload_enabled=True,
    )

    assert Glean.test_is_experiment_active("experiment_set_preinit")
    assert not Glean.test_is_experiment_active("experiment_preinit_disabled")
Exemplo n.º 19
0
def test_client_activity_api(tmpdir, monkeypatch):
    Glean._reset()

    info_path = Path(str(tmpdir)) / "info.txt"

    # This test relies on testing mode to be disabled, since we need to prove the
    # real-world async behaviour of this.

    configuration = Glean._configuration
    configuration.ping_uploader = _RecordingUploader(info_path)
    Glean._initialize_with_tempdir_for_testing(
        application_id=GLEAN_APP_ID,
        application_version=glean_version,
        upload_enabled=True,
        configuration=Glean._configuration,
    )

    # Wait until the work is complete
    Dispatcher._task_worker._queue.join()

    # Making it active
    Glean.handle_client_active()

    url_path, payload = wait_for_ping(info_path)
    assert "baseline" == url_path.split("/")[3]
    assert payload["ping_info"]["reason"] == "active"
    assert "timespan" not in payload["metrics"]

    # Making it inactive
    Glean.handle_client_inactive()

    url_path, payload = wait_for_ping(info_path)
    assert "baseline" == url_path.split("/")[3]
    assert payload["ping_info"]["reason"] == "inactive"
    assert "glean.baseline.duration" in payload["metrics"]["timespan"]

    # Once more active
    Glean.handle_client_active()

    url_path, payload = wait_for_ping(info_path)
    assert "baseline" == url_path.split("/")[3]
    assert payload["ping_info"]["reason"] == "active"
    assert "timespan" not in payload["metrics"]
Exemplo n.º 20
0
def test_clear_application_lifetime_metrics(tmpdir):
    Glean._reset()

    Glean.initialize(
        application_id=GLEAN_APP_ID,
        application_version=glean_version,
        upload_enabled=True,
        data_dir=Path(str(tmpdir)),
    )

    counter_metric = CounterMetricType(
        disabled=False,
        category="test.telemetry",
        lifetime=Lifetime.APPLICATION,
        name="lifetime_reset",
        send_in_pings=["store1"],
    )

    # Additionally get metrics using the loader.
    metrics = load_metrics(ROOT / "data" / "core.yaml",
                           config={"allow_reserved": True})

    counter_metric.add(10)
    metrics.core_ping.seq.add(10)

    assert counter_metric.test_has_value()
    assert counter_metric.test_get_value() == 10

    assert metrics.core_ping.seq.test_has_value()
    assert metrics.core_ping.seq.test_get_value() == 10

    Glean._reset()

    Glean.initialize(
        application_id=GLEAN_APP_ID,
        application_version=glean_version,
        upload_enabled=True,
        data_dir=Path(str(tmpdir)),
    )

    assert not counter_metric.test_has_value()
    assert not metrics.core_ping.seq.test_has_value()
Exemplo n.º 21
0
def test_tempdir_is_cleared_multiprocess(safe_httpserver):
    safe_httpserver.serve_content(b"", code=200)
    Glean._configuration.server_endpoint = safe_httpserver.url

    pings_dir = PingUploadWorker.storage_directory()
    pings_dir.mkdir()

    for i in range(100):
        with (pings_dir / str(uuid.uuid4())).open("wb") as fd:
            fd.write(b"/data/path/\n")
            fd.write(b"{}\n")

    # Make sure that resetting while the PingUploadWorker is running doesn't
    # delete the directory out from under the PingUploadWorker.
    p1 = PingUploadWorker._process()
    Glean._reset()

    p1.wait()
    assert p1.returncode == 0

    assert 100 == len(safe_httpserver.requests)
Exemplo n.º 22
0
def test_initialize_must_not_crash_if_data_dir_is_messed_up(tmpdir):
    filename = tmpdir / "dummy_file"

    # Create a file in a temporary directory
    with filename.open("w") as fd:
        fd.write("Contents\n")

    Glean._reset()
    assert False is Glean.is_initialized()

    # Pass in the filename as the data_dir
    Glean.initialize(
        application_id=GLEAN_APP_ID,
        application_version=glean_version,
        upload_enabled=True,
        data_dir=filename,
    )

    # This should cause initialization to fail
    assert False is Glean.is_initialized()

    shutil.rmtree(str(tmpdir))
Exemplo n.º 23
0
def test_that_thread_joins_before_directory_is_deleted_in_reset():
    Dispatcher._testing_mode = False
    Dispatcher._queue_initial_tasks = False
    thread_canary = [0]

    boolean_metric = metrics.BooleanMetricType(
        disabled=False,
        category="telemetry",
        lifetime=Lifetime.APPLICATION,
        name="boolean_metric",
        send_in_pings=["store1"],
    )

    def slow_task():
        time.sleep(1)
        # This will cause a Rust panic if the data directory was deleted in
        # Glean._reset() before this has a chance to run.
        boolean_metric.set(True)
        thread_canary[0] = 1

    Dispatcher.launch(slow_task)
    Glean._reset()

    assert thread_canary[0] == 1
Exemplo n.º 24
0
def test_tempdir_is_cleared():
    tempdir = Glean._data_dir

    Glean._reset()

    assert not tempdir.exists()