gecko-dev/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp
Gabriele Svelto 5dc21d568c Bug 1600545 - Remove useless inclusions of header files generated from IDL files in modules/, netwerk/, parser/, security/, startupcache/, storage/, toolkit/, tools/, uriloader/, widget/, xpcom/ and xpfe/ r=Ehsan
The inclusions were removed with the following very crude script and the
resulting breakage was fixed up by hand. The manual fixups did either
revert the changes done by the script, replace a generic header with a more
specific one or replace a header with a forward declaration.

find . -name "*.idl" | grep -v web-platform | grep -v third_party | while read path; do
    interfaces=$(grep "^\(class\|interface\).*:.*" "$path" | cut -d' ' -f2)
    if [ -n "$interfaces" ]; then
        if [[ "$interfaces" == *$'\n'* ]]; then
          regexp="\("
          for i in $interfaces; do regexp="$regexp$i\|"; done
          regexp="${regexp%%\\\|}\)"
        else
          regexp="$interfaces"
        fi
        interface=$(basename "$path")
        rg -l "#include.*${interface%%.idl}.h" . | while read path2; do
            hits=$(grep -v "#include.*${interface%%.idl}.h" "$path2" | grep -c "$regexp" )
            if [ $hits -eq 0 ]; then
                echo "Removing ${interface} from ${path2}"
                grep -v "#include.*${interface%%.idl}.h" "$path2" > "$path2".tmp
                mv -f "$path2".tmp "$path2"
            fi
        done
    fi
done

Differential Revision: https://phabricator.services.mozilla.com/D55444

--HG--
extra : moz-landing-system : lando
2019-12-06 09:17:57 +00:00

902 lines
37 KiB
C++

