Roll src/third_party/WebKit b41a10f:afd8afd (svn 202201:202202)
[chromium-blink-merge.git] / remoting / host / policy_watcher_unittest.cc
blobcf5ea3732f57766bedba0ffc02b22a76faac5972
1 // Copyright 2015 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 "base/basictypes.h"
6 #include "base/bind.h"
7 #include "base/json/json_writer.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "base/test/mock_log.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "components/policy/core/common/fake_async_policy_loader.h"
15 #include "policy/policy_constants.h"
16 #include "remoting/host/dns_blackhole_checker.h"
17 #include "remoting/host/policy_watcher.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 namespace remoting {
23 namespace key = ::policy::key;
25 MATCHER_P(IsPolicies, dict, "") {
26 bool equal = arg->Equals(dict);
27 if (!equal) {
28 std::string actual_value;
29 base::JSONWriter::WriteWithOptions(
30 *arg, base::JSONWriter::OPTIONS_PRETTY_PRINT, &actual_value);
32 std::string expected_value;
33 base::JSONWriter::WriteWithOptions(
34 *dict, base::JSONWriter::OPTIONS_PRETTY_PRINT, &expected_value);
36 *result_listener << "Policies are not equal. ";
37 *result_listener << "Expected policy: " << expected_value << ". ";
38 *result_listener << "Actual policy: " << actual_value << ".";
40 return equal;
43 class MockPolicyCallback {
44 public:
45 MockPolicyCallback(){};
47 // TODO(lukasza): gmock cannot mock a method taking scoped_ptr<T>...
48 MOCK_METHOD1(OnPolicyUpdatePtr, void(const base::DictionaryValue* policies));
49 void OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies) {
50 OnPolicyUpdatePtr(policies.get());
53 MOCK_METHOD0(OnPolicyError, void());
55 private:
56 DISALLOW_COPY_AND_ASSIGN(MockPolicyCallback);
59 class PolicyWatcherTest : public testing::Test {
60 public:
61 PolicyWatcherTest() : message_loop_(base::MessageLoop::TYPE_IO) {}
63 void SetUp() override {
64 // We expect no callbacks unless explicitly specified by individual tests.
65 EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(testing::_)).Times(0);
66 EXPECT_CALL(mock_policy_callback_, OnPolicyError()).Times(0);
68 // Retaining a raw pointer to keep control over policy contents.
69 policy_loader_ =
70 new policy::FakeAsyncPolicyLoader(base::ThreadTaskRunnerHandle::Get());
71 policy_watcher_ =
72 PolicyWatcher::CreateFromPolicyLoader(make_scoped_ptr(policy_loader_));
74 nat_true_.SetBoolean(key::kRemoteAccessHostFirewallTraversal, true);
75 nat_false_.SetBoolean(key::kRemoteAccessHostFirewallTraversal, false);
76 nat_one_.SetInteger(key::kRemoteAccessHostFirewallTraversal, 1);
77 nat_one_domain_full_.SetInteger(key::kRemoteAccessHostFirewallTraversal, 1);
78 nat_one_domain_full_.SetString(key::kRemoteAccessHostDomain, kHostDomain);
79 domain_empty_.SetString(key::kRemoteAccessHostDomain, std::string());
80 domain_full_.SetString(key::kRemoteAccessHostDomain, kHostDomain);
81 SetDefaults(nat_true_others_default_);
82 nat_true_others_default_.SetBoolean(key::kRemoteAccessHostFirewallTraversal,
83 true);
84 SetDefaults(nat_false_others_default_);
85 nat_false_others_default_.SetBoolean(
86 key::kRemoteAccessHostFirewallTraversal, false);
87 SetDefaults(domain_empty_others_default_);
88 domain_empty_others_default_.SetString(key::kRemoteAccessHostDomain,
89 std::string());
90 SetDefaults(domain_full_others_default_);
91 domain_full_others_default_.SetString(key::kRemoteAccessHostDomain,
92 kHostDomain);
93 nat_true_domain_empty_.SetBoolean(key::kRemoteAccessHostFirewallTraversal,
94 true);
95 nat_true_domain_empty_.SetString(key::kRemoteAccessHostDomain,
96 std::string());
97 nat_true_domain_full_.SetBoolean(key::kRemoteAccessHostFirewallTraversal,
98 true);
99 nat_true_domain_full_.SetString(key::kRemoteAccessHostDomain, kHostDomain);
100 nat_false_domain_empty_.SetBoolean(key::kRemoteAccessHostFirewallTraversal,
101 false);
102 nat_false_domain_empty_.SetString(key::kRemoteAccessHostDomain,
103 std::string());
104 nat_false_domain_full_.SetBoolean(key::kRemoteAccessHostFirewallTraversal,
105 false);
106 nat_false_domain_full_.SetString(key::kRemoteAccessHostDomain, kHostDomain);
107 SetDefaults(nat_true_domain_empty_others_default_);
108 nat_true_domain_empty_others_default_.SetBoolean(
109 key::kRemoteAccessHostFirewallTraversal, true);
110 nat_true_domain_empty_others_default_.SetString(
111 key::kRemoteAccessHostDomain, std::string());
112 unknown_policies_.SetString("UnknownPolicyOne", std::string());
113 unknown_policies_.SetString("UnknownPolicyTwo", std::string());
114 unknown_policies_.SetBoolean("RemoteAccessHostUnknownPolicyThree", true);
116 const char kOverrideNatTraversalToFalse[] =
117 "{ \"RemoteAccessHostFirewallTraversal\": false }";
118 nat_true_and_overridden_.SetBoolean(key::kRemoteAccessHostFirewallTraversal,
119 true);
120 nat_true_and_overridden_.SetString(
121 key::kRemoteAccessHostDebugOverridePolicies,
122 kOverrideNatTraversalToFalse);
123 pairing_true_.SetBoolean(key::kRemoteAccessHostAllowClientPairing, true);
124 pairing_false_.SetBoolean(key::kRemoteAccessHostAllowClientPairing, false);
125 gnubby_auth_true_.SetBoolean(key::kRemoteAccessHostAllowGnubbyAuth, true);
126 gnubby_auth_false_.SetBoolean(key::kRemoteAccessHostAllowGnubbyAuth, false);
127 relay_true_.SetBoolean(key::kRemoteAccessHostAllowRelayedConnection, true);
128 relay_false_.SetBoolean(key::kRemoteAccessHostAllowRelayedConnection,
129 false);
130 port_range_full_.SetString(key::kRemoteAccessHostUdpPortRange, kPortRange);
131 port_range_empty_.SetString(key::kRemoteAccessHostUdpPortRange,
132 std::string());
133 port_range_malformed_.SetString(key::kRemoteAccessHostUdpPortRange,
134 "malformed");
135 port_range_malformed_domain_full_.MergeDictionary(&port_range_malformed_);
136 port_range_malformed_domain_full_.SetString(key::kRemoteAccessHostDomain,
137 kHostDomain);
139 curtain_true_.SetBoolean(key::kRemoteAccessHostRequireCurtain, true);
140 curtain_false_.SetBoolean(key::kRemoteAccessHostRequireCurtain, false);
141 username_true_.SetBoolean(key::kRemoteAccessHostMatchUsername, true);
142 username_false_.SetBoolean(key::kRemoteAccessHostMatchUsername, false);
143 talk_gadget_blah_.SetString(key::kRemoteAccessHostTalkGadgetPrefix, "blah");
144 third_party_auth_partial_.SetString(key::kRemoteAccessHostTokenUrl,
145 "https://token.com");
146 third_party_auth_partial_.SetString(
147 key::kRemoteAccessHostTokenValidationUrl, "https://validation.com");
148 third_party_auth_full_.MergeDictionary(&third_party_auth_partial_);
149 third_party_auth_full_.SetString(
150 key::kRemoteAccessHostTokenValidationCertificateIssuer,
151 "certificate subject");
152 third_party_auth_cert_empty_.MergeDictionary(&third_party_auth_partial_);
153 third_party_auth_cert_empty_.SetString(
154 key::kRemoteAccessHostTokenValidationCertificateIssuer, "");
156 #if !defined(NDEBUG)
157 SetDefaults(nat_false_overridden_others_default_);
158 nat_false_overridden_others_default_.SetBoolean(
159 key::kRemoteAccessHostFirewallTraversal, false);
160 nat_false_overridden_others_default_.SetString(
161 key::kRemoteAccessHostDebugOverridePolicies,
162 kOverrideNatTraversalToFalse);
163 #endif
166 void TearDown() override {
167 policy_watcher_.reset();
168 policy_loader_ = nullptr;
169 base::RunLoop().RunUntilIdle();
172 protected:
173 void StartWatching() {
174 policy_watcher_->StartWatching(
175 base::Bind(&MockPolicyCallback::OnPolicyUpdate,
176 base::Unretained(&mock_policy_callback_)),
177 base::Bind(&MockPolicyCallback::OnPolicyError,
178 base::Unretained(&mock_policy_callback_)));
179 base::RunLoop().RunUntilIdle();
182 void SetPolicies(const base::DictionaryValue& dict) {
183 // Copy |dict| into |policy_bundle|.
184 policy::PolicyNamespace policy_namespace =
185 policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string());
186 policy::PolicyBundle policy_bundle;
187 policy::PolicyMap& policy_map = policy_bundle.Get(policy_namespace);
188 policy_map.LoadFrom(&dict, policy::POLICY_LEVEL_MANDATORY,
189 policy::POLICY_SCOPE_MACHINE);
191 // Simulate a policy file/registry/preference update.
192 policy_loader_->SetPolicies(policy_bundle);
193 policy_loader_->PostReloadOnBackgroundThread(true /* force reload asap */);
194 base::RunLoop().RunUntilIdle();
197 const policy::Schema* GetPolicySchema() {
198 return policy_watcher_->GetPolicySchema();
201 const base::DictionaryValue& GetDefaultValues() {
202 return *(policy_watcher_->default_values_);
205 MOCK_METHOD0(PostPolicyWatcherShutdown, void());
207 static const char* kHostDomain;
208 static const char* kPortRange;
209 base::MessageLoop message_loop_;
210 MockPolicyCallback mock_policy_callback_;
212 // |policy_loader_| is owned by |policy_watcher_|. PolicyWatcherTest retains
213 // a raw pointer to |policy_loader_| in order to control the simulated / faked
214 // policy contents.
215 policy::FakeAsyncPolicyLoader* policy_loader_;
216 scoped_ptr<PolicyWatcher> policy_watcher_;
218 base::DictionaryValue empty_;
219 base::DictionaryValue nat_true_;
220 base::DictionaryValue nat_false_;
221 base::DictionaryValue nat_one_;
222 base::DictionaryValue nat_one_domain_full_;
223 base::DictionaryValue domain_empty_;
224 base::DictionaryValue domain_full_;
225 base::DictionaryValue nat_true_others_default_;
226 base::DictionaryValue nat_false_others_default_;
227 base::DictionaryValue domain_empty_others_default_;
228 base::DictionaryValue domain_full_others_default_;
229 base::DictionaryValue nat_true_domain_empty_;
230 base::DictionaryValue nat_true_domain_full_;
231 base::DictionaryValue nat_false_domain_empty_;
232 base::DictionaryValue nat_false_domain_full_;
233 base::DictionaryValue nat_true_domain_empty_others_default_;
234 base::DictionaryValue unknown_policies_;
235 base::DictionaryValue nat_true_and_overridden_;
236 base::DictionaryValue nat_false_overridden_others_default_;
237 base::DictionaryValue pairing_true_;
238 base::DictionaryValue pairing_false_;
239 base::DictionaryValue gnubby_auth_true_;
240 base::DictionaryValue gnubby_auth_false_;
241 base::DictionaryValue relay_true_;
242 base::DictionaryValue relay_false_;
243 base::DictionaryValue port_range_full_;
244 base::DictionaryValue port_range_empty_;
245 base::DictionaryValue port_range_malformed_;
246 base::DictionaryValue port_range_malformed_domain_full_;
247 base::DictionaryValue curtain_true_;
248 base::DictionaryValue curtain_false_;
249 base::DictionaryValue username_true_;
250 base::DictionaryValue username_false_;
251 base::DictionaryValue talk_gadget_blah_;
252 base::DictionaryValue third_party_auth_full_;
253 base::DictionaryValue third_party_auth_partial_;
254 base::DictionaryValue third_party_auth_cert_empty_;
256 private:
257 void SetDefaults(base::DictionaryValue& dict) {
258 dict.SetBoolean(key::kRemoteAccessHostFirewallTraversal, true);
259 dict.SetBoolean(key::kRemoteAccessHostAllowRelayedConnection, true);
260 dict.SetString(key::kRemoteAccessHostUdpPortRange, "");
261 dict.SetString(key::kRemoteAccessHostDomain, std::string());
262 dict.SetBoolean(key::kRemoteAccessHostMatchUsername, false);
263 dict.SetString(key::kRemoteAccessHostTalkGadgetPrefix,
264 kDefaultHostTalkGadgetPrefix);
265 dict.SetBoolean(key::kRemoteAccessHostRequireCurtain, false);
266 dict.SetString(key::kRemoteAccessHostTokenUrl, "");
267 dict.SetString(key::kRemoteAccessHostTokenValidationUrl, "");
268 dict.SetString(key::kRemoteAccessHostTokenValidationCertificateIssuer, "");
269 dict.SetBoolean(key::kRemoteAccessHostAllowClientPairing, true);
270 dict.SetBoolean(key::kRemoteAccessHostAllowGnubbyAuth, true);
271 #if !defined(NDEBUG)
272 dict.SetString(key::kRemoteAccessHostDebugOverridePolicies, "");
273 #endif
275 ASSERT_THAT(&dict, IsPolicies(&GetDefaultValues()))
276 << "Sanity check that defaults expected by the test code "
277 << "match what is stored in PolicyWatcher::default_values_";
281 const char* PolicyWatcherTest::kHostDomain = "google.com";
282 const char* PolicyWatcherTest::kPortRange = "12400-12409";
284 TEST_F(PolicyWatcherTest, None) {
285 EXPECT_CALL(mock_policy_callback_,
286 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
288 SetPolicies(empty_);
289 StartWatching();
292 TEST_F(PolicyWatcherTest, NatTrue) {
293 EXPECT_CALL(mock_policy_callback_,
294 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
296 SetPolicies(nat_true_);
297 StartWatching();
300 TEST_F(PolicyWatcherTest, NatFalse) {
301 EXPECT_CALL(mock_policy_callback_,
302 OnPolicyUpdatePtr(IsPolicies(&nat_false_others_default_)));
304 SetPolicies(nat_false_);
305 StartWatching();
308 TEST_F(PolicyWatcherTest, NatWrongType) {
309 EXPECT_CALL(mock_policy_callback_, OnPolicyError());
311 SetPolicies(nat_one_);
312 StartWatching();
315 // This test verifies that a mistyped policy value is still detected
316 // even though it doesn't change during the second SetPolicies call.
317 TEST_F(PolicyWatcherTest, NatWrongTypeThenIrrelevantChange) {
318 EXPECT_CALL(mock_policy_callback_, OnPolicyError()).Times(2);
320 SetPolicies(nat_one_);
321 StartWatching();
322 SetPolicies(nat_one_domain_full_);
325 // This test verifies that a malformed policy value is still detected
326 // even though it doesn't change during the second SetPolicies call.
327 TEST_F(PolicyWatcherTest, PortRangeMalformedThenIrrelevantChange) {
328 EXPECT_CALL(mock_policy_callback_, OnPolicyError()).Times(2);
330 SetPolicies(port_range_malformed_);
331 StartWatching();
332 SetPolicies(port_range_malformed_domain_full_);
335 TEST_F(PolicyWatcherTest, DomainEmpty) {
336 EXPECT_CALL(mock_policy_callback_,
337 OnPolicyUpdatePtr(IsPolicies(&domain_empty_others_default_)));
339 SetPolicies(domain_empty_);
340 StartWatching();
343 TEST_F(PolicyWatcherTest, DomainFull) {
344 EXPECT_CALL(mock_policy_callback_,
345 OnPolicyUpdatePtr(IsPolicies(&domain_full_others_default_)));
347 SetPolicies(domain_full_);
348 StartWatching();
351 TEST_F(PolicyWatcherTest, NatNoneThenTrue) {
352 EXPECT_CALL(mock_policy_callback_,
353 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
355 SetPolicies(empty_);
356 StartWatching();
357 SetPolicies(nat_true_);
360 TEST_F(PolicyWatcherTest, NatNoneThenTrueThenTrue) {
361 EXPECT_CALL(mock_policy_callback_,
362 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
364 SetPolicies(empty_);
365 StartWatching();
366 SetPolicies(nat_true_);
367 SetPolicies(nat_true_);
370 TEST_F(PolicyWatcherTest, NatNoneThenTrueThenTrueThenFalse) {
371 testing::InSequence sequence;
372 EXPECT_CALL(mock_policy_callback_,
373 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
374 EXPECT_CALL(mock_policy_callback_,
375 OnPolicyUpdatePtr(IsPolicies(&nat_false_)));
377 SetPolicies(empty_);
378 StartWatching();
379 SetPolicies(nat_true_);
380 SetPolicies(nat_true_);
381 SetPolicies(nat_false_);
384 TEST_F(PolicyWatcherTest, NatNoneThenFalse) {
385 testing::InSequence sequence;
386 EXPECT_CALL(mock_policy_callback_,
387 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
388 EXPECT_CALL(mock_policy_callback_,
389 OnPolicyUpdatePtr(IsPolicies(&nat_false_)));
391 SetPolicies(empty_);
392 StartWatching();
393 SetPolicies(nat_false_);
396 TEST_F(PolicyWatcherTest, NatNoneThenFalseThenTrue) {
397 testing::InSequence sequence;
398 EXPECT_CALL(mock_policy_callback_,
399 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
400 EXPECT_CALL(mock_policy_callback_,
401 OnPolicyUpdatePtr(IsPolicies(&nat_false_)));
402 EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(IsPolicies(&nat_true_)));
404 SetPolicies(empty_);
405 StartWatching();
406 SetPolicies(nat_false_);
407 SetPolicies(nat_true_);
410 TEST_F(PolicyWatcherTest, ChangeOneRepeatedlyThenTwo) {
411 testing::InSequence sequence;
412 EXPECT_CALL(
413 mock_policy_callback_,
414 OnPolicyUpdatePtr(IsPolicies(&nat_true_domain_empty_others_default_)));
415 EXPECT_CALL(mock_policy_callback_,
416 OnPolicyUpdatePtr(IsPolicies(&domain_full_)));
417 EXPECT_CALL(mock_policy_callback_,
418 OnPolicyUpdatePtr(IsPolicies(&nat_false_)));
419 EXPECT_CALL(mock_policy_callback_,
420 OnPolicyUpdatePtr(IsPolicies(&domain_empty_)));
421 EXPECT_CALL(mock_policy_callback_,
422 OnPolicyUpdatePtr(IsPolicies(&nat_true_domain_full_)));
424 SetPolicies(nat_true_domain_empty_);
425 StartWatching();
426 SetPolicies(nat_true_domain_full_);
427 SetPolicies(nat_false_domain_full_);
428 SetPolicies(nat_false_domain_empty_);
429 SetPolicies(nat_true_domain_full_);
432 TEST_F(PolicyWatcherTest, FilterUnknownPolicies) {
433 testing::InSequence sequence;
434 EXPECT_CALL(mock_policy_callback_,
435 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
437 SetPolicies(empty_);
438 StartWatching();
439 SetPolicies(unknown_policies_);
440 SetPolicies(empty_);
443 class MisspelledPolicyTest : public PolicyWatcherTest,
444 public ::testing::WithParamInterface<const char*> {
447 // Verify that a misspelled policy causes a warning written to the log.
448 TEST_P(MisspelledPolicyTest, WarningLogged) {
449 const char* misspelled_policy_name = GetParam();
450 base::test::MockLog mock_log;
452 ON_CALL(mock_log, Log(testing::_, testing::_, testing::_, testing::_,
453 testing::_)).WillByDefault(testing::Return(true));
455 EXPECT_CALL(mock_log,
456 Log(logging::LOG_WARNING, testing::_, testing::_, testing::_,
457 testing::HasSubstr(misspelled_policy_name))).Times(1);
459 EXPECT_CALL(mock_policy_callback_,
460 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
462 base::DictionaryValue misspelled_policies;
463 misspelled_policies.SetString(misspelled_policy_name, "some test value");
464 mock_log.StartCapturingLogs();
466 SetPolicies(misspelled_policies);
467 StartWatching();
469 mock_log.StopCapturingLogs();
472 INSTANTIATE_TEST_CASE_P(
473 PolicyWatcherTest,
474 MisspelledPolicyTest,
475 ::testing::Values("RemoteAccessHostDomainX",
476 "XRemoteAccessHostDomain",
477 "RemoteAccessHostdomain",
478 "RemoteAccessHostPolicyForFutureVersion"));
480 TEST_F(PolicyWatcherTest, DebugOverrideNatPolicy) {
481 #if !defined(NDEBUG)
482 EXPECT_CALL(
483 mock_policy_callback_,
484 OnPolicyUpdatePtr(IsPolicies(&nat_false_overridden_others_default_)));
485 #else
486 EXPECT_CALL(mock_policy_callback_,
487 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
488 #endif
490 SetPolicies(nat_true_and_overridden_);
491 StartWatching();
494 TEST_F(PolicyWatcherTest, PairingFalseThenTrue) {
495 testing::InSequence sequence;
496 EXPECT_CALL(mock_policy_callback_,
497 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
498 EXPECT_CALL(mock_policy_callback_,
499 OnPolicyUpdatePtr(IsPolicies(&pairing_false_)));
500 EXPECT_CALL(mock_policy_callback_,
501 OnPolicyUpdatePtr(IsPolicies(&pairing_true_)));
503 SetPolicies(empty_);
504 StartWatching();
505 SetPolicies(pairing_false_);
506 SetPolicies(pairing_true_);
509 TEST_F(PolicyWatcherTest, GnubbyAuth) {
510 testing::InSequence sequence;
511 EXPECT_CALL(mock_policy_callback_,
512 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
513 EXPECT_CALL(mock_policy_callback_,
514 OnPolicyUpdatePtr(IsPolicies(&gnubby_auth_false_)));
515 EXPECT_CALL(mock_policy_callback_,
516 OnPolicyUpdatePtr(IsPolicies(&gnubby_auth_true_)));
518 SetPolicies(empty_);
519 StartWatching();
520 SetPolicies(gnubby_auth_false_);
521 SetPolicies(gnubby_auth_true_);
524 TEST_F(PolicyWatcherTest, Relay) {
525 testing::InSequence sequence;
526 EXPECT_CALL(mock_policy_callback_,
527 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
528 EXPECT_CALL(mock_policy_callback_,
529 OnPolicyUpdatePtr(IsPolicies(&relay_false_)));
530 EXPECT_CALL(mock_policy_callback_,
531 OnPolicyUpdatePtr(IsPolicies(&relay_true_)));
533 SetPolicies(empty_);
534 StartWatching();
535 SetPolicies(relay_false_);
536 SetPolicies(relay_true_);
539 TEST_F(PolicyWatcherTest, Curtain) {
540 testing::InSequence sequence;
541 EXPECT_CALL(mock_policy_callback_,
542 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
543 EXPECT_CALL(mock_policy_callback_,
544 OnPolicyUpdatePtr(IsPolicies(&curtain_true_)));
545 EXPECT_CALL(mock_policy_callback_,
546 OnPolicyUpdatePtr(IsPolicies(&curtain_false_)));
548 SetPolicies(empty_);
549 StartWatching();
550 SetPolicies(curtain_true_);
551 SetPolicies(curtain_false_);
554 TEST_F(PolicyWatcherTest, MatchUsername) {
555 testing::InSequence sequence;
556 EXPECT_CALL(mock_policy_callback_,
557 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
558 #if !defined(OS_WIN)
559 EXPECT_CALL(mock_policy_callback_,
560 OnPolicyUpdatePtr(IsPolicies(&username_true_)));
561 EXPECT_CALL(mock_policy_callback_,
562 OnPolicyUpdatePtr(IsPolicies(&username_false_)));
563 #else
564 // On Windows the MatchUsername policy is ignored and therefore the 2
565 // SetPolicies calls won't result in any calls to OnPolicyUpdate.
566 #endif
568 SetPolicies(empty_);
569 StartWatching();
570 SetPolicies(username_true_);
571 SetPolicies(username_false_);
574 TEST_F(PolicyWatcherTest, TalkGadgetPrefix) {
575 testing::InSequence sequence;
576 EXPECT_CALL(mock_policy_callback_,
577 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
578 EXPECT_CALL(mock_policy_callback_,
579 OnPolicyUpdatePtr(IsPolicies(&talk_gadget_blah_)));
581 SetPolicies(empty_);
582 StartWatching();
583 SetPolicies(talk_gadget_blah_);
586 TEST_F(PolicyWatcherTest, ThirdPartyAuthFull) {
587 testing::InSequence sequence;
588 EXPECT_CALL(mock_policy_callback_,
589 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
590 EXPECT_CALL(mock_policy_callback_,
591 OnPolicyUpdatePtr(IsPolicies(&third_party_auth_full_)));
593 SetPolicies(empty_);
594 StartWatching();
595 SetPolicies(third_party_auth_full_);
598 // This test verifies what happens when only 1 out of 3 third-party auth
599 // policies changes. Without the other 2 policy values such policy values
600 // combination is invalid (i.e. cannot have TokenUrl without
601 // TokenValidationUrl) and can trigger OnPolicyError unless PolicyWatcher
602 // implementation is careful around this scenario.
603 TEST_F(PolicyWatcherTest, ThirdPartyAuthPartialToFull) {
604 testing::InSequence sequence;
605 EXPECT_CALL(mock_policy_callback_,
606 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
607 EXPECT_CALL(mock_policy_callback_,
608 OnPolicyUpdatePtr(IsPolicies(&third_party_auth_cert_empty_)));
609 EXPECT_CALL(mock_policy_callback_,
610 OnPolicyUpdatePtr(IsPolicies(&third_party_auth_full_)));
612 SetPolicies(empty_);
613 StartWatching();
614 SetPolicies(third_party_auth_partial_);
615 SetPolicies(third_party_auth_full_);
618 TEST_F(PolicyWatcherTest, UdpPortRange) {
619 testing::InSequence sequence;
620 EXPECT_CALL(mock_policy_callback_,
621 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
622 EXPECT_CALL(mock_policy_callback_,
623 OnPolicyUpdatePtr(IsPolicies(&port_range_full_)));
624 EXPECT_CALL(mock_policy_callback_,
625 OnPolicyUpdatePtr(IsPolicies(&port_range_empty_)));
627 SetPolicies(empty_);
628 StartWatching();
629 SetPolicies(port_range_full_);
630 SetPolicies(port_range_empty_);
633 TEST_F(PolicyWatcherTest, PolicySchemaAndPolicyWatcherShouldBeInSync) {
634 // This test verifies that
635 // 1) policy schema (generated out of policy_templates.json)
636 // and
637 // 2) PolicyWatcher's code (i.e. contents of the |default_values_| field)
638 // are kept in-sync.
640 std::map<std::string, base::Value::Type> expected_schema;
641 for (base::DictionaryValue::Iterator i(GetDefaultValues()); !i.IsAtEnd();
642 i.Advance()) {
643 expected_schema[i.key()] = i.value().GetType();
645 #if defined(OS_WIN)
646 // RemoteAccessHostMatchUsername is marked in policy_templates.json as not
647 // supported on Windows and therefore is (by design) excluded from the schema.
648 expected_schema.erase(key::kRemoteAccessHostMatchUsername);
649 #endif
650 #if defined(NDEBUG)
651 // Policy schema / policy_templates.json cannot differ between debug and
652 // release builds so we compensate below to account for the fact that
653 // PolicyWatcher::default_values_ does differ between debug and release.
654 expected_schema[key::kRemoteAccessHostDebugOverridePolicies] =
655 base::Value::TYPE_STRING;
656 #endif
658 std::map<std::string, base::Value::Type> actual_schema;
659 const policy::Schema* schema = GetPolicySchema();
660 ASSERT_TRUE(schema->valid());
661 for (auto it = schema->GetPropertiesIterator(); !it.IsAtEnd(); it.Advance()) {
662 std::string key = it.key();
663 if (key.find("RemoteAccessHost") == std::string::npos) {
664 // For now PolicyWatcher::GetPolicySchema() mixes Chrome and Chromoting
665 // policies, so we have to skip them here.
666 continue;
668 actual_schema[key] = it.schema().type();
671 EXPECT_THAT(actual_schema, testing::ContainerEq(expected_schema));
674 TEST_F(PolicyWatcherTest, SchemaTypeCheck) {
675 const policy::Schema* schema = GetPolicySchema();
676 ASSERT_TRUE(schema->valid());
678 // Check one, random "string" policy to see if the type propagated correctly
679 // from policy_templates.json file.
680 const policy::Schema string_schema =
681 schema->GetKnownProperty("RemoteAccessHostDomain");
682 EXPECT_TRUE(string_schema.valid());
683 EXPECT_EQ(string_schema.type(), base::Value::Type::TYPE_STRING);
685 // And check one, random "boolean" policy to see if the type propagated
686 // correctly from policy_templates.json file.
687 const policy::Schema boolean_schema =
688 schema->GetKnownProperty("RemoteAccessHostRequireCurtain");
689 EXPECT_TRUE(boolean_schema.valid());
690 EXPECT_EQ(boolean_schema.type(), base::Value::Type::TYPE_BOOLEAN);
693 // Unit tests cannot instantiate PolicyWatcher on ChromeOS
694 // (as this requires running inside a browser process).
695 #ifndef OS_CHROMEOS
697 namespace {
699 void OnPolicyUpdatedDumpPolicy(scoped_ptr<base::DictionaryValue> policies) {
700 VLOG(1) << "OnPolicyUpdated callback received the following policies:";
702 for (base::DictionaryValue::Iterator iter(*policies); !iter.IsAtEnd();
703 iter.Advance()) {
704 switch (iter.value().GetType()) {
705 case base::Value::Type::TYPE_STRING: {
706 std::string value;
707 CHECK(iter.value().GetAsString(&value));
708 VLOG(1) << iter.key() << " = "
709 << "string: " << '"' << value << '"';
710 break;
712 case base::Value::Type::TYPE_BOOLEAN: {
713 bool value;
714 CHECK(iter.value().GetAsBoolean(&value));
715 VLOG(1) << iter.key() << " = "
716 << "boolean: " << (value ? "True" : "False");
717 break;
719 default: {
720 VLOG(1) << iter.key() << " = "
721 << "unrecognized type";
722 break;
728 } // anonymous namespace
730 // To dump policy contents, run unit tests with the following flags:
731 // out/Debug/remoting_unittests --gtest_filter=*TestRealChromotingPolicy* -v=1
732 #if defined(ADDRESS_SANITIZER)
733 // http://crbug.com/517918
734 #define MAYBE_TestRealChromotingPolicy DISABLED_TestRealChromotingPolicy
735 #else
736 #define MAYBE_TestRealChromotingPolicy TestRealChromotingPolicy
737 #endif
738 TEST_F(PolicyWatcherTest, MAYBE_TestRealChromotingPolicy) {
739 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
740 base::MessageLoop::current()->task_runner();
741 scoped_ptr<PolicyWatcher> policy_watcher(
742 PolicyWatcher::Create(nullptr, task_runner));
745 base::RunLoop run_loop;
746 policy_watcher->StartWatching(base::Bind(OnPolicyUpdatedDumpPolicy),
747 base::Bind(base::DoNothing));
748 run_loop.RunUntilIdle();
751 // Today, the only verification offered by this test is:
752 // - Manual verification of policy values dumped by OnPolicyUpdatedDumpPolicy
753 // - Automated verification that nothing crashed
756 #endif
758 } // namespace remoting