Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/art/art/cmdline/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 22 kB image not shown  

Quelle  cmdline_parser_test.cc

  Sprache: C
 

/*
 * 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 "cmdline_parser.h"

#include <numeric>

#include "gtest/gtest.h"

#include "base/utils.h"
#include "jdwp_provider.h"
#include "experimental_flags.h"
#include "parsed_options.h"
#include "runtime.h"
#include "runtime_options.h"

#define EXPECT_NULL(expected) EXPECT_EQ(reinterpret_cast<const void*>(expected), \
                                        reinterpret_cast<void*>(nullptr));

namespace art {
  bool UsuallyEquals(double expected, double actual);

  // This has a gtest dependency, which is why it's in the gtest only.
  bool operator==(const ProfileSaverOptions& lhs, const ProfileSaverOptions& rhs) {
    return lhs.enabled_ == rhs.enabled_ &&
           lhs.min_save_period_ms_ == rhs.min_save_period_ms_ &&
           lhs.min_methods_to_save_ == rhs.min_methods_to_save_ &&
           lhs.min_classes_to_save_ == rhs.min_classes_to_save_ &&
           lhs.min_notification_before_wake_ == rhs.min_notification_before_wake_ &&
           lhs.max_notification_before_wake_ == rhs.max_notification_before_wake_;
  }

  bool UsuallyEquals(double expected, double actual) {
    using FloatingPoint = ::testing::internal::FloatingPoint<double>;

    FloatingPoint exp(expected);
    FloatingPoint act(actual);

    // Compare with ULPs instead of comparing with ==
    return exp.AlmostEquals(act);
  }

  template <typename T>
  bool UsuallyEquals(const T& expected, const T& actual,
                     typename std::enable_if<
                         detail::SupportsEqualityOperator<T>::value>::type* = nullptr) {
    return expected == actual;
  }

  template <char Separator>
  bool UsuallyEquals(const std::vector<std::string>& expected,
                     const ParseStringList<Separator>& actual) {
    return expected == static_cast<std::vector<std::string>>(actual);
  }

  // Try to use memcmp to compare simple plain-old-data structs.
  //
  // This should *not* generate false positives, but it can generate false negatives.
  // This will mostly work except for fields like float which can have different bit patterns
  // that are nevertheless equal.
  // If a test is failing because the structs aren't "equal" when they really are
  // then it's recommended to implement operator== for it instead.
  template <typename T, typename... Ignore>
  bool UsuallyEquals(
      const T& expected,
      const T& actual,
      [[maybe_unused]] const Ignore&... more,
      typename std::enable_if<std::is_pod<T>::value>::type* = nullptr,
      typename std::enable_if<!detail::SupportsEqualityOperator<T>::value>::type* = nullptr) {
    return memcmp(std::addressof(expected), std::addressof(actual), sizeof(T)) == 0;
  }

  bool UsuallyEquals(const XGcOption& expected, const XGcOption& actual) {
    return memcmp(std::addressof(expected), std::addressof(actual), sizeof(expected)) == 0;
  }

  bool UsuallyEquals(const char* expected, const std::string& actual) {
    return std::string(expected) == actual;
  }

  template <typename TMap, typename TKey, typename T>
  ::testing::AssertionResult IsExpectedKeyValue(const T& expected,
                                                const TMap& map,
                                                const TKey& key) {
    auto* actual = map.Get(key);
    if (actual != nullptr) {
      if (!UsuallyEquals(expected, *actual)) {
        return ::testing::AssertionFailure()
          << "expected " << detail::ToStringAny(expected) << " but got "
          << detail::ToStringAny(*actual);
      }
      return ::testing::AssertionSuccess();
    }

    return ::testing::AssertionFailure() << "key was not in the map";
  }

  template <typename TMap, typename TKey, typename T>
  ::testing::AssertionResult IsExpectedDefaultKeyValue(const T& expected,
                                                       const TMap& map,
                                                       const TKey& key) {
    const T& actual = map.GetOrDefault(key);
    if (!UsuallyEquals(expected, actual)) {
      return ::testing::AssertionFailure()
          << "expected " << detail::ToStringAny(expected) << " but got "
          << detail::ToStringAny(actual);
     }
    return ::testing::AssertionSuccess();
  }

class CmdlineParserTest : public ::testing::Test {
 public:
  CmdlineParserTest() = default;
  ~CmdlineParserTest() = default;

 protected:
  using M = RuntimeArgumentMap;
  using RuntimeParser = ParsedOptions::RuntimeParser;

  static void SetUpTestCase() {
    art::Locks::Init();
    art::InitLogging(nullptr, art::Runtime::Abort);  // argv = null
  }

  void SetUp() override {
    parser_ = ParsedOptions::MakeParser(false);  // do not ignore unrecognized options
  }

  static ::testing::AssertionResult IsResultSuccessful(const CmdlineResult& result) {
    if (result.IsSuccess()) {
      return ::testing::AssertionSuccess();
    } else {
      return ::testing::AssertionFailure()
        << result.GetStatus() << " with: " << result.GetMessage();
    }
  }

  static ::testing::AssertionResult IsResultFailure(const CmdlineResult& result,
                                                    CmdlineResult::Status failure_status) {
    if (result.IsSuccess()) {
      return ::testing::AssertionFailure() << " got success but expected failure: "
          << failure_status;
    } else if (result.GetStatus() == failure_status) {
      return ::testing::AssertionSuccess();
    }

    return ::testing::AssertionFailure() << "expected failure " << failure_status
        << " but got " << result.GetStatus();
  }

  std::unique_ptr<RuntimeParser> parser_;
};

#define EXPECT_KEY_EXISTS(map, key) EXPECT_TRUE((map).Exists(key))
#define EXPECT_KEY_VALUE(map, key, expected) EXPECT_TRUE(IsExpectedKeyValue(expected, map, key))
#define EXPECT_DEFAULT_KEY_VALUE(map, key, expected) EXPECT_TRUE(IsExpectedDefaultKeyValue(expected, map, key))

#define _EXPECT_SINGLE_PARSE_EMPTY_SUCCESS(argv)              \
  do {                                                        \
    EXPECT_TRUE(IsResultSuccessful(parser_->Parse(argv)));    \
    EXPECT_EQ(0u, parser_->GetArgumentsMap().Size());         \

#define EXPECT_SINGLE_PARSE_EMPTY_SUCCESS(argv)               \
  _EXPECT_SINGLE_PARSE_EMPTY_SUCCESS(argv);                   \
  } while (false)

#define EXPECT_SINGLE_PARSE_DEFAULT_VALUE(expected, argv, key)\
  _EXPECT_SINGLE_PARSE_EMPTY_SUCCESS(argv);                   \
    RuntimeArgumentMap args = parser_->ReleaseArgumentsMap(); \
    EXPECT_DEFAULT_KEY_VALUE(args, key, expected);            \
  } while (false)                                             // NOLINT [readability/namespace] [5]

#define _EXPECT_SINGLE_PARSE_EXISTS(argv, key)                \
  do {                                                        \
    EXPECT_TRUE(IsResultSuccessful(parser_->Parse(argv)));    \
    RuntimeArgumentMap args = parser_->ReleaseArgumentsMap(); \
    EXPECT_EQ(1u, args.Size());                               \
    EXPECT_KEY_EXISTS(args, key);                             \

#define EXPECT_SINGLE_PARSE_EXISTS(argv, key)                 \
    _EXPECT_SINGLE_PARSE_EXISTS(argv, key);                   \
  } while (false)

#define EXPECT_SINGLE_PARSE_VALUE(expected, argv, key)        \
    _EXPECT_SINGLE_PARSE_EXISTS(argv, key);                   \
    EXPECT_KEY_VALUE(args, key, expected);                    \
  } while (false)

#define EXPECT_SINGLE_PARSE_VALUE_STR(expected, argv, key)    \
  EXPECT_SINGLE_PARSE_VALUE(std::string(expected), argv, key)

#define EXPECT_SINGLE_PARSE_FAIL(argv, failure_status)         \
    do {                                                       \
      EXPECT_TRUE(IsResultFailure(parser_->Parse(argv), failure_status));\
      RuntimeArgumentMap args = parser_->ReleaseArgumentsMap();\
      EXPECT_EQ(0u, args.Size());                              \
    } while (false)

TEST_F(CmdlineParserTest, TestSimpleSuccesses) {
  auto& parser = *parser_;

  EXPECT_LT(0u, parser.CountDefinedArguments());

  {
    // Test case 1: No command line arguments
    EXPECT_TRUE(IsResultSuccessful(parser.Parse("")));
    RuntimeArgumentMap args = parser.ReleaseArgumentsMap();
    EXPECT_EQ(0u, args.Size());
  }

  EXPECT_SINGLE_PARSE_EXISTS("-Xzygote", M::Zygote);
  EXPECT_SINGLE_PARSE_VALUE(std::vector<std::string>({"/hello/world"}),
                            "-Xbootclasspath:/hello/world",
                            M::BootClassPath);
  EXPECT_SINGLE_PARSE_VALUE(std::vector<std::string>({"/hello""/world"}),
                            "-Xbootclasspath:/hello:/world",
                            M::BootClassPath);
  EXPECT_SINGLE_PARSE_VALUE_STR("/hello/world""-classpath /hello/world", M::ClassPath);
  EXPECT_SINGLE_PARSE_VALUE(Memory<1>(234), "-Xss234", M::StackSize);
  EXPECT_SINGLE_PARSE_VALUE(MemoryKiB(1234*MB), "-Xms1234m", M::MemoryInitialSize);
  EXPECT_SINGLE_PARSE_VALUE(true"-XX:EnableHSpaceCompactForOOM", M::EnableHSpaceCompactForOOM);
  EXPECT_SINGLE_PARSE_VALUE(false"-XX:DisableHSpaceCompactForOOM", M::EnableHSpaceCompactForOOM);
  EXPECT_SINGLE_PARSE_VALUE(0.5"-XX:HeapTargetUtilization=0.5", M::HeapTargetUtilization);
  EXPECT_SINGLE_PARSE_VALUE(5u, "-XX:ParallelGCThreads=5", M::ParallelGCThreads);
  EXPECT_SINGLE_PARSE_VALUE(10u,
                            "-XX:ParallelGCThreads=5 -XX:ParallelGCThreads=10",
                            M::ParallelGCThreads);
}  // TEST_F

TEST_F(CmdlineParserTest, TestSimpleFailures) {
  // Test argument is unknown to the parser
  EXPECT_SINGLE_PARSE_FAIL("abcdefg^%@#*(@#", CmdlineResult::kUnknown);
  // Test value map substitution fails
  EXPECT_SINGLE_PARSE_FAIL("-Xverify:whatever", CmdlineResult::kFailure);
  // Test value type parsing failures
  EXPECT_SINGLE_PARSE_FAIL("-Xsswhatever", CmdlineResult::kFailure);  // invalid memory value
  EXPECT_SINGLE_PARSE_FAIL("-Xms123", CmdlineResult::kFailure);       // memory value too small
  EXPECT_SINGLE_PARSE_FAIL("-XX:HeapTargetUtilization=0.0", CmdlineResult::kInvalid);  // toosmal
  EXPECT_SINGLE_PARSE_FAIL("-XX:HeapTargetUtilization=2.0", CmdlineResult::kInvalid);  // toolarg
  EXPECT_SINGLE_PARSE_FAIL("-XX:ParallelGCThreads=-5", CmdlineResult::kInvalid);  // too small
  EXPECT_SINGLE_PARSE_FAIL("-Xgc:blablabla", CmdlineResult::kInvalid);  // not a valid suboption
}  // TEST_F

TEST_F(CmdlineParserTest, TestLogVerbosity) {
  {
    const char* log_args = "-verbose:"
        "class,compiler,gc,heap,interpreter,jdwp,jni,monitor,profiler,signals,simulator,startup,"
        "third-party-jni,threads,verifier,verifier-debug";

    LogVerbosity log_verbosity = LogVerbosity();
    log_verbosity.class_linker = true;
    log_verbosity.compiler = true;
    log_verbosity.gc = true;
    log_verbosity.heap = true;
    log_verbosity.interpreter = true;
    log_verbosity.jdwp = true;
    log_verbosity.jni = true;
    log_verbosity.monitor = true;
    log_verbosity.profiler = true;
    log_verbosity.signals = true;
    log_verbosity.simulator = true;
    log_verbosity.startup = true;
    log_verbosity.third_party_jni = true;
    log_verbosity.threads = true;
    log_verbosity.verifier = true;
    log_verbosity.verifier_debug = true;

    EXPECT_SINGLE_PARSE_VALUE(log_verbosity, log_args, M::Verbose);
  }

  {
    const char* log_args = "-verbose:"
        "class,compiler,gc,heap,jdwp,jni,monitor";

    LogVerbosity log_verbosity = LogVerbosity();
    log_verbosity.class_linker = true;
    log_verbosity.compiler = true;
    log_verbosity.gc = true;
    log_verbosity.heap = true;
    log_verbosity.jdwp = true;
    log_verbosity.jni = true;
    log_verbosity.monitor = true;

    EXPECT_SINGLE_PARSE_VALUE(log_verbosity, log_args, M::Verbose);
  }

  EXPECT_SINGLE_PARSE_FAIL("-verbose:blablabla", CmdlineResult::kInvalid);  // invalid verbose opt

  {
    const char* log_args = "-verbose:deopt";
    LogVerbosity log_verbosity = LogVerbosity();
    log_verbosity.deopt = true;
    EXPECT_SINGLE_PARSE_VALUE(log_verbosity, log_args, M::Verbose);
  }

  {
    const char* log_args = "-verbose:collector";
    LogVerbosity log_verbosity = LogVerbosity();
    log_verbosity.collector = true;
    EXPECT_SINGLE_PARSE_VALUE(log_verbosity, log_args, M::Verbose);
  }

  {
    const char* log_args = "-verbose:oat";
    LogVerbosity log_verbosity = LogVerbosity();
    log_verbosity.oat = true;
    EXPECT_SINGLE_PARSE_VALUE(log_verbosity, log_args, M::Verbose);
  }

  {
    const char* log_args = "-verbose:dex";
    LogVerbosity log_verbosity = LogVerbosity();
    log_verbosity.dex = true;
    EXPECT_SINGLE_PARSE_VALUE(log_verbosity, log_args, M::Verbose);
  }

  {
    const char* log_args = "-verbose:hiddenapi";
    LogVerbosity log_verbosity = LogVerbosity();
    log_verbosity.hiddenapi = true;
    EXPECT_SINGLE_PARSE_VALUE(log_verbosity, log_args, M::Verbose);
  }
}  // TEST_F

TEST_F(CmdlineParserTest, TestXGcOption) {
  /*
   * Test success
   */

  {
    XGcOption option_all_true{};
    option_all_true.collector_type_ = gc::CollectorType::kCollectorTypeCMS;
    option_all_true.verify_pre_gc_heap_ = true;
    option_all_true.verify_pre_sweeping_heap_ = true;
    option_all_true.verify_post_gc_heap_ = true;
    option_all_true.verify_pre_gc_rosalloc_ = true;
    option_all_true.verify_pre_sweeping_rosalloc_ = true;
    option_all_true.verify_post_gc_rosalloc_ = true;

    const char * xgc_args_all_true = "-Xgc:concurrent,"
        "preverify,presweepingverify,postverify,"
        "preverify_rosalloc,presweepingverify_rosalloc,"
        "postverify_rosalloc,precise,"
        "verifycardtable";

    EXPECT_SINGLE_PARSE_VALUE(option_all_true, xgc_args_all_true, M::GcOption);

    XGcOption option_all_false{};
    option_all_false.collector_type_ = gc::CollectorType::kCollectorTypeMS;
    option_all_false.verify_pre_gc_heap_ = false;
    option_all_false.verify_pre_sweeping_heap_ = false;
    option_all_false.verify_post_gc_heap_ = false;
    option_all_false.verify_pre_gc_rosalloc_ = false;
    option_all_false.verify_pre_sweeping_rosalloc_ = false;
    option_all_false.verify_post_gc_rosalloc_ = false;

    const char* xgc_args_all_false = "-Xgc:nonconcurrent,"
        "nopreverify,nopresweepingverify,nopostverify,nopreverify_rosalloc,"
        "nopresweepingverify_rosalloc,nopostverify_rosalloc,noprecise,noverifycardtable";

    EXPECT_SINGLE_PARSE_VALUE(option_all_false, xgc_args_all_false, M::GcOption);

    XGcOption option_all_default{};

    const char* xgc_args_blank = "-Xgc:";
    EXPECT_SINGLE_PARSE_VALUE(option_all_default, xgc_args_blank, M::GcOption);
  }

  /*
   * Test failures
   */

  EXPECT_SINGLE_PARSE_FAIL("-Xgc:blablabla", CmdlineResult::kInvalid);  // invalid Xgc opt
}  // TEST_F

