/* * Copyright (C) 2012 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 #include #include #include #include #include "TestForkerEventListener.h" #include "TestExtensions.h" #define DEBUG_TEST_FORKER_EVENT_LISTENER 0 #define RETURN_CODE_PASSED 0 #define RETURN_CODE_FAILED 1 namespace android { namespace camera2 { namespace tests { bool TestForkerEventListener::mIsForked = false; TestForkerEventListener::TestForkerEventListener() { mIsForked = false; mHasSucceeded = true; mTermSignal = 0; } // Called before a test starts. void TestForkerEventListener::OnTestStart(const ::testing::TestInfo&) { if (!TEST_EXTENSION_FORKING_ENABLED) { return; } pid_t childPid = fork(); if (childPid != 0) { int status; waitpid(childPid, &status, /*options*/0); // terminated normally? mHasSucceeded = WIFEXITED(status); // terminate with return code 0 = test passed, 1 = test failed if (mHasSucceeded) { mHasSucceeded = WEXITSTATUS(status) == RETURN_CODE_PASSED; } else if (WIFSIGNALED(status)) { mTermSignal = WTERMSIG(status); } /* the test is then skipped by inserting the various TEST_EXTENSION_ macros in TestExtensions.h */ } else { mIsForked = true; } } // Called after a failed assertion or a SUCCEED() invocation. void TestForkerEventListener::OnTestPartResult( const ::testing::TestPartResult& test_part_result) { if (DEBUG_TEST_FORKER_EVENT_LISTENER) { printf("%s in %s:%d\n%s\n", test_part_result.failed() ? "*** Failure" : "Success", test_part_result.file_name(), test_part_result.line_number(), test_part_result.summary()); } } // Called after a test ends. void TestForkerEventListener::OnTestEnd(const ::testing::TestInfo& test_info) { if (!TEST_EXTENSION_FORKING_ENABLED) { return; } if (mIsForked) { exit(test_info.result()->Passed() ? RETURN_CODE_PASSED : RETURN_CODE_FAILED); } else if (!mHasSucceeded && mTermSignal != 0) { printf("*** Test %s.%s crashed with signal = %s\n", test_info.test_case_name(), test_info.name(), strsignal(mTermSignal)); } //TODO: overload the default event listener to suppress this message // dynamically (e.g. by skipping OnTestPartResult after OnTestEnd ) // trigger a test failure if the child has failed if (!mHasSucceeded) { ADD_FAILURE(); } mTermSignal = 0; } } } }