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