/*
 * { "-XjdwpProvider:_" }
 */

TEST_F(CmdlineParserTest, TestJdwpProviderEmpty) {
  {
    EXPECT_SINGLE_PARSE_DEFAULT_VALUE(JdwpProvider::kUnset, "", M::JdwpProvider);
  }
}  // TEST_F

TEST_F(CmdlineParserTest, TestJdwpProviderDefault) {
  const char* opt_args = "-XjdwpProvider:default";
  EXPECT_SINGLE_PARSE_VALUE(JdwpProvider::kDefaultJdwpProvider, opt_args, M::JdwpProvider);
}  // TEST_F

TEST_F(CmdlineParserTest, TestJdwpProviderNone) {
  const char* opt_args = "-XjdwpProvider:none";
  EXPECT_SINGLE_PARSE_VALUE(JdwpProvider::kNone, opt_args, M::JdwpProvider);
}  // TEST_F

TEST_F(CmdlineParserTest, TestJdwpProviderAdbconnection) {
  const char* opt_args = "-XjdwpProvider:adbconnection";
  EXPECT_SINGLE_PARSE_VALUE(JdwpProvider::kAdbConnection, opt_args, M::JdwpProvider);
}  // TEST_F

TEST_F(CmdlineParserTest, TestJdwpProviderHelp) {
  EXPECT_SINGLE_PARSE_FAIL("-XjdwpProvider:help", CmdlineResult::kHelp);
}  // TEST_F

