//
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "update_engine/payload_generator/inplace_generator.h"

#include <map>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include <base/format_macros.h>
#include <base/logging.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <gtest/gtest.h>

#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
#include "update_engine/payload_generator/cycle_breaker.h"
#include "update_engine/payload_generator/delta_diff_generator.h"
#include "update_engine/payload_generator/delta_diff_utils.h"
#include "update_engine/payload_generator/extent_ranges.h"
#include "update_engine/payload_generator/graph_types.h"
#include "update_engine/payload_generator/graph_utils.h"

using std::map;
using std::set;
using std::string;
using std::stringstream;
using std::vector;

namespace chromeos_update_engine {

using Block = InplaceGenerator::Block;

namespace {

void GenVertex(Vertex* out,
               const vector<Extent>& src_extents,
               const vector<Extent>& dst_extents,
               const string& path,
               InstallOperation_Type type) {
  out->aop.op.set_type(type);
  out->aop.name = path;
  StoreExtents(src_extents, out->aop.op.mutable_src_extents());
  StoreExtents(dst_extents, out->aop.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) {
  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() << "}";
}

void AppendExtent(vector<Extent>* vect, uint64_t start, uint64_t length) {
  vect->resize(vect->size() + 1);
  vect->back().set_start_block(start);
  vect->back().set_num_blocks(length);
}

void OpAppendExtent(InstallOperation* op, uint64_t start, uint64_t length) {
  Extent* extent = op->add_src_extents();
  extent->set_start_block(start);
  extent->set_num_blocks(length);
}

}  // namespace

class InplaceGeneratorTest : public ::testing::Test {
 protected:
  // Initialize |blob_path_|, |blob_file_size_| and |blob_file_fd_| variables
  // with a new blob file. The file is closed and removed automatically when
  // the test finishes.
  void CreateBlobFile() {
    // blob_fd_closer_ takes a pointer to blob_fd_. Make sure we destroy a
    // previous instance before overriding blob_fd_.
    blob_fd_closer_.reset();
    EXPECT_TRUE(utils::MakeTempFile(
        "InplaceGenerator_blob_file.XXXXXX", &blob_path_, &blob_fd_));
    blob_path_unlinker_.reset(new ScopedPathUnlinker(blob_path_));
    blob_fd_closer_.reset(new ScopedFdCloser(&blob_fd_));
    blob_file_size_ = 0;
    EXPECT_GE(blob_fd_, 0);
    blob_file_.reset(new BlobFileWriter(blob_fd_, &blob_file_size_));
  }

  // Dump the list of operations |aops| in case of test failure.
  void DumpAopsOnFailure(const vector<AnnotatedOperation>& aops) {
    if (HasNonfatalFailure()) {
      LOG(INFO) << "Result operation list:";
      for (const auto& aop : aops) {
        LOG(INFO) << aop;
      }
    }
  }

