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 32namespace android { 33namespace camera2 { 34namespace tests { 35 36bool TestForkerEventListener::mIsForked = false; 37 38TestForkerEventListener::TestForkerEventListener() { 39 mIsForked = false; 40 mHasSucceeded = true; 41 mTermSignal = 0; 42} 43 44// Called before a test starts. 45void 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. 74void 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. 87void 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