blob: f6e75b01ff8fc96050dd9b5386fa1bb649ca3bec [file] [log] [blame]
Tom Cherrydcb3d152019-08-07 16:02:28 -07001/*
2 * Copyright (C) 2019 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 "firmware_handler.h"
18
19#include <stdlib.h>
20#include <iostream>
21
22#include <android-base/file.h>
23#include <gtest/gtest.h>
24
25#include "uevent.h"
26
27using android::base::GetExecutablePath;
28using namespace std::literals;
29
30namespace android {
31namespace init {
32
33void FirmwareTestWithExternalHandler(const std::string& test_name, bool expect_new_firmware) {
34 auto test_path = GetExecutablePath() + " firmware " + test_name;
35 auto external_firmware_handler = ExternalFirmwareHandler(
36 "/devices/led/firmware/test_firmware001.bin", getuid(), test_path);
37
38 auto firmware_handler = FirmwareHandler({"/test"}, {external_firmware_handler});
39
40 auto uevent = Uevent{
41 .path = "/devices/led/firmware/test_firmware001.bin",
42 .firmware = "test_firmware001.bin",
43 };
44
45 if (expect_new_firmware) {
46 EXPECT_EQ("other_firmware001.bin", firmware_handler.GetFirmwarePath(uevent));
47 } else {
48 EXPECT_EQ("test_firmware001.bin", firmware_handler.GetFirmwarePath(uevent));
49 }
50
51 // Always test the base case that the handler isn't invoked if the devpath doesn't match.
52 auto uevent_different_path = Uevent{
53 .path = "/devices/led/not/mine",
54 .firmware = "test_firmware001.bin",
55 };
56 EXPECT_EQ("test_firmware001.bin", firmware_handler.GetFirmwarePath(uevent_different_path));
57}
58
59TEST(firmware_handler, HandleChange) {
60 FirmwareTestWithExternalHandler("HandleChange", true);
61}
62
63int HandleChange(int argc, char** argv) {
64 // Assert that the environment is set up correctly.
65 if (getenv("DEVPATH") != "/devices/led/firmware/test_firmware001.bin"s) {
66 std::cerr << "$DEVPATH not set correctly" << std::endl;
67 return EXIT_FAILURE;
68 }
69 if (getenv("FIRMWARE") != "test_firmware001.bin"s) {
70 std::cerr << "$FIRMWARE not set correctly" << std::endl;
71 return EXIT_FAILURE;
72 }
73 std::cout << "other_firmware001.bin" << std::endl;
74 return 0;
75}
76
77TEST(firmware_handler, HandleAbort) {
78 FirmwareTestWithExternalHandler("HandleAbort", false);
79}
80
81int HandleAbort(int argc, char** argv) {
Tom Cherry94b1c572020-12-15 06:38:55 -080082 // Since this is an expected failure, disable debuggerd to not generate a tombstone.
83 signal(SIGABRT, SIG_DFL);
Tom Cherrydcb3d152019-08-07 16:02:28 -070084 abort();
85 return 0;
86}
87
88TEST(firmware_handler, HandleFailure) {
89 FirmwareTestWithExternalHandler("HandleFailure", false);
90}
91
92int HandleFailure(int argc, char** argv) {
93 std::cerr << "Failed" << std::endl;
94 return EXIT_FAILURE;
95}
96
97TEST(firmware_handler, HandleBadPath) {
98 FirmwareTestWithExternalHandler("HandleBadPath", false);
99}
100
101int HandleBadPath(int argc, char** argv) {
102 std::cout << "../firmware.bin";
103 return 0;
104}
105
David Anderson19872d02021-04-16 13:33:56 -0700106TEST(firmware_handler, Matching) {
107 ExternalFirmwareHandler h("/dev/path/a.bin", getuid(), "/test");
108 ASSERT_TRUE(h.match("/dev/path/a.bin"));
109 ASSERT_FALSE(h.match("/dev/path/a.bi"));
110
111 h = ExternalFirmwareHandler("/dev/path/a.*", getuid(), "/test");
112 ASSERT_TRUE(h.match("/dev/path/a.bin"));
113 ASSERT_TRUE(h.match("/dev/path/a.bix"));
114 ASSERT_FALSE(h.match("/dev/path/b.bin"));
115
116 h = ExternalFirmwareHandler("/dev/*/a.bin", getuid(), "/test");
117 ASSERT_TRUE(h.match("/dev/path/a.bin"));
118 ASSERT_TRUE(h.match("/dev/other/a.bin"));
119 ASSERT_FALSE(h.match("/dev/other/c.bin"));
120 ASSERT_FALSE(h.match("/dev/path/b.bin"));
121}
122
Tom Cherrydcb3d152019-08-07 16:02:28 -0700123} // namespace init
124} // namespace android
125
126// init_test.cpp contains the main entry point for all init tests.
127int FirmwareTestChildMain(int argc, char** argv) {
128 if (argc < 3) {
129 return 1;
130 }
131
132#define RunTest(testname) \
133 if (argv[2] == std::string(#testname)) { \
134 return android::init::testname(argc, argv); \
135 }
136
137 RunTest(HandleChange);
138 RunTest(HandleAbort);
139 RunTest(HandleFailure);
140 RunTest(HandleBadPath);
141
142#undef RunTest
143 return 1;
144}