TEST_F(CmdlineParserTest, TestJdwpProviderFail) {
  EXPECT_SINGLE_PARSE_FAIL("-XjdwpProvider:blablabla", CmdlineResult::kFailure);
}  // TEST_F

/*
 * -D_ -D_ -D_ ...
 */

TEST_F(CmdlineParserTest, TestPropertiesList) {
  /*
   * Test successes
   */

  {
    std::vector<std::string> opt = {"hello"};

    EXPECT_SINGLE_PARSE_VALUE(opt, "-Dhello", M::PropertiesList);
  }

  {
    std::vector<std::string> opt = {"hello""world"};

    EXPECT_SINGLE_PARSE_VALUE(opt, "-Dhello -Dworld", M::PropertiesList);
  }

  {
    std::vector<std::string> opt = {"one""two""three"};

    EXPECT_SINGLE_PARSE_VALUE(opt, "-Done -Dtwo -Dthree", M::PropertiesList);
  }
}  // TEST_F

/*
* -Xcompiler-option foo -Xcompiler-option bar ...
*/

TEST_F(CmdlineParserTest, TestCompilerOption) {
 /*
  * Test successes
  */

  {
    std::vector<std::string> opt = {"hello"};
    EXPECT_SINGLE_PARSE_VALUE(opt, "-Xcompiler-option hello", M::CompilerOptions);
  }

  {
    std::vector<std::string> opt = {"hello""world"};
    EXPECT_SINGLE_PARSE_VALUE(opt,
                              "-Xcompiler-option hello -Xcompiler-option world",
                              M::CompilerOptions);
  }

  {
    std::vector<std::string> opt = {"one""two""three"};
    EXPECT_SINGLE_PARSE_VALUE(opt,
                              "-Xcompiler-option one -Xcompiler-option two -Xcompiler-option three",
                              M::CompilerOptions);
  }
}  // TEST_F