  // Blob file name, file descriptor and file size used to store operation
  // blobs.
  string blob_path_;
  int blob_fd_{-1};
  off_t blob_file_size_{0};
  std::unique_ptr<BlobFileWriter> blob_file_;
  std::unique_ptr<ScopedPathUnlinker> blob_path_unlinker_;
  std::unique_ptr<ScopedFdCloser> blob_fd_closer_;
};

TEST_F(InplaceGeneratorTest, BlockDefaultValues) {
  // Tests that a Block is initialized with the default values as a
  // Vertex::kInvalidIndex. This is required by the delta generators.
  Block block;
  EXPECT_EQ(Vertex::kInvalidIndex, block.reader);
  EXPECT_EQ(Vertex::kInvalidIndex, block.writer);
}

TEST_F(InplaceGeneratorTest, SubstituteBlocksTest) {
  vector<Extent> remove_blocks;
  AppendExtent(&remove_blocks, 3, 3);
  AppendExtent(&remove_blocks, 7, 1);
  vector<Extent> replace_blocks;
  AppendExtent(&replace_blocks, 10, 2);
  AppendExtent(&replace_blocks, 13, 2);
  Vertex vertex;
  InstallOperation& op = vertex.aop.op;
  OpAppendExtent(&op, 4, 3);
  OpAppendExtent(&op, kSparseHole, 4);  // Sparse hole in file
  OpAppendExtent(&op, 3, 1);
  OpAppendExtent(&op, 7, 3);

  InplaceGenerator::SubstituteBlocks(&vertex, remove_blocks, replace_blocks);

  EXPECT_EQ(7, op.src_extents_size());
  EXPECT_EQ(11U, op.src_extents(0).start_block());
  EXPECT_EQ(1U, op.src_extents(0).num_blocks());
  EXPECT_EQ(13U, op.src_extents(1).start_block());
  EXPECT_EQ(1U, op.src_extents(1).num_blocks());
  EXPECT_EQ(6U, op.src_extents(2).start_block());
  EXPECT_EQ(1U, op.src_extents(2).num_blocks());
  EXPECT_EQ(kSparseHole, op.src_extents(3).start_block());
  EXPECT_EQ(4U, op.src_extents(3).num_blocks());
  EXPECT_EQ(10U, op.src_extents(4).start_block());
  EXPECT_EQ(1U, op.src_extents(4).num_blocks());
  EXPECT_EQ(14U, op.src_extents(5).start_block());
  EXPECT_EQ(1U, op.src_extents(5).num_blocks());
  EXPECT_EQ(8U, op.src_extents(6).start_block());
  EXPECT_EQ(2U, op.src_extents(6).num_blocks());
}

TEST_F(InplaceGeneratorTest, CutEdgesTest) {
  Graph graph;
  vector<Block> blocks(9);

  // Create nodes in graph
  {
    graph.resize(graph.size() + 1);
    graph.back().aop.op.set_type(InstallOperation::MOVE);
    // Reads from blocks 3, 5, 7
    vector<Extent> extents;
    AppendBlockToExtents(&extents, 3);
    AppendBlockToExtents(&extents, 5);
    AppendBlockToExtents(&extents, 7);
    StoreExtents(extents, graph.back().aop.op.mutable_src_extents());
    blocks[3].reader = graph.size() - 1;
    blocks[5].reader = graph.size() - 1;
    blocks[7].reader = graph.size() - 1;

    // Writes to blocks 1, 2, 4
    extents.clear();
    AppendBlockToExtents(&extents, 1);
    AppendBlockToExtents(&extents, 2);
    AppendBlockToExtents(&extents, 4);
    StoreExtents(extents, graph.back().aop.op.mutable_dst_extents());
    blocks[1].writer = graph.size() - 1;
    blocks[2].writer = graph.size() - 1;
    blocks[4].writer = graph.size() - 1;
  }
  {
    graph.resize(graph.size() + 1);
    graph.back().aop.op.set_type(InstallOperation::MOVE);
    // Reads from blocks 1, 2, 4
    vector<Extent> extents;
    AppendBlockToExtents(&extents, 1);
    AppendBlockToExtents(&extents, 2);
    AppendBlockToExtents(&extents, 4);
    StoreExtents(extents, graph.back().aop.op.mutable_src_extents());
    blocks[1].reader = graph.size() - 1;
    blocks[2].reader = graph.size() - 1;
    blocks[4].reader = graph.size() - 1;

    // Writes to blocks 3, 5, 6
    extents.clear();
    AppendBlockToExtents(&extents, 3);
    AppendBlockToExtents(&extents, 5);
    AppendBlockToExtents(&extents, 6);
    StoreExtents(extents, graph.back().aop.op.mutable_dst_extents());
    blocks[3].writer = graph.size() - 1;
    blocks[5].writer = graph.size() - 1;
    blocks[6].writer = graph.size() - 1;
  }

  // Create edges
  InplaceGenerator::CreateEdges(&graph, blocks);

  // Find cycles
  CycleBreaker cycle_breaker;
  set<Edge> cut_edges;
  cycle_breaker.BreakCycles(graph, &cut_edges);

  EXPECT_EQ(1U, cut_edges.size());
  EXPECT_TRUE(cut_edges.end() != cut_edges.find(
      std::pair<Vertex::Index, Vertex::Index>(1, 0)));

  vector<CutEdgeVertexes> cuts;
  EXPECT_TRUE(InplaceGenerator::CutEdges(&graph, cut_edges, &cuts));

  EXPECT_EQ(3U, graph.size());

  // Check new node in graph:
  EXPECT_EQ(InstallOperation::MOVE, graph.back().aop.op.type());
  EXPECT_EQ(2, graph.back().aop.op.src_extents_size());
  EXPECT_EQ(1, graph.back().aop.op.dst_extents_size());
  EXPECT_EQ(kTempBlockStart, graph.back().aop.op.dst_extents(0).start_block());
  EXPECT_EQ(2U, graph.back().aop.op.dst_extents(0).num_blocks());
  EXPECT_TRUE(graph.back().out_edges.empty());

  // Check that old node reads from new blocks
  EXPECT_EQ(2, graph[0].aop.op.src_extents_size());
  EXPECT_EQ(kTempBlockStart, graph[0].aop.op.src_extents(0).start_block());
  EXPECT_EQ(2U, graph[0].aop.op.src_extents(0).num_blocks());
  EXPECT_EQ(7U, graph[0].aop.op.src_extents(1).start_block());
  EXPECT_EQ(1U, graph[0].aop.op.src_extents(1).num_blocks());

  // And that the old dst extents haven't changed
  EXPECT_EQ(2, graph[0].aop.op.dst_extents_size());
  EXPECT_EQ(1U, graph[0].aop.op.dst_extents(0).start_block());
  EXPECT_EQ(2U, graph[0].aop.op.dst_extents(0).num_blocks());
  EXPECT_EQ(4U, graph[0].aop.op.dst_extents(1).start_block());
  EXPECT_EQ(1U, graph[0].aop.op.dst_extents(1).num_blocks());

  // Ensure it only depends on the next node and the new temp node
  EXPECT_EQ(2U, graph[0].out_edges.size());
  EXPECT_TRUE(graph[0].out_edges.end() != graph[0].out_edges.find(1));
  EXPECT_TRUE(graph[0].out_edges.end() != graph[0].out_edges.find(graph.size() -
                                                                  1));

  // Check second node has unchanged extents
  EXPECT_EQ(2, graph[1].aop.op.src_extents_size());
  EXPECT_EQ(1U, graph[1].aop.op.src_extents(0).start_block());
  EXPECT_EQ(2U, graph[1].aop.op.src_extents(0).num_blocks());
  EXPECT_EQ(4U, graph[1].aop.op.src_extents(1).start_block());
  EXPECT_EQ(1U, graph[1].aop.op.src_extents(1).num_blocks());

  EXPECT_EQ(2, graph[1].aop.op.dst_extents_size());
  EXPECT_EQ(3U, graph[1].aop.op.dst_extents(0).start_block());
  EXPECT_EQ(1U, graph[1].aop.op.dst_extents(0).num_blocks());
  EXPECT_EQ(5U, graph[1].aop.op.dst_extents(1).start_block());
  EXPECT_EQ(2U, graph[1].aop.op.dst_extents(1).num_blocks());

  // Ensure it only depends on the next node
  EXPECT_EQ(1U, graph[1].out_edges.size());
  EXPECT_TRUE(graph[1].out_edges.end() != graph[1].out_edges.find(2));
}

TEST_F(InplaceGeneratorTest, AssignTempBlocksReuseTest) {
  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), "", InstallOperation::MOVE);
  GenVertex(&graph[1],
            VectOfExt(tmp, 1),
            VectOfExt(0, 1),
            "",
            InstallOperation::MOVE);
  GenVertex(&graph[2],
            VectOfExt(1, 1),
            VectOfExt(tmp, 1),
            "",
            InstallOperation::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), "", InstallOperation::MOVE);
  GenVertex(
      &graph[4], VectOfExt(6, 1), VectOfExt(7, 1), "", InstallOperation::MOVE);
  GenVertex(&graph[5],
            VectOfExt(tmp, 3),
            VectOfExt(4, 3),
            kFilename,
            InstallOperation::MOVE);
  GenVertex(&graph[6],
            VectOfExt(2, 2),
            VectOfExt(tmp, 2),
            "",
            InstallOperation::MOVE);
  GenVertex(&graph[7],
            VectOfExt(7, 1),
            VectOfExt(tmp + 2, 1),
            "",
            InstallOperation::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), "", InstallOperation::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;
  InplaceGenerator::GenerateReverseTopoOrderMap(op_indexes,
                                                &reverse_op_indexes);

  CreateBlobFile();
  EXPECT_TRUE(InplaceGenerator::AssignTempBlocks(&graph,
                                                 "/dev/zero",
                                                 blob_file_.get(),
                                                 &op_indexes,
                                                 &reverse_op_indexes,
                                                 cuts));
  EXPECT_FALSE(graph[6].valid);
  EXPECT_FALSE(graph[7].valid);
  EXPECT_EQ(1, graph[1].aop.op.src_extents_size());
  EXPECT_EQ(2U, graph[1].aop.op.src_extents(0).start_block());
  EXPECT_EQ(1U, graph[1].aop.op.src_extents(0).num_blocks());
  EXPECT_EQ(InstallOperation::REPLACE_BZ, graph[5].aop.op.type());
}

