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

Commit 2ccef016 authored by Darin Petkov's avatar Darin Petkov
Browse files

Add some basic tests for metrics_daemon.

A separate CL adds a test stanza to the metrics ebuild. More tests
(specifically, for the D-Bus MessageFilter) will also come in a
separate CL.

Review URL: http://codereview.chromium.org/1919005
parent 41e0623c
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@ CXXFLAGS += -Wall -Werror -fPIC -fno-exceptions $(CCONFIG)

CLIENT = metrics_client
DAEMON = metrics_daemon
TESTDAEMON = test_daemon
DAEMON_TEST = metrics_daemon_test
LIB = libmetrics.a
SHAREDLIB = libmetrics.so

@@ -25,12 +25,14 @@ DAEMON_OBJS = \
	metrics_daemon_main.o
TESTDAEMON_OBJS = \
	metrics_daemon.o \
	metrics_daemon_unittest.o
	metrics_daemon_test.o

DAEMON_LDFLAGS = $(LDCONFIG) -lrt -lbase -lpthread -lgflags
TESTDAEMON_LIBS = -lgtest

all: $(LIB) $(SHAREDLIB) $(CLIENT) $(DAEMON) $(TESTDAEMON)
all: $(LIB) $(SHAREDLIB) $(CLIENT) $(DAEMON)

tests: $(DAEMON_TEST)

$(CLIENT): $(CLIENT_OBJS) $(SHAREDLIB)
	$(CXX) $(LDFLAGS) $^ -o $@
@@ -38,11 +40,11 @@ $(CLIENT): $(CLIENT_OBJS) $(SHAREDLIB)
$(DAEMON): $(DAEMON_OBJS) $(SHAREDLIB)
	$(CXX) -o $@ $^ $(DAEMON_LDFLAGS)

$(TESTDAEMON): $(TESTDAEMON_OBJS) $(SHAREDLIB)
$(DAEMON_TEST): $(TESTDAEMON_OBJS) $(SHAREDLIB)
	$(CXX) -o $@ $^ $(DAEMON_LDFLAGS) $(TESTDAEMON_LIBS)

$(LIB): $(LIB_OBJS)
	ar rcs $@ $^
	$(AR) rcs $@ $^

$(SHAREDLIB): $(LIB_OBJS)
	$(CXX) $(LDFLAGS) -shared $^ -o $@
@@ -56,7 +58,7 @@ metrics_daemon.o: \
	metrics_daemon.h \
	network_states.h \
	power_states.h
metrics_daemon_unittest.o: \
metrics_daemon_test.o: \
	metrics_daemon.h \
	network_states.h \
	power_states.h

metrics/make_tests.sh

0 → 100755
+12 −0
Original line number Diff line number Diff line
#!/bin/bash

# Copyright (c) 2010 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.

# Builds tests.

set -e
make tests
mkdir -p "${OUT_DIR}"
cp *_test "${OUT_DIR}"
+47 −20
Original line number Diff line number Diff line
@@ -37,6 +37,20 @@ static const int kSecondsPerDay = kMinutesPerDay * kSecondsPerMinute;
static const int kUseMonitorIntervalInit = 1 * kSecondsPerMinute;
static const int kUseMonitorIntervalMax = 10 * kSecondsPerMinute;

// static metrics parameters.
const char MetricsDaemon::kMetricDailyUseTimeName[] =
    "Logging.DailyUseTime";
const int MetricsDaemon::kMetricDailyUseTimeMin = 1;
const int MetricsDaemon::kMetricDailyUseTimeMax = kMinutesPerDay;
const int MetricsDaemon::kMetricDailyUseTimeBuckets = 50;

const char MetricsDaemon::kMetricTimeToNetworkDropName[] =
    "Network.TimeToDrop";
const int MetricsDaemon::kMetricTimeToNetworkDropMin = 1;
const int MetricsDaemon::kMetricTimeToNetworkDropMax =
    8 /* hours */ * kMinutesPerHour * kSecondsPerMinute;
const int MetricsDaemon::kMetricTimeToNetworkDropBuckets = 50;

