1fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// Copyright 2013, Google Inc.
2fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// All rights reserved.
3fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes//
4fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// Redistribution and use in source and binary forms, with or without
5fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// modification, are permitted provided that the following conditions are
6fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// met:
7fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes//
8fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes//     * Redistributions of source code must retain the above copyright
9fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// notice, this list of conditions and the following disclaimer.
10fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes//     * Redistributions in binary form must reproduce the above
11fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// copyright notice, this list of conditions and the following disclaimer
12fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// in the documentation and/or other materials provided with the
13fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// distribution.
14fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes//     * Neither the name of Google Inc. nor the names of its
15fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// contributors may be used to endorse or promote products derived from
16fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// this software without specific prior written permission.
17fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes//
18fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes//
30fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// Author: wan@google.com (Zhanyong Wan)
31fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes//
32fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// Tests that Google Test manipulates the premature-exit-detection
33fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// file correctly.
34fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
35fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes#include <stdio.h>
36fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
37fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes#include "gtest/gtest.h"
38fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
39fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesusing ::testing::InitGoogleTest;
40fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesusing ::testing::Test;
41fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesusing ::testing::internal::posix::GetEnv;
42fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesusing ::testing::internal::posix::Stat;
43fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesusing ::testing::internal::posix::StatStruct;
44fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
45fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesnamespace {
46fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
47fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// Is the TEST_PREMATURE_EXIT_FILE environment variable expected to be
48fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// set?
49fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesconst bool kTestPrematureExitFileEnvVarShouldBeSet = false;
50fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
51fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesclass PrematureExitTest : public Test {
52fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes public:
53fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  // Returns true iff the given file exists.
54fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  static bool FileExists(const char* filepath) {
55fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes    StatStruct stat;
56fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes    return Stat(filepath, &stat) == 0;
57fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  }
58fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
59fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes protected:
60fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  PrematureExitTest() {
61fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes    premature_exit_file_path_ = GetEnv("TEST_PREMATURE_EXIT_FILE");
62fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
63fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes    // Normalize NULL to "" for ease of handling.
64fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes    if (premature_exit_file_path_ == NULL) {
65fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes      premature_exit_file_path_ = "";
66fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes    }
67fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  }
68fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
69fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  // Returns true iff the premature-exit file exists.
70fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  bool PrematureExitFileExists() const {
71fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes    return FileExists(premature_exit_file_path_);
72fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  }
73fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
74fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  const char* premature_exit_file_path_;
75fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes};
76fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
77fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughestypedef PrematureExitTest PrematureExitDeathTest;
78fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
79fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// Tests that:
80fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes//   - the premature-exit file exists during the execution of a
81fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes//     death test (EXPECT_DEATH*), and
82fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes//   - a death test doesn't interfere with the main test process's
83fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes//     handling of the premature-exit file.
84fc2de66453b0669c09eaca643b07d34443858b6fElliott HughesTEST_F(PrematureExitDeathTest, FileExistsDuringExecutionOfDeathTest) {
85fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  if (*premature_exit_file_path_ == '\0') {
86fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes    return;
87fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  }
88fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
89fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  EXPECT_DEATH_IF_SUPPORTED({
90fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes      // If the file exists, crash the process such that the main test
91fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes      // process will catch the (expected) crash and report a success;
92fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes      // otherwise don't crash, which will cause the main test process
93fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes      // to report that the death test has failed.
94fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes      if (PrematureExitFileExists()) {
95fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes        exit(1);
96fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes      }
97fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes    }, "");
98fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes}
99fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
100fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// Tests that TEST_PREMATURE_EXIT_FILE is set where it's expected to
101fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// be set.
102fc2de66453b0669c09eaca643b07d34443858b6fElliott HughesTEST_F(PrematureExitTest, TestPrematureExitFileEnvVarIsSet) {
103fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  if (kTestPrematureExitFileEnvVarShouldBeSet) {
104fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes    const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE");
105fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes    ASSERT_TRUE(filepath != NULL);
106fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes    ASSERT_NE(*filepath, '\0');
107fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  }
108fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes}
109fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
110fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// Tests that the premature-exit file exists during the execution of a
111fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes// normal (non-death) test.
112fc2de66453b0669c09eaca643b07d34443858b6fElliott HughesTEST_F(PrematureExitTest, PrematureExitFileExistsDuringTestExecution) {
113fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  if (*premature_exit_file_path_ == '\0') {
114fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes    return;
115fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  }
116fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
117fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  EXPECT_TRUE(PrematureExitFileExists())
118fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes      << " file " << premature_exit_file_path_
119fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes      << " should exist during test execution, but doesn't.";
120fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes}
121fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
122fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes}  // namespace
123fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
124fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughesint main(int argc, char **argv) {
125fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  InitGoogleTest(&argc, argv);
126fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  const int exit_code = RUN_ALL_TESTS();
127fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
128fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  // Test that the premature-exit file is deleted upon return from
129fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  // RUN_ALL_TESTS().
130fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE");
131fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  if (filepath != NULL && *filepath != '\0') {
132fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes    if (PrematureExitTest::FileExists(filepath)) {
133fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes      printf(
134fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes          "File %s shouldn't exist after the test program finishes, but does.",
135fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes          filepath);
136fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes      return 1;
137fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes    }
138fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  }
139fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes
140fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes  return exit_code;
141fc2de66453b0669c09eaca643b07d34443858b6fElliott Hughes}
142