1eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin/*
2eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin * Copyright (C) 2012 The Android Open Source Project
3eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin *
4eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
5eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin * you may not use this file except in compliance with the License.
6eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin * You may obtain a copy of the License at
7eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin *
8eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
9eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin *
10eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin * Unless required by applicable law or agreed to in writing, software
11eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
12eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin * See the License for the specific language governing permissions and
14eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin * limitations under the License.
15eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin */
16eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
17eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin#include <unistd.h>
18eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin#include <sys/types.h>
19eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin#include <sys/wait.h>
20eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin#include <string.h>
21eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
22eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin#include <gtest/gtest.h>
23eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
24eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin#include "TestForkerEventListener.h"
25eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin#include "TestExtensions.h"
26eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
27eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin#define DEBUG_TEST_FORKER_EVENT_LISTENER 0
28eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
29eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin#define RETURN_CODE_PASSED 0
30eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin#define RETURN_CODE_FAILED 1
31eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
32eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkinnamespace android {
33eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkinnamespace camera2 {
34eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkinnamespace tests {
35eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
36eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkinbool TestForkerEventListener::mIsForked         = false;
37eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
38eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor MurashkinTestForkerEventListener::TestForkerEventListener() {
39eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    mIsForked = false;
40eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    mHasSucceeded = true;
41eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    mTermSignal = 0;
42eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin}
43eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
44eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin// Called before a test starts.
45eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkinvoid TestForkerEventListener::OnTestStart(const ::testing::TestInfo&) {
46eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
47eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    if (!TEST_EXTENSION_FORKING_ENABLED) {
48eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin        return;
49eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    }
50eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
51eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    pid_t childPid = fork();
52eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    if (childPid != 0) {
53eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin        int status;
54eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin        waitpid(childPid, &status, /*options*/0);
55eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
56eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin        // terminated normally?
57eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin        mHasSucceeded = WIFEXITED(status);
58eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin        // terminate with return code 0 = test passed, 1 = test failed
59eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin        if (mHasSucceeded) {
60eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin          mHasSucceeded = WEXITSTATUS(status) == RETURN_CODE_PASSED;
61eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin        } else if (WIFSIGNALED(status)) {
62eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin          mTermSignal = WTERMSIG(status);
63eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin        }
64eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
65eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin        /* the test is then skipped by inserting the various
66eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin        TEST_EXTENSION_ macros in TestExtensions.h */
67eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
68eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    } else {
69eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin        mIsForked = true;
70eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    }
71eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin}
72eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
73eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin// Called after a failed assertion or a SUCCEED() invocation.
74eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkinvoid TestForkerEventListener::OnTestPartResult(
75eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    const ::testing::TestPartResult& test_part_result) {
76eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
77eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    if (DEBUG_TEST_FORKER_EVENT_LISTENER) {
78eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin        printf("%s in %s:%d\n%s\n",
79eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin             test_part_result.failed() ? "*** Failure" : "Success",
80eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin             test_part_result.file_name(),
81eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin             test_part_result.line_number(),
82eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin             test_part_result.summary());
83eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    }
84eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin}
85eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
86eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin// Called after a test ends.
87eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkinvoid TestForkerEventListener::OnTestEnd(const ::testing::TestInfo& test_info) {
88eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
89eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    if (!TEST_EXTENSION_FORKING_ENABLED) {
90eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin        return;
91eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    }
92eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
93eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    if (mIsForked) {
94eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin        exit(test_info.result()->Passed()
95eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin            ? RETURN_CODE_PASSED : RETURN_CODE_FAILED);
96eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    } else if (!mHasSucceeded && mTermSignal != 0) {
97eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
98eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin      printf("*** Test %s.%s crashed with signal = %s\n",
99eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin             test_info.test_case_name(), test_info.name(),
100eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin             strsignal(mTermSignal));
101eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    }
102eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
103eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    //TODO: overload the default event listener to suppress this message
104eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    // dynamically (e.g. by skipping OnTestPartResult after OnTestEnd )
105eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
106eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    // trigger a test failure if the child has failed
107eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    if (!mHasSucceeded) {
108eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin        ADD_FAILURE();
109eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    }
110eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin    mTermSignal = 0;
111eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin}
112eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
113eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
114eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin}
115eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin}
116eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin}
117eab33fc589a8e1ca04f5703b5f1ace69f8ff9aeaIgor Murashkin
118