Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 12531867 authored by Bertrand SIMONNET's avatar Bertrand SIMONNET
Browse files

metricsd: Make the unit tests pass.

This cleans up the unit tests and update them to pass.

Cleaned up:
* removed the irrelevant bits.
* Used ScopedTempDir for all test specific files (instead of the current
  directory).
* Update some objects to make them more easily testable.
* Group all the test in a single binary and use bionic's test runner.

BUG: 23682444
Change-Id: I289e3a5ff89968fdecd4a156e93bc38bbc25f58b
parent 7b0bdec4
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -41,6 +41,28 @@ metrics_daemon_sources := \
  serialization/metric_sample.cc \
  serialization/serialization_utils.cc

metrics_tests_sources := \
  metrics_daemon.cc \
  metrics_daemon_test.cc \
  metrics_library_test.cc \
  persistent_integer.cc \
  persistent_integer_test.cc \
  serialization/metric_sample.cc \
  serialization/serialization_utils.cc \
  serialization/serialization_utils_unittest.cc \
  timer.cc \
  timer_test.cc \
  uploader/metrics_hashes.cc \
  uploader/metrics_hashes_unittest.cc \
  uploader/metrics_log_base.cc \
  uploader/metrics_log_base_unittest.cc \
  uploader/metrics_log.cc \
  uploader/mock/sender_mock.cc \
  uploader/sender_http.cc \
  uploader/system_profile_cache.cc \
  uploader/upload_service.cc \
  uploader/upload_service_test.cc \

metrics_CFLAGS := -Wall \
  -Wno-char-subscripts \
  -Wno-missing-field-initializers \
@@ -125,4 +147,25 @@ LOCAL_SRC_FILES := init.$(LOCAL_INIT_SERVICE).rc
include $(BUILD_PREBUILT)
endif # INITRC_TEMPLATE

# Unit tests for metrics.
# ========================================================
include $(CLEAR_VARS)
LOCAL_MODULE := metrics_tests
LOCAL_CFLAGS := $(metrics_CFLAGS)
LOCAL_CPP_EXTENSION := $(metrics_cpp_extension)
LOCAL_CPPFLAGS := $(metrics_CPPFLAGS) -Wno-sign-compare
LOCAL_RTTI_FLAG := -frtti
LOCAL_SHARED_LIBRARIES := $(metrics_shared_libraries) \
  libmetrics \
  libprotobuf-cpp-lite \
  libchromeos-http \
  libchromeos-dbus \
  libcutils \
  libdbus \

LOCAL_SRC_FILES := $(metrics_tests_sources)
LOCAL_STATIC_LIBRARIES := libBionicGtestMain libgmock metrics_daemon_protos

include $(BUILD_NATIVE_TEST)

