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"
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"
22 class ONCValidatorTest : public ::testing::Test {
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,
33 ::onc::ONCSource onc_source) {
34 scoped_ptr<Validator> validator;
36 // Create a strict validator that complains about every error.
37 validator.reset(new Validator(true, true, true, managed_onc));
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,
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());
67 Validator::Result validation_result_;
68 scoped_ptr<const base::DictionaryValue> original_object_;
69 scoped_ptr<const base::DictionaryValue> repaired_object_;
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,
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) {
88 const OncValueSignature* signature;
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) << ")";
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);
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);
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);
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(OncParams("managed_toplevel1.onc",
137 &kToplevelConfigurationSignature,
139 OncParams("managed_toplevel2.onc",
140 &kToplevelConfigurationSignature,
142 OncParams("managed_toplevel_with_global_config.onc",
143 &kToplevelConfigurationSignature,
145 // Check that at least one configuration is accepted for
147 OncParams("managed_toplevel_wifi_peap.onc",
148 &kToplevelConfigurationSignature,
150 ::onc::ONC_SOURCE_DEVICE_POLICY),
151 OncParams("toplevel_wifi_wpa_psk.onc",
152 &kToplevelConfigurationSignature,
154 OncParams("encrypted.onc",
155 &kToplevelConfigurationSignature,
157 OncParams("managed_vpn.onc",
158 &kNetworkConfigurationSignature,
160 OncParams("ethernet.onc",
161 &kNetworkConfigurationSignature,
163 OncParams("ethernet_with_eap.onc",
164 &kNetworkConfigurationSignature,
166 OncParams("translation_of_shill_wifi_with_state.onc",
167 &kNetworkWithStateSignature,
172 struct RepairParams {
173 // Both arguments are strings to identify the object that is expected as the
174 // validation result. They may either be used as filenames or as dictionary
176 RepairParams(std::string strict_repaired,
177 std::string liberal_repaired)
178 : location_of_strict_repaired(strict_repaired),
179 location_of_liberal_repaired(liberal_repaired) {
182 std::string location_of_strict_repaired;
183 std::string location_of_liberal_repaired;
186 ::std::ostream& operator<<(::std::ostream& os, const RepairParams& rp) {
187 return os << "(" << rp.location_of_strict_repaired << ", "
188 << rp.location_of_liberal_repaired << ")";
193 // This test case is about validating ONC objects that contain errors which can
194 // be repaired (then the errors count as warnings). If a location of the
195 // expected repaired object is given, then it is checked that the validator
196 // (either strict or liberal) returns this repaired object and the result is
197 // VALID_WITH_WARNINGS. If the location is the empty string, then it is expected
198 // that the validator returns NULL and the result INVALID.
199 class ONCValidatorTestRepairable
200 : public ONCValidatorTest,
201 public ::testing::WithParamInterface<std::pair<OncParams,
204 // Load the common test data and return the dictionary at the field with
206 scoped_ptr<base::DictionaryValue> GetDictionaryFromTestFile(
207 const std::string &name) {
208 scoped_ptr<const base::DictionaryValue> dict(
209 test_utils::ReadTestDictionary("invalid_settings_with_repairs.json"));
210 const base::DictionaryValue* onc_object = NULL;
211 CHECK(dict->GetDictionary(name, &onc_object));
212 return make_scoped_ptr(onc_object->DeepCopy());
216 TEST_P(ONCValidatorTestRepairable, StrictValidation) {
217 OncParams onc = GetParam().first;
218 Validate(true, GetDictionaryFromTestFile(onc.location), onc.signature,
219 onc.is_managed, onc.onc_source);
220 std::string location_of_repaired =
221 GetParam().second.location_of_strict_repaired;
222 if (location_of_repaired.empty())
225 ExpectRepairWithWarnings(*GetDictionaryFromTestFile(location_of_repaired));
228 TEST_P(ONCValidatorTestRepairable, LiberalValidation) {
229 OncParams onc = GetParam().first;
230 Validate(false, GetDictionaryFromTestFile(onc.location), onc.signature,
231 onc.is_managed, onc.onc_source);
232 std::string location_of_repaired =
233 GetParam().second.location_of_liberal_repaired;
234 if (location_of_repaired.empty())
237 ExpectRepairWithWarnings(*GetDictionaryFromTestFile(location_of_repaired));
240 // The parameters for all test case instantations below are:
241 // OncParams(string: A fieldname in the dictionary from the file
242 // "invalid_settings_with_repairs.json". That nested
243 // dictionary will be tested.
244 // OncValueSignature: signature of that ONC,
245 // bool: true if the ONC is managed).
246 // RepairParams(string: A fieldname in the dictionary from the file
247 // "invalid_settings_with_repairs.json". That nested
248 // dictionary is the expected result from strict
250 // string: A fieldname in the dictionary from the file
251 // "invalid_settings_with_repairs.json". That nested
252 // dictionary is the expected result from liberal
255 // Strict validator returns INVALID. Liberal validator repairs.
256 INSTANTIATE_TEST_CASE_P(
257 StrictInvalidLiberalRepair,
258 ONCValidatorTestRepairable,
260 std::make_pair(OncParams("network-unknown-fieldname",
261 &kNetworkConfigurationSignature,
263 RepairParams("", "network-repaired")),
264 std::make_pair(OncParams("managed-network-unknown-fieldname",
265 &kNetworkConfigurationSignature,
267 RepairParams("", "managed-network-repaired")),
268 std::make_pair(OncParams("managed-network-unknown-recommended",
269 &kNetworkConfigurationSignature,
271 RepairParams("", "managed-network-repaired")),
272 std::make_pair(OncParams("managed-network-dict-recommended",
273 &kNetworkConfigurationSignature,
275 RepairParams("", "managed-network-repaired")),
276 std::make_pair(OncParams("network-missing-required",
277 &kNetworkConfigurationSignature,
279 RepairParams("", "network-missing-required")),
280 std::make_pair(OncParams("managed-network-missing-required",
281 &kNetworkConfigurationSignature,
283 RepairParams("", "managed-network-missing-required")),
284 // Ensure that state values from Shill aren't accepted as
286 std::make_pair(OncParams("network-state-field",
287 &kNetworkConfigurationSignature,
289 RepairParams("", "network-repaired")),
290 std::make_pair(OncParams("network-nested-state-field",
291 &kNetworkConfigurationSignature,
294 "network-nested-state-field-repaired")),
295 std::make_pair(OncParams("toplevel-with-repairable-networks",
296 &kToplevelConfigurationSignature,
298 ::onc::ONC_SOURCE_DEVICE_POLICY),
299 RepairParams("", "toplevel-with-repaired-networks"))));
301 // Strict and liberal validator repair identically.
302 INSTANTIATE_TEST_CASE_P(
303 StrictAndLiberalRepairIdentically,
304 ONCValidatorTestRepairable,
306 std::make_pair(OncParams("toplevel-invalid-network",
307 &kToplevelConfigurationSignature,
309 RepairParams("toplevel-repaired",
310 "toplevel-repaired")),
311 std::make_pair(OncParams("toplevel-invalid-network",
312 &kToplevelConfigurationSignature,
314 RepairParams("toplevel-repaired",
315 "toplevel-repaired")),
316 // Ignore recommended arrays in unmanaged ONC.
317 std::make_pair(OncParams("network-with-illegal-recommended",
318 &kNetworkConfigurationSignature,
320 RepairParams("network-repaired", "network-repaired")),
321 std::make_pair(OncParams("toplevel-with-vpn",
322 &kToplevelConfigurationSignature,
324 ::onc::ONC_SOURCE_DEVICE_POLICY),
325 RepairParams("toplevel-empty", "toplevel-empty")),
326 std::make_pair(OncParams("toplevel-with-server-and-ca-cert",
327 &kToplevelConfigurationSignature,
329 ::onc::ONC_SOURCE_DEVICE_POLICY),
330 RepairParams("toplevel-server-and-ca-cert-dropped",
331 "toplevel-server-and-ca-cert-dropped"))));
333 // Strict and liberal validator both repair, but with different results.
334 INSTANTIATE_TEST_CASE_P(
335 StrictAndLiberalRepairDifferently,
336 ONCValidatorTestRepairable,
338 std::make_pair(OncParams("toplevel-with-nested-warning",
339 &kToplevelConfigurationSignature,
341 RepairParams("toplevel-empty", "toplevel-repaired"))));
343 // Strict and liberal validator return both INVALID.
344 INSTANTIATE_TEST_CASE_P(
345 StrictAndLiberalInvalid,
346 ONCValidatorTestRepairable,
348 std::make_pair(OncParams("network-unknown-value",
349 &kNetworkConfigurationSignature, false),
350 RepairParams("", "")),
351 std::make_pair(OncParams("managed-network-unknown-value",
352 &kNetworkConfigurationSignature, true),
353 RepairParams("", "")),
354 std::make_pair(OncParams("network-value-out-of-range",
355 &kNetworkConfigurationSignature, false),
356 RepairParams("", "")),
357 std::make_pair(OncParams("managed-network-value-out-of-range",
358 &kNetworkConfigurationSignature, true),
359 RepairParams("", "")),
360 std::make_pair(OncParams("network-wrong-type",
361 &kNetworkConfigurationSignature, false),
362 RepairParams("", "")),
363 std::make_pair(OncParams("managed-network-wrong-type",
364 &kNetworkConfigurationSignature, true),
365 RepairParams("", "")),
366 std::make_pair(OncParams("network-with-client-cert-pattern",
367 &kNetworkConfigurationSignature, true,
368 ::onc::ONC_SOURCE_DEVICE_POLICY),
369 RepairParams("", ""))));
372 } // namespace chromeos