blob: 2ed9d624be4f70ac0f3cada634853beb2aa5b369 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/ash/components/network/metrics/cellular_network_metrics_logger.h"
#include <memory>
#include "ash/constants/ash_features.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/values.h"
#include "chromeos/ash/components/dbus/shill/shill_service_client.h"
#include "chromeos/ash/components/network/metrics/connection_results.h"
#include "chromeos/ash/components/network/network_handler_test_helper.h"
#include "chromeos/ash/components/network/network_metadata_store.h"
#include "chromeos/ash/components/network/network_state_handler.h"
#include "components/onc/onc_constants.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace ash {
namespace {
const char kCellularGuid[] = "test_guid";
const char kCellularServicePath[] = "/service/network";
const char kCellularName[] = "network_name";
const char kWifiGuid[] = "test_guid2";
const char kWifiServicePath[] = "/service/network2";
const char kWifiName[] = "network_name2";
struct ApnHistogramCounts {
size_t custom_apns_total_hist_count = 0u;
size_t enabled_custom_apns_total_hist_count = 0u;
size_t disabled_custom_apns_total_hist_count = 0u;
size_t no_enabled_custom_apns = 0u;
size_t has_enabled_custom_apns = 0u;
};
} // namespace
class CellularNetworkMetricsLoggerTest : public testing::Test {
protected:
CellularNetworkMetricsLoggerTest() = default;
CellularNetworkMetricsLoggerTest(const CellularNetworkMetricsLoggerTest&) =
delete;
CellularNetworkMetricsLoggerTest& operator=(
const CellularNetworkMetricsLoggerTest&) = delete;
~CellularNetworkMetricsLoggerTest() override = default;
void SetUp() override {
network_handler_test_helper_ = std::make_unique<NetworkHandlerTestHelper>();
histogram_tester_ = std::make_unique<base::HistogramTester>();
shill_service_client_ = ShillServiceClient::Get()->GetTestInterface();
shill_service_client_->ClearServices();
base::RunLoop().RunUntilIdle();
network_handler_test_helper_->RegisterPrefs(profile_prefs_.registry(),
local_state_.registry());
network_handler_test_helper_->InitializePrefs(&profile_prefs_,
&local_state_);
}
void TearDown() override {
shill_service_client_->ClearServices();
network_handler_test_helper_.reset();
}
void SetUpGenericCellularNetwork() {
shill_service_client_->AddService(kCellularServicePath, kCellularGuid,
kCellularName, shill::kTypeCellular,
shill::kStateIdle,
/*visible=*/true);
base::RunLoop().RunUntilIdle();
}
void SetUpGenericWifiNetwork() {
shill_service_client_->AddService(kWifiServicePath, kWifiGuid, kWifiName,
shill::kTypeWifi, shill::kStateIdle,
/*visible=*/true);
base::RunLoop().RunUntilIdle();
}
void SetShillState(const std::string& service_path,
const std::string& shill_state) {
shill_service_client_->SetServiceProperty(
service_path, shill::kStateProperty, base::Value(shill_state));
base::RunLoop().RunUntilIdle();
}
void SetShillError(const std::string& service_path,
const std::string& shill_error) {
shill_service_client_->SetServiceProperty(
service_path, shill::kErrorProperty, base::Value(shill_error));
base::RunLoop().RunUntilIdle();
}
void AssertHistogramsTotalCount(const ApnHistogramCounts& counts) {
histogram_tester_->ExpectTotalCount(
CellularNetworkMetricsLogger::kCustomApnsCountHistogram,
counts.custom_apns_total_hist_count);
histogram_tester_->ExpectTotalCount(
CellularNetworkMetricsLogger::kCustomApnsEnabledCountHistogram,
counts.enabled_custom_apns_total_hist_count);
histogram_tester_->ExpectTotalCount(
CellularNetworkMetricsLogger::kCustomApnsDisabledCountHistogram,
counts.disabled_custom_apns_total_hist_count);
histogram_tester_->ExpectTotalCount(
CellularNetworkMetricsLogger::
kConnectResultNoEnabledCustomApnsAllHistogram,
counts.no_enabled_custom_apns);
histogram_tester_->ExpectTotalCount(
CellularNetworkMetricsLogger::
kConnectResultHasEnabledCustomApnsAllHistogram,
counts.has_enabled_custom_apns);
}
void AssertCustomApnsStatusBucketCount(
ash::ShillConnectResult no_enabled_custom_apns_bucket,
size_t no_enabled_bucket_count,
ash::ShillConnectResult has_enabled_custom_apns_bucket,
size_t has_enabled_bucket_count) {
histogram_tester_->ExpectBucketCount(
CellularNetworkMetricsLogger::
kConnectResultNoEnabledCustomApnsAllHistogram,
no_enabled_custom_apns_bucket, no_enabled_bucket_count);
histogram_tester_->ExpectBucketCount(
CellularNetworkMetricsLogger::
kConnectResultHasEnabledCustomApnsAllHistogram,
has_enabled_custom_apns_bucket, has_enabled_bucket_count);
}
std::unique_ptr<base::HistogramTester> histogram_tester_;
private:
base::test::TaskEnvironment task_environment_;
std::unique_ptr<NetworkHandlerTestHelper> network_handler_test_helper_;
ShillServiceClient::TestInterface* shill_service_client_;
TestingPrefServiceSimple profile_prefs_;
TestingPrefServiceSimple local_state_;
};
TEST_F(CellularNetworkMetricsLoggerTest, AutoStatusTransitionsRevampEnabled) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(ash::features::kApnRevamp);
SetUpGenericCellularNetwork();
ApnHistogramCounts counts;
SetShillState(kCellularServicePath, shill::kStateIdle);
AssertHistogramsTotalCount(counts);
SetShillState(kCellularServicePath, shill::kStateOnline);
counts.custom_apns_total_hist_count++;
counts.no_enabled_custom_apns++;
AssertHistogramsTotalCount(counts);
AssertCustomApnsStatusBucketCount(
ShillConnectResult::kSuccess, /*no_enabled_bucket_count=*/1,
ShillConnectResult::kSuccess, /*has_enabled_bucket_count=*/0);
histogram_tester_->ExpectBucketCount(
CellularNetworkMetricsLogger::kCustomApnsCountHistogram,
/*sample=*/0, /*expected_count=*/1);
// Add an APN to the network.
base::Value::Dict apn1;
apn1.Set(::onc::cellular_apn::kAccessPointName, "apn1");
apn1.Set(::onc::cellular_apn::kState, ::onc::cellular_apn::kStateEnabled);
base::Value::List custom_apn_list;
custom_apn_list.Append(std::move(apn1));
NetworkHandler::Get()->network_metadata_store()->SetCustomApnList(
kCellularGuid, custom_apn_list.Clone());
SetShillState(kCellularServicePath, shill::kStateAssociation);
AssertHistogramsTotalCount(counts);
SetShillState(kCellularServicePath, shill::kStateOnline);
counts.custom_apns_total_hist_count++;
counts.has_enabled_custom_apns++;
counts.enabled_custom_apns_total_hist_count++;
counts.disabled_custom_apns_total_hist_count++;
AssertHistogramsTotalCount(counts);
AssertCustomApnsStatusBucketCount(
ShillConnectResult::kSuccess, /*no_enabled_bucket_count=*/1,
ShillConnectResult::kSuccess, /*has_enabled_bucket_count=*/1);
histogram_tester_->ExpectBucketCount(
CellularNetworkMetricsLogger::kCustomApnsEnabledCountHistogram,
/*sample=*/1, /*expected_count=*/1);
histogram_tester_->ExpectBucketCount(
CellularNetworkMetricsLogger::kCustomApnsDisabledCountHistogram,
/*sample=*/0,
/*expected_count=*/1);
base::Value::Dict apn2;
apn2.Set(::onc::cellular_apn::kAccessPointName, "apn2");
apn2.Set(::onc::cellular_apn::kState, ::onc::cellular_apn::kStateDisabled);
custom_apn_list.Append(std::move(apn2));
NetworkHandler::Get()->network_metadata_store()->SetCustomApnList(
kCellularGuid, std::move(custom_apn_list));
SetShillState(kCellularServicePath, shill::kStateAssociation);
AssertHistogramsTotalCount(counts);
SetShillState(kCellularServicePath, shill::kStateOnline);
counts.custom_apns_total_hist_count++;
counts.has_enabled_custom_apns++;
counts.enabled_custom_apns_total_hist_count++;
counts.disabled_custom_apns_total_hist_count++;
AssertHistogramsTotalCount(counts);
AssertCustomApnsStatusBucketCount(
ShillConnectResult::kSuccess, /*no_enabled_bucket_count=*/1,
ShillConnectResult::kSuccess, /*has_enabled_bucket_count=*/2);
histogram_tester_->ExpectBucketCount(
CellularNetworkMetricsLogger::kCustomApnsEnabledCountHistogram,
/*sample=*/1, /*expected_count=*/2);
histogram_tester_->ExpectBucketCount(
CellularNetworkMetricsLogger::kCustomApnsDisabledCountHistogram,
/*sample=*/1,
/*expected_count=*/1);
// Fail to connect from disconnecting to disconnected.
SetShillState(kCellularServicePath, shill::kStateAssociation);
AssertHistogramsTotalCount(counts);
SetShillState(kCellularServicePath, shill::kStateDisconnect);
AssertHistogramsTotalCount(counts);
// Fail to connect from disconnecting to disconnected.
SetShillError(kCellularServicePath, shill::kErrorConnectFailed);
AssertHistogramsTotalCount(counts);
SetShillState(kCellularServicePath, shill::kStateIdle);
counts.has_enabled_custom_apns++;
AssertHistogramsTotalCount(counts);
AssertCustomApnsStatusBucketCount(ShillConnectResult::kSuccess,
/*no_enabled_bucket_count=*/1,
ShillConnectResult::kErrorConnectFailed,
/*has_enabled_bucket_count=*/1);
}
TEST_F(CellularNetworkMetricsLoggerTest, AutoStatusTransitionsRevampDisabled) {
SetUpGenericCellularNetwork();
ApnHistogramCounts counts;
// Successful connect from disconnected to connected.
SetShillState(kCellularServicePath, shill::kStateIdle);
AssertHistogramsTotalCount(counts);
SetShillState(kCellularServicePath, shill::kStateOnline);
counts.custom_apns_total_hist_count++;
counts.no_enabled_custom_apns++;
AssertHistogramsTotalCount(counts);
AssertCustomApnsStatusBucketCount(
ShillConnectResult::kSuccess, /*no_enabled_bucket_count=*/1,
ShillConnectResult::kSuccess, /*has_enabled_bucket_count=*/0);
histogram_tester_->ExpectBucketCount(
CellularNetworkMetricsLogger::kCustomApnsCountHistogram, 0, 1);
// Add an APN to the network.
base::Value::Dict apn;
apn.Set(::onc::cellular_apn::kAccessPointName, "apn1");
apn.Set(::onc::cellular_apn::kState, ::onc::cellular_apn::kStateEnabled);
base::Value::List custom_apn_list;
custom_apn_list.Append(std::move(apn));
NetworkHandler::Get()->network_metadata_store()->SetCustomApnList(
kCellularGuid, std::move(custom_apn_list));
// Successful connect from connecting to connected.
SetShillState(kCellularServicePath, shill::kStateAssociation);
AssertHistogramsTotalCount(counts);
SetShillState(kCellularServicePath, shill::kStateOnline);
counts.custom_apns_total_hist_count++;
counts.has_enabled_custom_apns++;
AssertHistogramsTotalCount(counts);
AssertCustomApnsStatusBucketCount(
ShillConnectResult::kSuccess, /*no_enabled_bucket_count=*/1,
ShillConnectResult::kSuccess, /*has_enabled_bucket_count=*/1);
histogram_tester_->ExpectBucketCount(
CellularNetworkMetricsLogger::kCustomApnsCountHistogram, 1, 1);
// Successful connect from connecting to connected again.
SetShillState(kCellularServicePath, shill::kStateAssociation);
AssertHistogramsTotalCount(counts);
SetShillState(kCellularServicePath, shill::kStateOnline);
counts.custom_apns_total_hist_count++;
counts.has_enabled_custom_apns++;
AssertHistogramsTotalCount(counts);
AssertCustomApnsStatusBucketCount(
ShillConnectResult::kSuccess, /*no_enabled_bucket_count=*/1,
ShillConnectResult::kSuccess, /*has_enabled_bucket_count=*/2);
histogram_tester_->ExpectBucketCount(
CellularNetworkMetricsLogger::kCustomApnsCountHistogram, 1, 2);
// Fail to connect from connecting to disconnecting, no valid shill error.
SetShillState(kCellularServicePath, shill::kStateAssociation);
AssertHistogramsTotalCount(counts);
SetShillState(kCellularServicePath, shill::kStateDisconnect);
AssertHistogramsTotalCount(counts);
// Fail to connect from disconnecting to disconnected.
SetShillError(kCellularServicePath, shill::kErrorConnectFailed);
SetShillState(kCellularServicePath, shill::kStateIdle);
counts.has_enabled_custom_apns++;
AssertHistogramsTotalCount(counts);
AssertCustomApnsStatusBucketCount(ShillConnectResult::kSuccess,
/*no_enabled_bucket_count=*/1,
ShillConnectResult::kErrorConnectFailed,
/*has_enabled_bucket_count=*/1);
}
TEST_F(CellularNetworkMetricsLoggerTest, OnlyCellularNetworksStatusRecorded) {
SetUpGenericCellularNetwork();
SetUpGenericWifiNetwork();
ApnHistogramCounts counts;
SetShillState(kCellularServicePath, shill::kStateIdle);
AssertHistogramsTotalCount(counts);
SetShillState(kCellularServicePath, shill::kStateOnline);
counts.custom_apns_total_hist_count++;
counts.no_enabled_custom_apns++;
AssertHistogramsTotalCount(counts);
AssertCustomApnsStatusBucketCount(
ShillConnectResult::kSuccess, /*no_enabled_bucket_count=*/1,
ShillConnectResult::kSuccess, /*has_enabled_bucket_count=*/0);
histogram_tester_->ExpectBucketCount(
CellularNetworkMetricsLogger::kCustomApnsCountHistogram, 0, 1);
SetShillState(kWifiServicePath, shill::kStateIdle);
AssertHistogramsTotalCount(counts);
SetShillState(kWifiServicePath, shill::kStateOnline);
AssertHistogramsTotalCount(counts);
}
} // namespace ash