// Copyright (c) 2012 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/postinstall_runner_action.h"

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

#include <memory>
#include <string>
#include <vector>

#include <base/files/file_util.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <gtest/gtest.h>

#include "update_engine/constants.h"
#include "update_engine/test_utils.h"
#include "update_engine/utils.h"

using chromeos_update_engine::test_utils::System;
using chromeos_update_engine::test_utils::WriteFileString;
using std::string;
using std::unique_ptr;
using std::vector;

namespace chromeos_update_engine {

namespace {
gboolean StartProcessorInRunLoop(gpointer data) {
  ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data);
  processor->StartProcessing();
  return FALSE;
}
}  // namespace

class PostinstallRunnerActionTest : public ::testing::Test {
 public:
  // DoTest with various combinations of do_losetup, err_code and
  // powerwash_required.
  void DoTest(bool do_losetup, int err_code, bool powerwash_required);

 private:
  static const char* kImageMountPointTemplate;
};

class PostinstActionProcessorDelegate : public ActionProcessorDelegate {
 public:
  PostinstActionProcessorDelegate()
      : loop_(nullptr),
        code_(ErrorCode::kError),
        code_set_(false) {}
  void ProcessingDone(const ActionProcessor* processor,
                      ErrorCode code) {
    ASSERT_TRUE(loop_);
    g_main_loop_quit(loop_);
  }
  void ActionCompleted(ActionProcessor* processor,
                       AbstractAction* action,
                       ErrorCode code) {
    if (action->Type() == PostinstallRunnerAction::StaticType()) {
      code_ = code;
      code_set_ = true;
    }
  }
  GMainLoop* loop_;
  ErrorCode code_;
  bool code_set_;
};

TEST_F(PostinstallRunnerActionTest, RunAsRootSimpleTest) {
  ASSERT_EQ(0, getuid());
  DoTest(true, 0, false);
}

TEST_F(PostinstallRunnerActionTest, RunAsRootPowerwashRequiredTest) {
  ASSERT_EQ(0, getuid());
  DoTest(true, 0, true);
}

TEST_F(PostinstallRunnerActionTest, RunAsRootCantMountTest) {
  ASSERT_EQ(0, getuid());
  DoTest(false, 0, true);
}

TEST_F(PostinstallRunnerActionTest, RunAsRootErrScriptTest) {
  ASSERT_EQ(0, getuid());
  DoTest(true, 1, false);
}

TEST_F(PostinstallRunnerActionTest, RunAsRootFirmwareBErrScriptTest) {
  ASSERT_EQ(0, getuid());
  DoTest(true, 3, false);
}

TEST_F(PostinstallRunnerActionTest, RunAsRootFirmwareROErrScriptTest) {
  ASSERT_EQ(0, getuid());
  DoTest(true, 4, false);
}

const char* PostinstallRunnerActionTest::kImageMountPointTemplate =
    "au_destination-XXXXXX";