/*
* -Xjit, -Xnojit, -Xjitcodecachesize, Xjitcompilethreshold
*/

TEST_F(CmdlineParserTest, TestJitOptions) {
 /*
  * Test successes
  */

  {
    EXPECT_SINGLE_PARSE_VALUE(true"-Xusejit:true", M::UseJitCompilation);
    EXPECT_SINGLE_PARSE_VALUE(false"-Xusejit:false", M::UseJitCompilation);
  }
  {
    EXPECT_SINGLE_PARSE_VALUE(
        MemoryKiB(16 * KB), "-Xjitinitialsize:16K", M::JITCodeCacheInitialCapacity);
    EXPECT_SINGLE_PARSE_VALUE(
        MemoryKiB(16 * MB), "-Xjitmaxsize:16M", M::JITCodeCacheMaxCapacity);
  }
  {
    EXPECT_SINGLE_PARSE_VALUE(12345u, "-Xjitthreshold:12345", M::JITOptimizeThreshold);
  }
}  // TEST_F

/*
* -Xps-*
*/

TEST_F(CmdlineParserTest, ProfileSaverOptions) {
  ProfileSaverOptions opt = ProfileSaverOptions(true1234567"abc"true);

  EXPECT_SINGLE_PARSE_VALUE(opt,
                            "-Xjitsaveprofilinginfo "
                            "-Xps-min-save-period-ms:1 "
                            "-Xps-min-first-save-ms:2 "
                            "-Xps-min-methods-to-save:3 "
                            "-Xps-min-classes-to-save:4 "
                            "-Xps-min-notification-before-wake:5 "
                            "-Xps-max-notification-before-wake:6 "
                            "-Xps-inline-cache-threshold:7 "
                            "-Xps-profile-path:abc "
                            "-Xps-profile-boot-class-path",
                            M::ProfileSaverOpts);
}  // TEST_F

