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 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 string& path, const 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 string& path, string* err) const;
148  virtual bool WriteFile(const string& path, const string& contents);
149  virtual bool MakeDir(const string& path);
150  virtual Status ReadFile(const string& path, string* contents, string* err);
151  virtual int RemoveFile(const string& path);
152 
153  /// An entry for a single in-memory file.
154  struct Entry {
155  int mtime;
156  string stat_error; // If mtime is -1.
157  string contents;
158  };
159 
160  vector<string> directories_made_;
161  vector<string> files_read_;
162  typedef map<string, Entry> FileMap;
164  set<string> files_removed_;
165  set<string> files_created_;
166 
167  /// A simple fake timestamp for file operations.
168  int now_;
169 };
170 
172  /// Create a temporary directory and chdir into it.
173  void CreateAndEnter(const string& name);
174 
175  /// Clean up the temporary directory.
176  void Cleanup();
177 
178  /// The temp directory containing our dir.
179  string start_dir_;
180  /// The subdirectory name for our dir, or empty if it hasn't been set up.
182 };
183 
184 #endif // NINJA_TEST_H_
map< string, Entry > FileMap
Definition: test.h:162
FileMap files_
Definition: test.h:163
An implementation of DiskInterface that uses an in-memory representation of disk state.
Definition: test.h:134
Definition: test.h:29
void VerifyGraph(const State &state)
Definition: test.cc:111
Node * GetNode(const string &path)
Short way to get a Node by its path from state_.
Definition: test.cc:93
int Tick()
Tick "time" forwards; subsequent file operations will be newer than previous ones.
Definition: test.h:142
bool failed_
Definition: test.h:31
void AssertParse(State *state, const char *input, ManifestParserOptions=ManifestParserOptions())
Definition: test.cc:98
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
set< string > files_removed_
Definition: test.h:164
virtual bool WriteFile(const string &path, const string &contents)
Create a file, with the specified name and contents Returns true on success, false on failure...
Definition: test.cc:159
Interface for accessing the disk.
int now_
A simple fake timestamp for file operations.
Definition: test.h:168
void Create(const string &path, const string &contents)
"Create" a file with contents.
Definition: test.cc:143
virtual void TearDown()
Definition: test.h:37
set< string > files_created_
Definition: test.h:165
vector< string > directories_made_
Definition: test.h:160
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:107
int assertion_failures_
Definition: test.h:32
void AddCatRule(State *state)
Add a "cat" rule to state.
Definition: test.cc:87
testing::Test * g_current_test
Definition: ninja_test.cc:41
bool Failed() const
Definition: test.h:40
virtual ~Test()
Definition: test.h:35
string start_dir_
The temp directory containing our dir.
Definition: test.h:179
VirtualFileSystem()
Definition: test.h:135
void AddAssertionFailure()
Definition: test.h:42
virtual bool MakeDir(const string &path)
Create a directory, returning false on failure.
Definition: test.cc:164
Status
Result of ReadFile.
int64_t TimeStamp
Definition: timestamp.h:31
bool Check(bool condition, const char *file, int line, const char *error)
Definition: ninja_test.cc:119
void Cleanup()
Clean up the temporary directory.
Definition: test.cc:218
int AssertionFailures() const
Definition: test.h:41
virtual TimeStamp Stat(const string &path, string *err) const
stat() a file, returning the mtime, or 0 if missing and -1 on other errors.
Definition: test.cc:150
An entry for a single in-memory file.
Definition: test.h:154
virtual Status ReadFile(const string &path, string *contents, string *err)
Read and store in given string.
Definition: test.cc:169
void CreateAndEnter(const string &name)
Create a temporary directory and chdir into it.
Definition: test.cc:196
Global state (file status) for a single run.
Definition: state.h:85
vector< string > files_read_
Definition: test.h:161
virtual int RemoveFile(const string &path)
Remove the file named path.
Definition: test.cc:182
unsigned long long uint64_t
Definition: win32port.h:29
string temp_dir_name_
The subdirectory name for our dir, or empty if it hasn&#39;t been set up.
Definition: test.h:181
void RegisterTest(testing::Test *(*)(), const char *)
virtual void Run()=0