| // Copyright 2015 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <string> |
| |
| #include "base/logging.h" |
| |
| #include "chromiumos-wide-profiling/compat/string.h" |
| #include "chromiumos-wide-profiling/compat/test.h" |
| #include "chromiumos-wide-profiling/perf_stat_parser.h" |
| #include "chromiumos-wide-profiling/scoped_temp_path.h" |
| #include "chromiumos-wide-profiling/utils.h" |
| |
| namespace quipper { |
| |
| namespace { |
| |
| const char kInvalidInput[] = |
| "PerfDataProto\n" |
| "Attr: Even Count BuildID\n" |
| "1.234 1234.5 time seconds\n"; |
| |
| const char kSmallInput[] = |
| "/uncore/reads/: 711983 1002113142 1002111143\n" |
| "/uncore/writes/: 140867 1002113864 1002113864\n" |
| " \n"; // Test parsing an empty line |
| |
| // From a Peppy running: |
| // 'perf stat -v -a -e cycles -e L1-dcache-loads -e bus-cycles -e r02c4 --' |
| // ' sleep 2' |
| const char kFullInput[] = |
| "cycles: 19062079 4002390292 4002381587\n" |
| "L1-dcache-loads: 2081375 4002517554 4002511235\n" |
| "bus-cycles: 2259169 4002527446 4002523976\n" |
| "r02c4: 201584 4002518485 4002518485\n" |
| "\n" |
| " Performance counter stats for 'system wide':\n" |
| "\n" |
| " 19062079 cycles [100.00%]\n" |
| " 2081375 L1-dcache-loads [100.00%]\n" |
| " 2259169 bus-cycles [100.00%]\n" |
| " 201584 r02c4 \n" |
| "\n" |
| " 2.001402976 seconds time elapsed\n" |
| "\n"; |
| |
| } // namespace |
| |
| TEST(PerfStatParserTest, InvalidStringReturnsFalse) { |
| PerfStatProto proto; |
| ASSERT_FALSE(ParsePerfStatOutputToProto(kInvalidInput, &proto)); |
| } |
| |
| TEST(PerfStatParserTest, ValidInputParsesCorrectly) { |
| // Test string input |
| PerfStatProto proto; |
| ASSERT_TRUE(ParsePerfStatOutputToProto(kSmallInput, &proto)); |
| |
| ASSERT_EQ(proto.line_size(), 2); |
| |
| const auto& line1 = proto.line(0); |
| EXPECT_EQ("/uncore/reads/", line1.event_name()); |
| EXPECT_EQ(711983, line1.count()); |
| EXPECT_FALSE(line1.has_time_ms()); |
| |
| const auto& line2 = proto.line(1); |
| EXPECT_EQ("/uncore/writes/", line2.event_name()); |
| EXPECT_EQ(140867, line2.count()); |
| EXPECT_FALSE(line2.has_time_ms()); |
| |
| // Test file input |
| ScopedTempFile input; |
| ASSERT_FALSE(input.path().empty()); |
| ASSERT_TRUE(BufferToFile(input.path(), string(kSmallInput))); |
| PerfStatProto proto2; |
| ASSERT_TRUE(ParsePerfStatFileToProto(input.path(), &proto2)); |
| |
| ASSERT_EQ(proto2.line_size(), 2); |
| |
| const auto& line3 = proto2.line(0); |
| EXPECT_EQ("/uncore/reads/", line3.event_name()); |
| EXPECT_EQ(711983, line3.count()); |
| EXPECT_FALSE(line3.has_time_ms()); |
| |
| const auto& line4 = proto2.line(1); |
| EXPECT_EQ("/uncore/writes/", line4.event_name()); |
| EXPECT_EQ(140867, line4.count()); |
| EXPECT_FALSE(line4.has_time_ms()); |
| } |
| |
| TEST(PerfStatParserTest, ValidFullStringParsesCorrectly) { |
| PerfStatProto proto; |
| ASSERT_TRUE(ParsePerfStatOutputToProto(kFullInput, &proto)); |
| |
| ASSERT_EQ(proto.line_size(), 4); |
| |
| const auto& line1 = proto.line(0); |
| EXPECT_EQ("cycles", line1.event_name()); |
| EXPECT_EQ(19062079, line1.count()); |
| EXPECT_EQ(2001, line1.time_ms()); |
| |
| const auto& line2 = proto.line(1); |
| EXPECT_EQ("L1-dcache-loads", line2.event_name()); |
| EXPECT_EQ(2081375, line2.count()); |
| EXPECT_EQ(2001, line2.time_ms()); |
| |
| const auto& line3 = proto.line(2); |
| EXPECT_EQ("bus-cycles", line3.event_name()); |
| EXPECT_EQ(2259169, line3.count()); |
| EXPECT_EQ(2001, line3.time_ms()); |
| |
| const auto& line4 = proto.line(3); |
| EXPECT_EQ("r02c4", line4.event_name()); |
| EXPECT_EQ(201584, line4.count()); |
| EXPECT_EQ(2001, line4.time_ms()); |
| } |
| |
| TEST(PerfStatParserTest, NonexistentFileReturnsFalse) { |
| PerfStatProto proto; |
| ASSERT_FALSE(ParsePerfStatFileToProto("/dev/null/nope/nope.txt", &proto)); |
| } |
| |
| TEST(PerfStatParserTest, ParseTime) { |
| uint64_t out; |
| EXPECT_TRUE(SecondsStringToMillisecondsUint64("123.456", &out)); |
| EXPECT_EQ(123456, out); |
| EXPECT_TRUE(SecondsStringToMillisecondsUint64("2.0014", &out)); |
| EXPECT_EQ(2001, out); |
| EXPECT_TRUE(SecondsStringToMillisecondsUint64("0.0027", &out)); |
| EXPECT_EQ(3, out); |
| EXPECT_FALSE(SecondsStringToMillisecondsUint64("-10.0027", &out)); |
| EXPECT_FALSE(SecondsStringToMillisecondsUint64("string", &out)); |
| EXPECT_FALSE(SecondsStringToMillisecondsUint64("string.string", &out)); |
| EXPECT_FALSE(SecondsStringToMillisecondsUint64("23.string", &out)); |
| EXPECT_FALSE(SecondsStringToMillisecondsUint64("string.23456", &out)); |
| EXPECT_FALSE(SecondsStringToMillisecondsUint64("123.234.456", &out)); |
| } |
| |
| } // namespace quipper |