Infer appropriate GNU_STACK alignment for a shared library.
[chromium-blink-merge.git] / remoting / host / policy_watcher_unittest.cc
blob850048c7b12fa99c5421fb7cb12a27f6289de8e1
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/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"
18 namespace remoting {
20 class MockPolicyCallback {
21 public:
22 MockPolicyCallback(){};
24 // TODO(lukasza): gmock cannot mock a method taking scoped_ptr<T>...
25 MOCK_METHOD1(OnPolicyUpdatePtr, void(const base::DictionaryValue* policies));
26 void OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies) {
27 OnPolicyUpdatePtr(policies.get());
30 MOCK_METHOD0(OnPolicyError, void());
32 private:
33 DISALLOW_COPY_AND_ASSIGN(MockPolicyCallback);
36 class PolicyWatcherTest : public testing::Test {
37 public:
38 PolicyWatcherTest() : message_loop_(base::MessageLoop::TYPE_IO) {}
40 void SetUp() override {
41 message_loop_proxy_ = base::MessageLoopProxy::current();
43 // Retaining a raw pointer to keep control over policy contents.
44 policy_loader_ = new policy::FakeAsyncPolicyLoader(message_loop_proxy_);
45 policy_watcher_ =
46 PolicyWatcher::CreateFromPolicyLoader(make_scoped_ptr(policy_loader_));
48 nat_true_.SetBoolean(policy::key::kRemoteAccessHostFirewallTraversal, true);
49 nat_false_.SetBoolean(policy::key::kRemoteAccessHostFirewallTraversal,
50 false);
51 nat_one_.SetInteger(policy::key::kRemoteAccessHostFirewallTraversal, 1);
52 domain_empty_.SetString(policy::key::kRemoteAccessHostDomain,
53 std::string());
54 domain_full_.SetString(policy::key::kRemoteAccessHostDomain, kHostDomain);
55 SetDefaults(nat_true_others_default_);
56 nat_true_others_default_.SetBoolean(
57 policy::key::kRemoteAccessHostFirewallTraversal, true);
58 SetDefaults(nat_false_others_default_);
59 nat_false_others_default_.SetBoolean(
60 policy::key::kRemoteAccessHostFirewallTraversal, false);
61 SetDefaults(domain_empty_others_default_);
62 domain_empty_others_default_.SetString(policy::key::kRemoteAccessHostDomain,
63 std::string());
64 SetDefaults(domain_full_others_default_);
65 domain_full_others_default_.SetString(policy::key::kRemoteAccessHostDomain,
66 kHostDomain);
67 nat_true_domain_empty_.SetBoolean(
68 policy::key::kRemoteAccessHostFirewallTraversal, true);
69 nat_true_domain_empty_.SetString(policy::key::kRemoteAccessHostDomain,
70 std::string());
71 nat_true_domain_full_.SetBoolean(
72 policy::key::kRemoteAccessHostFirewallTraversal, true);
73 nat_true_domain_full_.SetString(policy::key::kRemoteAccessHostDomain,
74 kHostDomain);
75 nat_false_domain_empty_.SetBoolean(
76 policy::key::kRemoteAccessHostFirewallTraversal, false);
77 nat_false_domain_empty_.SetString(policy::key::kRemoteAccessHostDomain,
78 std::string());
79 nat_false_domain_full_.SetBoolean(
80 policy::key::kRemoteAccessHostFirewallTraversal, false);
81 nat_false_domain_full_.SetString(policy::key::kRemoteAccessHostDomain,
82 kHostDomain);
83 SetDefaults(nat_true_domain_empty_others_default_);
84 nat_true_domain_empty_others_default_.SetBoolean(
85 policy::key::kRemoteAccessHostFirewallTraversal, true);
86 nat_true_domain_empty_others_default_.SetString(
87 policy::key::kRemoteAccessHostDomain, std::string());
88 unknown_policies_.SetString("UnknownPolicyOne", std::string());
89 unknown_policies_.SetString("UnknownPolicyTwo", std::string());
91 const char kOverrideNatTraversalToFalse[] =
92 "{ \"RemoteAccessHostFirewallTraversal\": false }";
93 nat_true_and_overridden_.SetBoolean(
94 policy::key::kRemoteAccessHostFirewallTraversal, true);
95 nat_true_and_overridden_.SetString(
96 policy::key::kRemoteAccessHostDebugOverridePolicies,
97 kOverrideNatTraversalToFalse);
98 pairing_true_.SetBoolean(policy::key::kRemoteAccessHostAllowClientPairing,
99 true);
100 pairing_false_.SetBoolean(policy::key::kRemoteAccessHostAllowClientPairing,
101 false);
102 gnubby_auth_true_.SetBoolean(policy::key::kRemoteAccessHostAllowGnubbyAuth,
103 true);
104 gnubby_auth_false_.SetBoolean(policy::key::kRemoteAccessHostAllowGnubbyAuth,
105 false);
106 relay_true_.SetBoolean(policy::key::kRemoteAccessHostAllowRelayedConnection,
107 true);
108 relay_false_.SetBoolean(
109 policy::key::kRemoteAccessHostAllowRelayedConnection, false);
110 port_range_full_.SetString(policy::key::kRemoteAccessHostUdpPortRange,
111 kPortRange);
112 port_range_empty_.SetString(policy::key::kRemoteAccessHostUdpPortRange,
113 std::string());
115 #if !defined(NDEBUG)
116 SetDefaults(nat_false_overridden_others_default_);
117 nat_false_overridden_others_default_.SetBoolean(
118 policy::key::kRemoteAccessHostFirewallTraversal, false);
119 nat_false_overridden_others_default_.SetString(
120 policy::key::kRemoteAccessHostDebugOverridePolicies,
121 kOverrideNatTraversalToFalse);
122 #endif
125 void TearDown() override {
126 policy_watcher_.reset();
127 policy_loader_ = nullptr;
128 base::RunLoop().RunUntilIdle();
131 protected:
132 void StartWatching() {
133 policy_watcher_->StartWatching(
134 base::Bind(&MockPolicyCallback::OnPolicyUpdate,
135 base::Unretained(&mock_policy_callback_)),
136 base::Bind(&MockPolicyCallback::OnPolicyError,
137 base::Unretained(&mock_policy_callback_)));
138 base::RunLoop().RunUntilIdle();
141 void SetPolicies(const base::DictionaryValue& dict) {
142 // Copy |dict| into |policy_bundle|.
143 policy::PolicyNamespace policy_namespace =
144 policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string());
145 policy::PolicyBundle policy_bundle;
146 policy::PolicyMap& policy_map = policy_bundle.Get(policy_namespace);
147 policy_map.LoadFrom(&dict, policy::POLICY_LEVEL_MANDATORY,
148 policy::POLICY_SCOPE_MACHINE);
150 // Simulate a policy file/registry/preference update.
151 policy_loader_->SetPolicies(policy_bundle);
152 policy_loader_->PostReloadOnBackgroundThread(true /* force reload asap */);
153 base::RunLoop().RunUntilIdle();
156 void SignalTransientErrorForTest() {
157 policy_watcher_->SignalTransientPolicyError();
160 MOCK_METHOD0(PostPolicyWatcherShutdown, void());
162 static const char* kHostDomain;
163 static const char* kPortRange;
164 base::MessageLoop message_loop_;
165 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
166 MockPolicyCallback mock_policy_callback_;
168 // |policy_loader_| is owned by |policy_watcher_|. PolicyWatcherTest retains
169 // a raw pointer to |policy_loader_| in order to control the simulated / faked
170 // policy contents.
171 policy::FakeAsyncPolicyLoader* policy_loader_;
172 scoped_ptr<PolicyWatcher> policy_watcher_;
174 base::DictionaryValue empty_;
175 base::DictionaryValue nat_true_;
176 base::DictionaryValue nat_false_;
177 base::DictionaryValue nat_one_;
178 base::DictionaryValue domain_empty_;
179 base::DictionaryValue domain_full_;
180 base::DictionaryValue nat_true_others_default_;
181 base::DictionaryValue nat_false_others_default_;
182 base::DictionaryValue domain_empty_others_default_;
183 base::DictionaryValue domain_full_others_default_;
184 base::DictionaryValue nat_true_domain_empty_;
185 base::DictionaryValue nat_true_domain_full_;
186 base::DictionaryValue nat_false_domain_empty_;
187 base::DictionaryValue nat_false_domain_full_;
188 base::DictionaryValue nat_true_domain_empty_others_default_;
189 base::DictionaryValue unknown_policies_;
190 base::DictionaryValue nat_true_and_overridden_;
191 base::DictionaryValue nat_false_overridden_others_default_;
192 base::DictionaryValue pairing_true_;
193 base::DictionaryValue pairing_false_;
194 base::DictionaryValue gnubby_auth_true_;
195 base::DictionaryValue gnubby_auth_false_;
196 base::DictionaryValue relay_true_;
197 base::DictionaryValue relay_false_;
198 base::DictionaryValue port_range_full_;
199 base::DictionaryValue port_range_empty_;
201 private:
202 void SetDefaults(base::DictionaryValue& dict) {
203 dict.SetBoolean(policy::key::kRemoteAccessHostFirewallTraversal, true);
204 dict.SetBoolean(policy::key::kRemoteAccessHostAllowRelayedConnection, true);
205 dict.SetString(policy::key::kRemoteAccessHostUdpPortRange, "");
206 dict.SetBoolean(policy::key::kRemoteAccessHostRequireTwoFactor, false);
207 dict.SetString(policy::key::kRemoteAccessHostDomain, std::string());
208 dict.SetBoolean(policy::key::kRemoteAccessHostMatchUsername, false);
209 dict.SetString(policy::key::kRemoteAccessHostTalkGadgetPrefix,
210 kDefaultHostTalkGadgetPrefix);
211 dict.SetBoolean(policy::key::kRemoteAccessHostRequireCurtain, false);
212 dict.SetString(policy::key::kRemoteAccessHostTokenUrl, std::string());
213 dict.SetString(policy::key::kRemoteAccessHostTokenValidationUrl,
214 std::string());
215 dict.SetString(
216 policy::key::kRemoteAccessHostTokenValidationCertificateIssuer,
217 std::string());
218 dict.SetBoolean(policy::key::kRemoteAccessHostAllowClientPairing, true);
219 dict.SetBoolean(policy::key::kRemoteAccessHostAllowGnubbyAuth, true);
220 #if !defined(NDEBUG)
221 dict.SetString(policy::key::kRemoteAccessHostDebugOverridePolicies, "");
222 #endif
226 const char* PolicyWatcherTest::kHostDomain = "google.com";
227 const char* PolicyWatcherTest::kPortRange = "12400-12409";
229 MATCHER_P(IsPolicies, dict, "") {
230 bool equal = arg->Equals(dict);
231 if (!equal) {
232 std::string actual_value;
233 base::JSONWriter::WriteWithOptions(
234 arg, base::JSONWriter::OPTIONS_PRETTY_PRINT, &actual_value);
236 std::string expected_value;
237 base::JSONWriter::WriteWithOptions(
238 dict, base::JSONWriter::OPTIONS_PRETTY_PRINT, &expected_value);
240 *result_listener << "Policies are not equal. ";
241 *result_listener << "Expected policy: " << expected_value << ". ";
242 *result_listener << "Actual policy: " << actual_value << ".";
244 return equal;
247 TEST_F(PolicyWatcherTest, None) {
248 EXPECT_CALL(mock_policy_callback_,
249 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
251 SetPolicies(empty_);
252 StartWatching();
255 TEST_F(PolicyWatcherTest, NatTrue) {
256 EXPECT_CALL(mock_policy_callback_,
257 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
259 SetPolicies(nat_true_);
260 StartWatching();
263 TEST_F(PolicyWatcherTest, NatFalse) {
264 EXPECT_CALL(mock_policy_callback_,
265 OnPolicyUpdatePtr(IsPolicies(&nat_false_others_default_)));
267 SetPolicies(nat_false_);
268 StartWatching();
271 TEST_F(PolicyWatcherTest, NatOne) {
272 EXPECT_CALL(mock_policy_callback_,
273 OnPolicyUpdatePtr(IsPolicies(&nat_false_others_default_)));
275 SetPolicies(nat_one_);
276 StartWatching();
279 TEST_F(PolicyWatcherTest, DomainEmpty) {
280 EXPECT_CALL(mock_policy_callback_,
281 OnPolicyUpdatePtr(IsPolicies(&domain_empty_others_default_)));
283 SetPolicies(domain_empty_);
284 StartWatching();
287 TEST_F(PolicyWatcherTest, DomainFull) {
288 EXPECT_CALL(mock_policy_callback_,
289 OnPolicyUpdatePtr(IsPolicies(&domain_full_others_default_)));
291 SetPolicies(domain_full_);
292 StartWatching();
295 TEST_F(PolicyWatcherTest, NatNoneThenTrue) {
296 EXPECT_CALL(mock_policy_callback_,
297 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
299 SetPolicies(empty_);
300 StartWatching();
301 SetPolicies(nat_true_);
304 TEST_F(PolicyWatcherTest, NatNoneThenTrueThenTrue) {
305 EXPECT_CALL(mock_policy_callback_,
306 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
308 SetPolicies(empty_);
309 StartWatching();
310 SetPolicies(nat_true_);
311 SetPolicies(nat_true_);
314 TEST_F(PolicyWatcherTest, NatNoneThenTrueThenTrueThenFalse) {
315 testing::InSequence sequence;
316 EXPECT_CALL(mock_policy_callback_,
317 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
318 EXPECT_CALL(mock_policy_callback_,
319 OnPolicyUpdatePtr(IsPolicies(&nat_false_)));
321 SetPolicies(empty_);
322 StartWatching();
323 SetPolicies(nat_true_);
324 SetPolicies(nat_true_);
325 SetPolicies(nat_false_);
328 TEST_F(PolicyWatcherTest, NatNoneThenFalse) {
329 testing::InSequence sequence;
330 EXPECT_CALL(mock_policy_callback_,
331 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
332 EXPECT_CALL(mock_policy_callback_,
333 OnPolicyUpdatePtr(IsPolicies(&nat_false_)));
335 SetPolicies(empty_);
336 StartWatching();
337 SetPolicies(nat_false_);
340 TEST_F(PolicyWatcherTest, NatNoneThenFalseThenTrue) {
341 testing::InSequence sequence;
342 EXPECT_CALL(mock_policy_callback_,
343 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
344 EXPECT_CALL(mock_policy_callback_,
345 OnPolicyUpdatePtr(IsPolicies(&nat_false_)));
346 EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(IsPolicies(&nat_true_)));
348 SetPolicies(empty_);
349 StartWatching();
350 SetPolicies(nat_false_);
351 SetPolicies(nat_true_);
354 TEST_F(PolicyWatcherTest, ChangeOneRepeatedlyThenTwo) {
355 testing::InSequence sequence;
356 EXPECT_CALL(
357 mock_policy_callback_,
358 OnPolicyUpdatePtr(IsPolicies(&nat_true_domain_empty_others_default_)));
359 EXPECT_CALL(mock_policy_callback_,
360 OnPolicyUpdatePtr(IsPolicies(&domain_full_)));
361 EXPECT_CALL(mock_policy_callback_,
362 OnPolicyUpdatePtr(IsPolicies(&nat_false_)));
363 EXPECT_CALL(mock_policy_callback_,
364 OnPolicyUpdatePtr(IsPolicies(&domain_empty_)));
365 EXPECT_CALL(mock_policy_callback_,
366 OnPolicyUpdatePtr(IsPolicies(&nat_true_domain_full_)));
368 SetPolicies(nat_true_domain_empty_);
369 StartWatching();
370 SetPolicies(nat_true_domain_full_);
371 SetPolicies(nat_false_domain_full_);
372 SetPolicies(nat_false_domain_empty_);
373 SetPolicies(nat_true_domain_full_);
376 TEST_F(PolicyWatcherTest, FilterUnknownPolicies) {
377 testing::InSequence sequence;
378 EXPECT_CALL(mock_policy_callback_,
379 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
381 SetPolicies(empty_);
382 StartWatching();
383 SetPolicies(unknown_policies_);
384 SetPolicies(empty_);
387 TEST_F(PolicyWatcherTest, DebugOverrideNatPolicy) {
388 #if !defined(NDEBUG)
389 EXPECT_CALL(
390 mock_policy_callback_,
391 OnPolicyUpdatePtr(IsPolicies(&nat_false_overridden_others_default_)));
392 #else
393 EXPECT_CALL(mock_policy_callback_,
394 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
395 #endif
397 SetPolicies(nat_true_and_overridden_);
398 StartWatching();
401 TEST_F(PolicyWatcherTest, PairingFalseThenTrue) {
402 testing::InSequence sequence;
403 EXPECT_CALL(mock_policy_callback_,
404 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
405 EXPECT_CALL(mock_policy_callback_,
406 OnPolicyUpdatePtr(IsPolicies(&pairing_false_)));
407 EXPECT_CALL(mock_policy_callback_,
408 OnPolicyUpdatePtr(IsPolicies(&pairing_true_)));
410 SetPolicies(empty_);
411 StartWatching();
412 SetPolicies(pairing_false_);
413 SetPolicies(pairing_true_);
416 TEST_F(PolicyWatcherTest, GnubbyAuth) {
417 testing::InSequence sequence;
418 EXPECT_CALL(mock_policy_callback_,
419 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
420 EXPECT_CALL(mock_policy_callback_,
421 OnPolicyUpdatePtr(IsPolicies(&gnubby_auth_false_)));
422 EXPECT_CALL(mock_policy_callback_,
423 OnPolicyUpdatePtr(IsPolicies(&gnubby_auth_true_)));
425 SetPolicies(empty_);
426 StartWatching();
427 SetPolicies(gnubby_auth_false_);
428 SetPolicies(gnubby_auth_true_);
431 TEST_F(PolicyWatcherTest, Relay) {
432 testing::InSequence sequence;
433 EXPECT_CALL(mock_policy_callback_,
434 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
435 EXPECT_CALL(mock_policy_callback_,
436 OnPolicyUpdatePtr(IsPolicies(&relay_false_)));
437 EXPECT_CALL(mock_policy_callback_,
438 OnPolicyUpdatePtr(IsPolicies(&relay_true_)));
440 SetPolicies(empty_);
441 StartWatching();
442 SetPolicies(relay_false_);
443 SetPolicies(relay_true_);
446 TEST_F(PolicyWatcherTest, UdpPortRange) {
447 testing::InSequence sequence;
448 EXPECT_CALL(mock_policy_callback_,
449 OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
450 EXPECT_CALL(mock_policy_callback_,
451 OnPolicyUpdatePtr(IsPolicies(&port_range_full_)));
452 EXPECT_CALL(mock_policy_callback_,
453 OnPolicyUpdatePtr(IsPolicies(&port_range_empty_)));
455 SetPolicies(empty_);
456 StartWatching();
457 SetPolicies(port_range_full_);
458 SetPolicies(port_range_empty_);
461 const int kMaxTransientErrorRetries = 5;
463 TEST_F(PolicyWatcherTest, SingleTransientErrorDoesntTriggerErrorCallback) {
464 EXPECT_CALL(mock_policy_callback_, OnPolicyError()).Times(0);
466 StartWatching();
467 SignalTransientErrorForTest();
470 TEST_F(PolicyWatcherTest, MultipleTransientErrorsTriggerErrorCallback) {
471 EXPECT_CALL(mock_policy_callback_, OnPolicyError());
473 StartWatching();
474 for (int i = 0; i < kMaxTransientErrorRetries; i++) {
475 SignalTransientErrorForTest();
479 TEST_F(PolicyWatcherTest, PolicyUpdateResetsTransientErrorsCounter) {
480 testing::InSequence s;
481 EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(testing::_));
482 EXPECT_CALL(mock_policy_callback_, OnPolicyError()).Times(0);
484 StartWatching();
485 for (int i = 0; i < (kMaxTransientErrorRetries - 1); i++) {
486 SignalTransientErrorForTest();
488 SetPolicies(nat_true_);
489 for (int i = 0; i < (kMaxTransientErrorRetries - 1); i++) {
490 SignalTransientErrorForTest();
494 // Unit tests cannot instantiate PolicyWatcher on ChromeOS
495 // (as this requires running inside a browser process).
496 #ifndef OS_CHROMEOS
498 namespace {
500 void OnPolicyUpdatedDumpPolicy(scoped_ptr<base::DictionaryValue> policies) {
501 VLOG(1) << "OnPolicyUpdated callback received the following policies:";
503 for (base::DictionaryValue::Iterator iter(*policies); !iter.IsAtEnd();
504 iter.Advance()) {
505 switch (iter.value().GetType()) {
506 case base::Value::Type::TYPE_STRING: {
507 std::string value;
508 CHECK(iter.value().GetAsString(&value));
509 VLOG(1) << iter.key() << " = "
510 << "string: " << '"' << value << '"';
511 break;
513 case base::Value::Type::TYPE_BOOLEAN: {
514 bool value;
515 CHECK(iter.value().GetAsBoolean(&value));
516 VLOG(1) << iter.key() << " = "
517 << "boolean: " << (value ? "True" : "False");
518 break;
520 default: {
521 VLOG(1) << iter.key() << " = "
522 << "unrecognized type";
523 break;
529 } // anonymous namespace
531 // To dump policy contents, run unit tests with the following flags:
532 // out/Debug/remoting_unittests --gtest_filter=*TestRealChromotingPolicy* -v=1
533 TEST_F(PolicyWatcherTest, TestRealChromotingPolicy) {
534 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
535 base::MessageLoop::current()->task_runner();
536 scoped_ptr<PolicyWatcher> policy_watcher(
537 PolicyWatcher::Create(nullptr, task_runner));
540 base::RunLoop run_loop;
541 policy_watcher->StartWatching(base::Bind(OnPolicyUpdatedDumpPolicy),
542 base::Bind(base::DoNothing));
543 run_loop.RunUntilIdle();
546 // Today, the only verification offered by this test is:
547 // - Manual verification of policy values dumped by OnPolicyUpdatedDumpPolicy
548 // - Automated verification that nothing crashed
551 #endif
553 } // namespace remoting