blob: 81a3230dc53e1024c8b3a0d169d7f485a3af3b3b [file] [log] [blame]
Tianjie Xu90aaa102017-10-10 17:39:03 -07001//
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
Amin Hassaniec7bc112020-10-29 16:47:58 -070017#include "update_engine/aosp/update_attempter_android.h"
Tianjie Xu90aaa102017-10-10 17:39:03 -070018
19#include <memory>
20#include <string>
Tianjie Xu21030c12019-08-14 13:00:23 -070021#include <utility>
Tianjie Xu90aaa102017-10-10 17:39:03 -070022
Kelvin Zhang3fe49642021-10-04 15:35:02 -070023#include <sys/fcntl.h>
24#include <sys/sendfile.h>
25#include <unistd.h>
26
Tianjie Xu90aaa102017-10-10 17:39:03 -070027#include <android-base/properties.h>
28#include <base/time/time.h>
Kelvin Zhang3fe49642021-10-04 15:35:02 -070029#include <brillo/data_encoding.h>
30#include <brillo/message_loops/fake_message_loop.h>
Tianjie Xu90aaa102017-10-10 17:39:03 -070031#include <gtest/gtest.h>
Kelvin Zhang3fe49642021-10-04 15:35:02 -070032#include <liblp/builder.h>
33#include <fs_mgr.h>
34#include <liblp/liblp.h>
Tianjie Xu90aaa102017-10-10 17:39:03 -070035
Kelvin Zhang3fe49642021-10-04 15:35:02 -070036#include "update_engine/aosp/boot_control_android.h"
Amin Hassaniec7bc112020-10-29 16:47:58 -070037#include "update_engine/aosp/daemon_state_android.h"
Kelvin Zhang3fe49642021-10-04 15:35:02 -070038#include "update_engine/common/constants.h"
39#include "update_engine/common/prefs.h"
40#include "update_engine/common/testing_constants.h"
41#include "update_engine/common/hash_calculator.h"
Tianjie Xu90aaa102017-10-10 17:39:03 -070042#include "update_engine/common/fake_boot_control.h"
43#include "update_engine/common/fake_clock.h"
44#include "update_engine/common/fake_hardware.h"
45#include "update_engine/common/fake_prefs.h"
46#include "update_engine/common/mock_action_processor.h"
Amin Hassaniec7bc112020-10-29 16:47:58 -070047#include "update_engine/common/mock_metrics_reporter.h"
Tianjie Xud4777a12017-10-24 14:54:18 -070048#include "update_engine/common/test_utils.h"
Tianjie Xu90aaa102017-10-10 17:39:03 -070049#include "update_engine/common/utils.h"
Kelvin Zhang3fe49642021-10-04 15:35:02 -070050#include "update_engine/payload_consumer/payload_constants.h"
51#include "update_engine/payload_consumer/install_plan.h"
52#include "update_engine/payload_generator/delta_diff_generator.h"
53#include "update_engine/payload_generator/extent_ranges.h"
54#include "update_engine/payload_generator/payload_file.h"
55#include "update_engine/payload_generator/payload_signer.h"
56#include "update_engine/update_metadata.pb.h"
57#include "update_engine/update_status_utils.h"
Tianjie Xu90aaa102017-10-10 17:39:03 -070058
59using base::Time;
60using base::TimeDelta;
61using testing::_;
62using update_engine::UpdateStatus;
63
64namespace chromeos_update_engine {
Tianjie Xud4777a12017-10-24 14:54:18 -070065
Tianjie Xu90aaa102017-10-10 17:39:03 -070066class UpdateAttempterAndroidTest : public ::testing::Test {
67 protected:
68 UpdateAttempterAndroidTest() = default;
69
70 void SetUp() override {
71 clock_ = new FakeClock();
72 metrics_reporter_ = new testing::NiceMock<MockMetricsReporter>();
73 update_attempter_android_.metrics_reporter_.reset(metrics_reporter_);
74 update_attempter_android_.clock_.reset(clock_);
75 update_attempter_android_.processor_.reset(
76 new testing::NiceMock<MockActionProcessor>());
77 }
78
79 void SetUpdateStatus(update_engine::UpdateStatus status) {
80 update_attempter_android_.status_ = status;
81 }
82
Tianjie Xu21030c12019-08-14 13:00:23 -070083 void AddPayload(InstallPlan::Payload&& payload) {
84 update_attempter_android_.install_plan_.payloads.push_back(
85 std::move(payload));
86 }
87
Tianjie Xu90aaa102017-10-10 17:39:03 -070088 DaemonStateAndroid daemon_state_;
89 FakePrefs prefs_;
90 FakeBootControl boot_control_;
91 FakeHardware hardware_;
92
Yifan Hong93c497d2021-02-08 14:25:52 -080093 UpdateAttempterAndroid update_attempter_android_{
Mohammad Samiul Islam24a82792021-02-12 16:52:36 +000094 &daemon_state_, &prefs_, &boot_control_, &hardware_, nullptr};
Yifan Hong93c497d2021-02-08 14:25:52 -080095
Tianjie Xu90aaa102017-10-10 17:39:03 -070096 FakeClock* clock_;
97 testing::NiceMock<MockMetricsReporter>* metrics_reporter_;
98};
99
100TEST_F(UpdateAttempterAndroidTest, UpdatePrefsSameBuildVersionOnInit) {
101 std::string build_version =
102 android::base::GetProperty("ro.build.version.incremental", "");
103 prefs_.SetString(kPrefsPreviousVersion, build_version);
104 prefs_.SetString(kPrefsBootId, "oldboot");
105 prefs_.SetInt64(kPrefsNumReboots, 1);
Kelvin Zhang86603472021-05-11 12:16:27 -0400106 prefs_.SetInt64(kPrefsPreviousSlot, 1);
107 boot_control_.SetCurrentSlot(1);
Tianjie Xu90aaa102017-10-10 17:39:03 -0700108
109 EXPECT_CALL(*metrics_reporter_, ReportTimeToReboot(_)).Times(0);
110 update_attempter_android_.Init();
111
112 // Check that the boot_id and reboot_count are updated.
113 std::string boot_id;
114 utils::GetBootId(&boot_id);
Kelvin Zhang86603472021-05-11 12:16:27 -0400115 ASSERT_TRUE(prefs_.Exists(kPrefsBootId));
Tianjie Xu90aaa102017-10-10 17:39:03 -0700116 std::string prefs_boot_id;
Kelvin Zhang86603472021-05-11 12:16:27 -0400117 ASSERT_TRUE(prefs_.GetString(kPrefsBootId, &prefs_boot_id));
118 ASSERT_EQ(boot_id, prefs_boot_id);
Tianjie Xu90aaa102017-10-10 17:39:03 -0700119
Kelvin Zhang86603472021-05-11 12:16:27 -0400120 ASSERT_TRUE(prefs_.Exists(kPrefsNumReboots));
Tianjie Xu90aaa102017-10-10 17:39:03 -0700121 int64_t reboot_count;
Kelvin Zhang86603472021-05-11 12:16:27 -0400122 ASSERT_TRUE(prefs_.GetInt64(kPrefsNumReboots, &reboot_count));
123 ASSERT_EQ(2, reboot_count);
Tianjie Xu90aaa102017-10-10 17:39:03 -0700124}
125
126TEST_F(UpdateAttempterAndroidTest, UpdatePrefsBuildVersionChangeOnInit) {
127 prefs_.SetString(kPrefsPreviousVersion, "00001"); // Set the fake version
128 prefs_.SetInt64(kPrefsPayloadAttemptNumber, 1);
129 prefs_.SetInt64(kPrefsSystemUpdatedMarker, 23456);
Kelvin Zhanga43d6e82021-05-26 10:14:42 -0400130 prefs_.SetInt64(kPrefsPreviousSlot, 1);
Tianjie Xu90aaa102017-10-10 17:39:03 -0700131
132 EXPECT_CALL(*metrics_reporter_,
133 ReportAbnormallyTerminatedUpdateAttemptMetrics())
134 .Times(1);
135
136 Time now = Time::FromInternalValue(34456);
137 clock_->SetMonotonicTime(now);
138 TimeDelta duration = now - Time::FromInternalValue(23456);
139 EXPECT_CALL(*metrics_reporter_, ReportTimeToReboot(duration.InMinutes()))
140 .Times(1);
141
142 update_attempter_android_.Init();
143 // Check that we reset the metric prefs.
144 EXPECT_FALSE(prefs_.Exists(kPrefsNumReboots));
Tianjie Xu90aaa102017-10-10 17:39:03 -0700145 EXPECT_FALSE(prefs_.Exists(kPrefsUpdateTimestampStart));
146 EXPECT_FALSE(prefs_.Exists(kPrefsSystemUpdatedMarker));
xunchang9cf52622019-01-25 11:04:58 -0800147 // PayloadAttemptNumber should persist across reboots.
148 EXPECT_TRUE(prefs_.Exists(kPrefsPayloadAttemptNumber));
Tianjie Xu90aaa102017-10-10 17:39:03 -0700149}
150
151TEST_F(UpdateAttempterAndroidTest, ReportMetricsOnUpdateTerminated) {
152 prefs_.SetInt64(kPrefsNumReboots, 3);
153 prefs_.SetInt64(kPrefsPayloadAttemptNumber, 2);
154 prefs_.SetString(kPrefsPreviousVersion, "56789");
Tianjie Xu2a0ea632018-08-06 12:59:23 -0700155 prefs_.SetInt64(kPrefsUpdateBootTimestampStart, 10000);
Tianjie Xu90aaa102017-10-10 17:39:03 -0700156 prefs_.SetInt64(kPrefsUpdateTimestampStart, 12345);
157
Tianjie Xu52c678c2017-10-18 15:52:27 -0700158 Time boot_time = Time::FromInternalValue(22345);
159 Time up_time = Time::FromInternalValue(21345);
160 clock_->SetBootTime(boot_time);
161 clock_->SetMonotonicTime(up_time);
Tianjie Xu2a0ea632018-08-06 12:59:23 -0700162 TimeDelta duration = boot_time - Time::FromInternalValue(10000);
Tianjie Xu52c678c2017-10-18 15:52:27 -0700163 TimeDelta duration_uptime = up_time - Time::FromInternalValue(12345);
Tianjie Xu90aaa102017-10-10 17:39:03 -0700164 EXPECT_CALL(
165 *metrics_reporter_,
Amin Hassani538bd592020-11-04 20:46:08 -0800166 ReportUpdateAttemptMetrics(2,
Tianjie Xu90aaa102017-10-10 17:39:03 -0700167 _,
Tianjie Xu90aaa102017-10-10 17:39:03 -0700168 duration,
Tianjie Xu52c678c2017-10-18 15:52:27 -0700169 duration_uptime,
Tianjie Xu90aaa102017-10-10 17:39:03 -0700170 _,
171 metrics::AttemptResult::kUpdateSucceeded,
172 ErrorCode::kSuccess))
173 .Times(1);
174 EXPECT_CALL(*metrics_reporter_,
Sen Jiang8712e962018-05-08 12:12:28 -0700175 ReportSuccessfulUpdateMetrics(
Tianjie Xu21030c12019-08-14 13:00:23 -0700176 2, 0, _, 50, _, _, duration, duration_uptime, 3, _))
Tianjie Xu90aaa102017-10-10 17:39:03 -0700177 .Times(1);
178
Tianjie Xu21030c12019-08-14 13:00:23 -0700179 // Adds a payload of 50 bytes to the InstallPlan.
180 InstallPlan::Payload payload;
181 payload.size = 50;
182 AddPayload(std::move(payload));
Tianjie Xu90aaa102017-10-10 17:39:03 -0700183 SetUpdateStatus(UpdateStatus::UPDATE_AVAILABLE);
184 update_attempter_android_.ProcessingDone(nullptr, ErrorCode::kSuccess);
185
186 EXPECT_FALSE(prefs_.Exists(kPrefsNumReboots));
187 EXPECT_FALSE(prefs_.Exists(kPrefsPayloadAttemptNumber));
188 EXPECT_FALSE(prefs_.Exists(kPrefsUpdateTimestampStart));
189 EXPECT_TRUE(prefs_.Exists(kPrefsSystemUpdatedMarker));
190}
191
Tianjie Xud4777a12017-10-24 14:54:18 -0700192TEST_F(UpdateAttempterAndroidTest, ReportMetricsForBytesDownloaded) {
193 // Check both prefs are updated correctly.
194 update_attempter_android_.BytesReceived(20, 50, 200);
195 EXPECT_EQ(
196 20,
197 metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, &prefs_));
198 EXPECT_EQ(
199 20,
200 metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, &prefs_));
201
202 EXPECT_CALL(*metrics_reporter_,
203 ReportUpdateAttemptDownloadMetrics(50, _, _, _, _))
204 .Times(1);
205 EXPECT_CALL(*metrics_reporter_,
206 ReportUpdateAttemptDownloadMetrics(40, _, _, _, _))
207 .Times(1);
208
209 int64_t total_bytes[kNumDownloadSources] = {};
210 total_bytes[kDownloadSourceHttpsServer] = 90;
211 EXPECT_CALL(*metrics_reporter_,
212 ReportSuccessfulUpdateMetrics(
213 _,
214 _,
215 _,
Tianjie Xu21030c12019-08-14 13:00:23 -0700216 50,
Tianjie Xud4777a12017-10-24 14:54:18 -0700217 test_utils::DownloadSourceMatcher(total_bytes),
Tianjie Xu21030c12019-08-14 13:00:23 -0700218 80,
Tianjie Xud4777a12017-10-24 14:54:18 -0700219 _,
220 _,
Sen Jiang8712e962018-05-08 12:12:28 -0700221 _,
Tianjie Xud4777a12017-10-24 14:54:18 -0700222 _))
223 .Times(1);
224
Tianjie Xu21030c12019-08-14 13:00:23 -0700225 // Adds a payload of 50 bytes to the InstallPlan.
226 InstallPlan::Payload payload;
227 payload.size = 50;
228 AddPayload(std::move(payload));
229
Sen Jiang771f6482018-04-04 17:59:10 -0700230 // The first update fails after receiving 50 bytes in total.
Tianjie Xud4777a12017-10-24 14:54:18 -0700231 update_attempter_android_.BytesReceived(30, 50, 200);
232 update_attempter_android_.ProcessingDone(nullptr, ErrorCode::kError);
233 EXPECT_EQ(
234 0,
235 metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, &prefs_));
236 EXPECT_EQ(
237 50,
238 metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, &prefs_));
239
240 // The second update succeeds after receiving 40 bytes, which leads to a
Tianjie Xu21030c12019-08-14 13:00:23 -0700241 // overhead of (90 - 50) / 50 = 80%.
Tianjie Xud4777a12017-10-24 14:54:18 -0700242 update_attempter_android_.BytesReceived(40, 40, 50);
243 update_attempter_android_.ProcessingDone(nullptr, ErrorCode::kSuccess);
244 // Both prefs should be cleared.
245 EXPECT_EQ(
246 0,
247 metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, &prefs_));
248 EXPECT_EQ(
249 0, metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, &prefs_));
250}
251
Tianjie Xu90aaa102017-10-10 17:39:03 -0700252} // namespace chromeos_update_engine