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/synchronization/waitable_event.h"
11 #include "components/policy/core/common/fake_async_policy_loader.h"
12 #include "policy/policy_constants.h"
13 #include "remoting/host/dns_blackhole_checker.h"
14 #include "remoting/host/policy_watcher.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
20 MATCHER_P(IsPolicies
, dict
, "") {
21 bool equal
= arg
->Equals(dict
);
23 std::string actual_value
;
24 base::JSONWriter::WriteWithOptions(
25 arg
, base::JSONWriter::OPTIONS_PRETTY_PRINT
, &actual_value
);
27 std::string expected_value
;
28 base::JSONWriter::WriteWithOptions(
29 dict
, base::JSONWriter::OPTIONS_PRETTY_PRINT
, &expected_value
);
31 *result_listener
<< "Policies are not equal. ";
32 *result_listener
<< "Expected policy: " << expected_value
<< ". ";
33 *result_listener
<< "Actual policy: " << actual_value
<< ".";
38 class MockPolicyCallback
{
40 MockPolicyCallback(){};
42 // TODO(lukasza): gmock cannot mock a method taking scoped_ptr<T>...
43 MOCK_METHOD1(OnPolicyUpdatePtr
, void(const base::DictionaryValue
* policies
));
44 void OnPolicyUpdate(scoped_ptr
<base::DictionaryValue
> policies
) {
45 OnPolicyUpdatePtr(policies
.get());
48 MOCK_METHOD0(OnPolicyError
, void());
51 DISALLOW_COPY_AND_ASSIGN(MockPolicyCallback
);
54 class PolicyWatcherTest
: public testing::Test
{
56 PolicyWatcherTest() : message_loop_(base::MessageLoop::TYPE_IO
) {}
58 void SetUp() override
{
59 message_loop_proxy_
= base::MessageLoopProxy::current();
61 // Retaining a raw pointer to keep control over policy contents.
62 policy_loader_
= new policy::FakeAsyncPolicyLoader(message_loop_proxy_
);
64 PolicyWatcher::CreateFromPolicyLoader(make_scoped_ptr(policy_loader_
));
66 nat_true_
.SetBoolean(policy::key::kRemoteAccessHostFirewallTraversal
, true);
67 nat_false_
.SetBoolean(policy::key::kRemoteAccessHostFirewallTraversal
,
69 nat_one_
.SetInteger(policy::key::kRemoteAccessHostFirewallTraversal
, 1);
70 domain_empty_
.SetString(policy::key::kRemoteAccessHostDomain
,
72 domain_full_
.SetString(policy::key::kRemoteAccessHostDomain
, kHostDomain
);
73 SetDefaults(nat_true_others_default_
);
74 nat_true_others_default_
.SetBoolean(
75 policy::key::kRemoteAccessHostFirewallTraversal
, true);
76 SetDefaults(nat_false_others_default_
);
77 nat_false_others_default_
.SetBoolean(
78 policy::key::kRemoteAccessHostFirewallTraversal
, false);
79 SetDefaults(domain_empty_others_default_
);
80 domain_empty_others_default_
.SetString(policy::key::kRemoteAccessHostDomain
,
82 SetDefaults(domain_full_others_default_
);
83 domain_full_others_default_
.SetString(policy::key::kRemoteAccessHostDomain
,
85 nat_true_domain_empty_
.SetBoolean(
86 policy::key::kRemoteAccessHostFirewallTraversal
, true);
87 nat_true_domain_empty_
.SetString(policy::key::kRemoteAccessHostDomain
,
89 nat_true_domain_full_
.SetBoolean(
90 policy::key::kRemoteAccessHostFirewallTraversal
, true);
91 nat_true_domain_full_
.SetString(policy::key::kRemoteAccessHostDomain
,
93 nat_false_domain_empty_
.SetBoolean(
94 policy::key::kRemoteAccessHostFirewallTraversal
, false);
95 nat_false_domain_empty_
.SetString(policy::key::kRemoteAccessHostDomain
,
97 nat_false_domain_full_
.SetBoolean(
98 policy::key::kRemoteAccessHostFirewallTraversal
, false);
99 nat_false_domain_full_
.SetString(policy::key::kRemoteAccessHostDomain
,
101 SetDefaults(nat_true_domain_empty_others_default_
);
102 nat_true_domain_empty_others_default_
.SetBoolean(
103 policy::key::kRemoteAccessHostFirewallTraversal
, true);
104 nat_true_domain_empty_others_default_
.SetString(
105 policy::key::kRemoteAccessHostDomain
, std::string());
106 unknown_policies_
.SetString("UnknownPolicyOne", std::string());
107 unknown_policies_
.SetString("UnknownPolicyTwo", std::string());
108 unknown_policies_
.SetBoolean("RemoteAccessHostUnknownPolicyThree", true);
110 const char kOverrideNatTraversalToFalse
[] =
111 "{ \"RemoteAccessHostFirewallTraversal\": false }";
112 nat_true_and_overridden_
.SetBoolean(
113 policy::key::kRemoteAccessHostFirewallTraversal
, true);
114 nat_true_and_overridden_
.SetString(
115 policy::key::kRemoteAccessHostDebugOverridePolicies
,
116 kOverrideNatTraversalToFalse
);
117 pairing_true_
.SetBoolean(policy::key::kRemoteAccessHostAllowClientPairing
,
119 pairing_false_
.SetBoolean(policy::key::kRemoteAccessHostAllowClientPairing
,
121 gnubby_auth_true_
.SetBoolean(policy::key::kRemoteAccessHostAllowGnubbyAuth
,
123 gnubby_auth_false_
.SetBoolean(policy::key::kRemoteAccessHostAllowGnubbyAuth
,
125 relay_true_
.SetBoolean(policy::key::kRemoteAccessHostAllowRelayedConnection
,
127 relay_false_
.SetBoolean(
128 policy::key::kRemoteAccessHostAllowRelayedConnection
, false);
129 port_range_full_
.SetString(policy::key::kRemoteAccessHostUdpPortRange
,
131 port_range_empty_
.SetString(policy::key::kRemoteAccessHostUdpPortRange
,
133 curtain_true_
.SetBoolean(policy::key::kRemoteAccessHostRequireCurtain
,
135 curtain_false_
.SetBoolean(policy::key::kRemoteAccessHostRequireCurtain
,
137 username_true_
.SetBoolean(policy::key::kRemoteAccessHostMatchUsername
,
139 username_false_
.SetBoolean(policy::key::kRemoteAccessHostMatchUsername
,
141 talk_gadget_blah_
.SetString(policy::key::kRemoteAccessHostTalkGadgetPrefix
,
143 token_url_https_
.SetString(policy::key::kRemoteAccessHostTalkGadgetPrefix
,
144 "https://example.com");
145 token_validation_url_https_
.SetString(
146 policy::key::kRemoteAccessHostTalkGadgetPrefix
, "https://example.com");
147 token_certificate_blah_
.SetString(
148 policy::key::kRemoteAccessHostTokenValidationCertificateIssuer
, "blah");
151 SetDefaults(nat_false_overridden_others_default_
);
152 nat_false_overridden_others_default_
.SetBoolean(
153 policy::key::kRemoteAccessHostFirewallTraversal
, false);
154 nat_false_overridden_others_default_
.SetString(
155 policy::key::kRemoteAccessHostDebugOverridePolicies
,
156 kOverrideNatTraversalToFalse
);
160 void TearDown() override
{
161 policy_watcher_
.reset();
162 policy_loader_
= nullptr;
163 base::RunLoop().RunUntilIdle();
167 void StartWatching() {
168 policy_watcher_
->StartWatching(
169 base::Bind(&MockPolicyCallback::OnPolicyUpdate
,
170 base::Unretained(&mock_policy_callback_
)),
171 base::Bind(&MockPolicyCallback::OnPolicyError
,
172 base::Unretained(&mock_policy_callback_
)));
173 base::RunLoop().RunUntilIdle();
176 void SetPolicies(const base::DictionaryValue
& dict
) {
177 // Copy |dict| into |policy_bundle|.
178 policy::PolicyNamespace policy_namespace
=
179 policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME
, std::string());
180 policy::PolicyBundle policy_bundle
;
181 policy::PolicyMap
& policy_map
= policy_bundle
.Get(policy_namespace
);
182 policy_map
.LoadFrom(&dict
, policy::POLICY_LEVEL_MANDATORY
,
183 policy::POLICY_SCOPE_MACHINE
);
185 // Simulate a policy file/registry/preference update.
186 policy_loader_
->SetPolicies(policy_bundle
);
187 policy_loader_
->PostReloadOnBackgroundThread(true /* force reload asap */);
188 base::RunLoop().RunUntilIdle();
191 const policy::Schema
* GetPolicySchema() {
192 return policy_watcher_
->GetPolicySchema();
195 const base::DictionaryValue
& GetDefaultValues() {
196 return *(policy_watcher_
->default_values_
);
199 MOCK_METHOD0(PostPolicyWatcherShutdown
, void());
201 static const char* kHostDomain
;
202 static const char* kPortRange
;
203 base::MessageLoop message_loop_
;
204 scoped_refptr
<base::MessageLoopProxy
> message_loop_proxy_
;
205 MockPolicyCallback mock_policy_callback_
;
207 // |policy_loader_| is owned by |policy_watcher_|. PolicyWatcherTest retains
208 // a raw pointer to |policy_loader_| in order to control the simulated / faked
210 policy::FakeAsyncPolicyLoader
* policy_loader_
;
211 scoped_ptr
<PolicyWatcher
> policy_watcher_
;
213 base::DictionaryValue empty_
;
214 base::DictionaryValue nat_true_
;
215 base::DictionaryValue nat_false_
;
216 base::DictionaryValue nat_one_
;
217 base::DictionaryValue domain_empty_
;
218 base::DictionaryValue domain_full_
;
219 base::DictionaryValue nat_true_others_default_
;
220 base::DictionaryValue nat_false_others_default_
;
221 base::DictionaryValue domain_empty_others_default_
;
222 base::DictionaryValue domain_full_others_default_
;
223 base::DictionaryValue nat_true_domain_empty_
;
224 base::DictionaryValue nat_true_domain_full_
;
225 base::DictionaryValue nat_false_domain_empty_
;
226 base::DictionaryValue nat_false_domain_full_
;
227 base::DictionaryValue nat_true_domain_empty_others_default_
;
228 base::DictionaryValue unknown_policies_
;
229 base::DictionaryValue nat_true_and_overridden_
;
230 base::DictionaryValue nat_false_overridden_others_default_
;
231 base::DictionaryValue pairing_true_
;
232 base::DictionaryValue pairing_false_
;
233 base::DictionaryValue gnubby_auth_true_
;
234 base::DictionaryValue gnubby_auth_false_
;
235 base::DictionaryValue relay_true_
;
236 base::DictionaryValue relay_false_
;
237 base::DictionaryValue port_range_full_
;
238 base::DictionaryValue port_range_empty_
;
239 base::DictionaryValue curtain_true_
;
240 base::DictionaryValue curtain_false_
;
241 base::DictionaryValue username_true_
;
242 base::DictionaryValue username_false_
;
243 base::DictionaryValue talk_gadget_blah_
;
244 base::DictionaryValue token_url_https_
;
245 base::DictionaryValue token_validation_url_https_
;
246 base::DictionaryValue token_certificate_blah_
;
249 void SetDefaults(base::DictionaryValue
& dict
) {
250 dict
.SetBoolean(policy::key::kRemoteAccessHostFirewallTraversal
, true);
251 dict
.SetBoolean(policy::key::kRemoteAccessHostAllowRelayedConnection
, true);
252 dict
.SetString(policy::key::kRemoteAccessHostUdpPortRange
, "");
253 dict
.SetString(policy::key::kRemoteAccessHostDomain
, std::string());
254 dict
.SetBoolean(policy::key::kRemoteAccessHostMatchUsername
, false);
255 dict
.SetString(policy::key::kRemoteAccessHostTalkGadgetPrefix
,
256 kDefaultHostTalkGadgetPrefix
);
257 dict
.SetBoolean(policy::key::kRemoteAccessHostRequireCurtain
, false);
258 dict
.SetString(policy::key::kRemoteAccessHostTokenUrl
, std::string());
259 dict
.SetString(policy::key::kRemoteAccessHostTokenValidationUrl
,
262 policy::key::kRemoteAccessHostTokenValidationCertificateIssuer
,
264 dict
.SetBoolean(policy::key::kRemoteAccessHostAllowClientPairing
, true);
265 dict
.SetBoolean(policy::key::kRemoteAccessHostAllowGnubbyAuth
, true);
267 dict
.SetString(policy::key::kRemoteAccessHostDebugOverridePolicies
, "");
270 ASSERT_THAT(&dict
, IsPolicies(&GetDefaultValues()))
271 << "Sanity check that defaults expected by the test code "
272 << "match what is stored in PolicyWatcher::default_values_";
276 const char* PolicyWatcherTest::kHostDomain
= "google.com";
277 const char* PolicyWatcherTest::kPortRange
= "12400-12409";
279 TEST_F(PolicyWatcherTest
, None
) {
280 EXPECT_CALL(mock_policy_callback_
,
281 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
287 TEST_F(PolicyWatcherTest
, NatTrue
) {
288 EXPECT_CALL(mock_policy_callback_
,
289 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
291 SetPolicies(nat_true_
);
295 TEST_F(PolicyWatcherTest
, NatFalse
) {
296 EXPECT_CALL(mock_policy_callback_
,
297 OnPolicyUpdatePtr(IsPolicies(&nat_false_others_default_
)));
299 SetPolicies(nat_false_
);
303 TEST_F(PolicyWatcherTest
, NatWrongType
) {
304 EXPECT_CALL(mock_policy_callback_
, OnPolicyError());
306 SetPolicies(nat_one_
);
310 TEST_F(PolicyWatcherTest
, DomainEmpty
) {
311 EXPECT_CALL(mock_policy_callback_
,
312 OnPolicyUpdatePtr(IsPolicies(&domain_empty_others_default_
)));
314 SetPolicies(domain_empty_
);
318 TEST_F(PolicyWatcherTest
, DomainFull
) {
319 EXPECT_CALL(mock_policy_callback_
,
320 OnPolicyUpdatePtr(IsPolicies(&domain_full_others_default_
)));
322 SetPolicies(domain_full_
);
326 TEST_F(PolicyWatcherTest
, NatNoneThenTrue
) {
327 EXPECT_CALL(mock_policy_callback_
,
328 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
332 SetPolicies(nat_true_
);
335 TEST_F(PolicyWatcherTest
, NatNoneThenTrueThenTrue
) {
336 EXPECT_CALL(mock_policy_callback_
,
337 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
341 SetPolicies(nat_true_
);
342 SetPolicies(nat_true_
);
345 TEST_F(PolicyWatcherTest
, NatNoneThenTrueThenTrueThenFalse
) {
346 testing::InSequence sequence
;
347 EXPECT_CALL(mock_policy_callback_
,
348 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
349 EXPECT_CALL(mock_policy_callback_
,
350 OnPolicyUpdatePtr(IsPolicies(&nat_false_
)));
354 SetPolicies(nat_true_
);
355 SetPolicies(nat_true_
);
356 SetPolicies(nat_false_
);
359 TEST_F(PolicyWatcherTest
, NatNoneThenFalse
) {
360 testing::InSequence sequence
;
361 EXPECT_CALL(mock_policy_callback_
,
362 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
363 EXPECT_CALL(mock_policy_callback_
,
364 OnPolicyUpdatePtr(IsPolicies(&nat_false_
)));
368 SetPolicies(nat_false_
);
371 TEST_F(PolicyWatcherTest
, NatNoneThenFalseThenTrue
) {
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_
)));
377 EXPECT_CALL(mock_policy_callback_
, OnPolicyUpdatePtr(IsPolicies(&nat_true_
)));
381 SetPolicies(nat_false_
);
382 SetPolicies(nat_true_
);
385 TEST_F(PolicyWatcherTest
, ChangeOneRepeatedlyThenTwo
) {
386 testing::InSequence sequence
;
388 mock_policy_callback_
,
389 OnPolicyUpdatePtr(IsPolicies(&nat_true_domain_empty_others_default_
)));
390 EXPECT_CALL(mock_policy_callback_
,
391 OnPolicyUpdatePtr(IsPolicies(&domain_full_
)));
392 EXPECT_CALL(mock_policy_callback_
,
393 OnPolicyUpdatePtr(IsPolicies(&nat_false_
)));
394 EXPECT_CALL(mock_policy_callback_
,
395 OnPolicyUpdatePtr(IsPolicies(&domain_empty_
)));
396 EXPECT_CALL(mock_policy_callback_
,
397 OnPolicyUpdatePtr(IsPolicies(&nat_true_domain_full_
)));
399 SetPolicies(nat_true_domain_empty_
);
401 SetPolicies(nat_true_domain_full_
);
402 SetPolicies(nat_false_domain_full_
);
403 SetPolicies(nat_false_domain_empty_
);
404 SetPolicies(nat_true_domain_full_
);
407 TEST_F(PolicyWatcherTest
, FilterUnknownPolicies
) {
408 testing::InSequence sequence
;
409 EXPECT_CALL(mock_policy_callback_
,
410 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
414 SetPolicies(unknown_policies_
);
418 TEST_F(PolicyWatcherTest
, DebugOverrideNatPolicy
) {
421 mock_policy_callback_
,
422 OnPolicyUpdatePtr(IsPolicies(&nat_false_overridden_others_default_
)));
424 EXPECT_CALL(mock_policy_callback_
,
425 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
428 SetPolicies(nat_true_and_overridden_
);
432 TEST_F(PolicyWatcherTest
, PairingFalseThenTrue
) {
433 testing::InSequence sequence
;
434 EXPECT_CALL(mock_policy_callback_
,
435 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
436 EXPECT_CALL(mock_policy_callback_
,
437 OnPolicyUpdatePtr(IsPolicies(&pairing_false_
)));
438 EXPECT_CALL(mock_policy_callback_
,
439 OnPolicyUpdatePtr(IsPolicies(&pairing_true_
)));
443 SetPolicies(pairing_false_
);
444 SetPolicies(pairing_true_
);
447 TEST_F(PolicyWatcherTest
, GnubbyAuth
) {
448 testing::InSequence sequence
;
449 EXPECT_CALL(mock_policy_callback_
,
450 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
451 EXPECT_CALL(mock_policy_callback_
,
452 OnPolicyUpdatePtr(IsPolicies(&gnubby_auth_false_
)));
453 EXPECT_CALL(mock_policy_callback_
,
454 OnPolicyUpdatePtr(IsPolicies(&gnubby_auth_true_
)));
458 SetPolicies(gnubby_auth_false_
);
459 SetPolicies(gnubby_auth_true_
);
462 TEST_F(PolicyWatcherTest
, Relay
) {
463 testing::InSequence sequence
;
464 EXPECT_CALL(mock_policy_callback_
,
465 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
466 EXPECT_CALL(mock_policy_callback_
,
467 OnPolicyUpdatePtr(IsPolicies(&relay_false_
)));
468 EXPECT_CALL(mock_policy_callback_
,
469 OnPolicyUpdatePtr(IsPolicies(&relay_true_
)));
473 SetPolicies(relay_false_
);
474 SetPolicies(relay_true_
);
477 TEST_F(PolicyWatcherTest
, Curtain
) {
478 testing::InSequence sequence
;
479 EXPECT_CALL(mock_policy_callback_
,
480 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
481 EXPECT_CALL(mock_policy_callback_
,
482 OnPolicyUpdatePtr(IsPolicies(&curtain_true_
)));
483 EXPECT_CALL(mock_policy_callback_
,
484 OnPolicyUpdatePtr(IsPolicies(&curtain_false_
)));
488 SetPolicies(curtain_true_
);
489 SetPolicies(curtain_false_
);
492 TEST_F(PolicyWatcherTest
, MatchUsername
) {
493 testing::InSequence sequence
;
494 EXPECT_CALL(mock_policy_callback_
,
495 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
497 EXPECT_CALL(mock_policy_callback_
,
498 OnPolicyUpdatePtr(IsPolicies(&username_true_
)));
499 EXPECT_CALL(mock_policy_callback_
,
500 OnPolicyUpdatePtr(IsPolicies(&username_false_
)));
502 // On Windows the MatchUsername policy is ignored and therefore the 2
503 // SetPolicies calls won't result in any calls to OnPolicyUpdate.
508 SetPolicies(username_true_
);
509 SetPolicies(username_false_
);
512 TEST_F(PolicyWatcherTest
, TalkGadgetPrefix
) {
513 testing::InSequence sequence
;
514 EXPECT_CALL(mock_policy_callback_
,
515 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
516 EXPECT_CALL(mock_policy_callback_
,
517 OnPolicyUpdatePtr(IsPolicies(&talk_gadget_blah_
)));
521 SetPolicies(talk_gadget_blah_
);
524 TEST_F(PolicyWatcherTest
, TokenUrl
) {
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(&token_url_https_
)));
533 SetPolicies(token_url_https_
);
536 TEST_F(PolicyWatcherTest
, TokenValidationUrl
) {
537 testing::InSequence sequence
;
538 EXPECT_CALL(mock_policy_callback_
,
539 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
540 EXPECT_CALL(mock_policy_callback_
,
541 OnPolicyUpdatePtr(IsPolicies(&token_validation_url_https_
)));
545 SetPolicies(token_validation_url_https_
);
548 TEST_F(PolicyWatcherTest
, TokenValidationCertificateIssuer
) {
549 testing::InSequence sequence
;
550 EXPECT_CALL(mock_policy_callback_
,
551 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
552 EXPECT_CALL(mock_policy_callback_
,
553 OnPolicyUpdatePtr(IsPolicies(&token_certificate_blah_
)));
557 SetPolicies(token_certificate_blah_
);
560 TEST_F(PolicyWatcherTest
, UdpPortRange
) {
561 testing::InSequence sequence
;
562 EXPECT_CALL(mock_policy_callback_
,
563 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_
)));
564 EXPECT_CALL(mock_policy_callback_
,
565 OnPolicyUpdatePtr(IsPolicies(&port_range_full_
)));
566 EXPECT_CALL(mock_policy_callback_
,
567 OnPolicyUpdatePtr(IsPolicies(&port_range_empty_
)));
571 SetPolicies(port_range_full_
);
572 SetPolicies(port_range_empty_
);
575 TEST_F(PolicyWatcherTest
, PolicySchemaAndPolicyWatcherShouldBeInSync
) {
576 // This test verifies that
577 // 1) policy schema (generated out of policy_templates.json)
579 // 2) PolicyWatcher's code (i.e. contents of the |default_values_| field)
582 std::map
<std::string
, base::Value::Type
> expected_schema
;
583 for (base::DictionaryValue::Iterator
i(GetDefaultValues()); !i
.IsAtEnd();
585 expected_schema
[i
.key()] = i
.value().GetType();
588 // RemoteAccessHostMatchUsername is marked in policy_templates.json as not
589 // supported on Windows and therefore is (by design) excluded from the schema.
590 expected_schema
.erase(policy::key::kRemoteAccessHostMatchUsername
);
593 // Policy schema / policy_templates.json cannot differ between debug and
594 // release builds so we compensate below to account for the fact that
595 // PolicyWatcher::default_values_ does differ between debug and release.
596 expected_schema
[policy::key::kRemoteAccessHostDebugOverridePolicies
] =
597 base::Value::TYPE_STRING
;
600 std::map
<std::string
, base::Value::Type
> actual_schema
;
601 const policy::Schema
* schema
= GetPolicySchema();
602 ASSERT_TRUE(schema
->valid());
603 for (auto it
= schema
->GetPropertiesIterator(); !it
.IsAtEnd(); it
.Advance()) {
604 std::string key
= it
.key();
605 if (key
.find("RemoteAccessHost") == std::string::npos
) {
606 // For now PolicyWatcher::GetPolicySchema() mixes Chrome and Chromoting
607 // policies, so we have to skip them here.
610 actual_schema
[key
] = it
.schema().type();
613 EXPECT_THAT(actual_schema
, testing::ContainerEq(expected_schema
));
616 TEST_F(PolicyWatcherTest
, SchemaTypeCheck
) {
617 const policy::Schema
* schema
= GetPolicySchema();
618 ASSERT_TRUE(schema
->valid());
620 // Check one, random "string" policy to see if the type propagated correctly
621 // from policy_templates.json file.
622 const policy::Schema string_schema
=
623 schema
->GetKnownProperty("RemoteAccessHostDomain");
624 EXPECT_TRUE(string_schema
.valid());
625 EXPECT_EQ(string_schema
.type(), base::Value::Type::TYPE_STRING
);
627 // And check one, random "boolean" policy to see if the type propagated
628 // correctly from policy_templates.json file.
629 const policy::Schema boolean_schema
=
630 schema
->GetKnownProperty("RemoteAccessHostRequireCurtain");
631 EXPECT_TRUE(boolean_schema
.valid());
632 EXPECT_EQ(boolean_schema
.type(), base::Value::Type::TYPE_BOOLEAN
);
635 // Unit tests cannot instantiate PolicyWatcher on ChromeOS
636 // (as this requires running inside a browser process).
641 void OnPolicyUpdatedDumpPolicy(scoped_ptr
<base::DictionaryValue
> policies
) {
642 VLOG(1) << "OnPolicyUpdated callback received the following policies:";
644 for (base::DictionaryValue::Iterator
iter(*policies
); !iter
.IsAtEnd();
646 switch (iter
.value().GetType()) {
647 case base::Value::Type::TYPE_STRING
: {
649 CHECK(iter
.value().GetAsString(&value
));
650 VLOG(1) << iter
.key() << " = "
651 << "string: " << '"' << value
<< '"';
654 case base::Value::Type::TYPE_BOOLEAN
: {
656 CHECK(iter
.value().GetAsBoolean(&value
));
657 VLOG(1) << iter
.key() << " = "
658 << "boolean: " << (value
? "True" : "False");
662 VLOG(1) << iter
.key() << " = "
663 << "unrecognized type";
670 } // anonymous namespace
672 // To dump policy contents, run unit tests with the following flags:
673 // out/Debug/remoting_unittests --gtest_filter=*TestRealChromotingPolicy* -v=1
674 TEST_F(PolicyWatcherTest
, TestRealChromotingPolicy
) {
675 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner
=
676 base::MessageLoop::current()->task_runner();
677 scoped_ptr
<PolicyWatcher
> policy_watcher(
678 PolicyWatcher::Create(nullptr, task_runner
));
681 base::RunLoop run_loop
;
682 policy_watcher
->StartWatching(base::Bind(OnPolicyUpdatedDumpPolicy
),
683 base::Bind(base::DoNothing
));
684 run_loop
.RunUntilIdle();
687 // Today, the only verification offered by this test is:
688 // - Manual verification of policy values dumped by OnPolicyUpdatedDumpPolicy
689 // - Automated verification that nothing crashed
694 } // namespace remoting