• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <string>
6 
7 #include "base/logging.h"
8 
9 #include "compat/string.h"
10 #include "compat/test.h"
11 #include "file_utils.h"
12 #include "perf_stat_parser.h"
13 #include "scoped_temp_path.h"
14 
15 namespace quipper {
16 
17 namespace {
18 
19 const char kInvalidInput[] =
20     "PerfDataProto\n"
21     "Attr: Even Count BuildID\n"
22     "1.234 1234.5 time seconds\n";
23 
24 const char kSmallInput[] =
25     "/uncore/reads/: 711983 1002113142 1002111143\n"
26     "/uncore/writes/: 140867 1002113864 1002113864\n"
27     "    \n";  // Test parsing an empty line
28 
29 // From a Peppy running:
30 // 'perf stat -v -a -e cycles -e L1-dcache-loads -e bus-cycles -e r02c4 --'
31 // ' sleep 2'
32 const char kFullInput[] =
33     "cycles: 19062079 4002390292 4002381587\n"
34     "L1-dcache-loads: 2081375 4002517554 4002511235\n"
35     "bus-cycles: 2259169 4002527446 4002523976\n"
36     "r02c4: 201584 4002518485 4002518485\n"
37     "\n"
38     " Performance counter stats for 'system wide':\n"
39     "\n"
40     "          19062079      cycles                    [100.00%]\n"
41     "           2081375      L1-dcache-loads           [100.00%]\n"
42     "           2259169      bus-cycles                [100.00%]\n"
43     "            201584      r02c4   \n"
44     "\n"
45     "       2.001402976 seconds time elapsed\n"
46     "\n";
47 
48 }  // namespace
49 
TEST(PerfStatParserTest,InvalidStringReturnsFalse)50 TEST(PerfStatParserTest, InvalidStringReturnsFalse) {
51   PerfStatProto proto;
52   ASSERT_FALSE(ParsePerfStatOutputToProto(kInvalidInput, &proto));
53 }
54 
TEST(PerfStatParserTest,ValidInputParsesCorrectly)55 TEST(PerfStatParserTest, ValidInputParsesCorrectly) {
56   // Test string input
57   PerfStatProto proto;
58   ASSERT_TRUE(ParsePerfStatOutputToProto(kSmallInput, &proto));
59 
60   ASSERT_EQ(proto.line_size(), 2);
61 
62   const auto& line1 = proto.line(0);
63   EXPECT_EQ("/uncore/reads/", line1.event_name());
64   EXPECT_EQ(711983, line1.count());
65   EXPECT_FALSE(line1.has_time_ms());
66 
67   const auto& line2 = proto.line(1);
68   EXPECT_EQ("/uncore/writes/", line2.event_name());
69   EXPECT_EQ(140867, line2.count());
70   EXPECT_FALSE(line2.has_time_ms());
71 
72   // Test file input
73   ScopedTempFile input;
74   ASSERT_FALSE(input.path().empty());
75   ASSERT_TRUE(BufferToFile(input.path(), string(kSmallInput)));
76   PerfStatProto proto2;
77   ASSERT_TRUE(ParsePerfStatFileToProto(input.path(), &proto2));
78 
79   ASSERT_EQ(proto2.line_size(), 2);
80 
81   const auto& line3 = proto2.line(0);
82   EXPECT_EQ("/uncore/reads/", line3.event_name());
83   EXPECT_EQ(711983, line3.count());
84   EXPECT_FALSE(line3.has_time_ms());
85 
86   const auto& line4 = proto2.line(1);
87   EXPECT_EQ("/uncore/writes/", line4.event_name());
88   EXPECT_EQ(140867, line4.count());
89   EXPECT_FALSE(line4.has_time_ms());
90 }
91 
TEST(PerfStatParserTest,ValidFullStringParsesCorrectly)92 TEST(PerfStatParserTest, ValidFullStringParsesCorrectly) {
93   PerfStatProto proto;
94   ASSERT_TRUE(ParsePerfStatOutputToProto(kFullInput, &proto));
95 
96   ASSERT_EQ(proto.line_size(), 4);
97 
98   const auto& line1 = proto.line(0);
99   EXPECT_EQ("cycles", line1.event_name());
100   EXPECT_EQ(19062079, line1.count());
101   EXPECT_EQ(2001, line1.time_ms());
102 
103   const auto& line2 = proto.line(1);
104   EXPECT_EQ("L1-dcache-loads", line2.event_name());
105   EXPECT_EQ(2081375, line2.count());
106   EXPECT_EQ(2001, line2.time_ms());
107 
108   const auto& line3 = proto.line(2);
109   EXPECT_EQ("bus-cycles", line3.event_name());
110   EXPECT_EQ(2259169, line3.count());
111   EXPECT_EQ(2001, line3.time_ms());
112 
113   const auto& line4 = proto.line(3);
114   EXPECT_EQ("r02c4", line4.event_name());
115   EXPECT_EQ(201584, line4.count());
116   EXPECT_EQ(2001, line4.time_ms());
117 }
118 
TEST(PerfStatParserTest,NonexistentFileReturnsFalse)119 TEST(PerfStatParserTest, NonexistentFileReturnsFalse) {
120   PerfStatProto proto;
121   ASSERT_FALSE(ParsePerfStatFileToProto("/dev/null/nope/nope.txt", &proto));
122 }
123 
TEST(PerfStatParserTest,ParseTime)124 TEST(PerfStatParserTest, ParseTime) {
125   uint64_t out;
126   EXPECT_TRUE(SecondsStringToMillisecondsUint64("123.456", &out));
127   EXPECT_EQ(123456, out);
128   EXPECT_TRUE(SecondsStringToMillisecondsUint64("2.0014", &out));
129   EXPECT_EQ(2001, out);
130   EXPECT_TRUE(SecondsStringToMillisecondsUint64("0.0027", &out));
131   EXPECT_EQ(3, out);
132   EXPECT_FALSE(SecondsStringToMillisecondsUint64("-10.0027", &out));
133   EXPECT_FALSE(SecondsStringToMillisecondsUint64("string", &out));
134   EXPECT_FALSE(SecondsStringToMillisecondsUint64("string.string", &out));
135   EXPECT_FALSE(SecondsStringToMillisecondsUint64("23.string", &out));
136   EXPECT_FALSE(SecondsStringToMillisecondsUint64("string.23456", &out));
137   EXPECT_FALSE(SecondsStringToMillisecondsUint64("123.234.456", &out));
138 }
139 
140 }  // namespace quipper
141