All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cvc5-cvc5-1.2.0.test.unit.options.options_black.cpp Maven / Gradle / Ivy

The newest version!
/******************************************************************************
 * Top contributors (to current version):
 *   Gereon Kremer, Andrew Reynolds, Aina Niemetz
 *
 * This file is part of the cvc5 project.
 *
 * Copyright (c) 2009-2024 by the authors listed in the file AUTHORS
 * in the top-level source directory and their institutional affiliations.
 * All rights reserved.  See the file COPYING in the top-level source
 * directory for licensing information.
 * ****************************************************************************
 *
 * Black box testing of the Solver class of the  C++ API.
 */

#include 
#include 

#include "options/option_exception.h"
#include "options/options_public.h"
#include "test_api.h"

namespace cvc5::internal {

namespace test {

template 
struct overloaded : Ts...
{
  using Ts::operator()...;
};
template 
overloaded(Ts...) -> overloaded;

class TestBlackOptions : public TestApi
{
 public:
  /**
   * Sets setting options for option "name".
   */
  void testSetOption(const std::string& name)
  {
    auto info = d_solver->getOptionInfo(name);

    try
    {
      std::visit(
          overloaded{
              [this, &name](const OptionInfo::VoidInfo& v) {
                d_solver->setOption(name, "");
              },
              [this, &name](const OptionInfo::ValueInfo& v) {
                d_solver->setOption(name, "false");
                d_solver->setOption(name, "true");
              },
              [this, &name](const OptionInfo::ValueInfo& v) {
                d_solver->setOption(name, "foo");
              },
              [this, &name](const OptionInfo::NumberInfo& v) {
                std::pair range{
                    std::numeric_limits::min(),
                    std::numeric_limits::max()};
                if (v.minimum)
                {
                  EXPECT_THROW(
                      d_solver->setOption(name, std::to_string(*v.minimum - 1)),
                      CVC5ApiOptionException);
                  EXPECT_NO_THROW(
                      d_solver->setOption(name, std::to_string(*v.minimum)));
                  range.first = *v.minimum;
                }
                if (v.maximum)
                {
                  EXPECT_THROW(
                      d_solver->setOption(name, std::to_string(*v.maximum + 1)),
                      CVC5ApiOptionException);
                  EXPECT_NO_THROW(
                      d_solver->setOption(name, std::to_string(*v.maximum)));
                  range.second = *v.maximum;
                }
                EXPECT_NO_THROW(d_solver->setOption(
                    name, std::to_string((range.first + range.second) / 2)));
                EXPECT_THROW(d_solver->setOption(name, "0123abc"),
                             CVC5ApiOptionException);
              },
              [this, &name](const OptionInfo::NumberInfo& v) {
                std::pair range{
                    std::numeric_limits::min(),
                    std::numeric_limits::max()};
                EXPECT_THROW(d_solver->setOption(name, "-1"),
                             CVC5ApiOptionException);
                if (v.minimum)
                {
                  EXPECT_THROW(
                      d_solver->setOption(name, std::to_string(*v.minimum - 1)),
                      CVC5ApiOptionException);
                  EXPECT_NO_THROW(
                      d_solver->setOption(name, std::to_string(*v.minimum)));
                  range.first = *v.minimum;
                }
                if (v.maximum)
                {
                  EXPECT_THROW(
                      d_solver->setOption(name, std::to_string(*v.maximum + 1)),
                      CVC5ApiOptionException);
                  EXPECT_NO_THROW(
                      d_solver->setOption(name, std::to_string(*v.maximum)));
                  range.second = *v.maximum;
                }
                EXPECT_NO_THROW(d_solver->setOption(
                    name, std::to_string((range.first + range.second) / 2)));
                EXPECT_THROW(d_solver->setOption(name, "0123abc"),
                             CVC5ApiOptionException);
              },
              [this, &name](const OptionInfo::NumberInfo& v) {
                std::pair range{
                    std::numeric_limits::min(),
                    std::numeric_limits::max()};
                if (v.minimum)
                {
                  EXPECT_THROW(
                      d_solver->setOption(name, std::to_string(*v.minimum - 1)),
                      CVC5ApiOptionException);
                  EXPECT_NO_THROW(
                      d_solver->setOption(name, std::to_string(*v.minimum)));
                  range.first = *v.minimum;
                }
                if (v.maximum)
                {
                  EXPECT_THROW(
                      d_solver->setOption(name, std::to_string(*v.maximum + 1)),
                      CVC5ApiOptionException);
                  EXPECT_NO_THROW(
                      d_solver->setOption(name, std::to_string(*v.maximum)));
                  range.second = *v.maximum;
                }
                EXPECT_NO_THROW(d_solver->setOption(
                    name, std::to_string((range.first + range.second) / 2)));
              },
              [this, &name](const OptionInfo::ModeInfo& v) {
                EXPECT_THROW(d_solver->setOption(name, "foobarbaz"),
                             CVC5ApiOptionException);
                for (const auto& m : v.modes)
                {
                  d_solver->setOption(name, m);
                  EXPECT_EQ(d_solver->getOption(name), m);
                }
                EXPECT_DEATH(d_solver->setOption(name, "help"), "");
              },
          },
          info.valueInfo);
    }
    catch (const CVC5ApiOptionException&)
    {
    }
  }
};

TEST_F(TestBlackOptions, set)
{
  const std::set muted{"copyright",
                                    "help",
                                    "show-config",
                                    "show-debug-tags",
                                    "show-trace-tags",
                                    "version"};
  for (const auto& name : options::getNames())
  {
    if (name == "safe-options")
    {
      // don't test safe-options here, since it will restrict the set of options
      // that can be set afterwards.
      continue;
    }
    if (muted.count(name))
    {
      testing::internal::CaptureStdout();
    }
    testSetOption(name);
    if (muted.count(name))
    {
      testing::internal::GetCapturedStdout();
    }
  }
}

TEST_F(TestBlackOptions, setSafe)
{
  const std::set muted{"copyright",
                                    "help",
                                    "show-config",
                                    "show-debug-tags",
                                    "show-trace-tags",
                                    "version"};
  // set safe options to true
  d_solver->setOption("safe-options", "true");
  bool alreadySetRegular = false;
  for (const auto& name : options::getNames())
  {
    auto info = d_solver->getOptionInfo(name);
    // skip if an expert option
    if (info.isExpert)
    {
      continue;
    }
    if (info.isRegular)
    {
      if (alreadySetRegular)
      {
        // skip if already set a regular option
        continue;
      }
      alreadySetRegular = true;
    }
    if (muted.count(name))
    {
      testing::internal::CaptureStdout();
    }
    testSetOption(name);
    if (muted.count(name))
    {
      testing::internal::GetCapturedStdout();
    }
  }
}

TEST_F(TestBlackOptions, getOptionInfoBenchmark)
{
  auto names = options::getNames();
  std::unordered_set ignore = {
    "output",
    "quiet",
    "rweight",
    "trace",
    "verbose",
  };
  auto end = std::remove_if(names.begin(), names.end(), [&](const auto& i){
      return ignore.count(i);
  });
  names.erase(end, names.end());
  size_t ct = 0;
  for (size_t i = 0; i < 1000; ++i)
  {
    for (const auto& name : names)
    {
      ct += d_solver->getOption(name).size();
    }
  }
  std::cout << ct << std::endl;
}

}  // namespace test
}  // namespace cvc5::internal




© 2015 - 2024 Weber Informatics LLC | Privacy Policy