summaryrefslogtreecommitdiffstats
path: root/toolkit/components/telemetry/dap/tests/xpcshell/test_dap.js
blob: 2f4712e54b43d853c5c7b2465f3d675b5b65e404 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* 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 http://mozilla.org/MPL/2.0/. */

"use strict";

const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");

const lazy = {};

ChromeUtils.defineESModuleGetters(lazy, {
  DAPTelemetrySender: "resource://gre/modules/DAPTelemetrySender.sys.mjs",
});

const BinaryOutputStream = Components.Constructor(
  "@mozilla.org/binaryoutputstream;1",
  "nsIBinaryOutputStream",
  "setOutputStream"
);

const BinaryInputStream = Components.Constructor(
  "@mozilla.org/binaryinputstream;1",
  "nsIBinaryInputStream",
  "setInputStream"
);

const PREF_LEADER = "toolkit.telemetry.dap_leader";
const PREF_HELPER = "toolkit.telemetry.dap_helper";

let received = false;
let server;
let server_addr;

function hpkeConfigHandler(request, response) {
  if (
    request.queryString ==
      "task_id=QjMD4n8l_MHBoLrbCfLTFi8hC264fC59SKHPviPF0q8" ||
    request.queryString == "task_id=DSZGMFh26hBYXNaKvhL_N4AHA3P5lDn19on1vFPBxJM"
  ) {
    let config_bytes;
    if (request.path.startsWith("/leader")) {
      config_bytes = new Uint8Array([
        47, 0, 32, 0, 1, 0, 1, 0, 32, 11, 33, 206, 33, 131, 56, 220, 82, 153,
        110, 228, 200, 53, 98, 210, 38, 177, 197, 252, 198, 36, 201, 86, 121,
        169, 238, 220, 34, 143, 112, 177, 10,
      ]);
    } else {
      config_bytes = new Uint8Array([
        42, 0, 32, 0, 1, 0, 1, 0, 32, 28, 62, 242, 195, 117, 7, 173, 149, 250,
        15, 139, 178, 86, 241, 117, 143, 75, 26, 57, 60, 88, 130, 199, 175, 195,
        9, 241, 130, 61, 47, 215, 101,
      ]);
    }
    response.setHeader("Content-Type", "application/dap-hpke-config");
    let bos = new BinaryOutputStream(response.bodyOutputStream);
    bos.writeByteArray(config_bytes);
  } else {
    Assert.ok(false, "Unknown query string.");
  }
}

function uploadHandler(request, response) {
  Assert.equal(
    request.getHeader("Content-Type"),
    "application/dap-report",
    "Wrong Content-Type header."
  );

  let body = new BinaryInputStream(request.bodyInputStream);
  Assert.equal(
    true,
    body.available() == 432 || body.available() == 20720,
    "Wrong request body size."
  );
  received = true;
  response.setStatusLine(request.httpVersion, 200);
}

add_setup(async function () {
  do_get_profile();
  Services.fog.initializeFOG();

  // Set up a mock server to represent the DAP endpoints.
  server = new HttpServer();
  server.registerPathHandler("/leader_endpoint/hpke_config", hpkeConfigHandler);
  server.registerPathHandler("/helper_endpoint/hpke_config", hpkeConfigHandler);
  server.registerPathHandler("/leader_endpoint/upload", uploadHandler);
  server.start(-1);

  const orig_leader = Services.prefs.getStringPref(PREF_LEADER);
  const orig_helper = Services.prefs.getStringPref(PREF_HELPER);
  const i = server.identity;
  server_addr = i.primaryScheme + "://" + i.primaryHost + ":" + i.primaryPort;
  Services.prefs.setStringPref(PREF_LEADER, server_addr + "/leader_endpoint");
  Services.prefs.setStringPref(PREF_HELPER, server_addr + "/helper_endpoint");
  registerCleanupFunction(() => {
    Services.prefs.setStringPref(PREF_LEADER, orig_leader);
    Services.prefs.setStringPref(PREF_HELPER, orig_helper);

    return new Promise(resolve => {
      server.stop(resolve);
    });
  });
});

add_task(async function testVerificationTask() {
  Services.fog.testResetFOG();
  let before = Glean.dap.uploadStatus.success.testGetValue() ?? 0;
  await lazy.DAPTelemetrySender.sendTestReports();
  let after = Glean.dap.uploadStatus.success.testGetValue();
  Assert.equal(before + 2, after, "Successful submissions should be counted.");
  Assert.ok(received, "Report upload successful.");
});

add_task(async function testNetworkError() {
  Services.fog.testResetFOG();
  let before = Glean.dap.reportGenerationStatus.failure.testGetValue() ?? 0;
  Services.prefs.setStringPref(PREF_LEADER, server_addr + "/invalid-endpoint");
  await lazy.DAPTelemetrySender.sendTestReports();
  let after = Glean.dap.reportGenerationStatus.failure.testGetValue() ?? 0;
  Assert.equal(
    before + 2,
    after,
    "Failed report generation should be counted."
  );
});