1 /* 2 * Copyright (C) 2012 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 <unistd.h> 18 #include <sys/types.h> 19 #include <sys/wait.h> 20 #include <string.h> 21 22 #include <gtest/gtest.h> 23 24 #include "TestForkerEventListener.h" 25 #include "TestExtensions.h" 26 27 #define DEBUG_TEST_FORKER_EVENT_LISTENER 0 28 29 #define RETURN_CODE_PASSED 0 30 #define RETURN_CODE_FAILED 1 31 32 namespace android { 33 namespace camera2 { 34 namespace tests { 35 36 bool TestForkerEventListener::mIsForked = false; 37 38 TestForkerEventListener::TestForkerEventListener() { 39 mIsForked = false; 40 mHasSucceeded = true; 41 mTermSignal = 0; 42 } 43 44 // Called before a test starts. 45 void TestForkerEventListener::OnTestStart(const ::testing::TestInfo&) { 46 47 if (!TEST_EXTENSION_FORKING_ENABLED) { 48 return; 49 } 50 51 pid_t childPid = fork(); 52 if (childPid != 0) { 53 int status; 54 waitpid(childPid, &status, /*options*/0); 55 56 // terminated normally? 57 mHasSucceeded = WIFEXITED(status); 58 // terminate with return code 0 = test passed, 1 = test failed 59 if (mHasSucceeded) { 60 mHasSucceeded = WEXITSTATUS(status) == RETURN_CODE_PASSED; 61 } else if (WIFSIGNALED(status)) { 62 mTermSignal = WTERMSIG(status); 63 } 64 65 /* the test is then skipped by inserting the various 66 TEST_EXTENSION_ macros in TestExtensions.h */ 67 68 } else { 69 mIsForked = true; 70 } 71 } 72 73 // Called after a failed assertion or a SUCCEED() invocation. 74 void TestForkerEventListener::OnTestPartResult( 75 const ::testing::TestPartResult& test_part_result) { 76 77 if (DEBUG_TEST_FORKER_EVENT_LISTENER) { 78 printf("%s in %s:%d\n%s\n", 79 test_part_result.failed() ? "*** Failure" : "Success", 80 test_part_result.file_name(), 81 test_part_result.line_number(), 82 test_part_result.summary()); 83 } 84 } 85 86 // Called after a test ends. 87 void TestForkerEventListener::OnTestEnd(const ::testing::TestInfo& test_info) { 88 89 if (!TEST_EXTENSION_FORKING_ENABLED) { 90 return; 91 } 92 93 if (mIsForked) { 94 exit(test_info.result()->Passed() 95 ? RETURN_CODE_PASSED : RETURN_CODE_FAILED); 96 } else if (!mHasSucceeded && mTermSignal != 0) { 97 98 printf("*** Test %s.%s crashed with signal = %s\n", 99 test_info.test_case_name(), test_info.name(), 100 strsignal(mTermSignal)); 101 } 102 103 //TODO: overload the default event listener to suppress this message 104 // dynamically (e.g. by skipping OnTestPartResult after OnTestEnd ) 105 106 // trigger a test failure if the child has failed 107 if (!mHasSucceeded) { 108 ADD_FAILURE(); 109 } 110 mTermSignal = 0; 111 } 112 113 114 } 115 } 116 } 117 118