| // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "remoting/host/config_file_watcher.h" | 
 |  | 
 | #include "base/files/file_path.h" | 
 | #include "base/files/file_util.h" | 
 | #include "base/macros.h" | 
 | #include "base/message_loop/message_loop.h" | 
 | #include "base/run_loop.h" | 
 | #include "remoting/base/auto_thread.h" | 
 | #include "remoting/base/auto_thread_task_runner.h" | 
 | #include "testing/gmock/include/gmock/gmock.h" | 
 | #include "testing/gmock_mutant.h" | 
 | #include "testing/gtest/include/gtest/gtest.h" | 
 |  | 
 | using testing::_; | 
 | using testing::AnyNumber; | 
 | using testing::Return; | 
 |  | 
 | namespace remoting { | 
 |  | 
 | namespace { | 
 |  | 
 | class ConfigFileWatcherDelegate : public ConfigFileWatcher::Delegate { | 
 |  public: | 
 |   ConfigFileWatcherDelegate() {} | 
 |   virtual ~ConfigFileWatcherDelegate() {} | 
 |  | 
 |   MOCK_METHOD1(OnConfigUpdated, void(const std::string&)); | 
 |   MOCK_METHOD0(OnConfigWatcherError, void()); | 
 |  | 
 |  private: | 
 |   DISALLOW_COPY_AND_ASSIGN(ConfigFileWatcherDelegate); | 
 | }; | 
 |  | 
 | }  // namespace | 
 |  | 
 | class ConfigFileWatcherTest : public testing::Test { | 
 |  public: | 
 |   ConfigFileWatcherTest(); | 
 |   ~ConfigFileWatcherTest() override; | 
 |  | 
 |   // testing::Test overrides | 
 |   void SetUp() override; | 
 |   void TearDown() override; | 
 |  | 
 |   // Stops the config file watcher. | 
 |   void StopWatcher(); | 
 |  | 
 |  protected: | 
 |   base::MessageLoopForUI message_loop_; | 
 |   base::RunLoop run_loop_; | 
 |  | 
 |   ConfigFileWatcherDelegate delegate_; | 
 |  | 
 |   // Path to the configuration file used. | 
 |   base::FilePath config_file_; | 
 |  | 
 |   // The configuration file watcher that is being tested. | 
 |   std::unique_ptr<ConfigFileWatcher> watcher_; | 
 | }; | 
 |  | 
 | ConfigFileWatcherTest::ConfigFileWatcherTest() { | 
 | } | 
 |  | 
 | ConfigFileWatcherTest::~ConfigFileWatcherTest() { | 
 | } | 
 |  | 
 | void ConfigFileWatcherTest::StopWatcher() { | 
 |   watcher_.reset(); | 
 | } | 
 |  | 
 | void ConfigFileWatcherTest::SetUp() { | 
 |   EXPECT_TRUE(base::CreateTemporaryFile(&config_file_)); | 
 |  | 
 |   // Arrange to run |message_loop_| until no components depend on it. | 
 |   scoped_refptr<AutoThreadTaskRunner> task_runner = new AutoThreadTaskRunner( | 
 |       message_loop_.task_runner(), run_loop_.QuitClosure()); | 
 |  | 
 |   scoped_refptr<AutoThreadTaskRunner> io_task_runner = | 
 |       AutoThread::CreateWithType( | 
 |           "IPC thread", task_runner, base::MessageLoop::TYPE_IO); | 
 |  | 
 |   // Create an instance of the config watcher. | 
 |   watcher_.reset( | 
 |       new ConfigFileWatcher(task_runner, io_task_runner, config_file_)); | 
 | } | 
 |  | 
 | void ConfigFileWatcherTest::TearDown() { | 
 |   // Delete the test file. | 
 |   if (!config_file_.empty()) | 
 |     base::DeleteFile(config_file_, false); | 
 | } | 
 |  | 
 | // Verifies that the initial notification is delivered. | 
 | TEST_F(ConfigFileWatcherTest, Basic) { | 
 |   std::string data("test"); | 
 |   EXPECT_NE(base::WriteFile(config_file_, data.c_str(), | 
 |                                  static_cast<int>(data.size())), -1); | 
 |  | 
 |   EXPECT_CALL(delegate_, OnConfigUpdated(_)) | 
 |       .Times(1) | 
 |       .WillOnce(InvokeWithoutArgs(this, &ConfigFileWatcherTest::StopWatcher)); | 
 |   EXPECT_CALL(delegate_, OnConfigWatcherError()) | 
 |       .Times(0); | 
 |  | 
 |   watcher_->Watch(&delegate_); | 
 |   run_loop_.Run(); | 
 | } | 
 |  | 
 | MATCHER_P(EqualsString, s, "") { | 
 |   return arg == s; | 
 | } | 
 |  | 
 | // Verifies that an update notification is sent when the file is changed. | 
 | TEST_F(ConfigFileWatcherTest, Update) { | 
 |   EXPECT_CALL(delegate_, OnConfigUpdated(EqualsString("test"))) | 
 |       .Times(1) | 
 |       .WillOnce(InvokeWithoutArgs(this, &ConfigFileWatcherTest::StopWatcher)); | 
 |   EXPECT_CALL(delegate_, OnConfigWatcherError()) | 
 |       .Times(0); | 
 |  | 
 |   watcher_->Watch(&delegate_); | 
 |  | 
 |   // Modify the watched file. | 
 |   std::string data("test"); | 
 |   EXPECT_NE(base::WriteFile(config_file_, data.c_str(), | 
 |                                  static_cast<int>(data.size())), -1); | 
 |  | 
 |   run_loop_.Run(); | 
 | } | 
 |  | 
 | }  // namespace remoting |