/* -Xexperimental:_ */
TEST_F(CmdlineParserTest, TestExperimentalFlags) {
  // Default
  EXPECT_SINGLE_PARSE_DEFAULT_VALUE(ExperimentalFlags::kNone,
                                    "",
                                    M::Experimental);

  // Disabled explicitly
  EXPECT_SINGLE_PARSE_VALUE(ExperimentalFlags::kNone,
                            "-Xexperimental:none",
                            M::Experimental);
}

// -Xverify:_
TEST_F(CmdlineParserTest, TestVerify) {
  EXPECT_SINGLE_PARSE_VALUE(verifier::VerifyMode::kNone,     "-Xverify:none",     M::Verify);
  EXPECT_SINGLE_PARSE_VALUE(verifier::VerifyMode::kEnable,   "-Xverify:remote",   M::Verify);
  EXPECT_SINGLE_PARSE_VALUE(verifier::VerifyMode::kEnable,   "-Xverify:all",      M::Verify);
  EXPECT_SINGLE_PARSE_VALUE(verifier::VerifyMode::kSoftFail, "-Xverify:softfail", M::Verify);
}

TEST_F(CmdlineParserTest, TestIgnoreUnrecognized) {
  RuntimeParser::Builder parserBuilder;

  // clang-format off
  parserBuilder
      .Define("-help")
          .IntoKey(M::Help)
      .IgnoreUnrecognized(true);
  // clang-format on

  parser_.reset(new RuntimeParser(parserBuilder.Build()));

  EXPECT_SINGLE_PARSE_EMPTY_SUCCESS("-non-existent-option");
  EXPECT_SINGLE_PARSE_EMPTY_SUCCESS("-non-existent-option1 --non-existent-option-2");
}  //  TEST_F

