• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/net_log_util.h"
6 
7 #include <set>
8 #include <string_view>
9 #include <vector>
10 
11 #include "base/containers/contains.h"
12 #include "base/feature_list.h"
13 #include "base/files/file_path.h"
14 #include "base/memory/raw_ptr.h"
15 #include "base/metrics/field_trial.h"
16 #include "base/ranges/algorithm.h"
17 #include "base/test/scoped_feature_list.h"
18 #include "base/test/task_environment.h"
19 #include "base/values.h"
20 #include "net/base/net_errors.h"
21 #include "net/base/net_info_source_list.h"
22 #include "net/base/test_completion_callback.h"
23 #include "net/dns/public/doh_provider_entry.h"
24 #include "net/http/http_cache.h"
25 #include "net/http/http_transaction.h"
26 #include "net/http/mock_http_cache.h"
27 #include "net/log/net_log_source.h"
28 #include "net/log/net_log_with_source.h"
29 #include "net/log/test_net_log.h"
30 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
31 #include "net/url_request/url_request_context.h"
32 #include "net/url_request/url_request_context_builder.h"
33 #include "net/url_request/url_request_test_util.h"
34 #include "testing/gtest/include/gtest/gtest.h"
35 
36 namespace net {
37 
38 namespace {
39 
40 // Make sure GetNetConstants doesn't crash.
TEST(NetLogUtil,GetNetConstants)41 TEST(NetLogUtil, GetNetConstants) {
42   base::Value constants(GetNetConstants());
43 }
44 
45 // Make sure GetNetInfo doesn't crash when called on contexts with and without
46 // caches, and they have the same number of elements.
TEST(NetLogUtil,GetNetInfo)47 TEST(NetLogUtil, GetNetInfo) {
48   base::test::TaskEnvironment task_environment;
49 
50   auto context = CreateTestURLRequestContextBuilder()->Build();
51   HttpCache* http_cache = context->http_transaction_factory()->GetCache();
52 
53   // Get NetInfo when there's no cache backend (It's only created on first use).
54   EXPECT_FALSE(http_cache->GetCurrentBackend());
55   base::Value::Dict net_info_without_cache(GetNetInfo(context.get()));
56   EXPECT_FALSE(http_cache->GetCurrentBackend());
57   EXPECT_GT(net_info_without_cache.size(), 0u);
58 
59   // Force creation of a cache backend, and get NetInfo again.
60   auto [rv, _] = context->http_transaction_factory()->GetCache()->GetBackend(
61       TestGetBackendCompletionCallback().callback());
62   EXPECT_EQ(OK, rv);
63   EXPECT_TRUE(http_cache->GetCurrentBackend());
64   base::Value::Dict net_info_with_cache = GetNetInfo(context.get());
65   EXPECT_GT(net_info_with_cache.size(), 0u);
66 
67   EXPECT_EQ(net_info_without_cache.size(), net_info_with_cache.size());
68 }
69 
70 // Verify that active Field Trials are reflected.
TEST(NetLogUtil,GetNetInfoIncludesFieldTrials)71 TEST(NetLogUtil, GetNetInfoIncludesFieldTrials) {
72   base::test::TaskEnvironment task_environment;
73 
74   // Clear all Field Trials.
75   base::test::ScopedFeatureList scoped_feature_list;
76   scoped_feature_list.InitWithFeatureList(
77       std::make_unique<base::FeatureList>());
78 
79   // Add and activate a new Field Trial.
80   base::FieldTrialList::CreateFieldTrial("NewFieldTrial", "Active");
81   EXPECT_EQ(base::FieldTrialList::FindFullName("NewFieldTrial"), "Active");
82 
83   auto context = CreateTestURLRequestContextBuilder()->Build();
84   base::Value net_info(GetNetInfo(context.get()));
85 
86   // Verify that the returned information reflects the new trial.
87   ASSERT_TRUE(net_info.is_dict());
88   base::Value::List* trials =
89       net_info.GetDict().FindList("activeFieldTrialGroups");
90   ASSERT_NE(nullptr, trials);
91   EXPECT_EQ(1u, trials->size());
92   EXPECT_TRUE((*trials)[0].is_string());
93   EXPECT_EQ("NewFieldTrial:Active", (*trials)[0].GetString());
94 }
95 
96 // Demonstrate that disabling a provider causes it to be added to the list of
97 // disabled DoH providers.
98 //
99 // TODO(crbug.com/40218379) Stop using the real DoH provider list.
TEST(NetLogUtil,GetNetInfoIncludesDisabledDohProviders)100 TEST(NetLogUtil, GetNetInfoIncludesDisabledDohProviders) {
101   constexpr std::string_view kArbitraryProvider = "Google";
102   base::test::TaskEnvironment task_environment;
103 
104   for (bool provider_enabled : {false, true}) {
105     // Get the DoH provider entry.
106     auto provider_list = net::DohProviderEntry::GetList();
107     auto provider_it = base::ranges::find(provider_list, kArbitraryProvider,
108                                           &net::DohProviderEntry::provider);
109     CHECK(provider_it != provider_list.end());
110     const DohProviderEntry& provider_entry = **provider_it;
111 
112     // Enable or disable the provider's feature according to `provider_enabled`.
113     base::test::ScopedFeatureList scoped_feature_list;
114     scoped_feature_list.InitWithFeatureState(provider_entry.feature.get(),
115                                              provider_enabled);
116     EXPECT_EQ(provider_enabled,
117               base::FeatureList::IsEnabled(provider_entry.feature.get()));
118 
119     // Verify that the provider is present in the list of disabled providers iff
120     // we disabled it.
121     auto context = CreateTestURLRequestContextBuilder()->Build();
122     base::Value net_info(GetNetInfo(context.get()));
123     ASSERT_TRUE(net_info.is_dict());
124     const base::Value::List* disabled_doh_providers_list =
125         net_info.GetDict().FindList(kNetInfoDohProvidersDisabledDueToFeature);
126     CHECK(disabled_doh_providers_list);
127     EXPECT_EQ(!provider_enabled,
128               base::Contains(*disabled_doh_providers_list,
129                              base::Value(kArbitraryProvider)));
130   }
131 }
132 
133 // Make sure CreateNetLogEntriesForActiveObjects works for requests from a
134 // single URLRequestContext.
TEST(NetLogUtil,CreateNetLogEntriesForActiveObjectsOneContext)135 TEST(NetLogUtil, CreateNetLogEntriesForActiveObjectsOneContext) {
136   base::test::TaskEnvironment task_environment;
137 
138   // Using same context for each iteration makes sure deleted requests don't
139   // appear in the list, or result in crashes.
140   auto context = CreateTestURLRequestContextBuilder()->Build();
141   TestDelegate delegate;
142   for (size_t num_requests = 0; num_requests < 5; ++num_requests) {
143     std::vector<std::unique_ptr<URLRequest>> requests;
144     for (size_t i = 0; i < num_requests; ++i) {
145       requests.push_back(context->CreateRequest(GURL("about:life"),
146                                                 DEFAULT_PRIORITY, &delegate,
147                                                 TRAFFIC_ANNOTATION_FOR_TESTS));
148     }
149     std::set<URLRequestContext*> contexts;
150     contexts.insert(context.get());
151     RecordingNetLogObserver net_log_observer;
152     CreateNetLogEntriesForActiveObjects(contexts, &net_log_observer);
153     auto entry_list = net_log_observer.GetEntries();
154     ASSERT_EQ(num_requests, entry_list.size());
155 
156     for (size_t i = 0; i < num_requests; ++i) {
157       EXPECT_EQ(entry_list[i].source.id, requests[i]->net_log().source().id);
158     }
159   }
160 }
161 
162 // Make sure CreateNetLogEntriesForActiveObjects works with multiple
163 // URLRequestContexts.
TEST(NetLogUtil,CreateNetLogEntriesForActiveObjectsMultipleContexts)164 TEST(NetLogUtil, CreateNetLogEntriesForActiveObjectsMultipleContexts) {
165   base::test::TaskEnvironment task_environment;
166 
167   TestDelegate delegate;
168   for (size_t num_requests = 0; num_requests < 5; ++num_requests) {
169     std::vector<std::unique_ptr<URLRequestContext>> contexts;
170     std::vector<std::unique_ptr<URLRequest>> requests;
171     std::set<URLRequestContext*> context_set;
172     for (size_t i = 0; i < num_requests; ++i) {
173       contexts.push_back(CreateTestURLRequestContextBuilder()->Build());
174       context_set.insert(contexts[i].get());
175       requests.push_back(
176           contexts[i]->CreateRequest(GURL("about:hats"), DEFAULT_PRIORITY,
177                                      &delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
178     }
179     RecordingNetLogObserver net_log_observer;
180     CreateNetLogEntriesForActiveObjects(context_set, &net_log_observer);
181     auto entry_list = net_log_observer.GetEntries();
182     ASSERT_EQ(num_requests, entry_list.size());
183 
184     for (size_t i = 0; i < num_requests; ++i) {
185       EXPECT_EQ(entry_list[i].source.id, requests[i]->net_log().source().id);
186     }
187   }
188 }
189 
190 }  // namespace
191 
192 }  // namespace net
193