TEST_F(InplaceGeneratorTest, MoveAndSortFullOpsToBackTest) {
  Graph graph(4);
  graph[0].aop.name = "A";
  graph[0].aop.op.set_type(InstallOperation::REPLACE);
  graph[1].aop.name = "B";
  graph[1].aop.op.set_type(InstallOperation::BSDIFF);
  graph[2].aop.name = "C";
  graph[2].aop.op.set_type(InstallOperation::REPLACE_BZ);
  graph[3].aop.name = "D";
  graph[3].aop.op.set_type(InstallOperation::MOVE);

  vector<Vertex::Index> vect(graph.size());

  for (vector<Vertex::Index>::size_type i = 0; i < vect.size(); ++i) {
    vect[i] = i;
  }
  InplaceGenerator::MoveAndSortFullOpsToBack(&graph, &vect);
  EXPECT_EQ(vect.size(), graph.size());
  EXPECT_EQ(graph[vect[0]].aop.name, "B");
  EXPECT_EQ(graph[vect[1]].aop.name, "D");
  EXPECT_EQ(graph[vect[2]].aop.name, "A");
  EXPECT_EQ(graph[vect[3]].aop.name, "C");
}

TEST_F(InplaceGeneratorTest, AssignTempBlocksTest) {
  Graph graph(9);
  const vector<Extent> empt;  // empty
  const string kFilename = "/foo";

  // Some scratch space:
  GenVertex(&graph[0], empt, VectOfExt(200, 1), "", InstallOperation::REPLACE);
  GenVertex(&graph[1], empt, VectOfExt(210, 10), "", InstallOperation::REPLACE);
  GenVertex(&graph[2], empt, VectOfExt(220, 1), "", InstallOperation::REPLACE);

  // A cycle that requires 10 blocks to break:
  GenVertex(&graph[3],
            VectOfExt(10, 11),
            VectOfExt(0, 9),
            "",
            InstallOperation::BSDIFF);
  graph[3].out_edges[4] = EdgeWithReadDep(VectOfExt(0, 9));
  GenVertex(&graph[4],
            VectOfExt(0, 9),
            VectOfExt(10, 11),
            "",
            InstallOperation::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),
            "",
            InstallOperation::BSDIFF);
  graph[5].out_edges[6] = EdgeWithReadDep(VectOfExt(30, 10));
  GenVertex(&graph[6],
            VectOfExt(30, 10),
            VectOfExt(40, 11),
            "",
            InstallOperation::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),
            "",
            InstallOperation::BSDIFF);
  graph[7].out_edges[8] = EdgeWithReadDep(VectOfExt(60, 40));
  GenVertex(&graph[8],
            VectOfExt(60, 40),
            VectOfExt(120, 50),
            kFilename,
            InstallOperation::BSDIFF);
  graph[8].out_edges[7] = EdgeWithReadDep(VectOfExt(120, 50));

  graph_utils::DumpGraph(graph);

  vector<Vertex::Index> final_order;

  CreateBlobFile();
  EXPECT_TRUE(InplaceGenerator::ConvertGraphToDag(&graph,
                                                  "/dev/zero",
                                                  blob_file_.get(),
                                                  &final_order,
                                                  Vertex::kInvalidIndex));

  Graph expected_graph(12);
  GenVertex(&expected_graph[0],
            empt,
            VectOfExt(200, 1),
            "",
            InstallOperation::REPLACE);
  GenVertex(&expected_graph[1],
            empt,
            VectOfExt(210, 10),
            "",
            InstallOperation::REPLACE);
  GenVertex(&expected_graph[2],
            empt,
            VectOfExt(220, 1),
            "",
            InstallOperation::REPLACE);
  GenVertex(&expected_graph[3],
            VectOfExt(10, 11),
            VectOfExt(0, 9),
            "",
            InstallOperation::BSDIFF);
  expected_graph[3].out_edges[9] = EdgeWithReadDep(VectOfExt(0, 9));
  GenVertex(&expected_graph[4],
            VectOfExt(60, 9),
            VectOfExt(10, 11),
            "",
            InstallOperation::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),
            "",
            InstallOperation::BSDIFF);
  expected_graph[5].out_edges[10] = EdgeWithReadDep(VectOfExt(30, 10));

  GenVertex(&expected_graph[6],
            VectOfExt(60, 10),
            VectOfExt(40, 11),
            "",
            InstallOperation::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),
            "",
            InstallOperation::BSDIFF);
  expected_graph[7].out_edges[6] = EdgeWithReadDep(VectOfExt(60, 10));

  GenVertex(&expected_graph[8],
            empt,
            VectOfExt(0, 50),
            "/foo",
            InstallOperation::REPLACE_BZ);
  expected_graph[8].out_edges[7] = EdgeWithReadDep(VectOfExt(120, 50));

  GenVertex(&expected_graph[9],
            VectOfExt(0, 9),
            VectOfExt(60, 9),
            "",
            InstallOperation::MOVE);

  GenVertex(&expected_graph[10],
            VectOfExt(30, 10),
            VectOfExt(60, 10),
            "",
            InstallOperation::MOVE);
  expected_graph[10].out_edges[4] = EdgeWithReadDep(VectOfExt(60, 9));

  EXPECT_EQ(12U, 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;
    }
  }
}