// static
const char* MetricsDaemon::kDBusMatches_[] = {
  "type='signal',"
@@ -86,8 +100,8 @@ const char* MetricsDaemon::kSessionStates_[] = {
#include "session_states.h"
};

void MetricsDaemon::Run(bool run_as_daemon, bool testing) {
  Init(testing);
void MetricsDaemon::Run(bool run_as_daemon) {
  Init(false);
  if (!run_as_daemon || daemon(0, 0) == 0) {
    Loop();
  }
@@ -95,6 +109,11 @@ void MetricsDaemon::Run(bool run_as_daemon, bool testing) {

void MetricsDaemon::Init(bool testing) {
  testing_ = testing;
  daily_use_record_file_ = kDailyUseRecordFile;

  // Don't setup D-Bus and GLib in test mode.
  if (testing)
    return;

  g_thread_init(NULL);
  g_type_init();
@@ -192,17 +211,19 @@ void MetricsDaemon::NetStateChanged(const char* state_name, time_t now) {
  NetworkState state = LookupNetworkState(state_name);

  // Logs the time in seconds between the network going online to
  // going offline in order to measure the mean time to network
  // dropping. Going offline as part of suspend-to-RAM is not logged
  // as network drop -- the assumption is that the message for
  // suspend-to-RAM comes before the network offline message which
  // seems to and should be the case.
  if (state == kNetworkStateOffline &&
  // going offline (or, more precisely, going not online) in order to
  // measure the mean time to network dropping. Going offline as part
  // of suspend-to-RAM is not logged as network drop -- the assumption
  // is that the message for suspend-to-RAM comes before the network
  // offline message which seems to and should be the case.
  if (state != kNetworkStateOnline &&
      network_state_ == kNetworkStateOnline &&
      power_state_ != kPowerStateMem) {
    int online_time = static_cast<int>(now - network_state_last_);
    PublishMetric("Network.TimeToDrop", online_time,
                  1, 8 /* hours */ * 60 * 60, 50);
    PublishMetric(kMetricTimeToNetworkDropName, online_time,
                  kMetricTimeToNetworkDropMin,
                  kMetricTimeToNetworkDropMax,
                  kMetricTimeToNetworkDropBuckets);
  }

  network_state_ = state;
@@ -304,11 +325,11 @@ void MetricsDaemon::LogDailyUseRecord(int day, int seconds) {
    return;

  DLOG(INFO) << "day: " << day << " usage: " << seconds << " seconds";
  int fd = HANDLE_EINTR(open(kDailyUseRecordFile,
  int fd = HANDLE_EINTR(open(daily_use_record_file_,
                             O_RDWR | O_CREAT,
                             S_IRUSR | S_IWUSR));
  if (fd < 0) {
    DLOG(WARNING) << "Unable to open the daily use file.";
    PLOG(WARNING) << "Unable to open the daily use file";
    return;
  }

@@ -325,12 +346,14 @@ void MetricsDaemon::LogDailyUseRecord(int day, int seconds) {
      // the usage to the nearest minute and sends it to UMA.
      int minutes =
          (record.seconds_ + kSecondsPerMinute / 2) / kSecondsPerMinute;
      PublishMetric("Logging.DailyUseTime",
                    minutes, 1, kMinutesPerDay, 50);
      PublishMetric(kMetricDailyUseTimeName, minutes,
                    kMetricDailyUseTimeMin,
                    kMetricDailyUseTimeMax,
                    kMetricDailyUseTimeBuckets);

      // Truncates the usage file to ensure that no duplicate usage is
      // sent to UMA.
      LOG_IF(WARNING, HANDLE_EINTR(ftruncate(fd, 0)) != 0);
      PLOG_IF(WARNING, HANDLE_EINTR(ftruncate(fd, 0)) != 0);
    }
  }

@@ -344,9 +367,10 @@ void MetricsDaemon::LogDailyUseRecord(int day, int seconds) {
    // else an already existing record for the same day will be
    // overwritten with updated usage below.

    LOG_IF(WARNING, HANDLE_EINTR(lseek(fd, 0, SEEK_SET)) != 0);
    LOG_IF(WARNING,
           HANDLE_EINTR(write(fd, &record, sizeof(record))) != sizeof(record));
    PLOG_IF(WARNING, HANDLE_EINTR(lseek(fd, 0, SEEK_SET)) != 0);
    PLOG_IF(WARNING,
            HANDLE_EINTR(write(fd, &record, sizeof(record))) !=
            sizeof(record));
  }

  HANDLE_EINTR(close(fd));
@@ -374,6 +398,9 @@ bool MetricsDaemon::UseMonitor() {

bool MetricsDaemon::ScheduleUseMonitor(int interval, bool backoff)
{
  if (testing_)
    return false;

  // Caps the interval -- the bigger the interval, the more active use
  // time will be potentially dropped on system shutdown.
  if (interval > kUseMonitorIntervalMax)
@@ -417,7 +444,7 @@ void MetricsDaemon::UnscheduleUseMonitor() {

void MetricsDaemon::PublishMetric(const char* name, int sample,
                                  int min, int max, int nbuckets) {
  DLOG(INFO) << "received metric: " << name << " " << sample << " "
  LOG(INFO) << "received metric: " << name << " " << sample << " "
            << min << " " << max << " " << nbuckets;
  if (!testing_) {
    MetricsLibrary::SendToChrome(name, sample, min, max, nbuckets);
+32 −5
Original line number Diff line number Diff line
@@ -9,11 +9,14 @@
#include <glib.h>
#include <time.h>

#include <gtest/gtest_prod.h>  // for FRIEND_TEST

class MetricsDaemon {

 public:
  MetricsDaemon()
      : network_state_(kUnknownNetworkState),
      : daily_use_record_file_(NULL),
        network_state_(kUnknownNetworkState),
        network_state_last_(0),
        power_state_(kUnknownPowerState),
        screensaver_state_(kUnknownScreenSaverState),
@@ -26,11 +29,23 @@ class MetricsDaemon {
  ~MetricsDaemon() {}

  // Does all the work. If |run_as_daemon| is true, daemonizes by
  // forking. If |testing| is true, logs the stats instead of sending
  // them to Chrome.
  void Run(bool run_as_daemon, bool testing);
  // forking.
  void Run(bool run_as_daemon);

 private:
  friend class MetricsDaemonTest;
  FRIEND_TEST(MetricsDaemonTest, LogDailyUseRecord);
  FRIEND_TEST(MetricsDaemonTest, LookupNetworkState);
  FRIEND_TEST(MetricsDaemonTest, LookupPowerState);
  FRIEND_TEST(MetricsDaemonTest, LookupScreenSaverState);
  FRIEND_TEST(MetricsDaemonTest, LookupSessionState);
  FRIEND_TEST(MetricsDaemonTest, NetStateChanged);
  FRIEND_TEST(MetricsDaemonTest, PowerStateChanged);
  FRIEND_TEST(MetricsDaemonTest, PublishMetric);
  FRIEND_TEST(MetricsDaemonTest, ScreenSaverStateChanged);
  FRIEND_TEST(MetricsDaemonTest, SessionStateChanged);
  FRIEND_TEST(MetricsDaemonTest, SetUserActiveState);

  // The network states (see network_states.h).
  enum NetworkState {
    kUnknownNetworkState = -1, // Initial/unknown network state.
@@ -71,6 +86,16 @@ class MetricsDaemon {
    int seconds_;
  };

  // Metric parameters.
  static const char kMetricDailyUseTimeName[];
  static const int kMetricDailyUseTimeMin;
  static const int kMetricDailyUseTimeMax;
  static const int kMetricDailyUseTimeBuckets;
  static const char kMetricTimeToNetworkDropName[];
  static const int kMetricTimeToNetworkDropMin;
  static const int kMetricTimeToNetworkDropMax;
  static const int kMetricTimeToNetworkDropBuckets;

  // D-Bus message match strings.
  static const char* kDBusMatches_[];

@@ -161,9 +186,11 @@ class MetricsDaemon {
  void PublishMetric(const char* name, int sample,
                     int min, int max, int nbuckets);

  // Testing mode.
  // Test mode.
  bool testing_;

  const char* daily_use_record_file_;

  // Current network state.
  NetworkState network_state_;

+1 −1
Original line number Diff line number Diff line
@@ -12,5 +12,5 @@ DEFINE_bool(daemon, true, "run as daemon (use -nodaemon for debugging)");
int main(int argc, char** argv) {
  MetricsDaemon::MetricsDaemon d;
  google::ParseCommandLineFlags(&argc, &argv, true);
  d.Run(FLAGS_daemon, false);
  d.Run(FLAGS_daemon);
}
Loading