shill: rename ChromeosDaemon to DaemonTask

Rename ChromeosDaemon to DaemonTask since this class contains
all the logic for daemon-related tasks (e.g. start/stop,
init/shutdown). This will also prevent this class from being
confused with ShillDaemon.

BUG: 26653263
Change-Id: I9713203cb1f933163d7067a7ae982622bf5b17af
TEST: shill compiles and unit tests pass on Android.
TEST: shill compiles and unit tests pass on Chrome OS.
diff --git a/daemon_task_unittest.cc b/daemon_task_unittest.cc
new file mode 100644
index 0000000..d7fe41c
--- /dev/null
+++ b/daemon_task_unittest.cc
@@ -0,0 +1,248 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <stdint.h>
+
+#include <memory>
+#include <vector>
+
+#include <base/bind.h>
+#include <base/memory/ref_counted.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "shill/daemon_task.h"
+#include "shill/dhcp/mock_dhcp_provider.h"
+#include "shill/logging.h"
+#include "shill/mock_control.h"
+#include "shill/mock_manager.h"
+#include "shill/mock_metrics.h"
+#include "shill/mock_process_manager.h"
+#include "shill/mock_routing_table.h"
+#include "shill/net/io_handler.h"
+#include "shill/net/mock_rtnl_handler.h"
+#include "shill/net/ndisc.h"
+#include "shill/shill_test_config.h"
+#include "shill/test_event_dispatcher.h"
+
+#if !defined(DISABLE_WIFI)
+#include "shill/net/mock_netlink_manager.h"
+#include "shill/net/nl80211_message.h"
+#include "shill/wifi/callback80211_metrics.h"
+#endif  // DISABLE_WIFI
+
+using base::Bind;
+using base::Callback;
+using base::Unretained;
+using std::string;
+using std::vector;
+
+using ::testing::Expectation;
+using ::testing::Mock;
+using ::testing::Return;
+using ::testing::Test;
+using ::testing::_;
+
+namespace shill {
+
+class DaemonTaskForTest : public DaemonTask {
+ public:
+  DaemonTaskForTest(const Settings& setttings, Config* config)
+      : DaemonTask(Settings(), config) {}
+  virtual ~DaemonTaskForTest() {}
+
+  bool quit_result() { return quit_result_; }
+
+  void RunMessageLoop() { dispatcher_->DispatchForever(); }
+
+  bool Quit(const base::Closure& completion_callback) override {
+    quit_result_ = DaemonTask::Quit(completion_callback);
+    dispatcher_->PostTask(base::MessageLoop::QuitWhenIdleClosure());
+    return quit_result_;
+  }
+
+ private:
+  bool quit_result_;
+};
+
+class DaemonTaskTest : public Test {
+ public:
+  DaemonTaskTest()
+      : daemon_(DaemonTask::Settings(), &config_),
+        dispatcher_(new EventDispatcherForTest()),
+        control_(new MockControl()),
+        metrics_(new MockMetrics(dispatcher_)),
+        manager_(new MockManager(control_, dispatcher_, metrics_)),
+#if !defined(DISABLE_WIFI)
+        callback_metrics_(new Callback80211Metrics(metrics_)),
+#endif  // DISABLE_WIFI
+        device_info_(control_, dispatcher_, metrics_, manager_) {
+  }
+  virtual ~DaemonTaskTest() {}
+  virtual void SetUp() {
+    // Tests initialization done by the daemon's constructor
+    daemon_.rtnl_handler_ = &rtnl_handler_;
+    daemon_.routing_table_ = &routing_table_;
+    daemon_.dhcp_provider_ = &dhcp_provider_;
+    daemon_.process_manager_ = &process_manager_;
+    daemon_.metrics_.reset(metrics_);        // Passes ownership
+    daemon_.manager_.reset(manager_);        // Passes ownership
+    daemon_.control_.reset(control_);        // Passes ownership
+    daemon_.dispatcher_.reset(dispatcher_);  // Passes ownership
+
+#if !defined(DISABLE_WIFI)
+    daemon_.netlink_manager_ = &netlink_manager_;
+    // Passes ownership
+    daemon_.callback80211_metrics_.reset(callback_metrics_);
+#endif  // DISABLE_WIFI
+  }
+  void StartDaemon() { daemon_.Start(); }
+
+  void StopDaemon() { daemon_.Stop(); }
+
+  void RunDaemon() { daemon_.RunMessageLoop(); }
+
+  void ApplySettings(const DaemonTask::Settings& settings) {
+    daemon_.settings_ = settings;
+    daemon_.ApplySettings();
+  }
+
+  MOCK_METHOD0(TerminationAction, void());
+  MOCK_METHOD0(BreakTerminationLoop, void());
+
+ protected:
+  TestConfig config_;
+  DaemonTaskForTest daemon_;
+  MockRTNLHandler rtnl_handler_;
+  MockRoutingTable routing_table_;
+  MockDHCPProvider dhcp_provider_;
+  MockProcessManager process_manager_;
+  EventDispatcherForTest* dispatcher_;
+  MockControl* control_;
+  MockMetrics* metrics_;
+  MockManager* manager_;
+#if !defined(DISABLE_WIFI)
+  MockNetlinkManager netlink_manager_;
+  Callback80211Metrics* callback_metrics_;
+#endif  // DISABLE_WIFI
+  DeviceInfo device_info_;
+};
+
+TEST_F(DaemonTaskTest, StartStop) {
+  // To ensure we do not have any stale routes, we flush a device's routes
+  // when it is started.  This requires that the routing table is fully
+  // populated before we create and start devices.  So test to make sure that
+  // the RoutingTable starts before the Manager (which in turn starts
+  // DeviceInfo who is responsible for creating and starting devices).
+  // The result is that we request the dump of the routing table and when that
+  // completes, we request the dump of the links.  For each link found, we
+  // create and start the device.
+  EXPECT_CALL(*metrics_, Start());
+  EXPECT_CALL(rtnl_handler_, Start(RTMGRP_LINK | RTMGRP_IPV4_IFADDR |
+                                   RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_IFADDR |
+                                   RTMGRP_IPV6_ROUTE | RTMGRP_ND_USEROPT));
+  Expectation routing_table_started = EXPECT_CALL(routing_table_, Start());
+  EXPECT_CALL(dhcp_provider_, Init(_, _, _));
+  EXPECT_CALL(process_manager_, Init(_));
+#if !defined(DISABLE_WIFI)
+  EXPECT_CALL(netlink_manager_, Init());
+  const uint16_t kNl80211MessageType = 42;  // Arbitrary.
+  EXPECT_CALL(netlink_manager_,
+              GetFamily(Nl80211Message::kMessageTypeString, _))
+      .WillOnce(Return(kNl80211MessageType));
+  EXPECT_CALL(netlink_manager_, Start());
+#endif  // DISABLE_WIFI
+  EXPECT_CALL(*manager_, Start()).After(routing_table_started);
+  StartDaemon();
+  Mock::VerifyAndClearExpectations(metrics_);
+  Mock::VerifyAndClearExpectations(manager_);
+
+  EXPECT_CALL(*manager_, Stop());
+  EXPECT_CALL(*metrics_, Stop());
+  EXPECT_CALL(process_manager_, Stop());
+  StopDaemon();
+}
+
+ACTION_P2(CompleteAction, manager, name) {
+  manager->TerminationActionComplete(name);
+}
+
+TEST_F(DaemonTaskTest, QuitWithTerminationAction) {
+  // This expectation verifies that the termination actions are invoked.
+  EXPECT_CALL(*this, TerminationAction())
+      .WillOnce(CompleteAction(manager_, "daemon test"));
+  EXPECT_CALL(*this, BreakTerminationLoop()).Times(1);
+
+  manager_->AddTerminationAction(
+      "daemon test",
+      Bind(&DaemonTaskTest::TerminationAction, Unretained(this)));
+
+  // Run Daemon::Quit() after the daemon starts running.
+  dispatcher_->PostTask(
+      Bind(IgnoreResult(&DaemonTask::Quit), Unretained(&daemon_),
+           Bind(&DaemonTaskTest::BreakTerminationLoop, Unretained(this))));
+
+  RunDaemon();
+  EXPECT_FALSE(daemon_.quit_result());
+}
+
+TEST_F(DaemonTaskTest, QuitWithoutTerminationActions) {
+  EXPECT_CALL(*this, BreakTerminationLoop()).Times(0);
+  EXPECT_TRUE(daemon_.Quit(
+      Bind(&DaemonTaskTest::BreakTerminationLoop, Unretained(this))));
+}
+
+TEST_F(DaemonTaskTest, ApplySettings) {
+  DaemonTask::Settings settings;
+  vector<string> kEmptyStringList;
+  EXPECT_CALL(*manager_, SetBlacklistedDevices(kEmptyStringList));
+  EXPECT_CALL(*manager_, SetDHCPv6EnabledDevices(kEmptyStringList));
+  EXPECT_CALL(*manager_, SetTechnologyOrder("", _));
+  EXPECT_CALL(*manager_, SetIgnoreUnknownEthernet(false));
+  EXPECT_CALL(*manager_, SetStartupPortalList(_)).Times(0);
+  EXPECT_CALL(*manager_, SetPassiveMode()).Times(0);
+  EXPECT_CALL(*manager_, SetPrependDNSServers(""));
+  EXPECT_CALL(*manager_, SetMinimumMTU(_)).Times(0);
+  EXPECT_CALL(*manager_, SetAcceptHostnameFrom(""));
+  ApplySettings(settings);
+  Mock::VerifyAndClearExpectations(manager_);
+
+  vector<string> kBlacklistedDevices = {"eth0", "eth1"};
+  settings.device_blacklist = kBlacklistedDevices;
+  settings.default_technology_order = "wifi,ethernet";
+  vector<string> kDHCPv6EnabledDevices{"eth2", "eth3"};
+  settings.dhcpv6_enabled_devices = kDHCPv6EnabledDevices;
+  settings.ignore_unknown_ethernet = false;
+  settings.portal_list = "wimax";
+  settings.use_portal_list = true;
+  settings.passive_mode = true;
+  settings.prepend_dns_servers = "8.8.8.8,8.8.4.4";
+  settings.minimum_mtu = 256;
+  settings.accept_hostname_from = "eth*";
+  EXPECT_CALL(*manager_, SetBlacklistedDevices(kBlacklistedDevices));
+  EXPECT_CALL(*manager_, SetDHCPv6EnabledDevices(kDHCPv6EnabledDevices));
+  EXPECT_CALL(*manager_, SetTechnologyOrder("wifi,ethernet", _));
+  EXPECT_CALL(*manager_, SetIgnoreUnknownEthernet(false));
+  EXPECT_CALL(*manager_, SetStartupPortalList("wimax"));
+  EXPECT_CALL(*manager_, SetPassiveMode());
+  EXPECT_CALL(*manager_, SetPrependDNSServers("8.8.8.8,8.8.4.4"));
+  EXPECT_CALL(*manager_, SetMinimumMTU(256));
+  EXPECT_CALL(*manager_, SetAcceptHostnameFrom("eth*"));
+  ApplySettings(settings);
+  Mock::VerifyAndClearExpectations(manager_);
+}
+
+}  // namespace shill