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 <gtest/gtest.h> 19 20 #include "disk_interface.h" 21 #include "manifest_parser.h" 22 #include "state.h" 23 24 // Support utilities for tests. 25 26 struct Node; 27 28 /// A base test fixture that includes a State object with a 29 /// builtin "cat" rule. 30 struct StateTestWithBuiltinRules : public testing::Test { 31 StateTestWithBuiltinRules(); 32 33 /// Add a "cat" rule to \a state. Used by some tests; it's 34 /// otherwise done by the ctor to state_. 35 void AddCatRule(State* state); 36 37 /// Short way to get a Node by its path from state_. 38 Node* GetNode(const std::string& path); 39 40 State state_; 41 }; 42 43 void AssertParse(State* state, const char* input, 44 ManifestParserOptions = ManifestParserOptions()); 45 void AssertHash(const char* expected, uint64_t actual); 46 void VerifyGraph(const State& state); 47 48 /// An implementation of DiskInterface that uses an in-memory representation 49 /// of disk state. It also logs file accesses and directory creations 50 /// so it can be used by tests to verify disk access patterns. 51 struct VirtualFileSystem : public DiskInterface { VirtualFileSystemVirtualFileSystem52 VirtualFileSystem() : now_(1) {} 53 54 /// "Create" a file with contents. 55 void Create(const std::string& path, const std::string& contents); 56 57 /// Tick "time" forwards; subsequent file operations will be newer than 58 /// previous ones. TickVirtualFileSystem59 int Tick() { 60 return ++now_; 61 } 62 63 // DiskInterface 64 virtual TimeStamp Stat(const std::string& path, std::string* err) const; 65 virtual bool WriteFile(const std::string& path, const std::string& contents); 66 virtual bool MakeDir(const std::string& path); 67 virtual Status ReadFile(const std::string& path, std::string* contents, 68 std::string* err); 69 virtual int RemoveFile(const std::string& path); 70 71 /// An entry for a single in-memory file. 72 struct Entry { 73 int mtime; 74 std::string stat_error; // If mtime is -1. 75 std::string contents; 76 }; 77 78 std::vector<std::string> directories_made_; 79 std::vector<std::string> files_read_; 80 typedef std::map<std::string, Entry> FileMap; 81 FileMap files_; 82 std::set<std::string> files_removed_; 83 std::set<std::string> files_created_; 84 85 /// A simple fake timestamp for file operations. 86 int now_; 87 }; 88 89 struct ScopedTempDir { 90 /// Create a temporary directory and chdir into it. 91 void CreateAndEnter(const std::string& name); 92 93 /// Clean up the temporary directory. 94 void Cleanup(); 95 96 /// The temp directory containing our dir. 97 std::string start_dir_; 98 /// The subdirectory name for our dir, or empty if it hasn't been set up. 99 std::string temp_dir_name_; 100 }; 101 102 /// A class that records a file path and ensures that it is removed 103 /// on destruction. This ensures that tests do not keep stale files in the 104 /// current directory where they run, even in case of assertion failure. 105 struct ScopedFilePath { 106 /// Constructor just records the file path. ScopedFilePathScopedFilePath107 ScopedFilePath(const std::string& path) : path_(path) {} ScopedFilePathScopedFilePath108 ScopedFilePath(const char* path) : path_(path) {} 109 110 /// Allow move operations. 111 ScopedFilePath(ScopedFilePath&&) noexcept; 112 ScopedFilePath& operator=(ScopedFilePath&&) noexcept; 113 114 /// Destructor destroys the file, unless Release() was called. 115 ~ScopedFilePath(); 116 117 /// Release the file, the destructor will not remove the file. 118 void Release(); 119 c_strScopedFilePath120 const char* c_str() const { return path_.c_str(); } pathScopedFilePath121 const std::string& path() const { return path_; } releasedScopedFilePath122 bool released() const { return released_; } 123 124 private: 125 std::string path_; 126 bool released_ = false; 127 }; 128 129 #endif // NINJA_TEST_H_ 130