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"
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"
23 namespace key
= ::policy::key
;
25 MATCHER_P(IsPolicies
, dict
, "") {
26 bool equal
= arg
->Equals(dict
);
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
<< ".";
43 class MockPolicyCallback
{
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());
56 DISALLOW_COPY_AND_ASSIGN(MockPolicyCallback
);
59 class PolicyWatcherTest
: public testing::Test
{
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.
70 new policy::FakeAsyncPolicyLoader(base::ThreadTaskRunnerHandle::Get());
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
,
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
,
90 SetDefaults(domain_full_others_default_
);
91 domain_full_others_default_
.SetString(key::kRemoteAccessHostDomain
,
93 nat_true_domain_empty_
.SetBoolean(key::kRemoteAccessHostFirewallTraversal
,
95 nat_true_domain_empty_
.SetString(key::kRemoteAccessHostDomain
,
97 nat_true_domain_full_
.SetBoolean(key::kRemoteAccessHostFirewallTraversal
,
99 nat_true_domain_full_
.SetString(key::kRemoteAccessHostDomain
, kHostDomain
);
100 nat_false_domain_empty_
.SetBoolean(key::kRemoteAccessHostFirewallTraversal
,
102 nat_false_domain_empty_
.SetString(key::kRemoteAccessHostDomain
,
104 nat_false_domain_full_
.SetBoolean(key::kRemoteAccessHostFirewallTraversal
,
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
,
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
,
130 port_range_full_
.SetString(key::kRemoteAccessHostUdpPortRange
, kPortRange
);
131 port_range_empty_
.SetString(key::kRemoteAccessHostUdpPortRange
,
133 port_range_malformed_
.SetString(key::kRemoteAccessHostUdpPortRange
,
135 port_range_malformed_domain_full_
.MergeDictionary(&port_range_malformed_
);
136 port_range_malformed_domain_full_
.SetString(key::kRemoteAccessHostDomain
,
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
, "");
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
);
166 void TearDown() override
{
167 policy_watcher_
.reset();
168 policy_loader_
= nullptr;
169 base::RunLoop().RunUntilIdle();
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
,
190 policy::POLICY_SOURCE_CLOUD
);
192 // Simulate a policy file/registry/preference update.
193 policy_loader_
->SetPolicies(policy_bundle
);
194 policy_loader_
->PostReloadOnBackgroundThread(true /* force reload asap */);
195 base::RunLoop().RunUntilIdle();
198 const policy::Schema
* GetPolicySchema() {
199 return policy_watcher_
->GetPolicySchema();
202 const base::DictionaryValue
& GetDefaultValues() {
203 return *(policy_watcher_
->default_values_
);
206 MOCK_METHOD0(PostPolicyWatcherShutdown
, void());
208 static const char* kHostDomain
;
209 static const char* kPortRange
;
210 base::MessageLoop message_loop_
;
211 MockPolicyCallback mock_policy_callback_
;
213 // |policy_loader_| is owned by |policy_watcher_|. PolicyWatcherTest retains
214 // a raw pointer to |policy_loader_| in order to control the simulated / faked
216 policy::FakeAsyncPolicyLoader
* policy_loader_
;
217 scoped_ptr
<PolicyWatcher
> policy_watcher_
;
219 base::DictionaryValue empty_
;
220 base::DictionaryValue nat_true_
;
221 base::DictionaryValue nat_false_
;
222 base::DictionaryValue nat_one_
;
223 base::DictionaryValue nat_one_domain_full_
;
224 base::DictionaryValue domain_empty_
;
225 base::DictionaryValue domain_full_
;
226 base::DictionaryValue nat_true_others_default_
;
227 base::DictionaryValue nat_false_others_default_
;
228 base::DictionaryValue domain_empty_others_default_
;
229 base::DictionaryValue domain_full_others_default_
;
230 base::DictionaryValue nat_true_domain_empty_
;
231 base::DictionaryValue nat_true_domain_full_
;
232 base::DictionaryValue nat_false_domain_empty_
;
233 base::DictionaryValue nat_false_domain_full_
;
234 base::DictionaryValue nat_true_domain_empty_others_default_
;
235 base::DictionaryValue unknown_policies_
;
236 base::DictionaryValue nat_true_and_overridden_
;
237 base::DictionaryValue nat_false_overridden_others_default_
;
238 base::DictionaryValue pairing_true_
;
239 base::DictionaryValue pairing_false_
;
240 base::DictionaryValue gnubby_auth_true_
;
241 base::DictionaryValue gnubby_auth_false_
;
242 base::DictionaryValue relay_true_
;
243 base::DictionaryValue relay_false_
;
244 base::DictionaryValue port_range_full_
;
245 base::DictionaryValue port_range_empty_
;
246 base::DictionaryValue port_range_malformed_
;
247 base::DictionaryValue port_range_malformed_domain_full_
;
248 base::DictionaryValue curtain_true_
;
249 base::DictionaryValue curtain_false_
;
250 base::DictionaryValue username_true_
;
251 base::DictionaryValue username_false_
;
252 base::DictionaryValue talk_gadget_blah_
;
253 base::DictionaryValue third_party_auth_full_
;
254 base::DictionaryValue third_party_auth_partial_
;
255 base::DictionaryValue third_party_auth_cert_empty_
;
258 void SetDefaults(base::DictionaryValue
& dict
) {
259 dict
.SetBoolean(key::kRemoteAccessHostFirewallTraversal
, true);
260 dict
.SetBoolean(key::kRemoteAccessHostAllowRelayedConnection
, true);
261 dict
.SetString(key::kRemoteAccessHostUdpPortRange
, "");
262 dict
.SetString(key::kRemoteAccessHostDomain
, std::string());
263 dict
.SetBoolean(key::kRemoteAccessHostMatchUsername
, false);
264 dict
.SetString(key::kRemoteAccessHostTalkGadgetPrefix
,
265 kDefaultHostTalkGadgetPrefix
);
266 dict
.SetBoolean(key::kRemoteAccessHostRequireCurtain
, false);
267 dict
.SetString(key::kRemoteAccessHostTokenUrl
, "");
268 dict
.SetString(key::kRemoteAccessHostTokenValidationUrl
, "");
269 dict
.SetString(key::kRemoteAccessHostTokenValidationCertificateIssuer
, "");
270 dict
.SetBoolean(key::kRemoteAccessHostAllowClientPairing
, true);
271 dict
.SetBoolean(key::kRemoteAccessHostAllowGnubbyAuth
, true);
273 dict
.SetString(key::kRemoteAccessHostDebugOverridePolicies
, "");
276 ASSERT_THAT(&dict
, IsPolicies(&GetDefaultValues()))
277 << "Sanity check that defaults expected by the test code "
278 << "match what is stored in PolicyWatcher::default_values_";
282 const char* PolicyWatcherTest::kHostDomain
= "google.com";
283 const char* PolicyWatcherTest::kPortRange
= "12400-12409";
285 TEST_F(PolicyWatcherTest
, None
) {
286 EXPECT_CALL(mock_policy_callback_
,
287 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
293 TEST_F(PolicyWatcherTest
, NatTrue
) {
294 EXPECT_CALL(mock_policy_callback_
,
295 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
297 SetPolicies(nat_true_
);
301 TEST_F(PolicyWatcherTest
, NatFalse
) {
302 EXPECT_CALL(mock_policy_callback_
,
303 OnPolicyUpdatePtr(IsPolicies(&nat_false_others_default_
)));
305 SetPolicies(nat_false_
);
309 TEST_F(PolicyWatcherTest
, NatWrongType
) {
310 EXPECT_CALL(mock_policy_callback_
, OnPolicyError());
312 SetPolicies(nat_one_
);
316 // This test verifies that a mistyped policy value is still detected
317 // even though it doesn't change during the second SetPolicies call.
318 TEST_F(PolicyWatcherTest
, NatWrongTypeThenIrrelevantChange
) {
319 EXPECT_CALL(mock_policy_callback_
, OnPolicyError()).Times(2);
321 SetPolicies(nat_one_
);
323 SetPolicies(nat_one_domain_full_
);
326 // This test verifies that a malformed policy value is still detected
327 // even though it doesn't change during the second SetPolicies call.
328 TEST_F(PolicyWatcherTest
, PortRangeMalformedThenIrrelevantChange
) {
329 EXPECT_CALL(mock_policy_callback_
, OnPolicyError()).Times(2);
331 SetPolicies(port_range_malformed_
);
333 SetPolicies(port_range_malformed_domain_full_
);
336 TEST_F(PolicyWatcherTest
, DomainEmpty
) {
337 EXPECT_CALL(mock_policy_callback_
,
338 OnPolicyUpdatePtr(IsPolicies(&domain_empty_others_default_
)));
340 SetPolicies(domain_empty_
);
344 TEST_F(PolicyWatcherTest
, DomainFull
) {
345 EXPECT_CALL(mock_policy_callback_
,
346 OnPolicyUpdatePtr(IsPolicies(&domain_full_others_default_
)));
348 SetPolicies(domain_full_
);
352 TEST_F(PolicyWatcherTest
, NatNoneThenTrue
) {
353 EXPECT_CALL(mock_policy_callback_
,
354 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
358 SetPolicies(nat_true_
);
361 TEST_F(PolicyWatcherTest
, NatNoneThenTrueThenTrue
) {
362 EXPECT_CALL(mock_policy_callback_
,
363 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
367 SetPolicies(nat_true_
);
368 SetPolicies(nat_true_
);
371 TEST_F(PolicyWatcherTest
, NatNoneThenTrueThenTrueThenFalse
) {
372 testing::InSequence sequence
;
373 EXPECT_CALL(mock_policy_callback_
,
374 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
375 EXPECT_CALL(mock_policy_callback_
,
376 OnPolicyUpdatePtr(IsPolicies(&nat_false_
)));
380 SetPolicies(nat_true_
);
381 SetPolicies(nat_true_
);
382 SetPolicies(nat_false_
);
385 TEST_F(PolicyWatcherTest
, NatNoneThenFalse
) {
386 testing::InSequence sequence
;
387 EXPECT_CALL(mock_policy_callback_
,
388 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
389 EXPECT_CALL(mock_policy_callback_
,
390 OnPolicyUpdatePtr(IsPolicies(&nat_false_
)));
394 SetPolicies(nat_false_
);
397 TEST_F(PolicyWatcherTest
, NatNoneThenFalseThenTrue
) {
398 testing::InSequence sequence
;
399 EXPECT_CALL(mock_policy_callback_
,
400 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
401 EXPECT_CALL(mock_policy_callback_
,
402 OnPolicyUpdatePtr(IsPolicies(&nat_false_
)));
403 EXPECT_CALL(mock_policy_callback_
, OnPolicyUpdatePtr(IsPolicies(&nat_true_
)));
407 SetPolicies(nat_false_
);
408 SetPolicies(nat_true_
);
411 TEST_F(PolicyWatcherTest
, ChangeOneRepeatedlyThenTwo
) {
412 testing::InSequence sequence
;
414 mock_policy_callback_
,
415 OnPolicyUpdatePtr(IsPolicies(&nat_true_domain_empty_others_default_
)));
416 EXPECT_CALL(mock_policy_callback_
,
417 OnPolicyUpdatePtr(IsPolicies(&domain_full_
)));
418 EXPECT_CALL(mock_policy_callback_
,
419 OnPolicyUpdatePtr(IsPolicies(&nat_false_
)));
420 EXPECT_CALL(mock_policy_callback_
,
421 OnPolicyUpdatePtr(IsPolicies(&domain_empty_
)));
422 EXPECT_CALL(mock_policy_callback_
,
423 OnPolicyUpdatePtr(IsPolicies(&nat_true_domain_full_
)));
425 SetPolicies(nat_true_domain_empty_
);
427 SetPolicies(nat_true_domain_full_
);
428 SetPolicies(nat_false_domain_full_
);
429 SetPolicies(nat_false_domain_empty_
);
430 SetPolicies(nat_true_domain_full_
);
433 TEST_F(PolicyWatcherTest
, FilterUnknownPolicies
) {
434 testing::InSequence sequence
;
435 EXPECT_CALL(mock_policy_callback_
,
436 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
440 SetPolicies(unknown_policies_
);
444 class MisspelledPolicyTest
: public PolicyWatcherTest
,
445 public ::testing::WithParamInterface
<const char*> {
448 // Verify that a misspelled policy causes a warning written to the log.
449 TEST_P(MisspelledPolicyTest
, WarningLogged
) {
450 const char* misspelled_policy_name
= GetParam();
451 base::test::MockLog mock_log
;
453 ON_CALL(mock_log
, Log(testing::_
, testing::_
, testing::_
, testing::_
,
454 testing::_
)).WillByDefault(testing::Return(true));
456 EXPECT_CALL(mock_log
,
457 Log(logging::LOG_WARNING
, testing::_
, testing::_
, testing::_
,
458 testing::HasSubstr(misspelled_policy_name
))).Times(1);
460 EXPECT_CALL(mock_policy_callback_
,
461 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
463 base::DictionaryValue misspelled_policies
;
464 misspelled_policies
.SetString(misspelled_policy_name
, "some test value");
465 mock_log
.StartCapturingLogs();
467 SetPolicies(misspelled_policies
);
470 mock_log
.StopCapturingLogs();
473 INSTANTIATE_TEST_CASE_P(
475 MisspelledPolicyTest
,
476 ::testing::Values("RemoteAccessHostDomainX",
477 "XRemoteAccessHostDomain",
478 "RemoteAccessHostdomain",
479 "RemoteAccessHostPolicyForFutureVersion"));
481 TEST_F(PolicyWatcherTest
, DebugOverrideNatPolicy
) {
484 mock_policy_callback_
,
485 OnPolicyUpdatePtr(IsPolicies(&nat_false_overridden_others_default_
)));
487 EXPECT_CALL(mock_policy_callback_
,
488 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
491 SetPolicies(nat_true_and_overridden_
);
495 TEST_F(PolicyWatcherTest
, PairingFalseThenTrue
) {
496 testing::InSequence sequence
;
497 EXPECT_CALL(mock_policy_callback_
,
498 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
499 EXPECT_CALL(mock_policy_callback_
,
500 OnPolicyUpdatePtr(IsPolicies(&pairing_false_
)));
501 EXPECT_CALL(mock_policy_callback_
,
502 OnPolicyUpdatePtr(IsPolicies(&pairing_true_
)));
506 SetPolicies(pairing_false_
);
507 SetPolicies(pairing_true_
);
510 TEST_F(PolicyWatcherTest
, GnubbyAuth
) {
511 testing::InSequence sequence
;
512 EXPECT_CALL(mock_policy_callback_
,
513 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
514 EXPECT_CALL(mock_policy_callback_
,
515 OnPolicyUpdatePtr(IsPolicies(&gnubby_auth_false_
)));
516 EXPECT_CALL(mock_policy_callback_
,
517 OnPolicyUpdatePtr(IsPolicies(&gnubby_auth_true_
)));
521 SetPolicies(gnubby_auth_false_
);
522 SetPolicies(gnubby_auth_true_
);
525 TEST_F(PolicyWatcherTest
, Relay
) {
526 testing::InSequence sequence
;
527 EXPECT_CALL(mock_policy_callback_
,
528 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
529 EXPECT_CALL(mock_policy_callback_
,
530 OnPolicyUpdatePtr(IsPolicies(&relay_false_
)));
531 EXPECT_CALL(mock_policy_callback_
,
532 OnPolicyUpdatePtr(IsPolicies(&relay_true_
)));
536 SetPolicies(relay_false_
);
537 SetPolicies(relay_true_
);
540 TEST_F(PolicyWatcherTest
, Curtain
) {
541 testing::InSequence sequence
;
542 EXPECT_CALL(mock_policy_callback_
,
543 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
544 EXPECT_CALL(mock_policy_callback_
,
545 OnPolicyUpdatePtr(IsPolicies(&curtain_true_
)));
546 EXPECT_CALL(mock_policy_callback_
,
547 OnPolicyUpdatePtr(IsPolicies(&curtain_false_
)));
551 SetPolicies(curtain_true_
);
552 SetPolicies(curtain_false_
);
555 TEST_F(PolicyWatcherTest
, MatchUsername
) {
556 testing::InSequence sequence
;
557 EXPECT_CALL(mock_policy_callback_
,
558 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
560 EXPECT_CALL(mock_policy_callback_
,
561 OnPolicyUpdatePtr(IsPolicies(&username_true_
)));
562 EXPECT_CALL(mock_policy_callback_
,
563 OnPolicyUpdatePtr(IsPolicies(&username_false_
)));
565 // On Windows the MatchUsername policy is ignored and therefore the 2
566 // SetPolicies calls won't result in any calls to OnPolicyUpdate.
571 SetPolicies(username_true_
);
572 SetPolicies(username_false_
);
575 TEST_F(PolicyWatcherTest
, TalkGadgetPrefix
) {
576 testing::InSequence sequence
;
577 EXPECT_CALL(mock_policy_callback_
,
578 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
579 EXPECT_CALL(mock_policy_callback_
,
580 OnPolicyUpdatePtr(IsPolicies(&talk_gadget_blah_
)));
584 SetPolicies(talk_gadget_blah_
);
587 TEST_F(PolicyWatcherTest
, ThirdPartyAuthFull
) {
588 testing::InSequence sequence
;
589 EXPECT_CALL(mock_policy_callback_
,
590 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
591 EXPECT_CALL(mock_policy_callback_
,
592 OnPolicyUpdatePtr(IsPolicies(&third_party_auth_full_
)));
596 SetPolicies(third_party_auth_full_
);
599 // This test verifies what happens when only 1 out of 3 third-party auth
600 // policies changes. Without the other 2 policy values such policy values
601 // combination is invalid (i.e. cannot have TokenUrl without
602 // TokenValidationUrl) and can trigger OnPolicyError unless PolicyWatcher
603 // implementation is careful around this scenario.
604 TEST_F(PolicyWatcherTest
, ThirdPartyAuthPartialToFull
) {
605 testing::InSequence sequence
;
606 EXPECT_CALL(mock_policy_callback_
,
607 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
608 EXPECT_CALL(mock_policy_callback_
,
609 OnPolicyUpdatePtr(IsPolicies(&third_party_auth_cert_empty_
)));
610 EXPECT_CALL(mock_policy_callback_
,
611 OnPolicyUpdatePtr(IsPolicies(&third_party_auth_full_
)));
615 SetPolicies(third_party_auth_partial_
);
616 SetPolicies(third_party_auth_full_
);
619 TEST_F(PolicyWatcherTest
, UdpPortRange
) {
620 testing::InSequence sequence
;
621 EXPECT_CALL(mock_policy_callback_
,
622 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
623 EXPECT_CALL(mock_policy_callback_
,
624 OnPolicyUpdatePtr(IsPolicies(&port_range_full_
)));
625 EXPECT_CALL(mock_policy_callback_
,
626 OnPolicyUpdatePtr(IsPolicies(&port_range_empty_
)));
630 SetPolicies(port_range_full_
);
631 SetPolicies(port_range_empty_
);
634 TEST_F(PolicyWatcherTest
, PolicySchemaAndPolicyWatcherShouldBeInSync
) {
635 // This test verifies that
636 // 1) policy schema (generated out of policy_templates.json)
638 // 2) PolicyWatcher's code (i.e. contents of the |default_values_| field)
641 std::map
<std::string
, base::Value::Type
> expected_schema
;
642 for (base::DictionaryValue::Iterator
i(GetDefaultValues()); !i
.IsAtEnd();
644 expected_schema
[i
.key()] = i
.value().GetType();
647 // RemoteAccessHostMatchUsername is marked in policy_templates.json as not
648 // supported on Windows and therefore is (by design) excluded from the schema.
649 expected_schema
.erase(key::kRemoteAccessHostMatchUsername
);
652 // Policy schema / policy_templates.json cannot differ between debug and
653 // release builds so we compensate below to account for the fact that
654 // PolicyWatcher::default_values_ does differ between debug and release.
655 expected_schema
[key::kRemoteAccessHostDebugOverridePolicies
] =
656 base::Value::TYPE_STRING
;
659 std::map
<std::string
, base::Value::Type
> actual_schema
;
660 const policy::Schema
* schema
= GetPolicySchema();
661 ASSERT_TRUE(schema
->valid());
662 for (auto it
= schema
->GetPropertiesIterator(); !it
.IsAtEnd(); it
.Advance()) {
663 std::string key
= it
.key();
664 if (key
.find("RemoteAccessHost") == std::string::npos
) {
665 // For now PolicyWatcher::GetPolicySchema() mixes Chrome and Chromoting
666 // policies, so we have to skip them here.
669 actual_schema
[key
] = it
.schema().type();
672 EXPECT_THAT(actual_schema
, testing::ContainerEq(expected_schema
));
675 TEST_F(PolicyWatcherTest
, SchemaTypeCheck
) {
676 const policy::Schema
* schema
= GetPolicySchema();
677 ASSERT_TRUE(schema
->valid());
679 // Check one, random "string" policy to see if the type propagated correctly
680 // from policy_templates.json file.
681 const policy::Schema string_schema
=
682 schema
->GetKnownProperty("RemoteAccessHostDomain");
683 EXPECT_TRUE(string_schema
.valid());
684 EXPECT_EQ(string_schema
.type(), base::Value::Type::TYPE_STRING
);
686 // And check one, random "boolean" policy to see if the type propagated
687 // correctly from policy_templates.json file.
688 const policy::Schema boolean_schema
=
689 schema
->GetKnownProperty("RemoteAccessHostRequireCurtain");
690 EXPECT_TRUE(boolean_schema
.valid());
691 EXPECT_EQ(boolean_schema
.type(), base::Value::Type::TYPE_BOOLEAN
);
694 // Unit tests cannot instantiate PolicyWatcher on ChromeOS
695 // (as this requires running inside a browser process).
700 void OnPolicyUpdatedDumpPolicy(scoped_ptr
<base::DictionaryValue
> policies
) {
701 VLOG(1) << "OnPolicyUpdated callback received the following policies:";
703 for (base::DictionaryValue::Iterator
iter(*policies
); !iter
.IsAtEnd();
705 switch (iter
.value().GetType()) {
706 case base::Value::Type::TYPE_STRING
: {
708 CHECK(iter
.value().GetAsString(&value
));
709 VLOG(1) << iter
.key() << " = "
710 << "string: " << '"' << value
<< '"';
713 case base::Value::Type::TYPE_BOOLEAN
: {
715 CHECK(iter
.value().GetAsBoolean(&value
));
716 VLOG(1) << iter
.key() << " = "
717 << "boolean: " << (value
? "True" : "False");
721 VLOG(1) << iter
.key() << " = "
722 << "unrecognized type";
729 } // anonymous namespace
731 // To dump policy contents, run unit tests with the following flags:
732 // out/Debug/remoting_unittests --gtest_filter=*TestRealChromotingPolicy* -v=1
733 #if defined(ADDRESS_SANITIZER)
734 // http://crbug.com/517918
735 #define MAYBE_TestRealChromotingPolicy DISABLED_TestRealChromotingPolicy
737 #define MAYBE_TestRealChromotingPolicy TestRealChromotingPolicy
739 TEST_F(PolicyWatcherTest
, MAYBE_TestRealChromotingPolicy
) {
740 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner
=
741 base::MessageLoop::current()->task_runner();
742 scoped_ptr
<PolicyWatcher
> policy_watcher(
743 PolicyWatcher::Create(nullptr, task_runner
));
746 base::RunLoop run_loop
;
747 policy_watcher
->StartWatching(base::Bind(OnPolicyUpdatedDumpPolicy
),
748 base::Bind(base::DoNothing
));
749 run_loop
.RunUntilIdle();
752 // Today, the only verification offered by this test is:
753 // - Manual verification of policy values dumped by OnPolicyUpdatedDumpPolicy
754 // - Automated verification that nothing crashed
759 } // namespace remoting