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
TEST(PerfOptionParserTest,GoodRecord)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
TEST(PerfOptionParserTest,GoodStat)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.
TEST(PerfOptionParserTest,BadRecord_OutputOptions)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
TEST(PerfOptionParserTest,BadRecord_BannedOptions)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
TEST(PerfOptionParserTest,GoodMemRecord)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
TEST(PerfOptionParserTest,BadMemRecord_OutputOptions)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
TEST(PerfOptionParserTest,BadMemRecord_BannedOptions)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.
TEST(PerfOptionParserTest,BadStat_OutputOptions)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
TEST(PerfOptionParserTest,BadStat_BannedOptions)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
TEST(PerfOptionParserTest,DontAllowOtherPerfSubcommands)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.
TEST(PerfOptionParserTest,Ugly)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.
TEST(PerfOptionParserTest,ValueCommandAtEnd)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