xref: /aosp_15_r20/external/cronet/net/log/trace_net_log_observer_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2014 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/log/trace_net_log_observer.h"
6 
7 #include <memory>
8 #include <string>
9 #include <vector>
10 
11 #include "base/check.h"
12 #include "base/functional/bind.h"
13 #include "base/json/json_reader.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/memory/ref_counted_memory.h"
17 #include "base/run_loop.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/test/task_environment.h"
20 #include "base/trace_event/trace_buffer.h"
21 #include "base/trace_event/trace_event.h"
22 #include "base/trace_event/trace_event_impl.h"
23 #include "base/values.h"
24 #include "net/log/net_log.h"
25 #include "net/log/net_log_event_type.h"
26 #include "net/log/net_log_source_type.h"
27 #include "net/log/net_log_with_source.h"
28 #include "net/log/test_net_log.h"
29 #include "net/test/test_with_task_environment.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 
32 using base::trace_event::TraceLog;
33 
34 namespace net {
35 
36 namespace {
37 
38 // TraceLog category for NetLog events.
39 const char kNetLogTracingCategory[] = "netlog";
40 
41 struct TraceEntryInfo {
42   std::string category;
43   // The netlog source id formatted as a hexadecimal string.
44   std::string id;
45   std::string phase;
46   std::string name;
47   std::string source_type;
48 };
49 
GetTraceEntryInfoFromValue(const base::Value::Dict & value)50 TraceEntryInfo GetTraceEntryInfoFromValue(const base::Value::Dict& value) {
51   TraceEntryInfo info;
52   if (const std::string* cat = value.FindString("cat")) {
53     info.category = *cat;
54   } else {
55     ADD_FAILURE() << "Missing 'cat'";
56   }
57   if (const std::string* id = value.FindString("id")) {
58     info.id = *id;
59   } else {
60     ADD_FAILURE() << "Missing 'id'";
61   }
62   if (const std::string* ph = value.FindString("ph")) {
63     info.phase = *ph;
64   } else {
65     ADD_FAILURE() << "Missing 'ph'";
66   }
67   if (const std::string* name = value.FindString("name")) {
68     info.name = *name;
69   } else {
70     ADD_FAILURE() << "Missing 'name'";
71   }
72   if (const std::string* type =
73           value.FindStringByDottedPath("args.source_type")) {
74     info.source_type = *type;
75   } else {
76     EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_END), info.phase);
77   }
78 
79   return info;
80 }
81 
EnableTraceLog(std::string_view category)82 void EnableTraceLog(std::string_view category) {
83   TraceLog::GetInstance()->SetEnabled(
84       base::trace_event::TraceConfig(category, ""), TraceLog::RECORDING_MODE);
85   // AsyncEnabledStateObserver will receive enabled notification one message
86   // loop iteration later.
87   base::RunLoop().RunUntilIdle();
88 }
89 
DisableTraceLog()90 void DisableTraceLog() {
91   TraceLog::GetInstance()->SetDisabled();
92   // AsyncEnabledStateObserver will receive disabled notification one message
93   // loop iteration later.
94   base::RunLoop().RunUntilIdle();
95 }
96 
EnableTraceLogWithNetLog()97 void EnableTraceLogWithNetLog() {
98   EnableTraceLog(kNetLogTracingCategory);
99 }
100 
EnableTraceLogWithoutNetLog()101 void EnableTraceLogWithoutNetLog() {
102   std::string disabled_netlog_category =
103       std::string("-") + kNetLogTracingCategory;
104   EnableTraceLog(disabled_netlog_category);
105 }
106 
107 class TraceNetLogObserverTest : public TestWithTaskEnvironment {
108  public:
TraceNetLogObserverTest()109   TraceNetLogObserverTest() {
110     TraceLog* tracelog = TraceLog::GetInstance();
111     DCHECK(tracelog);
112     DCHECK(!tracelog->IsEnabled());
113     trace_buffer_.SetOutputCallback(json_output_.GetCallback());
114     trace_net_log_observer_ = std::make_unique<TraceNetLogObserver>();
115   }
116 
~TraceNetLogObserverTest()117   ~TraceNetLogObserverTest() override {
118     DCHECK(!TraceLog::GetInstance()->IsEnabled());
119   }
120 
OnTraceDataCollected(base::RunLoop * run_loop,const scoped_refptr<base::RefCountedString> & events_str,bool has_more_events)121   void OnTraceDataCollected(
122       base::RunLoop* run_loop,
123       const scoped_refptr<base::RefCountedString>& events_str,
124       bool has_more_events) {
125     DCHECK(trace_events_.empty());
126     trace_buffer_.Start();
127     trace_buffer_.AddFragment(events_str->data());
128     trace_buffer_.Finish();
129 
130     std::optional<base::Value> trace_value;
131     trace_value =
132         base::JSONReader::Read(json_output_.json_output, base::JSON_PARSE_RFC);
133 
134     ASSERT_TRUE(trace_value) << json_output_.json_output;
135     ASSERT_TRUE(trace_value->is_list());
136 
137     trace_events_ = FilterNetLogTraceEvents(trace_value->GetList());
138 
139     if (!has_more_events)
140       run_loop->Quit();
141   }
142 
EndTraceAndFlush()143   void EndTraceAndFlush() {
144     DisableTraceLog();
145     base::RunLoop run_loop;
146     TraceLog::GetInstance()->Flush(base::BindRepeating(
147         &TraceNetLogObserverTest::OnTraceDataCollected, base::Unretained(this),
148         base::Unretained(&run_loop)));
149     run_loop.Run();
150   }
151 
set_trace_net_log_observer(std::unique_ptr<TraceNetLogObserver> trace_net_log_observer)152   void set_trace_net_log_observer(
153       std::unique_ptr<TraceNetLogObserver> trace_net_log_observer) {
154     trace_net_log_observer_ = std::move(trace_net_log_observer);
155   }
156 
FilterNetLogTraceEvents(const base::Value::List & trace_events)157   static base::Value::List FilterNetLogTraceEvents(
158       const base::Value::List& trace_events) {
159     base::Value::List filtered_trace_events;
160 
161     for (const auto& event : trace_events) {
162       if (!event.is_dict()) {
163         ADD_FAILURE() << "Unexpected non-dictionary event in trace_events";
164         continue;
165       }
166       const std::string* category =
167           event.GetDict().FindStringByDottedPath("cat");
168       if (!category) {
169         ADD_FAILURE()
170             << "Unexpected item without a category field in trace_events";
171         continue;
172       }
173       if (*category != kNetLogTracingCategory)
174         continue;
175       filtered_trace_events.Append(event.Clone());
176     }
177     return filtered_trace_events;
178   }
179 
trace_events() const180   const base::Value::List& trace_events() const { return trace_events_; }
181 
clear_trace_events()182   void clear_trace_events() {
183     trace_events_.clear();
184     json_output_.json_output.clear();
185   }
186 
trace_events_size() const187   size_t trace_events_size() const { return trace_events_.size(); }
188 
net_log_observer()189   RecordingNetLogObserver* net_log_observer() { return &net_log_observer_; }
190 
trace_net_log_observer() const191   TraceNetLogObserver* trace_net_log_observer() const {
192     return trace_net_log_observer_.get();
193   }
194 
195  private:
196   base::Value::List trace_events_;
197   base::trace_event::TraceResultBuffer trace_buffer_;
198   base::trace_event::TraceResultBuffer::SimpleOutput json_output_;
199   RecordingNetLogObserver net_log_observer_;
200   std::unique_ptr<TraceNetLogObserver> trace_net_log_observer_;
201 };
202 
TEST_F(TraceNetLogObserverTest,TracingNotEnabled)203 TEST_F(TraceNetLogObserverTest, TracingNotEnabled) {
204   trace_net_log_observer()->WatchForTraceStart(NetLog::Get());
205   NetLog::Get()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE);
206 
207   EndTraceAndFlush();
208   trace_net_log_observer()->StopWatchForTraceStart();
209 
210   EXPECT_EQ(0u, trace_events_size());
211 }
212 
213 // This test will result in a deadlock if EnabledStateObserver instead
214 // of AsyncEnabledStateObserver is used. Regression test for crbug.com/760817.
215 // Perfetto SDK doesn't have this problem, so the test is not necessary.
216 #if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
TEST_F(TraceNetLogObserverTest,TracingDisabledDuringOnAddEntry)217 TEST_F(TraceNetLogObserverTest, TracingDisabledDuringOnAddEntry) {
218   trace_net_log_observer()->WatchForTraceStart(NetLog::Get());
219   TraceLog* trace_log = TraceLog::GetInstance();
220   trace_log->SetTraceBufferForTesting(base::WrapUnique(
221       base::trace_event::TraceBuffer::CreateTraceBufferVectorOfSize(1)));
222   EnableTraceLogWithNetLog();
223   // TraceLog will disable itself when an event makes the TraceBuffer full.
224   while (!trace_log->BufferIsFull()) {
225     NetLog::Get()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE);
226   }
227 
228   base::RunLoop().RunUntilIdle();
229   ASSERT_FALSE(trace_log->IsEnabled());
230   ASSERT_FALSE(trace_net_log_observer()->net_log());
231   trace_net_log_observer()->StopWatchForTraceStart();
232   // Flush now so that TraceLog's buffer is empty in the next test.
233   EndTraceAndFlush();
234 }
235 #endif  // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
236 
TEST_F(TraceNetLogObserverTest,TraceEventCaptured)237 TEST_F(TraceNetLogObserverTest, TraceEventCaptured) {
238   auto entries = net_log_observer()->GetEntries();
239   EXPECT_TRUE(entries.empty());
240 
241   trace_net_log_observer()->WatchForTraceStart(NetLog::Get());
242   EnableTraceLogWithNetLog();
243   NetLogWithSource net_log_with_source =
244       NetLogWithSource::Make(NetLog::Get(), net::NetLogSourceType::NONE);
245   NetLog::Get()->AddGlobalEntry(NetLogEventType::CANCELLED);
246   net_log_with_source.BeginEvent(NetLogEventType::URL_REQUEST_START_JOB);
247   net_log_with_source.EndEvent(NetLogEventType::URL_REQUEST_START_JOB);
248 
249   entries = net_log_observer()->GetEntries();
250   EXPECT_EQ(3u, entries.size());
251   EndTraceAndFlush();
252   trace_net_log_observer()->StopWatchForTraceStart();
253 
254   EXPECT_EQ(3u, trace_events_size());
255 
256   const base::Value* item1 = &trace_events()[0];
257   ASSERT_TRUE(item1->is_dict());
258   TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(item1->GetDict());
259   EXPECT_EQ(kNetLogTracingCategory, actual_item1.category);
260   EXPECT_EQ(base::StringPrintf("0x%x", entries[0].source.id), actual_item1.id);
261   EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
262             actual_item1.phase);
263   EXPECT_EQ(NetLogEventTypeToString(NetLogEventType::CANCELLED),
264             actual_item1.name);
265   EXPECT_EQ(NetLog::SourceTypeToString(entries[0].source.type),
266             actual_item1.source_type);
267 
268   const base::Value* item2 = &trace_events()[1];
269   ASSERT_TRUE(item2->is_dict());
270   TraceEntryInfo actual_item2 = GetTraceEntryInfoFromValue(item2->GetDict());
271   EXPECT_EQ(kNetLogTracingCategory, actual_item2.category);
272   EXPECT_EQ(base::StringPrintf("0x%x", entries[1].source.id), actual_item2.id);
273   EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN),
274             actual_item2.phase);
275   EXPECT_EQ(NetLogEventTypeToString(NetLogEventType::URL_REQUEST_START_JOB),
276             actual_item2.name);
277   EXPECT_EQ(NetLog::SourceTypeToString(entries[1].source.type),
278             actual_item2.source_type);
279 
280   const base::Value* item3 = &trace_events()[2];
281   ASSERT_TRUE(item3->is_dict());
282   TraceEntryInfo actual_item3 = GetTraceEntryInfoFromValue(item3->GetDict());
283   EXPECT_EQ(kNetLogTracingCategory, actual_item3.category);
284   EXPECT_EQ(base::StringPrintf("0x%x", entries[2].source.id), actual_item3.id);
285   EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_END),
286             actual_item3.phase);
287   EXPECT_EQ(NetLogEventTypeToString(NetLogEventType::URL_REQUEST_START_JOB),
288             actual_item3.name);
289 }
290 
TEST_F(TraceNetLogObserverTest,EnableAndDisableTracing)291 TEST_F(TraceNetLogObserverTest, EnableAndDisableTracing) {
292   trace_net_log_observer()->WatchForTraceStart(NetLog::Get());
293   EnableTraceLogWithNetLog();
294   NetLog::Get()->AddGlobalEntry(NetLogEventType::CANCELLED);
295   EndTraceAndFlush();
296 
297   auto entries = net_log_observer()->GetEntries();
298   EXPECT_EQ(1u, entries.size());
299   EXPECT_EQ(1u, trace_events_size());
300   const base::Value* item1 = &trace_events()[0];
301   ASSERT_TRUE(item1->is_dict());
302   TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(item1->GetDict());
303   EXPECT_EQ(kNetLogTracingCategory, actual_item1.category);
304   EXPECT_EQ(base::StringPrintf("0x%x", entries[0].source.id), actual_item1.id);
305   EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
306             actual_item1.phase);
307   EXPECT_EQ(NetLogEventTypeToString(NetLogEventType::CANCELLED),
308             actual_item1.name);
309   EXPECT_EQ(NetLog::SourceTypeToString(entries[0].source.type),
310             actual_item1.source_type);
311 
312   clear_trace_events();
313 
314   // This entry is emitted while tracing is off.
315   NetLog::Get()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE);
316 
317   EnableTraceLogWithNetLog();
318   NetLog::Get()->AddGlobalEntry(NetLogEventType::URL_REQUEST_START_JOB);
319   EndTraceAndFlush();
320   trace_net_log_observer()->StopWatchForTraceStart();
321 
322   entries = net_log_observer()->GetEntries();
323   EXPECT_EQ(3u, entries.size());
324   EXPECT_EQ(1u, trace_events_size());
325   const base::Value* item2 = &trace_events()[0];
326   ASSERT_TRUE(item2->is_dict());
327   TraceEntryInfo actual_item2 = GetTraceEntryInfoFromValue(item2->GetDict());
328   EXPECT_EQ(kNetLogTracingCategory, actual_item2.category);
329   EXPECT_EQ(base::StringPrintf("0x%x", entries[2].source.id), actual_item2.id);
330   EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
331             actual_item2.phase);
332   EXPECT_EQ(NetLogEventTypeToString(NetLogEventType::URL_REQUEST_START_JOB),
333             actual_item2.name);
334   EXPECT_EQ(NetLog::SourceTypeToString(entries[2].source.type),
335             actual_item2.source_type);
336 }
337 
TEST_F(TraceNetLogObserverTest,DestroyObserverWhileTracing)338 TEST_F(TraceNetLogObserverTest, DestroyObserverWhileTracing) {
339   trace_net_log_observer()->WatchForTraceStart(NetLog::Get());
340   EnableTraceLogWithNetLog();
341   NetLog::Get()->AddGlobalEntry(NetLogEventType::CANCELLED);
342   trace_net_log_observer()->StopWatchForTraceStart();
343   set_trace_net_log_observer(nullptr);
344   NetLog::Get()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE);
345 
346   EndTraceAndFlush();
347 
348   auto entries = net_log_observer()->GetEntries();
349   EXPECT_EQ(2u, entries.size());
350   EXPECT_EQ(1u, trace_events_size());
351 
352   const base::Value* item1 = &trace_events()[0];
353   ASSERT_TRUE(item1->is_dict());
354 
355   TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(item1->GetDict());
356   EXPECT_EQ(kNetLogTracingCategory, actual_item1.category);
357   EXPECT_EQ(base::StringPrintf("0x%x", entries[0].source.id), actual_item1.id);
358   EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
359             actual_item1.phase);
360   EXPECT_EQ(NetLogEventTypeToString(NetLogEventType::CANCELLED),
361             actual_item1.name);
362   EXPECT_EQ(NetLog::SourceTypeToString(entries[0].source.type),
363             actual_item1.source_type);
364 }
365 
TEST_F(TraceNetLogObserverTest,DestroyObserverWhileNotTracing)366 TEST_F(TraceNetLogObserverTest, DestroyObserverWhileNotTracing) {
367   trace_net_log_observer()->WatchForTraceStart(NetLog::Get());
368   NetLog::Get()->AddGlobalEntry(NetLogEventType::CANCELLED);
369   trace_net_log_observer()->StopWatchForTraceStart();
370   set_trace_net_log_observer(nullptr);
371   NetLog::Get()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE);
372   NetLog::Get()->AddGlobalEntry(NetLogEventType::URL_REQUEST_START_JOB);
373 
374   EndTraceAndFlush();
375 
376   auto entries = net_log_observer()->GetEntries();
377   EXPECT_EQ(3u, entries.size());
378   EXPECT_EQ(0u, trace_events_size());
379 }
380 
TEST_F(TraceNetLogObserverTest,CreateObserverAfterTracingStarts)381 TEST_F(TraceNetLogObserverTest, CreateObserverAfterTracingStarts) {
382   set_trace_net_log_observer(nullptr);
383   EnableTraceLogWithNetLog();
384   set_trace_net_log_observer(std::make_unique<TraceNetLogObserver>());
385   trace_net_log_observer()->WatchForTraceStart(NetLog::Get());
386   NetLog::Get()->AddGlobalEntry(NetLogEventType::CANCELLED);
387   trace_net_log_observer()->StopWatchForTraceStart();
388   NetLog::Get()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE);
389   NetLog::Get()->AddGlobalEntry(NetLogEventType::URL_REQUEST_START_JOB);
390 
391   EndTraceAndFlush();
392 
393   auto entries = net_log_observer()->GetEntries();
394   EXPECT_EQ(3u, entries.size());
395   EXPECT_EQ(1u, trace_events_size());
396 }
397 
TEST_F(TraceNetLogObserverTest,CreateObserverAfterTracingStartsDisabledCategory)398 TEST_F(TraceNetLogObserverTest,
399        CreateObserverAfterTracingStartsDisabledCategory) {
400   set_trace_net_log_observer(nullptr);
401 
402   EnableTraceLogWithoutNetLog();
403 
404   set_trace_net_log_observer(std::make_unique<TraceNetLogObserver>());
405   trace_net_log_observer()->WatchForTraceStart(NetLog::Get());
406   NetLog::Get()->AddGlobalEntry(NetLogEventType::CANCELLED);
407   trace_net_log_observer()->StopWatchForTraceStart();
408   NetLog::Get()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE);
409   NetLog::Get()->AddGlobalEntry(NetLogEventType::URL_REQUEST_START_JOB);
410 
411   EndTraceAndFlush();
412 
413   auto entries = net_log_observer()->GetEntries();
414   EXPECT_EQ(3u, entries.size());
415   EXPECT_EQ(0u, trace_events_size());
416 }
417 
TEST_F(TraceNetLogObserverTest,EventsWithAndWithoutParameters)418 TEST_F(TraceNetLogObserverTest, EventsWithAndWithoutParameters) {
419   trace_net_log_observer()->WatchForTraceStart(NetLog::Get());
420   EnableTraceLogWithNetLog();
421 
422   NetLog::Get()->AddGlobalEntryWithStringParams(NetLogEventType::CANCELLED,
423                                                 "foo", "bar");
424   NetLog::Get()->AddGlobalEntry(NetLogEventType::REQUEST_ALIVE);
425 
426   EndTraceAndFlush();
427   trace_net_log_observer()->StopWatchForTraceStart();
428 
429   auto entries = net_log_observer()->GetEntries();
430   EXPECT_EQ(2u, entries.size());
431   EXPECT_EQ(2u, trace_events_size());
432   const base::Value* item1 = &trace_events()[0];
433   ASSERT_TRUE(item1->is_dict());
434   const base::Value* item2 = &trace_events()[1];
435   ASSERT_TRUE(item2->is_dict());
436 
437   TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(item1->GetDict());
438   TraceEntryInfo actual_item2 = GetTraceEntryInfoFromValue(item2->GetDict());
439 
440   EXPECT_EQ(kNetLogTracingCategory, actual_item1.category);
441   EXPECT_EQ(base::StringPrintf("0x%x", entries[0].source.id), actual_item1.id);
442   EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
443             actual_item1.phase);
444   EXPECT_EQ(NetLogEventTypeToString(NetLogEventType::CANCELLED),
445             actual_item1.name);
446   EXPECT_EQ(NetLog::SourceTypeToString(entries[0].source.type),
447             actual_item1.source_type);
448 
449   EXPECT_EQ(kNetLogTracingCategory, actual_item2.category);
450   EXPECT_EQ(base::StringPrintf("0x%x", entries[1].source.id), actual_item2.id);
451   EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
452             actual_item2.phase);
453   EXPECT_EQ(NetLogEventTypeToString(NetLogEventType::REQUEST_ALIVE),
454             actual_item2.name);
455   EXPECT_EQ(NetLog::SourceTypeToString(entries[1].source.type),
456             actual_item2.source_type);
457 
458   const std::string* item1_params =
459       item1->GetDict().FindStringByDottedPath("args.params.foo");
460   ASSERT_TRUE(item1_params);
461   EXPECT_EQ("bar", *item1_params);
462 
463 #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
464   // Perfetto tracing backend skips empty args.
465   const base::Value::Dict* item2_args =
466       item2->GetDict().FindDictByDottedPath("args");
467   EXPECT_FALSE(item2_args->contains("params"));
468 #else
469   const base::Value::Dict* item2_params =
470       item2->GetDict().FindDictByDottedPath("args.params");
471   ASSERT_TRUE(item2_params);
472   EXPECT_TRUE(item2_params->empty());
473 #endif
474 }
475 
TEST(TraceNetLogObserverCategoryTest,DisabledCategory)476 TEST(TraceNetLogObserverCategoryTest, DisabledCategory) {
477   base::test::TaskEnvironment task_environment;
478   TraceNetLogObserver observer;
479   observer.WatchForTraceStart(NetLog::Get());
480 
481   EXPECT_FALSE(NetLog::Get()->IsCapturing());
482 
483   EnableTraceLogWithoutNetLog();
484 
485   EXPECT_FALSE(NetLog::Get()->IsCapturing());
486   observer.StopWatchForTraceStart();
487   EXPECT_FALSE(NetLog::Get()->IsCapturing());
488 
489   DisableTraceLog();
490 }
491 
TEST(TraceNetLogObserverCategoryTest,EnabledCategory)492 TEST(TraceNetLogObserverCategoryTest, EnabledCategory) {
493   base::test::TaskEnvironment task_environment;
494   TraceNetLogObserver observer;
495   observer.WatchForTraceStart(NetLog::Get());
496 
497   EXPECT_FALSE(NetLog::Get()->IsCapturing());
498 
499   EnableTraceLogWithNetLog();
500 
501   EXPECT_TRUE(NetLog::Get()->IsCapturing());
502   observer.StopWatchForTraceStart();
503   EXPECT_FALSE(NetLog::Get()->IsCapturing());
504 
505   DisableTraceLog();
506 }
507 
508 }  // namespace
509 
510 }  // namespace net
511