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_constants.h"
14 #include "chromeos/network/onc/onc_signature.h"
15 #include "chromeos/network/onc/onc_test_utils.h"
16 #include "chromeos/network/onc/onc_utils.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 scoped_ptr
<Validator
> validator
;
35 // Create a strict validator that complains about every error.
36 validator
.reset(new Validator(true, true, true, managed_onc
));
38 // Create a liberal validator that ignores or repairs non-critical errors.
39 validator
.reset(new Validator(false, false, false, managed_onc
));
41 original_object_
= onc_object
.Pass();
42 repaired_object_
= validator
->ValidateAndRepairObject(signature
,
48 EXPECT_EQ(Validator::VALID
, validation_result_
);
49 EXPECT_TRUE(test_utils::Equals(original_object_
.get(),
50 repaired_object_
.get()));
53 void ExpectRepairWithWarnings(
54 const base::DictionaryValue
& expected_repaired
) {
55 EXPECT_EQ(Validator::VALID_WITH_WARNINGS
, validation_result_
);
56 EXPECT_TRUE(test_utils::Equals(&expected_repaired
, repaired_object_
.get()));
59 void ExpectInvalid() {
60 EXPECT_EQ(Validator::INVALID
, validation_result_
);
61 EXPECT_EQ(NULL
, repaired_object_
.get());
65 Validator::Result validation_result_
;
66 scoped_ptr
<const base::DictionaryValue
> original_object_
;
67 scoped_ptr
<const base::DictionaryValue
> repaired_object_
;
73 // |location_of_object| is a string to identify the object to be tested. It
74 // may be used as a filename or as a dictionary key.
75 OncParams(std::string location_of_object
,
76 const OncValueSignature
* onc_signature
,
78 : location(location_of_object
),
79 signature(onc_signature
),
80 is_managed(is_managed_onc
) {
84 const OncValueSignature
* signature
;
88 ::std::ostream
& operator<<(::std::ostream
& os
, const OncParams
& onc
) {
89 return os
<< "(" << onc
.location
<< ", " << onc
.signature
<< ", "
90 << (onc
.is_managed
? "managed" : "unmanaged") << ")";
95 // Ensure that the constant |kEmptyUnencryptedConfiguration| describes a valid
96 // ONC toplevel object.
97 TEST_F(ONCValidatorTest
, EmptyUnencryptedConfiguration
) {
98 Validate(true, ReadDictionaryFromJson(kEmptyUnencryptedConfiguration
),
99 &kToplevelConfigurationSignature
, false);
103 // This test case is about validating valid ONC objects without any errors. Both
104 // the strict and the liberal validator accept the object.
105 class ONCValidatorValidTest
: public ONCValidatorTest
,
106 public ::testing::WithParamInterface
<OncParams
> {
109 TEST_P(ONCValidatorValidTest
, StrictValidationValid
) {
110 OncParams onc
= GetParam();
111 Validate(true, test_utils::ReadTestDictionary(onc
.location
), onc
.signature
,
116 TEST_P(ONCValidatorValidTest
, LiberalValidationValid
) {
117 OncParams onc
= GetParam();
118 Validate(false, test_utils::ReadTestDictionary(onc
.location
), onc
.signature
,
123 // The parameters are:
124 // OncParams(string: Filename of a ONC file that is to be validated,
125 // OncValueSignature: signature of that ONC,
126 // bool: true if the ONC is managed).
127 INSTANTIATE_TEST_CASE_P(
128 ONCValidatorValidTest
,
129 ONCValidatorValidTest
,
130 ::testing::Values(OncParams("managed_toplevel1.onc",
131 &kToplevelConfigurationSignature
,
133 OncParams("managed_toplevel2.onc",
134 &kToplevelConfigurationSignature
,
136 // Test a configuration generated by CPanel.
137 OncParams("managed_toplevel_cpanel.onc",
138 &kToplevelConfigurationSignature
,
140 OncParams("encrypted.onc",
141 &kToplevelConfigurationSignature
,
143 OncParams("managed_vpn.onc",
144 &kNetworkConfigurationSignature
,
146 OncParams("managed_ethernet.onc",
147 &kNetworkConfigurationSignature
,
152 struct RepairParams
{
153 // Both arguments are strings to identify the object that is expected as the
154 // validation result. They may either be used as filenames or as dictionary
156 RepairParams(std::string strict_repaired
,
157 std::string liberal_repaired
)
158 : location_of_strict_repaired(strict_repaired
),
159 location_of_liberal_repaired(liberal_repaired
) {
162 std::string location_of_strict_repaired
;
163 std::string location_of_liberal_repaired
;
166 ::std::ostream
& operator<<(::std::ostream
& os
, const RepairParams
& rp
) {
167 return os
<< "(" << rp
.location_of_strict_repaired
<< ", "
168 << rp
.location_of_liberal_repaired
<< ")";
173 // This test case is about validating ONC objects that contain errors which can
174 // be repaired (then the errors count as warnings). If a location of the
175 // expected repaired object is given, then it is checked that the validator
176 // (either strict or liberal) returns this repaired object and the result is
177 // VALID_WITH_WARNINGS. If the location is the empty string, then it is expected
178 // that the validator returns NULL and the result INVALID.
179 class ONCValidatorTestRepairable
180 : public ONCValidatorTest
,
181 public ::testing::WithParamInterface
<std::pair
<OncParams
,
184 // Load the common test data and return the dictionary at the field with
186 scoped_ptr
<base::DictionaryValue
> GetDictionaryFromTestFile(
187 const std::string
&name
) {
188 scoped_ptr
<const base::DictionaryValue
> dict(
189 test_utils::ReadTestDictionary("invalid_settings_with_repairs.json"));
190 const base::DictionaryValue
* onc_object
= NULL
;
191 CHECK(dict
->GetDictionary(name
, &onc_object
));
192 return make_scoped_ptr(onc_object
->DeepCopy());
196 TEST_P(ONCValidatorTestRepairable
, StrictValidation
) {
197 OncParams onc
= GetParam().first
;
198 Validate(true, GetDictionaryFromTestFile(onc
.location
), onc
.signature
,
200 std::string location_of_repaired
=
201 GetParam().second
.location_of_strict_repaired
;
202 if (location_of_repaired
.empty())
205 ExpectRepairWithWarnings(*GetDictionaryFromTestFile(location_of_repaired
));
208 TEST_P(ONCValidatorTestRepairable
, LiberalValidation
) {
209 OncParams onc
= GetParam().first
;
210 Validate(false, GetDictionaryFromTestFile(onc
.location
), onc
.signature
,
212 std::string location_of_repaired
=
213 GetParam().second
.location_of_liberal_repaired
;
214 if (location_of_repaired
.empty())
217 ExpectRepairWithWarnings(*GetDictionaryFromTestFile(location_of_repaired
));
220 // The parameters for all test case instantations below are:
221 // OncParams(string: A fieldname in the dictionary from the file
222 // "invalid_settings_with_repairs.json". That nested
223 // dictionary will be tested.
224 // OncValueSignature: signature of that ONC,
225 // bool: true if the ONC is managed).
226 // RepairParams(string: A fieldname in the dictionary from the file
227 // "invalid_settings_with_repairs.json". That nested
228 // dictionary is the expected result from strict
230 // string: A fieldname in the dictionary from the file
231 // "invalid_settings_with_repairs.json". That nested
232 // dictionary is the expected result from liberal
235 // Strict validator returns INVALID. Liberal validator repairs.
236 INSTANTIATE_TEST_CASE_P(
237 StrictInvalidLiberalRepair
,
238 ONCValidatorTestRepairable
,
240 std::make_pair(OncParams("network-unknown-fieldname",
241 &kNetworkConfigurationSignature
,
243 RepairParams("", "network-repaired")),
244 std::make_pair(OncParams("managed-network-unknown-fieldname",
245 &kNetworkConfigurationSignature
,
247 RepairParams("", "managed-network-repaired")),
248 std::make_pair(OncParams("managed-network-unknown-recommended",
249 &kNetworkConfigurationSignature
,
251 RepairParams("", "managed-network-repaired")),
252 std::make_pair(OncParams("managed-network-dict-recommended",
253 &kNetworkConfigurationSignature
,
255 RepairParams("", "managed-network-repaired")),
256 std::make_pair(OncParams("network-missing-required",
257 &kNetworkConfigurationSignature
,
259 RepairParams("", "network-missing-required")),
260 std::make_pair(OncParams("managed-network-missing-required",
261 &kNetworkConfigurationSignature
,
263 RepairParams("", "managed-network-missing-required"))));
265 // Strict and liberal validator repair identically.
266 INSTANTIATE_TEST_CASE_P(
267 StrictAndLiberalRepairIdentically
,
268 ONCValidatorTestRepairable
,
270 std::make_pair(OncParams("toplevel-invalid-network",
271 &kToplevelConfigurationSignature
,
273 RepairParams("toplevel-repaired",
274 "toplevel-repaired")),
275 std::make_pair(OncParams("toplevel-invalid-network",
276 &kToplevelConfigurationSignature
,
278 RepairParams("toplevel-repaired",
279 "toplevel-repaired")),
280 // Ignore recommended arrays in unmanaged ONC.
281 std::make_pair(OncParams("network-with-illegal-recommended",
282 &kNetworkConfigurationSignature
,
284 RepairParams("network-repaired", "network-repaired"))));
286 // Strict and liberal validator both repair, but with different results.
287 INSTANTIATE_TEST_CASE_P(
288 StrictAndLiberalRepairDifferently
,
289 ONCValidatorTestRepairable
,
291 std::make_pair(OncParams("toplevel-with-nested-warning",
292 &kToplevelConfigurationSignature
,
294 RepairParams("toplevel-empty", "toplevel-repaired"))));
296 // Strict and liberal validator return both INVALID.
297 INSTANTIATE_TEST_CASE_P(
298 StrictAndLiberalInvalid
,
299 ONCValidatorTestRepairable
,
301 std::make_pair(OncParams("network-unknown-value",
302 &kNetworkConfigurationSignature
, false),
303 RepairParams("", "")),
304 std::make_pair(OncParams("managed-network-unknown-value",
305 &kNetworkConfigurationSignature
, true),
306 RepairParams("", "")),
307 std::make_pair(OncParams("network-value-out-of-range",
308 &kNetworkConfigurationSignature
, false),
309 RepairParams("", "")),
310 std::make_pair(OncParams("managed-network-value-out-of-range",
311 &kNetworkConfigurationSignature
, true),
312 RepairParams("", "")),
313 std::make_pair(OncParams("network-wrong-type",
314 &kNetworkConfigurationSignature
, false),
315 RepairParams("", "")),
316 std::make_pair(OncParams("managed-network-wrong-type",
317 &kNetworkConfigurationSignature
, true),
318 RepairParams("", ""))));
321 } // namespace chromeos