|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 * http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 "use strict"; |
|
5 |
|
6 const {utils: Cu} = Components; |
|
7 |
|
8 Cu.import("resource://gre/modules/Metrics.jsm"); |
|
9 Cu.import("resource://gre/modules/Preferences.jsm"); |
|
10 Cu.import("resource://gre/modules/Task.jsm"); |
|
11 Cu.import("resource://testing-common/services/metrics/mocks.jsm"); |
|
12 |
|
13 |
|
14 const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000; |
|
15 |
|
16 |
|
17 function getProvider(storageName) { |
|
18 return Task.spawn(function () { |
|
19 let provider = new DummyProvider(); |
|
20 let storage = yield Metrics.Storage(storageName); |
|
21 |
|
22 yield provider.init(storage); |
|
23 |
|
24 throw new Task.Result(provider); |
|
25 }); |
|
26 } |
|
27 |
|
28 |
|
29 function run_test() { |
|
30 run_next_test(); |
|
31 }; |
|
32 |
|
33 add_test(function test_constructor() { |
|
34 let failed = false; |
|
35 try { |
|
36 new Metrics.Provider(); |
|
37 } catch(ex) { |
|
38 do_check_true(ex.message.startsWith("Provider must define a name")); |
|
39 failed = true; |
|
40 } |
|
41 finally { |
|
42 do_check_true(failed); |
|
43 } |
|
44 |
|
45 run_next_test(); |
|
46 }); |
|
47 |
|
48 add_task(function test_init() { |
|
49 let provider = new DummyProvider(); |
|
50 let storage = yield Metrics.Storage("init"); |
|
51 |
|
52 yield provider.init(storage); |
|
53 |
|
54 let m = provider.getMeasurement("DummyMeasurement", 1); |
|
55 do_check_true(m instanceof Metrics.Measurement); |
|
56 do_check_eq(m.id, 1); |
|
57 do_check_eq(Object.keys(m._fields).length, 7); |
|
58 do_check_true(m.hasField("daily-counter")); |
|
59 do_check_false(m.hasField("does-not-exist")); |
|
60 |
|
61 yield storage.close(); |
|
62 }); |
|
63 |
|
64 add_task(function test_default_collectors() { |
|
65 let provider = new DummyProvider(); |
|
66 let storage = yield Metrics.Storage("default_collectors"); |
|
67 yield provider.init(storage); |
|
68 |
|
69 for (let property in Metrics.Provider.prototype) { |
|
70 if (!property.startsWith("collect")) { |
|
71 continue; |
|
72 } |
|
73 |
|
74 let result = provider[property](); |
|
75 do_check_neq(result, null); |
|
76 do_check_eq(typeof(result.then), "function"); |
|
77 } |
|
78 |
|
79 yield storage.close(); |
|
80 }); |
|
81 |
|
82 add_task(function test_measurement_storage_basic() { |
|
83 let provider = yield getProvider("measurement_storage_basic"); |
|
84 let m = provider.getMeasurement("DummyMeasurement", 1); |
|
85 |
|
86 let now = new Date(); |
|
87 let yesterday = new Date(now.getTime() - MILLISECONDS_PER_DAY); |
|
88 |
|
89 // Daily counter. |
|
90 let counterID = m.fieldID("daily-counter"); |
|
91 yield m.incrementDailyCounter("daily-counter", now); |
|
92 yield m.incrementDailyCounter("daily-counter", now); |
|
93 yield m.incrementDailyCounter("daily-counter", yesterday); |
|
94 let count = yield provider.storage.getDailyCounterCountFromFieldID(counterID, now); |
|
95 do_check_eq(count, 2); |
|
96 |
|
97 count = yield provider.storage.getDailyCounterCountFromFieldID(counterID, yesterday); |
|
98 do_check_eq(count, 1); |
|
99 |
|
100 yield m.incrementDailyCounter("daily-counter", now, 4); |
|
101 count = yield provider.storage.getDailyCounterCountFromFieldID(counterID, now); |
|
102 do_check_eq(count, 6); |
|
103 |
|
104 // Daily discrete numeric. |
|
105 let dailyDiscreteNumericID = m.fieldID("daily-discrete-numeric"); |
|
106 yield m.addDailyDiscreteNumeric("daily-discrete-numeric", 5, now); |
|
107 yield m.addDailyDiscreteNumeric("daily-discrete-numeric", 6, now); |
|
108 yield m.addDailyDiscreteNumeric("daily-discrete-numeric", 7, yesterday); |
|
109 |
|
110 let values = yield provider.storage.getDailyDiscreteNumericFromFieldID( |
|
111 dailyDiscreteNumericID, now); |
|
112 |
|
113 do_check_eq(values.size, 1); |
|
114 do_check_true(values.hasDay(now)); |
|
115 let actual = values.getDay(now); |
|
116 do_check_eq(actual.length, 2); |
|
117 do_check_eq(actual[0], 5); |
|
118 do_check_eq(actual[1], 6); |
|
119 |
|
120 values = yield provider.storage.getDailyDiscreteNumericFromFieldID( |
|
121 dailyDiscreteNumericID, yesterday); |
|
122 |
|
123 do_check_eq(values.size, 1); |
|
124 do_check_true(values.hasDay(yesterday)); |
|
125 do_check_eq(values.getDay(yesterday)[0], 7); |
|
126 |
|
127 // Daily discrete text. |
|
128 let dailyDiscreteTextID = m.fieldID("daily-discrete-text"); |
|
129 yield m.addDailyDiscreteText("daily-discrete-text", "foo", now); |
|
130 yield m.addDailyDiscreteText("daily-discrete-text", "bar", now); |
|
131 yield m.addDailyDiscreteText("daily-discrete-text", "biz", yesterday); |
|
132 |
|
133 values = yield provider.storage.getDailyDiscreteTextFromFieldID( |
|
134 dailyDiscreteTextID, now); |
|
135 |
|
136 do_check_eq(values.size, 1); |
|
137 do_check_true(values.hasDay(now)); |
|
138 actual = values.getDay(now); |
|
139 do_check_eq(actual.length, 2); |
|
140 do_check_eq(actual[0], "foo"); |
|
141 do_check_eq(actual[1], "bar"); |
|
142 |
|
143 values = yield provider.storage.getDailyDiscreteTextFromFieldID( |
|
144 dailyDiscreteTextID, yesterday); |
|
145 do_check_true(values.hasDay(yesterday)); |
|
146 do_check_eq(values.getDay(yesterday)[0], "biz"); |
|
147 |
|
148 // Daily last numeric. |
|
149 let lastDailyNumericID = m.fieldID("daily-last-numeric"); |
|
150 yield m.setDailyLastNumeric("daily-last-numeric", 5, now); |
|
151 yield m.setDailyLastNumeric("daily-last-numeric", 6, yesterday); |
|
152 |
|
153 let result = yield provider.storage.getDailyLastNumericFromFieldID( |
|
154 lastDailyNumericID, now); |
|
155 do_check_eq(result.size, 1); |
|
156 do_check_true(result.hasDay(now)); |
|
157 do_check_eq(result.getDay(now), 5); |
|
158 |
|
159 result = yield provider.storage.getDailyLastNumericFromFieldID( |
|
160 lastDailyNumericID, yesterday); |
|
161 do_check_true(result.hasDay(yesterday)); |
|
162 do_check_eq(result.getDay(yesterday), 6); |
|
163 |
|
164 yield m.setDailyLastNumeric("daily-last-numeric", 7, now); |
|
165 result = yield provider.storage.getDailyLastNumericFromFieldID( |
|
166 lastDailyNumericID, now); |
|
167 do_check_eq(result.getDay(now), 7); |
|
168 |
|
169 // Daily last text. |
|
170 let lastDailyTextID = m.fieldID("daily-last-text"); |
|
171 yield m.setDailyLastText("daily-last-text", "foo", now); |
|
172 yield m.setDailyLastText("daily-last-text", "bar", yesterday); |
|
173 |
|
174 result = yield provider.storage.getDailyLastTextFromFieldID( |
|
175 lastDailyTextID, now); |
|
176 do_check_eq(result.size, 1); |
|
177 do_check_true(result.hasDay(now)); |
|
178 do_check_eq(result.getDay(now), "foo"); |
|
179 |
|
180 result = yield provider.storage.getDailyLastTextFromFieldID( |
|
181 lastDailyTextID, yesterday); |
|
182 do_check_true(result.hasDay(yesterday)); |
|
183 do_check_eq(result.getDay(yesterday), "bar"); |
|
184 |
|
185 yield m.setDailyLastText("daily-last-text", "biz", now); |
|
186 result = yield provider.storage.getDailyLastTextFromFieldID( |
|
187 lastDailyTextID, now); |
|
188 do_check_eq(result.getDay(now), "biz"); |
|
189 |
|
190 // Last numeric. |
|
191 let lastNumericID = m.fieldID("last-numeric"); |
|
192 yield m.setLastNumeric("last-numeric", 1, now); |
|
193 result = yield provider.storage.getLastNumericFromFieldID(lastNumericID); |
|
194 do_check_eq(result[1], 1); |
|
195 do_check_true(result[0].getTime() < now.getTime()); |
|
196 do_check_true(result[0].getTime() > yesterday.getTime()); |
|
197 |
|
198 yield m.setLastNumeric("last-numeric", 2, now); |
|
199 result = yield provider.storage.getLastNumericFromFieldID(lastNumericID); |
|
200 do_check_eq(result[1], 2); |
|
201 |
|
202 // Last text. |
|
203 let lastTextID = m.fieldID("last-text"); |
|
204 yield m.setLastText("last-text", "foo", now); |
|
205 result = yield provider.storage.getLastTextFromFieldID(lastTextID); |
|
206 do_check_eq(result[1], "foo"); |
|
207 do_check_true(result[0].getTime() < now.getTime()); |
|
208 do_check_true(result[0].getTime() > yesterday.getTime()); |
|
209 |
|
210 yield m.setLastText("last-text", "bar", now); |
|
211 result = yield provider.storage.getLastTextFromFieldID(lastTextID); |
|
212 do_check_eq(result[1], "bar"); |
|
213 |
|
214 yield provider.storage.close(); |
|
215 }); |
|
216 |
|
217 add_task(function test_serialize_json_default() { |
|
218 let provider = yield getProvider("serialize_json_default"); |
|
219 |
|
220 let now = new Date(); |
|
221 let yesterday = new Date(now.getTime() - MILLISECONDS_PER_DAY); |
|
222 |
|
223 let m = provider.getMeasurement("DummyMeasurement", 1); |
|
224 |
|
225 m.incrementDailyCounter("daily-counter", now); |
|
226 m.incrementDailyCounter("daily-counter", now); |
|
227 m.incrementDailyCounter("daily-counter", yesterday); |
|
228 |
|
229 m.addDailyDiscreteNumeric("daily-discrete-numeric", 1, now); |
|
230 m.addDailyDiscreteNumeric("daily-discrete-numeric", 2, now); |
|
231 m.addDailyDiscreteNumeric("daily-discrete-numeric", 3, yesterday); |
|
232 |
|
233 m.addDailyDiscreteText("daily-discrete-text", "foo", now); |
|
234 m.addDailyDiscreteText("daily-discrete-text", "bar", now); |
|
235 m.addDailyDiscreteText("daily-discrete-text", "baz", yesterday); |
|
236 |
|
237 m.setDailyLastNumeric("daily-last-numeric", 4, now); |
|
238 m.setDailyLastNumeric("daily-last-numeric", 5, yesterday); |
|
239 |
|
240 m.setDailyLastText("daily-last-text", "apple", now); |
|
241 m.setDailyLastText("daily-last-text", "orange", yesterday); |
|
242 |
|
243 m.setLastNumeric("last-numeric", 6, now); |
|
244 yield m.setLastText("last-text", "hello", now); |
|
245 |
|
246 let data = yield provider.storage.getMeasurementValues(m.id); |
|
247 |
|
248 let serializer = m.serializer(m.SERIALIZE_JSON); |
|
249 let formatted = serializer.singular(data.singular); |
|
250 |
|
251 do_check_eq(Object.keys(formatted).length, 3); // Our keys + _v. |
|
252 do_check_true("last-numeric" in formatted); |
|
253 do_check_true("last-text" in formatted); |
|
254 do_check_eq(formatted["last-numeric"], 6); |
|
255 do_check_eq(formatted["last-text"], "hello"); |
|
256 do_check_eq(formatted["_v"], 1); |
|
257 |
|
258 formatted = serializer.daily(data.days.getDay(now)); |
|
259 do_check_eq(Object.keys(formatted).length, 6); // Our keys + _v. |
|
260 do_check_eq(formatted["daily-counter"], 2); |
|
261 do_check_eq(formatted["_v"], 1); |
|
262 |
|
263 do_check_true(Array.isArray(formatted["daily-discrete-numeric"])); |
|
264 do_check_eq(formatted["daily-discrete-numeric"].length, 2); |
|
265 do_check_eq(formatted["daily-discrete-numeric"][0], 1); |
|
266 do_check_eq(formatted["daily-discrete-numeric"][1], 2); |
|
267 |
|
268 do_check_true(Array.isArray(formatted["daily-discrete-text"])); |
|
269 do_check_eq(formatted["daily-discrete-text"].length, 2); |
|
270 do_check_eq(formatted["daily-discrete-text"][0], "foo"); |
|
271 do_check_eq(formatted["daily-discrete-text"][1], "bar"); |
|
272 |
|
273 do_check_eq(formatted["daily-last-numeric"], 4); |
|
274 do_check_eq(formatted["daily-last-text"], "apple"); |
|
275 |
|
276 formatted = serializer.daily(data.days.getDay(yesterday)); |
|
277 do_check_eq(formatted["daily-last-numeric"], 5); |
|
278 do_check_eq(formatted["daily-last-text"], "orange"); |
|
279 |
|
280 // Now let's turn off a field so that it's present in the DB |
|
281 // but not present in the output. |
|
282 let called = false; |
|
283 let excluded = "daily-last-numeric"; |
|
284 Object.defineProperty(m, "shouldIncludeField", { |
|
285 value: function fakeShouldIncludeField(field) { |
|
286 called = true; |
|
287 return field != excluded; |
|
288 }, |
|
289 }); |
|
290 |
|
291 let limited = serializer.daily(data.days.getDay(yesterday)); |
|
292 do_check_true(called); |
|
293 do_check_false(excluded in limited); |
|
294 do_check_eq(formatted["daily-last-text"], "orange"); |
|
295 |
|
296 yield provider.storage.close(); |
|
297 }); |