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() : log_level_(0), log_handler_(NULL) { }
48 :
49 : // @name IO Stream Accessors.
50 : // Call InitStreams() to route the IO streams to/from specific files;
51 : // otherwise, they will be routed to/from the NUL device on first use.
52 : // @{
53 E : FILE* in() const { return GetOrInitFile(&in_, "r"); }
54 E : FILE* out() const { return GetOrInitFile(&out_, "w"); }
55 E : FILE* err() const { return GetOrInitFile(&err_, "w"); }
56 : // @}
57 :
58 : // Initialize the IO Streams to send output to specific files. Also intercepts
59 : // logging messages.
60 : void InitStreams(const base::FilePath& in_path,
61 : const base::FilePath& out_path,
62 : const base::FilePath& err_path);
63 :
64 : // Manually tear down the various streams.
65 : void TearDownStreams();
66 :
67 : // Creates a temporary directory, which is cleaned up after the test runs.
68 E : void CreateTemporaryDir(base::FilePath* temp_dir) {
69 E : ASSERT_TRUE(file_util::CreateNewTempDirectory(L"", temp_dir));
70 E : temp_dirs_.push_back(*temp_dir);
71 E : }
72 :
73 : // Sets up before each test invocation.
74 : virtual void SetUp() OVERRIDE;
75 :
76 : // Cleans up after each test invocation.
77 : virtual void TearDown() OVERRIDE;
78 :
79 : // Disables logging for the test in which this is called.
80 E : void DisableLogging() {
81 E : logging::SetMinLogLevel(logging::LOG_FATAL);
82 E : }
83 :
84 : protected:
85 : typedef testing::Test Super;
86 :
87 : // Used for logging interception, redirecting via err().
88 : static bool HandleLogMessage(int severity, const char* file, int line,
89 : size_t message_start, const std::string& str);
90 :
91 : // Tears down the given stream.
92 : static void TearDownStream(file_util::ScopedFILE* stream);
93 :
94 : // Helper to initialize a given stream to refer to the NUL device on first
95 : // use if it hasn't already been associated with a file.
96 : static FILE* GetOrInitFile(file_util::ScopedFILE* f, const char* mode);
97 :
98 : // List of temporary directories created during this test invocation.
99 : typedef std::vector<const base::FilePath> DirList;
100 : DirList temp_dirs_;
101 :
102 : // @name Replacements for the standard IO streams.
103 : //
104 : // By default they are routed to the NUL device (on first uninitialized use).
105 : //
106 : // @{
107 : mutable file_util::ScopedFILE in_;
108 : mutable file_util::ScopedFILE out_;
109 : mutable file_util::ScopedFILE err_;
110 : // @}
111 :
112 : // The logging level saved during SetUp. We restore this on TearDown.
113 : int log_level_;
114 :
115 : // The log message handler that was intercepted.
116 : logging::LogMessageHandlerFunction log_handler_;
117 :
118 : // The instance of this test that is redirecting logging. This only works for
119 : // a single instance at a time, but only one test is running at a time so
120 : // this is not really an issue.
121 : static ApplicationTestBase* self_;
122 : };
123 :
124 : } // namespace testing
125 :
126 : #endif // SYZYGY_COMMON_UNITTEST_UTIL_H_
|