1 //
2 // Copyright (C) 2017 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "update_engine/aosp/update_attempter_android.h"
18 
19 #include <memory>
20 #include <string>
21 #include <utility>
22 
23 #include <android-base/properties.h>
24 #include <base/time/time.h>
25 #include <gtest/gtest.h>
26 
27 #include "common/constants.h"
28 #include "update_engine/aosp/daemon_state_android.h"
29 #include "update_engine/common/fake_boot_control.h"
30 #include "update_engine/common/fake_clock.h"
31 #include "update_engine/common/fake_hardware.h"
32 #include "update_engine/common/fake_prefs.h"
33 #include "update_engine/common/mock_action_processor.h"
34 #include "update_engine/common/mock_metrics_reporter.h"
35 #include "update_engine/common/test_utils.h"
36 #include "update_engine/common/utils.h"
37 
38 using base::Time;
39 using base::TimeDelta;
40 using testing::_;
41 using update_engine::UpdateStatus;
42 
43 namespace chromeos_update_engine {
44 
45 class UpdateAttempterAndroidTest : public ::testing::Test {
46  protected:
47   UpdateAttempterAndroidTest() = default;
48 
SetUp()49   void SetUp() override {
50     clock_ = new FakeClock();
51     metrics_reporter_ = new testing::NiceMock<MockMetricsReporter>();
52     update_attempter_android_.metrics_reporter_.reset(metrics_reporter_);
53     update_attempter_android_.clock_.reset(clock_);
54     update_attempter_android_.processor_.reset(
55         new testing::NiceMock<MockActionProcessor>());
56   }
57 
SetUpdateStatus(update_engine::UpdateStatus status)58   void SetUpdateStatus(update_engine::UpdateStatus status) {
59     update_attempter_android_.status_ = status;
60   }
61 
AddPayload(InstallPlan::Payload && payload)62   void AddPayload(InstallPlan::Payload&& payload) {
63     update_attempter_android_.install_plan_.payloads.push_back(
64         std::move(payload));
65   }
66 
67   DaemonStateAndroid daemon_state_;
68   FakePrefs prefs_;
69   FakeBootControl boot_control_;
70   FakeHardware hardware_;
71 
72   UpdateAttempterAndroid update_attempter_android_{
73       &daemon_state_, &prefs_, &boot_control_, &hardware_, nullptr};
74 
75   FakeClock* clock_;
76   testing::NiceMock<MockMetricsReporter>* metrics_reporter_;
77 };
78 
TEST_F(UpdateAttempterAndroidTest,UpdatePrefsSameBuildVersionOnInit)79 TEST_F(UpdateAttempterAndroidTest, UpdatePrefsSameBuildVersionOnInit) {
80   std::string build_version =
81       android::base::GetProperty("ro.build.version.incremental", "");
82   prefs_.SetString(kPrefsPreviousVersion, build_version);
83   prefs_.SetString(kPrefsBootId, "oldboot");
84   prefs_.SetInt64(kPrefsNumReboots, 1);
85   prefs_.SetInt64(kPrefsPreviousSlot, 1);
86   boot_control_.SetCurrentSlot(1);
87 
88   EXPECT_CALL(*metrics_reporter_, ReportTimeToReboot(_)).Times(0);
89   update_attempter_android_.Init();
90 
91   // Check that the boot_id and reboot_count are updated.
92   std::string boot_id;
93   utils::GetBootId(&boot_id);
94   ASSERT_TRUE(prefs_.Exists(kPrefsBootId));
95   std::string prefs_boot_id;
96   ASSERT_TRUE(prefs_.GetString(kPrefsBootId, &prefs_boot_id));
97   ASSERT_EQ(boot_id, prefs_boot_id);
98 
99   ASSERT_TRUE(prefs_.Exists(kPrefsNumReboots));
100   int64_t reboot_count;
101   ASSERT_TRUE(prefs_.GetInt64(kPrefsNumReboots, &reboot_count));
102   ASSERT_EQ(2, reboot_count);
103 }
104 
TEST_F(UpdateAttempterAndroidTest,UpdatePrefsBuildVersionChangeOnInit)105 TEST_F(UpdateAttempterAndroidTest, UpdatePrefsBuildVersionChangeOnInit) {
106   prefs_.SetString(kPrefsPreviousVersion, "00001");  // Set the fake version
107   prefs_.SetInt64(kPrefsPayloadAttemptNumber, 1);
108   prefs_.SetInt64(kPrefsSystemUpdatedMarker, 23456);
109 
110   EXPECT_CALL(*metrics_reporter_,
111               ReportAbnormallyTerminatedUpdateAttemptMetrics())
112       .Times(1);
113 
114   Time now = Time::FromInternalValue(34456);
115   clock_->SetMonotonicTime(now);
116   TimeDelta duration = now - Time::FromInternalValue(23456);
117   EXPECT_CALL(*metrics_reporter_, ReportTimeToReboot(duration.InMinutes()))
118       .Times(1);
119 
120   update_attempter_android_.Init();
121   // Check that we reset the metric prefs.
122   EXPECT_FALSE(prefs_.Exists(kPrefsNumReboots));
123   EXPECT_FALSE(prefs_.Exists(kPrefsUpdateTimestampStart));
124   EXPECT_FALSE(prefs_.Exists(kPrefsSystemUpdatedMarker));
125   // PayloadAttemptNumber should persist across reboots.
126   EXPECT_TRUE(prefs_.Exists(kPrefsPayloadAttemptNumber));
127 }
128 
TEST_F(UpdateAttempterAndroidTest,ReportMetricsOnUpdateTerminated)129 TEST_F(UpdateAttempterAndroidTest, ReportMetricsOnUpdateTerminated) {
130   prefs_.SetInt64(kPrefsNumReboots, 3);
131   prefs_.SetInt64(kPrefsPayloadAttemptNumber, 2);
132   prefs_.SetString(kPrefsPreviousVersion, "56789");
133   prefs_.SetInt64(kPrefsUpdateBootTimestampStart, 10000);
134   prefs_.SetInt64(kPrefsUpdateTimestampStart, 12345);
135 
136   Time boot_time = Time::FromInternalValue(22345);
137   Time up_time = Time::FromInternalValue(21345);
138   clock_->SetBootTime(boot_time);
139   clock_->SetMonotonicTime(up_time);
140   TimeDelta duration = boot_time - Time::FromInternalValue(10000);
141   TimeDelta duration_uptime = up_time - Time::FromInternalValue(12345);
142   EXPECT_CALL(
143       *metrics_reporter_,
144       ReportUpdateAttemptMetrics(2,
145                                  _,
146                                  duration,
147                                  duration_uptime,
148                                  _,
149                                  metrics::AttemptResult::kUpdateSucceeded,
150                                  ErrorCode::kSuccess))
151       .Times(1);
152   EXPECT_CALL(*metrics_reporter_,
153               ReportSuccessfulUpdateMetrics(
154                   2, 0, _, 50, _, _, duration, duration_uptime, 3, _))
155       .Times(1);
156 
157   // Adds a payload of 50 bytes to the InstallPlan.
158   InstallPlan::Payload payload;
159   payload.size = 50;
160   AddPayload(std::move(payload));
161   SetUpdateStatus(UpdateStatus::UPDATE_AVAILABLE);
162   update_attempter_android_.ProcessingDone(nullptr, ErrorCode::kSuccess);
163 
164   EXPECT_FALSE(prefs_.Exists(kPrefsNumReboots));
165   EXPECT_FALSE(prefs_.Exists(kPrefsPayloadAttemptNumber));
166   EXPECT_FALSE(prefs_.Exists(kPrefsUpdateTimestampStart));
167   EXPECT_TRUE(prefs_.Exists(kPrefsSystemUpdatedMarker));
168 }
169 
TEST_F(UpdateAttempterAndroidTest,ReportMetricsForBytesDownloaded)170 TEST_F(UpdateAttempterAndroidTest, ReportMetricsForBytesDownloaded) {
171   // Check both prefs are updated correctly.
172   update_attempter_android_.BytesReceived(20, 50, 200);
173   EXPECT_EQ(
174       20,
175       metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, &prefs_));
176   EXPECT_EQ(
177       20,
178       metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, &prefs_));
179 
180   EXPECT_CALL(*metrics_reporter_,
181               ReportUpdateAttemptDownloadMetrics(50, _, _, _, _))
182       .Times(1);
183   EXPECT_CALL(*metrics_reporter_,
184               ReportUpdateAttemptDownloadMetrics(40, _, _, _, _))
185       .Times(1);
186 
187   int64_t total_bytes[kNumDownloadSources] = {};
188   total_bytes[kDownloadSourceHttpsServer] = 90;
189   EXPECT_CALL(*metrics_reporter_,
190               ReportSuccessfulUpdateMetrics(
191                   _,
192                   _,
193                   _,
194                   50,
195                   test_utils::DownloadSourceMatcher(total_bytes),
196                   80,
197                   _,
198                   _,
199                   _,
200                   _))
201       .Times(1);
202 
203   // Adds a payload of 50 bytes to the InstallPlan.
204   InstallPlan::Payload payload;
205   payload.size = 50;
206   AddPayload(std::move(payload));
207 
208   // The first update fails after receiving 50 bytes in total.
209   update_attempter_android_.BytesReceived(30, 50, 200);
210   update_attempter_android_.ProcessingDone(nullptr, ErrorCode::kError);
211   EXPECT_EQ(
212       0,
213       metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, &prefs_));
214   EXPECT_EQ(
215       50,
216       metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, &prefs_));
217 
218   // The second update succeeds after receiving 40 bytes, which leads to a
219   // overhead of (90 - 50) / 50 = 80%.
220   update_attempter_android_.BytesReceived(40, 40, 50);
221   update_attempter_android_.ProcessingDone(nullptr, ErrorCode::kSuccess);
222   // Both prefs should be cleared.
223   EXPECT_EQ(
224       0,
225       metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, &prefs_));
226   EXPECT_EQ(
227       0, metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, &prefs_));
228 }
229 
230 }  // namespace chromeos_update_engine
231