void PostinstallRunnerActionTest::DoTest(
    bool do_losetup,
    int err_code,
    bool powerwash_required) {
  ASSERT_EQ(0, getuid()) << "Run me as root. Ideally don't run other tests "
                         << "as root, tho.";
  // True if the post-install action is expected to succeed.
  bool should_succeed = do_losetup && !err_code;

  string orig_cwd;
  {
    vector<char> buf(1000);
    ASSERT_EQ(buf.data(), getcwd(buf.data(), buf.size()));
    orig_cwd = string(buf.data(), strlen(buf.data()));
  }

  // Create a unique named working directory and chdir into it.
  string cwd;
  ASSERT_TRUE(utils::MakeTempDirectory(
          "postinstall_runner_action_unittest-XXXXXX",
          &cwd));
  ASSERT_EQ(0, test_utils::Chdir(cwd));

  // Create a 10MiB sparse file to be used as image; format it as ext2.
  ASSERT_EQ(0, System(
          "dd if=/dev/zero of=image.dat seek=10485759 bs=1 count=1 "
          "status=none"));
  ASSERT_EQ(0, System("mkfs.ext2 -F image.dat"));

  // Create a uniquely named image mount point, mount the image.
  ASSERT_EQ(0, System(string("mkdir -p ") + kStatefulPartition));
  string mountpoint;
  ASSERT_TRUE(utils::MakeTempDirectory(
          string(kStatefulPartition) + "/" + kImageMountPointTemplate,
          &mountpoint));
  ASSERT_EQ(0, System(string("mount -o loop image.dat ") + mountpoint));

  // Generate a fake postinst script inside the image.
  string script = (err_code ?
                   base::StringPrintf("#!/bin/bash\nexit %d", err_code) :
                   base::StringPrintf(
                       "#!/bin/bash\n"
                       "mount | grep au_postint_mount | grep ext2\n"
                       "if [ $? -eq 0 ]; then\n"
                       "  touch %s/postinst_called\n"
                       "fi\n",
                       cwd.c_str()));
  const string script_file_name = mountpoint + "/postinst";
  ASSERT_TRUE(WriteFileString(script_file_name, script));
  ASSERT_EQ(0, System(string("chmod a+x ") + script_file_name));

  // Unmount image; do not remove the uniquely named directory as it will be
  // reused during the test.
  ASSERT_TRUE(utils::UnmountFilesystem(mountpoint));

  // get a loop device we can use for the install device
  string dev = "/dev/null";

  unique_ptr<test_utils::ScopedLoopbackDeviceBinder> loop_releaser;
  if (do_losetup) {
    loop_releaser.reset(new test_utils::ScopedLoopbackDeviceBinder(
            cwd + "/image.dat", &dev));
  }

  // We use a test-specific powerwash marker file, to avoid race conditions.
  string powerwash_marker_file = mountpoint + "/factory_install_reset";
  LOG(INFO) << ">>> powerwash_marker_file=" << powerwash_marker_file;

  ActionProcessor processor;
  ObjectFeederAction<InstallPlan> feeder_action;
  InstallPlan install_plan;
  install_plan.install_path = dev;
  install_plan.download_url = "http://devserver:8080/update";
  install_plan.powerwash_required = powerwash_required;
  feeder_action.set_obj(install_plan);
  PostinstallRunnerAction runner_action(powerwash_marker_file.c_str());
  BondActions(&feeder_action, &runner_action);
  ObjectCollectorAction<InstallPlan> collector_action;
  BondActions(&runner_action, &collector_action);
  PostinstActionProcessorDelegate delegate;
  processor.EnqueueAction(&feeder_action);
  processor.EnqueueAction(&runner_action);
  processor.EnqueueAction(&collector_action);
  processor.set_delegate(&delegate);

  GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
  delegate.loop_ = loop;
  g_timeout_add(0, &StartProcessorInRunLoop, &processor);
  g_main_loop_run(loop);
  g_main_loop_unref(loop);
  ASSERT_FALSE(processor.IsRunning());

  EXPECT_TRUE(delegate.code_set_);
  EXPECT_EQ(should_succeed, delegate.code_ == ErrorCode::kSuccess);
  EXPECT_EQ(should_succeed, !collector_action.object().install_path.empty());
  if (should_succeed)
    EXPECT_TRUE(install_plan == collector_action.object());

  const base::FilePath kPowerwashMarkerPath(powerwash_marker_file);
  string actual_cmd;
  if (should_succeed && powerwash_required) {
    EXPECT_TRUE(base::ReadFileToString(kPowerwashMarkerPath, &actual_cmd));
    EXPECT_EQ(kPowerwashCommand, actual_cmd);
  } else {
    EXPECT_FALSE(
        base::ReadFileToString(kPowerwashMarkerPath, &actual_cmd));
  }

  if (err_code == 2)
    EXPECT_EQ(ErrorCode::kPostinstallBootedFromFirmwareB, delegate.code_);

  struct stat stbuf;
  int rc = lstat((string(cwd) + "/postinst_called").c_str(), &stbuf);
  if (should_succeed)
    ASSERT_EQ(0, rc);
  else
    ASSERT_LT(rc, 0);

  if (do_losetup) {
    loop_releaser.reset(nullptr);
  }

  // Remove unique stateful directory.
  ASSERT_EQ(0, System(string("rm -fr ") + mountpoint));

  // Remove the temporary work directory.
  ASSERT_EQ(0, test_utils::Chdir(orig_cwd));
  ASSERT_EQ(0, System(string("rm -fr ") + cwd));
}

// Death tests don't seem to be working on Hardy
TEST_F(PostinstallRunnerActionTest, DISABLED_RunAsRootDeathTest) {
  ASSERT_EQ(0, getuid());
  PostinstallRunnerAction runner_action;
  ASSERT_DEATH({ runner_action.TerminateProcessing(); },
               "postinstall_runner_action.h:.*] Check failed");
}

}  // namespace chromeos_update_engine
