17e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh/*
27e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh * Copyright (C) 2015 The Android Open Source Project
37e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh *
47e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh * Licensed under the Apache License, Version 2.0 (the "License");
57e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh * you may not use this file except in compliance with the License.
67e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh * You may obtain a copy of the License at
77e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh *
87e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh *      http://www.apache.org/licenses/LICENSE-2.0
97e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh *
107e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh * Unless required by applicable law or agreed to in writing, software
117e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh * distributed under the License is distributed on an "AS IS" BASIS,
127e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh * See the License for the specific language governing permissions and
147e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh * limitations under the License.
157e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh */
167e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
177e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <gtest/gtest.h>
187e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <algorithm>
197e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <cctype>
207e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <string>
217e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <regex>
227e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <stdio.h>
237e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <sys/types.h>
247e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <sys/stat.h>
257e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include <fcntl.h>
267e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
2766dd09e8e2407082ce93bf0784de641298131912Elliott Hughes#include <android-base/stringprintf.h>
28f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen
297e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include "perfprofdcore.h"
308c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh#include "configreader.h"
317e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include "perfprofdutils.h"
327e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include "perfprofdmockutils.h"
337e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
347e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include "perf_profile.pb.h"
357e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#include "google/protobuf/text_format.h"
367e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
377e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh//
387e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Set to argv[0] on startup
397e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh//
407e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic const char *executable_path;
417e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
427e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh//
437e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// test_dir is the directory containing the test executable and
447e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// any files associated with the test (will be created by the harness).
457e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh//
467e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// dest_dir is a subdirectory of test_dir that we'll create on the fly
477e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// at the start of each testpoint (into which new files can be written),
487e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// then delete at end of testpoint.
497e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh//
507e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic std::string test_dir;
517e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic std::string dest_dir;
527e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
537e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Path to perf executable on device
547e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#define PERFPATH "/system/bin/perf"
557e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
567e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Temporary config file that we will emit for the daemon to read
577e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#define CONFIGFILE "perfprofd.conf"
587e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
59f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chenstatic std::string encoded_file_path(int seq)
607e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{
61f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  return android::base::StringPrintf("%s/perf.data.encoded.%d",
62f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen                                     dest_dir.c_str(), seq);
637e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh}
647e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
657e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshclass PerfProfdTest : public testing::Test {
667e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh protected:
677e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  virtual void SetUp() {
687e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    mock_perfprofdutils_init();
697e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    create_dest_dir();
7007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh    yesclean();
717e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
727e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
737e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  virtual void TearDown() {
747e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    mock_perfprofdutils_finish();
757e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
767e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
7707f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh  void noclean() {
7807f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh    clean_ = false;
7907f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh  }
8007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh  void yesclean() {
8107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh    clean_ = true;
8207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh  }
8307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh
847e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh private:
8507f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh  bool clean_;
867e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
877e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  void create_dest_dir() {
887e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    setup_dirs();
897e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    ASSERT_FALSE(dest_dir == "");
9007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh    if (clean_) {
9107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh      std::string cmd("rm -rf ");
9207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh      cmd += dest_dir;
9307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh      system(cmd.c_str());
9407f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh    }
957e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    std::string cmd("mkdir -p ");
967e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    cmd += dest_dir;
977e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    system(cmd.c_str());
987e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
997e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
1007e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  void setup_dirs()
1017e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  {
1027e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    if (test_dir == "") {
1037e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      ASSERT_TRUE(executable_path != nullptr);
1047e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      std::string s(executable_path);
1057e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      auto found = s.find_last_of("/");
1067e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      test_dir = s.substr(0,found);
1077e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      dest_dir = test_dir;
1087e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      dest_dir += "/tmp";
1097e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    }
1107e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
1117e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
1127e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh};
1137e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
1147e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic bool bothWhiteSpace(char lhs, char rhs)
1157e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{
1167e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  return (std::isspace(lhs) && std::isspace(rhs));
1177e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh}
1187e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
1197e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh//
1207e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Squeeze out repeated whitespace from expected/actual logs.
1217e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh//
1227e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic std::string squeezeWhite(const std::string &str,
1237e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                                const char *tag,
1247e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                                bool dump=false)
1257e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{
1267e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  if (dump) { fprintf(stderr, "raw %s is %s\n", tag, str.c_str()); }
1277e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  std::string result(str);
1287e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  std::replace( result.begin(), result.end(), '\n', ' ');
1297e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  auto new_end = std::unique(result.begin(), result.end(), bothWhiteSpace);
1307e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  result.erase(new_end, result.end());
1317e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  while (result.begin() != result.end() && std::isspace(*result.rbegin())) {
1327e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    result.pop_back();
1337e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
1347e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  if (dump) { fprintf(stderr, "squeezed %s is %s\n", tag, result.c_str()); }
1357e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  return result;
1367e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh}
1377e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
1387e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh///
1397e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh/// Helper class to kick off a run of the perfprofd daemon with a specific
1407e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh/// config file.
1417e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh///
1427e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshclass PerfProfdRunner {
1437e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh public:
1447e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  PerfProfdRunner()
1457e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      : config_path_(test_dir)
1467e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  {
1477e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    config_path_ += "/" CONFIGFILE;
1487e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
1497e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
1507e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  ~PerfProfdRunner()
1517e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  {
152f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen    remove_processed_file();
1537e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
1547e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
1557e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  void addToConfig(const std::string &line)
1567e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  {
1577e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    config_text_ += line;
1587e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    config_text_ += "\n";
1597e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
1607e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
1617e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  void remove_semaphore_file()
1627e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  {
16358bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen    std::string semaphore(test_dir);
1647e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    semaphore += "/" SEMAPHORE_FILENAME;
1657e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    unlink(semaphore.c_str());
1667e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
1677e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
1687e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  void create_semaphore_file()
1697e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  {
17058bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen    std::string semaphore(test_dir);
1717e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    semaphore += "/" SEMAPHORE_FILENAME;
1727e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    close(open(semaphore.c_str(), O_WRONLY|O_CREAT));
1737e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
1747e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
175f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  void write_processed_file(int start_seq, int end_seq)
176f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  {
177f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen    std::string processed = test_dir + "/" PROCESSED_FILENAME;
178f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen    FILE *fp = fopen(processed.c_str(), "w");
179f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen    for (int i = start_seq; i < end_seq; i++) {
180f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      fprintf(fp, "%d\n", i);
181f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen    }
182f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen    fclose(fp);
183f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  }
184f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen
185f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  void remove_processed_file()
186f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  {
187f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen    std::string processed = test_dir + "/" PROCESSED_FILENAME;
188f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen    unlink(processed.c_str());
189f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  }
190f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen
1917e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  int invoke()
1927e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  {
1937e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    static const char *argv[3] = { "perfprofd", "-c", "" };
1947e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    argv[2] = config_path_.c_str();
1957e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
1967e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    writeConfigFile(config_path_, config_text_);
19707f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh
1987e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    // execute daemon main
1997e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    return perfprofd_main(3, (char **) argv);
2007e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
2017e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
2027e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh private:
2037e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  std::string config_path_;
2047e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  std::string config_text_;
2057e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
2067e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  void writeConfigFile(const std::string &config_path,
2077e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                       const std::string &config_text)
2087e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  {
2097e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    FILE *fp = fopen(config_path.c_str(), "w");
2107e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    ASSERT_TRUE(fp != nullptr);
2117e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    fprintf(fp, "%s\n", config_text.c_str());
2127e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    fclose(fp);
2137e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
2147e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh};
2157e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
2167e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh//......................................................................
2177e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
2187e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic void readEncodedProfile(const char *testpoint,
219124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh                               wireless_android_play_playlog::AndroidPerfProfile &encodedProfile)
2207e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{
2217e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  struct stat statb;
222f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  int perf_data_stat_result = stat(encoded_file_path(0).c_str(), &statb);
2237e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  ASSERT_NE(-1, perf_data_stat_result);
2247e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
2257e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // read
2267e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  std::string encoded;
2277e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  encoded.resize(statb.st_size);
228f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  FILE *ifp = fopen(encoded_file_path(0).c_str(), "r");
2297e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  ASSERT_NE(nullptr, ifp);
2307e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  size_t items_read = fread((void*) encoded.data(), statb.st_size, 1, ifp);
2317e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  ASSERT_EQ(1, items_read);
2327e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  fclose(ifp);
2337e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
2347e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // decode
2357e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  encodedProfile.ParseFromString(encoded);
236124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh}
237124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh
238124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntoshstatic std::string encodedLoadModuleToString(const wireless_android_play_playlog::LoadModule &lm)
239124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh{
240124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh  std::stringstream ss;
241124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh  ss << "name: \"" << lm.name() << "\"\n";
242124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh  if (lm.build_id() != "") {
243124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh    ss << "build_id: \"" << lm.build_id() << "\"\n";
244124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh  }
245124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh  return ss.str();
246124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh}
2477e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
248124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntoshstatic std::string encodedModuleSamplesToString(const wireless_android_play_playlog::LoadModuleSamples &mod)
249124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh{
250124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh  std::stringstream ss;
251124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh
252124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh  ss << "load_module_id: " << mod.load_module_id() << "\n";
253124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh  for (size_t k = 0; k < mod.address_samples_size(); k++) {
254124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh    const auto &sample = mod.address_samples(k);
255124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh    ss << "  address_samples {\n";
256124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh    for (size_t l = 0; l < mod.address_samples(k).address_size();
257124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh         l++) {
258124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh      auto address = mod.address_samples(k).address(l);
259124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh      ss << "    address: " << address << "\n";
2607e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    }
261124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh    ss << "    count: " << sample.count() << "\n";
262124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh    ss << "  }\n";
2637e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
264124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh  return ss.str();
2657e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh}
2667e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
2677e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh#define RAW_RESULT(x) #x
2687e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
2697e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh//
2707e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// Check to see if the log messages emitted by the daemon
2717e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// match the expected result. By default we use a partial
2727e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// match, e.g. if we see the expected excerpt anywhere in the
2737e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh// result, it's a match (for exact match, set exact to true)
2747e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh//
2757e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshstatic void compareLogMessages(const std::string &actual,
2767e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                               const std::string &expected,
2777e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                               const char *testpoint,
2787e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                               bool exactMatch=false)
2797e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{
2807e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh   std::string sqexp = squeezeWhite(expected, "expected");
2817e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh   std::string sqact = squeezeWhite(actual, "actual");
2827e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh   if (exactMatch) {
2837e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh     EXPECT_STREQ(sqexp.c_str(), sqact.c_str());
2847e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh   } else {
2857e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh     std::size_t foundpos = sqact.find(sqexp);
2867e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh     bool wasFound = true;
2877e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh     if (foundpos == std::string::npos) {
2887e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh       std::cerr << testpoint << ": expected result not found\n";
2897e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh       std::cerr << " Actual: \"" << sqact << "\"\n";
2907e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh       std::cerr << " Expected: \"" << sqexp << "\"\n";
2917e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh       wasFound = false;
2927e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh     }
2937e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh     EXPECT_TRUE(wasFound);
2947e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh   }
2957e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh}
2967e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
2977e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshTEST_F(PerfProfdTest, MissingGMS)
2987e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{
2997e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  //
3007e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // AWP requires cooperation between the daemon and the GMS core
3017e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // piece. If we're running on a device that has an old or damaged
30258bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen  // version of GMS core, then the config directory we're interested in
30358bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen  // may not be there. This test insures that the daemon does the
30458bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen  // right thing in this case.
3057e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  //
3067e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  PerfProfdRunner runner;
3077e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("only_debug_build=0");
308f353d8bf370eab2117e6259630f5540f12b361b0Than McIntosh  runner.addToConfig("trace_config_read=0");
30958bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen  runner.addToConfig("config_directory=/does/not/exist");
3107e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("main_loop_iterations=1");
3117e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("use_fixed_seed=1");
3127e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("collection_interval=100");
3137e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
3147e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Kick off daemon
3157e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  int daemon_main_return_code = runner.invoke();
3167e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
3177e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Check return code from daemon
3187e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  EXPECT_EQ(0, daemon_main_return_code);
3197e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
3207e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Verify log contents
3217e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  const std::string expected = RAW_RESULT(
3227e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      I: sleep 90 seconds
32358bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen      W: unable to open config directory /does/not/exist: (No such file or directory)
32458bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen      I: profile collection skipped (missing config directory)
32558bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen                                          );
3267e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
3277e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // check to make sure entire log matches
3287e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  compareLogMessages(mock_perfprofdutils_getlogged(),
32958bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen                     expected, "MissingGMS");
3307e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh}
3317e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
33258bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen
3337e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshTEST_F(PerfProfdTest, MissingOptInSemaphoreFile)
3347e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{
3357e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  //
3367e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Android device owners must opt in to "collect and report usage
3377e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // data" in order for us to be able to collect profiles. The opt-in
3387e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // check is performed in the GMS core component; if the check
3397e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // passes, then it creates a semaphore file for the daemon to pick
3407e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // up on.
3417e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  //
3427e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  PerfProfdRunner runner;
3437e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("only_debug_build=0");
34458bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen  std::string cfparam("config_directory="); cfparam += test_dir;
34558bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen  runner.addToConfig(cfparam);
3467e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  std::string ddparam("destination_directory="); ddparam += dest_dir;
3477e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig(ddparam);
3487e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("main_loop_iterations=1");
3497e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("use_fixed_seed=1");
3507e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("collection_interval=100");
3517e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
3527e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.remove_semaphore_file();
3537e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
3547e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Kick off daemon
3557e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  int daemon_main_return_code = runner.invoke();
3567e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
3577e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Check return code from daemon
3587e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  EXPECT_EQ(0, daemon_main_return_code);
3597e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
3607e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Verify log contents
3617e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  const std::string expected = RAW_RESULT(
3627e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      I: profile collection skipped (missing semaphore file)
3637e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                                          );
3647e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // check to make sure log excerpt matches
3657e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  compareLogMessages(mock_perfprofdutils_getlogged(),
3667e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                     expected, "MissingOptInSemaphoreFile");
3677e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh}
3687e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
3697e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshTEST_F(PerfProfdTest, MissingPerfExecutable)
3707e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{
3717e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  //
37207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh  // Perfprofd uses the 'simpleperf' tool to collect profiles
37307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh  // (although this may conceivably change in the future). This test
37407f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh  // checks to make sure that if 'simpleperf' is not present we bail out
37507f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh  // from collecting profiles.
3767e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  //
3777e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  PerfProfdRunner runner;
3787e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("only_debug_build=0");
3797e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("trace_config_read=1");
38058bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen  std::string cfparam("config_directory="); cfparam += test_dir;
38158bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen  runner.addToConfig(cfparam);
3827e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  std::string ddparam("destination_directory="); ddparam += dest_dir;
3837e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig(ddparam);
3847e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("main_loop_iterations=1");
3857e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("use_fixed_seed=1");
3867e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("collection_interval=100");
3877e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("perf_path=/does/not/exist");
3887e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
3897e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Create semaphore file
3907e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.create_semaphore_file();
3917e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
3927e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Kick off daemon
3937e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  int daemon_main_return_code = runner.invoke();
3947e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
3957e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Check return code from daemon
3967e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  EXPECT_EQ(0, daemon_main_return_code);
3977e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
3987e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // expected log contents
3997e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  const std::string expected = RAW_RESULT(
4007e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      I: profile collection skipped (missing 'perf' executable)
4017e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                                          );
4027e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // check to make sure log excerpt matches
4037e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  compareLogMessages(mock_perfprofdutils_getlogged(),
4047e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                     expected, "MissingPerfExecutable");
4057e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh}
4067e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
4077e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshTEST_F(PerfProfdTest, BadPerfRun)
4087e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{
4097e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  //
41007f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh  // Perf tools tend to be tightly coupled with a specific kernel
41107f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh  // version -- if things are out of sync perf could fail or
41207f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh  // crash. This test makes sure that we detect such a case and log
41307f00fd438a0c10bc6b2487352d09eb0a648db40Than McIntosh  // the error.
4147e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  //
4157e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  PerfProfdRunner runner;
4167e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("only_debug_build=0");
41758bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen  std::string cfparam("config_directory="); cfparam += test_dir;
41858bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen  runner.addToConfig(cfparam);
4197e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  std::string ddparam("destination_directory="); ddparam += dest_dir;
4207e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig(ddparam);
4217e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("main_loop_iterations=1");
4227e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("use_fixed_seed=1");
4237e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("collection_interval=100");
4247e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("perf_path=/system/bin/false");
4257e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
4267e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Create semaphore file
4277e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.create_semaphore_file();
4287e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
4297e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Kick off daemon
4307e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  int daemon_main_return_code = runner.invoke();
4317e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
4327e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Check return code from daemon
4337e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  EXPECT_EQ(0, daemon_main_return_code);
4347e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
4357e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Verify log contents
4367e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  const std::string expected = RAW_RESULT(
4377e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      I: profile collection failed (perf record returned bad exit status)
4387e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                                          );
4397e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
4407e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // check to make sure log excerpt matches
4417e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  compareLogMessages(mock_perfprofdutils_getlogged(),
4427e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                     expected, "BadPerfRun");
4437e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh}
4447e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
4457e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshTEST_F(PerfProfdTest, ConfigFileParsing)
4467e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{
4477e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  //
4487e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Gracefully handly malformed items in the config file
4497e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  //
4507e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  PerfProfdRunner runner;
4517e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("only_debug_build=0");
4527e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("main_loop_iterations=1");
4537e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("collection_interval=100");
4547e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("use_fixed_seed=1");
4557e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("destination_directory=/does/not/exist");
4567e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
4577e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // assorted bad syntax
4587e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("collection_interval=0");
4597e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("collection_interval=-1");
4607e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("collection_interval=2");
4617e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("nonexistent_key=something");
4627e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("no_equals_stmt");
4637e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
4647e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Kick off daemon
4657e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  int daemon_main_return_code = runner.invoke();
4667e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
4677e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Check return code from daemon
4687e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  EXPECT_EQ(0, daemon_main_return_code);
4697e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
4707e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Verify log contents
4717e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  const std::string expected = RAW_RESULT(
4727e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      W: line 6: specified value 0 for 'collection_interval' outside permitted range [100 4294967295] (ignored)
4737e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      W: line 7: malformed unsigned value (ignored)
4747e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      W: line 8: specified value 2 for 'collection_interval' outside permitted range [100 4294967295] (ignored)
4757e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      W: line 9: unknown option 'nonexistent_key' ignored
4767e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      W: line 10: line malformed (no '=' found)
4777e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                                          );
4787e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
4797e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // check to make sure log excerpt matches
4807e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  compareLogMessages(mock_perfprofdutils_getlogged(),
4817e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                     expected, "ConfigFileParsing");
4827e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh}
4837e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
4848c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntoshTEST_F(PerfProfdTest, ProfileCollectionAnnotations)
4858c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh{
4868c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh  unsigned util1 = collect_cpu_utilization();
4878c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh  EXPECT_LE(util1, 100);
4888c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh  EXPECT_GE(util1, 0);
4898c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh
4908c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh  // NB: expectation is that when we run this test, the device will be
4918c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh  // completed booted, will be on charger, and will not have the camera
4928c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh  // active.
4938c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh  EXPECT_FALSE(get_booting());
4948c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh  EXPECT_TRUE(get_charging());
4958c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh  EXPECT_FALSE(get_camera_active());
4968c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh}
4978c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh
4987e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshTEST_F(PerfProfdTest, BasicRunWithCannedPerf)
4997e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{
5007e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  //
5017e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Verify the portion of the daemon that reads and encodes
5027e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // perf.data files. Here we run the encoder on a canned perf.data
5037e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // file and verify that the resulting protobuf contains what
5047e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // we think it should contain.
5057e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  //
5067e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  std::string input_perf_data(test_dir);
5077e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  input_perf_data += "/canned.perf.data";
5087e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
5098c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh  // Set up config to avoid these annotations (they are tested elsewhere)
5108c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh  ConfigReader config;
5118c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh  config.overrideUnsignedEntry("collect_cpu_utilization", 0);
5128c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh  config.overrideUnsignedEntry("collect_charging_state", 0);
5138c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh  config.overrideUnsignedEntry("collect_camera_active", 0);
5148c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh
5157e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Kick off encoder and check return code
5167e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  PROFILE_RESULT result =
5178c7c7db1f1a23ab0c575cc217bed6b45f42b9ba5Than McIntosh      encode_to_proto(input_perf_data, encoded_file_path(0).c_str(), config, 0);
5187e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  EXPECT_EQ(OK_PROFILE_COLLECTION, result);
5197e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
5207e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Read and decode the resulting perf.data.encoded file
5217e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  wireless_android_play_playlog::AndroidPerfProfile encodedProfile;
5227e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  readEncodedProfile("BasicRunWithCannedPerf",
5237e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                     encodedProfile);
5247e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
5257e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Expect 29 load modules
5267e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  EXPECT_EQ(29, encodedProfile.programs_size());
5277e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
5287e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Check a couple of load modules
5297e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  { const auto &lm0 = encodedProfile.load_modules(0);
530124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh    std::string act_lm0 = encodedLoadModuleToString(lm0);
5317e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    std::string sqact0 = squeezeWhite(act_lm0, "actual for lm 0");
5327e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    const std::string expected_lm0 = RAW_RESULT(
5337e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh        name: "/data/app/com.google.android.apps.plus-1/lib/arm/libcronet.so"
5347e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                                                );
5357e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    std::string sqexp0 = squeezeWhite(expected_lm0, "expected_lm0");
5367e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    EXPECT_STREQ(sqexp0.c_str(), sqact0.c_str());
5377e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
5387e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  { const auto &lm9 = encodedProfile.load_modules(9);
539124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh    std::string act_lm9 = encodedLoadModuleToString(lm9);
5407e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    std::string sqact9 = squeezeWhite(act_lm9, "actual for lm 9");
5417e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    const std::string expected_lm9 = RAW_RESULT(
5427e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh        name: "/system/lib/libandroid_runtime.so" build_id: "8164ed7b3a8b8f5a220d027788922510"
5437e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                                                );
5447e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    std::string sqexp9 = squeezeWhite(expected_lm9, "expected_lm9");
5457e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    EXPECT_STREQ(sqexp9.c_str(), sqact9.c_str());
5467e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
5477e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
5487e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Examine some of the samples now
5497e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  { const auto &p1 = encodedProfile.programs(0);
5507e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    const auto &lm1 = p1.modules(0);
551124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh    std::string act_lm1 = encodedModuleSamplesToString(lm1);
5527e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    std::string sqact1 = squeezeWhite(act_lm1, "actual for lm1");
5537e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    const std::string expected_lm1 = RAW_RESULT(
5547e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh        load_module_id: 9 address_samples { address: 296100 count: 1 }
5557e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                                                );
5567e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    std::string sqexp1 = squeezeWhite(expected_lm1, "expected_lm1");
5577e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    EXPECT_STREQ(sqexp1.c_str(), sqact1.c_str());
5587e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
5597e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  { const auto &p1 = encodedProfile.programs(2);
5607e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    const auto &lm2 = p1.modules(0);
561124dd4262f2a2c8e55fdb81af9981b1f949a9686Than McIntosh    std::string act_lm2 = encodedModuleSamplesToString(lm2);
5627e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    std::string sqact2 = squeezeWhite(act_lm2, "actual for lm2");
5637e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    const std::string expected_lm2 = RAW_RESULT(
5647e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh        load_module_id: 2
5657e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh        address_samples { address: 28030244 count: 1 }
5667e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh        address_samples { address: 29657840 count: 1 }
5677e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                                                );
5687e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    std::string sqexp2 = squeezeWhite(expected_lm2, "expected_lm2");
5697e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh    EXPECT_STREQ(sqexp2.c_str(), sqact2.c_str());
5707e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  }
5717e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh}
5727e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
5737e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshTEST_F(PerfProfdTest, BasicRunWithLivePerf)
5747e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh{
5757e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  //
5767e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Basic test to exercise the main loop of the daemon. It includes
5777e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // a live 'perf' run
5787e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  //
5797e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  PerfProfdRunner runner;
5807e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("only_debug_build=0");
5817e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  std::string ddparam("destination_directory="); ddparam += dest_dir;
5827e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig(ddparam);
58358bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen  std::string cfparam("config_directory="); cfparam += test_dir;
58458bade36c738ed96137cfcc8d15f0505f085b5aeDehao Chen  runner.addToConfig(cfparam);
5857e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("main_loop_iterations=1");
5867e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("use_fixed_seed=12345678");
587f353d8bf370eab2117e6259630f5540f12b361b0Than McIntosh  runner.addToConfig("max_unprocessed_profiles=100");
5887e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.addToConfig("collection_interval=9999");
589f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  runner.addToConfig("sample_duration=2");
5907e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
5917e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Create semaphore file
5927e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  runner.create_semaphore_file();
5937e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
5947e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Kick off daemon
5957e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  int daemon_main_return_code = runner.invoke();
5967e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
5977e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Check return code from daemon
5987e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  EXPECT_EQ(0, daemon_main_return_code);
5997e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
6007e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Read and decode the resulting perf.data.encoded file
6017e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  wireless_android_play_playlog::AndroidPerfProfile encodedProfile;
6027e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  readEncodedProfile("BasicRunWithLivePerf", encodedProfile);
6037e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
6047e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Examine what we get back. Since it's a live profile, we can't
6057e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // really do much in terms of verifying the contents.
6067e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  EXPECT_LT(0, encodedProfile.programs_size());
6077e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
6087e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // Verify log contents
6097e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  const std::string expected = RAW_RESULT(
6107e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      I: starting Android Wide Profiling daemon
6117e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      I: config file path set to /data/nativetest/perfprofd_test/perfprofd.conf
6127e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      I: random seed set to 12345678
6137e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      I: sleep 674 seconds
6147e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      I: initiating profile collection
6157e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      I: profile collection complete
6167e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      I: sleep 9325 seconds
6177e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh      I: finishing Android Wide Profiling daemon
6187e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                                          );
6197e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // check to make sure log excerpt matches
6207e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  compareLogMessages(mock_perfprofdutils_getlogged(),
6217e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh                     expected, "BasicRunWithLivePerf", true);
6227e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh}
6237e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh
624f4605017b29dd98232af9385e71079a3ba0297f1Dehao ChenTEST_F(PerfProfdTest, MultipleRunWithLivePerf)
625f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen{
626f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  //
627f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  // Basic test to exercise the main loop of the daemon. It includes
628f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  // a live 'perf' run
629f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  //
630f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  PerfProfdRunner runner;
631f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  runner.addToConfig("only_debug_build=0");
632f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  std::string ddparam("destination_directory="); ddparam += dest_dir;
633f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  runner.addToConfig(ddparam);
634f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  std::string cfparam("config_directory="); cfparam += test_dir;
635f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  runner.addToConfig(cfparam);
636f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  runner.addToConfig("main_loop_iterations=3");
637f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  runner.addToConfig("use_fixed_seed=12345678");
638f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  runner.addToConfig("collection_interval=9999");
639f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  runner.addToConfig("sample_duration=2");
640f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  runner.write_processed_file(1, 2);
641f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen
642f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  // Create semaphore file
643f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  runner.create_semaphore_file();
644f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen
645f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  // Kick off daemon
646f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  int daemon_main_return_code = runner.invoke();
647f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen
648f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  // Check return code from daemon
649f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  EXPECT_EQ(0, daemon_main_return_code);
650f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen
651f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  // Read and decode the resulting perf.data.encoded file
652f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  wireless_android_play_playlog::AndroidPerfProfile encodedProfile;
653f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  readEncodedProfile("BasicRunWithLivePerf", encodedProfile);
654f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen
655f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  // Examine what we get back. Since it's a live profile, we can't
656f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  // really do much in terms of verifying the contents.
657f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  EXPECT_LT(0, encodedProfile.programs_size());
658f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen
659f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  // Examine that encoded.1 file is removed while encoded.{0|2} exists.
660f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  EXPECT_EQ(0, access(encoded_file_path(0).c_str(), F_OK));
661f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  EXPECT_NE(0, access(encoded_file_path(1).c_str(), F_OK));
662f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  EXPECT_EQ(0, access(encoded_file_path(2).c_str(), F_OK));
663f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen
664f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  // Verify log contents
665f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  const std::string expected = RAW_RESULT(
666f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      I: starting Android Wide Profiling daemon
667f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      I: config file path set to /data/nativetest/perfprofd_test/perfprofd.conf
668f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      I: random seed set to 12345678
669f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      I: sleep 674 seconds
670f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      I: initiating profile collection
671f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      I: profile collection complete
672f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      I: sleep 9325 seconds
673f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      I: sleep 4974 seconds
674f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      I: initiating profile collection
675f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      I: profile collection complete
676f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      I: sleep 5025 seconds
677f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      I: sleep 501 seconds
678f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      I: initiating profile collection
679f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      I: profile collection complete
680f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      I: sleep 9498 seconds
681f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen      I: finishing Android Wide Profiling daemon
682f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen                                          );
683f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  // check to make sure log excerpt matches
684f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen  compareLogMessages(mock_perfprofdutils_getlogged(),
685f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen                     expected, "BasicRunWithLivePerf", true);
686f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen}
687f4605017b29dd98232af9385e71079a3ba0297f1Dehao Chen
6887e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntoshint main(int argc, char **argv) {
6897e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  executable_path = argv[0];
6907e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // switch to / before starting testing (perfprofd
6917e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  // should be location-independent)
6927e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  chdir("/");
6937e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  testing::InitGoogleTest(&argc, argv);
6947e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh  return RUN_ALL_TESTS();
6957e2f4e9d384d501cf86118ebac4b8de2b86eac53Than McIntosh}
696