Skip to content

Commit

Permalink
Add unit tests
Browse files Browse the repository at this point in the history
Misc changes to support testing. E.g., to avoid needing to create
a V8 Script h5vcc, introduced cobalt_metrics_uploader_callback abstract
class that can be mocked in tests.

b/280094891

Change-Id: I0b1a19547b1be2747571fb451286ae67dd31b554
  • Loading branch information
joeltine committed Jun 15, 2023
1 parent fff1f10 commit 2ebb8d5
Show file tree
Hide file tree
Showing 15 changed files with 513 additions and 39 deletions.
29 changes: 29 additions & 0 deletions cobalt/browser/metrics/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ static_library("metrics") {
sources = [
"cobalt_enabled_state_provider.cc",
"cobalt_enabled_state_provider.h",
"cobalt_h5vcc_metrics_uploader_callback.cc",
"cobalt_h5vcc_metrics_uploader_callback.h",
"cobalt_metrics_log_uploader.cc",
"cobalt_metrics_log_uploader.h",
"cobalt_metrics_service_client.cc",
"cobalt_metrics_service_client.h",
"cobalt_metrics_services_manager_client.cc",
"cobalt_metrics_services_manager_client.h",
"cobalt_metrics_uploader_callback.h",
]

deps = [
Expand All @@ -34,3 +37,29 @@ static_library("metrics") {
"//third_party/metrics_proto",
]
}

target(gtest_target_type, "metrics_test") {
testonly = true
has_pedantic_warnings = true

sources = [
"cobalt_metrics_log_uploader_test.cc",
"cobalt_metrics_service_client_test.cc",
"cobalt_metrics_services_manager_client_test.cc",
]

deps = [
":metrics",
"//base",
"//cobalt/browser:generated_types",
"//cobalt/h5vcc",
"//cobalt/h5vcc:metric_event_handler_wrapper",
"//cobalt/test:run_all_unittests",
"//components/metrics",
"//components/prefs:test_support",
"//testing/gmock",
"//testing/gtest",
"//third_party/metrics_proto",
"//third_party/zlib/google:compression_utils",
]
}
28 changes: 28 additions & 0 deletions cobalt/browser/metrics/cobalt_h5vcc_metrics_uploader_callback.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2023 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/browser/metrics/cobalt_h5vcc_metrics_uploader_callback.h"

namespace cobalt {
namespace browser {
namespace metrics {

void CobaltH5vccMetricsUploaderCallback::Run(
const cobalt::h5vcc::H5vccMetricType& type, const std::string& payload) {
event_handler_->callback.value().Run(type, payload);
}

} // namespace metrics
} // namespace browser
} // namespace cobalt
48 changes: 48 additions & 0 deletions cobalt/browser/metrics/cobalt_h5vcc_metrics_uploader_callback.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2023 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_BROWSER_METRICS_COBALT_H5VCC_METRICS_UPLOADER_CALLBACK_H_
#define COBALT_BROWSER_METRICS_COBALT_H5VCC_METRICS_UPLOADER_CALLBACK_H_

#include <string>

#include "cobalt/browser/metrics/cobalt_metrics_uploader_callback.h"
#include "cobalt/h5vcc/h5vcc_metric_type.h"
#include "cobalt/h5vcc/metric_event_handler_wrapper.h"

namespace cobalt {
namespace browser {
namespace metrics {

// An implementation of CobaltMetricsUploaderCallback to support binding an
// H5vcc (JS) callback to be called with a metric payload.
class CobaltH5vccMetricsUploaderCallback
: public CobaltMetricsUploaderCallback {
public:
CobaltH5vccMetricsUploaderCallback(
h5vcc::MetricEventHandlerWrapper* event_handler)
: event_handler_(event_handler) {}

// Runs the h5vcc event_handler callback for the given type and payload.
void Run(const cobalt::h5vcc::H5vccMetricType& type,
const std::string& payload) override;

private:
h5vcc::MetricEventHandlerWrapper* event_handler_;
};
} // namespace metrics
} // namespace browser
} // namespace cobalt

#endif // COBALT_BROWSER_METRICS_COBALT_H5VCC_METRICS_UPLOADER_CALLBACK_H_
25 changes: 9 additions & 16 deletions cobalt/browser/metrics/cobalt_metrics_log_uploader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@

#include "cobalt/browser/metrics/cobalt_metrics_log_uploader.h"

#include "cobalt/browser/metrics/cobalt_metrics_uploader_callback.h"
#include "cobalt/h5vcc/h5vcc_metric_type.h"
#include "cobalt/h5vcc/metric_event_handler_wrapper.h"
#include "components/metrics/log_decoder.h"
#include "components/metrics/metrics_log_uploader.h"
#include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
#include "third_party/metrics_proto/reporting_info.pb.h"


Expand All @@ -34,19 +33,13 @@ CobaltMetricsLogUploader::CobaltMetricsLogUploader(
void CobaltMetricsLogUploader::UploadLog(
const std::string& compressed_log_data, const std::string& log_hash,
const ::metrics::ReportingInfo& reporting_info) {
::metrics::ChromeUserMetricsExtension uma_log;
if (service_type_ == ::metrics::MetricsLogUploader::UMA) {
std::string uncompressed_log_data;
::metrics::DecodeLogData(compressed_log_data, &uncompressed_log_data);
uma_log.ParseFromString(uncompressed_log_data);
if (event_handler_ != nullptr) {
std::string serialized;
if (uma_log.SerializeToString(&serialized)) {
event_handler_->callback.value().Run(
h5vcc::H5vccMetricType::kH5vccMetricTypeUma, serialized);
} else {
LOG(ERROR) << "Failed serializing uma proto";
}
std::string uncompressed_serialized_proto;
::metrics::DecodeLogData(compressed_log_data,
&uncompressed_serialized_proto);
if (upload_handler_ != nullptr) {
upload_handler_->Run(h5vcc::H5vccMetricType::kH5vccMetricTypeUma,
uncompressed_serialized_proto);
}
}

Expand All @@ -58,8 +51,8 @@ void CobaltMetricsLogUploader::UploadLog(
}

void CobaltMetricsLogUploader::SetOnUploadHandler(
h5vcc::MetricEventHandlerWrapper* metric_event_handler) {
event_handler_ = metric_event_handler;
CobaltMetricsUploaderCallback* upload_handler) {
upload_handler_ = upload_handler;
}

} // namespace metrics
Expand Down
6 changes: 3 additions & 3 deletions cobalt/browser/metrics/cobalt_metrics_log_uploader.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "cobalt/browser/metrics/cobalt_metrics_uploader_callback.h"
#include "cobalt/h5vcc/metric_event_handler_wrapper.h"
#include "components/metrics/metrics_log_uploader.h"
#include "third_party/metrics_proto/reporting_info.pb.h"
Expand Down Expand Up @@ -51,13 +52,12 @@ class CobaltMetricsLogUploader : public ::metrics::MetricsLogUploader {

// Sets the event handler wrapper to be called when metrics are ready for
// upload. This should be the JavaScript H5vcc callback implementation.
void SetOnUploadHandler(
h5vcc::MetricEventHandlerWrapper* metric_event_handler);
void SetOnUploadHandler(CobaltMetricsUploaderCallback* metric_event_handler);

private:
const ::metrics::MetricsLogUploader::MetricServiceType service_type_;
const ::metrics::MetricsLogUploader::UploadCallback on_upload_complete_;
h5vcc::MetricEventHandlerWrapper* event_handler_ = nullptr;
CobaltMetricsUploaderCallback* upload_handler_ = nullptr;
};

} // namespace metrics
Expand Down
129 changes: 129 additions & 0 deletions cobalt/browser/metrics/cobalt_metrics_log_uploader_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Copyright 2023 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/browser/metrics/cobalt_metrics_log_uploader.h"

#include <memory>

#include "cobalt/browser/metrics/cobalt_metrics_uploader_callback.h"
#include "cobalt/h5vcc/h5vcc_metrics.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
#include "third_party/metrics_proto/reporting_info.pb.h"
#include "third_party/zlib/google/compression_utils.h"


namespace cobalt {
namespace browser {
namespace metrics {

using cobalt::h5vcc::H5vccMetrics;
using cobalt::h5vcc::MetricEventHandler;
using cobalt::h5vcc::MetricEventHandlerWrapper;
using ::testing::_;
using ::testing::Eq;
using ::testing::StrEq;
using ::testing::StrictMock;

class CobaltMetricsLogUploaderTest : public ::testing::Test {
public:
void SetUp() override {
uploader_ = std::make_unique<CobaltMetricsLogUploader>(
::metrics::MetricsLogUploader::MetricServiceType::UMA,
base::Bind(&CobaltMetricsLogUploaderTest::UploadCompleteCallback,
base::Unretained(this)));
}

void TearDown() override {}

void UploadCompleteCallback(int response_code, int error_code,
bool was_https) {
callback_count_++;
}

protected:
std::unique_ptr<CobaltMetricsLogUploader> uploader_;
int callback_count_ = 0;
};

class MockMetricsUploaderCallback : public CobaltMetricsUploaderCallback {
public:
MOCK_METHOD2(Run, void(const cobalt::h5vcc::H5vccMetricType& type,
const std::string& payload));
};

TEST_F(CobaltMetricsLogUploaderTest, TriggersUploadHandler) {
StrictMock<MockMetricsUploaderCallback> mock_upload_handler;
uploader_->SetOnUploadHandler(&mock_upload_handler);
::metrics::ReportingInfo dummy_reporting_info;
::metrics::ChromeUserMetricsExtension uma_log;
uma_log.set_session_id(1234);
uma_log.set_client_id(1234);
std::string compressed_message;
compression::GzipCompress(uma_log.SerializeAsString(), &compressed_message);
EXPECT_CALL(mock_upload_handler,
Run(Eq(h5vcc::H5vccMetricType::kH5vccMetricTypeUma),
StrEq(uma_log.SerializeAsString())))
.Times(1);
uploader_->UploadLog(compressed_message, "fake_hash", dummy_reporting_info);
ASSERT_EQ(callback_count_, 1);

::metrics::ChromeUserMetricsExtension uma_log2;
uma_log2.set_session_id(456);
uma_log2.set_client_id(567);
std::string compressed_message2;
compression::GzipCompress(uma_log2.SerializeAsString(), &compressed_message2);
EXPECT_CALL(mock_upload_handler,
Run(Eq(h5vcc::H5vccMetricType::kH5vccMetricTypeUma),
StrEq(uma_log2.SerializeAsString())))
.Times(1);
uploader_->UploadLog(compressed_message2, "fake_hash", dummy_reporting_info);
ASSERT_EQ(callback_count_, 2);
}

TEST_F(CobaltMetricsLogUploaderTest, UnknownMetricTypeDoesntTriggerUpload) {
uploader_.reset(new CobaltMetricsLogUploader(
::metrics::MetricsLogUploader::MetricServiceType::UKM,
base::Bind(&CobaltMetricsLogUploaderTest::UploadCompleteCallback,
base::Unretained(this))));
StrictMock<MockMetricsUploaderCallback> mock_upload_handler;
uploader_->SetOnUploadHandler(&mock_upload_handler);
::metrics::ReportingInfo dummy_reporting_info;
::metrics::ChromeUserMetricsExtension uma_log;
uma_log.set_session_id(1234);
uma_log.set_client_id(1234);
std::string compressed_message;
compression::GzipCompress(uma_log.SerializeAsString(), &compressed_message);
EXPECT_CALL(mock_upload_handler, Run(_, _)).Times(0);
uploader_->UploadLog(compressed_message, "fake_hash", dummy_reporting_info);
// Even though we don't upload this log, we still need to trigger the complete
// callback so the metric code can keep running.
ASSERT_EQ(callback_count_, 1);
}

TEST_F(CobaltMetricsLogUploaderTest, BadCompressedDataSendsEmptyString) {
StrictMock<MockMetricsUploaderCallback> mock_upload_handler;
uploader_->SetOnUploadHandler(&mock_upload_handler);
::metrics::ReportingInfo dummy_reporting_info;
EXPECT_CALL(mock_upload_handler, Run(_, Eq(""))).Times(1);
// "bad data" isn't a compressed serialized proto, should just try to upload
// empty string.
uploader_->UploadLog("bad data", "fake_hash", dummy_reporting_info);
ASSERT_EQ(callback_count_, 1);
}

} // namespace metrics
} // namespace browser
} // namespace cobalt
14 changes: 7 additions & 7 deletions cobalt/browser/metrics/cobalt_metrics_service_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include "base/time/time.h"
#include "cobalt/browser/metrics/cobalt_enabled_state_provider.h"
#include "cobalt/browser/metrics/cobalt_metrics_log_uploader.h"
#include "cobalt/h5vcc/metric_event_handler_wrapper.h"
#include "cobalt/browser/metrics/cobalt_metrics_uploader_callback.h"
#include "components/metrics/enabled_state_provider.h"
#include "components/metrics/metrics_log_uploader.h"
#include "components/metrics/metrics_pref_names.h"
Expand All @@ -47,14 +47,14 @@ namespace metrics {
// The interval in between upload attempts. That is, every interval in which
// we package up the new, unlogged, metrics and attempt uploading them. In
// Cobalt's case, this is the shortest interval in which we'll call the H5vcc
// MetricEventHandlerWrapper.
// Upload Handler.
const int kStandardUploadIntervalSeconds = 5 * 60; // 5 minutes.

void CobaltMetricsServiceClient::SetOnUploadHandler(
h5vcc::MetricEventHandlerWrapper* metric_event_handler) {
metric_event_handler_ = metric_event_handler;
CobaltMetricsUploaderCallback* uploader_callback) {
upload_handler_ = uploader_callback;
if (log_uploader_) {
log_uploader_->SetOnUploadHandler(metric_event_handler_);
log_uploader_->SetOnUploadHandler(upload_handler_);
}
}

Expand Down Expand Up @@ -146,8 +146,8 @@ CobaltMetricsServiceClient::CreateUploader(
auto uploader = std::make_unique<CobaltMetricsLogUploader>(
service_type, on_upload_complete);
log_uploader_ = uploader.get();
if (metric_event_handler_ != nullptr) {
log_uploader_->SetOnUploadHandler(metric_event_handler_);
if (upload_handler_ != nullptr) {
log_uploader_->SetOnUploadHandler(upload_handler_);
}
return uploader;
}
Expand Down
Loading

0 comments on commit 2ebb8d5

Please sign in to comment.