update_engine: Add UMA stats for rollback
Adding the following UMA stats:
- UpdateEngine.Check.TargetVersion: first section of the Chrome OS
target version set by device policy. Sent during update checks if
target version policy is set.
- UpdateEngine.Check.RollbackTargetVersion: first section of the
Chrome OS target version if rollback is also allowed. Sent during
update checks if both policies are set.
- UpdateEngine.EnterpriseRollback.Success: first section of the
Chrome OS version to which rollback succeeded. Sent after
successful installation of the rollback image.
- UpdateEngine.EnterpriseRollback.Failure: first section of the
Chrome OS version to which rollback failed. Sent after
installation of the rollback image failed.
Chromium CL of the new histograms: crrev.com/c/1069129
BUG=chromium:843622
TEST='cros_run_unit_tests --board=caroline --packages update_engine'
Change-Id: I0b76fa286498ae0a1830a90034734ed9aa5efd3d
Reviewed-on: https://chromium-review.googlesource.com/1062033
Commit-Ready: ChromeOS CL Exonerator Bot <[email protected]>
Tested-by: Marton Hunyady <[email protected]>
Reviewed-by: Amin Hassani <[email protected]>
Reviewed-by: Jesse Doherty <[email protected]>
diff --git a/common/utils.cc b/common/utils.cc
index f651823..68cad51 100644
--- a/common/utils.cc
+++ b/common/utils.cc
@@ -291,7 +291,10 @@
return true;
}
-bool PReadAll(const FileDescriptorPtr& fd, void* buf, size_t count, off_t offset,
+bool PReadAll(const FileDescriptorPtr& fd,
+ void* buf,
+ size_t count,
+ off_t offset,
ssize_t* out_bytes_read) {
TEST_AND_RETURN_FALSE_ERRNO(fd->Seek(offset, SEEK_SET) !=
static_cast<off_t>(-1));
@@ -1067,6 +1070,18 @@
return true;
}
+int VersionPrefix(const std::string& version) {
+ if (version.empty()) {
+ return 0;
+ }
+ vector<string> tokens = base::SplitString(
+ version, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
+ int value;
+ if (tokens.empty() || !base::StringToInt(tokens[0], &value))
+ return -1; // Target version is invalid.
+ return value;
+}
+
} // namespace utils
} // namespace chromeos_update_engine
diff --git a/common/utils.h b/common/utils.h
index c102a16..8db0cf8 100644
--- a/common/utils.h
+++ b/common/utils.h
@@ -317,6 +317,11 @@
// reboot. Returns whether it succeeded getting the boot_id.
bool GetBootId(std::string* boot_id);
+// Returns the integer value of the first section of |version|. E.g. for
+// "10575.39." returns 10575. Returns 0 if |version| is empty, returns -1 if
+// first section of |version| is invalid (e.g. not a number).
+int VersionPrefix(const std::string& version);
+
} // namespace utils
diff --git a/common/utils_unittest.cc b/common/utils_unittest.cc
index 033702b..16fa481 100644
--- a/common/utils_unittest.cc
+++ b/common/utils_unittest.cc
@@ -511,4 +511,16 @@
EXPECT_FALSE(utils::IsMountpoint(file.value()));
}
+TEST(UtilsTest, VersionPrefix) {
+ EXPECT_EQ(10575, utils::VersionPrefix("10575.39."));
+ EXPECT_EQ(10575, utils::VersionPrefix("10575.39"));
+ EXPECT_EQ(10575, utils::VersionPrefix("10575.x"));
+ EXPECT_EQ(10575, utils::VersionPrefix("10575."));
+ EXPECT_EQ(10575, utils::VersionPrefix("10575"));
+ EXPECT_EQ(0, utils::VersionPrefix(""));
+ EXPECT_EQ(-1, utils::VersionPrefix("x"));
+ EXPECT_EQ(-1, utils::VersionPrefix("1x"));
+ EXPECT_EQ(-1, utils::VersionPrefix("x.1"));
+}
+
} // namespace chromeos_update_engine
diff --git a/metrics_reporter_android.h b/metrics_reporter_android.h
index 44f770e..06ad8c5 100644
--- a/metrics_reporter_android.h
+++ b/metrics_reporter_android.h
@@ -17,6 +17,8 @@
#ifndef UPDATE_ENGINE_METRICS_REPORTER_ANDROID_H_
#define UPDATE_ENGINE_METRICS_REPORTER_ANDROID_H_
+#include <string>
+
#include "update_engine/common/error_code.h"
#include "update_engine/metrics_constants.h"
#include "update_engine/metrics_reporter_interface.h"
@@ -33,6 +35,9 @@
void ReportRollbackMetrics(metrics::RollbackResult result) override {}
+ void ReportEnterpriseRollbackMetrics(
+ bool success, const std::string& rollback_version) override {}
+
void ReportDailyMetrics(base::TimeDelta os_age) override {}
void ReportUpdateCheckMetrics(
diff --git a/metrics_reporter_interface.h b/metrics_reporter_interface.h
index 13f5a54..8a7c864 100644
--- a/metrics_reporter_interface.h
+++ b/metrics_reporter_interface.h
@@ -18,6 +18,7 @@
#define UPDATE_ENGINE_METRICS_REPORTER_INTERFACE_H_
#include <memory>
+#include <string>
#include <base/time/time.h>
@@ -43,12 +44,20 @@
virtual void Initialize() = 0;
- // Helper function to report metrics related to rollback. The
+ // Helper function to report metrics related to user-initiated rollback. The
// following metrics are reported:
//
// |kMetricRollbackResult|
virtual void ReportRollbackMetrics(metrics::RollbackResult result) = 0;
+ // Helper function to report metrics related to enterprise (admin-initiated)
+ // rollback:
+ //
+ // |kMetricEnterpriseRollbackSuccess|
+ // |kMetricEnterpriseRollbackFailure|
+ virtual void ReportEnterpriseRollbackMetrics(
+ bool success, const std::string& rollback_version) = 0;
+
// Helper function to report metrics reported once a day. The
// following metrics are reported:
//
@@ -64,6 +73,8 @@
// |kMetricCheckDownloadErrorCode|
// |kMetricCheckTimeSinceLastCheckMinutes|
// |kMetricCheckTimeSinceLastCheckUptimeMinutes|
+ // |kMetricCheckTargetVersion|
+ // |kMetricCheckRollbackTargetVersion|
//
// The |kMetricCheckResult| metric will only be reported if |result|
// is not |kUnset|.
@@ -78,6 +89,10 @@
// |kMetricCheckTimeSinceLastCheckUptimeMinutes| metrics are
// automatically reported and calculated by maintaining persistent
// and process-local state variables.
+ //
+ // |kMetricCheckTargetVersion| reports the first section of the target version
+ // if it's set, |kMetricCheckRollbackTargetVersion| reports the same, but only
+ // if rollback is also allowed using enterprise policy.
virtual void ReportUpdateCheckMetrics(
SystemState* system_state,
metrics::CheckResult result,
diff --git a/metrics_reporter_omaha.cc b/metrics_reporter_omaha.cc
index 9c81088..0a2b674 100644
--- a/metrics_reporter_omaha.cc
+++ b/metrics_reporter_omaha.cc
@@ -17,9 +17,9 @@
#include "update_engine/metrics_reporter_omaha.h"
#include <memory>
-#include <string>
#include <base/logging.h>
+#include <base/strings/string_number_conversions.h>
#include <metrics/metrics_library.h>
#include "update_engine/common/clock_interface.h"
@@ -27,6 +27,7 @@
#include "update_engine/common/prefs_interface.h"
#include "update_engine/common/utils.h"
#include "update_engine/metrics_utils.h"
+#include "update_engine/omaha_request_params.h"
#include "update_engine/system_state.h"
using std::string;
@@ -43,6 +44,9 @@
"UpdateEngine.Check.DownloadErrorCode";
const char kMetricCheckReaction[] = "UpdateEngine.Check.Reaction";
const char kMetricCheckResult[] = "UpdateEngine.Check.Result";
+const char kMetricCheckTargetVersion[] = "UpdateEngine.Check.TargetVersion";
+const char kMetricCheckRollbackTargetVersion[] =
+ "UpdateEngine.Check.RollbackTargetVersion";
const char kMetricCheckTimeSinceLastCheckMinutes[] =
"UpdateEngine.Check.TimeSinceLastCheckMinutes";
const char kMetricCheckTimeSinceLastCheckUptimeMinutes[] =
@@ -100,6 +104,12 @@
// UpdateEngine.Rollback.* metric.
const char kMetricRollbackResult[] = "UpdateEngine.Rollback.Result";
+// UpdateEngine.EnterpriseRollback.* metrics.
+const char kMetricEnterpriseRollbackFailure[] =
+ "UpdateEngine.EnterpriseRollback.Failure";
+const char kMetricEnterpriseRollbackSuccess[] =
+ "UpdateEngine.EnterpriseRollback.Success";
+
// UpdateEngine.CertificateCheck.* metrics.
const char kMetricCertificateCheckUpdateCheck[] =
"UpdateEngine.CertificateCheck.UpdateCheck";
@@ -194,6 +204,25 @@
30 * 24 * 60, // max: 30 days
50); // num_buckets
}
+
+ // First section of target version specified for the update.
+ if (system_state && system_state->request_params()) {
+ string target_version =
+ system_state->request_params()->target_version_prefix();
+ value = utils::VersionPrefix(target_version);
+ if (value != 0) {
+ metric = metrics::kMetricCheckTargetVersion;
+ LOG(INFO) << "Sending " << value << " for metric " << metric
+ << " (sparse)";
+ metrics_lib_->SendSparseToUMA(metric, value);
+ if (system_state->request_params()->rollback_allowed()) {
+ metric = metrics::kMetricCheckRollbackTargetVersion;
+ LOG(INFO) << "Sending " << value << " for metric " << metric
+ << " (sparse)";
+ metrics_lib_->SendSparseToUMA(metric, value);
+ }
+ }
+ }
}
void MetricsReporterOmaha::ReportAbnormallyTerminatedUpdateAttemptMetrics() {
@@ -478,6 +507,16 @@
metric, value, static_cast<int>(metrics::RollbackResult::kNumConstants));
}
+void MetricsReporterOmaha::ReportEnterpriseRollbackMetrics(
+ bool success, const string& rollback_version) {
+ int value = utils::VersionPrefix(rollback_version);
+ string metric = metrics::kMetricEnterpriseRollbackSuccess;
+ if (!success)
+ metric = metrics::kMetricEnterpriseRollbackFailure;
+ LOG(INFO) << "Sending " << value << " for metric " << metric;
+ metrics_lib_->SendSparseToUMA(metric, value);
+}
+
void MetricsReporterOmaha::ReportCertificateCheckMetrics(
ServerToCheck server_to_check, CertificateCheckResult result) {
string metric;
diff --git a/metrics_reporter_omaha.h b/metrics_reporter_omaha.h
index 344cff8..97b283d 100644
--- a/metrics_reporter_omaha.h
+++ b/metrics_reporter_omaha.h
@@ -18,6 +18,7 @@
#define UPDATE_ENGINE_METRICS_REPORTER_OMAHA_H_
#include <memory>
+#include <string>
#include <base/time/time.h>
#include <metrics/metrics_library.h>
@@ -42,6 +43,8 @@
extern const char kMetricCheckDownloadErrorCode[];
extern const char kMetricCheckReaction[];
extern const char kMetricCheckResult[];
+extern const char kMetricCheckTargetVersion[];
+extern const char kMetricCheckRollbackTargetVersion[];
extern const char kMetricCheckTimeSinceLastCheckMinutes[];
extern const char kMetricCheckTimeSinceLastCheckUptimeMinutes[];
@@ -76,6 +79,10 @@
// UpdateEngine.Rollback.* metric.
extern const char kMetricRollbackResult[];
+// UpdateEngine.EnterpriseRollback.* metrics.
+extern const char kMetricEnterpriseRollbackFailure[];
+extern const char kMetricEnterpriseRollbackSuccess[];
+
// UpdateEngine.CertificateCheck.* metrics.
extern const char kMetricCertificateCheckUpdateCheck[];
extern const char kMetricCertificateCheckDownload[];
@@ -97,6 +104,9 @@
void ReportRollbackMetrics(metrics::RollbackResult result) override;
+ void ReportEnterpriseRollbackMetrics(
+ bool success, const std::string& rollback_version) override;
+
void ReportDailyMetrics(base::TimeDelta os_age) override;
void ReportUpdateCheckMetrics(
diff --git a/metrics_reporter_omaha_unittest.cc b/metrics_reporter_omaha_unittest.cc
index 76e33c6..c7641c0 100644
--- a/metrics_reporter_omaha_unittest.cc
+++ b/metrics_reporter_omaha_unittest.cc
@@ -29,8 +29,9 @@
#include "update_engine/fake_system_state.h"
using base::TimeDelta;
-using testing::AnyNumber;
using testing::_;
+using testing::AnyNumber;
+using testing::Return;
namespace chromeos_update_engine {
class MetricsReporterOmahaTest : public ::testing::Test {
@@ -85,6 +86,14 @@
static_cast<int>(error_code)))
.Times(2);
+ // Not pinned nor rollback
+ EXPECT_CALL(*mock_metrics_lib_,
+ SendSparseToUMA(metrics::kMetricCheckTargetVersion, _))
+ .Times(0);
+ EXPECT_CALL(*mock_metrics_lib_,
+ SendSparseToUMA(metrics::kMetricCheckRollbackTargetVersion, _))
+ .Times(0);
+
EXPECT_CALL(
*mock_metrics_lib_,
SendToUMA(metrics::kMetricCheckTimeSinceLastCheckMinutes, 1, _, _, _))
@@ -101,6 +110,62 @@
// Advance the clock by 1 minute and report the same metrics again.
fake_clock.SetWallclockTime(base::Time::FromInternalValue(61000000));
fake_clock.SetMonotonicTime(base::Time::FromInternalValue(61000000));
+ // Allow rollback
+ reporter_.ReportUpdateCheckMetrics(
+ &fake_system_state, result, reaction, error_code);
+}
+
+TEST_F(MetricsReporterOmahaTest, ReportUpdateCheckMetricsPinned) {
+ FakeSystemState fake_system_state;
+
+ OmahaRequestParams params(&fake_system_state);
+ params.set_target_version_prefix("10575.");
+ params.set_rollback_allowed(false);
+ fake_system_state.set_request_params(¶ms);
+
+ metrics::CheckResult result = metrics::CheckResult::kUpdateAvailable;
+ metrics::CheckReaction reaction = metrics::CheckReaction::kIgnored;
+ metrics::DownloadErrorCode error_code =
+ metrics::DownloadErrorCode::kHttpStatus200;
+
+ EXPECT_CALL(*mock_metrics_lib_,
+ SendSparseToUMA(metrics::kMetricCheckDownloadErrorCode, _));
+ // Target version set, but not a rollback.
+ EXPECT_CALL(*mock_metrics_lib_,
+ SendSparseToUMA(metrics::kMetricCheckTargetVersion, 10575))
+ .Times(1);
+ EXPECT_CALL(*mock_metrics_lib_,
+ SendSparseToUMA(metrics::kMetricCheckRollbackTargetVersion, _))
+ .Times(0);
+
+ reporter_.ReportUpdateCheckMetrics(
+ &fake_system_state, result, reaction, error_code);
+}
+
+TEST_F(MetricsReporterOmahaTest, ReportUpdateCheckMetricsRollback) {
+ FakeSystemState fake_system_state;
+
+ OmahaRequestParams params(&fake_system_state);
+ params.set_target_version_prefix("10575.");
+ params.set_rollback_allowed(true);
+ fake_system_state.set_request_params(¶ms);
+
+ metrics::CheckResult result = metrics::CheckResult::kUpdateAvailable;
+ metrics::CheckReaction reaction = metrics::CheckReaction::kIgnored;
+ metrics::DownloadErrorCode error_code =
+ metrics::DownloadErrorCode::kHttpStatus200;
+
+ EXPECT_CALL(*mock_metrics_lib_,
+ SendSparseToUMA(metrics::kMetricCheckDownloadErrorCode, _));
+ // Rollback.
+ EXPECT_CALL(*mock_metrics_lib_,
+ SendSparseToUMA(metrics::kMetricCheckTargetVersion, 10575))
+ .Times(1);
+ EXPECT_CALL(
+ *mock_metrics_lib_,
+ SendSparseToUMA(metrics::kMetricCheckRollbackTargetVersion, 10575))
+ .Times(1);
+
reporter_.ReportUpdateCheckMetrics(
&fake_system_state, result, reaction, error_code);
}
@@ -347,6 +412,18 @@
reporter_.ReportRollbackMetrics(result);
}
+TEST_F(MetricsReporterOmahaTest, ReportEnterpriseRollbackMetrics) {
+ EXPECT_CALL(*mock_metrics_lib_,
+ SendSparseToUMA(metrics::kMetricEnterpriseRollbackSuccess, 10575))
+ .Times(1);
+ EXPECT_CALL(*mock_metrics_lib_,
+ SendSparseToUMA(metrics::kMetricEnterpriseRollbackFailure, 10323))
+ .Times(1);
+
+ reporter_.ReportEnterpriseRollbackMetrics(/*success=*/true, "10575.39.2");
+ reporter_.ReportEnterpriseRollbackMetrics(/*success=*/false, "10323.67.7");
+}
+
TEST_F(MetricsReporterOmahaTest, ReportCertificateCheckMetrics) {
ServerToCheck server_to_check = ServerToCheck::kUpdate;
CertificateCheckResult result = CertificateCheckResult::kValid;
diff --git a/metrics_reporter_stub.h b/metrics_reporter_stub.h
index d0f75ab..8b559f3 100644
--- a/metrics_reporter_stub.h
+++ b/metrics_reporter_stub.h
@@ -17,6 +17,8 @@
#ifndef UPDATE_ENGINE_METRICS_REPORTER_STUB_H_
#define UPDATE_ENGINE_METRICS_REPORTER_STUB_H_
+#include <string>
+
#include "update_engine/common/error_code.h"
#include "update_engine/metrics_constants.h"
#include "update_engine/metrics_reporter_interface.h"
@@ -33,6 +35,9 @@
void ReportRollbackMetrics(metrics::RollbackResult result) override {}
+ void ReportEnterpriseRollbackMetrics(
+ bool success, const std::string& rollback_version) override {}
+
void ReportDailyMetrics(base::TimeDelta os_age) override {}
void ReportUpdateCheckMetrics(
diff --git a/mock_metrics_reporter.h b/mock_metrics_reporter.h
index a4e0a12..d080ce8 100644
--- a/mock_metrics_reporter.h
+++ b/mock_metrics_reporter.h
@@ -17,6 +17,8 @@
#ifndef UPDATE_ENGINE_MOCK_METRICS_REPORTER_H
#define UPDATE_ENGINE_MOCK_METRICS_REPORTER_H
+#include <string>
+
#include <gmock/gmock.h>
#include "update_engine/metrics_reporter_interface.h"
@@ -29,6 +31,9 @@
MOCK_METHOD1(ReportRollbackMetrics, void(metrics::RollbackResult result));
+ MOCK_METHOD2(ReportEnterpriseRollbackMetrics,
+ void(bool success, const std::string& rollback_version));
+
MOCK_METHOD1(ReportDailyMetrics, void(base::TimeDelta os_age));
MOCK_METHOD4(ReportUpdateCheckMetrics,
diff --git a/mock_omaha_request_params.h b/mock_omaha_request_params.h
index 6d8d3d8..2fe5e01 100644
--- a/mock_omaha_request_params.h
+++ b/mock_omaha_request_params.h
@@ -50,6 +50,7 @@
MOCK_METHOD3(SetTargetChannel, bool(const std::string& channel,
bool is_powerwash_allowed,
std::string* error));
+ MOCK_CONST_METHOD0(target_version_prefix, std::string(void));
MOCK_METHOD0(UpdateDownloadChannel, void(void));
MOCK_CONST_METHOD0(IsUpdateUrlOfficial, bool(void));
MOCK_CONST_METHOD0(ShouldPowerwash, bool(void));
diff --git a/omaha_response_handler_action.h b/omaha_response_handler_action.h
index e868b53..f5cc1a6 100644
--- a/omaha_response_handler_action.h
+++ b/omaha_response_handler_action.h
@@ -89,6 +89,10 @@
friend class OmahaResponseHandlerActionTest;
FRIEND_TEST(UpdateAttempterTest, CreatePendingErrorEventResumedTest);
+ FRIEND_TEST(UpdateAttempterTest, RollbackMetricsNotRollbackFailure);
+ FRIEND_TEST(UpdateAttempterTest, RollbackMetricsNotRollbackSuccess);
+ FRIEND_TEST(UpdateAttempterTest, RollbackMetricsRollbackFailure);
+ FRIEND_TEST(UpdateAttempterTest, RollbackMetricsRollbackSuccess);
FRIEND_TEST(UpdateAttempterTest, SetRollbackHappenedNotRollback);
FRIEND_TEST(UpdateAttempterTest, SetRollbackHappenedRollback);
FRIEND_TEST(UpdateAttempterTest, UpdateDeferredByPolicyTest);
diff --git a/update_attempter.cc b/update_attempter.cc
index 4a71e4d..67391a3 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -1007,6 +1007,8 @@
// over the following powerwash.
if (install_plan.is_rollback) {
system_state_->payload_state()->SetRollbackHappened(true);
+ system_state_->metrics_reporter()->ReportEnterpriseRollbackMetrics(
+ /*success=*/true, install_plan.version);
}
// Expect to reboot into the new version to send the proper metric during
@@ -1377,6 +1379,15 @@
LOG(ERROR) << "Update failed.";
system_state_->payload_state()->UpdateFailed(error_event_->error_code);
+ // Send metrics if it was a rollback.
+ if (response_handler_action_) {
+ const InstallPlan& install_plan = response_handler_action_->install_plan();
+ if (install_plan.is_rollback) {
+ system_state_->metrics_reporter()->ReportEnterpriseRollbackMetrics(
+ /*success=*/false, install_plan.version);
+ }
+ }
+
// Send it to Omaha.
LOG(INFO) << "Reporting the error event";
shared_ptr<OmahaRequestAction> error_event_action(
diff --git a/update_attempter.h b/update_attempter.h
index a3e2b30..9504f88 100644
--- a/update_attempter.h
+++ b/update_attempter.h
@@ -270,6 +270,10 @@
FRIEND_TEST(UpdateAttempterTest, RollbackNotAllowed);
FRIEND_TEST(UpdateAttempterTest, RollbackAllowed);
FRIEND_TEST(UpdateAttempterTest, RollbackAllowedSetAndReset);
+ FRIEND_TEST(UpdateAttempterTest, RollbackMetricsNotRollbackFailure);
+ FRIEND_TEST(UpdateAttempterTest, RollbackMetricsNotRollbackSuccess);
+ FRIEND_TEST(UpdateAttempterTest, RollbackMetricsRollbackFailure);
+ FRIEND_TEST(UpdateAttempterTest, RollbackMetricsRollbackSuccess);
FRIEND_TEST(UpdateAttempterTest, ScheduleErrorEventActionNoEventTest);
FRIEND_TEST(UpdateAttempterTest, ScheduleErrorEventActionTest);
FRIEND_TEST(UpdateAttempterTest, SetRollbackHappenedNotRollback);
diff --git a/update_attempter_unittest.cc b/update_attempter_unittest.cc
index 3936404..29c1971 100644
--- a/update_attempter_unittest.cc
+++ b/update_attempter_unittest.cc
@@ -74,6 +74,8 @@
namespace chromeos_update_engine {
+const char kRollbackVersion[] = "10575.39.2";
+
// Test a subclass rather than the main class directly so that we can mock out
// methods within the class. There're explicit unit tests for the mocked out
// methods.
@@ -1267,4 +1269,60 @@
attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
}
+TEST_F(UpdateAttempterTest, RollbackMetricsRollbackSuccess) {
+ OmahaResponseHandlerAction* response_action =
+ new OmahaResponseHandlerAction(&fake_system_state_);
+ response_action->install_plan_.is_rollback = true;
+ response_action->install_plan_.version = kRollbackVersion;
+ attempter_.response_handler_action_.reset(response_action);
+
+ EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
+ ReportEnterpriseRollbackMetrics(true, kRollbackVersion))
+ .Times(1);
+ attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
+}
+
+TEST_F(UpdateAttempterTest, RollbackMetricsNotRollbackSuccess) {
+ OmahaResponseHandlerAction* response_action =
+ new OmahaResponseHandlerAction(&fake_system_state_);
+ response_action->install_plan_.is_rollback = false;
+ response_action->install_plan_.version = kRollbackVersion;
+ attempter_.response_handler_action_.reset(response_action);
+
+ EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
+ ReportEnterpriseRollbackMetrics(_, _))
+ .Times(0);
+ attempter_.ProcessingDone(nullptr, ErrorCode::kSuccess);
+}
+
+TEST_F(UpdateAttempterTest, RollbackMetricsRollbackFailure) {
+ OmahaResponseHandlerAction* response_action =
+ new OmahaResponseHandlerAction(&fake_system_state_);
+ response_action->install_plan_.is_rollback = true;
+ response_action->install_plan_.version = kRollbackVersion;
+ attempter_.response_handler_action_.reset(response_action);
+
+ EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
+ ReportEnterpriseRollbackMetrics(false, kRollbackVersion))
+ .Times(1);
+ MockAction action;
+ attempter_.CreatePendingErrorEvent(&action, ErrorCode::kRollbackNotPossible);
+ attempter_.ProcessingDone(nullptr, ErrorCode::kRollbackNotPossible);
+}
+
+TEST_F(UpdateAttempterTest, RollbackMetricsNotRollbackFailure) {
+ OmahaResponseHandlerAction* response_action =
+ new OmahaResponseHandlerAction(&fake_system_state_);
+ response_action->install_plan_.is_rollback = false;
+ response_action->install_plan_.version = kRollbackVersion;
+ attempter_.response_handler_action_.reset(response_action);
+
+ EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
+ ReportEnterpriseRollbackMetrics(_, _))
+ .Times(0);
+ MockAction action;
+ attempter_.CreatePendingErrorEvent(&action, ErrorCode::kRollbackNotPossible);
+ attempter_.ProcessingDone(nullptr, ErrorCode::kRollbackNotPossible);
+}
+
} // namespace chromeos_update_engine