TEST_F(InplaceGeneratorTest, CreateScratchNodeTest) {
  Vertex vertex;
  InplaceGenerator::CreateScratchNode(12, 34, &vertex);
  EXPECT_EQ(InstallOperation::REPLACE_BZ, vertex.aop.op.type());
  EXPECT_EQ(0U, vertex.aop.op.data_offset());
  EXPECT_EQ(0U, vertex.aop.op.data_length());
  EXPECT_EQ(1, vertex.aop.op.dst_extents_size());
  EXPECT_EQ(12U, vertex.aop.op.dst_extents(0).start_block());
  EXPECT_EQ(34U, vertex.aop.op.dst_extents(0).num_blocks());
}

TEST_F(InplaceGeneratorTest, ApplyMapTest) {
  vector<uint64_t> collection = {1, 2, 3, 4, 6};
  vector<uint64_t> expected_values = {1, 2, 5, 4, 8};
  map<uint64_t, uint64_t> value_map;
  value_map[3] = 5;
  value_map[6] = 8;
  value_map[5] = 10;

  InplaceGenerator::ApplyMap(&collection, value_map);
  EXPECT_EQ(expected_values, collection);
}

// We can't produce MOVE operations with a source or destination in the block 0.
// This test checks that the cycle breaker procedure doesn't produce such
// operations.
TEST_F(InplaceGeneratorTest, ResolveReadAfterWriteDependenciesAvoidMoveToZero) {
  size_t block_size = 4096;
  size_t num_blocks = 4;
  vector<AnnotatedOperation> aops;

  // Create a REPLACE_BZ for block 0, and a circular dependency among all other
  // blocks. This situation would prefer to issue a MOVE to scratch space and
  // the only available block is 0.
  aops.emplace_back();
  aops.back().name = base::StringPrintf("<bz-block-0>");
  aops.back().op.set_type(InstallOperation::REPLACE_BZ);
  StoreExtents({ExtentForRange(0, 1)}, aops.back().op.mutable_dst_extents());

  for (size_t i = 1; i < num_blocks; i++) {
    AnnotatedOperation aop;
    aop.name = base::StringPrintf("<op-%" PRIuS ">", i);
    aop.op.set_type(InstallOperation::BSDIFF);
    StoreExtents({ExtentForRange(1 + i % (num_blocks - 1), 1)},
                 aop.op.mutable_src_extents());
    StoreExtents({ExtentForRange(i, 1)}, aop.op.mutable_dst_extents());
    aops.push_back(aop);
  }

  PartitionConfig part("part");
  part.path = "/dev/zero";
  part.size = num_blocks * block_size;

  CreateBlobFile();

  // We ran two tests here. The first one without enough blocks for the scratch
  // space, forcing it to create a new full operation and the second case with
  // one extra block in the partition that can be used for the move operation.
  for (const auto part_blocks : vector<uint64_t>{num_blocks, num_blocks + 1}) {
    SCOPED_TRACE(
        base::StringPrintf("Using partition_blocks=%" PRIu64, part_blocks));
    vector<AnnotatedOperation> result_aops = aops;
    EXPECT_TRUE(InplaceGenerator::ResolveReadAfterWriteDependencies(
        part,
        part,
        part_blocks * block_size,
        block_size,
        blob_file_.get(),
        &result_aops));

    size_t full_ops = 0;
    for (const auto& aop : result_aops) {
      if (diff_utils::IsAReplaceOperation(aop.op.type()))
        full_ops++;

      if (aop.op.type() != InstallOperation::MOVE)
        continue;
      for (const Extent& extent : aop.op.src_extents()) {
        EXPECT_NE(0U, extent.start_block())
            << "On src extents for aop: " << aop;
      }
      for (const Extent& extent : aop.op.dst_extents()) {
        EXPECT_NE(0U, extent.start_block())
            << "On dst extents for aop: " << aop;
      }
    }

    // If there's extra space in the partition, it should not use a new full
    // operation for it.
    EXPECT_EQ(part_blocks == num_blocks ? 2U : 1U, full_ops);

    DumpAopsOnFailure(result_aops);
  }
}

