25 #include <sys/types.h>
35 virtual void SetUp() {
39 virtual void TearDown() {
45 TEST_F(BuildLogTest, WriteRead) {
47 "build out: cat mid\n"
48 "build mid: cat in\n");
62 ASSERT_EQ(2u, log1.
entries().size());
63 ASSERT_EQ(2u, log2.
entries().size());
68 ASSERT_TRUE(*e1 == *e2);
70 ASSERT_EQ(
"out", e1->
output);
73 TEST_F(BuildLogTest, FirstWriteAddsSignature) {
74 const char kExpectedVersion[] =
"# ninja log vX\n";
75 const size_t kVersionPos = strlen(kExpectedVersion) - 2;
78 std::string contents, err;
86 if (contents.size() >= kVersionPos)
87 contents[kVersionPos] =
'X';
88 EXPECT_EQ(kExpectedVersion, contents);
98 if (contents.size() >= kVersionPos)
99 contents[kVersionPos] =
'X';
100 EXPECT_EQ(kExpectedVersion, contents);
103 TEST_F(BuildLogTest, DoubleEntry) {
105 fprintf(f,
"# ninja log v7\n");
106 fprintf(f,
"0\t1\t2\tout\t%" PRIx64 "\n",
108 fprintf(f,
"0\t1\t2\tout\t%" PRIx64 "\n",
124 "build out: cat mid\n"
125 "build mid: cat in\n");
136 #ifdef __USE_LARGEFILE64
137 struct stat64 statbuf;
143 ASSERT_GT(statbuf.st_size, 0);
147 for (off_t size = statbuf.st_size; size > 0; --size) {
164 TEST_F(BuildLogTest, ObsoleteOldVersion) {
166 fprintf(f,
"# ninja log v3\n");
167 fprintf(f,
"123 456 0 out command\n");
173 ASSERT_NE(err.find(
"version"), std::string::npos);
176 TEST_F(BuildLogTest, SpacesInOutput) {
178 fprintf(f,
"# ninja log v7\n");
179 fprintf(f,
"123\t456\t456\tout with space\t%" PRIx64 "\n",
192 ASSERT_EQ(456, e->
mtime);
196 TEST_F(BuildLogTest, DuplicateVersionHeader) {
201 fprintf(f,
"# ninja log v7\n");
202 fprintf(f,
"123\t456\t456\tout\t%" PRIx64 "\n",
204 fprintf(f,
"# ninja log v7\n");
205 fprintf(f,
"456\t789\t789\tout2\t%" PRIx64 "\n",
218 ASSERT_EQ(456, e->
mtime);
225 ASSERT_EQ(789, e->
mtime);
230 TimeStamp Stat(
const std::string& path, std::string* err)
const override {
233 bool WriteFile(
const std::string& path,
const std::string& contents,
234 bool crlf_on_windows)
override {
238 bool MakeDir(
const std::string& path)
override {
243 std::string* err)
override {
247 int RemoveFile(
const std::string& path)
override {
253 TEST_F(BuildLogTest, Restat) {
255 fprintf(f,
"# ninja log v7\n"
256 "1\t2\t3\tout\tcommand\n");
263 ASSERT_EQ(3, e->
mtime);
265 TestDiskInterface testDiskInterface;
266 char out2[] = {
'o',
'u',
't',
'2', 0 };
267 char* filter2[] = { out2 };
271 ASSERT_EQ(3, e->
mtime);
276 ASSERT_EQ(4, e->
mtime);
279 TEST_F(BuildLogTest, VeryLongInputLine) {
283 fprintf(f,
"# ninja log v7\n");
284 fprintf(f,
"123\t456\t456\tout\tcommand start");
285 for (
size_t i = 0; i < (512 << 10) / strlen(
" more_command"); ++i)
286 fputs(
" more_command", f);
288 fprintf(f,
"456\t789\t789\tout2\t%" PRIx64 "\n",
304 ASSERT_EQ(789, e->
mtime);
308 TEST_F(BuildLogTest, MultiTargetEdge) {
310 "build out out.d: cat\n");
315 ASSERT_EQ(2u, log.
entries().size());
320 ASSERT_EQ(
"out", e1->
output);
321 ASSERT_EQ(
"out.d", e2->
output);
328 struct BuildLogRecompactTest :
public BuildLogTest {
329 virtual bool IsPathDead(
StringPiece s)
const {
return s ==
"out2"; }
332 TEST_F(BuildLogRecompactTest, Recompact) {
334 "build out: cat in\n"
335 "build out2: cat in\n");
343 for (
int i = 0; i < 200; ++i)
352 ASSERT_EQ(2u, log2.
entries().size());
363 ASSERT_EQ(1u, log2.
entries().size());
const char kTestFilename[]
Can answer questions about the manifest for the BuildLog.
virtual bool IsPathDead(StringPiece s) const =0
Return if a given output is no longer part of the build manifest.
static uint64_t HashCommand(StringPiece command)
Store a log of every command ran for every build.
LogEntry * LookupByOutput(const std::string &path)
Lookup a previously-run command by its output path.
LoadStatus Load(const std::string &path, std::string *err)
Load the on-disk log.
const Entries & entries() const
bool Restat(StringPiece path, const DiskInterface &disk_interface, int output_count, char **outputs, std::string *err)
Restat all outputs in the log.
bool OpenForWrite(const std::string &path, const BuildLogUser &user, std::string *err)
Prepares writing to the log file without actually opening it - that will happen when/if it's needed.
bool RecordCommand(Edge *edge, int start_time, int end_time, TimeStamp mtime=0)
Interface for accessing the disk.
virtual bool WriteFile(const std::string &path, const std::string &contents, bool crlf_on_windows)=0
Create a file, with the specified name and contents If crlf_on_windows is true, will be converted t...
virtual bool MakeDir(const std::string &path)=0
Create a directory, returning false on failure.
virtual int RemoveFile(const std::string &path)=0
Remove the file named path.
virtual TimeStamp Stat(const std::string &path, std::string *err) const =0
stat() a file, returning the mtime, or 0 if missing and -1 on other errors.
virtual Status ReadFile(const std::string &path, std::string *contents, std::string *err)=0
Read and store in given string.
A base test fixture that includes a State object with a builtin "cat" rule.
Abstract interface to object that tracks the status of a build: completion fraction,...
StringPiece represents a slice of a string whose memory is managed externally.
void AssertParse(State *state, const char *input, ManifestParserOptions opts)
void AssertHash(const char *expected, uint64_t actual)
int platformAwareUnlink(const char *filename)
bool Truncate(const string &path, size_t size, string *err)
int ReadFile(const string &path, string *contents, string *err)