Ninja
test.h
Go to the documentation of this file.
1 // Copyright 2011 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 #ifndef NINJA_TEST_H_
16 #define NINJA_TEST_H_
17 
18 #include "disk_interface.h"
19 #include "manifest_parser.h"
20 #include "state.h"
21 #include "util.h"
22 
23 // A tiny testing framework inspired by googletest, but much simpler and
24 // faster to compile. It supports most things commonly used from googltest. The
25 // most noticeable things missing: EXPECT_* and ASSERT_* don't support
26 // streaming notes to them with operator<<, and for failing tests the lhs and
27 // rhs are not printed. That's so that this header does not have to include
28 // sstream, which slows down building ninja_test almost 20%.
29 namespace testing {
30 class Test {
31  bool failed_;
33  public:
34  Test() : failed_(false), assertion_failures_(0) {}
35  virtual ~Test() {}
36  virtual void SetUp() {}
37  virtual void TearDown() {}
38  virtual void Run() = 0;
39 
40  bool Failed() const { return failed_; }
41  int AssertionFailures() const { return assertion_failures_; }
43  bool Check(bool condition, const char* file, int line, const char* error);
44 };
45 }
46 
47 void RegisterTest(testing::Test* (*)(), const char*);
48 
50 #define TEST_F_(x, y, name) \
51  struct y : public x { \
52  static testing::Test* Create() { return g_current_test = new y; } \
53  virtual void Run(); \
54  }; \
55  struct Register##y { \
56  Register##y() { RegisterTest(y::Create, name); } \
57  }; \
58  Register##y g_register_##y; \
59  void y::Run()
60 
61 #define TEST_F(x, y) TEST_F_(x, x##y, #x "." #y)
62 #define TEST(x, y) TEST_F_(testing::Test, x##y, #x "." #y)
63 
64 #define EXPECT_EQ(a, b) \
65  g_current_test->Check(a == b, __FILE__, __LINE__, #a " == " #b)
66 #define EXPECT_NE(a, b) \
67  g_current_test->Check(a != b, __FILE__, __LINE__, #a " != " #b)
68 #define EXPECT_GT(a, b) \
69  g_current_test->Check(a > b, __FILE__, __LINE__, #a " > " #b)
70 #define EXPECT_LT(a, b) \
71  g_current_test->Check(a < b, __FILE__, __LINE__, #a " < " #b)
72 #define EXPECT_GE(a, b) \
73  g_current_test->Check(a >= b, __FILE__, __LINE__, #a " >= " #b)
74 #define EXPECT_LE(a, b) \
75  g_current_test->Check(a <= b, __FILE__, __LINE__, #a " <= " #b)
76 #define EXPECT_TRUE(a) \
77  g_current_test->Check(static_cast<bool>(a), __FILE__, __LINE__, #a)
78 #define EXPECT_FALSE(a) \
79  g_current_test->Check(!static_cast<bool>(a), __FILE__, __LINE__, #a)
80 
81 #define ASSERT_EQ(a, b) \
82  if (!EXPECT_EQ(a, b)) { g_current_test->AddAssertionFailure(); return; }
83 #define ASSERT_NE(a, b) \
84  if (!EXPECT_NE(a, b)) { g_current_test->AddAssertionFailure(); return; }
85 #define ASSERT_GT(a, b) \
86  if (!EXPECT_GT(a, b)) { g_current_test->AddAssertionFailure(); return; }
87 #define ASSERT_LT(a, b) \
88  if (!EXPECT_LT(a, b)) { g_current_test->AddAssertionFailure(); return; }
89 #define ASSERT_GE(a, b) \
90  if (!EXPECT_GE(a, b)) { g_current_test->AddAssertionFailure(); return; }
91 #define ASSERT_LE(a, b) \
92  if (!EXPECT_LE(a, b)) { g_current_test->AddAssertionFailure(); return; }
93 #define ASSERT_TRUE(a) \
94  if (!EXPECT_TRUE(a)) { g_current_test->AddAssertionFailure(); return; }
95 #define ASSERT_FALSE(a) \
96  if (!EXPECT_FALSE(a)) { g_current_test->AddAssertionFailure(); return; }
97 #define ASSERT_NO_FATAL_FAILURE(a) \
98  { \
99  int fail_count = g_current_test->AssertionFailures(); \
100  a; \
101  if (fail_count != g_current_test->AssertionFailures()) { \
102  g_current_test->AddAssertionFailure(); \
103  return; \
104  } \
105  }
106 
107 // Support utilities for tests.
108 
109 struct Node;
110 
111 /// A base test fixture that includes a State object with a
112 /// builtin "cat" rule.
115 
116  /// Add a "cat" rule to \a state. Used by some tests; it's
117  /// otherwise done by the ctor to state_.
118  void AddCatRule(State* state);
119 
120  /// Short way to get a Node by its path from state_.
121  Node* GetNode(const std::string& path);
122 
124 };
125 
126 void AssertParse(State* state, const char* input,
128 void AssertHash(const char* expected, uint64_t actual);
129 void VerifyGraph(const State& state);
130 
131 /// An implementation of DiskInterface that uses an in-memory representation
132 /// of disk state. It also logs file accesses and directory creations
133 /// so it can be used by tests to verify disk access patterns.
136 
137  /// "Create" a file with contents.
138  void Create(const std::string& path, const std::string& contents);
139 
140  /// Tick "time" forwards; subsequent file operations will be newer than
141  /// previous ones.
142  int Tick() {
143  return ++now_;
144  }
145 
146  // DiskInterface
147  virtual TimeStamp Stat(const std::string& path, std::string* err) const;
148  virtual bool WriteFile(const std::string& path, const std::string& contents);
149  virtual bool MakeDir(const std::string& path);
150  virtual Status ReadFile(const std::string& path, std::string* contents,
151  std::string* err);
152  virtual int RemoveFile(const std::string& path);
153 
154  /// An entry for a single in-memory file.
155  struct Entry {
156  int mtime;
157  std::string stat_error; // If mtime is -1.
158  std::string contents;
159  };
160 
161  std::vector<std::string> directories_made_;
162  std::vector<std::string> files_read_;
163  typedef std::map<std::string, Entry> FileMap;
165  std::set<std::string> files_removed_;
166  std::set<std::string> files_created_;
167 
168  /// A simple fake timestamp for file operations.
169  int now_;
170 };
171 
173  /// Create a temporary directory and chdir into it.
174  void CreateAndEnter(const std::string& name);
175 
176  /// Clean up the temporary directory.
177  void Cleanup();
178 
179  /// The temp directory containing our dir.
180  std::string start_dir_;
181  /// The subdirectory name for our dir, or empty if it hasn't been set up.
182  std::string temp_dir_name_;
183 };
184 
185 #endif // NINJA_TEST_H_
FileMap files_
Definition: test.h:164
An implementation of DiskInterface that uses an in-memory representation of disk state.
Definition: test.h:134
virtual TimeStamp Stat(const std::string &path, std::string *err) const
stat() a file, returning the mtime, or 0 if missing and -1 on other errors.
Definition: test.cc:152
Definition: test.h:29
void VerifyGraph(const State &state)
Definition: test.cc:113
int Tick()
Tick "time" forwards; subsequent file operations will be newer than previous ones.
Definition: test.h:142
std::set< std::string > files_created_
Definition: test.h:166
std::vector< std::string > files_read_
Definition: test.h:162
std::string contents
Definition: test.h:158
bool failed_
Definition: test.h:31
void AssertParse(State *state, const char *input, ManifestParserOptions=ManifestParserOptions())
Definition: test.cc:100
virtual void SetUp()
Definition: test.h:36
Information about a node in the dependency graph: the file, whether it&#39;s dirty, mtime, etc.
Definition: graph.h:37
void Create(const std::string &path, const std::string &contents)
"Create" a file with contents.
Definition: test.cc:145
Interface for accessing the disk.
int now_
A simple fake timestamp for file operations.
Definition: test.h:169
void CreateAndEnter(const std::string &name)
Create a temporary directory and chdir into it.
Definition: test.cc:198
Node * GetNode(const std::string &path)
Short way to get a Node by its path from state_.
Definition: test.cc:95
virtual bool WriteFile(const std::string &path, const std::string &contents)
Create a file, with the specified name and contents Returns true on success, false on failure...
Definition: test.cc:161
virtual void TearDown()
Definition: test.h:37
std::map< std::string, Entry > FileMap
Definition: test.h:163
A base test fixture that includes a State object with a builtin "cat" rule.
Definition: test.h:113
void AssertHash(const char *expected, uint64_t actual)
Definition: test.cc:109
int assertion_failures_
Definition: test.h:32
void AddCatRule(State *state)
Add a "cat" rule to state.
Definition: test.cc:89
testing::Test * g_current_test
Definition: ninja_test.cc:43
std::set< std::string > files_removed_
Definition: test.h:165
bool Failed() const
Definition: test.h:40
std::string temp_dir_name_
The subdirectory name for our dir, or empty if it hasn&#39;t been set up.
Definition: test.h:182
virtual ~Test()
Definition: test.h:35
virtual int RemoveFile(const std::string &path)
Remove the file named path.
Definition: test.cc:184
std::string start_dir_
The temp directory containing our dir.
Definition: test.h:180
virtual bool MakeDir(const std::string &path)
Create a directory, returning false on failure.
Definition: test.cc:166
VirtualFileSystem()
Definition: test.h:135
void AddAssertionFailure()
Definition: test.h:42
std::vector< std::string > directories_made_
Definition: test.h:161
std::string stat_error
Definition: test.h:157
Status
Result of ReadFile.
int64_t TimeStamp
Definition: timestamp.h:31
virtual Status ReadFile(const std::string &path, std::string *contents, std::string *err)
Read and store in given string.
Definition: test.cc:171
bool Check(bool condition, const char *file, int line, const char *error)
Definition: ninja_test.cc:121
void Cleanup()
Clean up the temporary directory.
Definition: test.cc:220
int AssertionFailures() const
Definition: test.h:41
An entry for a single in-memory file.
Definition: test.h:155
Global state (file status) for a single run.
Definition: state.h:84
unsigned long long uint64_t
Definition: win32port.h:29
void RegisterTest(testing::Test *(*)(), const char *)
virtual void Run()=0