Add new metrics.

The current metrics (Installer.* namespace) have several shortcomings,
for example it's not immediately clear when and how frequent each
metric is reported. This CL introduces new metrics that addresses this
and other problems. The new metrics are all in the UpdateEngine.*
namespace and fall into five categories

 UpdateEngine.Daily.*               Reported daily.
 UpdateEngine.Check.*               On every check.
 UpdateEngine.Attempt.*             On every attempt.
 UpdateEngine.SuccessfulUpdate.*    With every successful update.
 UpdateEngine.*                     Miscellaneous

Most of the new metrics mimic existing metrics and also leverage the
existing code, book-keeping and unit tests. The plan is to remove the
Installer.* metrics once we're happy with the new ones.

I've also tested this manually by performing updates and verifying
that chrome://histograms looks correct.

BUG=chromium:355745
TEST=New unit tests + unit tests pass + manual testing.

Change-Id: I7a3f68d75910384b116c7e4664776e25d3997584
Reviewed-on: https://chromium-review.googlesource.com/191314
Reviewed-by: David Zeuthen <zeuthen@chromium.org>
Tested-by: David Zeuthen <zeuthen@chromium.org>
Commit-Queue: David Zeuthen <zeuthen@chromium.org>
diff --git a/utils_unittest.cc b/utils_unittest.cc
index e89f069..7105d3a 100644
--- a/utils_unittest.cc
+++ b/utils_unittest.cc
@@ -16,6 +16,9 @@
 #include <base/strings/stringprintf.h>
 #include <gtest/gtest.h>
 
+#include "update_engine/fake_clock.h"
+#include "update_engine/mock_system_state.h"
+#include "update_engine/prefs.h"
 #include "update_engine/test_utils.h"
 #include "update_engine/utils.h"
 
@@ -527,4 +530,139 @@
   EXPECT_EQ(value1, value2 - 7);
 }
 
