blob: 0917a0b4c2df6ba1f9c64f022f31957153a81e51 [file] [log] [blame]
// Copyright 2018 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <base/types/cxx23_to_underlying.h>
#include <chromeos/ec/ec_commands.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <metrics/metrics_library_mock.h>
#include "biod/biod_metrics.h"
#include "biod/updater/update_reason.h"
#include "biod/utils.h"
using ::testing::_;
using ::testing::Ge;
using ::testing::Le;
namespace biod {
namespace {
class BiodMetricsTest : public testing::Test {
protected:
BiodMetricsTest() {
biod_metrics_.SetMetricsLibraryForTesting(
std::make_unique<MetricsLibraryMock>());
}
BiodMetricsTest(const BiodMetricsTest&) = delete;
BiodMetricsTest& operator=(const BiodMetricsTest&) = delete;
~BiodMetricsTest() override = default;
MetricsLibraryMock* GetMetricsLibraryMock() {
return static_cast<MetricsLibraryMock*>(
biod_metrics_.metrics_library_for_testing());
}
BiodMetrics biod_metrics_;
};
TEST_F(BiodMetricsTest, SendEnrolledFingerCount) {
const int finger_count = 2;
EXPECT_CALL(*GetMetricsLibraryMock(), SendEnumToUMA(_, finger_count, _))
.Times(1);
biod_metrics_.SendEnrolledFingerCount(finger_count);
}
TEST_F(BiodMetricsTest, SendEnrollmentCapturesCount) {
const int captures_count = 2;
EXPECT_CALL(*GetMetricsLibraryMock(), SendEnumToUMA(_, captures_count, _))
.Times(1);
biod_metrics_.SendEnrolledFingerCount(captures_count);
}
TEST_F(BiodMetricsTest, SendFpUnlockEnabled) {
EXPECT_CALL(*GetMetricsLibraryMock(), SendBoolToUMA(_, true)).Times(1);
EXPECT_CALL(*GetMetricsLibraryMock(), SendBoolToUMA(_, false)).Times(1);
biod_metrics_.SendFpUnlockEnabled(true);
biod_metrics_.SendFpUnlockEnabled(false);
}
TEST_F(BiodMetricsTest, SendFpLatencyStatsOnMatch) {
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kFpMatchDurationCapture, _, _, _, _))
.Times(1);
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kFpMatchDurationMatcher, _, _, _, _))
.Times(1);
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kFpMatchDurationOverall, _, _, _, _))
.Times(1);
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kFpNoMatchDurationCapture, _, _, _, _))
.Times(0);
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kFpNoMatchDurationMatcher, _, _, _, _))
.Times(0);
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kFpNoMatchDurationOverall, _, _, _, _))
.Times(0);
biod_metrics_.SendFpLatencyStats(
true, {.capture_ms = 0, .matcher_ms = 0, .overall_ms = 0});
}
TEST_F(BiodMetricsTest, SendFpLatencyStatsOnNoMatch) {
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kFpMatchDurationCapture, _, _, _, _))
.Times(0);
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kFpMatchDurationMatcher, _, _, _, _))
.Times(0);
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kFpMatchDurationOverall, _, _, _, _))
.Times(0);
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kFpNoMatchDurationCapture, _, _, _, _))
.Times(1);
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kFpNoMatchDurationMatcher, _, _, _, _))
.Times(1);
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kFpNoMatchDurationOverall, _, _, _, _))
.Times(1);
biod_metrics_.SendFpLatencyStats(
false, {.capture_ms = 0, .matcher_ms = 0, .overall_ms = 0});
}
TEST_F(BiodMetricsTest, SendFpLatencyStatsValues) {
constexpr ec::CrosFpDeviceInterface::FpStats stats = {
.capture_ms = 70,
.matcher_ms = 187,
.overall_ms = 223,
};
EXPECT_CALL(*GetMetricsLibraryMock(), SendToUMA(_, stats.capture_ms, _, _, _))
.Times(2);
EXPECT_CALL(*GetMetricsLibraryMock(), SendToUMA(_, stats.matcher_ms, _, _, _))
.Times(2);
EXPECT_CALL(*GetMetricsLibraryMock(), SendToUMA(_, stats.overall_ms, _, _, _))
.Times(2);
biod_metrics_.SendFpLatencyStats(true, stats);
biod_metrics_.SendFpLatencyStats(false, stats);
}
TEST_F(BiodMetricsTest, SendFwUpdaterStatusOnNoUpdate) {
const auto status = BiodMetrics::FwUpdaterStatus::kUnnecessary;
const auto reason = updater::UpdateReason::kNone;
const int overall_ms = 60;
// TODO(b/266077024) Change UMA enum names for kUpdaterStatus if new
// enums are added to avoid data discontinuity, and then use kMaxValue+1
// rather than kMaxValue for 'exclusive_max'.
EXPECT_CALL(*GetMetricsLibraryMock(),
SendEnumToUMA(
metrics::kUpdaterStatus, base::to_underlying(status),
base::to_underlying(BiodMetrics::FwUpdaterStatus::kMaxValue)))
.Times(1);
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kUpdaterDurationNoUpdate, overall_ms,
Le(overall_ms), Ge(overall_ms), _))
.Times(1);
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kUpdaterDurationUpdate, _, _, _, _))
.Times(0);
EXPECT_CALL(
*GetMetricsLibraryMock(),
SendEnumToUMA(metrics::kUpdaterReason, base::to_underlying(reason),
base::to_underlying(updater::UpdateReason::kMaxValue) + 1))
.Times(1);
biod_metrics_.SendFwUpdaterStatus(status, reason, overall_ms);
}
TEST_F(BiodMetricsTest, SendFwUpdaterStatusOnUpdate) {
const auto status = BiodMetrics::FwUpdaterStatus::kFailureUpdateRW;
const auto reason = updater::UpdateReason::kMismatchRWVersion |
updater::UpdateReason::kMismatchROVersion;
const int overall_ms = 40 * 1000;
EXPECT_CALL(*GetMetricsLibraryMock(),
SendEnumToUMA(
metrics::kUpdaterStatus, base::to_underlying(status),
base::to_underlying(BiodMetrics::FwUpdaterStatus::kMaxValue)))
.Times(1);
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kUpdaterDurationNoUpdate, _, _, _, _))
.Times(0);
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kUpdaterDurationUpdate, overall_ms,
Le(overall_ms), Ge(overall_ms), _))
.Times(1);
EXPECT_CALL(
*GetMetricsLibraryMock(),
SendEnumToUMA(metrics::kUpdaterReason, base::to_underlying(reason),
base::to_underlying(updater::UpdateReason::kMaxValue) + 1))
.Times(1);
biod_metrics_.SendFwUpdaterStatus(status, reason, overall_ms);
}
TEST_F(BiodMetricsTest, SendIgnoreMatchEventOnPowerButtonPress) {
EXPECT_CALL(*GetMetricsLibraryMock(), SendBoolToUMA(_, true)).Times(1);
biod_metrics_.SendIgnoreMatchEventOnPowerButtonPress(true);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
EXPECT_CALL(*GetMetricsLibraryMock(), SendBoolToUMA(_, false)).Times(1);
biod_metrics_.SendIgnoreMatchEventOnPowerButtonPress(false);
}
TEST_F(BiodMetricsTest, SendReadPositiveMatchSecretSuccess) {
EXPECT_CALL(*GetMetricsLibraryMock(), SendBoolToUMA(_, true)).Times(1);
biod_metrics_.SendReadPositiveMatchSecretSuccess(true);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
EXPECT_CALL(*GetMetricsLibraryMock(), SendBoolToUMA(_, false)).Times(1);
biod_metrics_.SendReadPositiveMatchSecretSuccess(false);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
}
TEST_F(BiodMetricsTest, SendPositiveMatchSecretCorrect) {
EXPECT_CALL(*GetMetricsLibraryMock(), SendBoolToUMA(_, true)).Times(1);
biod_metrics_.SendPositiveMatchSecretCorrect(true);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
EXPECT_CALL(*GetMetricsLibraryMock(), SendBoolToUMA(_, false)).Times(1);
biod_metrics_.SendPositiveMatchSecretCorrect(false);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
}
TEST_F(BiodMetricsTest, SendResetContextMode) {
constexpr int kExpectedResetSensorEnum = 10;
constexpr int kExpectedMaxEnum = 18;
EXPECT_CALL(*GetMetricsLibraryMock(),
SendEnumToUMA(metrics::kResetContextMode,
kExpectedResetSensorEnum, kExpectedMaxEnum))
.Times(1);
biod_metrics_.SendResetContextMode(
ec::FpMode(ec::FpMode::Mode::kResetSensor));
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
}
TEST_F(BiodMetricsTest, SendDeadPixelCount) {
constexpr int kExpectedNumDead = 5;
constexpr int kExpectedMin = 0;
constexpr int kExpectedMax = 1022;
constexpr int kExpectedNumBuckets = 50;
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kNumDeadPixels, kExpectedNumDead, kExpectedMin,
kExpectedMax, kExpectedNumBuckets))
.Times(1);
biod_metrics_.SendDeadPixelCount(5);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
}
TEST_F(BiodMetricsTest, SendUploadTemplateResult) {
constexpr int kExpectedSuccessEnum = 0;
constexpr int kExpectedInvalidParamEnum = 3;
constexpr int kExpectedUnavailableEnum = 9;
constexpr int kExpectedMinEnum = -1;
constexpr int kExpectedMaxEnum = 20;
constexpr int kExpectedNumBuckets = 22;
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(_, kExpectedSuccessEnum, kExpectedMinEnum,
kExpectedMaxEnum, kExpectedNumBuckets))
.Times(1);
biod_metrics_.SendUploadTemplateResult(EC_RES_SUCCESS);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(_, kExpectedInvalidParamEnum, kExpectedMinEnum,
kExpectedMaxEnum, kExpectedNumBuckets))
.Times(1);
biod_metrics_.SendUploadTemplateResult(EC_RES_INVALID_PARAM);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(_, kExpectedUnavailableEnum, kExpectedMinEnum,
kExpectedMaxEnum, kExpectedNumBuckets))
.Times(1);
biod_metrics_.SendUploadTemplateResult(EC_RES_UNAVAILABLE);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
}
TEST_F(BiodMetricsTest, SendPartialAttemptsBeforeSuccess) {
const int partial_attempts = 2;
EXPECT_CALL(*GetMetricsLibraryMock(), SendEnumToUMA(_, partial_attempts, _))
.Times(1);
biod_metrics_.SendPartialAttemptsBeforeSuccess(partial_attempts);
}
TEST_F(BiodMetricsTest, SendFpSensorErrorNoIrq) {
EXPECT_CALL(*GetMetricsLibraryMock(),
SendBoolToUMA(metrics::kFpSensorErrorNoIrq, true))
.Times(1);
biod_metrics_.SendFpSensorErrorNoIrq(true);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
EXPECT_CALL(*GetMetricsLibraryMock(),
SendBoolToUMA(metrics::kFpSensorErrorNoIrq, false))
.Times(1);
biod_metrics_.SendFpSensorErrorNoIrq(false);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
}
TEST_F(BiodMetricsTest, SendFpSensorErrorSpiCommunication) {
EXPECT_CALL(*GetMetricsLibraryMock(),
SendBoolToUMA(metrics::kFpSensorErrorSpiCommunication, true))
.Times(1);
biod_metrics_.SendFpSensorErrorSpiCommunication(true);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
EXPECT_CALL(*GetMetricsLibraryMock(),
SendBoolToUMA(metrics::kFpSensorErrorSpiCommunication, false))
.Times(1);
biod_metrics_.SendFpSensorErrorSpiCommunication(false);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
}
TEST_F(BiodMetricsTest, SendFpSensorErrorBadHardwareID) {
EXPECT_CALL(*GetMetricsLibraryMock(),
SendBoolToUMA(metrics::kFpSensorErrorBadHardwareID, true))
.Times(1);
biod_metrics_.SendFpSensorErrorBadHardwareID(true);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
EXPECT_CALL(*GetMetricsLibraryMock(),
SendBoolToUMA(metrics::kFpSensorErrorBadHardwareID, false))
.Times(1);
biod_metrics_.SendFpSensorErrorBadHardwareID(false);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
}
TEST_F(BiodMetricsTest, SendFpSensorErrorInitializationFailure) {
EXPECT_CALL(*GetMetricsLibraryMock(),
SendBoolToUMA(metrics::kFpSensorErrorInitializationFailure, true))
.Times(1);
biod_metrics_.SendFpSensorErrorInitializationFailure(true);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
EXPECT_CALL(
*GetMetricsLibraryMock(),
SendBoolToUMA(metrics::kFpSensorErrorInitializationFailure, false))
.Times(1);
biod_metrics_.SendFpSensorErrorInitializationFailure(false);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
}
TEST_F(BiodMetricsTest, SendSessionRetirevePrimarySessionResult) {
const auto result =
BiodMetrics::RetrievePrimarySessionResult::kErrorDBusNoReply;
EXPECT_CALL(*GetMetricsLibraryMock(),
SendEnumToUMA(metrics::kSessionRetrievePrimarySessionResult,
base::to_underlying(result), 7))
.Times(1);
biod_metrics_.SendSessionRetrievePrimarySessionResult(result);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
}
TEST_F(BiodMetricsTest, SendSessionRetrievePrimarySessionDuration) {
const int ms = 9999;
EXPECT_CALL(*GetMetricsLibraryMock(),
SendToUMA(metrics::kSessionRetrievePrimarySessionDuration, ms, 0,
25000, 50))
.Times(1);
biod_metrics_.SendSessionRetrievePrimarySessionDuration(ms);
testing::Mock::VerifyAndClearExpectations(GetMetricsLibraryMock());
}
} // namespace
} // namespace biod