Home | History | Annotate | Download | only in quipper
      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 
     50 TEST(PerfStatParserTest, InvalidStringReturnsFalse) {
     51   PerfStatProto proto;
     52   ASSERT_FALSE(ParsePerfStatOutputToProto(kInvalidInput, &proto));
     53 }
     54 
     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 
     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 
    119 TEST(PerfStatParserTest, NonexistentFileReturnsFalse) {
    120   PerfStatProto proto;
    121   ASSERT_FALSE(ParsePerfStatFileToProto("/dev/null/nope/nope.txt", &proto));
    122 }
    123 
    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