1// Copyright 2014 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.
4
5#include "chrome/browser/ui/webui/help/version_updater_chromeos.h"
6
7#include "base/bind.h"
8#include "base/compiler_specific.h"
9#include "base/macros.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/message_loop/message_loop.h"
12#include "chrome/browser/chromeos/login/users/mock_user_manager.h"
13#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
14#include "chrome/browser/chromeos/settings/cros_settings.h"
15#include "chrome/browser/chromeos/settings/device_settings_service.h"
16#include "chromeos/dbus/dbus_thread_manager.h"
17#include "chromeos/dbus/fake_update_engine_client.h"
18#include "chromeos/dbus/shill_service_client.h"
19#include "chromeos/network/network_handler.h"
20#include "testing/gmock/include/gmock/gmock.h"
21#include "testing/gtest/include/gtest/gtest.h"
22#include "third_party/cros_system_api/dbus/service_constants.h"
23
24using ::testing::AtLeast;
25using ::testing::Return;
26
27namespace chromeos {
28
29namespace {
30
31void CheckNotification(VersionUpdater::Status /* status */,
32                       int /* progress */,
33                       const base::string16& /* message */) {
34}
35
36}  // namespace
37
38class VersionUpdaterCrosTest : public ::testing::Test {
39 protected:
40  VersionUpdaterCrosTest()
41      : version_updater_(VersionUpdater::Create()),
42        fake_update_engine_client_(NULL),
43        mock_user_manager_(new MockUserManager()),
44        user_manager_enabler_(mock_user_manager_) {}
45
46  virtual ~VersionUpdaterCrosTest() {}
47
48  virtual void SetUp() OVERRIDE {
49    fake_update_engine_client_ = new FakeUpdateEngineClient();
50    scoped_ptr<DBusThreadManagerSetter> dbus_setter =
51        DBusThreadManager::GetSetterForTesting();
52    dbus_setter->SetUpdateEngineClient(
53        scoped_ptr<UpdateEngineClient>(fake_update_engine_client_).Pass());
54
55    EXPECT_CALL(*mock_user_manager_, IsCurrentUserOwner())
56        .WillRepeatedly(Return(false));
57    EXPECT_CALL(*mock_user_manager_, Shutdown()).Times(AtLeast(0));
58
59    DeviceSettingsService::Initialize();
60    CrosSettings::Initialize();
61
62    NetworkHandler::Initialize();
63    ShillServiceClient::TestInterface* service_test =
64        DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
65    service_test->AddService("/service/eth",
66                             "eth" /* guid */,
67                             "eth",
68                             shill::kTypeEthernet, shill::kStateOnline,
69                             true /* visible */);
70    loop_.RunUntilIdle();
71  }
72
73  virtual void TearDown() OVERRIDE {
74    NetworkHandler::Shutdown();
75
76    CrosSettings::Shutdown();
77    DeviceSettingsService::Shutdown();
78  }
79
80  scoped_ptr<VersionUpdater> version_updater_;
81  FakeUpdateEngineClient* fake_update_engine_client_;  // Not owned.
82
83  MockUserManager* mock_user_manager_;  // Not owned.
84  ScopedUserManagerEnabler user_manager_enabler_;
85
86  base::MessageLoop loop_;
87
88  DISALLOW_COPY_AND_ASSIGN(VersionUpdaterCrosTest);
89};
90
91// The test checks following behaviour:
92// 1. The device is currently on the dev channel and an user decides to switch
93// to the beta channel.
94// 2. In the middle of channel switch the user decides to switch to the stable
95// channel.
96// 3. Update engine reports an error because downloading channel (beta) is not
97// equal
98// to the target channel (stable).
99// 4. When update engine becomes idle downloading of the stable channel is
100// initiated.
101TEST_F(VersionUpdaterCrosTest, TwoOverlappingSetChannelRequests) {
102  version_updater_->SetChannel("beta-channel", true);
103
104  {
105    UpdateEngineClient::Status status;
106    status.status = UpdateEngineClient::UPDATE_STATUS_IDLE;
107    fake_update_engine_client_->set_default_status(status);
108    fake_update_engine_client_->NotifyObserversThatStatusChanged(status);
109  }
110
111  EXPECT_EQ(0, fake_update_engine_client_->request_update_check_call_count());
112
113  // IDLE -> DOWNLOADING transition after update check.
114  version_updater_->CheckForUpdate(base::Bind(&CheckNotification));
115  EXPECT_EQ(1, fake_update_engine_client_->request_update_check_call_count());
116
117  {
118    UpdateEngineClient::Status status;
119    status.status = UpdateEngineClient::UPDATE_STATUS_DOWNLOADING;
120    status.download_progress = 0.1;
121    fake_update_engine_client_->set_default_status(status);
122    fake_update_engine_client_->NotifyObserversThatStatusChanged(status);
123  }
124
125  version_updater_->SetChannel("stable-channel", true);
126
127  // DOWNLOADING -> REPORTING_ERROR_EVENT transition since target channel is not
128  // equal to downloading channel now.
129  {
130    UpdateEngineClient::Status status;
131    status.status = UpdateEngineClient::UPDATE_STATUS_REPORTING_ERROR_EVENT;
132    fake_update_engine_client_->set_default_status(status);
133    fake_update_engine_client_->NotifyObserversThatStatusChanged(status);
134  }
135
136  version_updater_->CheckForUpdate(base::Bind(&CheckNotification));
137  EXPECT_EQ(1, fake_update_engine_client_->request_update_check_call_count());
138
139  // REPORTING_ERROR_EVENT -> IDLE transition, update check should be
140  // automatically scheduled.
141  {
142    UpdateEngineClient::Status status;
143    status.status = UpdateEngineClient::UPDATE_STATUS_IDLE;
144    fake_update_engine_client_->set_default_status(status);
145    fake_update_engine_client_->NotifyObserversThatStatusChanged(status);
146  }
147
148  EXPECT_EQ(2, fake_update_engine_client_->request_update_check_call_count());
149}
150
151}  // namespace chromeos
152