// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "update_engine/payload_generator/extent_mapper.h"

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <set>
#include <string>
#include <vector>

#include <base/macros.h>
#include <gtest/gtest.h>

#include "update_engine/payload_constants.h"
#include "update_engine/utils.h"

using std::set;
using std::string;
using std::vector;

namespace chromeos_update_engine {

class ExtentMapperTest : public ::testing::Test {};

TEST(ExtentMapperTest, RunAsRootSimpleTest) {
  // It's hard to have a concrete test for extent mapping without including
  // a specific filesystem image.
  // In lieu of this, we do a weak test: make sure the extents of the unittest
  // executable are consistent and they match with the size of the file.
  const string kFilename = "/proc/self/exe";

  uint32_t block_size = 0;
  EXPECT_TRUE(extent_mapper::GetFilesystemBlockSize(kFilename, &block_size));
  EXPECT_GT(block_size, 0);

  vector<Extent> extents;

  ASSERT_TRUE(extent_mapper::ExtentsForFileFibmap(kFilename, &extents));

  EXPECT_FALSE(extents.empty());
  set<uint64_t> blocks;

  for (vector<Extent>::const_iterator it = extents.begin();
       it != extents.end(); ++it) {
    for (uint64_t block = it->start_block();
         block < it->start_block() + it->num_blocks();
         block++) {
      EXPECT_FALSE(utils::SetContainsKey(blocks, block));
      blocks.insert(block);
    }
  }

  off_t file_size = utils::FileSize(kFilename);
  EXPECT_GT(file_size, 0);
  EXPECT_EQ(blocks.size(), (file_size + block_size - 1)/block_size);

  // Map a 2-block chunk at offset |block_size|.
  vector<Extent> chunk_extents;
  ASSERT_TRUE(
      extent_mapper::ExtentsForFileChunkFibmap(kFilename,
                                               block_size,
                                               block_size + 1,
                                               &chunk_extents));
  EXPECT_FALSE(chunk_extents.empty());
  int chunk_blocks = 0;
  for (vector<Extent>::const_iterator it = chunk_extents.begin();
       it != chunk_extents.end(); ++it) {
    chunk_blocks += it->num_blocks();
  }
  EXPECT_EQ(2, chunk_blocks);
}

TEST(ExtentMapperTest, RunAsRootSparseFileTest) {
  // Create sparse file with one real block, then two sparse ones, then a real
  // block at the end.
  const char tmp_name_template[] =
      "/tmp/ExtentMapperTest.RunAsRootSparseFileTest.XXXXXX";
  char buf[sizeof(tmp_name_template)];
  strncpy(buf, tmp_name_template, sizeof(buf));
  COMPILE_ASSERT(sizeof(buf) > 8, buf_size_incorrect);
  ASSERT_EQ('\0', buf[sizeof(buf) - 1]);

  int fd = mkstemp(buf);
  ASSERT_GE(fd, 0);

  uint32_t block_size = 0;
  EXPECT_TRUE(extent_mapper::GetFilesystemBlockSize(buf, &block_size));
  EXPECT_GT(block_size, 0);

  EXPECT_EQ(1, pwrite(fd, "x", 1, 0));
  EXPECT_EQ(1, pwrite(fd, "x", 1, 3 * block_size));
  close(fd);

  vector<Extent> extents;
  EXPECT_TRUE(extent_mapper::ExtentsForFileFibmap(buf, &extents));
  unlink(buf);
  EXPECT_EQ(3, extents.size());
  EXPECT_EQ(1, extents[0].num_blocks());
  EXPECT_EQ(2, extents[1].num_blocks());
  EXPECT_EQ(1, extents[2].num_blocks());
  EXPECT_NE(kSparseHole, extents[0].start_block());
  EXPECT_EQ(kSparseHole, extents[1].start_block());
  EXPECT_NE(kSparseHole, extents[2].start_block());
  EXPECT_NE(extents[2].start_block(), extents[0].start_block());
}

}  // namespace chromeos_update_engine
