blob: ac544e40433d45d42609d433b1a34cbbd5516c75 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cronet_c.h"
#include "build/build_config.h"
#include "components/cronet/native/engine.h"
#include "components/cronet/native/generated/cronet.idl_impl_struct.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cronet {
namespace {
// Fake sent byte count for metrics testing.
constexpr int64_t kSentByteCount = 12345;
// App implementation of Cronet_Executor methods.
void TestExecutor_Execute(Cronet_ExecutorPtr self, Cronet_RunnablePtr command) {
CHECK(self);
Cronet_Runnable_Run(command);
Cronet_Runnable_Destroy(command);
}
// Context for TestRequestInfoListener_OnRequestFinished().
using TestOnRequestFinishedClientContext = int;
// App implementation of Cronet_RequestFinishedInfoListener methods.
//
// Expects a client context of type TestOnRequestFinishedClientContext -- will
// increment this value.
void TestRequestInfoListener_OnRequestFinished(
Cronet_RequestFinishedInfoListenerPtr self,
Cronet_RequestFinishedInfoPtr request_info,
Cronet_UrlResponseInfoPtr url_response_info,
Cronet_ErrorPtr error) {
CHECK(self);
Cronet_ClientContext context =
Cronet_RequestFinishedInfoListener_GetClientContext(self);
auto* listener_run_count =
static_cast<TestOnRequestFinishedClientContext*>(context);
++(*listener_run_count);
auto* metrics = Cronet_RequestFinishedInfo_metrics_get(request_info);
EXPECT_EQ(kSentByteCount, Cronet_Metrics_sent_byte_count_get(metrics));
EXPECT_NE(nullptr, url_response_info);
EXPECT_NE(nullptr, error);
}
TEST(EngineUnitTest, HasNoRequestFinishedInfoListener) {
Cronet_EnginePtr engine = Cronet_Engine_Create();
auto* engine_impl = static_cast<Cronet_EngineImpl*>(engine);
EXPECT_FALSE(engine_impl->HasRequestFinishedListener());
Cronet_Engine_Destroy(engine);
}
TEST(EngineUnitTest, HasRequestFinishedInfoListener) {
Cronet_EnginePtr engine = Cronet_Engine_Create();
Cronet_RequestFinishedInfoListenerPtr listener =
Cronet_RequestFinishedInfoListener_CreateWith(
TestRequestInfoListener_OnRequestFinished);
Cronet_ExecutorPtr executor =
Cronet_Executor_CreateWith(TestExecutor_Execute);
Cronet_Engine_AddRequestFinishedListener(engine, listener, executor);
auto* engine_impl = static_cast<Cronet_EngineImpl*>(engine);
EXPECT_TRUE(engine_impl->HasRequestFinishedListener());
Cronet_Engine_RemoveRequestFinishedListener(engine, listener);
EXPECT_FALSE(engine_impl->HasRequestFinishedListener());
Cronet_Executor_Destroy(executor);
Cronet_RequestFinishedInfoListener_Destroy(listener);
Cronet_Engine_Destroy(engine);
}
TEST(EngineUnitTest, RequestFinishedInfoListeners) {
using RequestInfo = base::RefCountedData<Cronet_RequestFinishedInfo>;
using UrlResponseInfo = base::RefCountedData<Cronet_UrlResponseInfo>;
using CronetError = base::RefCountedData<Cronet_Error>;
constexpr int kNumListeners = 5;
TestOnRequestFinishedClientContext listener_run_count = 0;
Cronet_EnginePtr engine = Cronet_Engine_Create();
Cronet_EngineParamsPtr engine_params = Cronet_EngineParams_Create();
Cronet_RequestFinishedInfoListenerPtr listeners[kNumListeners];
Cronet_ExecutorPtr executor =
Cronet_Executor_CreateWith(TestExecutor_Execute);
for (int i = 0; i < kNumListeners; ++i) {
listeners[i] = Cronet_RequestFinishedInfoListener_CreateWith(
TestRequestInfoListener_OnRequestFinished);
Cronet_RequestFinishedInfoListener_SetClientContext(listeners[i],
&listener_run_count);
Cronet_Engine_AddRequestFinishedListener(engine, listeners[i], executor);
}
// Simulate the UrlRequest reporting metrics to the engine.
auto* engine_impl = static_cast<Cronet_EngineImpl*>(engine);
auto request_info = base::MakeRefCounted<RequestInfo>();
auto url_response_info = base::MakeRefCounted<UrlResponseInfo>();
auto error = base::MakeRefCounted<CronetError>();
auto metrics = std::make_unique<Cronet_Metrics>();
metrics->sent_byte_count = kSentByteCount;
request_info->data.metrics.emplace(*metrics);
engine_impl->ReportRequestFinished(request_info, url_response_info, error);
EXPECT_EQ(kNumListeners, listener_run_count);
for (auto* listener : listeners) {
Cronet_RequestFinishedInfoListener_Destroy(listener);
Cronet_Engine_RemoveRequestFinishedListener(engine, listener);
}
Cronet_Executor_Destroy(executor);
Cronet_Engine_Destroy(engine);
Cronet_EngineParams_Destroy(engine_params);
}
// EXPECT_DEBUG_DEATH(), used by the tests below, isn't available on iOS.
#if !defined(OS_IOS)
TEST(EngineUnitTest, AddNullRequestFinishedInfoListener) {
Cronet_EnginePtr engine = Cronet_Engine_Create();
Cronet_ExecutorPtr executor =
Cronet_Executor_CreateWith(TestExecutor_Execute);
EXPECT_DEBUG_DEATH(
Cronet_Engine_AddRequestFinishedListener(engine, nullptr, executor),
"Both listener and executor must be non-null. listener: .* executor: "
".*\\.");
auto* engine_impl = static_cast<Cronet_EngineImpl*>(engine);
EXPECT_FALSE(engine_impl->HasRequestFinishedListener());
Cronet_Executor_Destroy(executor);
Cronet_Engine_Destroy(engine);
}
TEST(EngineUnitTest, AddNullRequestFinishedInfoExecutor) {
Cronet_EnginePtr engine = Cronet_Engine_Create();
Cronet_RequestFinishedInfoListenerPtr listener =
Cronet_RequestFinishedInfoListener_CreateWith(
TestRequestInfoListener_OnRequestFinished);
EXPECT_DEBUG_DEATH(
Cronet_Engine_AddRequestFinishedListener(engine, listener, nullptr),
"Both listener and executor must be non-null. listener: .* executor: "
".*\\.");
auto* engine_impl = static_cast<Cronet_EngineImpl*>(engine);
EXPECT_FALSE(engine_impl->HasRequestFinishedListener());
Cronet_RequestFinishedInfoListener_Destroy(listener);
Cronet_Engine_Destroy(engine);
}
TEST(EngineUnitTest, AddNullRequestFinishedInfoListenerAndExecutor) {
Cronet_EnginePtr engine = Cronet_Engine_Create();
EXPECT_DEBUG_DEATH(
Cronet_Engine_AddRequestFinishedListener(engine, nullptr, nullptr),
"Both listener and executor must be non-null. listener: .* executor: "
".*\\.");
auto* engine_impl = static_cast<Cronet_EngineImpl*>(engine);
EXPECT_FALSE(engine_impl->HasRequestFinishedListener());
Cronet_Engine_Destroy(engine);
}
TEST(EngineUnitTest, AddListenerTwice) {
Cronet_EnginePtr engine = Cronet_Engine_Create();
Cronet_RequestFinishedInfoListenerPtr listener =
Cronet_RequestFinishedInfoListener_CreateWith(
TestRequestInfoListener_OnRequestFinished);
Cronet_ExecutorPtr executor =
Cronet_Executor_CreateWith(TestExecutor_Execute);
Cronet_Engine_AddRequestFinishedListener(engine, listener, executor);
EXPECT_DEBUG_DEATH(
Cronet_Engine_AddRequestFinishedListener(engine, listener, executor),
"Listener .* already registered with executor .*, \\*NOT\\* changing to "
"new executor .*\\.");
auto* engine_impl = static_cast<Cronet_EngineImpl*>(engine);
EXPECT_TRUE(engine_impl->HasRequestFinishedListener());
Cronet_Engine_RemoveRequestFinishedListener(engine, listener);
EXPECT_FALSE(engine_impl->HasRequestFinishedListener());
Cronet_Executor_Destroy(executor);
Cronet_RequestFinishedInfoListener_Destroy(listener);
Cronet_Engine_Destroy(engine);
}
TEST(EngineUnitTest, RemoveNonexistentListener) {
Cronet_EnginePtr engine = Cronet_Engine_Create();
Cronet_RequestFinishedInfoListenerPtr listener =
Cronet_RequestFinishedInfoListener_CreateWith(
TestRequestInfoListener_OnRequestFinished);
EXPECT_DEBUG_DEATH(
Cronet_Engine_RemoveRequestFinishedListener(engine, listener),
"Asked to erase non-existent RequestFinishedInfoListener .*\\.");
auto* engine_impl = static_cast<Cronet_EngineImpl*>(engine);
EXPECT_FALSE(engine_impl->HasRequestFinishedListener());
Cronet_RequestFinishedInfoListener_Destroy(listener);
Cronet_Engine_Destroy(engine);
}
TEST(EngineUnitTest, RemoveNonexistentListenerWithAddedListener) {
Cronet_EnginePtr engine = Cronet_Engine_Create();
Cronet_RequestFinishedInfoListenerPtr listener =
Cronet_RequestFinishedInfoListener_CreateWith(
TestRequestInfoListener_OnRequestFinished);
Cronet_RequestFinishedInfoListenerPtr listener2 =
Cronet_RequestFinishedInfoListener_CreateWith(
TestRequestInfoListener_OnRequestFinished);
Cronet_ExecutorPtr executor =
Cronet_Executor_CreateWith(TestExecutor_Execute);
Cronet_Engine_AddRequestFinishedListener(engine, listener, executor);
EXPECT_DEBUG_DEATH(
Cronet_Engine_RemoveRequestFinishedListener(engine, listener2),
"Asked to erase non-existent RequestFinishedInfoListener .*\\.");
auto* engine_impl = static_cast<Cronet_EngineImpl*>(engine);
EXPECT_TRUE(engine_impl->HasRequestFinishedListener());
Cronet_Engine_RemoveRequestFinishedListener(engine, listener);
EXPECT_FALSE(engine_impl->HasRequestFinishedListener());
Cronet_RequestFinishedInfoListener_Destroy(listener);
Cronet_RequestFinishedInfoListener_Destroy(listener2);
Cronet_Executor_Destroy(executor);
Cronet_Engine_Destroy(engine);
}
TEST(EngineUnitTest, RemoveNullListener) {
Cronet_EnginePtr engine = Cronet_Engine_Create();
EXPECT_DEBUG_DEATH(
Cronet_Engine_RemoveRequestFinishedListener(engine, nullptr),
"Asked to erase non-existent RequestFinishedInfoListener .*\\.");
auto* engine_impl = static_cast<Cronet_EngineImpl*>(engine);
EXPECT_FALSE(engine_impl->HasRequestFinishedListener());
Cronet_Engine_Destroy(engine);
}
#endif // !defined(OS_IOS)
} // namespace
} // namespace cronet