1 // Copyright 2024 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/test/test_net_log_manager.h"
6
7 #include "base/command_line.h"
8 #include "base/files/file.h"
9 #include "base/logging.h"
10 #include "base/memory/raw_ptr.h"
11 #include "base/run_loop.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "net/log/file_net_log_observer.h"
15 #include "net/log/net_log.h"
16 #include "net/log/net_log_util.h"
17
18 namespace net {
19
20 // A simple NetLog::ThreadSafeObserver that dumps NetLog entries to VLOG.
21 class TestNetLogManager::VlogNetLogObserver
22 : public NetLog::ThreadSafeObserver {
23 public:
VlogNetLogObserver(NetLog * net_log,NetLogCaptureMode capture_mode)24 VlogNetLogObserver(NetLog* net_log, NetLogCaptureMode capture_mode)
25 : net_log_(net_log) {
26 LOG_IF(INFO, !VLOG_IS_ON(1))
27 << "Use --vmodule=test_net_log_manager=1 to see NetLog messages";
28 net_log_->AddObserver(this, capture_mode);
29 }
30
31 VlogNetLogObserver(const VlogNetLogObserver&) = delete;
32 VlogNetLogObserver& operator=(const VlogNetLogObserver&) = delete;
33
~VlogNetLogObserver()34 ~VlogNetLogObserver() override { net_log_->RemoveObserver(this); }
35
OnAddEntry(const NetLogEntry & entry)36 void OnAddEntry(const NetLogEntry& entry) override {
37 VLOG(1) << "NetLog: id=" << entry.source.id
38 << " source=" << NetLog::SourceTypeToString(entry.source.type)
39 << "\n"
40 << "event=" << NetLogEventTypeToString(entry.type)
41 << " phase=" << NetLog::EventPhaseToString(entry.phase) << "\n"
42 << entry.params.DebugString();
43 }
44
45 private:
46 const raw_ptr<NetLog> net_log_;
47 };
48
TestNetLogManager(NetLog * net_log,NetLogCaptureMode capture_mode)49 TestNetLogManager::TestNetLogManager(NetLog* net_log,
50 NetLogCaptureMode capture_mode) {
51 const base::CommandLine* command_line =
52 base::CommandLine::ForCurrentProcess();
53 base::FilePath log_file_path =
54 command_line->GetSwitchValuePath(kLogNetLogSwitch);
55 if (log_file_path.empty()) {
56 vlog_net_log_observer_ =
57 std::make_unique<VlogNetLogObserver>(net_log, capture_mode);
58 return;
59 }
60
61 base::File file = base::File(
62 log_file_path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
63 if (!file.IsValid()) {
64 return;
65 }
66
67 auto constants = std::make_unique<base::Value::Dict>(GetNetConstants());
68 base::Value::Dict client_info;
69 client_info.Set("name", "net_unittests");
70 base::CommandLine::StringType command_line_string =
71 command_line->GetCommandLineString();
72 #if BUILDFLAG(IS_WIN)
73 client_info.Set("command_line", base::WideToUTF8(command_line_string));
74 #else
75 client_info.Set("command_line", command_line_string);
76 #endif
77 constants->Set("clientInfo", std::move(client_info));
78
79 file_net_log_observer_ = FileNetLogObserver::CreateUnboundedPreExisting(
80 std::move(file), capture_mode, std::move(constants));
81 file_net_log_observer_->StartObserving(net_log);
82 }
83
~TestNetLogManager()84 TestNetLogManager::~TestNetLogManager() {
85 if (file_net_log_observer_) {
86 base::RunLoop run_loop;
87 file_net_log_observer_->StopObserving(/*polled_data=*/nullptr,
88 run_loop.QuitClosure());
89 run_loop.Run();
90 }
91 }
92
93 } // namespace net
94