1 : // Copyright 2012 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // Declares a handful of common unittest helper functions.
16 :
17 : #ifndef SYZYGY_COMMON_UNITTEST_UTIL_H_
18 : #define SYZYGY_COMMON_UNITTEST_UTIL_H_
19 :
20 : #include "base/file_util.h"
21 : #include "base/logging.h"
22 : #include "base/files/file_path.h"
23 : #include "gtest/gtest.h"
24 :
25 : namespace testing {
26 :
27 : // Helper class to make sure that a test that plays with the log level doesn't
28 : // change it for other tests.
29 : class ScopedLogLevelSaver {
30 : public:
31 E : ScopedLogLevelSaver() : level_(logging::GetMinLogLevel()) {
32 E : }
33 :
34 E : ~ScopedLogLevelSaver() {
35 E : logging::SetMinLogLevel(level_);
36 E : }
37 :
38 : int level() const { return level_; }
39 :
40 : private:
41 : int level_;
42 : };
43 :
44 : // An intermediate class to add helper streams to a unit-test fixture.
45 : class ApplicationTestBase : public testing::Test {
46 : public:
47 E : ApplicationTestBase()
48 : : log_level_(0), log_handler_(NULL), log_to_console_(false) { }
49 :
50 : // @name IO Stream Accessors.
51 : // Call InitStreams() to route the IO streams to/from specific files;
52 : // otherwise, they will be routed to/from the NUL device on first use.
53 : // @{
54 E : FILE* in() const { return GetOrInitFile(&in_, "r"); }
55 E : FILE* out() const { return GetOrInitFile(&out_, "w"); }
56 E : FILE* err() const { return GetOrInitFile(&err_, "w"); }
57 : // @}
58 :
59 : // Initialize the IO Streams to send output to specific files. Also intercepts
60 : // logging messages.
61 : void InitStreams(const base::FilePath& in_path,
62 : const base::FilePath& out_path,
63 : const base::FilePath& err_path);
64 :
65 : // Manually tear down the various streams.
66 : void TearDownStreams();
67 :
68 : // Creates a temporary directory, which is cleaned up after the test runs.
69 E : void CreateTemporaryDir(base::FilePath* temp_dir) {
70 E : ASSERT_TRUE(base::CreateNewTempDirectory(L"", temp_dir));
71 E : temp_dirs_.push_back(*temp_dir);
72 E : }
73 :
74 : // Sets up before each test invocation.
75 : virtual void SetUp() OVERRIDE;
76 :
77 : // Cleans up after each test invocation.
78 : virtual void TearDown() OVERRIDE;
79 :
80 : // Disables logging for the test in which this is called.
81 E : void DisableLogging() {
82 E : logging::SetMinLogLevel(logging::LOG_FATAL);
83 E : }
84 :
85 : // Enables logging to screen for the test in which this is called.
86 : void EnableLoggingToConsole() {
87 : log_to_console_ = true;
88 : }
89 :
90 : protected:
91 : typedef testing::Test Super;
92 :
93 : // Used for logging interception, redirecting via err().
94 : static bool HandleLogMessage(int severity, const char* file, int line,
95 : size_t message_start, const std::string& str);
96 :
97 : // Tears down the given stream.
98 : static void TearDownStream(base::ScopedFILE* stream);
99 :
100 : // Helper to initialize a given stream to refer to the NUL device on first
101 : // use if it hasn't already been associated with a file.
102 : static FILE* GetOrInitFile(base::ScopedFILE* f, const char* mode);
103 :
104 : // List of temporary directories created during this test invocation.
105 : typedef std::vector<const base::FilePath> DirList;
106 : DirList temp_dirs_;
107 :
108 : // @name Replacements for the standard IO streams.
109 : //
110 : // By default they are routed to the NUL device (on first uninitialized use).
111 : //
112 : // @{
113 : mutable base::ScopedFILE in_;
114 : mutable base::ScopedFILE out_;
115 : mutable base::ScopedFILE err_;
116 : // @}
117 :
118 : // The logging level saved during SetUp. We restore this on TearDown.
119 : int log_level_;
120 :
121 : // The log message handler that was intercepted.
122 : logging::LogMessageHandlerFunction log_handler_;
123 :
124 : // If this is true then log messages handled by this fixture will be repeated
125 : // to the console rather than simply going to the wrapped stderr. Defaults to
126 : // false.
127 : bool log_to_console_;
128 :
129 : // The instance of this test that is redirecting logging. This only works for
130 : // a single instance at a time, but only one test is running at a time so
131 : // this is not really an issue.
132 : static ApplicationTestBase* self_;
133 : };
134 :
135 : } // namespace testing
136 :
137 : #endif // SYZYGY_COMMON_UNITTEST_UTIL_H_
|