1 //
2 // Copyright (C) 2011 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/cros/omaha_request_params.h"
18
19 #include <stdio.h>
20
21 #include <string>
22
23 #include <base/files/file_util.h>
24 #include <base/files/scoped_temp_dir.h>
25 #include <gtest/gtest.h>
26
27 #include "update_engine/common/constants.h"
28 #include "update_engine/common/platform_constants.h"
29 #include "update_engine/common/test_utils.h"
30 #include "update_engine/common/utils.h"
31 #include "update_engine/cros/fake_system_state.h"
32
33 using chromeos_update_engine::test_utils::WriteFileString;
34 using std::string;
35
36 namespace chromeos_update_engine {
37
38 class OmahaRequestParamsTest : public ::testing::Test {
39 public:
OmahaRequestParamsTest()40 OmahaRequestParamsTest() : params_() {}
41
42 protected:
SetUp()43 void SetUp() override {
44 // Create a uniquely named test directory.
45 ASSERT_TRUE(tempdir_.CreateUniqueTempDir());
46 params_.set_root(tempdir_.GetPath().value());
47 FakeSystemState::CreateInstance();
48 SetLockDown(false);
49 }
50
SetLockDown(bool locked_down)51 void SetLockDown(bool locked_down) {
52 FakeSystemState::Get()->fake_hardware()->SetIsOfficialBuild(locked_down);
53 FakeSystemState::Get()->fake_hardware()->SetIsNormalBootMode(locked_down);
54 }
55
56 OmahaRequestParams params_;
57 base::ScopedTempDir tempdir_;
58 };
59
60 namespace {
GetMachineType()61 string GetMachineType() {
62 string machine_type;
63 if (!utils::ReadPipe("uname -m", &machine_type))
64 return "";
65 // Strip anything from the first newline char.
66 size_t newline_pos = machine_type.find('\n');
67 if (newline_pos != string::npos)
68 machine_type.erase(newline_pos);
69 return machine_type;
70 }
71 } // namespace
72
TEST_F(OmahaRequestParamsTest,MissingChannelTest)73 TEST_F(OmahaRequestParamsTest, MissingChannelTest) {
74 EXPECT_TRUE(params_.Init("", "", {}));
75 // By default, if no channel is set, we should track the stable-channel.
76 EXPECT_EQ("stable-channel", params_.target_channel());
77 }
78
TEST_F(OmahaRequestParamsTest,ForceVersionTest)79 TEST_F(OmahaRequestParamsTest, ForceVersionTest) {
80 EXPECT_TRUE(params_.Init("ForcedVersion", "", {}));
81 EXPECT_EQ(string("ForcedVersion_") + GetMachineType(), params_.os_sp());
82 EXPECT_EQ("ForcedVersion", params_.app_version());
83 }
84
TEST_F(OmahaRequestParamsTest,ForcedURLTest)85 TEST_F(OmahaRequestParamsTest, ForcedURLTest) {
86 EXPECT_TRUE(params_.Init("", "http://forced.google.com", {}));
87 EXPECT_EQ("http://forced.google.com", params_.update_url());
88 }
89
TEST_F(OmahaRequestParamsTest,MissingURLTest)90 TEST_F(OmahaRequestParamsTest, MissingURLTest) {
91 EXPECT_TRUE(params_.Init("", "", {}));
92 EXPECT_EQ(constants::kOmahaDefaultProductionURL, params_.update_url());
93 }
94
TEST_F(OmahaRequestParamsTest,DeltaOKTest)95 TEST_F(OmahaRequestParamsTest, DeltaOKTest) {
96 EXPECT_TRUE(params_.Init("", "", {}));
97 EXPECT_TRUE(params_.delta_okay());
98 }
99
TEST_F(OmahaRequestParamsTest,NoDeltasTest)100 TEST_F(OmahaRequestParamsTest, NoDeltasTest) {
101 ASSERT_TRUE(
102 WriteFileString(tempdir_.GetPath().Append(".nodelta").value(), ""));
103 EXPECT_TRUE(params_.Init("", "", {}));
104 EXPECT_FALSE(params_.delta_okay());
105 }
106
TEST_F(OmahaRequestParamsTest,SetTargetChannelTest)107 TEST_F(OmahaRequestParamsTest, SetTargetChannelTest) {
108 {
109 OmahaRequestParams params;
110 params.set_root(tempdir_.GetPath().value());
111 EXPECT_TRUE(params.Init("", "", {}));
112 EXPECT_TRUE(params.SetTargetChannel("canary-channel", false, nullptr));
113 EXPECT_FALSE(params.mutable_image_props_.is_powerwash_allowed);
114 }
115 params_.set_root(tempdir_.GetPath().value());
116 EXPECT_TRUE(params_.Init("", "", {}));
117 EXPECT_EQ("canary-channel", params_.target_channel());
118 EXPECT_FALSE(params_.mutable_image_props_.is_powerwash_allowed);
119 }
120
TEST_F(OmahaRequestParamsTest,SetIsPowerwashAllowedTest)121 TEST_F(OmahaRequestParamsTest, SetIsPowerwashAllowedTest) {
122 {
123 OmahaRequestParams params;
124 params.set_root(tempdir_.GetPath().value());
125 EXPECT_TRUE(params.Init("", "", {}));
126 EXPECT_TRUE(params.SetTargetChannel("canary-channel", true, nullptr));
127 EXPECT_TRUE(params.mutable_image_props_.is_powerwash_allowed);
128 }
129 params_.set_root(tempdir_.GetPath().value());
130 EXPECT_TRUE(params_.Init("", "", {}));
131 EXPECT_EQ("canary-channel", params_.target_channel());
132 EXPECT_TRUE(params_.mutable_image_props_.is_powerwash_allowed);
133 }
134
TEST_F(OmahaRequestParamsTest,SetTargetChannelInvalidTest)135 TEST_F(OmahaRequestParamsTest, SetTargetChannelInvalidTest) {
136 {
137 OmahaRequestParams params;
138 params.set_root(tempdir_.GetPath().value());
139 SetLockDown(true);
140 EXPECT_TRUE(params.Init("", "", {}));
141 params.image_props_.allow_arbitrary_channels = false;
142 string error_message;
143 EXPECT_FALSE(
144 params.SetTargetChannel("dogfood-channel", true, &error_message));
145 // The error message should include a message about the valid channels.
146 EXPECT_NE(string::npos, error_message.find("stable-channel"));
147 EXPECT_FALSE(params.mutable_image_props_.is_powerwash_allowed);
148 }
149 params_.set_root(tempdir_.GetPath().value());
150 EXPECT_TRUE(params_.Init("", "", {}));
151 EXPECT_EQ("stable-channel", params_.target_channel());
152 EXPECT_FALSE(params_.mutable_image_props_.is_powerwash_allowed);
153 }
154
TEST_F(OmahaRequestParamsTest,IsValidChannelTest)155 TEST_F(OmahaRequestParamsTest, IsValidChannelTest) {
156 EXPECT_TRUE(params_.IsValidChannel("canary-channel"));
157 EXPECT_TRUE(params_.IsValidChannel("stable-channel"));
158 EXPECT_TRUE(params_.IsValidChannel("beta-channel"));
159 EXPECT_TRUE(params_.IsValidChannel("dev-channel"));
160 EXPECT_FALSE(params_.IsValidChannel("testimage-channel"));
161 EXPECT_FALSE(params_.IsValidChannel("dogfood-channel"));
162 EXPECT_FALSE(params_.IsValidChannel("some-channel"));
163 EXPECT_FALSE(params_.IsValidChannel(""));
164 params_.image_props_.allow_arbitrary_channels = true;
165 EXPECT_TRUE(params_.IsValidChannel("some-channel"));
166 EXPECT_FALSE(params_.IsValidChannel("wrong-suffix"));
167 EXPECT_FALSE(params_.IsValidChannel(""));
168 }
169
TEST_F(OmahaRequestParamsTest,SetTargetChannelWorks)170 TEST_F(OmahaRequestParamsTest, SetTargetChannelWorks) {
171 params_.set_target_channel("dev-channel");
172 EXPECT_EQ("dev-channel", params_.target_channel());
173
174 // When an invalid value is set, it should be ignored.
175 EXPECT_FALSE(params_.SetTargetChannel("invalid-channel", false, nullptr));
176 EXPECT_EQ("dev-channel", params_.target_channel());
177
178 // When set to a valid value, it should take effect.
179 EXPECT_TRUE(params_.SetTargetChannel("beta-channel", true, nullptr));
180 EXPECT_EQ("beta-channel", params_.target_channel());
181
182 // When set to the same value, it should be idempotent.
183 EXPECT_TRUE(params_.SetTargetChannel("beta-channel", true, nullptr));
184 EXPECT_EQ("beta-channel", params_.target_channel());
185
186 // When set to a valid value while a change is already pending, it should
187 // succeed.
188 EXPECT_TRUE(params_.SetTargetChannel("stable-channel", true, nullptr));
189 EXPECT_EQ("stable-channel", params_.target_channel());
190
191 // Set a different channel in mutable_image_props_.
192 params_.set_target_channel("stable-channel");
193
194 // When set to a valid value while a change is already pending, it should
195 // succeed.
196 params_.Init("", "", {});
197 EXPECT_TRUE(params_.SetTargetChannel("beta-channel", true, nullptr));
198 // The target channel should reflect the change, but the download channel
199 // should continue to retain the old value ...
200 EXPECT_EQ("beta-channel", params_.target_channel());
201 EXPECT_EQ("stable-channel", params_.download_channel());
202
203 // ... until we update the download channel explicitly.
204 params_.UpdateDownloadChannel();
205 EXPECT_EQ("beta-channel", params_.download_channel());
206 EXPECT_EQ("beta-channel", params_.target_channel());
207 }
208
TEST_F(OmahaRequestParamsTest,ChannelIndexTest)209 TEST_F(OmahaRequestParamsTest, ChannelIndexTest) {
210 int canary = params_.GetChannelIndex("canary-channel");
211 int dev = params_.GetChannelIndex("dev-channel");
212 int beta = params_.GetChannelIndex("beta-channel");
213 int stable = params_.GetChannelIndex("stable-channel");
214 EXPECT_LE(canary, dev);
215 EXPECT_LE(dev, beta);
216 EXPECT_LE(beta, stable);
217
218 // testimage-channel or other names are not recognized, so index will be -1.
219 int testimage = params_.GetChannelIndex("testimage-channel");
220 int bogus = params_.GetChannelIndex("bogus-channel");
221 EXPECT_EQ(-1, testimage);
222 EXPECT_EQ(-1, bogus);
223 }
224
TEST_F(OmahaRequestParamsTest,ToMoreStableChannelFlagTest)225 TEST_F(OmahaRequestParamsTest, ToMoreStableChannelFlagTest) {
226 params_.image_props_.current_channel = "canary-channel";
227 params_.download_channel_ = "stable-channel";
228 EXPECT_TRUE(params_.ToMoreStableChannel());
229 params_.image_props_.current_channel = "stable-channel";
230 EXPECT_FALSE(params_.ToMoreStableChannel());
231 params_.download_channel_ = "beta-channel";
232 EXPECT_FALSE(params_.ToMoreStableChannel());
233 }
234
TEST_F(OmahaRequestParamsTest,TargetChannelHintTest)235 TEST_F(OmahaRequestParamsTest, TargetChannelHintTest) {
236 EXPECT_TRUE(params_.Init("", "", {}));
237 const string kHint("foo-hint");
238 params_.set_lts_tag(kHint);
239 EXPECT_EQ(kHint, params_.lts_tag());
240 }
241
TEST_F(OmahaRequestParamsTest,ShouldPowerwashTest)242 TEST_F(OmahaRequestParamsTest, ShouldPowerwashTest) {
243 params_.mutable_image_props_.is_powerwash_allowed = false;
244 EXPECT_FALSE(params_.ShouldPowerwash());
245 params_.mutable_image_props_.is_powerwash_allowed = true;
246 params_.image_props_.allow_arbitrary_channels = true;
247 params_.image_props_.current_channel = "foo-channel";
248 params_.download_channel_ = "bar-channel";
249 EXPECT_TRUE(params_.ShouldPowerwash());
250 params_.image_props_.allow_arbitrary_channels = false;
251 params_.image_props_.current_channel = "canary-channel";
252 params_.download_channel_ = "stable-channel";
253 EXPECT_TRUE(params_.ShouldPowerwash());
254 }
255
TEST_F(OmahaRequestParamsTest,RequisitionIsSetTest)256 TEST_F(OmahaRequestParamsTest, RequisitionIsSetTest) {
257 EXPECT_TRUE(params_.Init("", "", {}));
258 EXPECT_EQ("fake_requisition", params_.device_requisition());
259 }
260
TEST_F(OmahaRequestParamsTest,GetMissingDlcId)261 TEST_F(OmahaRequestParamsTest, GetMissingDlcId) {
262 EXPECT_TRUE(params_.Init("", "", {}));
263
264 string dlc_id;
265 EXPECT_FALSE(params_.GetDlcId("some-dlc-app-id", &dlc_id));
266 }
267
TEST_F(OmahaRequestParamsTest,GetDlcId)268 TEST_F(OmahaRequestParamsTest, GetDlcId) {
269 EXPECT_TRUE(params_.Init("", "", {}));
270 const string kExpectedDlcId = "test-dlc";
271 const string dlc_app_id = params_.GetDlcAppId(kExpectedDlcId);
272 params_.set_dlc_apps_params({{dlc_app_id, {.name = kExpectedDlcId}}});
273
274 string dlc_id;
275 EXPECT_TRUE(params_.GetDlcId(dlc_app_id, &dlc_id));
276 EXPECT_EQ(kExpectedDlcId, dlc_id);
277 }
278
TEST_F(OmahaRequestParamsTest,GetDlcAppId)279 TEST_F(OmahaRequestParamsTest, GetDlcAppId) {
280 EXPECT_TRUE(params_.Init("", "", {}));
281 const string kAppId = "test-app-id";
282 params_.set_app_id(kAppId);
283 const string kDlcId = "test-dlc";
284 const string expected_dlc_app_id = kAppId + "_" + kDlcId;
285
286 EXPECT_EQ(expected_dlc_app_id, params_.GetDlcAppId(kDlcId));
287 }
288
TEST_F(OmahaRequestParamsTest,AutoUpdateTokenTest)289 TEST_F(OmahaRequestParamsTest, AutoUpdateTokenTest) {
290 EXPECT_TRUE(params_.Init("", "", {.quick_fix_build_token = "foo-token"}));
291 EXPECT_EQ("foo-token", params_.autoupdate_token());
292 }
293
294 } // namespace chromeos_update_engine
295