Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp
Line
Count
Source (jump to first uncovered line)
1
/* Any copyright is dedicated to the Public Domain.
2
 * http://creativecommons.org/publicdomain/zero/1.0/
3
 */
4
5
#include "TelemetryTestHelpers.h"
6
7
#include "gtest/gtest.h"
8
#include "mozilla/CycleCollectedJSContext.h"
9
#include "core/TelemetryCommon.h"
10
#include "mozilla/Unused.h"
11
12
using namespace mozilla;
13
14
// Helper methods provided to simplify writing tests and meant to be used in C++ Gtests.
15
namespace TelemetryTestHelpers {
16
17
void
18
CheckUintScalar(const char* aName, JSContext* aCx, JS::HandleValue aSnapshot, uint32_t expectedValue)
19
0
{
20
0
  // Validate the value of the test scalar.
21
0
  JS::RootedValue value(aCx);
22
0
  JS::RootedObject scalarObj(aCx, &aSnapshot.toObject());
23
0
  ASSERT_TRUE(JS_GetProperty(aCx, scalarObj, aName, &value)) << "The test scalar must be reported.";
24
0
  JS_GetProperty(aCx, scalarObj, aName, &value);
25
0
26
0
  ASSERT_TRUE(value.isInt32()) << "The scalar value must be of the correct type.";
27
0
  ASSERT_TRUE(value.toInt32() >= 0) << "The uint scalar type must contain a value >= 0.";
28
0
  ASSERT_EQ(static_cast<uint32_t>(value.toInt32()), expectedValue) << "The scalar value must match the expected value.";
29
0
}
30
31
void
32
CheckBoolScalar(const char* aName, JSContext* aCx, JS::HandleValue aSnapshot, bool expectedValue)
33
0
{
34
0
  // Validate the value of the test scalar.
35
0
  JS::RootedValue value(aCx);
36
0
  JS::RootedObject scalarObj(aCx, &aSnapshot.toObject());
37
0
  ASSERT_TRUE(JS_GetProperty(aCx, scalarObj, aName, &value)) << "The test scalar must be reported.";
38
0
  ASSERT_TRUE(value.isBoolean()) << "The scalar value must be of the correct type.";
39
0
  ASSERT_EQ(static_cast<bool>(value.toBoolean()), expectedValue) << "The scalar value must match the expected value.";
40
0
}
41
42
void
43
CheckStringScalar(const char* aName, JSContext* aCx, JS::HandleValue aSnapshot, const char* expectedValue)
44
0
{
45
0
  // Validate the value of the test scalar.
46
0
  JS::RootedValue value(aCx);
47
0
  JS::RootedObject scalarObj(aCx, &aSnapshot.toObject());
48
0
  ASSERT_TRUE(JS_GetProperty(aCx, scalarObj, aName, &value)) << "The test scalar must be reported.";
49
0
  ASSERT_TRUE(value.isString()) << "The scalar value must be of the correct type.";
50
0
51
0
  bool sameString;
52
0
  ASSERT_TRUE(JS_StringEqualsAscii(aCx, value.toString(), expectedValue, &sameString)) << "JS String comparison failed";
53
0
  ASSERT_TRUE(sameString) << "The scalar value must match the expected string";
54
0
}
55
56
void
57
CheckKeyedUintScalar(const char* aName, const char* aKey, JSContext* aCx, JS::HandleValue aSnapshot,
58
                     uint32_t expectedValue)
59
0
{
60
0
  JS::RootedValue keyedScalar(aCx);
61
0
  JS::RootedObject scalarObj(aCx, &aSnapshot.toObject());
62
0
  // Get the aName keyed scalar object from the scalars snapshot.
63
0
  ASSERT_TRUE(JS_GetProperty(aCx, scalarObj, aName, &keyedScalar))
64
0
    << "The keyed scalar must be reported.";
65
0
66
0
  CheckUintScalar(aKey, aCx, keyedScalar, expectedValue);
67
0
}
68
69
void
70
CheckKeyedBoolScalar(const char* aName, const char* aKey, JSContext* aCx, JS::HandleValue aSnapshot,
71
                     bool expectedValue)
72
0
{
73
0
  JS::RootedValue keyedScalar(aCx);
74
0
  JS::RootedObject scalarObj(aCx, &aSnapshot.toObject());
75
0
  // Get the aName keyed scalar object from the scalars snapshot.
76
0
  ASSERT_TRUE(JS_GetProperty(aCx, scalarObj, aName, &keyedScalar))
77
0
    << "The keyed scalar must be reported.";
78
0
79
0
  CheckBoolScalar(aKey, aCx, keyedScalar, expectedValue);
80
0
}
81
82
void
83
CheckNumberOfProperties(const char* aName, JSContext* aCx, JS::HandleValue aSnapshot,
84
                        uint32_t expectedNumProperties)
85
0
{
86
0
  JS::RootedValue keyedScalar(aCx);
87
0
  JS::RootedObject scalarObj(aCx, &aSnapshot.toObject());
88
0
  // Get the aName keyed scalar object from the scalars snapshot.
89
0
  ASSERT_TRUE(JS_GetProperty(aCx, scalarObj, aName, &keyedScalar))
90
0
    << "The keyed scalar must be reported.";
91
0
92
0
  JS::RootedObject keyedScalarObj(aCx, &keyedScalar.toObject());
93
0
  JS::Rooted<JS::IdVector> ids(aCx, JS::IdVector(aCx));
94
0
  ASSERT_TRUE(JS_Enumerate(aCx, keyedScalarObj, &ids))
95
0
    << "We must be able to get keyed scalar members.";
96
0
97
0
  ASSERT_EQ(expectedNumProperties, ids.length())
98
0
    << "The scalar must report the expected number of properties.";
99
0
}
100
101
void
102
GetScalarsSnapshot(bool aKeyed, JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
103
                   ProcessID aProcessType)
104
0
{
105
0
  nsCOMPtr<nsITelemetry> telemetry = do_GetService("@mozilla.org/base/telemetry;1");
106
0
107
0
  // Get a snapshot of the scalars.
108
0
  JS::RootedValue scalarsSnapshot(aCx);
109
0
  nsresult rv;
110
0
111
0
  if (aKeyed) {
112
0
    rv = telemetry->SnapshotKeyedScalars(nsITelemetry::DATASET_RELEASE_CHANNEL_OPTIN,
113
0
                                         false, aCx, 0, &scalarsSnapshot);
114
0
  } else {
115
0
    rv = telemetry->SnapshotScalars(nsITelemetry::DATASET_RELEASE_CHANNEL_OPTIN,
116
0
                                    false, aCx, 0, &scalarsSnapshot);
117
0
  }
118
0
119
0
  // Validate the snapshot.
120
0
  ASSERT_EQ(rv, NS_OK) << "Creating a snapshot of the data must not fail.";
121
0
  ASSERT_TRUE(scalarsSnapshot.isObject()) << "The snapshot must be an object.";
122
0
123
0
  JS::RootedValue processScalars(aCx);
124
0
  JS::RootedObject scalarObj(aCx, &scalarsSnapshot.toObject());
125
0
  // Don't complain if no scalars for the process can be found. Just
126
0
  // return an empty object.
127
0
  Unused << JS_GetProperty(aCx,
128
0
                           scalarObj,
129
0
                           Telemetry::Common::GetNameForProcessID(aProcessType),
130
0
                           &processScalars);
131
0
132
0
  aResult.set(processScalars);
133
0
}
134
135
void
136
GetAndClearHistogram(JSContext* cx, nsCOMPtr<nsITelemetry> mTelemetry,
137
                     const nsACString &name, bool is_keyed)
138
0
{
139
0
  JS::RootedValue testHistogram(cx);
140
0
  nsresult rv = is_keyed ? mTelemetry->GetKeyedHistogramById(name, cx, &testHistogram)
141
0
                         : mTelemetry->GetHistogramById(name, cx, &testHistogram);
142
0
143
0
  ASSERT_EQ(rv, NS_OK) << "Cannot fetch histogram";
144
0
145
0
  // Clear the stored value
146
0
  JS::RootedObject testHistogramObj(cx, &testHistogram.toObject());
147
0
  JS::RootedValue rval(cx);
148
0
  ASSERT_TRUE(JS_CallFunctionName(cx, testHistogramObj, "clear",
149
0
                  JS::HandleValueArray::empty(), &rval)) << "Cannot clear histogram";
150
0
}
151
152
void
153
GetProperty(JSContext* cx, const char* name, JS::HandleValue valueIn,
154
            JS::MutableHandleValue valueOut)
155
0
{
156
0
  JS::RootedValue property(cx);
157
0
  JS::RootedObject valueInObj(cx, &valueIn.toObject());
158
0
  ASSERT_TRUE(JS_GetProperty(cx, valueInObj, name, &property))
159
0
    << "Cannot get property '" << name << "'";
160
0
  valueOut.set(property);
161
0
}
162
163
void
164
GetElement(JSContext* cx, uint32_t index, JS::HandleValue valueIn,
165
           JS::MutableHandleValue valueOut)
166
0
{
167
0
  JS::RootedValue element(cx);
168
0
  JS::RootedObject valueInObj(cx, &valueIn.toObject());
169
0
  ASSERT_TRUE(JS_GetElement(cx, valueInObj, index, &element))
170
0
    << "Cannot get element at index '" << index << "'";
171
0
  valueOut.set(element);
172
0
}
173
174
void
175
GetSnapshots(JSContext* cx, nsCOMPtr<nsITelemetry> mTelemetry,
176
             const char* name, JS::MutableHandleValue valueOut, bool is_keyed)
177
0
{
178
0
  JS::RootedValue snapshots(cx);
179
0
  nsresult rv = is_keyed ? mTelemetry->SnapshotKeyedHistograms(nsITelemetry::DATASET_RELEASE_CHANNEL_OPTIN, false, cx, &snapshots)
180
0
                         : mTelemetry->SnapshotHistograms(nsITelemetry::DATASET_RELEASE_CHANNEL_OPTIN, false, cx, &snapshots);
181
0
182
0
  JS::RootedValue snapshot(cx);
183
0
  GetProperty(cx, "parent", snapshots, &snapshot);
184
0
185
0
  ASSERT_EQ(rv, NS_OK) << "Cannot call histogram snapshots";
186
0
  valueOut.set(snapshot);
187
0
}
188
189
} // namespace TelemetryTestHelpers