24 #include <sys/types.h>
34 virtual void SetUp() {
36 unlink(kTestFilename);
38 virtual void TearDown() {
39 unlink(kTestFilename);
44 TEST_F(BuildLogTest, WriteRead) {
46 "build out: cat mid\n"
47 "build mid: cat in\n");
51 EXPECT_TRUE(log1.
OpenForWrite(kTestFilename, *
this, &err));
58 EXPECT_TRUE(log2.
Load(kTestFilename, &err));
61 ASSERT_EQ(2u, log1.
entries().size());
62 ASSERT_EQ(2u, log2.
entries().size());
67 ASSERT_TRUE(*e1 == *e2);
68 ASSERT_EQ(15, e1->start_time);
69 ASSERT_EQ(
"out", e1->output);
72 TEST_F(BuildLogTest, FirstWriteAddsSignature) {
73 const char kExpectedVersion[] =
"# ninja log vX\n";
74 const size_t kVersionPos = strlen(kExpectedVersion) - 2;
79 EXPECT_TRUE(log.
OpenForWrite(kTestFilename, *
this, &err));
83 ASSERT_EQ(0,
ReadFile(kTestFilename, &contents, &err));
85 if (contents.size() >= kVersionPos)
86 contents[kVersionPos] =
'X';
87 EXPECT_EQ(kExpectedVersion, contents);
90 EXPECT_TRUE(log.
OpenForWrite(kTestFilename, *
this, &err));
95 ASSERT_EQ(0,
ReadFile(kTestFilename, &contents, &err));
97 if (contents.size() >= kVersionPos)
98 contents[kVersionPos] =
'X';
99 EXPECT_EQ(kExpectedVersion, contents);
102 TEST_F(BuildLogTest, DoubleEntry) {
103 FILE* f = fopen(kTestFilename,
"wb");
104 fprintf(f,
"# ninja log v4\n");
105 fprintf(f,
"0\t1\t2\tout\tcommand abc\n");
106 fprintf(f,
"3\t4\t5\tout\tcommand def\n");
111 EXPECT_TRUE(log.
Load(kTestFilename, &err));
121 "build out: cat mid\n"
122 "build mid: cat in\n");
126 EXPECT_TRUE(log1.
OpenForWrite(kTestFilename, *
this, &err));
133 ASSERT_EQ(0, stat(kTestFilename, &statbuf));
134 ASSERT_GT(statbuf.st_size, 0);
138 for (off_t size = statbuf.st_size; size > 0; --size) {
141 EXPECT_TRUE(log2.
OpenForWrite(kTestFilename, *
this, &err));
147 ASSERT_TRUE(
Truncate(kTestFilename, size, &err));
151 ASSERT_TRUE(log3.
Load(kTestFilename, &err) || !err.empty());
155 TEST_F(BuildLogTest, ObsoleteOldVersion) {
156 FILE* f = fopen(kTestFilename,
"wb");
157 fprintf(f,
"# ninja log v3\n");
158 fprintf(f,
"123 456 0 out command\n");
163 EXPECT_TRUE(log.
Load(kTestFilename, &err));
164 ASSERT_NE(err.find(
"version"), string::npos);
167 TEST_F(BuildLogTest, SpacesInOutputV4) {
168 FILE* f = fopen(kTestFilename,
"wb");
169 fprintf(f,
"# ninja log v4\n");
170 fprintf(f,
"123\t456\t456\tout with space\tcommand\n");
175 EXPECT_TRUE(log.
Load(kTestFilename, &err));
186 TEST_F(BuildLogTest, DuplicateVersionHeader) {
190 FILE* f = fopen(kTestFilename,
"wb");
191 fprintf(f,
"# ninja log v4\n");
192 fprintf(f,
"123\t456\t456\tout\tcommand\n");
193 fprintf(f,
"# ninja log v4\n");
194 fprintf(f,
"456\t789\t789\tout2\tcommand2\n");
199 EXPECT_TRUE(log.
Load(kTestFilename, &err));
217 TEST_F(BuildLogTest, VeryLongInputLine) {
220 FILE* f = fopen(kTestFilename,
"wb");
221 fprintf(f,
"# ninja log v4\n");
222 fprintf(f,
"123\t456\t456\tout\tcommand start");
223 for (
size_t i = 0; i < (512 << 10) / strlen(
" more_command"); ++i)
224 fputs(
" more_command", f);
226 fprintf(f,
"456\t789\t789\tout2\tcommand2\n");
231 EXPECT_TRUE(log.
Load(kTestFilename, &err));
245 TEST_F(BuildLogTest, MultiTargetEdge) {
247 "build out out.d: cat\n");
252 ASSERT_EQ(2u, log.
entries().size());
257 ASSERT_EQ(
"out", e1->output);
258 ASSERT_EQ(
"out.d", e2->
output);
259 ASSERT_EQ(21, e1->start_time);
265 struct BuildLogRecompactTest :
public BuildLogTest {
266 virtual bool IsPathDead(
StringPiece s)
const {
return s ==
"out2"; }
269 TEST_F(BuildLogRecompactTest, Recompact) {
271 "build out: cat in\n"
272 "build out2: cat in\n");
276 EXPECT_TRUE(log1.
OpenForWrite(kTestFilename, *
this, &err));
280 for (
int i = 0; i < 200; ++i)
287 EXPECT_TRUE(log2.
Load(kTestFilename, &err));
289 ASSERT_EQ(2u, log2.
entries().size());
293 EXPECT_TRUE(log2.
OpenForWrite(kTestFilename, *
this, &err));
298 EXPECT_TRUE(log2.
Load(kTestFilename, &err));
300 ASSERT_EQ(1u, log2.
entries().size());
const Entries & entries() const
StringPiece represents a slice of a string whose memory is managed externally.
void AssertParse(State *state, const char *input)
Store a log of every command ran for every build.
A base test fixture that includes a State object with a builtin "cat" rule.
virtual bool IsPathDead(StringPiece s) const =0
Return if a given output no longer part of the build manifest.
bool OpenForWrite(const string &path, const BuildLogUser &user, string *err)
const char kTestFilename[]
int ReadFile(const string &path, string *contents, string *err)
Read a file to a string (in text mode: with CRLF conversion on Windows).
bool Truncate(const string &path, size_t size, string *err)
Truncates a file to the given size.
LogEntry * LookupByOutput(const string &path)
Lookup a previously-run command by its output path.
bool RecordCommand(Edge *edge, int start_time, int end_time, TimeStamp restat_mtime=0)
bool Load(const string &path, string *err)
Load the on-disk log.
void AssertHash(const char *expected, uint64_t actual)
Can answer questions about the manifest for the BuildLog.