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