1219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov//===-- sanitizer_flags_test.cc -------------------------------------------===//
2219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov//
3219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov//                     The LLVM Compiler Infrastructure
4219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov//
5219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov// This file is distributed under the University of Illinois Open Source
6219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov// License. See LICENSE.TXT for details.
7219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov//
8219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov//===----------------------------------------------------------------------===//
9219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov//
10219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
11219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov//
12219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov//===----------------------------------------------------------------------===//
13219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov#include "sanitizer_common/sanitizer_common.h"
14219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov#include "sanitizer_common/sanitizer_flags.h"
1586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#include "sanitizer_common/sanitizer_flag_parser.h"
1681088ebf34c3ef1b8ac3a9789d3896c7b9a93003Dmitry Vyukov#include "sanitizer_common/sanitizer_libc.h"
1786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#include "sanitizer_common/sanitizer_allocator_internal.h"
18219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov#include "gtest/gtest.h"
19219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov
20219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov#include <string.h>
21219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov
22219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonovnamespace __sanitizer {
23219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov
24219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonovstatic const char kFlagName[] = "flag_name";
2586277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstatic const char kFlagDesc[] = "flag description";
26219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov
27219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonovtemplate <typename T>
28219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonovstatic void TestFlag(T start_value, const char *env, T final_value) {
29219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov  T flag = start_value;
3086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
3186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  FlagParser parser;
3286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  RegisterFlag(&parser, kFlagName, kFlagDesc, &flag);
3386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
3486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  parser.ParseString(env);
3586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
36219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov  EXPECT_EQ(final_value, flag);
37219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov}
38219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov
3986277eb844c4983c81de62d7c050e92fe7155788Stephen Hinestemplate <>
4086277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesvoid TestFlag(const char *start_value, const char *env,
4186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines                     const char *final_value) {
42219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov  const char *flag = start_value;
4386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
4486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  FlagParser parser;
4586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  RegisterFlag(&parser, kFlagName, kFlagDesc, &flag);
4686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
4786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  parser.ParseString(env);
4886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
491f45e2dcd6732377577ac33f8729b21f981417b4Alexey Samsonov  EXPECT_EQ(0, internal_strcmp(final_value, flag));
50219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov}
51219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov
52219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey SamsonovTEST(SanitizerCommon, BooleanFlags) {
5386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestFlag(false, "flag_name=1", true);
54219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov  TestFlag(false, "flag_name=yes", true);
55219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov  TestFlag(false, "flag_name=true", true);
5686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestFlag(true, "flag_name=0", false);
57219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov  TestFlag(true, "flag_name=no", false);
58219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov  TestFlag(true, "flag_name=false", false);
59219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov}
60219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov
61219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey SamsonovTEST(SanitizerCommon, IntFlags) {
62219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov  TestFlag(-11, 0, -11);
6386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestFlag(-11, "flag_name=0", 0);
6486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestFlag(-11, "flag_name=42", 42);
6586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestFlag(-11, "flag_name=-42", -42);
6686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
6786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  // Unrecognized flags are ignored.
6886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestFlag(-11, "--flag_name=42", -11);
6986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestFlag(-11, "zzzzzzz=42", -11);
7086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
7186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  EXPECT_DEATH(TestFlag(-11, "flag_name", 0), "expected '='");
7286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  EXPECT_DEATH(TestFlag(-11, "flag_name=42U", 0),
7386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines               "Invalid value for int option");
74219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov}
75219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov
76219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey SamsonovTEST(SanitizerCommon, StrFlags) {
7786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestFlag("zzz", 0, "zzz");
7886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestFlag("zzz", "flag_name=", "");
7986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestFlag("zzz", "flag_name=abc", "abc");
8086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestFlag("", "flag_name=abc", "abc");
8186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestFlag("", "flag_name='abc zxc'", "abc zxc");
8286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  // TestStrFlag("", "flag_name=\"abc qwe\" asd", "abc qwe");
83219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov}
84219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov
851f45e2dcd6732377577ac33f8729b21f981417b4Alexey Samsonovstatic void TestTwoFlags(const char *env, bool expected_flag1,
8686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines                         const char *expected_flag2,
8786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines                         const char *name1 = "flag1",
8886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines                         const char *name2 = "flag2") {
891f45e2dcd6732377577ac33f8729b21f981417b4Alexey Samsonov  bool flag1 = !expected_flag1;
901f45e2dcd6732377577ac33f8729b21f981417b4Alexey Samsonov  const char *flag2 = "";
9186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
9286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  FlagParser parser;
9386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  RegisterFlag(&parser, name1, kFlagDesc, &flag1);
9486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  RegisterFlag(&parser, name2, kFlagDesc, &flag2);
9586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
9686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  parser.ParseString(env);
9786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
981f45e2dcd6732377577ac33f8729b21f981417b4Alexey Samsonov  EXPECT_EQ(expected_flag1, flag1);
991f45e2dcd6732377577ac33f8729b21f981417b4Alexey Samsonov  EXPECT_EQ(0, internal_strcmp(flag2, expected_flag2));
1001f45e2dcd6732377577ac33f8729b21f981417b4Alexey Samsonov}
1011f45e2dcd6732377577ac33f8729b21f981417b4Alexey Samsonov
1021f45e2dcd6732377577ac33f8729b21f981417b4Alexey SamsonovTEST(SanitizerCommon, MultipleFlags) {
1031f45e2dcd6732377577ac33f8729b21f981417b4Alexey Samsonov  TestTwoFlags("flag1=1 flag2='zzz'", true, "zzz");
1041f45e2dcd6732377577ac33f8729b21f981417b4Alexey Samsonov  TestTwoFlags("flag2='qxx' flag1=0", false, "qxx");
1051f45e2dcd6732377577ac33f8729b21f981417b4Alexey Samsonov  TestTwoFlags("flag1=false:flag2='zzz'", false, "zzz");
1061f45e2dcd6732377577ac33f8729b21f981417b4Alexey Samsonov  TestTwoFlags("flag2=qxx:flag1=yes", true, "qxx");
10786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestTwoFlags("flag2=qxx\nflag1=yes", true, "qxx");
10886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestTwoFlags("flag2=qxx\r\nflag1=yes", true, "qxx");
10986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestTwoFlags("flag2=qxx\tflag1=yes", true, "qxx");
11086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines}
11186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
11286277eb844c4983c81de62d7c050e92fe7155788Stephen HinesTEST(SanitizerCommon, CommonSuffixFlags) {
11386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestTwoFlags("flag=1 other_flag='zzz'", true, "zzz", "flag", "other_flag");
11486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestTwoFlags("other_flag='zzz' flag=1", true, "zzz", "flag", "other_flag");
11586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestTwoFlags("other_flag=' flag=0 ' flag=1", true, " flag=0 ", "flag",
11686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines               "other_flag");
11786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  TestTwoFlags("flag=1 other_flag=' flag=0 '", true, " flag=0 ", "flag",
11886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines               "other_flag");
11986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines}
12086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
12186277eb844c4983c81de62d7c050e92fe7155788Stephen HinesTEST(SanitizerCommon, CommonFlags) {
12286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CommonFlags cf;
12386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  FlagParser parser;
12486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  RegisterCommonFlags(&parser, &cf);
12586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
12686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  cf.SetDefaults();
12786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  EXPECT_TRUE(cf.symbolize);
12886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  EXPECT_STREQ(".", cf.coverage_dir);
12986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
13086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  cf.symbolize = false;
13186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  cf.coverage = true;
13286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  cf.coverage_direct = true;
13386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  cf.log_path = "path/one";
13486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
13586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  parser.ParseString("symbolize=1:coverage_direct=false log_path='path/two'");
13686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  EXPECT_TRUE(cf.symbolize);
13786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  EXPECT_TRUE(cf.coverage);
13886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  EXPECT_FALSE(cf.coverage_direct);
13986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  EXPECT_STREQ("path/two", cf.log_path);
1401f45e2dcd6732377577ac33f8729b21f981417b4Alexey Samsonov}
1411f45e2dcd6732377577ac33f8729b21f981417b4Alexey Samsonov
142219f20b5985371c4cfcef3e6f85fb94e8f3bc0e6Alexey Samsonov}  // namespace __sanitizer
143