OLD | NEW |
| (Empty) |
1 // Copyright 2011 Google Inc. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 // ======================================================================== | |
15 | |
16 #include "omaha/common/experiment_labels.h" | |
17 #include "omaha/testing/resource.h" | |
18 #include "omaha/testing/unit_test.h" | |
19 | |
20 namespace omaha { | |
21 | |
22 namespace { | |
23 | |
24 #define LABEL_DELIMITER_KV _T("=") | |
25 #define LABEL_DELIMITER_EX _T("|") | |
26 #define LABEL_DELIMITER_LA _T(";") | |
27 | |
28 #define LABELONE_KEY _T("test_key_1") | |
29 #define LABELONE_VALUE _T("test_value_1") | |
30 #define LABELONE_EXP_STR _T("Fri, 14 Aug 2015 16:13:03 GMT") | |
31 #define LABELONE_EXP_INT 130840423830000000uI64 | |
32 #define LABELONE_COMBINED LABELONE_KEY \ | |
33 LABEL_DELIMITER_KV \ | |
34 LABELONE_VALUE \ | |
35 LABEL_DELIMITER_EX \ | |
36 LABELONE_EXP_STR | |
37 | |
38 #define LABELTWO_KEY _T("test_key_2") | |
39 #define LABELTWO_VALUE _T("test_value_2") | |
40 #define LABELTWO_EXP_STR _T("Thu, 27 Nov 2014 23:59:59 GMT") | |
41 #define LABELTWO_EXP_INT 130616063990000000uI64 | |
42 #define LABELTWO_COMBINED LABELTWO_KEY \ | |
43 LABEL_DELIMITER_KV \ | |
44 LABELTWO_VALUE \ | |
45 LABEL_DELIMITER_EX \ | |
46 LABELTWO_EXP_STR | |
47 | |
48 #define LABELOLD_KEY _T("test_key_old") | |
49 #define LABELOLD_VALUE _T("test_value_old") | |
50 #define LABELOLD_EXP_STR _T("Mon, 04 Jan 2010 08:00:00 GMT") | |
51 #define LABELOLD_EXP_INT 129070656000000000uI64 | |
52 #define LABELOLD_COMBINED LABELOLD_KEY \ | |
53 LABEL_DELIMITER_KV \ | |
54 LABELOLD_VALUE \ | |
55 LABEL_DELIMITER_EX \ | |
56 LABELOLD_EXP_STR | |
57 | |
58 | |
59 const TCHAR* const kLabelOneKey = LABELONE_KEY; | |
60 const TCHAR* const kLabelOneValue = LABELONE_VALUE; | |
61 const TCHAR* const kLabelOneExpStr = LABELONE_EXP_STR; | |
62 const time64 kLabelOneExpInt = LABELONE_EXP_INT; | |
63 const TCHAR* const kLabelOneCombined = LABELONE_COMBINED; | |
64 | |
65 const TCHAR* const kLabelTwoKey = LABELTWO_KEY; | |
66 const TCHAR* const kLabelTwoValue = LABELTWO_VALUE; | |
67 const TCHAR* const kLabelTwoExpStr = LABELTWO_EXP_STR; | |
68 const time64 kLabelTwoExpInt = LABELTWO_EXP_INT; | |
69 const TCHAR* const kLabelTwoCombined = LABELTWO_COMBINED; | |
70 | |
71 const TCHAR* const kLabelOldKey = LABELOLD_KEY; | |
72 const TCHAR* const kLabelOldValue = LABELOLD_VALUE; | |
73 const TCHAR* const kLabelOldExpStr = LABELOLD_EXP_STR; | |
74 const time64 kLabelOldExpInt = LABELOLD_EXP_INT; | |
75 const TCHAR* const kLabelOldCombined = LABELOLD_COMBINED; | |
76 | |
77 const TCHAR* const kLabelNewCombined = LABELONE_COMBINED | |
78 LABEL_DELIMITER_LA | |
79 LABELTWO_COMBINED; | |
80 | |
81 const TCHAR* const kLabelAllCombined = LABELONE_COMBINED | |
82 LABEL_DELIMITER_LA | |
83 LABELTWO_COMBINED | |
84 LABEL_DELIMITER_LA | |
85 LABELOLD_COMBINED; | |
86 | |
87 } // end namespace | |
88 | |
89 TEST(ExperimentLabelsTest, Empty) { | |
90 ExperimentLabels el; | |
91 | |
92 EXPECT_EQ(0, el.NumLabels()); | |
93 EXPECT_FALSE(el.ContainsKey(kLabelOneKey)); | |
94 EXPECT_FALSE(el.ContainsKey(kLabelTwoKey)); | |
95 EXPECT_FALSE(el.ContainsKey(kLabelOldKey)); | |
96 EXPECT_FALSE(el.FindLabelByKey(kLabelOneKey, NULL, NULL)); | |
97 EXPECT_FALSE(el.FindLabelByKey(kLabelTwoKey, NULL, NULL)); | |
98 EXPECT_FALSE(el.FindLabelByKey(kLabelOldKey, NULL, NULL)); | |
99 } | |
100 | |
101 TEST(ExperimentLabelsTest, BasicOperations) { | |
102 ExperimentLabels el; | |
103 | |
104 EXPECT_EQ(0, el.NumLabels()); | |
105 EXPECT_FALSE(el.ContainsKey(kLabelOneKey)); | |
106 EXPECT_FALSE(el.ContainsKey(kLabelTwoKey)); | |
107 EXPECT_FALSE(el.ContainsKey(kLabelOldKey)); | |
108 | |
109 // Start by adding a single label. | |
110 EXPECT_TRUE(el.SetLabel(kLabelOneKey, kLabelOneValue, kLabelOneExpInt)); | |
111 EXPECT_EQ(1, el.NumLabels()); | |
112 EXPECT_TRUE(el.ContainsKey(kLabelOneKey)); | |
113 EXPECT_FALSE(el.ContainsKey(kLabelTwoKey)); | |
114 EXPECT_FALSE(el.ContainsKey(kLabelOldKey)); | |
115 | |
116 // Add both future labels now. | |
117 EXPECT_TRUE(el.SetLabel(kLabelTwoKey, kLabelTwoValue, kLabelTwoExpInt)); | |
118 EXPECT_EQ(2, el.NumLabels()); | |
119 EXPECT_TRUE(el.ContainsKey(kLabelOneKey)); | |
120 EXPECT_TRUE(el.ContainsKey(kLabelTwoKey)); | |
121 EXPECT_FALSE(el.ContainsKey(kLabelOldKey)); | |
122 | |
123 // Clear the first label; it should not appear. | |
124 EXPECT_TRUE(el.ClearLabel(kLabelOneKey)); | |
125 EXPECT_EQ(1, el.NumLabels()); | |
126 EXPECT_FALSE(el.ContainsKey(kLabelOneKey)); | |
127 EXPECT_TRUE(el.ContainsKey(kLabelTwoKey)); | |
128 EXPECT_FALSE(el.ContainsKey(kLabelOldKey)); | |
129 | |
130 // ClearLabel should return false if the key isn't present. | |
131 EXPECT_FALSE(el.ClearLabel(kLabelOldKey)); | |
132 | |
133 // ClearAllLabels should clear all labels. | |
134 el.ClearAllLabels(); | |
135 EXPECT_EQ(0, el.NumLabels()); | |
136 EXPECT_FALSE(el.ContainsKey(kLabelOneKey)); | |
137 EXPECT_FALSE(el.ContainsKey(kLabelTwoKey)); | |
138 EXPECT_FALSE(el.ContainsKey(kLabelOldKey)); | |
139 } | |
140 | |
141 TEST(ExperimentLabelsTest, SetInvalidParameters) { | |
142 ExperimentLabels el; | |
143 | |
144 // Verify that our core test parameters are okay by adding a key, then | |
145 // clearing all. | |
146 EXPECT_TRUE(el.SetLabel(kLabelOneKey, kLabelOneValue, kLabelOneExpInt)); | |
147 el.ClearAllLabels(); | |
148 | |
149 // Don't allow zero length names or values, or expirations in the past. | |
150 EXPECT_FALSE(el.SetLabel(_T(""), kLabelOneValue, kLabelOneExpInt)); | |
151 EXPECT_FALSE(el.SetLabel(kLabelOneKey, _T(""), kLabelOneExpInt)); | |
152 EXPECT_FALSE(el.SetLabel(kLabelOneKey, kLabelOneValue, 0)); | |
153 | |
154 // Explicitly validate that names and values do not contain delimiters, | |
155 // quotes, angle brackets, question marks, or ampersands, as these could | |
156 // break parsing at the label-string, extraargs, or XML levels. | |
157 EXPECT_FALSE(el.SetLabel(_T("=test"), kLabelOneValue, kLabelOneExpInt)); | |
158 EXPECT_FALSE(el.SetLabel(_T("te=st"), kLabelOneValue, kLabelOneExpInt)); | |
159 EXPECT_FALSE(el.SetLabel(_T("test="), kLabelOneValue, kLabelOneExpInt)); | |
160 EXPECT_FALSE(el.SetLabel(_T("|test"), kLabelOneValue, kLabelOneExpInt)); | |
161 EXPECT_FALSE(el.SetLabel(_T("te|st"), kLabelOneValue, kLabelOneExpInt)); | |
162 EXPECT_FALSE(el.SetLabel(_T("test|"), kLabelOneValue, kLabelOneExpInt)); | |
163 EXPECT_FALSE(el.SetLabel(_T("test<"), kLabelOneValue, kLabelOneExpInt)); | |
164 EXPECT_FALSE(el.SetLabel(_T("test>"), kLabelOneValue, kLabelOneExpInt)); | |
165 EXPECT_FALSE(el.SetLabel(_T("test&"), kLabelOneValue, kLabelOneExpInt)); | |
166 EXPECT_FALSE(el.SetLabel(_T("test?"), kLabelOneValue, kLabelOneExpInt)); | |
167 EXPECT_FALSE(el.SetLabel(_T("test^"), kLabelOneValue, kLabelOneExpInt)); | |
168 EXPECT_FALSE(el.SetLabel(_T("test'"), kLabelOneValue, kLabelOneExpInt)); | |
169 EXPECT_FALSE(el.SetLabel(_T("test\""), kLabelOneValue, kLabelOneExpInt)); | |
170 EXPECT_FALSE(el.SetLabel(kLabelOneKey, _T("=test"), kLabelOneExpInt)); | |
171 EXPECT_FALSE(el.SetLabel(kLabelOneKey, _T("te=st"), kLabelOneExpInt)); | |
172 EXPECT_FALSE(el.SetLabel(kLabelOneKey, _T("test="), kLabelOneExpInt)); | |
173 EXPECT_FALSE(el.SetLabel(kLabelOneKey, _T("|test"), kLabelOneExpInt)); | |
174 EXPECT_FALSE(el.SetLabel(kLabelOneKey, _T("te|st"), kLabelOneExpInt)); | |
175 EXPECT_FALSE(el.SetLabel(kLabelOneKey, _T("test|"), kLabelOneExpInt)); | |
176 EXPECT_FALSE(el.SetLabel(kLabelOneKey, _T("test<"), kLabelOneExpInt)); | |
177 EXPECT_FALSE(el.SetLabel(kLabelOneKey, _T("test>"), kLabelOneExpInt)); | |
178 EXPECT_FALSE(el.SetLabel(kLabelOneKey, _T("test&"), kLabelOneExpInt)); | |
179 EXPECT_FALSE(el.SetLabel(kLabelOneKey, _T("test?"), kLabelOneExpInt)); | |
180 EXPECT_FALSE(el.SetLabel(kLabelOneKey, _T("test^"), kLabelOneExpInt)); | |
181 EXPECT_FALSE(el.SetLabel(kLabelOneKey, _T("test'"), kLabelOneExpInt)); | |
182 EXPECT_FALSE(el.SetLabel(kLabelOneKey, _T("test\""), kLabelOneExpInt)); | |
183 EXPECT_EQ(0, el.NumLabels()); | |
184 | |
185 // Allow an expiration in the past if and only if we override the default | |
186 // preserve-expired-labels setting. | |
187 el.SetPreserveExpiredLabels(true); | |
188 EXPECT_TRUE(el.SetLabel(kLabelOneKey, kLabelOneValue, kLabelOldExpInt)); | |
189 EXPECT_EQ(1, el.NumLabels()); | |
190 } | |
191 | |
192 TEST(ExperimentLabelsTest, SetWillOverwrite) { | |
193 ExperimentLabels el; | |
194 CString value; | |
195 time64 expiration; | |
196 | |
197 EXPECT_TRUE(el.SetLabel(kLabelOneKey, kLabelOneValue, kLabelOneExpInt)); | |
198 | |
199 EXPECT_EQ(1, el.NumLabels()); | |
200 EXPECT_TRUE(el.FindLabelByKey(kLabelOneKey, &value, &expiration)); | |
201 EXPECT_STREQ(value, kLabelOneValue); | |
202 EXPECT_EQ(expiration, kLabelOneExpInt); | |
203 | |
204 EXPECT_TRUE(el.SetLabel(kLabelOneKey, kLabelTwoValue, kLabelTwoExpInt)); | |
205 | |
206 EXPECT_EQ(1, el.NumLabels()); | |
207 EXPECT_TRUE(el.FindLabelByKey(kLabelOneKey, &value, &expiration)); | |
208 EXPECT_STREQ(value, kLabelTwoValue); | |
209 EXPECT_EQ(expiration, kLabelTwoExpInt); | |
210 } | |
211 | |
212 TEST(ExperimentLabelsTest, FindLabelByKey) { | |
213 ExperimentLabels el; | |
214 CString value; | |
215 time64 expiration; | |
216 | |
217 EXPECT_TRUE(el.SetLabel(kLabelOneKey, kLabelOneValue, kLabelOneExpInt)); | |
218 EXPECT_TRUE(el.SetLabel(kLabelTwoKey, kLabelTwoValue, kLabelTwoExpInt)); | |
219 EXPECT_EQ(2, el.NumLabels()); | |
220 | |
221 // Safely return partial values if either or both out parameters are NULL. | |
222 EXPECT_TRUE(el.FindLabelByKey(kLabelOneKey, NULL, NULL)); | |
223 EXPECT_TRUE(el.FindLabelByKey(kLabelOneKey, &value, NULL)); | |
224 EXPECT_STREQ(value, kLabelOneValue); | |
225 EXPECT_TRUE(el.FindLabelByKey(kLabelOneKey, NULL, &expiration)); | |
226 EXPECT_EQ(expiration, kLabelOneExpInt); | |
227 | |
228 // Overwrite values if they already have values. | |
229 EXPECT_TRUE(el.FindLabelByKey(kLabelTwoKey, &value, &expiration)); | |
230 EXPECT_STREQ(value, kLabelTwoValue); | |
231 EXPECT_EQ(expiration, kLabelTwoExpInt); | |
232 | |
233 // If the key isn't present, return false; both out-params are unmodified. | |
234 EXPECT_FALSE(el.FindLabelByKey(kLabelOldKey, &value, &expiration)); | |
235 EXPECT_STREQ(value, kLabelTwoValue); | |
236 EXPECT_EQ(expiration, kLabelTwoExpInt); | |
237 } | |
238 | |
239 TEST(ExperimentLabelsTest, Serialize_Empty) { | |
240 ExperimentLabels el; | |
241 | |
242 CString serialized = el.Serialize(); | |
243 EXPECT_STREQ(serialized, _T("")); | |
244 } | |
245 | |
246 TEST(ExperimentLabelsTest, Serialize_Single_Valid) { | |
247 ExperimentLabels el; | |
248 | |
249 EXPECT_TRUE(el.SetLabel(kLabelOneKey, kLabelOneValue, kLabelOneExpInt)); | |
250 EXPECT_EQ(1, el.NumLabels()); | |
251 | |
252 CString serialized = el.Serialize(); | |
253 EXPECT_STREQ(serialized, kLabelOneCombined); | |
254 } | |
255 | |
256 TEST(ExperimentLabelsTest, Serialize_Single_Expired) { | |
257 ExperimentLabels el; | |
258 | |
259 el.SetPreserveExpiredLabels(true); | |
260 EXPECT_TRUE(el.SetLabel(kLabelOldKey, kLabelOldValue, kLabelOldExpInt)); | |
261 EXPECT_EQ(1, el.NumLabels()); | |
262 | |
263 el.SetPreserveExpiredLabels(false); | |
264 CString serialized = el.Serialize(); | |
265 EXPECT_STREQ(serialized, _T("")); | |
266 | |
267 el.SetPreserveExpiredLabels(true); | |
268 serialized = el.Serialize(); | |
269 EXPECT_STREQ(serialized, kLabelOldCombined); | |
270 } | |
271 | |
272 TEST(ExperimentLabelsTest, Serialize_Multi_Valid) { | |
273 ExperimentLabels el; | |
274 | |
275 EXPECT_TRUE(el.SetLabel(kLabelOneKey, kLabelOneValue, kLabelOneExpInt)); | |
276 EXPECT_TRUE(el.SetLabel(kLabelTwoKey, kLabelTwoValue, kLabelTwoExpInt)); | |
277 EXPECT_EQ(2, el.NumLabels()); | |
278 | |
279 CString serialized = el.Serialize(); | |
280 EXPECT_STREQ(serialized, kLabelNewCombined); | |
281 } | |
282 | |
283 TEST(ExperimentLabelsTest, Serialize_Multi_Valid_Expired) { | |
284 ExperimentLabels el; | |
285 | |
286 el.SetPreserveExpiredLabels(true); | |
287 EXPECT_TRUE(el.SetLabel(kLabelOneKey, kLabelOneValue, kLabelOneExpInt)); | |
288 EXPECT_TRUE(el.SetLabel(kLabelTwoKey, kLabelTwoValue, kLabelTwoExpInt)); | |
289 EXPECT_TRUE(el.SetLabel(kLabelOldKey, kLabelOldValue, kLabelOldExpInt)); | |
290 EXPECT_EQ(3, el.NumLabels()); | |
291 | |
292 el.SetPreserveExpiredLabels(false); | |
293 CString serialized = el.Serialize(); | |
294 EXPECT_STREQ(serialized, kLabelNewCombined); | |
295 | |
296 el.SetPreserveExpiredLabels(true); | |
297 serialized = el.Serialize(); | |
298 EXPECT_STREQ(serialized, kLabelAllCombined); | |
299 } | |
300 | |
301 | |
302 TEST(ExperimentLabelsTest, Deserialize_EmptyString) { | |
303 ExperimentLabels el; | |
304 | |
305 EXPECT_TRUE(el.Deserialize(_T(""))); | |
306 EXPECT_EQ(0, el.NumLabels()); | |
307 } | |
308 | |
309 TEST(ExperimentLabelsTest, Deserialize_Single_Valid) { | |
310 ExperimentLabels el; | |
311 | |
312 EXPECT_TRUE(el.Deserialize(kLabelOneCombined)); | |
313 EXPECT_EQ(1, el.NumLabels()); | |
314 | |
315 CString key; | |
316 CString value; | |
317 time64 expiration; | |
318 el.GetLabelByIndex(0, &key, &value, &expiration); | |
319 EXPECT_STREQ(key, kLabelOneKey); | |
320 EXPECT_STREQ(value, kLabelOneValue); | |
321 EXPECT_EQ(expiration, kLabelOneExpInt); | |
322 } | |
323 | |
324 TEST(ExperimentLabelsTest, Deserialize_Multi_Valid) { | |
325 ExperimentLabels el; | |
326 | |
327 EXPECT_TRUE(el.Deserialize(kLabelNewCombined)); | |
328 EXPECT_EQ(2, el.NumLabels()); | |
329 | |
330 CString key; | |
331 CString value; | |
332 time64 expiration; | |
333 el.GetLabelByIndex(0, &key, &value, &expiration); | |
334 EXPECT_STREQ(key, kLabelOneKey); | |
335 EXPECT_STREQ(value, kLabelOneValue); | |
336 EXPECT_EQ(expiration, kLabelOneExpInt); | |
337 el.GetLabelByIndex(1, &key, &value, &expiration); | |
338 EXPECT_STREQ(key, kLabelTwoKey); | |
339 EXPECT_STREQ(value, kLabelTwoValue); | |
340 EXPECT_EQ(expiration, kLabelTwoExpInt); | |
341 } | |
342 | |
343 TEST(ExperimentLabelsTest, Deserialize_Single_Valid_Expired) { | |
344 ExperimentLabels el; | |
345 | |
346 EXPECT_TRUE(el.Deserialize(kLabelOldCombined)); | |
347 EXPECT_EQ(0, el.NumLabels()); | |
348 | |
349 el.SetPreserveExpiredLabels(true); | |
350 EXPECT_TRUE(el.Deserialize(kLabelOldCombined)); | |
351 EXPECT_EQ(1, el.NumLabels()); | |
352 | |
353 CString key; | |
354 CString value; | |
355 time64 expiration; | |
356 el.GetLabelByIndex(0, &key, &value, &expiration); | |
357 EXPECT_STREQ(key, kLabelOldKey); | |
358 EXPECT_STREQ(value, kLabelOldValue); | |
359 EXPECT_EQ(expiration, kLabelOldExpInt); | |
360 } | |
361 | |
362 TEST(ExperimentLabelsTest, Deserialize_Multi_Valid_Expired) { | |
363 ExperimentLabels el; | |
364 | |
365 EXPECT_TRUE(el.Deserialize(kLabelAllCombined)); | |
366 EXPECT_EQ(2, el.NumLabels()); | |
367 EXPECT_TRUE(el.ContainsKey(kLabelOneKey)); | |
368 EXPECT_TRUE(el.ContainsKey(kLabelTwoKey)); | |
369 EXPECT_FALSE(el.ContainsKey(kLabelOldKey)); | |
370 | |
371 el.ClearAllLabels(); | |
372 | |
373 el.SetPreserveExpiredLabels(true); | |
374 EXPECT_TRUE(el.Deserialize(kLabelAllCombined)); | |
375 EXPECT_EQ(3, el.NumLabels()); | |
376 EXPECT_TRUE(el.ContainsKey(kLabelOneKey)); | |
377 EXPECT_TRUE(el.ContainsKey(kLabelTwoKey)); | |
378 EXPECT_TRUE(el.ContainsKey(kLabelOldKey)); | |
379 } | |
380 | |
381 TEST(ExperimentLabelsTest, Deserialize_Invalid_ZeroLengthKey) { | |
382 ExperimentLabels el; | |
383 | |
384 // Base case: "=valid_value|valid_exp" | |
385 const TCHAR* const invalid_segment = LABEL_DELIMITER_KV | |
386 LABELONE_VALUE | |
387 LABEL_DELIMITER_EX | |
388 LABELONE_EXP_STR; | |
389 EXPECT_FALSE(el.Deserialize(invalid_segment)); | |
390 EXPECT_EQ(0, el.NumLabels()); | |
391 | |
392 // Variant case 1: "=valid_value|valid_exp;valid_key=valid_value|valid_exp" | |
393 CString variant1 = invalid_segment; | |
394 variant1.Append(LABEL_DELIMITER_LA); | |
395 variant1.Append(LABELTWO_COMBINED); | |
396 EXPECT_FALSE(el.Deserialize(variant1)); | |
397 EXPECT_EQ(0, el.NumLabels()); | |
398 | |
399 // Variant case 2: "valid_key=valid_value|valid_exp;=valid_value|valid_exp" | |
400 CString variant2 = LABELTWO_COMBINED; | |
401 variant2.Append(LABEL_DELIMITER_LA); | |
402 variant2.Append(invalid_segment); | |
403 EXPECT_FALSE(el.Deserialize(variant2)); | |
404 EXPECT_EQ(0, el.NumLabels()); | |
405 } | |
406 | |
407 TEST(ExperimentLabelsTest, Deserialize_Invalid_ZeroLengthValue) { | |
408 ExperimentLabels el; | |
409 | |
410 // Base case: "valid_key=|valid_exp" | |
411 const TCHAR* const invalid_segment = LABELONE_KEY | |
412 LABEL_DELIMITER_KV | |
413 LABEL_DELIMITER_EX | |
414 LABELONE_EXP_STR; | |
415 EXPECT_FALSE(el.Deserialize(invalid_segment)); | |
416 EXPECT_EQ(0, el.NumLabels()); | |
417 | |
418 // Variant case 1: "valid_key=|valid_exp;valid_key=valid_value|valid_exp" | |
419 CString variant1 = invalid_segment; | |
420 variant1.Append(LABEL_DELIMITER_LA); | |
421 variant1.Append(LABELTWO_COMBINED); | |
422 EXPECT_FALSE(el.Deserialize(variant1)); | |
423 EXPECT_EQ(0, el.NumLabels()); | |
424 | |
425 // Variant case 2: "valid_key=valid_value|valid_exp;valid_key=|valid_exp" | |
426 el.ClearAllLabels(); | |
427 CString variant2 = LABELTWO_COMBINED; | |
428 variant2.Append(LABEL_DELIMITER_LA); | |
429 variant2.Append(invalid_segment); | |
430 EXPECT_FALSE(el.Deserialize(variant2)); | |
431 EXPECT_EQ(0, el.NumLabels()); | |
432 } | |
433 | |
434 TEST(ExperimentLabelsTest, Deserialize_Invalid_ZeroLengthDate) { | |
435 ExperimentLabels el; | |
436 | |
437 // Base case: "valid_key=valid_value|" | |
438 const TCHAR* const invalid_segment = LABELONE_KEY | |
439 LABEL_DELIMITER_KV | |
440 LABELONE_VALUE | |
441 LABEL_DELIMITER_EX; | |
442 EXPECT_FALSE(el.Deserialize(invalid_segment)); | |
443 EXPECT_EQ(0, el.NumLabels()); | |
444 | |
445 // Variant case 1: "valid_key=valid_value|;valid_key=valid_value|valid_exp" | |
446 CString variant1 = invalid_segment; | |
447 variant1.Append(LABEL_DELIMITER_LA); | |
448 variant1.Append(LABELTWO_COMBINED); | |
449 EXPECT_FALSE(el.Deserialize(variant1)); | |
450 EXPECT_EQ(0, el.NumLabels()); | |
451 | |
452 // Variant case 2: "valid_key=valid_value|valid_exp;valid_key=valid_value|" | |
453 CString variant2 = LABELTWO_COMBINED; | |
454 variant2.Append(LABEL_DELIMITER_LA); | |
455 variant2.Append(invalid_segment); | |
456 EXPECT_FALSE(el.Deserialize(variant2)); | |
457 EXPECT_EQ(0, el.NumLabels()); | |
458 } | |
459 | |
460 TEST(ExperimentLabelsTest, Deserialize_Invalid_ExtraDelimiters) { | |
461 ExperimentLabels el; | |
462 | |
463 // Repeated equals: "k==v|e" | |
464 EXPECT_FALSE(el.Deserialize(LABELONE_KEY | |
465 LABEL_DELIMITER_KV | |
466 LABEL_DELIMITER_KV | |
467 LABELONE_VALUE | |
468 LABEL_DELIMITER_EX | |
469 LABELONE_EXP_STR)); | |
470 | |
471 // Repeated pipe: "k=v||e" | |
472 EXPECT_FALSE(el.Deserialize(LABELONE_KEY | |
473 LABEL_DELIMITER_KV | |
474 LABELONE_VALUE | |
475 LABEL_DELIMITER_EX | |
476 LABEL_DELIMITER_EX | |
477 LABELONE_EXP_STR)); | |
478 | |
479 // Degenerate: "=|;=|" | |
480 EXPECT_FALSE(el.Deserialize(LABEL_DELIMITER_KV | |
481 LABEL_DELIMITER_EX | |
482 LABEL_DELIMITER_LA | |
483 LABEL_DELIMITER_KV | |
484 LABEL_DELIMITER_EX)); | |
485 | |
486 EXPECT_EQ(0, el.NumLabels()); | |
487 } | |
488 | |
489 TEST(ExperimentLabelsTest, Deserialize_Valid_ExtraLabelDelimiters) { | |
490 ExperimentLabels el; | |
491 | |
492 // We support (but discourage) leading/trailing/repeated separators; | |
493 // for example, "k=v|e;;;;k=v|e" should cleanly parse (two keys), as | |
494 // should ";;;k=v|e" and "k=v|e;;;" (one key each) and ";;;;;" (no keys). | |
495 | |
496 // Repeated separator: "k=v|e;;k=v|e" | |
497 EXPECT_TRUE(el.Deserialize(LABELONE_COMBINED | |
498 LABEL_DELIMITER_LA | |
499 LABEL_DELIMITER_LA | |
500 LABELTWO_COMBINED)); | |
501 EXPECT_EQ(2, el.NumLabels()); | |
502 el.ClearAllLabels(); | |
503 | |
504 // Leading separator: ";k=v|e" | |
505 EXPECT_TRUE(el.Deserialize(LABEL_DELIMITER_LA LABELONE_COMBINED)); | |
506 EXPECT_EQ(1, el.NumLabels()); | |
507 el.ClearAllLabels(); | |
508 | |
509 // Trailing separator: "k=v|e;" | |
510 EXPECT_TRUE(el.Deserialize(LABELONE_COMBINED LABEL_DELIMITER_LA)); | |
511 EXPECT_EQ(1, el.NumLabels()); | |
512 el.ClearAllLabels(); | |
513 | |
514 // Degenerate: ";;;" | |
515 EXPECT_TRUE(el.Deserialize(LABEL_DELIMITER_LA | |
516 LABEL_DELIMITER_LA | |
517 LABEL_DELIMITER_LA)); | |
518 EXPECT_EQ(0, el.NumLabels()); | |
519 } | |
520 | |
521 TEST(ExperimentLabelsTest, Deserialize_Invalid_MissingDelimiters) { | |
522 ExperimentLabels el; | |
523 | |
524 // Missing all delimiters, single string (kve) | |
525 EXPECT_FALSE(el.Deserialize(LABELONE_KEY | |
526 LABELONE_VALUE | |
527 LABELONE_EXP_STR)); | |
528 | |
529 // Missing expiration delimiter, single string (k=ve) | |
530 EXPECT_FALSE(el.Deserialize(LABELONE_KEY | |
531 LABEL_DELIMITER_KV | |
532 LABELONE_VALUE | |
533 LABELONE_EXP_STR)); | |
534 | |
535 // Missing value delimiter, single string (kv|e) | |
536 EXPECT_FALSE(el.Deserialize(LABELONE_KEY | |
537 LABELONE_VALUE | |
538 LABEL_DELIMITER_EX | |
539 LABELONE_EXP_STR)); | |
540 | |
541 // Missing label delimiter, multi-label (k=v|ek=v|e) | |
542 EXPECT_FALSE(el.Deserialize(LABELONE_COMBINED LABELTWO_COMBINED)); | |
543 | |
544 // Missing value+exp delimiter, multi-label, first (kve;k=v|e) | |
545 EXPECT_FALSE(el.Deserialize(LABELONE_KEY | |
546 LABELONE_VALUE | |
547 LABELONE_EXP_STR | |
548 LABEL_DELIMITER_LA | |
549 LABELTWO_COMBINED)); | |
550 | |
551 // Missing value+exp delimiter, multi-label, second (k=v|e;kve) | |
552 EXPECT_FALSE(el.Deserialize(LABELONE_COMBINED | |
553 LABEL_DELIMITER_LA | |
554 LABELTWO_KEY | |
555 LABELTWO_VALUE | |
556 LABELTWO_EXP_STR)); | |
557 | |
558 // Missing value delimiter, multi-label, first (kv|e;k=v|e) | |
559 EXPECT_FALSE(el.Deserialize(LABELONE_KEY | |
560 LABELONE_VALUE | |
561 LABEL_DELIMITER_EX | |
562 LABELONE_EXP_STR | |
563 LABEL_DELIMITER_LA | |
564 LABELTWO_COMBINED)); | |
565 | |
566 // Missing value delimiter, multi-label, second (k=v|e;kv|e) | |
567 EXPECT_FALSE(el.Deserialize(LABELONE_COMBINED | |
568 LABEL_DELIMITER_LA | |
569 LABELTWO_KEY | |
570 LABELTWO_VALUE | |
571 LABEL_DELIMITER_EX | |
572 LABELTWO_EXP_STR)); | |
573 | |
574 // Missing expiration delimiter, multi-label, first (k=ve;k=v|e) | |
575 EXPECT_FALSE(el.Deserialize(LABELONE_KEY | |
576 LABEL_DELIMITER_KV | |
577 LABELONE_VALUE | |
578 LABELONE_EXP_STR | |
579 LABEL_DELIMITER_LA | |
580 LABELTWO_COMBINED)); | |
581 | |
582 // Missing expiration delimiter, multi-label, second (k=v|e;k=ve) | |
583 EXPECT_FALSE(el.Deserialize(LABELONE_COMBINED | |
584 LABEL_DELIMITER_LA | |
585 LABELTWO_KEY | |
586 LABEL_DELIMITER_KV | |
587 LABELTWO_VALUE | |
588 LABELTWO_EXP_STR)); | |
589 | |
590 EXPECT_EQ(0, el.NumLabels()); | |
591 } | |
592 | |
593 TEST(ExperimentLabelsTest, DeserializeAndApplyDelta_Append) { | |
594 ExperimentLabels el; | |
595 | |
596 EXPECT_TRUE(el.SetLabel(kLabelOneKey, kLabelOneValue, kLabelOneExpInt)); | |
597 EXPECT_EQ(1, el.NumLabels()); | |
598 EXPECT_TRUE(el.DeserializeAndApplyDelta(kLabelTwoCombined)); | |
599 EXPECT_EQ(2, el.NumLabels()); | |
600 | |
601 CString value; | |
602 time64 expiration; | |
603 EXPECT_TRUE(el.FindLabelByKey(kLabelOneKey, &value, &expiration)); | |
604 EXPECT_STREQ(value, kLabelOneValue); | |
605 EXPECT_EQ(expiration, kLabelOneExpInt); | |
606 EXPECT_TRUE(el.FindLabelByKey(kLabelTwoKey, &value, &expiration)); | |
607 EXPECT_STREQ(value, kLabelTwoValue); | |
608 EXPECT_EQ(expiration, kLabelTwoExpInt); | |
609 } | |
610 | |
611 TEST(ExperimentLabelsTest, DeserializeAndApplyDelta_Append_Expired) { | |
612 ExperimentLabels el; | |
613 | |
614 EXPECT_TRUE(el.SetLabel(kLabelOneKey, kLabelOneValue, kLabelOneExpInt)); | |
615 EXPECT_EQ(1, el.NumLabels()); | |
616 EXPECT_TRUE(el.ContainsKey(kLabelOneKey)); | |
617 EXPECT_FALSE(el.ContainsKey(kLabelOldKey)); | |
618 | |
619 EXPECT_TRUE(el.DeserializeAndApplyDelta(kLabelOldCombined)); | |
620 EXPECT_EQ(1, el.NumLabels()); | |
621 EXPECT_TRUE(el.ContainsKey(kLabelOneKey)); | |
622 EXPECT_FALSE(el.ContainsKey(kLabelOldKey)); | |
623 } | |
624 | |
625 TEST(ExperimentLabelsTest, DeserializeAndApplyDelta_Overwrite_Single) { | |
626 ExperimentLabels el; | |
627 | |
628 EXPECT_TRUE(el.SetLabel(kLabelOneKey, kLabelOldValue, kLabelOneExpInt)); | |
629 EXPECT_EQ(1, el.NumLabels()); | |
630 EXPECT_TRUE(el.ContainsKey(kLabelOneKey)); | |
631 EXPECT_FALSE(el.ContainsKey(kLabelTwoKey)); | |
632 | |
633 CString value; | |
634 time64 expiration; | |
635 EXPECT_TRUE(el.FindLabelByKey(kLabelOneKey, &value, &expiration)); | |
636 EXPECT_STREQ(value, kLabelOldValue); | |
637 EXPECT_EQ(expiration, kLabelOneExpInt); | |
638 | |
639 EXPECT_TRUE(el.DeserializeAndApplyDelta(kLabelOneCombined)); | |
640 EXPECT_EQ(1, el.NumLabels()); | |
641 EXPECT_TRUE(el.ContainsKey(kLabelOneKey)); | |
642 EXPECT_FALSE(el.ContainsKey(kLabelTwoKey)); | |
643 | |
644 EXPECT_TRUE(el.FindLabelByKey(kLabelOneKey, &value, &expiration)); | |
645 EXPECT_STREQ(value, kLabelOneValue); | |
646 EXPECT_EQ(expiration, kLabelOneExpInt); | |
647 } | |
648 | |
649 TEST(ExperimentLabelsTest, DeserializeAndApplyDelta_Overwrite_Multi) { | |
650 ExperimentLabels el; | |
651 | |
652 EXPECT_TRUE(el.SetLabel(kLabelOneKey, kLabelOldValue, kLabelOneExpInt)); | |
653 EXPECT_EQ(1, el.NumLabels()); | |
654 EXPECT_TRUE(el.ContainsKey(kLabelOneKey)); | |
655 EXPECT_FALSE(el.ContainsKey(kLabelTwoKey)); | |
656 | |
657 EXPECT_TRUE(el.DeserializeAndApplyDelta(kLabelNewCombined)); | |
658 EXPECT_EQ(2, el.NumLabels()); | |
659 EXPECT_TRUE(el.ContainsKey(kLabelOneKey)); | |
660 EXPECT_TRUE(el.ContainsKey(kLabelTwoKey)); | |
661 | |
662 CString value; | |
663 time64 expiration; | |
664 EXPECT_TRUE(el.FindLabelByKey(kLabelOneKey, &value, &expiration)); | |
665 EXPECT_STREQ(value, kLabelOneValue); | |
666 EXPECT_EQ(expiration, kLabelOneExpInt); | |
667 EXPECT_TRUE(el.FindLabelByKey(kLabelTwoKey, &value, &expiration)); | |
668 EXPECT_STREQ(value, kLabelTwoValue); | |
669 EXPECT_EQ(expiration, kLabelTwoExpInt); | |
670 } | |
671 | |
672 TEST(ExperimentLabelsTest, DeserializeAndApplyDelta_Overwrite_Single_Expired) { | |
673 ExperimentLabels el; | |
674 | |
675 EXPECT_TRUE(el.SetLabel(kLabelOldKey, kLabelOldValue, kLabelOneExpInt)); | |
676 EXPECT_TRUE(el.SetLabel(kLabelTwoKey, kLabelTwoValue, kLabelTwoExpInt)); | |
677 EXPECT_EQ(2, el.NumLabels()); | |
678 EXPECT_TRUE(el.ContainsKey(kLabelOldKey)); | |
679 EXPECT_TRUE(el.ContainsKey(kLabelTwoKey)); | |
680 | |
681 EXPECT_TRUE(el.DeserializeAndApplyDelta(kLabelOldCombined)); | |
682 EXPECT_EQ(1, el.NumLabels()); | |
683 EXPECT_FALSE(el.ContainsKey(kLabelOldKey)); | |
684 EXPECT_TRUE(el.ContainsKey(kLabelTwoKey)); | |
685 } | |
686 | |
687 TEST(ExperimentLabelsTest, DeserializeAndApplyDelta_Overwrite_Multi_Expired) { | |
688 ExperimentLabels el; | |
689 | |
690 EXPECT_TRUE(el.SetLabel(kLabelOneKey, kLabelTwoValue, kLabelOneExpInt)); | |
691 EXPECT_TRUE(el.SetLabel(kLabelTwoKey, kLabelOneValue, kLabelTwoExpInt)); | |
692 EXPECT_TRUE(el.SetLabel(kLabelOldKey, kLabelOldValue, kLabelOneExpInt)); | |
693 EXPECT_EQ(3, el.NumLabels()); | |
694 EXPECT_TRUE(el.ContainsKey(kLabelOneKey)); | |
695 EXPECT_TRUE(el.ContainsKey(kLabelTwoKey)); | |
696 EXPECT_TRUE(el.ContainsKey(kLabelOldKey)); | |
697 | |
698 EXPECT_TRUE(el.DeserializeAndApplyDelta(kLabelAllCombined)); | |
699 EXPECT_EQ(2, el.NumLabels()); | |
700 EXPECT_TRUE(el.ContainsKey(kLabelOneKey)); | |
701 EXPECT_TRUE(el.ContainsKey(kLabelTwoKey)); | |
702 EXPECT_FALSE(el.ContainsKey(kLabelOldKey)); | |
703 } | |
704 | |
705 TEST(ExperimentLabelsTest, Expire) { | |
706 ExperimentLabels el; | |
707 | |
708 el.SetPreserveExpiredLabels(true); | |
709 EXPECT_TRUE(el.SetLabel(kLabelOneKey, kLabelOneValue, kLabelOneExpInt)); | |
710 EXPECT_TRUE(el.SetLabel(kLabelTwoKey, kLabelTwoValue, kLabelTwoExpInt)); | |
711 EXPECT_TRUE(el.SetLabel(kLabelOldKey, kLabelOldValue, kLabelOldExpInt)); | |
712 EXPECT_EQ(3, el.NumLabels()); | |
713 | |
714 el.ExpireLabels(); | |
715 EXPECT_EQ(2, el.NumLabels()); | |
716 EXPECT_TRUE(el.ContainsKey(kLabelOneKey)); | |
717 EXPECT_TRUE(el.ContainsKey(kLabelTwoKey)); | |
718 EXPECT_FALSE(el.ContainsKey(kLabelOldKey)); | |
719 | |
720 EXPECT_TRUE(el.SetLabel(kLabelOneKey, kLabelOneValue, kLabelOldExpInt)); | |
721 el.ExpireLabels(); | |
722 EXPECT_EQ(1, el.NumLabels()); | |
723 EXPECT_FALSE(el.ContainsKey(kLabelOneKey)); | |
724 EXPECT_TRUE(el.ContainsKey(kLabelTwoKey)); | |
725 EXPECT_FALSE(el.ContainsKey(kLabelOldKey)); | |
726 } | |
727 | |
728 } // namespace omaha | |
729 | |
OLD | NEW |