1 /*
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
27 using android::base::GetExecutablePath;
28 using namespace std::literals;
29
30 namespace android {
31 namespace init {
32
FirmwareTestWithExternalHandler(const std::string & test_name,bool expect_new_firmware)33 void 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
TEST(firmware_handler,HandleChange)59 TEST(firmware_handler, HandleChange) {
60 FirmwareTestWithExternalHandler("HandleChange", true);
61 }
62
HandleChange(int argc,char ** argv)63 int 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
TEST(firmware_handler,HandleAbort)77 TEST(firmware_handler, HandleAbort) {
78 FirmwareTestWithExternalHandler("HandleAbort", false);
79 }
80
HandleAbort(int argc,char ** argv)81 int HandleAbort(int argc, char** argv) {
82 abort();
83 return 0;
84 }
85
TEST(firmware_handler,HandleFailure)86 TEST(firmware_handler, HandleFailure) {
87 FirmwareTestWithExternalHandler("HandleFailure", false);
88 }
89
HandleFailure(int argc,char ** argv)90 int HandleFailure(int argc, char** argv) {
91 std::cerr << "Failed" << std::endl;
92 return EXIT_FAILURE;
93 }
94
TEST(firmware_handler,HandleBadPath)95 TEST(firmware_handler, HandleBadPath) {
96 FirmwareTestWithExternalHandler("HandleBadPath", false);
97 }
98
HandleBadPath(int argc,char ** argv)99 int HandleBadPath(int argc, char** argv) {
100 std::cout << "../firmware.bin";
101 return 0;
102 }
103
104 } // namespace init
105 } // namespace android
106
107 // init_test.cpp contains the main entry point for all init tests.
FirmwareTestChildMain(int argc,char ** argv)108 int FirmwareTestChildMain(int argc, char** argv) {
109 if (argc < 3) {
110 return 1;
111 }
112
113 #define RunTest(testname) \
114 if (argv[2] == std::string(#testname)) { \
115 return android::init::testname(argc, argv); \
116 }
117
118 RunTest(HandleChange);
119 RunTest(HandleAbort);
120 RunTest(HandleFailure);
121 RunTest(HandleBadPath);
122
123 #undef RunTest
124 return 1;
125 }
126