1 /*
2 * Copyright (C) 2018 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 "BootParameters.h"
18
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22
23 #include <android-base/file.h>
24 #include <android-base/test_utils.h>
25 #include <boot_parameters.pb.h>
26 #include <gtest/gtest.h>
27
28 namespace android {
29
30 namespace {
31
TEST(BootParametersTest,TestNoBootParametersIsNotSilent)32 TEST(BootParametersTest, TestNoBootParametersIsNotSilent) {
33 android::things::proto::BootParameters proto;
34
35 BootParameters bootParameters = BootParameters();
36 bootParameters.parseBootParameters(proto.SerializeAsString());
37
38 ASSERT_FALSE(bootParameters.isSilentBoot());
39 ASSERT_EQ(0u, bootParameters.getParameters().size());
40 }
41
TEST(BootParametersTest,TestParseIsSilent)42 TEST(BootParametersTest, TestParseIsSilent) {
43 android::things::proto::BootParameters proto;
44 proto.set_silent_boot(true);
45
46 BootParameters bootParameters = BootParameters();
47 bootParameters.parseBootParameters(proto.SerializeAsString());
48
49 ASSERT_TRUE(bootParameters.isSilentBoot());
50 }
51
TEST(BootParametersTest,TestParseIsNotSilent)52 TEST(BootParametersTest, TestParseIsNotSilent) {
53 android::things::proto::BootParameters proto;
54 proto.set_silent_boot(false);
55
56 BootParameters bootParameters = BootParameters();
57 bootParameters.parseBootParameters(proto.SerializeAsString());
58
59 ASSERT_FALSE(bootParameters.isSilentBoot());
60 }
61
TEST(BootParametersTest,TestParseBootParameters)62 TEST(BootParametersTest, TestParseBootParameters) {
63 android::things::proto::BootParameters proto;
64 proto.set_silent_boot(false);
65
66 auto userParameter = proto.add_user_parameter();
67 userParameter->set_key("key1");
68 userParameter->set_value("value1");
69
70 userParameter = proto.add_user_parameter();
71 userParameter->set_key("key2");
72 userParameter->set_value("value2");
73
74 BootParameters bootParameters = BootParameters();
75 bootParameters.parseBootParameters(proto.SerializeAsString());
76
77 auto ¶meters = bootParameters.getParameters();
78 ASSERT_EQ(2u, parameters.size());
79 ASSERT_STREQ(parameters[0].key, "key1");
80 ASSERT_STREQ(parameters[0].value, "value1");
81 ASSERT_STREQ(parameters[1].key, "key2");
82 ASSERT_STREQ(parameters[1].value, "value2");
83 }
84
TEST(BootParametersTest,TestParseLegacyDisableBootAnimationIsSilent)85 TEST(BootParametersTest, TestParseLegacyDisableBootAnimationIsSilent) {
86 BootParameters bootParameters = BootParameters();
87 bootParameters.parseLegacyBootParameters(R"(
88 {
89 "brightness":200,
90 "volume":100,
91 "boot_animation_disabled":1,
92 "param_names":[],
93 "param_values":[]
94 }
95 )");
96
97 ASSERT_TRUE(bootParameters.isSilentBoot());
98 }
99
TEST(BootParametersTest,TestParseLegacyZeroVolumeIsSilent)100 TEST(BootParametersTest, TestParseLegacyZeroVolumeIsSilent) {
101 BootParameters bootParameters = BootParameters();
102 bootParameters.parseLegacyBootParameters(R"(
103 {
104 "brightness":200,
105 "volume":0,
106 "boot_animation_disabled":0,
107 "param_names":[],
108 "param_values":[]
109 }
110 )");
111
112 ASSERT_TRUE(bootParameters.isSilentBoot());
113 }
114
TEST(BootParametersTest,TestParseLegacyDefaultVolumeIsSilent)115 TEST(BootParametersTest, TestParseLegacyDefaultVolumeIsSilent) {
116 BootParameters bootParameters = BootParameters();
117 bootParameters.parseLegacyBootParameters(R"(
118 {
119 "brightness":200,
120 "volume":-1000,
121 "boot_animation_disabled":0,
122 "param_names":[],
123 "param_values":[]
124 }
125 )");
126
127 ASSERT_TRUE(bootParameters.isSilentBoot());
128 }
129
TEST(BootParametersTest,TestParseLegacyNotSilent)130 TEST(BootParametersTest, TestParseLegacyNotSilent) {
131 BootParameters bootParameters = BootParameters();
132 bootParameters.parseLegacyBootParameters(R"(
133 {
134 "brightness":200,
135 "volume":500,
136 "boot_animation_disabled":0,
137 "param_names":[],
138 "param_values":[]
139 }
140 )");
141
142 ASSERT_FALSE(bootParameters.isSilentBoot());
143 }
144
TEST(BootParametersTest,TestParseLegacyParameters)145 TEST(BootParametersTest, TestParseLegacyParameters) {
146 BootParameters bootParameters = BootParameters();
147 bootParameters.parseLegacyBootParameters(R"(
148 {
149 "brightness":200,
150 "volume":100,
151 "boot_animation_disabled":1,
152 "param_names":["key1", "key2"],
153 "param_values":["value1", "value2"]
154 }
155 )");
156
157 auto parameters = bootParameters.getParameters();
158 ASSERT_EQ(2u, parameters.size());
159 ASSERT_STREQ(parameters[0].key, "key1");
160 ASSERT_STREQ(parameters[0].value, "value1");
161 ASSERT_STREQ(parameters[1].key, "key2");
162 ASSERT_STREQ(parameters[1].value, "value2");
163 }
164
TEST(BootParametersTest,TestParseLegacyZeroParameters)165 TEST(BootParametersTest, TestParseLegacyZeroParameters) {
166 BootParameters bootParameters = BootParameters();
167 bootParameters.parseLegacyBootParameters(R"(
168 {
169 "brightness":200,
170 "volume":100,
171 "boot_animation_disabled":1,
172 "param_names":[],
173 "param_values":[]
174 }
175 )");
176
177 ASSERT_EQ(0u, bootParameters.getParameters().size());
178 }
179
TEST(BootParametersTest,TestMalformedLegacyParametersAreSkipped)180 TEST(BootParametersTest, TestMalformedLegacyParametersAreSkipped) {
181 BootParameters bootParameters = BootParameters();
182 bootParameters.parseLegacyBootParameters(R"(
183 {
184 "brightness":500,
185 "volume":500,
186 "boot_animation_disabled":0,
187 "param_names":["key1", "key2"],
188 "param_values":[1, "value2"]
189 }
190 )");
191
192 auto parameters = bootParameters.getParameters();
193 ASSERT_EQ(1u, parameters.size());
194 ASSERT_STREQ(parameters[0].key, "key2");
195 ASSERT_STREQ(parameters[0].value, "value2");
196 }
197
TEST(BootParametersTest,TestLegacyUnequalParameterSizesAreSkipped)198 TEST(BootParametersTest, TestLegacyUnequalParameterSizesAreSkipped) {
199 BootParameters bootParameters = BootParameters();
200 bootParameters.parseLegacyBootParameters(R"(
201 {
202 "brightness":500,
203 "volume":500,
204 "boot_animation_disabled":0,
205 "param_names":["key1", "key2"],
206 "param_values":["value1"]
207 }
208 )");
209
210 ASSERT_EQ(0u, bootParameters.getParameters().size());
211 }
212
TEST(BootParametersTest,TestMissingLegacyBootParametersIsSilent)213 TEST(BootParametersTest, TestMissingLegacyBootParametersIsSilent) {
214 BootParameters bootParameters = BootParameters();
215 bootParameters.parseLegacyBootParameters(R"(
216 {
217 "brightness":500
218 }
219 )");
220
221 EXPECT_TRUE(bootParameters.isSilentBoot());
222 ASSERT_EQ(0u, bootParameters.getParameters().size());
223 }
224
TEST(BootParametersTest,TestLastFileIsRemovedOnError)225 TEST(BootParametersTest, TestLastFileIsRemovedOnError) {
226 TemporaryFile lastFile;
227 TemporaryDir tempDir;
228 std::string nonExistentFilePath(std::string(tempDir.path) + "/nonexistent");
229 std::string contents;
230
231 BootParameters::swapAndLoadBootConfigContents(lastFile.path, nonExistentFilePath.c_str(),
232 &contents);
233
234 struct stat buf;
235 ASSERT_EQ(-1, lstat(lastFile.path, &buf));
236 ASSERT_TRUE(contents.empty());
237 }
238
TEST(BootParametersTest,TestNextFileIsRemovedLastFileExistsOnSuccess)239 TEST(BootParametersTest, TestNextFileIsRemovedLastFileExistsOnSuccess) {
240 TemporaryFile lastFile;
241 TemporaryFile nextFile;
242
243 base::WriteStringToFile("foo", nextFile.path);
244
245 std::string contents;
246 // Expected side effects:
247 // - |next_file| is moved to |last_file|
248 // - |contents| is the contents of |next_file| before being moved.
249 BootParameters::swapAndLoadBootConfigContents(lastFile.path, nextFile.path, &contents);
250
251 struct stat buf;
252 ASSERT_EQ(0, lstat(lastFile.path, &buf));
253 ASSERT_EQ(-1, lstat(nextFile.path, &buf));
254 ASSERT_EQ(contents, "foo");
255
256 contents.clear();
257 ASSERT_TRUE(base::ReadFileToString(lastFile.path, &contents));
258 ASSERT_EQ(contents, "foo");
259 }
260
261 } // namespace
262
263 } // namespace android
264