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