blob: c32519d80c4a5f385b6064d2c14cb21cb01a5287 [file] [log] [blame]
Tao Bao8b7301b2016-12-14 15:52:34 -08001/*
2 * Copyright (C) 2016 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
Tianjie Xuca948562017-02-28 12:26:29 -080017#include <string>
18#include <vector>
19
Tao Bao8b7301b2016-12-14 15:52:34 -080020#include <android-base/strings.h>
21#include <bootloader_message/bootloader_message.h>
22#include <gtest/gtest.h>
23
Tianjie Xuca948562017-02-28 12:26:29 -080024#include "common/component_test_util.h"
Tao Bao8b7301b2016-12-14 15:52:34 -080025
26class BootloaderMessageTest : public ::testing::Test {
27 protected:
Tianjie Xuca948562017-02-28 12:26:29 -080028 BootloaderMessageTest() : has_misc(true) {}
29
30 virtual void SetUp() override {
31 has_misc = parse_misc();
32 }
33
Tao Bao8b7301b2016-12-14 15:52:34 -080034 virtual void TearDown() override {
35 // Clear the BCB.
36 std::string err;
37 ASSERT_TRUE(clear_bootloader_message(&err)) << "Failed to clear BCB: " << err;
38 }
Tianjie Xuca948562017-02-28 12:26:29 -080039
40 bool has_misc;
Tao Bao8b7301b2016-12-14 15:52:34 -080041};
42
43TEST_F(BootloaderMessageTest, clear_bootloader_message) {
Tianjie Xuca948562017-02-28 12:26:29 -080044 if (!has_misc) {
45 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
46 return;
47 }
48
Tao Bao8b7301b2016-12-14 15:52:34 -080049 // Clear the BCB.
50 std::string err;
51 ASSERT_TRUE(clear_bootloader_message(&err)) << "Failed to clear BCB: " << err;
52
53 // Verify the content.
54 bootloader_message boot;
55 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
56
57 // All the bytes should be cleared.
58 ASSERT_EQ(std::string(sizeof(boot), '\0'),
59 std::string(reinterpret_cast<const char*>(&boot), sizeof(boot)));
60}
61
62TEST_F(BootloaderMessageTest, read_and_write_bootloader_message) {
Tianjie Xuca948562017-02-28 12:26:29 -080063 if (!has_misc) {
64 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
65 return;
66 }
67
Tao Bao8b7301b2016-12-14 15:52:34 -080068 // Write the BCB.
69 bootloader_message boot = {};
70 strlcpy(boot.command, "command", sizeof(boot.command));
71 strlcpy(boot.recovery, "message1\nmessage2\n", sizeof(boot.recovery));
72 strlcpy(boot.status, "status1", sizeof(boot.status));
73
74 std::string err;
75 ASSERT_TRUE(write_bootloader_message(boot, &err)) << "Failed to write BCB: " << err;
76
77 // Read and verify.
78 bootloader_message boot_verify;
79 ASSERT_TRUE(read_bootloader_message(&boot_verify, &err)) << "Failed to read BCB: " << err;
80
81 ASSERT_EQ(std::string(reinterpret_cast<const char*>(&boot), sizeof(boot)),
82 std::string(reinterpret_cast<const char*>(&boot_verify), sizeof(boot_verify)));
83}
84
85TEST_F(BootloaderMessageTest, write_bootloader_message_options) {
Tianjie Xuca948562017-02-28 12:26:29 -080086 if (!has_misc) {
87 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
88 return;
89 }
90
Tao Bao8b7301b2016-12-14 15:52:34 -080091 // Write the options to BCB.
92 std::vector<std::string> options = { "option1", "option2" };
93 std::string err;
94 ASSERT_TRUE(write_bootloader_message(options, &err)) << "Failed to write BCB: " << err;
95
96 // Inject some bytes into boot, which should be overwritten while reading.
97 bootloader_message boot;
98 strlcpy(boot.recovery, "random message", sizeof(boot.recovery));
99 strlcpy(boot.reserved, "reserved bytes", sizeof(boot.reserved));
100
101 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
102
103 // Verify that command and recovery fields should be set.
104 ASSERT_EQ("boot-recovery", std::string(boot.command));
105 std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
106 ASSERT_EQ(expected, std::string(boot.recovery));
107
108 // The rest should be cleared.
109 ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status)));
110 ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage)));
111 ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'),
112 std::string(boot.reserved, sizeof(boot.reserved)));
113}
114
115TEST_F(BootloaderMessageTest, write_bootloader_message_options_empty) {
Tianjie Xuca948562017-02-28 12:26:29 -0800116 if (!has_misc) {
117 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
118 return;
119 }
120
Tao Bao8b7301b2016-12-14 15:52:34 -0800121 // Write empty vector.
122 std::vector<std::string> options;
123 std::string err;
124 ASSERT_TRUE(write_bootloader_message(options, &err)) << "Failed to write BCB: " << err;
125
126 // Read and verify.
127 bootloader_message boot;
128 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
129
130 // command and recovery fields should be set.
131 ASSERT_EQ("boot-recovery", std::string(boot.command));
132 ASSERT_EQ("recovery\n", std::string(boot.recovery));
133
134 // The rest should be cleared.
135 ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status)));
136 ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage)));
137 ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'),
138 std::string(boot.reserved, sizeof(boot.reserved)));
139}
140
141TEST_F(BootloaderMessageTest, write_bootloader_message_options_long) {
Tianjie Xuca948562017-02-28 12:26:29 -0800142 if (!has_misc) {
143 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
144 return;
145 }
146
Tao Bao8b7301b2016-12-14 15:52:34 -0800147 // Write super long message.
148 std::vector<std::string> options;
149 for (int i = 0; i < 100; i++) {
150 options.push_back("option: " + std::to_string(i));
151 }
152
153 std::string err;
154 ASSERT_TRUE(write_bootloader_message(options, &err)) << "Failed to write BCB: " << err;
155
156 // Read and verify.
157 bootloader_message boot;
158 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
159
160 // Make sure it's long enough.
161 std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
162 ASSERT_GE(expected.size(), sizeof(boot.recovery));
163
164 // command and recovery fields should be set.
165 ASSERT_EQ("boot-recovery", std::string(boot.command));
166 ASSERT_EQ(expected.substr(0, sizeof(boot.recovery) - 1), std::string(boot.recovery));
167 ASSERT_EQ('\0', boot.recovery[sizeof(boot.recovery) - 1]);
168
169 // The rest should be cleared.
170 ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status)));
171 ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage)));
172 ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'),
173 std::string(boot.reserved, sizeof(boot.reserved)));
174}
Tao Bao2292db82016-12-13 21:53:31 -0800175
176TEST_F(BootloaderMessageTest, update_bootloader_message) {
Tianjie Xuca948562017-02-28 12:26:29 -0800177 if (!has_misc) {
178 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
179 return;
180 }
181
Tao Bao2292db82016-12-13 21:53:31 -0800182 // Inject some bytes into boot, which should be not overwritten later.
183 bootloader_message boot;
184 strlcpy(boot.recovery, "random message", sizeof(boot.recovery));
185 strlcpy(boot.reserved, "reserved bytes", sizeof(boot.reserved));
186 std::string err;
187 ASSERT_TRUE(write_bootloader_message(boot, &err)) << "Failed to write BCB: " << err;
188
189 // Update the BCB message.
190 std::vector<std::string> options = { "option1", "option2" };
191 ASSERT_TRUE(update_bootloader_message(options, &err)) << "Failed to update BCB: " << err;
192
193 bootloader_message boot_verify;
194 ASSERT_TRUE(read_bootloader_message(&boot_verify, &err)) << "Failed to read BCB: " << err;
195
196 // Verify that command and recovery fields should be set.
197 ASSERT_EQ("boot-recovery", std::string(boot_verify.command));
198 std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
199 ASSERT_EQ(expected, std::string(boot_verify.recovery));
200
201 // The rest should be intact.
202 ASSERT_EQ(std::string(boot.status), std::string(boot_verify.status));
203 ASSERT_EQ(std::string(boot.stage), std::string(boot_verify.stage));
204 ASSERT_EQ(std::string(boot.reserved), std::string(boot_verify.reserved));
205}