+TEST(UtilsTest, WallclockDurationHelper) {
+  MockSystemState mock_system_state;
+  FakeClock fake_clock;
+  base::TimeDelta duration;
+  string state_variable_key = "test-prefs";
+  string temp_dir;
+  Prefs fake_prefs;
+
+  EXPECT_TRUE(utils::MakeTempDirectory("DurationPrefs.XXXXXX", &temp_dir));
+  fake_prefs.Init(base::FilePath(temp_dir));
+
+  mock_system_state.set_clock(&fake_clock);
+  mock_system_state.set_prefs(&fake_prefs);
+
+  // Initialize wallclock to 1 sec.
+  fake_clock.SetWallclockTime(base::Time::FromInternalValue(1000000));
+
+  // First time called so no previous measurement available.
+  EXPECT_FALSE(utils::WallclockDurationHelper(&mock_system_state,
+                                              state_variable_key,
+                                              &duration));
+
+  // Next time, we should get zero since the clock didn't advance.
+  EXPECT_TRUE(utils::WallclockDurationHelper(&mock_system_state,
+                                             state_variable_key,
+                                             &duration));
+  EXPECT_EQ(duration.InSeconds(), 0);
+
+  // We can also call it as many times as we want with it being
+  // considered a failure.
+  EXPECT_TRUE(utils::WallclockDurationHelper(&mock_system_state,
+                                             state_variable_key,
+                                             &duration));
+  EXPECT_EQ(duration.InSeconds(), 0);
+  EXPECT_TRUE(utils::WallclockDurationHelper(&mock_system_state,
+                                             state_variable_key,
+                                             &duration));
+  EXPECT_EQ(duration.InSeconds(), 0);
+
+  // Advance the clock one second, then we should get 1 sec on the
+  // next call and 0 sec on the subsequent call.
+  fake_clock.SetWallclockTime(base::Time::FromInternalValue(2000000));
+  EXPECT_TRUE(utils::WallclockDurationHelper(&mock_system_state,
+                                             state_variable_key,
+                                             &duration));
+  EXPECT_EQ(duration.InSeconds(), 1);
+  EXPECT_TRUE(utils::WallclockDurationHelper(&mock_system_state,
+                                             state_variable_key,
+                                             &duration));
+  EXPECT_EQ(duration.InSeconds(), 0);
+
+  // Advance clock two seconds and we should get 2 sec and then 0 sec.
+  fake_clock.SetWallclockTime(base::Time::FromInternalValue(4000000));
+  EXPECT_TRUE(utils::WallclockDurationHelper(&mock_system_state,
+                                             state_variable_key,
+                                             &duration));
+  EXPECT_EQ(duration.InSeconds(), 2);
+  EXPECT_TRUE(utils::WallclockDurationHelper(&mock_system_state,
+                                             state_variable_key,
+                                             &duration));
+  EXPECT_EQ(duration.InSeconds(), 0);
+
+  // There's a possibility that the wallclock can go backwards (NTP
+  // adjustments, for example) so check that we properly handle this
+  // case.
+  fake_clock.SetWallclockTime(base::Time::FromInternalValue(3000000));
+  EXPECT_FALSE(utils::WallclockDurationHelper(&mock_system_state,
+                                              state_variable_key,
+                                              &duration));
+  fake_clock.SetWallclockTime(base::Time::FromInternalValue(4000000));
+  EXPECT_TRUE(utils::WallclockDurationHelper(&mock_system_state,
+                                             state_variable_key,
+                                             &duration));
+  EXPECT_EQ(duration.InSeconds(), 1);
+
+  EXPECT_TRUE(utils::RecursiveUnlinkDir(temp_dir));
+}
+
+TEST(UtilsTest, MonotonicDurationHelper) {
+  int64_t storage = 0;
+  MockSystemState mock_system_state;
+  FakeClock fake_clock;
+  base::TimeDelta duration;
+
+  mock_system_state.set_clock(&fake_clock);
+
+  // Initialize monotonic clock to 1 sec.
+  fake_clock.SetMonotonicTime(base::Time::FromInternalValue(1000000));
+
+  // First time called so no previous measurement available.
+  EXPECT_FALSE(utils::MonotonicDurationHelper(&mock_system_state,
+                                              &storage,
+                                              &duration));
+
+  // Next time, we should get zero since the clock didn't advance.
+  EXPECT_TRUE(utils::MonotonicDurationHelper(&mock_system_state,
+                                             &storage,
+                                             &duration));
+  EXPECT_EQ(duration.InSeconds(), 0);
+
+  // We can also call it as many times as we want with it being
+  // considered a failure.
+  EXPECT_TRUE(utils::MonotonicDurationHelper(&mock_system_state,
+                                             &storage,
+                                             &duration));
+  EXPECT_EQ(duration.InSeconds(), 0);
+  EXPECT_TRUE(utils::MonotonicDurationHelper(&mock_system_state,
+                                             &storage,
+                                             &duration));
+  EXPECT_EQ(duration.InSeconds(), 0);
+
+  // Advance the clock one second, then we should get 1 sec on the
+  // next call and 0 sec on the subsequent call.
+  fake_clock.SetMonotonicTime(base::Time::FromInternalValue(2000000));
+  EXPECT_TRUE(utils::MonotonicDurationHelper(&mock_system_state,
+                                             &storage,
+                                             &duration));
+  EXPECT_EQ(duration.InSeconds(), 1);
+  EXPECT_TRUE(utils::MonotonicDurationHelper(&mock_system_state,
+                                             &storage,
+                                             &duration));
+  EXPECT_EQ(duration.InSeconds(), 0);
+
+  // Advance clock two seconds and we should get 2 sec and then 0 sec.
+  fake_clock.SetMonotonicTime(base::Time::FromInternalValue(4000000));
+  EXPECT_TRUE(utils::MonotonicDurationHelper(&mock_system_state,
+                                             &storage,
+                                             &duration));
+  EXPECT_EQ(duration.InSeconds(), 2);
+  EXPECT_TRUE(utils::MonotonicDurationHelper(&mock_system_state,
+                                             &storage,
+                                             &duration));
+  EXPECT_EQ(duration.InSeconds(), 0);
+}
+
 }  // namespace chromeos_update_engine