Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chromeos / network / onc / onc_validator_unittest.cc
blob8517f7175e09c77e1cefea802416580fdfec8ccd
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromeos/network/onc/onc_validator.h"
7 #include <string>
8 #include <utility>
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/values.h"
13 #include "chromeos/network/onc/onc_signature.h"
14 #include "chromeos/network/onc/onc_test_utils.h"
15 #include "chromeos/network/onc/onc_utils.h"
16 #include "components/onc/onc_constants.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 namespace chromeos {
20 namespace onc {
22 class ONCValidatorTest : public ::testing::Test {
23 public:
24 // Validate |onc_object| with the given |signature|. The object is considered
25 // to be managed if |managed_onc| is true. A strict validator is used if
26 // |strict| is true. |onc_object| and the resulting repaired object of the
27 // validation is stored, so that expectations can be checked afterwards using
28 // one of the Expect* functions below.
29 void Validate(bool strict,
30 scoped_ptr<base::DictionaryValue> onc_object,
31 const OncValueSignature* signature,
32 bool managed_onc,
33 ::onc::ONCSource onc_source) {
34 scoped_ptr<Validator> validator;
35 if (strict) {
36 // Create a strict validator that complains about every error.
37 validator.reset(new Validator(true, true, true, managed_onc));
38 } else {
39 // Create a liberal validator that ignores or repairs non-critical errors.
40 validator.reset(new Validator(false, false, false, managed_onc));
42 validator->SetOncSource(onc_source);
43 original_object_ = onc_object.Pass();
44 repaired_object_ = validator->ValidateAndRepairObject(signature,
45 *original_object_,
46 &validation_result_);
49 void ExpectValid() {
50 EXPECT_EQ(Validator::VALID, validation_result_);
51 EXPECT_TRUE(test_utils::Equals(original_object_.get(),
52 repaired_object_.get()));
55 void ExpectRepairWithWarnings(
56 const base::DictionaryValue& expected_repaired) {
57 EXPECT_EQ(Validator::VALID_WITH_WARNINGS, validation_result_);
58 EXPECT_TRUE(test_utils::Equals(&expected_repaired, repaired_object_.get()));
61 void ExpectInvalid() {
62 EXPECT_EQ(Validator::INVALID, validation_result_);
63 EXPECT_EQ(NULL, repaired_object_.get());
66 private:
67 Validator::Result validation_result_;
68 scoped_ptr<const base::DictionaryValue> original_object_;
69 scoped_ptr<const base::DictionaryValue> repaired_object_;
72 namespace {
74 struct OncParams {
75 // |location_of_object| is a string to identify the object to be tested. It
76 // may be used as a filename or as a dictionary key.
77 OncParams(const std::string& location_of_object,
78 const OncValueSignature* onc_signature,
79 bool is_managed_onc,
80 ::onc::ONCSource onc_source = ::onc::ONC_SOURCE_NONE)
81 : location(location_of_object),
82 signature(onc_signature),
83 is_managed(is_managed_onc),
84 onc_source(onc_source) {
87 std::string location;
88 const OncValueSignature* signature;
89 bool is_managed;
90 ::onc::ONCSource onc_source;
93 ::std::ostream& operator<<(::std::ostream& os, const OncParams& onc) {
94 return os << "(" << onc.location << ", " << onc.signature << ", "
95 << (onc.is_managed ? "managed" : "unmanaged") << ", "
96 << GetSourceAsString(onc.onc_source) << ")";
99 } // namespace
101 // Ensure that the constant |kEmptyUnencryptedConfiguration| describes a valid
102 // ONC toplevel object.
103 TEST_F(ONCValidatorTest, EmptyUnencryptedConfiguration) {
104 Validate(true, ReadDictionaryFromJson(kEmptyUnencryptedConfiguration),
105 &kToplevelConfigurationSignature, false, ::onc::ONC_SOURCE_NONE);
106 ExpectValid();
109 // This test case is about validating valid ONC objects without any errors. Both
110 // the strict and the liberal validator accept the object.
111 class ONCValidatorValidTest : public ONCValidatorTest,
112 public ::testing::WithParamInterface<OncParams> {
115 TEST_P(ONCValidatorValidTest, StrictValidationValid) {
116 OncParams onc = GetParam();
117 Validate(true, test_utils::ReadTestDictionary(onc.location), onc.signature,
118 onc.is_managed, onc.onc_source);
119 ExpectValid();
122 TEST_P(ONCValidatorValidTest, LiberalValidationValid) {
123 OncParams onc = GetParam();
124 Validate(false, test_utils::ReadTestDictionary(onc.location), onc.signature,
125 onc.is_managed, onc.onc_source);
126 ExpectValid();
129 // The parameters are:
130 // OncParams(string: Filename of a ONC file that is to be validated,
131 // OncValueSignature: signature of that ONC,
132 // bool: true if the ONC is managed).
133 INSTANTIATE_TEST_CASE_P(
134 ONCValidatorValidTest,
135 ONCValidatorValidTest,
136 ::testing::Values(
137 OncParams("managed_toplevel1.onc",
138 &kToplevelConfigurationSignature,
139 true),
140 OncParams("managed_toplevel2.onc",
141 &kToplevelConfigurationSignature,
142 true),
143 OncParams("managed_toplevel_with_global_config.onc",
144 &kToplevelConfigurationSignature,
145 true),
146 // Check that at least one configuration is accepted for
147 // device policies.
148 OncParams("managed_toplevel_wifi_peap.onc",
149 &kToplevelConfigurationSignature,
150 true,
151 ::onc::ONC_SOURCE_DEVICE_POLICY),
152 OncParams("managed_toplevel_l2tpipsec.onc",
153 &kToplevelConfigurationSignature,
154 true),
155 OncParams("toplevel_wifi_hexssid.onc",
156 &kToplevelConfigurationSignature,
157 false),
158 OncParams("toplevel_wifi_ssid_and_hexssid.onc",
159 &kToplevelConfigurationSignature,
160 false),
161 OncParams("toplevel_wifi_wpa_psk.onc",
162 &kToplevelConfigurationSignature,
163 false),
164 OncParams("toplevel_wifi_wep_proxy.onc",
165 &kToplevelConfigurationSignature,
166 false),
167 OncParams("toplevel_wifi_leap.onc",
168 &kToplevelConfigurationSignature,
169 false),
170 OncParams("toplevel_wifi_eap_clientcert_with_cert_pems.onc",
171 &kToplevelConfigurationSignature,
172 false),
173 OncParams("toplevel_wifi_remove.onc",
174 &kToplevelConfigurationSignature,
175 false),
176 OncParams("toplevel_wifi_open.onc",
177 &kToplevelConfigurationSignature,
178 false),
179 OncParams("toplevel_openvpn_clientcert_with_cert_pems.onc",
180 &kToplevelConfigurationSignature,
181 false),
182 OncParams("toplevel_empty.onc",
183 &kToplevelConfigurationSignature,
184 false),
185 OncParams("toplevel_only_global_config.onc",
186 &kToplevelConfigurationSignature,
187 true),
188 OncParams("encrypted.onc", &kToplevelConfigurationSignature, true),
189 OncParams("managed_vpn.onc", &kNetworkConfigurationSignature, true),
190 OncParams("ethernet.onc", &kNetworkConfigurationSignature, true),
191 OncParams("ethernet_with_eap.onc",
192 &kNetworkConfigurationSignature,
193 true),
194 OncParams("translation_of_shill_ethernet_with_ipconfig.onc",
195 &kNetworkWithStateSignature,
196 true),
197 OncParams("translation_of_shill_wifi_with_state.onc",
198 &kNetworkWithStateSignature,
199 false),
200 OncParams("translation_of_shill_cellular_with_state.onc",
201 &kNetworkWithStateSignature,
202 false),
203 OncParams("translation_of_shill_wimax_with_state.onc",
204 &kNetworkWithStateSignature,
205 false),
206 OncParams("valid_openvpn_with_cert_pems.onc",
207 &kNetworkConfigurationSignature,
208 false),
209 OncParams("openvpn_with_password.onc",
210 &kNetworkConfigurationSignature,
211 false),
212 OncParams("third_party_vpn.onc",
213 &kNetworkConfigurationSignature,
214 false)));
216 namespace {
218 struct RepairParams {
219 RepairParams(const std::string& strict_repaired,
220 const std::string& liberal_repaired,
221 bool liberal_valid)
222 : location_of_strict_repaired(strict_repaired),
223 location_of_liberal_repaired(liberal_repaired),
224 expect_liberal_valid(liberal_valid) {}
226 std::string location_of_strict_repaired;
227 std::string location_of_liberal_repaired;
228 bool expect_liberal_valid;
231 // Both |strict_repaired| and |liberal_repaired| are strings to identify the
232 // object that is expected as the validation result. They may either be used
233 // as filenames or as dictionary keys.
234 RepairParams ExpectBothNotValid(const std::string& strict_repaired,
235 const std::string& liberal_repaired) {
236 return RepairParams(strict_repaired, liberal_repaired, false);
239 // |strict_repaired| is a string to identify the object that is expected as the
240 // validation result. They may either be used
241 // as filenames or as dictionary keys.
242 RepairParams ExpectStrictNotValid(const std::string& strict_repaired) {
243 return RepairParams(strict_repaired, std::string(), true);
246 ::std::ostream& operator<<(::std::ostream& os, const RepairParams& rp) {
247 if (rp.expect_liberal_valid) {
248 os << "(" << rp.location_of_strict_repaired << ", liberal is valid)";
249 } else {
250 os << "(" << rp.location_of_strict_repaired << ", "
251 << rp.location_of_liberal_repaired << ")";
253 return os;
256 } // namespace
258 // This test case is about validating ONC objects that contain errors which can
259 // be repaired (then the errors count as warnings). If a location of the
260 // expected repaired object is given, then it is checked that the validator
261 // (either strict or liberal) returns this repaired object and the result is
262 // VALID_WITH_WARNINGS. If the location is the empty string, then it is expected
263 // that the validator returns NULL and the result INVALID.
264 class ONCValidatorTestRepairable
265 : public ONCValidatorTest,
266 public ::testing::WithParamInterface<std::pair<OncParams,
267 RepairParams> > {
268 public:
269 // Load the common test data and return the dictionary at the field with
270 // name |name|.
271 scoped_ptr<base::DictionaryValue> GetDictionaryFromTestFile(
272 const std::string &name) {
273 scoped_ptr<const base::DictionaryValue> dict(
274 test_utils::ReadTestDictionary("invalid_settings_with_repairs.json"));
275 const base::DictionaryValue* onc_object = NULL;
276 CHECK(dict->GetDictionary(name, &onc_object));
277 return make_scoped_ptr(onc_object->DeepCopy());
281 TEST_P(ONCValidatorTestRepairable, StrictValidation) {
282 OncParams onc = GetParam().first;
283 Validate(true, GetDictionaryFromTestFile(onc.location), onc.signature,
284 onc.is_managed, onc.onc_source);
285 std::string location_of_repaired =
286 GetParam().second.location_of_strict_repaired;
287 if (location_of_repaired.empty())
288 ExpectInvalid();
289 else
290 ExpectRepairWithWarnings(*GetDictionaryFromTestFile(location_of_repaired));
293 TEST_P(ONCValidatorTestRepairable, LiberalValidation) {
294 OncParams onc = GetParam().first;
295 Validate(false, GetDictionaryFromTestFile(onc.location), onc.signature,
296 onc.is_managed, onc.onc_source);
297 if (GetParam().second.expect_liberal_valid) {
298 ExpectValid();
299 } else {
300 std::string location_of_repaired =
301 GetParam().second.location_of_liberal_repaired;
302 if (location_of_repaired.empty())
303 ExpectInvalid();
304 else
305 ExpectRepairWithWarnings(
306 *GetDictionaryFromTestFile(location_of_repaired));
310 // The parameters for all test case instantations below are:
311 // OncParams(string: A fieldname in the dictionary from the file
312 // "invalid_settings_with_repairs.json". That nested
313 // dictionary will be tested.
314 // OncValueSignature: signature of that ONC,
315 // bool: true if the ONC is managed).
317 // If both strict and liberal validation are expected to be not valid:
318 // ExpectBothNotValid(string: A fieldname in the dictionary from the file
319 // "invalid_settings_with_repairs.json". That nested
320 // dictionary is the expected result from strict
321 // validation,
322 // string: A fieldname in the dictionary from the file
323 // "invalid_settings_with_repairs.json". That nested
324 // dictionary is the expected result from liberal
325 // validation).
327 // If liberal valiation is expected to return VALID and strict validation is
328 // expected to be not valid:
329 // ExpectStrictNotValid(string: A fieldname in the dictionary from the file
330 // "invalid_settings_with_repairs.json". That nested
331 // dictionary is the expected result from strict
332 // validation).
334 // Strict validator returns INVALID. Liberal validator returns VALID.
335 INSTANTIATE_TEST_CASE_P(
336 StrictInvalidLiberalValid,
337 ONCValidatorTestRepairable,
338 ::testing::Values(
339 std::make_pair(OncParams("network-missing-required",
340 &kNetworkConfigurationSignature,
341 false),
342 ExpectStrictNotValid("")),
343 std::make_pair(OncParams("network-missing-required-type",
344 &kNetworkConfigurationSignature,
345 false),
346 ExpectStrictNotValid("")),
347 std::make_pair(OncParams("managed-network-missing-required",
348 &kNetworkConfigurationSignature,
349 true),
350 ExpectStrictNotValid("")),
351 std::make_pair(OncParams("openvpn-missing-verify-x509-name",
352 &kNetworkConfigurationSignature,
353 false),
354 ExpectStrictNotValid("")),
355 std::make_pair(OncParams("third-party-vpn-missing-extension-id",
356 &kNetworkConfigurationSignature,
357 false),
358 ExpectStrictNotValid(""))));
360 // Strict validator returns INVALID. Liberal validator repairs.
361 INSTANTIATE_TEST_CASE_P(
362 StrictInvalidLiberalRepair,
363 ONCValidatorTestRepairable,
364 ::testing::Values(
365 std::make_pair(OncParams("network-unknown-fieldname",
366 &kNetworkConfigurationSignature,
367 false),
368 ExpectBothNotValid("", "network-repaired")),
369 std::make_pair(OncParams("managed-network-unknown-fieldname",
370 &kNetworkConfigurationSignature,
371 true),
372 ExpectBothNotValid("", "managed-network-repaired")),
373 std::make_pair(OncParams("managed-network-unknown-recommended",
374 &kNetworkConfigurationSignature,
375 true),
376 ExpectBothNotValid("", "managed-network-repaired")),
377 std::make_pair(OncParams("managed-network-dict-recommended",
378 &kNetworkConfigurationSignature,
379 true),
380 ExpectBothNotValid("", "managed-network-repaired")),
381 // Ensure that state values from Shill aren't accepted as
382 // configuration.
383 std::make_pair(OncParams("network-state-field",
384 &kNetworkConfigurationSignature,
385 false),
386 ExpectBothNotValid("", "network-repaired")),
387 std::make_pair(
388 OncParams("network-nested-state-field",
389 &kNetworkConfigurationSignature,
390 false),
391 ExpectBothNotValid("", "network-nested-state-field-repaired")),
392 std::make_pair(OncParams("network-with-ipconfigs",
393 &kNetworkConfigurationSignature,
394 false),
395 ExpectBothNotValid("", "network-repaired")),
396 std::make_pair(
397 OncParams("ipsec-with-client-cert-missing-cacert",
398 &kIPsecSignature,
399 false),
400 ExpectBothNotValid("", "ipsec-with-client-cert-missing-cacert")),
401 std::make_pair(OncParams("toplevel-with-repairable-networks",
402 &kToplevelConfigurationSignature,
403 false,
404 ::onc::ONC_SOURCE_DEVICE_POLICY),
405 ExpectBothNotValid("",
406 "toplevel-with-repaired-networks"))));
408 // Strict and liberal validator repair identically.
409 INSTANTIATE_TEST_CASE_P(
410 StrictAndLiberalRepairIdentically,
411 ONCValidatorTestRepairable,
412 ::testing::Values(
413 std::make_pair(OncParams("toplevel-invalid-network",
414 &kToplevelConfigurationSignature,
415 false),
416 ExpectBothNotValid("toplevel-repaired",
417 "toplevel-repaired")),
418 std::make_pair(OncParams("duplicate-network-guid",
419 &kToplevelConfigurationSignature,
420 false),
421 ExpectBothNotValid("repaired-duplicate-network-guid",
422 "repaired-duplicate-network-guid")),
423 std::make_pair(OncParams("duplicate-cert-guid",
424 &kToplevelConfigurationSignature,
425 false),
426 ExpectBothNotValid("repaired-duplicate-cert-guid",
427 "repaired-duplicate-cert-guid")),
428 std::make_pair(OncParams("toplevel-invalid-network",
429 &kToplevelConfigurationSignature,
430 true),
431 ExpectBothNotValid("toplevel-repaired",
432 "toplevel-repaired")),
433 // Ignore recommended arrays in unmanaged ONC.
434 std::make_pair(OncParams("network-with-illegal-recommended",
435 &kNetworkConfigurationSignature,
436 false),
437 ExpectBothNotValid("network-repaired",
438 "network-repaired")),
439 std::make_pair(OncParams("toplevel-with-vpn",
440 &kToplevelConfigurationSignature,
441 false,
442 ::onc::ONC_SOURCE_DEVICE_POLICY),
443 ExpectBothNotValid("toplevel-empty", "toplevel-empty")),
444 std::make_pair(OncParams("wifi-ssid-and-hexssid-inconsistent",
445 &kNetworkConfigurationSignature,
446 false),
447 ExpectBothNotValid("wifi-ssid-and-hexssid-repaired",
448 "wifi-ssid-and-hexssid-repaired")),
449 std::make_pair(OncParams("wifi-ssid-and-hexssid-partially-invalid",
450 &kNetworkConfigurationSignature,
451 false),
452 ExpectBothNotValid("wifi-ssid-and-hexssid-repaired",
453 "wifi-ssid-and-hexssid-repaired")),
454 std::make_pair(
455 OncParams("toplevel-with-server-and-ca-cert",
456 &kToplevelConfigurationSignature,
457 true,
458 ::onc::ONC_SOURCE_DEVICE_POLICY),
459 ExpectBothNotValid("toplevel-server-and-ca-cert-dropped",
460 "toplevel-server-and-ca-cert-dropped"))));
462 // Strict and liberal validator both repair, but with different results.
463 INSTANTIATE_TEST_CASE_P(
464 StrictAndLiberalRepairDifferently,
465 ONCValidatorTestRepairable,
466 ::testing::Values(std::make_pair(OncParams("toplevel-with-nested-warning",
467 &kToplevelConfigurationSignature,
468 false),
469 ExpectBothNotValid("toplevel-empty",
470 "toplevel-repaired"))));
472 // Strict and liberal validator return both INVALID.
473 INSTANTIATE_TEST_CASE_P(
474 StrictAndLiberalInvalid,
475 ONCValidatorTestRepairable,
476 ::testing::Values(
477 std::make_pair(OncParams("network-unknown-value",
478 &kNetworkConfigurationSignature,
479 false),
480 ExpectBothNotValid("", "")),
481 std::make_pair(OncParams("wifi-hexssid-invalid-length",
482 &kNetworkConfigurationSignature,
483 false),
484 ExpectBothNotValid("", "")),
485 std::make_pair(OncParams("wifi-ssid-invalid-length",
486 &kNetworkConfigurationSignature,
487 false),
488 ExpectBothNotValid("", "")),
489 std::make_pair(OncParams("wifi-invalid-hexssid",
490 &kNetworkConfigurationSignature,
491 false),
492 ExpectBothNotValid("", "")),
493 std::make_pair(OncParams("managed-network-unknown-value",
494 &kNetworkConfigurationSignature,
495 true),
496 ExpectBothNotValid("", "")),
497 std::make_pair(OncParams("network-value-out-of-range",
498 &kNetworkConfigurationSignature,
499 false),
500 ExpectBothNotValid("", "")),
501 std::make_pair(
502 OncParams("ipsec-with-psk-and-cacert", &kIPsecSignature, false),
503 ExpectBothNotValid("", "")),
504 std::make_pair(
505 OncParams("ipsec-with-empty-cacertrefs", &kIPsecSignature, false),
506 ExpectBothNotValid("", "")),
507 std::make_pair(OncParams("ipsec-with-servercaref-and-servercarefs",
508 &kIPsecSignature,
509 false),
510 ExpectBothNotValid("", "")),
511 std::make_pair(OncParams("openvpn-with-servercaref-and-servercarefs",
512 &kOpenVPNSignature,
513 false),
514 ExpectBothNotValid("", "")),
515 std::make_pair(OncParams("eap-with-servercaref-and-servercarefs",
516 &kEAPSignature,
517 false),
518 ExpectBothNotValid("", "")),
519 std::make_pair(OncParams("managed-network-value-out-of-range",
520 &kNetworkConfigurationSignature,
521 true),
522 ExpectBothNotValid("", "")),
523 std::make_pair(OncParams("network-wrong-type",
524 &kNetworkConfigurationSignature,
525 false),
526 ExpectBothNotValid("", "")),
527 std::make_pair(OncParams("managed-network-wrong-type",
528 &kNetworkConfigurationSignature,
529 true),
530 ExpectBothNotValid("", "")),
531 std::make_pair(OncParams("network-with-client-cert-pattern",
532 &kNetworkConfigurationSignature,
533 true,
534 ::onc::ONC_SOURCE_DEVICE_POLICY),
535 ExpectBothNotValid("", "")),
536 std::make_pair(OncParams("openvpn-invalid-verify-x509-type",
537 &kNetworkConfigurationSignature,
538 false),
539 ExpectBothNotValid("", ""))));
541 } // namespace onc
542 } // namespace chromeos