// Copyright 2018 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 "debugd/src/storage_tool.h"

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <gtest/gtest.h>
#include <stdlib.h>

namespace {

constexpr char kMountsDataForNone[] = R"(
/dev/root / ext2 rw 0 0
devtmpfs /dev devtmpfs rw 0 0
none /proc proc rw,nosuid,nodev,noexec,relatime 0 0
none /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0
none /sys/fs/selinux selinuxfs rw,nosuid,noexec,relatime 0 0
tmp /tmp tmpfs rw,seclabel,nodev,relatime 0 0
run /run tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,mode=755 0 0
  )";

constexpr char kMountsDataForSamePrefix[] = R"(
/dev/root / ext2 rw 0 0
devtmpfs /dev devtmpfs rw 0 0
none /proc proc rw,nosuid,nodev,noexec,relatime 0 0
none /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0
none /sys/fs/selinux selinuxfs rw,nosuid,noexec,relatime 0 0
tmp /tmp tmpfs rw,seclabel,nodev,relatime 0 0
run /run tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,mode=755 0 0
/dev/mapper/encstateful /mnt/stateful_partition/encrypted ext4 rw 0 0
/dev/sda1 /mnt/stateful_partition rw 0 0
  )";

constexpr char kMountsDataExample[] = R"(
/dev/root / ext2 rw 0 0
devtmpfs /dev devtmpfs rw 0 0
none /proc proc rw,nosuid,nodev,noexec,relatime 0 0
none /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0
none /sys/fs/selinux selinuxfs rw,nosuid,noexec,relatime 0 0
tmp /tmp tmpfs rw,seclabel,nodev,relatime 0 0
run /run tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,mode=755 0 0
/dev/mapper/encstateful /mnt/stateful_partition/encrypted ext4 rw 0 0
/dev/sda1 /mnt/stateful_partition rw 0 0
  )";

constexpr char kMountsDataExampleMMC[] = R"(
/dev/root / ext2 rw 0 0
devtmpfs /dev devtmpfs rw 0 0
none /proc proc rw,nosuid,nodev,noexec,relatime 0 0
none /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0
none /sys/fs/selinux selinuxfs rw,nosuid,noexec,relatime 0 0
tmp /tmp tmpfs rw,seclabel,nodev,relatime 0 0
run /run tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,mode=755 0 0
/dev/mapper/encstateful /mnt/stateful_partition/encrypted ext4 rw 0 0
/dev/mmcblk0p10 /mnt/stateful_partition rw 0 0
  )";

constexpr char kMountsDataExampleMMCRepeatedNumber[] = R"(
/dev/root / ext2 rw 0 0
devtmpfs /dev devtmpfs rw 0 0
none /proc proc rw,nosuid,nodev,noexec,relatime 0 0
none /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0
none /sys/fs/selinux selinuxfs rw,nosuid,noexec,relatime 0 0
tmp /tmp tmpfs rw,seclabel,nodev,relatime 0 0
run /run tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,mode=755 0 0
/dev/mapper/encstateful /mnt/stateful_partition/encrypted ext4 rw 0 0
/dev/mmcblk3p3 /mnt/stateful_partition rw 0 0
  )";

constexpr char kMountsDataExampleDM[] = R"(
/dev/root / ext2 rw 0 0
devtmpfs /dev devtmpfs rw 0 0
none /proc proc rw,nosuid,nodev,noexec,relatime 0 0
none /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0
none /sys/fs/selinux selinuxfs rw,nosuid,noexec,relatime 0 0
tmp /tmp tmpfs rw,seclabel,nodev,relatime 0 0
run /run tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,mode=755 0 0
/dev/mapper/encstateful /mnt/stateful_partition/encrypted ext4 rw 0 0
/dev/dm-1 /mnt/stateful_partition rw 0 0
  )";

constexpr char kMountsDataExampleNVME[] = R"(
/dev/root / ext2 rw 0 0
devtmpfs /dev devtmpfs rw 0 0
none /proc proc rw,nosuid,nodev,noexec,relatime 0 0
none /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0
none /sys/fs/selinux selinuxfs rw,nosuid,noexec,relatime 0 0
tmp /tmp tmpfs rw,seclabel,nodev,relatime 0 0
run /run tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,mode=755 0 0
/dev/mapper/encstateful /mnt/stateful_partition/encrypted ext4 rw 0 0
/dev/nvme0n1p1 /mnt/stateful_partition rw 0 0
  )";