TEST_F(CmdlineParserTest, TestIgnoredArguments) {
  std::initializer_list<const char*> ignored_args = {
      "-ea""-da""-enableassertions""-disableassertions""--runtime-arg""-esa",
      "-dsa""-enablesystemassertions""-disablesystemassertions""-Xrs""-Xint:abdef",
      "-Xdexopt:foobar""-Xnoquithandler""-Xjnigreflimit:ixnay""-Xgenregmap""-Xnogenregmap",
      "-Xverifyopt:never""-Xcheckdexsum""-Xincludeselectedop""-Xjitop:noop",
      "-Xincludeselectedmethod""-Xjitblocking""-Xjitmethod:_""-Xjitclass:nosuchluck",
      "-Xjitoffset:none""-Xjitconfig:yes""-Xjitcheckcg""-Xjitverbose""-Xjitprofile",
      "-Xjitdisableopt""-Xjitsuspendpoll""-XX:mainThreadStackSize=1337"
  };

  // Check they are ignored when parsed one at a time
  for (auto&& arg : ignored_args) {
    SCOPED_TRACE(arg);
    EXPECT_SINGLE_PARSE_EMPTY_SUCCESS(arg);
  }

  // Check they are ignored when we pass it all together at once
  std::vector<const char*> argv = ignored_args;
  EXPECT_SINGLE_PARSE_EMPTY_SUCCESS(argv);
}  //  TEST_F