endif # HOST_OS == linux
+3 −0
Original line number Diff line number Diff line
@@ -129,6 +129,9 @@ class MetricsLibrary : public MetricsLibraryInterface {
  FRIEND_TEST(MetricsLibraryTest, SendMessageToChrome);
  FRIEND_TEST(MetricsLibraryTest, SendMessageToChromeUMAEventsBadFileLocation);

  void InitForTest(const std::string& uma_events_file,
                   const std::string& consent_file);

  // Sets |*result| to whether or not the |mounts_file| indicates that
  // the |device_name| is currently mounted.  Uses |buffer| of
  // |buffer_size| to read the file.  Returns false if any error.
+4 −4
Original line number Diff line number Diff line
@@ -195,8 +195,8 @@ int MetricsDaemon::Run() {
}

void MetricsDaemon::RunUploaderTest() {
  upload_service_.reset(new UploadService(new SystemProfileCache(true,
                                                                 config_root_),
  upload_service_.reset(new UploadService(
      new SystemProfileCache(true, base::FilePath(config_root_)),
      metrics_lib_,
      server_));
  upload_service_->Init(upload_interval_, metrics_file_);
+48 −132
Original line number Diff line number Diff line
@@ -22,11 +22,12 @@

#include <base/at_exit.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/stringprintf.h>
#include <chromeos/dbus/service_constants.h>
#include <gtest/gtest.h>

#include "constants.h"
#include "metrics_daemon.h"
#include "metrics_library_mock.h"
#include "persistent_integer_mock.h"
@@ -45,7 +46,6 @@ using ::testing::Return;
using ::testing::StrictMock;
using chromeos_metrics::PersistentIntegerMock;

static const char kFakeDiskStatsName[] = "fake-disk-stats";
static const char kFakeDiskStatsFormat[] =
    "    1793     1788    %" PRIu64 "   105580    "
    "    196      175     %" PRIu64 "    30290    "
@@ -53,9 +53,6 @@ static const char kFakeDiskStatsFormat[] =
static const uint64_t kFakeReadSectors[] = {80000, 100000};
static const uint64_t kFakeWriteSectors[] = {3000, 4000};

static const char kFakeVmStatsName[] = "fake-vm-stats";
static const char kFakeScalingMaxFreqPath[] = "fake-scaling-max-freq";
static const char kFakeCpuinfoMaxFreqPath[] = "fake-cpuinfo-max-freq";

class MetricsDaemonTest : public testing::Test {
 protected:
@@ -63,78 +60,35 @@ class MetricsDaemonTest : public testing::Test {
  std::string kFakeDiskStats1;

  virtual void SetUp() {
    EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
    scaling_max_freq_path_ = temp_dir_.path().Append("scaling_max");
    cpu_max_freq_path_ = temp_dir_.path().Append("cpu_freq_max");
    disk_stats_path_ = temp_dir_.path().Append("disk_stats");

    kFakeDiskStats0 = base::StringPrintf(kFakeDiskStatsFormat,
                                           kFakeReadSectors[0],
                                           kFakeWriteSectors[0]);
    kFakeDiskStats1 = base::StringPrintf(kFakeDiskStatsFormat,
                                           kFakeReadSectors[1],
                                           kFakeWriteSectors[1]);
    CreateFakeDiskStatsFile(kFakeDiskStats0.c_str());
    CreateUint64ValueFile(base::FilePath(kFakeCpuinfoMaxFreqPath), 10000000);
    CreateUint64ValueFile(base::FilePath(kFakeScalingMaxFreqPath), 10000000);

    chromeos_metrics::PersistentInteger::SetTestingMode(true);
    CreateFakeDiskStatsFile(kFakeDiskStats0);
    CreateUint64ValueFile(cpu_max_freq_path_, 10000000);
    CreateUint64ValueFile(scaling_max_freq_path_, 10000000);

    chromeos_metrics::PersistentInteger::SetMetricsDirectory(
        temp_dir_.path().value());
    daemon_.Init(true,
                 false,
                 true,
                 &metrics_lib_,
                 kFakeDiskStatsName,
                 kFakeVmStatsName,
                 kFakeScalingMaxFreqPath,
                 kFakeCpuinfoMaxFreqPath,
                 disk_stats_path_.value(),
                 scaling_max_freq_path_.value(),
                 cpu_max_freq_path_.value(),
                 base::TimeDelta::FromMinutes(30),
                 kMetricsServer,
                 kMetricsFilePath,
                 metrics::kMetricsServer,
                 metrics::kMetricsEventsFilePath,
                 "/");

    // Replace original persistent values with mock ones.
    daily_active_use_mock_ =
        new StrictMock<PersistentIntegerMock>("1.mock");
    daemon_.daily_active_use_.reset(daily_active_use_mock_);

    kernel_crash_interval_mock_ =
        new StrictMock<PersistentIntegerMock>("2.mock");
    daemon_.kernel_crash_interval_.reset(kernel_crash_interval_mock_);

    user_crash_interval_mock_ =
        new StrictMock<PersistentIntegerMock>("3.mock");
    daemon_.user_crash_interval_.reset(user_crash_interval_mock_);

    unclean_shutdown_interval_mock_ =
        new StrictMock<PersistentIntegerMock>("4.mock");
    daemon_.unclean_shutdown_interval_.reset(unclean_shutdown_interval_mock_);
  }

  virtual void TearDown() {
    EXPECT_EQ(0, unlink(kFakeDiskStatsName));
    EXPECT_EQ(0, unlink(kFakeScalingMaxFreqPath));
    EXPECT_EQ(0, unlink(kFakeCpuinfoMaxFreqPath));
  }

  // Adds active use aggregation counters update expectations that the
  // specified count will be added.
  void ExpectActiveUseUpdate(int count) {
    EXPECT_CALL(*daily_active_use_mock_, Add(count))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*kernel_crash_interval_mock_, Add(count))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*user_crash_interval_mock_, Add(count))
        .Times(1)
        .RetiresOnSaturation();
  }

  // As above, but ignore values of counter updates.
  void IgnoreActiveUseUpdate() {
    EXPECT_CALL(*daily_active_use_mock_, Add(_))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*kernel_crash_interval_mock_, Add(_))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*user_crash_interval_mock_, Add(_))
        .Times(1)
        .RetiresOnSaturation();
  }

  // Adds a metrics library mock expectation that the specified metric
@@ -177,19 +131,15 @@ class MetricsDaemonTest : public testing::Test {
  }

  // Creates or overwrites an input file containing fake disk stats.
  void CreateFakeDiskStatsFile(const char* fake_stats) {
    if (unlink(kFakeDiskStatsName) < 0) {
      EXPECT_EQ(errno, ENOENT);
    }
    FILE* f = fopen(kFakeDiskStatsName, "w");
    EXPECT_EQ(1, fwrite(fake_stats, strlen(fake_stats), 1, f));
    EXPECT_EQ(0, fclose(f));
  void CreateFakeDiskStatsFile(const string& fake_stats) {
    EXPECT_EQ(base::WriteFile(disk_stats_path_,
                              fake_stats.data(), fake_stats.size()),
              fake_stats.size());
  }

  // Creates or overwrites the file in |path| so that it contains the printable
  // representation of |value|.
  void CreateUint64ValueFile(const base::FilePath& path, uint64_t value) {
    base::DeleteFile(path, false);
    std::string value_string = base::Uint64ToString(value);
    ASSERT_EQ(value_string.length(),
              base::WriteFile(path, value_string.c_str(),
@@ -199,29 +149,19 @@ class MetricsDaemonTest : public testing::Test {
  // The MetricsDaemon under test.
  MetricsDaemon daemon_;

  // Temporary directory used for tests.
  base::ScopedTempDir temp_dir_;

  // Path for the fake files.
  base::FilePath scaling_max_freq_path_;
  base::FilePath cpu_max_freq_path_;
  base::FilePath disk_stats_path_;

  // Mocks. They are strict mock so that all unexpected
  // calls are marked as failures.
  StrictMock<MetricsLibraryMock> metrics_lib_;
  StrictMock<PersistentIntegerMock>* daily_active_use_mock_;
  StrictMock<PersistentIntegerMock>* kernel_crash_interval_mock_;
  StrictMock<PersistentIntegerMock>* user_crash_interval_mock_;
  StrictMock<PersistentIntegerMock>* unclean_shutdown_interval_mock_;
};

TEST_F(MetricsDaemonTest, CheckSystemCrash) {
  static const char kKernelCrashDetected[] = "test-kernel-crash-detected";
  EXPECT_FALSE(daemon_.CheckSystemCrash(kKernelCrashDetected));

  base::FilePath crash_detected(kKernelCrashDetected);
  base::WriteFile(crash_detected, "", 0);
  EXPECT_TRUE(base::PathExists(crash_detected));
  EXPECT_TRUE(daemon_.CheckSystemCrash(kKernelCrashDetected));
  EXPECT_FALSE(base::PathExists(crash_detected));
  EXPECT_FALSE(daemon_.CheckSystemCrash(kKernelCrashDetected));
  EXPECT_FALSE(base::PathExists(crash_detected));
  base::DeleteFile(crash_detected, false);
}

TEST_F(MetricsDaemonTest, MessageFilter) {
  // Ignore calls to SendToUMA.
  EXPECT_CALL(metrics_lib_, SendToUMA(_, _, _, _, _)).Times(AnyNumber());
@@ -232,7 +172,6 @@ TEST_F(MetricsDaemonTest, MessageFilter) {
  EXPECT_EQ(DBUS_HANDLER_RESULT_NOT_YET_HANDLED, res);
  DeleteDBusMessage(msg);

  IgnoreActiveUseUpdate();
  vector<string> signal_args;
  msg = NewDBusSignalString("/",
                            "org.chromium.CrashReporter",
@@ -260,25 +199,6 @@ TEST_F(MetricsDaemonTest, SendSample) {
                     /* min */ 1, /* max */ 100, /* buckets */ 50);
}

TEST_F(MetricsDaemonTest, ReportDiskStats) {
  uint64_t read_sectors_now, write_sectors_now;
  CreateFakeDiskStatsFile(kFakeDiskStats1.c_str());
  daemon_.DiskStatsReadStats(&read_sectors_now, &write_sectors_now);
  EXPECT_EQ(read_sectors_now, kFakeReadSectors[1]);
  EXPECT_EQ(write_sectors_now, kFakeWriteSectors[1]);

  MetricsDaemon::StatsState s_state = daemon_.stats_state_;
  EXPECT_CALL(metrics_lib_,
              SendToUMA(_, (kFakeReadSectors[1] - kFakeReadSectors[0]) / 30,
                        _, _, _));
  EXPECT_CALL(metrics_lib_,
              SendToUMA(_, (kFakeWriteSectors[1] - kFakeWriteSectors[0]) / 30,
                        _, _, _));
  EXPECT_CALL(metrics_lib_, SendEnumToUMA(_, _, _));  // SendCpuThrottleMetrics
  daemon_.StatsCallback();
  EXPECT_TRUE(s_state != daemon_.stats_state_);
}

TEST_F(MetricsDaemonTest, ProcessMeminfo) {
  string meminfo =
      "MemTotal:        2000000 kB\nMemFree:          500000 kB\n"
@@ -337,24 +257,24 @@ TEST_F(MetricsDaemonTest, ReadFreqToInt) {
  const int fake_max_freq = 2000000;
  int scaled_freq = 0;
  int max_freq = 0;
  CreateUint64ValueFile(base::FilePath(kFakeScalingMaxFreqPath),
                        fake_scaled_freq);
  CreateUint64ValueFile(base::FilePath(kFakeCpuinfoMaxFreqPath), fake_max_freq);
  CreateUint64ValueFile(scaling_max_freq_path_, fake_scaled_freq);
  CreateUint64ValueFile(cpu_max_freq_path_, fake_max_freq);
  EXPECT_TRUE(daemon_.testing_);
  EXPECT_TRUE(daemon_.ReadFreqToInt(kFakeScalingMaxFreqPath, &scaled_freq));
  EXPECT_TRUE(daemon_.ReadFreqToInt(kFakeCpuinfoMaxFreqPath, &max_freq));
  EXPECT_TRUE(daemon_.ReadFreqToInt(scaling_max_freq_path_.value(),
                                    &scaled_freq));
  EXPECT_TRUE(daemon_.ReadFreqToInt(cpu_max_freq_path_.value(), &max_freq));
  EXPECT_EQ(fake_scaled_freq, scaled_freq);
  EXPECT_EQ(fake_max_freq, max_freq);
}

TEST_F(MetricsDaemonTest, SendCpuThrottleMetrics) {
  CreateUint64ValueFile(base::FilePath(kFakeCpuinfoMaxFreqPath), 2001000);
  CreateUint64ValueFile(cpu_max_freq_path_, 2001000);
  // Test the 101% and 100% cases.
  CreateUint64ValueFile(base::FilePath(kFakeScalingMaxFreqPath), 2001000);
  CreateUint64ValueFile(scaling_max_freq_path_, 2001000);
  EXPECT_TRUE(daemon_.testing_);
  EXPECT_CALL(metrics_lib_, SendEnumToUMA(_, 101, 101));
  daemon_.SendCpuThrottleMetrics();
  CreateUint64ValueFile(base::FilePath(kFakeScalingMaxFreqPath), 2000000);
  CreateUint64ValueFile(scaling_max_freq_path_, 2000000);
  EXPECT_CALL(metrics_lib_, SendEnumToUMA(_, 100, 101));
  daemon_.SendCpuThrottleMetrics();
}
@@ -370,12 +290,14 @@ TEST_F(MetricsDaemonTest, SendZramMetrics) {
  const uint64_t page_size = 4096;
  const uint64_t zero_pages = 10 * 1000 * 1000 / page_size;

  CreateUint64ValueFile(base::FilePath(MetricsDaemon::kComprDataSizeName),
  CreateUint64ValueFile(
      temp_dir_.path().Append(MetricsDaemon::kComprDataSizeName),
      compr_data_size);
  CreateUint64ValueFile(base::FilePath(MetricsDaemon::kOrigDataSizeName),
  CreateUint64ValueFile(
      temp_dir_.path().Append(MetricsDaemon::kOrigDataSizeName),
      orig_data_size);
  CreateUint64ValueFile(base::FilePath(MetricsDaemon::kZeroPagesName),
                        zero_pages);
  CreateUint64ValueFile(
      temp_dir_.path().Append(MetricsDaemon::kZeroPagesName), zero_pages);

  const uint64_t real_orig_size = orig_data_size + zero_pages * page_size;
  const uint64_t zero_ratio_percent =
@@ -390,11 +312,5 @@ TEST_F(MetricsDaemonTest, SendZramMetrics) {
  EXPECT_CALL(metrics_lib_, SendToUMA(_, zero_pages, _, _, _));
  EXPECT_CALL(metrics_lib_, SendToUMA(_, zero_ratio_percent, _, _, _));

  EXPECT_TRUE(daemon_.ReportZram(base::FilePath(".")));
}

int main(int argc, char** argv) {
  testing::InitGoogleTest(&argc, argv);

  return RUN_ALL_TESTS();
  EXPECT_TRUE(daemon_.ReportZram(temp_dir_.path()));
}
+6 −0
Original line number Diff line number Diff line
@@ -140,6 +140,12 @@ void MetricsLibrary::Init() {
  uma_events_file_ = metrics::kMetricsEventsFilePath;
}

void MetricsLibrary::InitForTest(const std::string& uma_events_file,
                                 const std::string& consent_file) {
  uma_events_file_ = uma_events_file;
  consent_file_ = consent_file;
}

bool MetricsLibrary::SendToUMA(const std::string& name,
                               int sample,
                               int min,
Loading