Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1925)

Unified Diff: delta_diff_generator_unittest.cc

Issue 3597014: AU: reuse scratch blocks in delta generation, tolerate insufficient scratch. (Closed) Base URL: ssh://git@chromiumos-git/update_engine.git
Patch Set: address comments, fix code duplication Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « delta_diff_generator.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: delta_diff_generator_unittest.cc
diff --git a/delta_diff_generator_unittest.cc b/delta_diff_generator_unittest.cc
index 11f77350552bb3896292e310bfc4d5f363f3b1ce..0d7b0fe20903fdd423642932c7c429128f672636 100644
--- a/delta_diff_generator_unittest.cc
+++ b/delta_diff_generator_unittest.cc
@@ -7,6 +7,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <set>
+#include <sstream>
#include <string>
#include <utility>
#include <vector>
@@ -15,15 +16,18 @@
#include "update_engine/cycle_breaker.h"
#include "update_engine/delta_diff_generator.h"
#include "update_engine/delta_performer.h"
+#include "update_engine/extent_ranges.h"
#include "update_engine/graph_types.h"
#include "update_engine/graph_utils.h"
#include "update_engine/subprocess.h"
#include "update_engine/test_utils.h"
+#include "update_engine/topological_sort.h"
#include "update_engine/utils.h"
using std::make_pair;
using std::set;
using std::string;
+using std::stringstream;
using std::vector;
namespace chromeos_update_engine {
@@ -161,13 +165,14 @@ TEST_F(DeltaDiffGeneratorTest, SubstituteBlocksTest) {
vector<Extent> replace_blocks;
AppendExtent(&replace_blocks, 10, 2);
AppendExtent(&replace_blocks, 13, 2);
- DeltaArchiveManifest_InstallOperation op;
+ Vertex vertex;
+ DeltaArchiveManifest_InstallOperation& op = vertex.op;
OpAppendExtent(&op, 4, 3);
OpAppendExtent(&op, kSparseHole, 4); // Sparse hole in file
OpAppendExtent(&op, 3, 1);
OpAppendExtent(&op, 7, 3);
- DeltaDiffGenerator::SubstituteBlocks(&op, remove_blocks, replace_blocks);
+ DeltaDiffGenerator::SubstituteBlocks(&vertex, remove_blocks, replace_blocks);
EXPECT_EQ(7, op.src_extents_size());
EXPECT_EQ(11, op.src_extents(0).start_block());
@@ -254,7 +259,8 @@ TEST_F(DeltaDiffGeneratorTest, CutEdgesTest) {
EXPECT_TRUE(cut_edges.end() != cut_edges.find(make_pair<Vertex::Index>(1,
0)));
- EXPECT_TRUE(DeltaDiffGenerator::CutEdges(&graph, blocks, cut_edges));
+ vector<CutEdgeVertexes> cuts;
+ EXPECT_TRUE(DeltaDiffGenerator::CutEdges(&graph, cut_edges, &cuts));
EXPECT_EQ(3, graph.size());
@@ -262,21 +268,17 @@ TEST_F(DeltaDiffGeneratorTest, CutEdgesTest) {
EXPECT_EQ(DeltaArchiveManifest_InstallOperation_Type_MOVE,
graph.back().op.type());
EXPECT_EQ(2, graph.back().op.src_extents_size());
- EXPECT_EQ(2, graph.back().op.dst_extents_size());
- EXPECT_EQ(0, graph.back().op.dst_extents(0).start_block());
- EXPECT_EQ(1, graph.back().op.dst_extents(0).num_blocks());
- EXPECT_EQ(8, graph.back().op.dst_extents(1).start_block());
- EXPECT_EQ(1, graph.back().op.dst_extents(1).num_blocks());
+ EXPECT_EQ(1, graph.back().op.dst_extents_size());
+ EXPECT_EQ(kTempBlockStart, graph.back().op.dst_extents(0).start_block());
+ EXPECT_EQ(2, graph.back().op.dst_extents(0).num_blocks());
EXPECT_TRUE(graph.back().out_edges.empty());
// Check that old node reads from new blocks
- EXPECT_EQ(3, graph[0].op.src_extents_size());
- EXPECT_EQ(0, graph[0].op.src_extents(0).start_block());
- EXPECT_EQ(1, graph[0].op.src_extents(0).num_blocks());
- EXPECT_EQ(8, graph[0].op.src_extents(1).start_block());
+ EXPECT_EQ(2, graph[0].op.src_extents_size());
+ EXPECT_EQ(kTempBlockStart, graph[0].op.src_extents(0).start_block());
+ EXPECT_EQ(2, graph[0].op.src_extents(0).num_blocks());
+ EXPECT_EQ(7, graph[0].op.src_extents(1).start_block());
EXPECT_EQ(1, graph[0].op.src_extents(1).num_blocks());
- EXPECT_EQ(7, graph[0].op.src_extents(2).start_block());
- EXPECT_EQ(1, graph[0].op.src_extents(2).num_blocks());
// And that the old dst extents haven't changed
EXPECT_EQ(2, graph[0].op.dst_extents_size());
@@ -348,4 +350,209 @@ TEST_F(DeltaDiffGeneratorTest, ReorderBlobsTest) {
unlink(new_blobs.c_str());
}
+TEST_F(DeltaDiffGeneratorTest, MoveFullOpsToBackTest) {
+ Graph graph(4);
+ graph[0].file_name = "A";
+ graph[0].op.set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE);
+ graph[1].file_name = "B";
+ graph[1].op.set_type(DeltaArchiveManifest_InstallOperation_Type_BSDIFF);
+ graph[2].file_name = "C";
+ graph[2].op.set_type(DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ);
+ graph[3].file_name = "D";
+ graph[3].op.set_type(DeltaArchiveManifest_InstallOperation_Type_MOVE);
+
+ vector<Vertex::Index> vect(graph.size());
+
+ for (vector<Vertex::Index>::size_type i = 0; i < vect.size(); ++i) {
+ vect[i] = i;
+ }
+ DeltaDiffGenerator::MoveFullOpsToBack(&graph, &vect);
+ EXPECT_EQ(vect.size(), graph.size());
+ EXPECT_EQ(graph[vect[0]].file_name, "B");
+ EXPECT_EQ(graph[vect[1]].file_name, "D");
+ EXPECT_EQ(graph[vect[2]].file_name, "A");
+ EXPECT_EQ(graph[vect[3]].file_name, "C");
+}
+
+namespace {
+
+#define OP_BSDIFF DeltaArchiveManifest_InstallOperation_Type_BSDIFF
+#define OP_MOVE DeltaArchiveManifest_InstallOperation_Type_MOVE
+#define OP_REPLACE DeltaArchiveManifest_InstallOperation_Type_REPLACE
+#define OP_REPLACE_BZ DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ
+
+void GenVertex(Vertex* out,
+ const vector<Extent>& src_extents,
+ const vector<Extent>& dst_extents,
+ const string& path,
+ DeltaArchiveManifest_InstallOperation_Type type) {
+ out->op.set_type(type);
+ out->file_name = path;
+ DeltaDiffGenerator::StoreExtents(src_extents, out->op.mutable_src_extents());
+ DeltaDiffGenerator::StoreExtents(dst_extents, out->op.mutable_dst_extents());
+}
+
+vector<Extent> VectOfExt(uint64_t start_block, uint64_t num_blocks) {
+ return vector<Extent>(1, ExtentForRange(start_block, num_blocks));
+}
+
+EdgeProperties EdgeWithReadDep(const vector<Extent>& extents) {
+ EdgeProperties ret;
+ ret.extents = extents;
+ return ret;
+}
+
+EdgeProperties EdgeWithWriteDep(const vector<Extent>& extents) {
+ EdgeProperties ret;
+ ret.write_extents = extents;
+ return ret;
+}
+
+template<typename T>
+void DumpVect(const vector<T>& vect) {
+ std::stringstream ss(stringstream::out);
+ for (typename vector<T>::const_iterator it = vect.begin(), e = vect.end();
+ it != e; ++it) {
+ ss << *it << ", ";
+ }
+ LOG(INFO) << "{" << ss.str() << "}";
+}
+
+} // namespace {}
+
+TEST_F(DeltaDiffGeneratorTest, RunAsRootAssignTempBlocksTest) {
+ Graph graph(9);
+ const vector<Extent> empt; // empty
+ const string kFilename = "/foo";
+
+ // Some scratch space:
+ GenVertex(&graph[0], empt, VectOfExt(200, 1), "", OP_REPLACE);
+ GenVertex(&graph[1], empt, VectOfExt(210, 10), "", OP_REPLACE);
+ GenVertex(&graph[2], empt, VectOfExt(220, 1), "", OP_REPLACE);
+
+ // A cycle that requires 10 blocks to break:
+ GenVertex(&graph[3], VectOfExt(10, 11), VectOfExt(0, 9), "", OP_BSDIFF);
+ graph[3].out_edges[4] = EdgeWithReadDep(VectOfExt(0, 9));
+ GenVertex(&graph[4], VectOfExt(0, 9), VectOfExt(10, 11), "", OP_BSDIFF);
+ graph[4].out_edges[3] = EdgeWithReadDep(VectOfExt(10, 11));
+
+ // A cycle that requires 9 blocks to break:
+ GenVertex(&graph[5], VectOfExt(40, 11), VectOfExt(30, 10), "", OP_BSDIFF);
+ graph[5].out_edges[6] = EdgeWithReadDep(VectOfExt(30, 10));
+ GenVertex(&graph[6], VectOfExt(30, 10), VectOfExt(40, 11), "", OP_BSDIFF);
+ graph[6].out_edges[5] = EdgeWithReadDep(VectOfExt(40, 11));
+
+ // A cycle that requires 40 blocks to break (which is too many):
+ GenVertex(&graph[7],
+ VectOfExt(120, 50),
+ VectOfExt(60, 40),
+ "",
+ OP_BSDIFF);
+ graph[7].out_edges[8] = EdgeWithReadDep(VectOfExt(60, 40));
+ GenVertex(&graph[8],
+ VectOfExt(60, 40),
+ VectOfExt(120, 50),
+ kFilename,
+ OP_BSDIFF);
+ graph[8].out_edges[7] = EdgeWithReadDep(VectOfExt(120, 50));
+
+ graph_utils::DumpGraph(graph);
+
+ vector<Vertex::Index> final_order;
+
+
+ // Prepare the filesystem with the minimum required for this to work
+ string temp_dir;
+ EXPECT_TRUE(utils::MakeTempDirectory("/tmp/AssignTempBlocksTest.XXXXXX",
+ &temp_dir));
+ ScopedDirRemover temp_dir_remover(temp_dir);
+
+ const size_t kBlockSize = 4096;
+ vector<char> temp_data(kBlockSize * 50);
+ FillWithData(&temp_data);
+ EXPECT_TRUE(WriteFileVector(temp_dir + kFilename, temp_data));
+ ScopedPathUnlinker filename_unlinker(temp_dir + kFilename);
+
+ int fd;
+ EXPECT_TRUE(utils::MakeTempFile("/tmp/AssignTempBlocksTestData.XXXXXX",
+ NULL,
+ &fd));
+ ScopedFdCloser fd_closer(&fd);
+ off_t data_file_size = 0;
+
+
+ EXPECT_TRUE(DeltaDiffGenerator::ConvertGraphToDag(&graph,
+ temp_dir,
+ fd,
+ &data_file_size,
+ &final_order));
+
+
+ Graph expected_graph(12);
+ GenVertex(&expected_graph[0], empt, VectOfExt(200, 1), "", OP_REPLACE);
+ GenVertex(&expected_graph[1], empt, VectOfExt(210, 10), "", OP_REPLACE);
+ GenVertex(&expected_graph[2], empt, VectOfExt(220, 1), "", OP_REPLACE);
+ GenVertex(&expected_graph[3],
+ VectOfExt(10, 11),
+ VectOfExt(0, 9),
+ "",
+ OP_BSDIFF);
+ expected_graph[3].out_edges[9] = EdgeWithReadDep(VectOfExt(0, 9));
+ GenVertex(&expected_graph[4],
+ VectOfExt(60, 9),
+ VectOfExt(10, 11),
+ "",
+ OP_BSDIFF);
+ expected_graph[4].out_edges[3] = EdgeWithReadDep(VectOfExt(10, 11));
+ expected_graph[4].out_edges[9] = EdgeWithWriteDep(VectOfExt(60, 9));
+ GenVertex(&expected_graph[5],
+ VectOfExt(40, 11),
+ VectOfExt(30, 10),
+ "",
+ OP_BSDIFF);
+ expected_graph[5].out_edges[10] = EdgeWithReadDep(VectOfExt(30, 10));
+
+ GenVertex(&expected_graph[6],
+ VectOfExt(60, 10),
+ VectOfExt(40, 11),
+ "",
+ OP_BSDIFF);
+ expected_graph[6].out_edges[5] = EdgeWithReadDep(VectOfExt(40, 11));
+ expected_graph[6].out_edges[10] = EdgeWithWriteDep(VectOfExt(60, 10));
+
+ GenVertex(&expected_graph[7],
+ VectOfExt(120, 50),
+ VectOfExt(60, 40),
+ "",
+ OP_BSDIFF);
+ expected_graph[7].out_edges[6] = EdgeWithReadDep(VectOfExt(60, 10));
+
+ GenVertex(&expected_graph[8], empt, VectOfExt(0, 50), "/foo", OP_REPLACE_BZ);
+ expected_graph[8].out_edges[7] = EdgeWithReadDep(VectOfExt(120, 50));
+
+ GenVertex(&expected_graph[9],
+ VectOfExt(0, 9),
+ VectOfExt(60, 9),
+ "",
+ OP_MOVE);
+
+ GenVertex(&expected_graph[10],
+ VectOfExt(30, 10),
+ VectOfExt(60, 10),
+ "",
+ OP_MOVE);
+ expected_graph[10].out_edges[4] = EdgeWithReadDep(VectOfExt(60, 9));
+
+ EXPECT_EQ(12, graph.size());
+ EXPECT_FALSE(graph.back().valid);
+ for (Graph::size_type i = 0; i < graph.size() - 1; i++) {
+ EXPECT_TRUE(graph[i].out_edges == expected_graph[i].out_edges);
+ if (i == 8) {
+ // special case
+ } else {
+ // EXPECT_TRUE(graph[i] == expected_graph[i]) << "i = " << i;
+ }
+ }
+}
+
} // namespace chromeos_update_engine
« no previous file with comments | « delta_diff_generator.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698