summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Martin <martine@danga.com>2013-04-26 18:21:57 (GMT)
committerEvan Martin <martine@danga.com>2013-04-26 18:21:57 (GMT)
commita4c33ea48bdbecb3b0176681885c0192599b01fd (patch)
treeb5dfbf614e4c10dd9df5caa6b477f92be3f9a0fd
parent89bc19b23d31263ea54ba1c802e4e0d03ae70118 (diff)
downloadNinja-a4c33ea48bdbecb3b0176681885c0192599b01fd.zip
Ninja-a4c33ea48bdbecb3b0176681885c0192599b01fd.tar.gz
Ninja-a4c33ea48bdbecb3b0176681885c0192599b01fd.tar.bz2
add a test for truncated deps
This doesn't yet exhibit the full problems with truncation, but it's a start.
-rw-r--r--src/deps_log.h1
-rw-r--r--src/deps_log_test.cc60
2 files changed, 61 insertions, 0 deletions
diff --git a/src/deps_log.h b/src/deps_log.h
index 99b006e..4b357a8 100644
--- a/src/deps_log.h
+++ b/src/deps_log.h
@@ -86,6 +86,7 @@ struct DepsLog {
/// Used for tests.
const vector<Node*>& nodes() const { return nodes_; }
+ const vector<Deps*>& deps() const { return deps_; }
private:
// Write a node name record, assigning it an id.
diff --git a/src/deps_log_test.cc b/src/deps_log_test.cc
index 0172d24..40539a7 100644
--- a/src/deps_log_test.cc
+++ b/src/deps_log_test.cc
@@ -218,4 +218,64 @@ TEST_F(DepsLogTest, InvalidHeader) {
}
}
+// Simulate what happens if a write gets interrupted and the resulting
+// file is truncated.
+TEST_F(DepsLogTest, Truncated) {
+ // Create a file with some entries.
+ {
+ State state;
+ DepsLog log;
+ string err;
+ EXPECT_TRUE(log.OpenForWrite(kTestFilename, &err));
+ ASSERT_EQ("", err);
+
+ vector<Node*> deps;
+ deps.push_back(state.GetNode("foo.h"));
+ deps.push_back(state.GetNode("bar.h"));
+ log.RecordDeps(state.GetNode("out.o"), 1, deps);
+
+ deps.clear();
+ deps.push_back(state.GetNode("foo.h"));
+ deps.push_back(state.GetNode("bar2.h"));
+ log.RecordDeps(state.GetNode("out2.o"), 2, deps);
+
+ log.Close();
+ }
+
+ // Get the file size.
+ struct stat st;
+ ASSERT_EQ(0, stat(kTestFilename, &st));
+
+ // Try reloading at truncated sizes.
+ // Track how many nodes/deps were found; they should decrease with
+ // smaller sizes.
+ int node_count = 5;
+ int deps_count = 2;
+ for (int size = (int)st.st_size; size > 0; --size) {
+ ASSERT_EQ(0, truncate(kTestFilename, size));
+
+ State state;
+ DepsLog log;
+ string err;
+ EXPECT_TRUE(log.Load(kTestFilename, &state, &err));
+ if (!err.empty()) {
+ // At some point the log will be so short as to be unparseable.
+ break;
+ }
+
+ ASSERT_GE(node_count, log.nodes().size());
+ node_count = log.nodes().size();
+
+ // Count how many non-NULL deps entries there are.
+ int new_deps_count = 0;
+ for (vector<DepsLog::Deps*>::const_iterator i = log.deps().begin();
+ i != log.deps().end(); ++i) {
+ if (*i)
+ ++new_deps_count;
+ }
+ ASSERT_GE(deps_count, new_deps_count);
+ deps_count = new_deps_count;
+ }
+}
+
} // anonymous namespace