// Test that we can shrink a filesystem and break cycles.
TEST_F(InplaceGeneratorTest, ResolveReadAfterWriteDependenciesShrinkData) {
  size_t block_size = 4096;
  size_t old_blocks = 10;
  size_t new_blocks = 8;
  vector<AnnotatedOperation> aops;

  // Create a loop using the blocks 1-6 and one other operation writing to the
  // block 7 from outside the new partition. The loop in the blocks 1-6 uses
  // two-block operations, so it needs two blocks of scratch space. It can't use
  // the block 0 as scratch space (see previous test) and it can't use the
  // blocks 7 or 8 due the last move operation.

  aops.emplace_back();
  aops.back().name = base::StringPrintf("<bz-block-0>");
  aops.back().op.set_type(InstallOperation::REPLACE_BZ);
  StoreExtents({ExtentForRange(0, 1)}, aops.back().op.mutable_dst_extents());

  const size_t num_ops = 3;
  for (size_t i = 0; i < num_ops; i++) {
    AnnotatedOperation aop;
    aop.name = base::StringPrintf("<op-%" PRIuS ">", i);
    aop.op.set_type(InstallOperation::BSDIFF);
    StoreExtents({ExtentForRange(1 + 2 * i, 2)}, aop.op.mutable_src_extents());
    StoreExtents({ExtentForRange(1 + 2 * ((i + 1) % num_ops), 2)},
                 aop.op.mutable_dst_extents());
    aops.push_back(aop);
  }

  {
    AnnotatedOperation aop;
    aop.name = "<op-shrink>";
    aop.op.set_type(InstallOperation::BSDIFF);
    StoreExtents({ExtentForRange(8, 1)}, aop.op.mutable_src_extents());
    StoreExtents({ExtentForRange(7, 1)}, aop.op.mutable_dst_extents());
    aops.push_back(aop);
  }

  PartitionConfig old_part("part");
  old_part.path = "/dev/zero";
  old_part.size = old_blocks * block_size;

  PartitionConfig new_part("part");
  new_part.path = "/dev/zero";
  new_part.size = new_blocks * block_size;

  CreateBlobFile();

  EXPECT_TRUE(InplaceGenerator::ResolveReadAfterWriteDependencies(
      old_part,
      new_part,
      (old_blocks + 2) * block_size,  // enough scratch space.
      block_size,
      blob_file_.get(),
      &aops));

  size_t full_ops = 0;
  for (const auto& aop : aops) {
    if (diff_utils::IsAReplaceOperation(aop.op.type()))
      full_ops++;
  }
  // There should be only one REPLACE* operation, the one we added for block 0.
  EXPECT_EQ(1U, full_ops);

  // There should be only one MOVE operation, the one used to break the loop
  // which should write to scratch space past the block 7 (the last block of the
  // new partition) which is being written later.
  size_t move_ops = 0;
  for (const auto& aop : aops) {
    if (aop.op.type() == InstallOperation::MOVE) {
      move_ops++;
      for (const Extent& extent : aop.op.dst_extents()) {
        EXPECT_LE(7U, extent.start_block()) << "On dst extents for aop: "
                                            << aop;
      }
    }
  }
  EXPECT_EQ(1U, move_ops);

  DumpAopsOnFailure(aops);
}

}  // namespace chromeos_update_engine
