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 15namespace quipper { 16 17namespace { 18 19const char kInvalidInput[] = 20 "PerfDataProto\n" 21 "Attr: Even Count BuildID\n" 22 "1.234 1234.5 time seconds\n"; 23 24const 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' 32const 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 50TEST(PerfStatParserTest, InvalidStringReturnsFalse) { 51 PerfStatProto proto; 52 ASSERT_FALSE(ParsePerfStatOutputToProto(kInvalidInput, &proto)); 53} 54 55TEST(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 92TEST(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 119TEST(PerfStatParserTest, NonexistentFileReturnsFalse) { 120 PerfStatProto proto; 121 ASSERT_FALSE(ParsePerfStatFileToProto("/dev/null/nope/nope.txt", &proto)); 122} 123 124TEST(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