OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chromeos/network/onc/onc_validator.h" | 5 #include "chromeos/network/onc/onc_validator.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
| 9 #include "base/logging.h" |
9 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
10 #include "base/values.h" | 11 #include "base/values.h" |
11 #include "chromeos/network/onc/onc_constants.h" | 12 #include "chromeos/network/onc/onc_constants.h" |
12 #include "chromeos/network/onc/onc_signature.h" | 13 #include "chromeos/network/onc/onc_signature.h" |
13 #include "chromeos/network/onc/onc_test_utils.h" | 14 #include "chromeos/network/onc/onc_test_utils.h" |
14 #include "chromeos/network/onc/onc_utils.h" | 15 #include "chromeos/network/onc/onc_utils.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
16 | 17 |
17 namespace chromeos { | 18 namespace chromeos { |
18 namespace onc { | 19 namespace onc { |
| 20 |
| 21 class ONCValidatorTest : public ::testing::Test { |
| 22 public: |
| 23 // Validate |onc_object| with the given |signature|. The object is considered |
| 24 // to be managed if |managed_onc| is true. A strict validator is used if |
| 25 // |strict| is true. |onc_object| and the resulting repaired object of the |
| 26 // validation is stored, so that expectations can be checked afterwards using |
| 27 // one of the Expect* functions below. |
| 28 void Validate(bool strict, |
| 29 scoped_ptr<base::DictionaryValue> onc_object, |
| 30 const OncValueSignature* signature, |
| 31 bool managed_onc) { |
| 32 scoped_ptr<Validator> validator; |
| 33 if (strict) { |
| 34 // Create a strict validator that complains about every error. |
| 35 validator.reset(new Validator(true, true, true, managed_onc)); |
| 36 } else { |
| 37 // Create a liberal validator that ignores or repairs non-critical errors. |
| 38 validator.reset(new Validator(false, false, false, managed_onc)); |
| 39 } |
| 40 original_object_ = onc_object.Pass(); |
| 41 repaired_object_ = validator->ValidateAndRepairObject(signature, |
| 42 *original_object_, |
| 43 &validation_result_); |
| 44 } |
| 45 |
| 46 void ExpectValid() { |
| 47 EXPECT_EQ(Validator::VALID, validation_result_); |
| 48 EXPECT_TRUE(test_utils::Equals(original_object_.get(), |
| 49 repaired_object_.get())); |
| 50 } |
| 51 |
| 52 void ExpectRepairWithWarnings( |
| 53 const base::DictionaryValue& expected_repaired) { |
| 54 EXPECT_EQ(Validator::VALID_WITH_WARNINGS, validation_result_); |
| 55 EXPECT_TRUE(test_utils::Equals(&expected_repaired, repaired_object_.get())); |
| 56 } |
| 57 |
| 58 void ExpectInvalid() { |
| 59 EXPECT_EQ(Validator::INVALID, validation_result_); |
| 60 EXPECT_EQ(NULL, repaired_object_.get()); |
| 61 } |
| 62 |
| 63 private: |
| 64 Validator::Result validation_result_; |
| 65 scoped_ptr<const base::DictionaryValue> original_object_; |
| 66 scoped_ptr<const base::DictionaryValue> repaired_object_; |
| 67 }; |
| 68 |
19 namespace { | 69 namespace { |
20 | 70 |
21 // Create a strict validator that complains about every error. | 71 struct OncParams { |
22 scoped_ptr<Validator> CreateStrictValidator(bool managed_onc) { | 72 // |location_of_object| is a string to identify the object to be tested. It |
23 return make_scoped_ptr(new Validator(true, true, true, managed_onc)); | 73 // may be used as a filename or as a dictionary key. |
24 } | 74 OncParams(std::string location_of_object, |
25 | 75 const OncValueSignature* onc_signature, |
26 // Create a liberal validator that ignores or repairs non-critical errors. | 76 bool is_managed_onc) |
27 scoped_ptr<Validator> CreateLiberalValidator(bool managed_onc) { | 77 : location(location_of_object), |
28 return make_scoped_ptr(new Validator(false, false, false, managed_onc)); | 78 signature(onc_signature), |
29 } | 79 is_managed(is_managed_onc) { |
| 80 } |
| 81 |
| 82 std::string location; |
| 83 const OncValueSignature* signature; |
| 84 bool is_managed; |
| 85 }; |
| 86 |
| 87 ::std::ostream& operator<<(::std::ostream& os, const OncParams& onc) { |
| 88 return os << "(" << onc.location << ", " << onc.signature << ", " |
| 89 << (onc.is_managed ? "managed" : "unmanaged") << ")"; |
| 90 } |
| 91 |
30 } // namespace | 92 } // namespace |
31 | 93 |
32 TEST(ONCValidatorValidTest, EmptyUnencryptedConfiguration) { | 94 // Ensure that the constant |kEmptyUnencryptedConfiguration| describes a valid |
33 scoped_ptr<Validator> validator(CreateStrictValidator(true)); | 95 // ONC toplevel object. |
34 scoped_ptr<const base::DictionaryValue> original( | 96 TEST_F(ONCValidatorTest, EmptyUnencryptedConfiguration) { |
35 ReadDictionaryFromJson(kEmptyUnencryptedConfiguration)); | 97 Validate(true, ReadDictionaryFromJson(kEmptyUnencryptedConfiguration), |
36 | 98 &kToplevelConfigurationSignature, false); |
37 Validator::Result result; | 99 ExpectValid(); |
38 scoped_ptr<const base::DictionaryValue> repaired( | 100 } |
39 validator->ValidateAndRepairObject(&kToplevelConfigurationSignature, | 101 |
40 *original, &result)); | 102 // This test case is about validating valid ONC objects without any errors. Both |
41 EXPECT_EQ(Validator::VALID, result); | 103 // the strict and the liberal validator accept the object. |
42 EXPECT_TRUE(test_utils::Equals(original.get(), repaired.get())); | 104 class ONCValidatorValidTest : public ONCValidatorTest, |
43 } | 105 public ::testing::WithParamInterface<OncParams> { |
44 | 106 }; |
45 // This test case is about validating valid ONC objects. | 107 |
46 class ONCValidatorValidTest | 108 TEST_P(ONCValidatorValidTest, StrictValidationValid) { |
47 : public ::testing::TestWithParam< | 109 OncParams onc = GetParam(); |
48 std::pair<std::string, const OncValueSignature*> > { | 110 Validate(true, test_utils::ReadTestDictionary(onc.location), onc.signature, |
49 protected: | 111 onc.is_managed); |
50 std::string GetFilename() const { | 112 ExpectValid(); |
51 return GetParam().first; | 113 } |
52 } | 114 |
53 | 115 TEST_P(ONCValidatorValidTest, LiberalValidationValid) { |
54 const OncValueSignature* GetSignature() const { | 116 OncParams onc = GetParam(); |
55 return GetParam().second; | 117 Validate(false, test_utils::ReadTestDictionary(onc.location), onc.signature, |
56 } | 118 onc.is_managed); |
57 }; | 119 ExpectValid(); |
58 | 120 } |
59 TEST_P(ONCValidatorValidTest, ValidPolicyOnc) { | 121 |
60 scoped_ptr<Validator> validator(CreateStrictValidator(true)); | 122 // The parameters are: |
61 scoped_ptr<const base::DictionaryValue> original( | 123 // OncParams(string: Filename of a ONC file that is to be validated, |
62 test_utils::ReadTestDictionary(GetFilename())); | 124 // OncValueSignature: signature of that ONC, |
63 | 125 // bool: true if the ONC is managed). |
64 Validator::Result result; | |
65 scoped_ptr<const base::DictionaryValue> repaired( | |
66 validator->ValidateAndRepairObject(GetSignature(), *original, &result)); | |
67 EXPECT_EQ(Validator::VALID, result); | |
68 EXPECT_TRUE(test_utils::Equals(original.get(), repaired.get())); | |
69 } | |
70 | |
71 INSTANTIATE_TEST_CASE_P( | 126 INSTANTIATE_TEST_CASE_P( |
72 ONCValidatorValidTest, | 127 ONCValidatorValidTest, |
73 ONCValidatorValidTest, | 128 ONCValidatorValidTest, |
74 ::testing::Values(std::make_pair("managed_toplevel.onc", | 129 ::testing::Values(OncParams("managed_toplevel.onc", |
75 &kToplevelConfigurationSignature), | 130 &kToplevelConfigurationSignature, |
76 std::make_pair("encrypted.onc", | 131 true), |
77 &kToplevelConfigurationSignature), | 132 OncParams("encrypted.onc", |
78 std::make_pair("managed_vpn.onc", | 133 &kToplevelConfigurationSignature, |
79 &kNetworkConfigurationSignature), | 134 true), |
80 std::make_pair("managed_ethernet.onc", | 135 OncParams("managed_vpn.onc", |
81 &kNetworkConfigurationSignature), | 136 &kNetworkConfigurationSignature, |
82 // Ignore recommended arrays in unmanaged ONC: | 137 true), |
83 std::make_pair("recommended_in_unmanaged.onc", | 138 OncParams("managed_ethernet.onc", |
84 &kNetworkConfigurationSignature))); | 139 &kNetworkConfigurationSignature, |
85 | 140 true))); |
86 // Validate invalid ONC objects and check the resulting repaired object. This | 141 |
87 // test fixture loads a test json file into |invalid_| containing several test | 142 namespace { |
88 // objects which can be accessed by their path. The test boolean parameter | 143 |
89 // determines wether to use the strict or the liberal validator. | 144 struct RepairParams { |
90 class ONCValidatorInvalidTest : public ::testing::TestWithParam<bool> { | 145 // Both arguments are strings to identify the object that is expected as the |
| 146 // validation result. They may either be used as filenames or as dictionary |
| 147 // keys. |
| 148 RepairParams(std::string strict_repaired, |
| 149 std::string liberal_repaired) |
| 150 : location_of_strict_repaired(strict_repaired), |
| 151 location_of_liberal_repaired(liberal_repaired) { |
| 152 } |
| 153 |
| 154 std::string location_of_strict_repaired; |
| 155 std::string location_of_liberal_repaired; |
| 156 }; |
| 157 |
| 158 ::std::ostream& operator<<(::std::ostream& os, const RepairParams& rp) { |
| 159 return os << "(" << rp.location_of_strict_repaired << ", " |
| 160 << rp.location_of_liberal_repaired << ")"; |
| 161 } |
| 162 |
| 163 } // namespace |
| 164 |
| 165 // This test case is about validating ONC objects that contain errors which can |
| 166 // be repaired (then the errors count as warnings). If a location of the |
| 167 // expected repaired object is given, then it is checked that the validator |
| 168 // (either strict or liberal) returns this repaired object and the result is |
| 169 // VALID_WITH_WARNINGS. If the location is the empty string, then it is expected |
| 170 // that the validator returns NULL and the result INVALID. |
| 171 class ONCValidatorTestRepairable |
| 172 : public ONCValidatorTest, |
| 173 public ::testing::WithParamInterface<std::pair<OncParams, |
| 174 RepairParams> > { |
91 public: | 175 public: |
92 // Validate the entry at |path_to_object| with the given | 176 // Load the common test data and return the dictionary at the field with |
93 // |signature|. Depending on |managed_onc| the object is interpreted as a | 177 // name |name|. |
94 // managed onc (with recommended fields) or not. The resulting repaired object | 178 scoped_ptr<base::DictionaryValue> GetDictionaryFromTestFile( |
95 // must match the entry at |path_to_repaired| if the liberal validator is | 179 const std::string &name) { |
96 // used. | 180 scoped_ptr<const base::DictionaryValue> dict( |
97 void ValidateInvalid(const std::string& path_to_object, | 181 test_utils::ReadTestDictionary("invalid_settings_with_repairs.json")); |
98 const std::string& path_to_repaired, | 182 const base::DictionaryValue* onc_object = NULL; |
99 const OncValueSignature* signature, | 183 CHECK(dict->GetDictionary(name, &onc_object)); |
100 bool managed_onc) { | 184 return make_scoped_ptr(onc_object->DeepCopy()); |
101 scoped_ptr<Validator> validator; | 185 } |
102 if (GetParam()) | 186 }; |
103 validator = CreateStrictValidator(managed_onc); | 187 |
104 else | 188 TEST_P(ONCValidatorTestRepairable, StrictValidation) { |
105 validator = CreateLiberalValidator(managed_onc); | 189 OncParams onc = GetParam().first; |
106 | 190 Validate(true, GetDictionaryFromTestFile(onc.location), onc.signature, |
107 const base::DictionaryValue* object = NULL; | 191 onc.is_managed); |
108 ASSERT_TRUE(invalid_->GetDictionary(path_to_object, &object)); | 192 std::string location_of_repaired = |
109 | 193 GetParam().second.location_of_strict_repaired; |
110 Validator::Result result; | 194 if (location_of_repaired.empty()) |
111 scoped_ptr<base::DictionaryValue> actual_repaired = | 195 ExpectInvalid(); |
112 validator->ValidateAndRepairObject(signature, *object, &result); | 196 else |
113 if (GetParam() || path_to_repaired == "") { | 197 ExpectRepairWithWarnings(*GetDictionaryFromTestFile(location_of_repaired)); |
114 EXPECT_EQ(Validator::INVALID, result); | 198 } |
115 EXPECT_EQ(NULL, actual_repaired.get()); | 199 |
116 } else { | 200 TEST_P(ONCValidatorTestRepairable, LiberalValidation) { |
117 EXPECT_EQ(Validator::VALID_WITH_WARNINGS, result); | 201 OncParams onc = GetParam().first; |
118 const base::DictionaryValue* expected_repaired = NULL; | 202 Validate(false, GetDictionaryFromTestFile(onc.location), onc.signature, |
119 invalid_->GetDictionary(path_to_repaired, &expected_repaired); | 203 onc.is_managed); |
120 EXPECT_TRUE(test_utils::Equals(expected_repaired, actual_repaired.get())); | 204 std::string location_of_repaired = |
121 } | 205 GetParam().second.location_of_liberal_repaired; |
122 } | 206 if (location_of_repaired.empty()) |
123 | 207 ExpectInvalid(); |
124 virtual void SetUp() { | 208 else |
125 invalid_ = | 209 ExpectRepairWithWarnings(*GetDictionaryFromTestFile(location_of_repaired)); |
126 test_utils::ReadTestDictionary("invalid_settings_with_repairs.json"); | 210 } |
127 } | 211 |
128 | 212 // The parameters for all test case instantations below are: |
129 scoped_ptr<const base::DictionaryValue> invalid_; | 213 // OncParams(string: A fieldname in the dictionary from the file |
130 }; | 214 // "invalid_settings_with_repairs.json". That nested |
131 | 215 // dictionary will be tested. |
132 TEST_P(ONCValidatorInvalidTest, UnknownFieldName) { | 216 // OncValueSignature: signature of that ONC, |
133 ValidateInvalid("network-unknown-fieldname", | 217 // bool: true if the ONC is managed). |
134 "network-repaired", | 218 // RepairParams(string: A fieldname in the dictionary from the file |
135 &kNetworkConfigurationSignature, false); | 219 // "invalid_settings_with_repairs.json". That nested |
136 ValidateInvalid("managed-network-unknown-fieldname", | 220 // dictionary is the expected result from strict |
137 "managed-network-repaired", | 221 // validation, |
138 &kNetworkConfigurationSignature, true); | 222 // string: A fieldname in the dictionary from the file |
139 } | 223 // "invalid_settings_with_repairs.json". That nested |
140 | 224 // dictionary is the expected result from liberal |
141 TEST_P(ONCValidatorInvalidTest, UnknownType) { | 225 // validation). |
142 ValidateInvalid("network-unknown-type", | 226 |
143 "", | 227 // Strict validator returns INVALID. Liberal validator repairs. |
144 &kNetworkConfigurationSignature, false); | 228 INSTANTIATE_TEST_CASE_P( |
145 ValidateInvalid("managed-network-unknown-type", | 229 StrictInvalidLiberalRepair, |
146 "", | 230 ONCValidatorTestRepairable, |
147 &kNetworkConfigurationSignature, true); | 231 ::testing::Values( |
148 } | 232 std::make_pair(OncParams("network-unknown-fieldname", |
149 | 233 &kNetworkConfigurationSignature, |
150 TEST_P(ONCValidatorInvalidTest, UnknownRecommendedFieldName) { | 234 false), |
151 ValidateInvalid("managed-network-unknown-recommended", | 235 RepairParams("", "network-repaired")), |
152 "managed-network-repaired", | 236 std::make_pair(OncParams("managed-network-unknown-fieldname", |
153 &kNetworkConfigurationSignature, true); | 237 &kNetworkConfigurationSignature, |
154 } | 238 true), |
155 | 239 RepairParams("", "managed-network-repaired")), |
156 TEST_P(ONCValidatorInvalidTest, DictionaryRecommended) { | 240 std::make_pair(OncParams("managed-network-unknown-recommended", |
157 ValidateInvalid("managed-network-dict-recommended", | 241 &kNetworkConfigurationSignature, |
158 "managed-network-repaired", | 242 true), |
159 &kNetworkConfigurationSignature, true); | 243 RepairParams("", "managed-network-repaired")), |
160 } | 244 std::make_pair(OncParams("managed-network-dict-recommended", |
161 | 245 &kNetworkConfigurationSignature, |
162 TEST_P(ONCValidatorInvalidTest, MissingRequiredField) { | 246 true), |
163 ValidateInvalid("network-missing-required", | 247 RepairParams("", "managed-network-repaired")), |
164 "network-missing-required", | 248 std::make_pair(OncParams("network-missing-required", |
165 &kNetworkConfigurationSignature, false); | 249 &kNetworkConfigurationSignature, |
166 ValidateInvalid("managed-network-missing-required", | 250 false), |
167 "managed-network-missing-required", | 251 RepairParams("", "network-missing-required")), |
168 &kNetworkConfigurationSignature, true); | 252 std::make_pair(OncParams("managed-network-missing-required", |
169 } | 253 &kNetworkConfigurationSignature, |
170 | 254 true), |
171 TEST_P(ONCValidatorInvalidTest, RecommendedInUnmanaged) { | 255 RepairParams("", "managed-network-missing-required")))); |
172 ValidateInvalid("network-illegal-recommended", | 256 |
173 "network-repaired", | 257 // Strict and liberal validator repair identically. |
174 &kNetworkConfigurationSignature, false); | 258 INSTANTIATE_TEST_CASE_P( |
175 } | 259 StrictAndLiberalRepairIdentically, |
176 | 260 ONCValidatorTestRepairable, |
177 INSTANTIATE_TEST_CASE_P(ONCValidatorInvalidTest, | 261 ::testing::Values( |
178 ONCValidatorInvalidTest, | 262 std::make_pair(OncParams("toplevel-invalid-network", |
179 ::testing::Bool()); | 263 &kToplevelConfigurationSignature, |
| 264 false), |
| 265 RepairParams("toplevel-repaired", |
| 266 "toplevel-repaired")), |
| 267 std::make_pair(OncParams("toplevel-invalid-network", |
| 268 &kToplevelConfigurationSignature, |
| 269 true), |
| 270 RepairParams("toplevel-repaired", |
| 271 "toplevel-repaired")), |
| 272 // Ignore recommended arrays in unmanaged ONC. |
| 273 std::make_pair(OncParams("network-with-illegal-recommended", |
| 274 &kNetworkConfigurationSignature, |
| 275 false), |
| 276 RepairParams("network-repaired", "network-repaired")))); |
| 277 |
| 278 // Strict and liberal validator return both INVALID. |
| 279 INSTANTIATE_TEST_CASE_P( |
| 280 StrictAndLiberalInvalid, |
| 281 ONCValidatorTestRepairable, |
| 282 ::testing::Values( |
| 283 std::make_pair(OncParams("network-unknown-value", |
| 284 &kNetworkConfigurationSignature, false), |
| 285 RepairParams("", "")), |
| 286 std::make_pair(OncParams("managed-network-unknown-value", |
| 287 &kNetworkConfigurationSignature, true), |
| 288 RepairParams("", "")), |
| 289 std::make_pair(OncParams("network-value-out-of-range", |
| 290 &kNetworkConfigurationSignature, false), |
| 291 RepairParams("", "")), |
| 292 std::make_pair(OncParams("managed-network-value-out-of-range", |
| 293 &kNetworkConfigurationSignature, true), |
| 294 RepairParams("", "")), |
| 295 std::make_pair(OncParams("network-wrong-type", |
| 296 &kNetworkConfigurationSignature, false), |
| 297 RepairParams("", "")), |
| 298 std::make_pair(OncParams("managed-network-wrong-type", |
| 299 &kNetworkConfigurationSignature, true), |
| 300 RepairParams("", "")))); |
180 | 301 |
181 } // namespace onc | 302 } // namespace onc |
182 } // namespace chromeos | 303 } // namespace chromeos |
OLD | NEW |