constexpr char kMountsDataExampleLOOP[] = R"(
/dev/root / ext2 rw 0 0
devtmpfs /dev devtmpfs rw 0 0
none /proc proc rw,nosuid,nodev,noexec,relatime 0 0
none /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0
none /sys/fs/selinux selinuxfs rw,nosuid,noexec,relatime 0 0
tmp /tmp tmpfs rw,seclabel,nodev,relatime 0 0
run /run tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,mode=755 0 0
/dev/mapper/encstateful /mnt/stateful_partition/encrypted ext4 rw 0 0
/dev/loop1 /mnt/stateful_partition rw 0 0
  )";


constexpr char kTypeFileDataTarget[] = "/sys/devices/target/type";

constexpr char kTypeFileDataMMC[] = "/sys/devices/mmc_host/mmc0/type";

TEST(StorageToolTest, TestGetDevice) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath mounts = temp_dir.path().Append("mounts");
  base::WriteFile(mounts, kMountsDataExample,
                  sizeof(kMountsDataExample));

  debugd::StorageTool sTool;
  const base::FilePath device =
    sTool.GetDevice(base::FilePath("/mnt/stateful_partition"), mounts);
  EXPECT_STREQ(device.value().c_str(), "/dev/sda");
}

TEST(StorageToolTest, TestGetDeviceMMC) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath mounts = temp_dir.path().Append("mounts");
  base::WriteFile(mounts, kMountsDataExampleMMC,
                  sizeof(kMountsDataExampleMMC));

  debugd::StorageTool sTool;
  const base::FilePath device =
    sTool.GetDevice(base::FilePath("/mnt/stateful_partition"), mounts);
  EXPECT_STREQ(device.value().c_str(), "/dev/mmcblk0");
}

TEST(StorageToolTest, TestGetDeviceMMCRepeatedNumber) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath mounts = temp_dir.path().Append("mounts");
  base::WriteFile(mounts, kMountsDataExampleMMCRepeatedNumber,
                  sizeof(kMountsDataExampleMMCRepeatedNumber));

  debugd::StorageTool sTool;
  const base::FilePath device =
    sTool.GetDevice(base::FilePath("/mnt/stateful_partition"), mounts);
  EXPECT_STREQ(device.value().c_str(), "/dev/mmcblk3");
}

TEST(StorageToolTest, TestGetDeviceDM) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath mounts = temp_dir.path().Append("mounts");
  base::WriteFile(mounts, kMountsDataExampleDM,
                  sizeof(kMountsDataExampleDM));

  debugd::StorageTool sTool;
  const base::FilePath device =
    sTool.GetDevice(base::FilePath("/mnt/stateful_partition"), mounts);
  EXPECT_STREQ(device.value().c_str(), "/dev/dm-1");
}

TEST(StorageToolTest, TestGetDeviceNVME) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath mounts = temp_dir.path().Append("mounts");
  base::WriteFile(mounts, kMountsDataExampleNVME,
                  sizeof(kMountsDataExampleNVME));

  debugd::StorageTool sTool;
  const base::FilePath device =
    sTool.GetDevice(base::FilePath("/mnt/stateful_partition"), mounts);
  EXPECT_STREQ(device.value().c_str(), "/dev/nvme0n1");
}

TEST(StorageToolTest, TestGetDeviceLoop) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath mounts = temp_dir.path().Append("mounts");
  base::WriteFile(mounts, kMountsDataExampleLOOP,
                  sizeof(kMountsDataExampleLOOP));

  debugd::StorageTool sTool;
  const base::FilePath device =
    sTool.GetDevice(base::FilePath("/mnt/stateful_partition"), mounts);
  EXPECT_STREQ(device.value().c_str(), "/dev/loop1");
}

TEST(StorageToolTest, TestGetDeviceNoMounts) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath mounts = temp_dir.path().Append("mounts");

  debugd::StorageTool sTool;
  const base::FilePath device =
    sTool.GetDevice(base::FilePath("/mnt/stateful_partition"), mounts);
  EXPECT_STREQ(device.value().c_str(), "");
}

