Index: delta_diff_generator_unittest.cc |
diff --git a/delta_diff_generator_unittest.cc b/delta_diff_generator_unittest.cc |
index ef4190f274020f9f2f90e942c303f39662bdbd58..4a11c52904dc55fe0b72babeb79cfd905ef6e172 100644 |
--- a/delta_diff_generator_unittest.cc |
+++ b/delta_diff_generator_unittest.cc |
@@ -429,6 +429,13 @@ vector<Extent> VectOfExt(uint64_t start_block, uint64_t num_blocks) { |
return vector<Extent>(1, ExtentForRange(start_block, num_blocks)); |
} |
+vector<Extent> VectOfExts(uint64_t start_block1, uint64_t num_blocks1, |
+ uint64_t start_block2, uint64_t num_blocks2) { |
+ vector<Extent> ret(1, ExtentForRange(start_block1, num_blocks1)); |
+ ret.push_back(ExtentForRange(start_block2, num_blocks2)); |
+ return ret; |
+} |
+ |
EdgeProperties EdgeWithReadDep(const vector<Extent>& extents) { |
EdgeProperties ret; |
ret.extents = extents; |
@@ -613,4 +620,112 @@ TEST_F(DeltaDiffGeneratorTest, IsNoopOperationTest) { |
EXPECT_FALSE(DeltaDiffGenerator::IsNoopOperation(op)); |
} |
+TEST_F(DeltaDiffGeneratorTest, RunAsRootAssignTempBlocksReuseTest) { |
+ // AssignTempBlocks(Graph* graph, |
+ // const string& new_root, |
+ // int data_fd, |
+ // off_t* data_file_size, |
+ // vector<Vertex::Index>* op_indexes, |
+ // vector<vector<Vertex::Index>::size_type>* reverse_op_indexes, |
+ // const vector<CutEdgeVertexes>& cuts |
+ Graph graph(9); |
+ |
+ const vector<Extent> empt; |
+ uint64_t tmp = kTempBlockStart; |
+ const string kFilename = "/foo"; |
+ |
+ vector<CutEdgeVertexes> cuts; |
+ cuts.resize(3); |
+ |
+ // Simple broken loop: |
+ GenVertex(&graph[0], VectOfExt(0, 1), VectOfExt(1, 1), "", OP_MOVE); |
+ GenVertex(&graph[1], VectOfExt(tmp, 1), VectOfExt(0, 1), "", OP_MOVE); |
+ GenVertex(&graph[2], VectOfExt(1, 1), VectOfExt(tmp, 1), "", OP_MOVE); |
+ // Corresponding edges: |
+ graph[0].out_edges[2] = EdgeWithReadDep(VectOfExt(1, 1)); |
+ graph[1].out_edges[2] = EdgeWithWriteDep(VectOfExt(tmp, 1)); |
+ graph[1].out_edges[0] = EdgeWithReadDep(VectOfExt(0, 1)); |
+ // Store the cut: |
+ cuts[0].old_dst = 1; |
+ cuts[0].old_src = 0; |
+ cuts[0].new_vertex = 2; |
+ cuts[0].tmp_extents = VectOfExt(tmp, 1); |
+ tmp++; |
+ |
+ // Slightly more complex pair of loops: |
+ GenVertex(&graph[3], VectOfExt(4, 2), VectOfExt(2, 2), "", OP_MOVE); |
+ GenVertex(&graph[4], VectOfExt(6, 1), VectOfExt(7, 1), "", OP_MOVE); |
+ GenVertex(&graph[5], VectOfExt(tmp, 3), VectOfExt(4, 3), kFilename, OP_MOVE); |
+ GenVertex(&graph[6], VectOfExt(2, 2), VectOfExt(tmp, 2), "", OP_MOVE); |
+ GenVertex(&graph[7], VectOfExt(7, 1), VectOfExt(tmp + 2, 1), "", OP_MOVE); |
+ // Corresponding edges: |
+ graph[3].out_edges[6] = EdgeWithReadDep(VectOfExt(2, 2)); |
+ graph[4].out_edges[7] = EdgeWithReadDep(VectOfExt(7, 1)); |
+ graph[5].out_edges[6] = EdgeWithWriteDep(VectOfExt(tmp, 2)); |
+ graph[5].out_edges[7] = EdgeWithWriteDep(VectOfExt(tmp + 2, 1)); |
+ graph[5].out_edges[3] = EdgeWithReadDep(VectOfExt(4, 2)); |
+ graph[5].out_edges[4] = EdgeWithReadDep(VectOfExt(6, 1)); |
+ // Store the cuts: |
+ cuts[1].old_dst = 5; |
+ cuts[1].old_src = 3; |
+ cuts[1].new_vertex = 6; |
+ cuts[1].tmp_extents = VectOfExt(tmp, 2); |
+ cuts[2].old_dst = 5; |
+ cuts[2].old_src = 4; |
+ cuts[2].new_vertex = 7; |
+ cuts[2].tmp_extents = VectOfExt(tmp + 2, 1); |
+ |
+ // Supplier of temp block: |
+ GenVertex(&graph[8], empt, VectOfExt(8, 1), "", OP_REPLACE); |
+ |
+ // Specify the final order: |
+ vector<Vertex::Index> op_indexes; |
+ op_indexes.push_back(2); |
+ op_indexes.push_back(0); |
+ op_indexes.push_back(1); |
+ op_indexes.push_back(6); |
+ op_indexes.push_back(3); |
+ op_indexes.push_back(7); |
+ op_indexes.push_back(4); |
+ op_indexes.push_back(5); |
+ op_indexes.push_back(8); |
+ |
+ vector<vector<Vertex::Index>::size_type> reverse_op_indexes; |
+ DeltaDiffGenerator::GenerateReverseTopoOrderMap(op_indexes, |
+ &reverse_op_indexes); |
+ |
+ // Prepare the filesystem with the minimum required for this to work |
+ string temp_dir; |
+ EXPECT_TRUE(utils::MakeTempDirectory("/tmp/AssignTempBlocksReuseTest.XXXXXX", |
+ &temp_dir)); |
+ ScopedDirRemover temp_dir_remover(temp_dir); |
+ |
+ const size_t kBlockSize = 4096; |
+ vector<char> temp_data(kBlockSize * 3); |
+ FillWithData(&temp_data); |
+ EXPECT_TRUE(WriteFileVector(temp_dir + kFilename, temp_data)); |
+ ScopedPathUnlinker filename_unlinker(temp_dir + kFilename); |
+ |
+ int fd; |
+ EXPECT_TRUE(utils::MakeTempFile("/tmp/AssignTempBlocksReuseTest.XXXXXX", |
+ NULL, |
+ &fd)); |
+ ScopedFdCloser fd_closer(&fd); |
+ off_t data_file_size = 0; |
+ |
+ EXPECT_TRUE(DeltaDiffGenerator::AssignTempBlocks(&graph, |
+ temp_dir, |
+ fd, |
+ &data_file_size, |
+ &op_indexes, |
+ &reverse_op_indexes, |
+ cuts)); |
+ EXPECT_FALSE(graph[6].valid); |
+ EXPECT_FALSE(graph[7].valid); |
+ EXPECT_EQ(1, graph[1].op.src_extents_size()); |
+ EXPECT_EQ(2, graph[1].op.src_extents(0).start_block()); |
+ EXPECT_EQ(1, graph[1].op.src_extents(0).num_blocks()); |
+ EXPECT_EQ(OP_REPLACE_BZ, graph[5].op.type()); |
+} |
+ |
} // namespace chromeos_update_engine |