TEST_F(CmdlineParserTest, MultipleArguments) {
  EXPECT_TRUE(IsResultSuccessful(parser_->Parse(
      "-help -XX:ForegroundHeapGrowthMultiplier=0.5 "
      "-Xmethod-trace -XX:LargeObjectSpace=map")));

  auto&& map = parser_->ReleaseArgumentsMap();
  EXPECT_EQ(4u, map.Size());
  EXPECT_KEY_VALUE(map, M::Help, Unit{});
  EXPECT_KEY_VALUE(map, M::ForegroundHeapGrowthMultiplier, 0.5);
  EXPECT_KEY_VALUE(map, M::MethodTrace, Unit{});
  EXPECT_KEY_VALUE(map, M::LargeObjectSpace, gc::space::LargeObjectSpaceType::kMap);
}  //  TEST_F

TEST_F(CmdlineParserTest, TypesNotInRuntime) {
  using ParseCommaSeparatedIntList = ParseIntList<','>;
  CmdlineType<ParseCommaSeparatedIntList> ct;
  auto success0 =
      CmdlineParseResult<ParseCommaSeparatedIntList>::Success(ParseCommaSeparatedIntList({1234}));
  EXPECT_EQ(success0, ct.Parse("1,2,3,4"));
  auto success1 =
      CmdlineParseResult<ParseCommaSeparatedIntList>::Success(ParseCommaSeparatedIntList({0}));
  EXPECT_EQ(success1, ct.Parse("1"));

  EXPECT_FALSE(ct.Parse("").IsSuccess());
  EXPECT_FALSE(ct.Parse(",").IsSuccess());
  EXPECT_FALSE(ct.Parse("1,").IsSuccess());
  EXPECT_FALSE(ct.Parse(",1").IsSuccess());
  EXPECT_FALSE(ct.Parse("1a2").IsSuccess());
  EXPECT_EQ(CmdlineResult::kInvalid, ct.Parse("1,10000000000000").GetStatus());
  EXPECT_EQ(CmdlineResult::kInvalid, ct.Parse("-10000000000000,123").GetStatus());
}  // TEST_F
}  // namespace art

Messung V0.5 in Prozent
C=89 H=93 G=90

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet am  2026-06-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.