TEST(StorageToolTest, TestGetDeviceForNone) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath mounts = temp_dir.path().Append("mounts");
  base::WriteFile(mounts, kMountsDataForNone,
                  sizeof(kMountsDataForNone));

  debugd::StorageTool sTool;
  const base::FilePath device =
    sTool.GetDevice(base::FilePath("/mnt/stateful_partition"), mounts);
  EXPECT_STREQ(device.value().c_str(), "");
}

TEST(StorageToolTest, TestGetDeviceSamePrefix) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath mounts = temp_dir.path().Append("mounts");
  base::WriteFile(mounts, kMountsDataForSamePrefix,
                  sizeof(kMountsDataForSamePrefix));

  debugd::StorageTool sTool;
  const base::FilePath device =
    sTool.GetDevice(base::FilePath("/mnt/stateful_partition"), mounts);
  EXPECT_STREQ(device.value().c_str(), "/dev/sda");
}

TEST(StorageToolTest, TestIsSupportedNoTypeLink) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath typeFile = temp_dir.path().Append("type");
  base::FilePath vendFile = temp_dir.path().Append("vendor");

  debugd::StorageTool sTool;
  std::string msg;
  bool supported = sTool.IsSupported(typeFile, vendFile, &msg);
  EXPECT_FALSE(supported);
  EXPECT_STREQ(msg.c_str(), "<Failed to read device type link>");
}

TEST(StorageToolTest, TestIsSupportedMMC) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath typeFile = temp_dir.path().Append("mmc_type");
  base::FilePath vendFile = temp_dir.path().Append("vendor");
  base::WriteFile(typeFile, kTypeFileDataMMC,
                  sizeof(kTypeFileDataMMC));

  debugd::StorageTool sTool;
  std::string msg;
  bool supported = sTool.IsSupported(typeFile, vendFile, &msg);
  EXPECT_FALSE(supported);
  EXPECT_STREQ(msg.c_str(), "<This feature is not supported>");
}

TEST(StorageToolTest, TestIsSupportedNoVend) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath typeFile = temp_dir.path().Append("target_type");
  base::FilePath vendFile = temp_dir.path().Append("vendor");
  base::WriteFile(typeFile, kTypeFileDataTarget,
                  sizeof(kTypeFileDataTarget));

  debugd::StorageTool sTool;
  std::string msg;
  bool supported = sTool.IsSupported(typeFile, vendFile, &msg);
  EXPECT_FALSE(supported);
  EXPECT_STREQ(msg.c_str(), "<Failed to open vendor file>");
}

TEST(StorageToolTest, TestIsSupportedVendEmpty) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath typeFile = temp_dir.path().Append("target_type");
  base::FilePath vendFile = temp_dir.path().Append("vendor");
  base::WriteFile(typeFile, kTypeFileDataTarget,
                  sizeof(kTypeFileDataTarget));

  const char *vendData = "";
  base::WriteFile(vendFile, vendData, 0);

  debugd::StorageTool sTool;
  std::string msg;
  bool supported = sTool.IsSupported(typeFile, vendFile, &msg);
  EXPECT_FALSE(supported);
  EXPECT_STREQ(msg.c_str(), "<Failed to find device type>");
}

TEST(StorageToolTest, TestIsSupportedOther) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath typeFile = temp_dir.path().Append("target_type");
  base::FilePath vendFile = temp_dir.path().Append("vendor");
  base::WriteFile(typeFile, kTypeFileDataTarget,
                  sizeof(kTypeFileDataTarget));

  constexpr char vendData[] = "OTHER";
  base::WriteFile(vendFile, vendData,
                  sizeof(vendData));

  debugd::StorageTool sTool;
  std::string msg;
  bool supported = sTool.IsSupported(typeFile, vendFile, &msg);
  EXPECT_FALSE(supported);
  EXPECT_STREQ(msg.c_str(), "<This feature is not supported>");
}

TEST(StorageToolTest, TestIsSupportedATA) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath typeFile = temp_dir.path().Append("target_type");
  base::FilePath vendFile = temp_dir.path().Append("vendor");
  base::WriteFile(typeFile, kTypeFileDataTarget,
                  sizeof(kTypeFileDataTarget));

  constexpr char vendData[] = "ATA";
  base::WriteFile(vendFile, vendData,
                  sizeof(vendData));

  debugd::StorageTool sTool;
  std::string msg;
  bool supported = sTool.IsSupported(typeFile, vendFile, &msg);
  EXPECT_TRUE(supported);
  EXPECT_STREQ(msg.c_str(), "");
}

}  // namespace
