diff options
author | Evan Martin <martine@danga.com> | 2013-04-26 18:21:57 (GMT) |
---|---|---|
committer | Evan Martin <martine@danga.com> | 2013-04-26 18:21:57 (GMT) |
commit | a4c33ea48bdbecb3b0176681885c0192599b01fd (patch) | |
tree | b5dfbf614e4c10dd9df5caa6b477f92be3f9a0fd | |
parent | 89bc19b23d31263ea54ba1c802e4e0d03ae70118 (diff) | |
download | Ninja-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.h | 1 | ||||
-rw-r--r-- | src/deps_log_test.cc | 60 |
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 |