blob: 0357accfe190cd578fa6c11ef3f8efaba12247d3 [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.
Tianjie Xucace7432017-03-03 11:28:49 -080036 if (has_misc) {
37 std::string err;
38 ASSERT_TRUE(clear_bootloader_message(&err)) << "Failed to clear BCB: " << err;
39 }
Tao Bao8b7301b2016-12-14 15:52:34 -080040 }
Tianjie Xuca948562017-02-28 12:26:29 -080041
42 bool has_misc;
Tao Bao8b7301b2016-12-14 15:52:34 -080043};
44
45TEST_F(BootloaderMessageTest, clear_bootloader_message) {
Tianjie Xuca948562017-02-28 12:26:29 -080046 if (!has_misc) {
47 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
48 return;
49 }
50
Tao Bao8b7301b2016-12-14 15:52:34 -080051 // Clear the BCB.
52 std::string err;
53 ASSERT_TRUE(clear_bootloader_message(&err)) << "Failed to clear BCB: " << err;
54
55 // Verify the content.
56 bootloader_message boot;
57 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
58
59 // All the bytes should be cleared.
60 ASSERT_EQ(std::string(sizeof(boot), '\0'),
61 std::string(reinterpret_cast<const char*>(&boot), sizeof(boot)));
62}
63
64TEST_F(BootloaderMessageTest, read_and_write_bootloader_message) {
Tianjie Xuca948562017-02-28 12:26:29 -080065 if (!has_misc) {
66 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
67 return;
68 }
69
Tao Bao8b7301b2016-12-14 15:52:34 -080070 // Write the BCB.
71 bootloader_message boot = {};
72 strlcpy(boot.command, "command", sizeof(boot.command));
73 strlcpy(boot.recovery, "message1\nmessage2\n", sizeof(boot.recovery));
74 strlcpy(boot.status, "status1", sizeof(boot.status));
75
76 std::string err;
77 ASSERT_TRUE(write_bootloader_message(boot, &err)) << "Failed to write BCB: " << err;
78
79 // Read and verify.
80 bootloader_message boot_verify;
81 ASSERT_TRUE(read_bootloader_message(&boot_verify, &err)) << "Failed to read BCB: " << err;
82
83 ASSERT_EQ(std::string(reinterpret_cast<const char*>(&boot), sizeof(boot)),
84 std::string(reinterpret_cast<const char*>(&boot_verify), sizeof(boot_verify)));
85}
86
87TEST_F(BootloaderMessageTest, write_bootloader_message_options) {
Tianjie Xuca948562017-02-28 12:26:29 -080088 if (!has_misc) {
89 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
90 return;
91 }
92
Tao Bao8b7301b2016-12-14 15:52:34 -080093 // Write the options to BCB.
94 std::vector<std::string> options = { "option1", "option2" };
95 std::string err;
96 ASSERT_TRUE(write_bootloader_message(options, &err)) << "Failed to write BCB: " << err;
97
98 // Inject some bytes into boot, which should be overwritten while reading.
99 bootloader_message boot;
100 strlcpy(boot.recovery, "random message", sizeof(boot.recovery));
101 strlcpy(boot.reserved, "reserved bytes", sizeof(boot.reserved));
102
103 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
104
105 // Verify that command and recovery fields should be set.
106 ASSERT_EQ("boot-recovery", std::string(boot.command));
107 std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
108 ASSERT_EQ(expected, std::string(boot.recovery));
109
110 // The rest should be cleared.
111 ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status)));
112 ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage)));
113 ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'),
114 std::string(boot.reserved, sizeof(boot.reserved)));
115}
116
117TEST_F(BootloaderMessageTest, write_bootloader_message_options_empty) {
Tianjie Xuca948562017-02-28 12:26:29 -0800118 if (!has_misc) {
119 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
120 return;
121 }
122
Tao Bao8b7301b2016-12-14 15:52:34 -0800123 // Write empty vector.
124 std::vector<std::string> options;
125 std::string err;
126 ASSERT_TRUE(write_bootloader_message(options, &err)) << "Failed to write BCB: " << err;
127
128 // Read and verify.
129 bootloader_message boot;
130 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
131
132 // command and recovery fields should be set.
133 ASSERT_EQ("boot-recovery", std::string(boot.command));
134 ASSERT_EQ("recovery\n", std::string(boot.recovery));
135
136 // The rest should be cleared.
137 ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status)));
138 ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage)));
139 ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'),
140 std::string(boot.reserved, sizeof(boot.reserved)));
141}
142
143TEST_F(BootloaderMessageTest, write_bootloader_message_options_long) {
Tianjie Xuca948562017-02-28 12:26:29 -0800144 if (!has_misc) {
145 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
146 return;
147 }
148
Tao Bao8b7301b2016-12-14 15:52:34 -0800149 // Write super long message.
150 std::vector<std::string> options;
151 for (int i = 0; i < 100; i++) {
152 options.push_back("option: " + std::to_string(i));
153 }
154
155 std::string err;
156 ASSERT_TRUE(write_bootloader_message(options, &err)) << "Failed to write BCB: " << err;
157
158 // Read and verify.
159 bootloader_message boot;
160 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
161
162 // Make sure it's long enough.
163 std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
164 ASSERT_GE(expected.size(), sizeof(boot.recovery));
165
166 // command and recovery fields should be set.
167 ASSERT_EQ("boot-recovery", std::string(boot.command));
168 ASSERT_EQ(expected.substr(0, sizeof(boot.recovery) - 1), std::string(boot.recovery));
169 ASSERT_EQ('\0', boot.recovery[sizeof(boot.recovery) - 1]);
170
171 // The rest should be cleared.
172 ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status)));
173 ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage)));
174 ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'),
175 std::string(boot.reserved, sizeof(boot.reserved)));
176}
Tao Bao2292db82016-12-13 21:53:31 -0800177
178TEST_F(BootloaderMessageTest, update_bootloader_message) {
Tianjie Xuca948562017-02-28 12:26:29 -0800179 if (!has_misc) {
180 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
181 return;
182 }
183
Tao Bao2292db82016-12-13 21:53:31 -0800184 // Inject some bytes into boot, which should be not overwritten later.
185 bootloader_message boot;
186 strlcpy(boot.recovery, "random message", sizeof(boot.recovery));
187 strlcpy(boot.reserved, "reserved bytes", sizeof(boot.reserved));
188 std::string err;
189 ASSERT_TRUE(write_bootloader_message(boot, &err)) << "Failed to write BCB: " << err;
190
191 // Update the BCB message.
192 std::vector<std::string> options = { "option1", "option2" };
193 ASSERT_TRUE(update_bootloader_message(options, &err)) << "Failed to update BCB: " << err;
194
195 bootloader_message boot_verify;
196 ASSERT_TRUE(read_bootloader_message(&boot_verify, &err)) << "Failed to read BCB: " << err;
197
198 // Verify that command and recovery fields should be set.
199 ASSERT_EQ("boot-recovery", std::string(boot_verify.command));
200 std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
201 ASSERT_EQ(expected, std::string(boot_verify.recovery));
202
203 // The rest should be intact.
204 ASSERT_EQ(std::string(boot.status), std::string(boot_verify.status));
205 ASSERT_EQ(std::string(boot.stage), std::string(boot_verify.stage));
206 ASSERT_EQ(std::string(boot.reserved), std::string(boot_verify.reserved));
207}