/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "firmware_handler.h" #include #include #include #include #include "uevent.h" using android::base::GetExecutablePath; using namespace std::literals; namespace android { namespace init { void FirmwareTestWithExternalHandler(const std::string& test_name, bool expect_new_firmware) { auto test_path = GetExecutablePath() + " firmware " + test_name; auto external_firmware_handler = ExternalFirmwareHandler( "/devices/led/firmware/test_firmware001.bin", getuid(), test_path); auto firmware_handler = FirmwareHandler({"/test"}, {external_firmware_handler}); auto uevent = Uevent{ .path = "/devices/led/firmware/test_firmware001.bin", .firmware = "test_firmware001.bin", }; if (expect_new_firmware) { EXPECT_EQ("other_firmware001.bin", firmware_handler.GetFirmwarePath(uevent)); } else { EXPECT_EQ("test_firmware001.bin", firmware_handler.GetFirmwarePath(uevent)); } // Always test the base case that the handler isn't invoked if the devpath doesn't match. auto uevent_different_path = Uevent{ .path = "/devices/led/not/mine", .firmware = "test_firmware001.bin", }; EXPECT_EQ("test_firmware001.bin", firmware_handler.GetFirmwarePath(uevent_different_path)); } TEST(firmware_handler, HandleChange) { FirmwareTestWithExternalHandler("HandleChange", true); } int HandleChange(int argc, char** argv) { // Assert that the environment is set up correctly. if (getenv("DEVPATH") != "/devices/led/firmware/test_firmware001.bin"s) { std::cerr << "$DEVPATH not set correctly" << std::endl; return EXIT_FAILURE; } if (getenv("FIRMWARE") != "test_firmware001.bin"s) { std::cerr << "$FIRMWARE not set correctly" << std::endl; return EXIT_FAILURE; } std::cout << "other_firmware001.bin" << std::endl; return 0; } TEST(firmware_handler, HandleAbort) { FirmwareTestWithExternalHandler("HandleAbort", false); } int HandleAbort(int argc, char** argv) { abort(); return 0; } TEST(firmware_handler, HandleFailure) { FirmwareTestWithExternalHandler("HandleFailure", false); } int HandleFailure(int argc, char** argv) { std::cerr << "Failed" << std::endl; return EXIT_FAILURE; } TEST(firmware_handler, HandleBadPath) { FirmwareTestWithExternalHandler("HandleBadPath", false); } int HandleBadPath(int argc, char** argv) { std::cout << "../firmware.bin"; return 0; } } // namespace init } // namespace android // init_test.cpp contains the main entry point for all init tests. int FirmwareTestChildMain(int argc, char** argv) { if (argc < 3) { return 1; } #define RunTest(testname) \ if (argv[2] == std::string(#testname)) { \ return android::init::testname(argc, argv); \ } RunTest(HandleChange); RunTest(HandleAbort); RunTest(HandleFailure); RunTest(HandleBadPath); #undef RunTest return 1; }