blob: e93eefe19d43e86a1b25fd040fe12c613632e8fe [file] [log] [blame]
// Copyright 2020 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 "services/network/net_log_proxy_sink.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "net/log/test_net_log.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
class FakeNetLogProxySource : public network::mojom::NetLogProxySource {
public:
explicit FakeNetLogProxySource(
mojo::PendingReceiver<network::mojom::NetLogProxySource>
proxy_source_receiver)
: proxy_source_receiver_(this, std::move(proxy_source_receiver)),
run_loop_(std::make_unique<base::RunLoop>()) {}
FakeNetLogProxySource(const FakeNetLogProxySource&) = delete;
FakeNetLogProxySource& operator=(const FakeNetLogProxySource&) = delete;
// mojom::NetLogProxySource:
void UpdateCaptureModes(net::NetLogCaptureModeSet modes) override {
EXPECT_FALSE(already_stored_last_modes_);
already_stored_last_modes_ = true;
last_modes_ = modes;
run_loop_->Quit();
}
net::NetLogCaptureModeSet WaitForUpdateCaptureModes() {
run_loop_->Run();
EXPECT_TRUE(already_stored_last_modes_);
already_stored_last_modes_ = false;
net::NetLogCaptureModeSet last_modes = last_modes_;
last_modes_ = 0;
run_loop_ = std::make_unique<base::RunLoop>();
return last_modes;
}
private:
mojo::Receiver<network::mojom::NetLogProxySource> proxy_source_receiver_;
bool already_stored_last_modes_ = false;
std::unique_ptr<base::RunLoop> run_loop_;
net::NetLogCaptureModeSet last_modes_;
};
void CreateObserver(std::unique_ptr<net::RecordingNetLogObserver>* out_observer,
net::NetLogCaptureMode capture_mode) {
*out_observer = std::make_unique<net::RecordingNetLogObserver>(capture_mode);
}
void DestroyObserver(
std::unique_ptr<net::RecordingNetLogObserver>* out_observer) {
out_observer->reset();
}
} // namespace
TEST(NetLogProxySink, TestMultipleObservers) {
base::test::TaskEnvironment scoped_task_environment;
network::NetLogProxySink net_log_sink;
mojo::PendingRemote<network::mojom::NetLogProxySource> proxy_source_remote;
mojo::PendingReceiver<network::mojom::NetLogProxySource>
proxy_source_receiver =
proxy_source_remote.InitWithNewPipeAndPassReceiver();
mojo::Remote<network::mojom::NetLogProxySink> proxy_sink_remote;
FakeNetLogProxySource net_log_proxy_source(std::move(proxy_source_receiver));
net_log_sink.AttachSource(std::move(proxy_source_remote),
proxy_sink_remote.BindNewPipeAndPassReceiver());
// Attaching should notify with the current capture modeset.
EXPECT_EQ(0U, net_log_proxy_source.WaitForUpdateCaptureModes());
std::unique_ptr<net::RecordingNetLogObserver> net_log_observer1 =
std::make_unique<net::RecordingNetLogObserver>(
net::NetLogCaptureMode::kIncludeSensitive);
EXPECT_EQ(
net::NetLogCaptureModeToBit(net::NetLogCaptureMode::kIncludeSensitive),
net_log_proxy_source.WaitForUpdateCaptureModes());
std::unique_ptr<net::RecordingNetLogObserver> net_log_observer2;
// Create observer2 on a different thread.
base::ThreadPool::PostTask(FROM_HERE,
base::BindOnce(&CreateObserver, &net_log_observer2,
net::NetLogCaptureMode::kDefault));
EXPECT_EQ(
net::NetLogCaptureModeToBit(net::NetLogCaptureMode::kIncludeSensitive) |
net::NetLogCaptureModeToBit(net::NetLogCaptureMode::kDefault),
net_log_proxy_source.WaitForUpdateCaptureModes());
base::RunLoop add_entry_runloop;
net_log_observer1->SetThreadsafeAddEntryCallback(
add_entry_runloop.QuitClosure());
base::TimeTicks source1_start_time =
base::TimeTicks() + base::TimeDelta::FromMilliseconds(10);
base::TimeTicks source1_event0_time =
source1_start_time + base::TimeDelta::FromMilliseconds(1);
base::Value source1_event0_params(base::Value::Type::DICTIONARY);
source1_event0_params.SetStringKey("hello", "world");
proxy_sink_remote->AddEntry(
static_cast<uint32_t>(net::NetLogEventType::REQUEST_ALIVE),
static_cast<uint32_t>(net::NetLogSourceType::URL_REQUEST), 1U,
source1_start_time, net::NetLogEventPhase::BEGIN, source1_event0_time,
source1_event0_params.Clone());
add_entry_runloop.Run();
auto entries = net_log_observer1->GetEntries();
ASSERT_EQ(1U, entries.size());
EXPECT_EQ(net::NetLogEventType::REQUEST_ALIVE, entries[0].type);
EXPECT_EQ(net::NetLogSourceType::URL_REQUEST, entries[0].source.type);
EXPECT_EQ(1U, entries[0].source.id);
EXPECT_EQ(source1_start_time, entries[0].source.start_time);
EXPECT_EQ(net::NetLogEventPhase::BEGIN, entries[0].phase);
EXPECT_EQ(source1_event0_time, entries[0].time);
EXPECT_TRUE(entries[0].HasParams());
EXPECT_EQ(source1_event0_params, entries[0].params);
auto entries2 = net_log_observer2->GetEntries();
ASSERT_EQ(1U, entries2.size());
EXPECT_EQ(entries[0].type, entries2[0].type);
EXPECT_EQ(entries[0].source.type, entries2[0].source.type);
EXPECT_EQ(entries[0].source.id, entries2[0].source.id);
EXPECT_EQ(entries[0].source.start_time, entries2[0].source.start_time);
EXPECT_EQ(entries[0].phase, entries2[0].phase);
EXPECT_EQ(entries[0].time, entries2[0].time);
EXPECT_EQ(entries[0].params, entries2[0].params);
net_log_observer1.reset();
EXPECT_EQ(net::NetLogCaptureModeToBit(net::NetLogCaptureMode::kDefault),
net_log_proxy_source.WaitForUpdateCaptureModes());
// Destroy observer2 on a different thread.
base::ThreadPool::PostTask(
FROM_HERE, base::BindOnce(DestroyObserver, &net_log_observer2));
EXPECT_EQ(0U, net_log_proxy_source.WaitForUpdateCaptureModes());
}
TEST(NetLogProxySink, TestAttachAfterObserverAdded) {
base::test::TaskEnvironment scoped_task_environment;
// Start observing before creating/attaching the net log proxy.
std::unique_ptr<net::RecordingNetLogObserver> net_log_observer1 =
std::make_unique<net::RecordingNetLogObserver>(
net::NetLogCaptureMode::kIncludeSensitive);
network::NetLogProxySink net_log_sink;
mojo::PendingRemote<network::mojom::NetLogProxySource> proxy_source_remote;
mojo::PendingReceiver<network::mojom::NetLogProxySource>
proxy_source_receiver =
proxy_source_remote.InitWithNewPipeAndPassReceiver();
mojo::Remote<network::mojom::NetLogProxySink> proxy_sink_remote;
FakeNetLogProxySource net_log_proxy_source(std::move(proxy_source_receiver));
net_log_sink.AttachSource(std::move(proxy_source_remote),
proxy_sink_remote.BindNewPipeAndPassReceiver());
// Attaching should notify with the current capture modeset.
EXPECT_EQ(
net::NetLogCaptureModeToBit(net::NetLogCaptureMode::kIncludeSensitive),
net_log_proxy_source.WaitForUpdateCaptureModes());
net_log_observer1.reset();
EXPECT_EQ(0U, net_log_proxy_source.WaitForUpdateCaptureModes());
}