• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <fcntl.h>
24 #include <sys/sendfile.h>
25 #include <unistd.h>
26 
27 #include <android-base/properties.h>
28 #include <base/time/time.h>
29 #include <brillo/data_encoding.h>
30 #include <brillo/message_loops/fake_message_loop.h>
31 #include <gtest/gtest.h>
32 #include <liblp/builder.h>
33 #include <fs_mgr.h>
34 #include <liblp/liblp.h>
35 
36 #include "update_engine/aosp/boot_control_android.h"
37 #include "update_engine/aosp/daemon_state_android.h"
38 #include "update_engine/common/constants.h"
39 #include "update_engine/common/fake_boot_control.h"
40 #include "update_engine/common/fake_clock.h"
41 #include "update_engine/common/fake_hardware.h"
42 #include "update_engine/common/fake_prefs.h"
43 #include "update_engine/common/hash_calculator.h"
44 #include "update_engine/common/mock_action_processor.h"
45 #include "update_engine/common/mock_metrics_reporter.h"
46 #include "update_engine/common/prefs.h"
47 #include "update_engine/common/test_utils.h"
48 #include "update_engine/common/testing_constants.h"
49 #include "update_engine/common/utils.h"
50 #include "update_engine/payload_consumer/install_plan.h"
51 #include "update_engine/payload_consumer/payload_constants.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"
58 
59 using base::Time;
60 using base::TimeDelta;
61 using testing::_;
62 using update_engine::UpdateStatus;
63 
64 namespace chromeos_update_engine {
65 
66 // Compare the value of builtin array for download source parameter.
67 MATCHER_P(DownloadSourceMatcher, source_array, "") {
68   return std::equal(source_array, source_array + kNumDownloadSources, arg);
69 }
70 
71 class UpdateAttempterAndroidTest : public ::testing::Test {
72  protected:
73   UpdateAttempterAndroidTest() = default;
74 
SetUp()75   void SetUp() override {
76     clock_ = new FakeClock();
77     metrics_reporter_ = new testing::NiceMock<MockMetricsReporter>();
78     update_attempter_android_.metrics_reporter_.reset(metrics_reporter_);
79     update_attempter_android_.clock_.reset(clock_);
80     update_attempter_android_.processor_.reset(
81         new testing::NiceMock<MockActionProcessor>());
82   }
83 
SetUpdateStatus(update_engine::UpdateStatus status)84   void SetUpdateStatus(update_engine::UpdateStatus status) {
85     update_attempter_android_.status_ = status;
86   }
87 
AddPayload(InstallPlan::Payload && payload)88   void AddPayload(InstallPlan::Payload&& payload) {
89     update_attempter_android_.install_plan_.payloads.push_back(
90         std::move(payload));
91   }
92 
93   DaemonStateAndroid daemon_state_;
94   FakePrefs prefs_;
95   FakeBootControl boot_control_;
96   FakeHardware hardware_;
97 
98   UpdateAttempterAndroid update_attempter_android_{
99       &daemon_state_, &prefs_, &boot_control_, &hardware_, nullptr};
100 
101   FakeClock* clock_;
102   testing::NiceMock<MockMetricsReporter>* metrics_reporter_;
103 };
104 
105 namespace {
106 
TEST_F(UpdateAttempterAndroidTest,UpdatePrefsSameBuildVersionOnInit)107 TEST_F(UpdateAttempterAndroidTest, UpdatePrefsSameBuildVersionOnInit) {
108   std::string build_version =
109       android::base::GetProperty("ro.build.version.incremental", "");
110   prefs_.SetString(kPrefsPreviousVersion, build_version);
111   prefs_.SetString(kPrefsBootId, "oldboot");
112   prefs_.SetInt64(kPrefsNumReboots, 1);
113   prefs_.SetInt64(kPrefsPreviousSlot, 1);
114   boot_control_.SetCurrentSlot(1);
115 
116   EXPECT_CALL(*metrics_reporter_, ReportTimeToReboot(_)).Times(0);
117   update_attempter_android_.Init();
118 
119   // Check that the boot_id and reboot_count are updated.
120   std::string boot_id;
121   utils::GetBootId(&boot_id);
122   ASSERT_TRUE(prefs_.Exists(kPrefsBootId));
123   std::string prefs_boot_id;
124   ASSERT_TRUE(prefs_.GetString(kPrefsBootId, &prefs_boot_id));
125   ASSERT_EQ(boot_id, prefs_boot_id);
126 
127   ASSERT_TRUE(prefs_.Exists(kPrefsNumReboots));
128   int64_t reboot_count;
129   ASSERT_TRUE(prefs_.GetInt64(kPrefsNumReboots, &reboot_count));
130   ASSERT_EQ(2, reboot_count);
131 }
132 
TEST_F(UpdateAttempterAndroidTest,UpdatePrefsBuildVersionChangeOnInit)133 TEST_F(UpdateAttempterAndroidTest, UpdatePrefsBuildVersionChangeOnInit) {
134   prefs_.SetString(kPrefsPreviousVersion, "00001");  // Set the fake version
135   prefs_.SetInt64(kPrefsPayloadAttemptNumber, 1);
136   prefs_.SetInt64(kPrefsSystemUpdatedMarker, 23456);
137   prefs_.SetInt64(kPrefsPreviousSlot, 1);
138 
139   EXPECT_CALL(*metrics_reporter_,
140               ReportAbnormallyTerminatedUpdateAttemptMetrics())
141       .Times(1);
142 
143   Time now = Time::FromInternalValue(34456);
144   clock_->SetMonotonicTime(now);
145   TimeDelta duration = now - Time::FromInternalValue(23456);
146   EXPECT_CALL(*metrics_reporter_, ReportTimeToReboot(duration.InMinutes()))
147       .Times(1);
148 
149   update_attempter_android_.Init();
150   // Check that we reset the metric prefs.
151   EXPECT_FALSE(prefs_.Exists(kPrefsNumReboots));
152   EXPECT_FALSE(prefs_.Exists(kPrefsUpdateTimestampStart));
153   EXPECT_FALSE(prefs_.Exists(kPrefsSystemUpdatedMarker));
154   // PayloadAttemptNumber should persist across reboots.
155   EXPECT_TRUE(prefs_.Exists(kPrefsPayloadAttemptNumber));
156 }
157 
TEST_F(UpdateAttempterAndroidTest,ReportMetricsOnUpdateTerminated)158 TEST_F(UpdateAttempterAndroidTest, ReportMetricsOnUpdateTerminated) {
159   prefs_.SetInt64(kPrefsNumReboots, 3);
160   prefs_.SetInt64(kPrefsPayloadAttemptNumber, 2);
161   prefs_.SetString(kPrefsPreviousVersion, "56789");
162   prefs_.SetInt64(kPrefsUpdateBootTimestampStart, 10000);
163   prefs_.SetInt64(kPrefsUpdateTimestampStart, 12345);
164 
165   Time boot_time = Time::FromInternalValue(22345);
166   Time up_time = Time::FromInternalValue(21345);
167   clock_->SetBootTime(boot_time);
168   clock_->SetMonotonicTime(up_time);
169   TimeDelta duration = boot_time - Time::FromInternalValue(10000);
170   TimeDelta duration_uptime = up_time - Time::FromInternalValue(12345);
171   EXPECT_CALL(
172       *metrics_reporter_,
173       ReportUpdateAttemptMetrics(2,
174                                  _,
175                                  duration,
176                                  duration_uptime,
177                                  _,
178                                  metrics::AttemptResult::kUpdateSucceeded,
179                                  ErrorCode::kSuccess))
180       .Times(1);
181   EXPECT_CALL(*metrics_reporter_,
182               ReportSuccessfulUpdateMetrics(
183                   2, 0, _, 50, _, _, duration, duration_uptime, 3, _))
184       .Times(1);
185 
186   // Adds a payload of 50 bytes to the InstallPlan.
187   InstallPlan::Payload payload;
188   payload.size = 50;
189   AddPayload(std::move(payload));
190   SetUpdateStatus(UpdateStatus::UPDATE_AVAILABLE);
191   update_attempter_android_.ProcessingDone(nullptr, ErrorCode::kSuccess);
192 
193   EXPECT_FALSE(prefs_.Exists(kPrefsNumReboots));
194   EXPECT_FALSE(prefs_.Exists(kPrefsPayloadAttemptNumber));
195   EXPECT_FALSE(prefs_.Exists(kPrefsUpdateTimestampStart));
196   EXPECT_TRUE(prefs_.Exists(kPrefsSystemUpdatedMarker));
197 }
198 
TEST_F(UpdateAttempterAndroidTest,ReportMetricsForBytesDownloaded)199 TEST_F(UpdateAttempterAndroidTest, ReportMetricsForBytesDownloaded) {
200   // Check both prefs are updated correctly.
201   update_attempter_android_.BytesReceived(20, 50, 200);
202   EXPECT_EQ(
203       20,
204       metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, &prefs_));
205   EXPECT_EQ(
206       20,
207       metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, &prefs_));
208 
209   EXPECT_CALL(*metrics_reporter_,
210               ReportUpdateAttemptDownloadMetrics(50, _, _, _, _))
211       .Times(1);
212   EXPECT_CALL(*metrics_reporter_,
213               ReportUpdateAttemptDownloadMetrics(40, _, _, _, _))
214       .Times(1);
215 
216   int64_t total_bytes[kNumDownloadSources] = {};
217   total_bytes[kDownloadSourceHttpsServer] = 90;
218   EXPECT_CALL(
219       *metrics_reporter_,
220       ReportSuccessfulUpdateMetrics(
221           _, _, _, 50, DownloadSourceMatcher(total_bytes), 80, _, _, _, _))
222       .Times(1);
223 
224   // Adds a payload of 50 bytes to the InstallPlan.
225   InstallPlan::Payload payload;
226   payload.size = 50;
227   AddPayload(std::move(payload));
228 
229   // The first update fails after receiving 50 bytes in total.
230   update_attempter_android_.BytesReceived(30, 50, 200);
231   update_attempter_android_.ProcessingDone(nullptr, ErrorCode::kError);
232   EXPECT_EQ(
233       0,
234       metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, &prefs_));
235   EXPECT_EQ(
236       50,
237       metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, &prefs_));
238 
239   // The second update succeeds after receiving 40 bytes, which leads to a
240   // overhead of (90 - 50) / 50 = 80%.
241   update_attempter_android_.BytesReceived(40, 40, 50);
242   update_attempter_android_.ProcessingDone(nullptr, ErrorCode::kSuccess);
243   // Both prefs should be cleared.
244   EXPECT_EQ(
245       0,
246       metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, &prefs_));
247   EXPECT_EQ(
248       0, metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, &prefs_));
249 }
250 
251 }  // namespace
252 
253 }  // namespace chromeos_update_engine
254