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 { |
19 namespace { | 20 |
20 | 21 class ONCValidatorTest : public ::testing::Test { |
21 // Create a strict validator that complains about every error. | 22 public: |
22 scoped_ptr<Validator> CreateStrictValidator(bool managed_onc) { | 23 // Validate |onc_object| with the given |signature|. The object is considered |
23 return make_scoped_ptr(new Validator(true, true, true, managed_onc)); | 24 // to be managed if |managed_onc| is true. A strict validator is used if |
24 } | 25 // |strict| is true. |onc_object| and the resulting repaired object of the |
25 | 26 // validation is stored, so that expectations can be checked afterwards using |
26 // Create a liberal validator that ignores or repairs non-critical errors. | 27 // one of the Expect* functions below. |
27 scoped_ptr<Validator> CreateLiberalValidator(bool managed_onc) { | 28 void Validate(bool strict, |
28 return make_scoped_ptr(new Validator(false, false, false, managed_onc)); | 29 scoped_ptr<base::DictionaryValue> onc_object, |
29 } | 30 const OncValueSignature* signature, |
30 } // namespace | 31 bool managed_onc) { |
31 | 32 scoped_ptr<Validator> validator; |
32 TEST(ONCValidatorValidTest, EmptyUnencryptedConfiguration) { | 33 if (strict) { |
33 scoped_ptr<Validator> validator(CreateStrictValidator(true)); | 34 // Create a strict validator that complains about every error. |
34 scoped_ptr<const base::DictionaryValue> original( | 35 validator.reset(new Validator(true, true, true, managed_onc)); |
35 ReadDictionaryFromJson(kEmptyUnencryptedConfiguration)); | 36 } else { |
36 | 37 // Create a liberal validator that ignores or repairs non-critical errors. |
37 Validator::Result result; | 38 validator.reset(new Validator(false, false, false, managed_onc)); |
38 scoped_ptr<const base::DictionaryValue> repaired( | 39 } |
39 validator->ValidateAndRepairObject(&kToplevelConfigurationSignature, | 40 original_object_ = onc_object.Pass(); |
40 *original, &result)); | 41 repaired_object_ = validator->ValidateAndRepairObject(signature, |
41 EXPECT_EQ(Validator::VALID, result); | 42 *original_object_, |
42 EXPECT_TRUE(test_utils::Equals(original.get(), repaired.get())); | 43 &validation_result_); |
43 } | 44 } |
44 | 45 |
45 // This test case is about validating valid ONC objects. | 46 void ExpectValid() { |
46 class ONCValidatorValidTest | 47 EXPECT_EQ(Validator::VALID, validation_result_); |
47 : public ::testing::TestWithParam< | 48 EXPECT_TRUE(test_utils::Equals(original_object_.get(), |
48 std::pair<std::string, const OncValueSignature*> > { | 49 repaired_object_.get())); |
49 protected: | 50 } |
50 std::string GetFilename() const { | 51 |
51 return GetParam().first; | 52 void ExpectRepairWithWarnings( |
52 } | 53 const base::DictionaryValue& expected_repaired) { |
53 | 54 EXPECT_EQ(Validator::VALID_WITH_WARNINGS, validation_result_); |
54 const OncValueSignature* GetSignature() const { | 55 EXPECT_TRUE(test_utils::Equals(&expected_repaired, repaired_object_.get())); |
55 return GetParam().second; | 56 } |
56 } | 57 |
57 }; | 58 void ExpectInvalid() { |
58 | 59 EXPECT_EQ(Validator::INVALID, validation_result_); |
59 TEST_P(ONCValidatorValidTest, ValidPolicyOnc) { | 60 EXPECT_EQ(NULL, repaired_object_.get()); |
60 scoped_ptr<Validator> validator(CreateStrictValidator(true)); | 61 } |
61 scoped_ptr<const base::DictionaryValue> original( | 62 |
62 test_utils::ReadTestDictionary(GetFilename())); | 63 private: |
63 | 64 Validator::Result validation_result_; |
64 Validator::Result result; | 65 scoped_ptr<const base::DictionaryValue> original_object_; |
65 scoped_ptr<const base::DictionaryValue> repaired( | 66 scoped_ptr<const base::DictionaryValue> repaired_object_; |
66 validator->ValidateAndRepairObject(GetSignature(), *original, &result)); | 67 }; |
67 EXPECT_EQ(Validator::VALID, result); | 68 |
68 EXPECT_TRUE(test_utils::Equals(original.get(), repaired.get())); | 69 struct OncParams { |
Mattias Nissler (ping if slow)
2012/12/13 09:45:18
migt want to hide this is in an anonymous namespac
pneubeck (no reviews)
2012/12/13 12:50:03
Done.
| |
70 OncParams(std::string location_of_object, | |
71 const OncValueSignature* onc_signature, | |
72 bool is_managed_onc) | |
73 : location(location_of_object), | |
Mattias Nissler (ping if slow)
2012/12/13 09:45:18
How about renaming all these "location" variables
pneubeck (no reviews)
2012/12/13 12:50:03
Because it's either a filename or a key in the dic
| |
74 signature(onc_signature), | |
75 is_managed(is_managed_onc) { | |
76 } | |
77 | |
78 std::string location; | |
79 const OncValueSignature* signature; | |
80 bool is_managed; | |
81 }; | |
82 | |
83 ::std::ostream& operator<<(::std::ostream& os, const OncParams& onc) { | |
84 return os << "(" << onc.location << ", " << onc.signature << ", " | |
85 << (onc.is_managed ? "managed" : "unmanaged") << ")"; | |
86 } | |
87 | |
88 // Ensure that the constant |kEmptyUnencryptedConfiguration| describes a valid | |
89 // ONC toplevel object. | |
90 TEST_F(ONCValidatorTest, EmptyUnencryptedConfiguration) { | |
91 Validate(true, ReadDictionaryFromJson(kEmptyUnencryptedConfiguration), | |
92 &kToplevelConfigurationSignature, false); | |
93 ExpectValid(); | |
94 } | |
95 | |
96 // This test case is about validating valid ONC objects without any errors. Both | |
97 // the strict and the liberal validator accept the object. | |
98 class ONCValidatorValidTest : public ONCValidatorTest, | |
99 public ::testing::WithParamInterface<OncParams> { | |
100 }; | |
101 | |
102 TEST_P(ONCValidatorValidTest, StrictValidationValid) { | |
103 OncParams onc = GetParam(); | |
104 Validate(true, test_utils::ReadTestDictionary(onc.location), onc.signature, | |
105 onc.is_managed); | |
106 ExpectValid(); | |
107 } | |
108 | |
109 TEST_P(ONCValidatorValidTest, LiberalValidationValid) { | |
110 OncParams onc = GetParam(); | |
111 Validate(false, test_utils::ReadTestDictionary(onc.location), onc.signature, | |
112 onc.is_managed); | |
113 ExpectValid(); | |
69 } | 114 } |
70 | 115 |
71 INSTANTIATE_TEST_CASE_P( | 116 INSTANTIATE_TEST_CASE_P( |
72 ONCValidatorValidTest, | 117 ONCValidatorValidTest, |
73 ONCValidatorValidTest, | 118 ONCValidatorValidTest, |
74 ::testing::Values(std::make_pair("managed_toplevel.onc", | 119 ::testing::Values(OncParams("managed_toplevel.onc", |
75 &kToplevelConfigurationSignature), | 120 &kToplevelConfigurationSignature, |
76 std::make_pair("encrypted.onc", | 121 true), |
77 &kToplevelConfigurationSignature), | 122 OncParams("encrypted.onc", |
78 std::make_pair("managed_vpn.onc", | 123 &kToplevelConfigurationSignature, |
79 &kNetworkConfigurationSignature), | 124 true), |
80 std::make_pair("managed_ethernet.onc", | 125 OncParams("managed_vpn.onc", |
81 &kNetworkConfigurationSignature), | 126 &kNetworkConfigurationSignature, |
82 // Ignore recommended arrays in unmanaged ONC: | 127 true), |
83 std::make_pair("recommended_in_unmanaged.onc", | 128 OncParams("managed_ethernet.onc", |
84 &kNetworkConfigurationSignature))); | 129 &kNetworkConfigurationSignature, |
85 | 130 true))); |
86 // Validate invalid ONC objects and check the resulting repaired object. This | 131 |
87 // test fixture loads a test json file into |invalid_| containing several test | 132 struct RepairParams { |
88 // objects which can be accessed by their path. The test boolean parameter | 133 RepairParams(std::string strict_repaired, |
89 // determines wether to use the strict or the liberal validator. | 134 std::string liberal_repaired) |
90 class ONCValidatorInvalidTest : public ::testing::TestWithParam<bool> { | 135 : location_of_strict_repaired(strict_repaired), |
136 location_of_liberal_repaired(liberal_repaired) { | |
137 } | |
138 | |
139 std::string location_of_strict_repaired; | |
140 std::string location_of_liberal_repaired; | |
141 }; | |
142 | |
143 ::std::ostream& operator<<(::std::ostream& os, const RepairParams& rp) { | |
144 return os << "(" << rp.location_of_strict_repaired << ", " | |
145 << rp.location_of_liberal_repaired << ")"; | |
146 } | |
147 | |
148 // This test case is about validating ONC objects that contain errors which can | |
149 // be repaired (then the errors count as warnings). If a location of the | |
150 // expected repaired object is given, then it is checked that the validator | |
151 // (either strict or liberal) returns this repaired object and the result is | |
152 // VALID_WITH_WARNINGS. If the location is the empty string, then it is expected | |
153 // that the validator returns NULL and the result INVALID. | |
154 class ONCValidatorTestRepairable | |
155 : public ONCValidatorTest, | |
156 public ::testing::WithParamInterface<std::pair<OncParams, | |
157 RepairParams> > { | |
91 public: | 158 public: |
92 // Validate the entry at |path_to_object| with the given | 159 scoped_ptr<base::DictionaryValue> LoadObject(const std::string &name) { |
Mattias Nissler (ping if slow)
2012/12/13 09:45:18
Rename to LoadDictionaryFromFile maybe?
pneubeck (no reviews)
2012/12/13 12:50:03
Then "name" could be misinterpreted as the filenam
| |
93 // |signature|. Depending on |managed_onc| the object is interpreted as a | 160 scoped_ptr<const base::DictionaryValue> dict( |
94 // managed onc (with recommended fields) or not. The resulting repaired object | 161 test_utils::ReadTestDictionary("invalid_settings_with_repairs.json")); |
95 // must match the entry at |path_to_repaired| if the liberal validator is | 162 const base::DictionaryValue* onc_object = NULL; |
96 // used. | 163 CHECK(dict->GetDictionary(name, &onc_object)); |
97 void ValidateInvalid(const std::string& path_to_object, | 164 return make_scoped_ptr(onc_object->DeepCopy()); |
98 const std::string& path_to_repaired, | 165 } |
99 const OncValueSignature* signature, | 166 }; |
100 bool managed_onc) { | 167 |
101 scoped_ptr<Validator> validator; | 168 TEST_P(ONCValidatorTestRepairable, StrictValidation) { |
102 if (GetParam()) | 169 OncParams onc = GetParam().first; |
103 validator = CreateStrictValidator(managed_onc); | 170 Validate(true, LoadObject(onc.location), onc.signature, onc.is_managed); |
104 else | 171 std::string location_of_repaired = |
105 validator = CreateLiberalValidator(managed_onc); | 172 GetParam().second.location_of_strict_repaired; |
106 | 173 if (location_of_repaired.empty()) |
107 const base::DictionaryValue* object = NULL; | 174 ExpectInvalid(); |
108 ASSERT_TRUE(invalid_->GetDictionary(path_to_object, &object)); | 175 else |
109 | 176 ExpectRepairWithWarnings(*LoadObject(location_of_repaired)); |
110 Validator::Result result; | 177 } |
111 scoped_ptr<base::DictionaryValue> actual_repaired = | 178 |
112 validator->ValidateAndRepairObject(signature, *object, &result); | 179 TEST_P(ONCValidatorTestRepairable, LiberalValidation) { |
113 if (GetParam() || path_to_repaired == "") { | 180 OncParams onc = GetParam().first; |
114 EXPECT_EQ(Validator::INVALID, result); | 181 Validate(false, LoadObject(onc.location), onc.signature, onc.is_managed); |
115 EXPECT_EQ(NULL, actual_repaired.get()); | 182 std::string location_of_repaired = |
116 } else { | 183 GetParam().second.location_of_liberal_repaired; |
117 EXPECT_EQ(Validator::VALID_WITH_WARNINGS, result); | 184 if (location_of_repaired.empty()) |
118 const base::DictionaryValue* expected_repaired = NULL; | 185 ExpectInvalid(); |
119 invalid_->GetDictionary(path_to_repaired, &expected_repaired); | 186 else |
120 EXPECT_TRUE(test_utils::Equals(expected_repaired, actual_repaired.get())); | 187 ExpectRepairWithWarnings(*LoadObject(location_of_repaired)); |
121 } | 188 } |
122 } | 189 |
123 | 190 // Strict validator returns INVALID. Liberal validator repairs. |
124 virtual void SetUp() { | 191 INSTANTIATE_TEST_CASE_P( |
125 invalid_ = | 192 StrictInvalidLiberalRepair, |
126 test_utils::ReadTestDictionary("invalid_settings_with_repairs.json"); | 193 ONCValidatorTestRepairable, |
127 } | 194 ::testing::Values( |
128 | 195 std::make_pair(OncParams("network-unknown-fieldname", |
129 scoped_ptr<const base::DictionaryValue> invalid_; | 196 &kNetworkConfigurationSignature, |
130 }; | 197 false), |
131 | 198 RepairParams("", "network-repaired")), |
132 TEST_P(ONCValidatorInvalidTest, UnknownFieldName) { | 199 std::make_pair(OncParams("managed-network-unknown-fieldname", |
133 ValidateInvalid("network-unknown-fieldname", | 200 &kNetworkConfigurationSignature, |
134 "network-repaired", | 201 true), |
135 &kNetworkConfigurationSignature, false); | 202 RepairParams("", "managed-network-repaired")), |
136 ValidateInvalid("managed-network-unknown-fieldname", | 203 std::make_pair(OncParams("managed-network-unknown-recommended", |
137 "managed-network-repaired", | 204 &kNetworkConfigurationSignature, |
138 &kNetworkConfigurationSignature, true); | 205 true), |
139 } | 206 RepairParams("", "managed-network-repaired")), |
140 | 207 std::make_pair(OncParams("managed-network-dict-recommended", |
141 TEST_P(ONCValidatorInvalidTest, UnknownType) { | 208 &kNetworkConfigurationSignature, |
142 ValidateInvalid("network-unknown-type", | 209 true), |
143 "", | 210 RepairParams("", "managed-network-repaired")), |
144 &kNetworkConfigurationSignature, false); | 211 std::make_pair(OncParams("network-missing-required", |
145 ValidateInvalid("managed-network-unknown-type", | 212 &kNetworkConfigurationSignature, |
146 "", | 213 false), |
147 &kNetworkConfigurationSignature, true); | 214 RepairParams("", "network-missing-required")), |
148 } | 215 std::make_pair(OncParams("managed-network-missing-required", |
149 | 216 &kNetworkConfigurationSignature, |
150 TEST_P(ONCValidatorInvalidTest, UnknownRecommendedFieldName) { | 217 true), |
151 ValidateInvalid("managed-network-unknown-recommended", | 218 RepairParams("", "managed-network-missing-required")))); |
152 "managed-network-repaired", | 219 |
153 &kNetworkConfigurationSignature, true); | 220 // Strict and liberal validator repair identically. |
154 } | 221 INSTANTIATE_TEST_CASE_P( |
155 | 222 StrictAndLiberalRepairIdentically, |
156 TEST_P(ONCValidatorInvalidTest, DictionaryRecommended) { | 223 ONCValidatorTestRepairable, |
157 ValidateInvalid("managed-network-dict-recommended", | 224 ::testing::Values( |
158 "managed-network-repaired", | 225 std::make_pair(OncParams("toplevel-invalid-network", |
159 &kNetworkConfigurationSignature, true); | 226 &kToplevelConfigurationSignature, |
160 } | 227 false), |
161 | 228 RepairParams("toplevel-repaired", |
162 TEST_P(ONCValidatorInvalidTest, MissingRequiredField) { | 229 "toplevel-repaired")), |
163 ValidateInvalid("network-missing-required", | 230 std::make_pair(OncParams("toplevel-invalid-network", |
164 "network-missing-required", | 231 &kToplevelConfigurationSignature, |
165 &kNetworkConfigurationSignature, false); | 232 true), |
166 ValidateInvalid("managed-network-missing-required", | 233 RepairParams("toplevel-repaired", |
167 "managed-network-missing-required", | 234 "toplevel-repaired")), |
168 &kNetworkConfigurationSignature, true); | 235 // Ignore recommended arrays in unmanaged ONC. |
169 } | 236 std::make_pair(OncParams("network-with-illegal-recommended", |
170 | 237 &kNetworkConfigurationSignature, |
171 TEST_P(ONCValidatorInvalidTest, RecommendedInUnmanaged) { | 238 false), |
172 ValidateInvalid("network-illegal-recommended", | 239 RepairParams("network-repaired", "network-repaired")))); |
173 "network-repaired", | 240 |
174 &kNetworkConfigurationSignature, false); | 241 // Strict and liberal validator return both INVALID. |
175 } | 242 INSTANTIATE_TEST_CASE_P( |
176 | 243 StrictAndLiberalInvalid, |
177 INSTANTIATE_TEST_CASE_P(ONCValidatorInvalidTest, | 244 ONCValidatorTestRepairable, |
178 ONCValidatorInvalidTest, | 245 ::testing::Values( |
179 ::testing::Bool()); | 246 std::make_pair(OncParams("network-unknown-value", |
247 &kNetworkConfigurationSignature, false), | |
248 RepairParams("", "")), | |
249 std::make_pair(OncParams("managed-network-unknown-value", | |
250 &kNetworkConfigurationSignature, true), | |
251 RepairParams("", "")), | |
252 std::make_pair(OncParams("network-value-out-of-range", | |
253 &kNetworkConfigurationSignature, false), | |
254 RepairParams("", "")), | |
255 std::make_pair(OncParams("managed-network-value-out-of-range", | |
256 &kNetworkConfigurationSignature, true), | |
257 RepairParams("", "")), | |
258 std::make_pair(OncParams("network-wrong-type", | |
259 &kNetworkConfigurationSignature, false), | |
260 RepairParams("", "")), | |
261 std::make_pair(OncParams("managed-network-wrong-type", | |
262 &kNetworkConfigurationSignature, true), | |
263 RepairParams("", "")))); | |
180 | 264 |
181 } // namespace onc | 265 } // namespace onc |
182 } // namespace chromeos | 266 } // namespace chromeos |
OLD | NEW |