/* vim:set ts=2 sw=2 sts=0 et: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
#include "gtest/gtest.h"
#include "js/Conversions.h"
#include "mozilla/Telemetry.h"
#include "TelemetryFixture.h"
#include "TelemetryTestHelpers.h"
using namespace mozilla;
using namespace TelemetryTestHelpers;
TEST_F(TelemetryTestFixture, AccumulateCountHistogram) {
const uint32_t kExpectedValue = 200;
AutoJSContextWithGlobal cx(mCleanGlobal);
const char* telemetryTestCountName =
Telemetry::GetHistogramName(Telemetry::TELEMETRY_TEST_COUNT);
ASSERT_STREQ(telemetryTestCountName, "TELEMETRY_TEST_COUNT")
<< "The histogram name is wrong";
GetAndClearHistogram(cx.GetJSContext(), mTelemetry,
NS_LITERAL_CSTRING("TELEMETRY_TEST_COUNT"), false);
// Accumulate in the histogram
Telemetry::Accumulate(Telemetry::TELEMETRY_TEST_COUNT, kExpectedValue / 2);
Telemetry::Accumulate("TELEMETRY_TEST_COUNT", kExpectedValue / 2);
// Get a snapshot for all the histograms
JS::RootedValue snapshot(cx.GetJSContext());
GetSnapshots(cx.GetJSContext(), mTelemetry, telemetryTestCountName, &snapshot,
false);
// Get the histogram from the snapshot
JS::RootedValue histogram(cx.GetJSContext());
GetProperty(cx.GetJSContext(), telemetryTestCountName, snapshot, &histogram);
// Get "sum" property from histogram
JS::RootedValue sum(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "sum", histogram, &sum);
// Check that the "sum" stored in the histogram matches with |kExpectedValue|
uint32_t uSum = 0;
JS::ToUint32(cx.GetJSContext(), sum, &uSum);
ASSERT_EQ(uSum, kExpectedValue)
<< "The histogram is not returning expected value";
}
TEST_F(TelemetryTestFixture, AccumulateKeyedCountHistogram) {
const uint32_t kExpectedValue = 100;
AutoJSContextWithGlobal cx(mCleanGlobal);
GetAndClearHistogram(cx.GetJSContext(), mTelemetry,
NS_LITERAL_CSTRING("TELEMETRY_TEST_KEYED_COUNT"), true);
// Accumulate data in the provided key within the histogram
Telemetry::Accumulate(Telemetry::TELEMETRY_TEST_KEYED_COUNT,
NS_LITERAL_CSTRING("sample"), kExpectedValue);
// Get a snapshot for all the histograms
JS::RootedValue snapshot(cx.GetJSContext());
GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_KEYED_COUNT",
&snapshot, true);
// Get the histogram from the snapshot
JS::RootedValue histogram(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_KEYED_COUNT", snapshot,
&histogram);
// Get "sample" property from histogram
JS::RootedValue expectedKeyData(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "sample", histogram, &expectedKeyData);
// Get "sum" property from keyed data
JS::RootedValue sum(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "sum", expectedKeyData, &sum);
// Check that the sum stored in the histogram matches with |kExpectedValue|
uint32_t uSum = 0;
JS::ToUint32(cx.GetJSContext(), sum, &uSum);
ASSERT_EQ(uSum, kExpectedValue)
<< "The histogram is not returning expected sum";
}
TEST_F(TelemetryTestFixture, TestKeyedKeysHistogram) {
AutoJSContextWithGlobal cx(mCleanGlobal);
JS::RootedValue testHistogram(cx.GetJSContext());
JS::RootedValue rval(cx.GetJSContext());
GetAndClearHistogram(cx.GetJSContext(), mTelemetry,
NS_LITERAL_CSTRING("TELEMETRY_TEST_KEYED_KEYS"), true);
// Test the accumulation on both the allowed and unallowed keys, using
// the API that accepts histogram IDs.
Telemetry::Accumulate(Telemetry::TELEMETRY_TEST_KEYED_KEYS,
NS_LITERAL_CSTRING("not-allowed"), 1);
Telemetry::Accumulate(Telemetry::TELEMETRY_TEST_KEYED_KEYS,
NS_LITERAL_CSTRING("testkey"), 0);
// Do the same, using the API that accepts the histogram name as a string.
Telemetry::Accumulate("TELEMETRY_TEST_KEYED_KEYS",
NS_LITERAL_CSTRING("not-allowed"), 1);
Telemetry::Accumulate("TELEMETRY_TEST_KEYED_KEYS",
NS_LITERAL_CSTRING("CommonKey"), 1);
// Get a snapshot for all the histograms
JS::RootedValue snapshot(cx.GetJSContext());
GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_KEYED_KEYS",
&snapshot, true);
// Get the histogram from the snapshot
JS::RootedValue histogram(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_KEYED_KEYS", snapshot,
&histogram);
// Get "testkey" property from histogram and check that it stores the correct
// data.
JS::RootedValue expectedKeyData(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "testkey", histogram, &expectedKeyData);
ASSERT_TRUE(!expectedKeyData.isUndefined())
<< "Cannot find the expected key in the histogram data";
JS::RootedValue sum(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "sum", expectedKeyData, &sum);
uint32_t uSum = 0;
JS::ToUint32(cx.GetJSContext(), sum, &uSum);
ASSERT_EQ(uSum, 0U)
<< "The histogram is not returning expected sum for 'testkey'";
// Do the same for the "CommonKey" property.
GetProperty(cx.GetJSContext(), "CommonKey", histogram, &expectedKeyData);
ASSERT_TRUE(!expectedKeyData.isUndefined())
<< "Cannot find the expected key in the histogram data";
GetProperty(cx.GetJSContext(), "sum", expectedKeyData, &sum);
JS::ToUint32(cx.GetJSContext(), sum, &uSum);
ASSERT_EQ(uSum, 1U)
<< "The histogram is not returning expected sum for 'CommonKey'";
GetProperty(cx.GetJSContext(), "not-allowed", histogram, &expectedKeyData);
ASSERT_TRUE(expectedKeyData.isUndefined())
<< "Unallowed keys must not be recorded in the histogram data";
// The 'not-allowed' key accumulation for 'TELEMETRY_TESTED_KEYED_KEYS' was
// attemtped twice, so we expect the count of
// 'telemetry.accumulate_unknown_histogram_keys' to be 2
const uint32_t expectedAccumulateUnknownCount = 2;
JS::RootedValue scalarsSnapshot(cx.GetJSContext());
GetScalarsSnapshot(true, cx.GetJSContext(), &scalarsSnapshot);
CheckKeyedUintScalar("telemetry.accumulate_unknown_histogram_keys",
"TELEMETRY_TEST_KEYED_KEYS", cx.GetJSContext(),
scalarsSnapshot, expectedAccumulateUnknownCount);
}
TEST_F(TelemetryTestFixture, AccumulateCategoricalHistogram) {
const uint32_t kExpectedValue = 2;
AutoJSContextWithGlobal cx(mCleanGlobal);
GetAndClearHistogram(cx.GetJSContext(), mTelemetry,
NS_LITERAL_CSTRING("TELEMETRY_TEST_CATEGORICAL"), false);
// Accumulate one unit into the categorical histogram with label
// Telemetry::LABELS_TELEMETRY_TEST_CATEGORICAL::CommonLabel
Telemetry::AccumulateCategorical(
Telemetry::LABELS_TELEMETRY_TEST_CATEGORICAL::CommonLabel);
// Accumulate another unit into the same categorical histogram using a string
// label
Telemetry::AccumulateCategorical(Telemetry::TELEMETRY_TEST_CATEGORICAL,
NS_LITERAL_CSTRING("CommonLabel"));
// Get a snapshot for all the histograms
JS::RootedValue snapshot(cx.GetJSContext());
GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_CATEGORICAL",
&snapshot, false);
// Get our histogram from the snapshot
JS::RootedValue histogram(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_CATEGORICAL", snapshot,
&histogram);
// Get values object from histogram. Each entry in the object maps to a label
// in the histogram.
JS::RootedValue values(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "values", histogram, &values);
// Get the value for the label we care about
JS::RootedValue value(cx.GetJSContext());
GetElement(cx.GetJSContext(),
static_cast<uint32_t>(
Telemetry::LABELS_TELEMETRY_TEST_CATEGORICAL::CommonLabel),
values, &value);
// Check that the value stored in the histogram matches with |kExpectedValue|
uint32_t uValue = 0;
JS::ToUint32(cx.GetJSContext(), value, &uValue);
ASSERT_EQ(uValue, kExpectedValue)
<< "The histogram is not returning expected value";
}
TEST_F(TelemetryTestFixture, AccumulateKeyedCategoricalHistogram) {
const uint32_t kSampleExpectedValue = 2;
const uint32_t kOtherSampleExpectedValue = 1;
AutoJSContextWithGlobal cx(mCleanGlobal);
GetAndClearHistogram(cx.GetJSContext(), mTelemetry,
NS_LITERAL_CSTRING("TELEMETRY_TEST_KEYED_CATEGORICAL"),
true);
// Accumulate one unit into the categorical histogram with label
// Telemetry::LABELS_TELEMETRY_TEST_KEYED_CATEGORICAL::CommonLabel
Telemetry::AccumulateCategoricalKeyed(
NS_LITERAL_CSTRING("sample"),
Telemetry::LABELS_TELEMETRY_TEST_KEYED_CATEGORICAL::CommonLabel);
// Accumulate another unit into the same categorical histogram
Telemetry::AccumulateCategoricalKeyed(
NS_LITERAL_CSTRING("sample"),
Telemetry::LABELS_TELEMETRY_TEST_KEYED_CATEGORICAL::CommonLabel);
// Accumulate another unit into a different categorical histogram
Telemetry::AccumulateCategoricalKeyed(
NS_LITERAL_CSTRING("other-sample"),
Telemetry::LABELS_TELEMETRY_TEST_KEYED_CATEGORICAL::CommonLabel);
// Get a snapshot for all the histograms
JS::RootedValue snapshot(cx.GetJSContext());
GetSnapshots(cx.GetJSContext(), mTelemetry,
"TELEMETRY_TEST_KEYED_CATEGORICAL", &snapshot, true);
// Get the histogram from the snapshot
JS::RootedValue histogram(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_KEYED_CATEGORICAL", snapshot,
&histogram);
// Check that the sample histogram contains the values we expect
JS::RootedValue sample(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "sample", histogram, &sample);
// Get values object from sample. Each entry in the object maps to a label in
// the histogram.
JS::RootedValue sampleValues(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "values", sample, &sampleValues);
// Get the value for the label we care about
JS::RootedValue sampleValue(cx.GetJSContext());
GetElement(
cx.GetJSContext(),
static_cast<uint32_t>(
Telemetry::LABELS_TELEMETRY_TEST_KEYED_CATEGORICAL::CommonLabel),
sampleValues, &sampleValue);
// Check that the value stored in the histogram matches with
// |kSampleExpectedValue|
uint32_t uSampleValue = 0;
JS::ToUint32(cx.GetJSContext(), sampleValue, &uSampleValue);
ASSERT_EQ(uSampleValue, kSampleExpectedValue)
<< "The sample histogram is not returning expected value";
// Check that the other-sample histogram contains the values we expect
JS::RootedValue otherSample(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "other-sample", histogram, &otherSample);
// Get values object from the other-sample. Each entry in the object maps to a
// label in the histogram.
JS::RootedValue otherValues(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "values", otherSample, &otherValues);
// Get the value for the label we care about
JS::RootedValue otherValue(cx.GetJSContext());
GetElement(
cx.GetJSContext(),
static_cast<uint32_t>(
Telemetry::LABELS_TELEMETRY_TEST_KEYED_CATEGORICAL::CommonLabel),
otherValues, &otherValue);
// Check that the value stored in the histogram matches with
// |kOtherSampleExpectedValue|
uint32_t uOtherValue = 0;
JS::ToUint32(cx.GetJSContext(), otherValue, &uOtherValue);
ASSERT_EQ(uOtherValue, kOtherSampleExpectedValue)
<< "The other-sample histogram is not returning expected value";
}
TEST_F(TelemetryTestFixture, AccumulateCountHistogram_MultipleSamples) {
nsTArray<uint32_t> samples({4, 4, 4});
const uint32_t kExpectedSum = 12;
AutoJSContextWithGlobal cx(mCleanGlobal);
GetAndClearHistogram(cx.GetJSContext(), mTelemetry,
NS_LITERAL_CSTRING("TELEMETRY_TEST_COUNT"), false);
// Accumulate in histogram
Telemetry::Accumulate(Telemetry::TELEMETRY_TEST_COUNT, samples);
// Get a snapshot of all the histograms
JS::RootedValue snapshot(cx.GetJSContext());
GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_COUNT", &snapshot,
false);
// Get histogram from snapshot
JS::RootedValue histogram(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_COUNT", snapshot, &histogram);
// Get "sum" from histogram
JS::RootedValue sum(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "sum", histogram, &sum);
// Check that sum matches with aValue
uint32_t uSum = 0;
JS::ToUint32(cx.GetJSContext(), sum, &uSum);
ASSERT_EQ(uSum, kExpectedSum)
<< "This histogram is not returning expected value";
}
TEST_F(TelemetryTestFixture, AccumulateLinearHistogram_MultipleSamples) {
nsTArray<uint32_t> samples({4, 4, 4});
const uint32_t kExpectedCount = 3;
AutoJSContextWithGlobal cx(mCleanGlobal);
GetAndClearHistogram(cx.GetJSContext(), mTelemetry,
NS_LITERAL_CSTRING("TELEMETRY_TEST_LINEAR"), false);
// Accumulate in the histogram
Telemetry::Accumulate(Telemetry::TELEMETRY_TEST_LINEAR, samples);
// Get a snapshot of all the histograms
JS::RootedValue snapshot(cx.GetJSContext());
GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_LINEAR",
&snapshot, false);
// Get histogram from snapshot
JS::RootedValue histogram(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_LINEAR", snapshot, &histogram);
// Get "values" object from histogram
JS::RootedValue values(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "values", histogram, &values);
// Index 0 is only for values less than 'low'. Values within range start at
// index 1
JS::RootedValue count(cx.GetJSContext());
const uint32_t index = 1;
GetElement(cx.GetJSContext(), index, values, &count);
// Check that this count matches with nSamples
uint32_t uCount = 0;
JS::ToUint32(cx.GetJSContext(), count, &uCount);
ASSERT_EQ(uCount, kExpectedCount)
<< "The histogram did not accumulate the correct number of values";
}
TEST_F(TelemetryTestFixture, AccumulateLinearHistogram_DifferentSamples) {
nsTArray<uint32_t> samples(
{4, 8, 2147483646, uint32_t(INT_MAX) + 1, UINT32_MAX});
AutoJSContextWithGlobal cx(mCleanGlobal);
mTelemetry->ClearScalars();
GetAndClearHistogram(cx.GetJSContext(), mTelemetry,
NS_LITERAL_CSTRING("TELEMETRY_TEST_LINEAR"), false);
// Accumulate in histogram
Telemetry::Accumulate(Telemetry::TELEMETRY_TEST_LINEAR, samples);
// Get a snapshot of all histograms
JS::RootedValue snapshot(cx.GetJSContext());
GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_LINEAR",
&snapshot, false);
// Get histogram from snapshot
JS::RootedValue histogram(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_LINEAR", snapshot, &histogram);
// Get values object from histogram
JS::RootedValue values(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "values", histogram, &values);
// Get values in first and last buckets
JS::RootedValue countFirst(cx.GetJSContext());
JS::RootedValue countLast(cx.GetJSContext());
const uint32_t firstIndex = 1;
// Buckets are indexed by their start value
const uint32_t lastIndex = INT32_MAX - 1;
GetElement(cx.GetJSContext(), firstIndex, values, &countFirst);
GetElement(cx.GetJSContext(), lastIndex, values, &countLast);
// Check that the values match
uint32_t uCountFirst = 0;
uint32_t uCountLast = 0;
JS::ToUint32(cx.GetJSContext(), countFirst, &uCountFirst);
JS::ToUint32(cx.GetJSContext(), countLast, &uCountLast);
const uint32_t kExpectedCountFirst = 2;
// We expect 2147483646 to be in the last bucket, as well the two samples
// above 2^31 (prior to bug 1438335, values between INT_MAX and UINT32_MAX
// would end up as 0s)
const uint32_t kExpectedCountLast = 3;
ASSERT_EQ(uCountFirst, kExpectedCountFirst)
<< "The first bucket did not accumulate the correct number of values";
ASSERT_EQ(uCountLast, kExpectedCountLast)
<< "The last bucket did not accumulate the correct number of values";
// We accumulated two values that had to be clamped. We expect the count in
// 'telemetry.accumulate_clamped_values' to be 2 (only one storage).
const uint32_t expectedAccumulateClampedCount = 2;
JS::RootedValue scalarsSnapshot(cx.GetJSContext());
GetScalarsSnapshot(true, cx.GetJSContext(), &scalarsSnapshot);
CheckKeyedUintScalar("telemetry.accumulate_clamped_values",
"TELEMETRY_TEST_LINEAR", cx.GetJSContext(),
scalarsSnapshot, expectedAccumulateClampedCount);
}
TEST_F(TelemetryTestFixture, AccumulateKeyedCountHistogram_MultipleSamples) {
const nsTArray<uint32_t> samples({5, 10, 15});
const uint32_t kExpectedSum = 5 + 10 + 15;
AutoJSContextWithGlobal cx(mCleanGlobal);
GetAndClearHistogram(cx.GetJSContext(), mTelemetry,
NS_LITERAL_CSTRING("TELEMETRY_TEST_KEYED_COUNT"), true);
// Accumulate data in the provided key within the histogram
Telemetry::Accumulate(Telemetry::TELEMETRY_TEST_KEYED_COUNT,
NS_LITERAL_CSTRING("sample"), samples);
// Get a snapshot for all the histograms
JS::RootedValue snapshot(cx.GetJSContext());
GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_KEYED_COUNT",
&snapshot, true);
// Get the histogram from the snapshot
JS::RootedValue histogram(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_KEYED_COUNT", snapshot,
&histogram);
// Get "sample" property from histogram
JS::RootedValue expectedKeyData(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "sample", histogram, &expectedKeyData);
// Get "sum" property from keyed data
JS::RootedValue sum(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "sum", expectedKeyData, &sum);
// Check that the sum stored in the histogram matches with |kExpectedSum|
uint32_t uSum = 0;
JS::ToUint32(cx.GetJSContext(), sum, &uSum);
ASSERT_EQ(uSum, kExpectedSum)
<< "The histogram is not returning expected sum";
}
TEST_F(TelemetryTestFixture, TestKeyedLinearHistogram_MultipleSamples) {
AutoJSContextWithGlobal cx(mCleanGlobal);
mTelemetry->ClearScalars();
GetAndClearHistogram(cx.GetJSContext(), mTelemetry,
NS_LITERAL_CSTRING("TELEMETRY_TEST_KEYED_LINEAR"), true);
const nsTArray<uint32_t> samples({1, 5, 250000, UINT_MAX});
// Test the accumulation on the key 'testkey', using
// the API that accepts histogram IDs.
Telemetry::Accumulate(Telemetry::TELEMETRY_TEST_KEYED_LINEAR,
NS_LITERAL_CSTRING("testkey"), samples);
// Get a snapshot for all the histograms
JS::RootedValue snapshot(cx.GetJSContext());
GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_KEYED_LINEAR",
&snapshot, true);
// Get the histogram from the snapshot
JS::RootedValue histogram(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_KEYED_LINEAR", snapshot,
&histogram);
// Get "testkey" property from histogram.
JS::RootedValue expectedKeyData(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "testkey", histogram, &expectedKeyData);
ASSERT_TRUE(!expectedKeyData.isUndefined())
<< "Cannot find the expected key in the histogram data";
// Get values object from 'testkey' histogram.
JS::RootedValue values(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "values", expectedKeyData, &values);
// Get values in first and last buckets.
JS::RootedValue countFirst(cx.GetJSContext());
JS::RootedValue countLast(cx.GetJSContext());
const uint32_t firstIndex = 1;
// Buckets are indexed by their start value
const uint32_t lastIndex = 250000;
GetElement(cx.GetJSContext(), firstIndex, values, &countFirst);
GetElement(cx.GetJSContext(), lastIndex, values, &countLast);
// Check that the values match.
uint32_t uCountFirst = 0;
uint32_t uCountLast = 0;
JS::ToUint32(cx.GetJSContext(), countFirst, &uCountFirst);
JS::ToUint32(cx.GetJSContext(), countLast, &uCountLast);
const uint32_t kExpectedCountFirst = 2;
const uint32_t kExpectedCountLast = 2;
ASSERT_EQ(uCountFirst, kExpectedCountFirst)
<< "The first bucket did not accumulate the correct number of values for "
"key 'testkey'";
ASSERT_EQ(uCountLast, kExpectedCountLast)
<< "The last bucket did not accumulate the correct number of values for "
"key 'testkey'";
// We accumulated one keyed values that had to be clamped. We expect the
// count in 'telemetry.accumulate_clamped_values' to be 1
const uint32_t expectedAccumulateClampedCount = 1;
JS::RootedValue scalarsSnapshot(cx.GetJSContext());
GetScalarsSnapshot(true, cx.GetJSContext(), &scalarsSnapshot);
CheckKeyedUintScalar("telemetry.accumulate_clamped_values",
"TELEMETRY_TEST_KEYED_LINEAR", cx.GetJSContext(),
scalarsSnapshot, expectedAccumulateClampedCount);
}
TEST_F(TelemetryTestFixture, TestKeyedKeysHistogram_MultipleSamples) {
AutoJSContextWithGlobal cx(mCleanGlobal);
mTelemetry->ClearScalars();
const nsTArray<uint32_t> samples({false, false, true, 32, true});
GetAndClearHistogram(cx.GetJSContext(), mTelemetry,
NS_LITERAL_CSTRING("TELEMETRY_TEST_KEYED_KEYS"), true);
// Test the accumulation on both the allowed and unallowed keys, using
// the API that accepts histogram IDs.
Telemetry::Accumulate(Telemetry::TELEMETRY_TEST_KEYED_KEYS,
NS_LITERAL_CSTRING("not-allowed"), samples);
Telemetry::Accumulate(Telemetry::TELEMETRY_TEST_KEYED_KEYS,
NS_LITERAL_CSTRING("testkey"), samples);
// Get a snapshot for all the histograms
JS::RootedValue snapshot(cx.GetJSContext());
GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_KEYED_KEYS",
&snapshot, true);
// Get the histogram from the snapshot
JS::RootedValue histogram(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_KEYED_KEYS", snapshot,
&histogram);
// Get "testkey" property from histogram and check that it stores the correct
// data.
JS::RootedValue testKeyData(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "testkey", histogram, &testKeyData);
ASSERT_TRUE(!testKeyData.isUndefined())
<< "Cannot find the key 'testkey' in the histogram data";
JS::RootedValue values(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "values", testKeyData, &values);
// Get values in buckets 0,1,2
const uint32_t falseIndex = 0;
const uint32_t trueIndex = 1;
const uint32_t otherIndex = 2;
JS::RootedValue countFalse(cx.GetJSContext());
JS::RootedValue countTrue(cx.GetJSContext());
JS::RootedValue countOther(cx.GetJSContext());
GetElement(cx.GetJSContext(), falseIndex, values, &countFalse);
GetElement(cx.GetJSContext(), trueIndex, values, &countTrue);
GetElement(cx.GetJSContext(), otherIndex, values, &countOther);
uint32_t uCountFalse = 0;
uint32_t uCountTrue = 0;
uint32_t uCountOther = 0;
JS::ToUint32(cx.GetJSContext(), countFalse, &uCountFalse);
JS::ToUint32(cx.GetJSContext(), countTrue, &uCountTrue);
JS::ToUint32(cx.GetJSContext(), countOther, &uCountOther);
const uint32_t kExpectedCountFalse = 2;
const uint32_t kExpectedCountTrue = 3;
const uint32_t kExpectedCountOther = 0;
ASSERT_EQ(uCountFalse, kExpectedCountFalse)
<< "The histogram did not accumulate the correct number of 'false' "
"booleans for key 'testkey'";
ASSERT_EQ(uCountTrue, kExpectedCountTrue)
<< "The histogram did not accumulate the correct number of 'true' "
"booleans for key 'testkey'";
ASSERT_EQ(uCountOther, kExpectedCountOther)
<< "The histogram did not accumulate the correct number of undefined "
"values for key 'testkey'";
// Here we check that we are not accumulating to a different (but still
// 'allowed') key. Get "CommonKey" property from histogram and check that it
// has no data. Since we accumulated no data to it, commonKeyData should be
// undefined.
JS::RootedValue commonKeyData(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "CommonKey", histogram, &commonKeyData);
ASSERT_TRUE(commonKeyData.isUndefined())
<< "Found data in key 'CommonKey' even though we accumulated no data to "
"it";
// Here we check that our function does not allow accumulation into unallowed
// keys. Get 'not-allowed' property from histogram and check that this also
// has no data. This should contain no data because this key is not allowed.
JS::RootedValue notAllowedKeyData(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "not-allowed", histogram, &notAllowedKeyData);
ASSERT_TRUE(notAllowedKeyData.isUndefined())
<< "Found data in key 'not-allowed' even though accumuling data to it is "
"not allowed";
// The 'not-allowed' key accumulation for 'TELEMETRY_TESTED_KEYED_KEYS' was
// attemtped once, so we expect the count of
// 'telemetry.accumulate_unknown_histogram_keys' to be 1
const uint32_t expectedAccumulateUnknownCount = 1;
JS::RootedValue scalarsSnapshot(cx.GetJSContext());
GetScalarsSnapshot(true, cx.GetJSContext(), &scalarsSnapshot);
CheckKeyedUintScalar("telemetry.accumulate_unknown_histogram_keys",
"TELEMETRY_TEST_KEYED_KEYS", cx.GetJSContext(),
scalarsSnapshot, expectedAccumulateUnknownCount);
}
TEST_F(TelemetryTestFixture,
AccumulateCategoricalHistogram_MultipleStringLabels) {
const uint32_t kExpectedValue = 2;
const nsTArray<nsCString> labels(
{NS_LITERAL_CSTRING("CommonLabel"), NS_LITERAL_CSTRING("CommonLabel")});
AutoJSContextWithGlobal cx(mCleanGlobal);
GetAndClearHistogram(cx.GetJSContext(), mTelemetry,
NS_LITERAL_CSTRING("TELEMETRY_TEST_CATEGORICAL"), false);
// Accumulate the units into a categorical histogram using a string label
Telemetry::AccumulateCategorical(Telemetry::TELEMETRY_TEST_CATEGORICAL,
labels);
// Get a snapshot for all the histograms
JS::RootedValue snapshot(cx.GetJSContext());
GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_CATEGORICAL",
&snapshot, false);
// Get our histogram from the snapshot
JS::RootedValue histogram(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_CATEGORICAL", snapshot,
&histogram);
// Get values object from histogram. Each entry in the object maps to a label
// in the histogram.
JS::RootedValue values(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "values", histogram, &values);
// Get the value for the label we care about
JS::RootedValue value(cx.GetJSContext());
GetElement(cx.GetJSContext(),
static_cast<uint32_t>(
Telemetry::LABELS_TELEMETRY_TEST_CATEGORICAL::CommonLabel),
values, &value);
// Check that the value stored in the histogram matches with |kExpectedValue|
uint32_t uValue = 0;
JS::ToUint32(cx.GetJSContext(), value, &uValue);
ASSERT_EQ(uValue, kExpectedValue)
<< "The histogram is not returning expected value";
// Now we check for no accumulation when a bad label is present in the array.
//
// The 'values' property is not initialized unless data is accumulated so
// keeping another test to check for this case alone is wasteful as we will
// have to accumulate some data anyway.
const nsTArray<nsCString> badLabelArray(
{NS_LITERAL_CSTRING("CommonLabel"), NS_LITERAL_CSTRING("BadLabel")});
// Try to accumulate the array into the histogram.
Telemetry::AccumulateCategorical(Telemetry::TELEMETRY_TEST_CATEGORICAL,
badLabelArray);
// Get snapshot of all the histograms
GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_CATEGORICAL",
&snapshot, false);
// Get our histogram from the snapshot
GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_CATEGORICAL", snapshot,
&histogram);
// Get values array from histogram
GetProperty(cx.GetJSContext(), "values", histogram, &values);
// Get the value for the label we care about
GetElement(cx.GetJSContext(),
static_cast<uint32_t>(
Telemetry::LABELS_TELEMETRY_TEST_CATEGORICAL::CommonLabel),
values, &value);
// Check that the value stored in the histogram matches with |kExpectedValue|
uValue = 0;
JS::ToUint32(cx.GetJSContext(), value, &uValue);
ASSERT_EQ(uValue, kExpectedValue)
<< "The histogram accumulated data when it should not have";
}
TEST_F(TelemetryTestFixture,
AccumulateCategoricalHistogram_MultipleEnumValues) {
const uint32_t kExpectedValue = 2;
const nsTArray<Telemetry::LABELS_TELEMETRY_TEST_CATEGORICAL> enumLabels(
{Telemetry::LABELS_TELEMETRY_TEST_CATEGORICAL::CommonLabel,
Telemetry::LABELS_TELEMETRY_TEST_CATEGORICAL::CommonLabel});
AutoJSContextWithGlobal cx(mCleanGlobal);
GetAndClearHistogram(cx.GetJSContext(), mTelemetry,
NS_LITERAL_CSTRING("TELEMETRY_TEST_CATEGORICAL"), false);
// Accumulate the units into a categorical histogram using the enumLabels
// array
Telemetry::AccumulateCategorical<
Telemetry::LABELS_TELEMETRY_TEST_CATEGORICAL>(enumLabels);
// Get a snapshot for all the histograms
JS::RootedValue snapshot(cx.GetJSContext());
GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_CATEGORICAL",
&snapshot, false);
// Get our histogram from the snapshot
JS::RootedValue histogram(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_CATEGORICAL", snapshot,
&histogram);
// Get values object from histogram. Each entry in the object maps to a label
// in the histogram.
JS::RootedValue values(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "values", histogram, &values);
// Get the value for the label we care about
JS::RootedValue value(cx.GetJSContext());
GetElement(cx.GetJSContext(),
static_cast<uint32_t>(
Telemetry::LABELS_TELEMETRY_TEST_CATEGORICAL::CommonLabel),
values, &value);
// Check that the value stored in the histogram matches with |kExpectedValue|
uint32_t uValue = 0;
JS::ToUint32(cx.GetJSContext(), value, &uValue);
ASSERT_EQ(uValue, kExpectedValue)
<< "The histogram is not returning expected value";
}
TEST_F(TelemetryTestFixture,
AccumulateKeyedCategoricalHistogram_MultipleEnumValues) {
const uint32_t kExpectedCommonLabel = 2;
const uint32_t kExpectedLabel2 = 1;
const nsTArray<Telemetry::LABELS_TELEMETRY_TEST_KEYED_CATEGORICAL> enumLabels(
{Telemetry::LABELS_TELEMETRY_TEST_KEYED_CATEGORICAL::CommonLabel,
Telemetry::LABELS_TELEMETRY_TEST_KEYED_CATEGORICAL::CommonLabel,
Telemetry::LABELS_TELEMETRY_TEST_KEYED_CATEGORICAL::Label2});
AutoJSContextWithGlobal cx(mCleanGlobal);
GetAndClearHistogram(cx.GetJSContext(), mTelemetry,
NS_LITERAL_CSTRING("TELEMETRY_TEST_KEYED_CATEGORICAL"),
true);
// Accumulate the array into the categorical keyed histogram
Telemetry::AccumulateCategoricalKeyed(NS_LITERAL_CSTRING("sampleKey"),
enumLabels);
// Get a snapshot for all the histograms
JS::RootedValue snapshot(cx.GetJSContext());
GetSnapshots(cx.GetJSContext(), mTelemetry,
"TELEMETRY_TEST_KEYED_CATEGORICAL", &snapshot, true);
// Get the histogram from the snapshot
JS::RootedValue histogram(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_KEYED_CATEGORICAL", snapshot,
&histogram);
// Check that the sampleKey histogram contains correct number of CommonLabel
// samples
JS::RootedValue sample(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "sampleKey", histogram, &sample);
// Get values object from the sample. Each entry in the object maps to a label
// in the histogram.
JS::RootedValue sampleKeyValues(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "values", sample, &sampleKeyValues);
// Get the count of CommonLabel
JS::RootedValue commonLabelValue(cx.GetJSContext());
GetElement(
cx.GetJSContext(),
static_cast<uint32_t>(
Telemetry::LABELS_TELEMETRY_TEST_KEYED_CATEGORICAL::CommonLabel),
sampleKeyValues, &commonLabelValue);
// Check that the value stored in the histogram matches with
// |kExpectedCommonLabel|
uint32_t uCommonLabelValue = 0;
JS::ToUint32(cx.GetJSContext(), commonLabelValue, &uCommonLabelValue);
ASSERT_EQ(uCommonLabelValue, kExpectedCommonLabel)
<< "The sampleKey histogram did not accumulate the correct number of "
"CommonLabel samples";
// Check that the sampleKey histogram contains the correct number of Label2
// values Get the count of Label2
JS::RootedValue label2Value(cx.GetJSContext());
GetElement(cx.GetJSContext(),
static_cast<uint32_t>(
Telemetry::LABELS_TELEMETRY_TEST_KEYED_CATEGORICAL::Label2),
sampleKeyValues, &label2Value);
// Check that the value stored in the histogram matches with |kExpectedLabel2|
uint32_t uLabel2Value = 0;
JS::ToUint32(cx.GetJSContext(), label2Value, &uLabel2Value);
ASSERT_EQ(uLabel2Value, kExpectedLabel2)
<< "The sampleKey histogram did not accumulate the correct number of "
"Label2 samples";
}
TEST_F(TelemetryTestFixture, AccumulateTimeDelta) {
const uint32_t kExpectedValue = 100;
const TimeStamp start = TimeStamp::Now();
const TimeDuration delta = TimeDuration::FromMilliseconds(50);
AutoJSContextWithGlobal cx(mCleanGlobal);
GetAndClearHistogram(cx.GetJSContext(), mTelemetry,
NS_LITERAL_CSTRING("TELEMETRY_TEST_COUNT"), false);
// Accumulate in the histogram
Telemetry::AccumulateTimeDelta(Telemetry::TELEMETRY_TEST_COUNT, start - delta,
start);
Telemetry::AccumulateTimeDelta(Telemetry::TELEMETRY_TEST_COUNT, start - delta,
start);
Telemetry::AccumulateTimeDelta(Telemetry::TELEMETRY_TEST_COUNT, start, start);
// end > start timestamp gives zero contribution
Telemetry::AccumulateTimeDelta(Telemetry::TELEMETRY_TEST_COUNT, start + delta,
start);
// Get a snapshot for all the histograms
JS::RootedValue snapshot(cx.GetJSContext());
GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_COUNT", &snapshot,
false);
// Get the histogram from the snapshot
JS::RootedValue histogram(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_COUNT", snapshot, &histogram);
// Get "sum" property from histogram
JS::RootedValue sum(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "sum", histogram, &sum);
// Check that the "sum" stored in the histogram matches with |kExpectedValue|
uint32_t uSum = 0;
JS::ToUint32(cx.GetJSContext(), sum, &uSum);
ASSERT_EQ(uSum, kExpectedValue)
<< "The histogram is not returning expected value";
}
TEST_F(TelemetryTestFixture, AccumulateKeyedTimeDelta) {
const uint32_t kExpectedValue = 100;
const TimeStamp start = TimeStamp::Now();
const TimeDuration delta = TimeDuration::FromMilliseconds(50);
AutoJSContextWithGlobal cx(mCleanGlobal);
GetAndClearHistogram(cx.GetJSContext(), mTelemetry,
NS_LITERAL_CSTRING("TELEMETRY_TEST_KEYED_COUNT"), true);
// Accumulate time delta in the provided key within the histogram
Telemetry::AccumulateTimeDelta(Telemetry::TELEMETRY_TEST_KEYED_COUNT,
NS_LITERAL_CSTRING("sample"), start - delta,
start);
Telemetry::AccumulateTimeDelta(Telemetry::TELEMETRY_TEST_KEYED_COUNT,
NS_LITERAL_CSTRING("sample"), start - delta,
start);
// end > start timestamp gives zero contribution
Telemetry::AccumulateTimeDelta(Telemetry::TELEMETRY_TEST_KEYED_COUNT,
NS_LITERAL_CSTRING("sample"), start + delta,
start);
Telemetry::AccumulateTimeDelta(Telemetry::TELEMETRY_TEST_KEYED_COUNT,
NS_LITERAL_CSTRING("sample"), start, start);
// Get a snapshot for all the histograms
JS::RootedValue snapshot(cx.GetJSContext());
GetSnapshots(cx.GetJSContext(), mTelemetry, "TELEMETRY_TEST_KEYED_COUNT",
&snapshot, true);
// Get the histogram from the snapshot
JS::RootedValue histogram(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "TELEMETRY_TEST_KEYED_COUNT", snapshot,
&histogram);
// Get "sample" property from histogram
JS::RootedValue expectedKeyData(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "sample", histogram, &expectedKeyData);
// Get "sum" property from keyed data
JS::RootedValue sum(cx.GetJSContext());
GetProperty(cx.GetJSContext(), "sum", expectedKeyData, &sum);
// Check that the sum stored in the histogram matches with |kExpectedValue|
uint32_t uSum = 0;
JS::ToUint32(cx.GetJSContext(), sum, &uSum);
ASSERT_EQ(uSum, kExpectedValue)
<< "The histogram is not returning expected sum";
}