blob: dbcaf619e470b8d8b1929da083426b23a9e5fd2d [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
17#include <android-base/strings.h>
18#include <bootloader_message/bootloader_message.h>
19#include <gtest/gtest.h>
20
21#include <string>
22#include <vector>
23
24class BootloaderMessageTest : public ::testing::Test {
25 protected:
26 virtual void TearDown() override {
27 // Clear the BCB.
28 std::string err;
29 ASSERT_TRUE(clear_bootloader_message(&err)) << "Failed to clear BCB: " << err;
30 }
31};
32
33TEST_F(BootloaderMessageTest, clear_bootloader_message) {
34 // Clear the BCB.
35 std::string err;
36 ASSERT_TRUE(clear_bootloader_message(&err)) << "Failed to clear BCB: " << err;
37
38 // Verify the content.
39 bootloader_message boot;
40 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
41
42 // All the bytes should be cleared.
43 ASSERT_EQ(std::string(sizeof(boot), '\0'),
44 std::string(reinterpret_cast<const char*>(&boot), sizeof(boot)));
45}
46
47TEST_F(BootloaderMessageTest, read_and_write_bootloader_message) {
48 // Write the BCB.
49 bootloader_message boot = {};
50 strlcpy(boot.command, "command", sizeof(boot.command));
51 strlcpy(boot.recovery, "message1\nmessage2\n", sizeof(boot.recovery));
52 strlcpy(boot.status, "status1", sizeof(boot.status));
53
54 std::string err;
55 ASSERT_TRUE(write_bootloader_message(boot, &err)) << "Failed to write BCB: " << err;
56
57 // Read and verify.
58 bootloader_message boot_verify;
59 ASSERT_TRUE(read_bootloader_message(&boot_verify, &err)) << "Failed to read BCB: " << err;
60
61 ASSERT_EQ(std::string(reinterpret_cast<const char*>(&boot), sizeof(boot)),
62 std::string(reinterpret_cast<const char*>(&boot_verify), sizeof(boot_verify)));
63}
64
65TEST_F(BootloaderMessageTest, write_bootloader_message_options) {
66 // Write the options to BCB.
67 std::vector<std::string> options = { "option1", "option2" };
68 std::string err;
69 ASSERT_TRUE(write_bootloader_message(options, &err)) << "Failed to write BCB: " << err;
70
71 // Inject some bytes into boot, which should be overwritten while reading.
72 bootloader_message boot;
73 strlcpy(boot.recovery, "random message", sizeof(boot.recovery));
74 strlcpy(boot.reserved, "reserved bytes", sizeof(boot.reserved));
75
76 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
77
78 // Verify that command and recovery fields should be set.
79 ASSERT_EQ("boot-recovery", std::string(boot.command));
80 std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
81 ASSERT_EQ(expected, std::string(boot.recovery));
82
83 // The rest should be cleared.
84 ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status)));
85 ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage)));
86 ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'),
87 std::string(boot.reserved, sizeof(boot.reserved)));
88}
89
90TEST_F(BootloaderMessageTest, write_bootloader_message_options_empty) {
91 // Write empty vector.
92 std::vector<std::string> options;
93 std::string err;
94 ASSERT_TRUE(write_bootloader_message(options, &err)) << "Failed to write BCB: " << err;
95
96 // Read and verify.
97 bootloader_message boot;
98 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
99
100 // command and recovery fields should be set.
101 ASSERT_EQ("boot-recovery", std::string(boot.command));
102 ASSERT_EQ("recovery\n", std::string(boot.recovery));
103
104 // The rest should be cleared.
105 ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status)));
106 ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage)));
107 ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'),
108 std::string(boot.reserved, sizeof(boot.reserved)));
109}
110
111TEST_F(BootloaderMessageTest, write_bootloader_message_options_long) {
112 // Write super long message.
113 std::vector<std::string> options;
114 for (int i = 0; i < 100; i++) {
115 options.push_back("option: " + std::to_string(i));
116 }
117
118 std::string err;
119 ASSERT_TRUE(write_bootloader_message(options, &err)) << "Failed to write BCB: " << err;
120
121 // Read and verify.
122 bootloader_message boot;
123 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
124
125 // Make sure it's long enough.
126 std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
127 ASSERT_GE(expected.size(), sizeof(boot.recovery));
128
129 // command and recovery fields should be set.
130 ASSERT_EQ("boot-recovery", std::string(boot.command));
131 ASSERT_EQ(expected.substr(0, sizeof(boot.recovery) - 1), std::string(boot.recovery));
132 ASSERT_EQ('\0', boot.recovery[sizeof(boot.recovery) - 1]);
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}
Tao Bao2292db82016-12-13 21:53:31 -0800140
141TEST_F(BootloaderMessageTest, update_bootloader_message) {
142 // Inject some bytes into boot, which should be not overwritten later.
143 bootloader_message boot;
144 strlcpy(boot.recovery, "random message", sizeof(boot.recovery));
145 strlcpy(boot.reserved, "reserved bytes", sizeof(boot.reserved));
146 std::string err;
147 ASSERT_TRUE(write_bootloader_message(boot, &err)) << "Failed to write BCB: " << err;
148
149 // Update the BCB message.
150 std::vector<std::string> options = { "option1", "option2" };
151 ASSERT_TRUE(update_bootloader_message(options, &err)) << "Failed to update BCB: " << err;
152
153 bootloader_message boot_verify;
154 ASSERT_TRUE(read_bootloader_message(&boot_verify, &err)) << "Failed to read BCB: " << err;
155
156 // Verify that command and recovery fields should be set.
157 ASSERT_EQ("boot-recovery", std::string(boot_verify.command));
158 std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
159 ASSERT_EQ(expected, std::string(boot_verify.recovery));
160
161 // The rest should be intact.
162 ASSERT_EQ(std::string(boot.status), std::string(boot_verify.status));
163 ASSERT_EQ(std::string(boot.stage), std::string(boot_verify.stage));
164 ASSERT_EQ(std::string(boot.reserved), std::string(boot_verify.reserved));
165}