1 // Copyright 2015 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "perf_option_parser.h" 6 7 #include "compat/string.h" 8 #include "compat/test.h" 9 10 namespace quipper { 11 12 TEST(PerfOptionParserTest, GoodRecord) { 13 EXPECT_TRUE(ValidatePerfCommandLine({"perf", "record"})); 14 EXPECT_TRUE(ValidatePerfCommandLine({"perf", "record", "-e", "cycles"})); 15 EXPECT_TRUE(ValidatePerfCommandLine( 16 {"perf", "record", "-e", "-$;(*^:,.Non-sense!"})); // let perf reject it. 17 EXPECT_TRUE(ValidatePerfCommandLine( 18 {"perf", "record", "-a", "-e", "iTLB-misses", "-c", "1000003"})); 19 EXPECT_TRUE(ValidatePerfCommandLine( 20 {"perf", "record", "-a", "-e", "cycles", "-g", "-c", "4000037"})); 21 EXPECT_TRUE(ValidatePerfCommandLine({"perf", "record", "-a", "-e", "cycles", 22 "-j", "any_call", "-c", "1000003"})); 23 } 24 25 TEST(PerfOptionParserTest, GoodStat) { 26 EXPECT_TRUE(ValidatePerfCommandLine( 27 {"perf", "stat", "-a", "-e", "cpu/mem-loads/", "-e", "cpu/mem-stores/"})); 28 } 29 30 // Options that control the output format should only be specified by quipper. 31 TEST(PerfOptionParserTest, BadRecord_OutputOptions) { 32 EXPECT_FALSE( 33 ValidatePerfCommandLine({"perf", "record", "-e", "cycles", "-v"})); 34 EXPECT_FALSE( 35 ValidatePerfCommandLine({"perf", "record", "--verbose", "-e", "cycles"})); 36 EXPECT_FALSE( 37 ValidatePerfCommandLine({"perf", "record", "-q", "-e", "cycles"})); 38 EXPECT_FALSE( 39 ValidatePerfCommandLine({"perf", "record", "-e", "cycles", "--quiet"})); 40 EXPECT_FALSE( 41 ValidatePerfCommandLine({"perf", "record", "-e", "cycles", "-m", "512"})); 42 EXPECT_FALSE(ValidatePerfCommandLine( 43 {"perf", "record", "-e", "cycles", "--mmap-pages", "512"})); 44 } 45 46 TEST(PerfOptionParserTest, BadRecord_BannedOptions) { 47 EXPECT_FALSE( 48 ValidatePerfCommandLine({"perf", "record", "-e", "cycles", "-D"})); 49 EXPECT_FALSE( 50 ValidatePerfCommandLine({"perf", "record", "-e", "cycles", "-D", "10"})); 51 } 52 53 TEST(PerfOptionParserTest, GoodMemRecord) { 54 EXPECT_TRUE(ValidatePerfCommandLine({"perf", "mem", "record"})); 55 EXPECT_TRUE( 56 ValidatePerfCommandLine({"perf", "mem", "record", "-e", "cycles"})); 57 // let perf reject it. 58 EXPECT_TRUE(ValidatePerfCommandLine( 59 {"perf", "mem", "record", "-e", "-$;(*^:,.Non-sense!"})); 60 EXPECT_TRUE(ValidatePerfCommandLine( 61 {"perf", "mem", "record", "-a", "-e", "iTLB-misses", "-c", "1000003"})); 62 EXPECT_TRUE(ValidatePerfCommandLine( 63 {"perf", "mem", "record", "-a", "-e", "cycles", "-g", "-c", "4000037"})); 64 EXPECT_TRUE( 65 ValidatePerfCommandLine({"perf", "mem", "record", "-a", "-e", "cycles", 66 "-j", "any_call", "-c", "1000003"})); 67 68 // Check perf-mem options that come before "record". 69 // See http://man7.org/linux/man-pages/man1/perf-mem.1.html 70 EXPECT_TRUE(ValidatePerfCommandLine( 71 {"perf", "mem", "-t", "load", "record", "-e", "-$;(*^:,.Non-sense!"})); 72 EXPECT_TRUE( 73 ValidatePerfCommandLine({"perf", "mem", "--type", "load,store", "record", 74 "-a", "-e", "iTLB-misses", "-c", "1000003"})); 75 EXPECT_TRUE( 76 ValidatePerfCommandLine({"perf", "mem", "-D", "-x", ":", "record", "-a", 77 "-e", "cycles", "-g", "-c", "4000037"})); 78 EXPECT_TRUE( 79 ValidatePerfCommandLine({"perf", "mem", "-C", "0,1", "record", "-a", "-e", 80 "cycles", "-j", "any_call", "-c", "1000003"})); 81 } 82 83 TEST(PerfOptionParserTest, BadMemRecord_OutputOptions) { 84 EXPECT_FALSE(ValidatePerfCommandLine( 85 {"perf", "mem", "-t", "load,store", "record", "-e", "cycles", "-v"})); 86 EXPECT_FALSE(ValidatePerfCommandLine( 87 {"perf", "mem", "-t", "load", "record", "--verbose", "-e", "cycles"})); 88 EXPECT_FALSE(ValidatePerfCommandLine( 89 {"perf", "mem", "-D", "-x", ":", "record", "-q", "-e", "cycles"})); 90 EXPECT_FALSE(ValidatePerfCommandLine( 91 {"perf", "mem", "-C", "0,1", "record", "-e", "cycles", "--quiet"})); 92 EXPECT_FALSE(ValidatePerfCommandLine( 93 {"perf", "mem", "record", "-e", "cycles", "-m", "512"})); 94 EXPECT_FALSE(ValidatePerfCommandLine( 95 {"perf", "mem", "record", "-e", "cycles", "--mmap-pages", "512"})); 96 97 // Try some bad perf-mem options. 98 EXPECT_FALSE(ValidatePerfCommandLine( 99 {"perf", "mem", "-y", "-z", "record", "-e", "-$;(*^:,.Non-sense!"})); 100 EXPECT_FALSE(ValidatePerfCommandLine({"perf", "mem", "--blah", "record", "-a", 101 "-e", "iTLB-misses", "-c", "1000003"})); 102 EXPECT_FALSE( 103 ValidatePerfCommandLine({"perf", "mem", "--no-way", "record", "-a", "-e", 104 "cycles", "-g", "-c", "4000037"})); 105 EXPECT_FALSE( 106 ValidatePerfCommandLine({"perf", "mem", "--danger", "record", "-a", "-e", 107 "cycles", "-j", "any_call", "-c", "1000003"})); 108 } 109 110 TEST(PerfOptionParserTest, BadMemRecord_BannedOptions) { 111 EXPECT_FALSE( 112 ValidatePerfCommandLine({"perf", "mem", "record", "-e", "cycles", "-D"})); 113 EXPECT_FALSE(ValidatePerfCommandLine( 114 {"perf", "mem", "record", "-e", "cycles", "-D", "10"})); 115 } 116 117 // Options that control the output format should only be specified by quipper. 118 TEST(PerfOptionParserTest, BadStat_OutputOptions) { 119 EXPECT_FALSE(ValidatePerfCommandLine({"perf", "stat", "-e", "cycles", "-v"})); 120 EXPECT_FALSE( 121 ValidatePerfCommandLine({"perf", "stat", "--verbose", "-e", "cycles"})); 122 EXPECT_FALSE(ValidatePerfCommandLine({"perf", "stat", "-q", "-e", "cycles"})); 123 EXPECT_FALSE( 124 ValidatePerfCommandLine({"perf", "stat", "-e", "cycles", "--quiet"})); 125 EXPECT_FALSE( 126 ValidatePerfCommandLine({"perf", "stat", "-e", "cycles", "-x", "::"})); 127 EXPECT_FALSE(ValidatePerfCommandLine( 128 {"perf", "stat", "-e", "cycles", "--field-separator", ","})); 129 } 130 131 TEST(PerfOptionParserTest, BadStat_BannedOptions) { 132 EXPECT_FALSE(ValidatePerfCommandLine({"perf", "stat", "--pre", "rm -rf /"})); 133 EXPECT_FALSE(ValidatePerfCommandLine({"perf", "stat", "--post", "rm -rf /"})); 134 EXPECT_FALSE(ValidatePerfCommandLine({"perf", "stat", "-d"})); 135 EXPECT_FALSE(ValidatePerfCommandLine({"perf", "stat", "--log-fd", "4"})); 136 } 137 138 TEST(PerfOptionParserTest, DontAllowOtherPerfSubcommands) { 139 EXPECT_FALSE(ValidatePerfCommandLine({"perf", "list"})); 140 EXPECT_FALSE(ValidatePerfCommandLine({"perf", "report"})); 141 EXPECT_FALSE(ValidatePerfCommandLine({"perf", "trace"})); 142 } 143 144 // Unsafe command lines for either perf command. 145 TEST(PerfOptionParserTest, Ugly) { 146 for (const string &subcmd : {"record", "stat", "mem"}) { 147 EXPECT_FALSE(ValidatePerfCommandLine({"perf", subcmd, "rm", "-rf", "/"})); 148 EXPECT_FALSE( 149 ValidatePerfCommandLine({"perf", subcmd, "--", "rm", "-rf", "/"})); 150 EXPECT_FALSE(ValidatePerfCommandLine( 151 {"perf", subcmd, "-e", "cycles", "rm", "-rf", "/"})); 152 EXPECT_FALSE(ValidatePerfCommandLine( 153 {"perf", subcmd, "-e", "cycles", "-o", "/root/haha.perf.data"})); 154 } 155 } 156 157 // Regression test for correct past-the-end iteration. 158 TEST(PerfOptionParserTest, ValueCommandAtEnd) { 159 EXPECT_FALSE( 160 ValidatePerfCommandLine({"perf", "record", "-c" /*missing value!*/})); 161 EXPECT_FALSE( 162 ValidatePerfCommandLine({"perf", "stat", "-e" /*missing value!*/})); 163 EXPECT_FALSE(ValidatePerfCommandLine({"perf", "mem", 164 "record" 165 "-j" /*missing value!*/})); 166 EXPECT_FALSE(ValidatePerfCommandLine( 167 {"perf", "mem", "-t", "load", "record", "-e" /*missing value!*/})); 168 } 169 170 } // namespace quipper 171