Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: components/net_log/net_log_file_writer_unittest.cc

Issue 2603523002: Move net-export thread-hopping code into NetLogFileWriter and add IO polled data. (Closed)
Patch Set: Fixed free-after-return issue FileWriterGetFilePathToCompletedLog() Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/net_log/net_log_file_writer.h" 5 #include "components/net_log/net_log_file_writer.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h" 13 #include "base/files/file_util.h"
14 #include "base/files/scoped_file.h" 14 #include "base/files/scoped_file.h"
15 #include "base/files/scoped_temp_dir.h" 15 #include "base/files/scoped_temp_dir.h"
16 #include "base/json/json_reader.h" 16 #include "base/json/json_reader.h"
17 #include "base/message_loop/message_loop.h" 17 #include "base/message_loop/message_loop.h"
18 #include "base/run_loop.h"
19 #include "base/synchronization/waitable_event.h"
20 #include "base/threading/thread.h"
18 #include "base/values.h" 21 #include "base/values.h"
19 #include "build/build_config.h" 22 #include "build/build_config.h"
20 #include "components/net_log/chrome_net_log.h" 23 #include "components/net_log/chrome_net_log.h"
24 #include "net/base/test_completion_callback.h"
25 #include "net/http/http_network_session.h"
21 #include "net/log/net_log_capture_mode.h" 26 #include "net/log/net_log_capture_mode.h"
22 #include "net/log/net_log_event_type.h" 27 #include "net/log/net_log_event_type.h"
23 #include "net/log/write_to_file_net_log_observer.h" 28 #include "net/log/write_to_file_net_log_observer.h"
29 #include "net/url_request/url_request_context_getter.h"
30 #include "net/url_request/url_request_test_util.h"
24 #include "testing/gtest/include/gtest/gtest.h" 31 #include "testing/gtest/include/gtest/gtest.h"
25 32
26 namespace { 33 namespace {
27 34
28 const char kChannelString[] = "SomeChannel"; 35 const char kChannelString[] = "SomeChannel";
29 36
37 // Keep this in sync with kLogRelativePath defined in net_log_file_writer.cc.
38 base::FilePath::CharType kLogRelativePath[] =
39 FILE_PATH_LITERAL("net-export/chrome-net-export-log.json");
40
41 const char kCaptureModeDefaultString[] = "STRIP_PRIVATE_DATA";
42 const char kCaptureModeIncludeCookiesAndCredentialsString[] = "NORMAL";
43 const char kCaptureModeIncludeSocketBytesString[] = "LOG_BYTES";
44
45 const char kStateUninitializedString[] = "UNINITIALIZED";
46 const char kStateNotLoggingString[] = "NOT_LOGGING";
47 const char kStateLoggingString[] = "LOGGING";
48
30 } // namespace 49 } // namespace
31 50
32 namespace net_log { 51 namespace net_log {
33 52
34 class TestNetLogFileWriter : public NetLogFileWriter { 53 // Sets |path| to |path_to_return| and always returns true. This function is
54 // used to override NetLogFileWriter's usual getter for the default log base
55 // directory.
56 bool SetPathToGivenAndReturnTrue(const base::FilePath& path_to_return,
57 base::FilePath* path) {
58 *path = path_to_return;
59 return true;
60 }
61
62 // Checks the fields of the state returned by NetLogFileWriter's state callback.
63 // |expected_log_capture_mode_string| is only checked if
64 // |expected_log_capture_mode_known| is true.
65 void VerifyState(std::unique_ptr<base::DictionaryValue> state,
66 const std::string& expected_state_string,
67 bool expected_log_exists,
68 bool expected_log_capture_mode_known,
69 const std::string& expected_log_capture_mode_string) {
70 std::string state_string;
71 ASSERT_TRUE(state->GetString("state", &state_string));
72 EXPECT_EQ(state_string, expected_state_string);
73
74 bool log_exists;
75 ASSERT_TRUE(state->GetBoolean("logExists", &log_exists));
76 EXPECT_EQ(log_exists, expected_log_exists);
77
78 bool log_capture_mode_known;
79 ASSERT_TRUE(
80 state->GetBoolean("logCaptureModeKnown", &log_capture_mode_known));
81 EXPECT_EQ(log_capture_mode_known, expected_log_capture_mode_known);
82
83 if (expected_log_capture_mode_known) {
84 std::string log_capture_mode_string;
85 ASSERT_TRUE(state->GetString("captureMode", &log_capture_mode_string));
86 EXPECT_EQ(log_capture_mode_string, expected_log_capture_mode_string);
87 }
88 }
89
90 ::testing::AssertionResult ReadCompleteLogFile(
91 const base::FilePath& log_path,
92 std::unique_ptr<base::DictionaryValue>* root) {
93 DCHECK(!log_path.empty());
94
95 if (!base::PathExists(log_path)) {
96 return ::testing::AssertionFailure() << log_path.value()
97 << " does not exist.";
98 }
99 // Parse log file contents into a dictionary
100 std::string log_string;
101 if (!base::ReadFileToString(log_path, &log_string)) {
102 return ::testing::AssertionFailure() << log_path.value()
103 << " could not be read.";
104 }
105 *root = base::DictionaryValue::From(base::JSONReader::Read(log_string));
106 if (!*root) {
107 return ::testing::AssertionFailure()
108 << "Contents of " << log_path.value()
109 << " do not form valid JSON dictionary.";
110 }
111 // Make sure the "constants" section exists
112 base::DictionaryValue* constants;
113 if (!(*root)->GetDictionary("constants", &constants)) {
114 root->reset();
115 return ::testing::AssertionFailure() << log_path.value()
116 << " does not contain constants.";
117 }
118 // Make sure the "events" section exists
119 base::ListValue* events;
120 if (!(*root)->GetList("events", &events)) {
121 root->reset();
122 return ::testing::AssertionFailure() << log_path.value()
123 << " does not contain events list.";
124 }
125 return ::testing::AssertionSuccess();
126 }
127
128 void SetUpTestContextWithQuicTimeoutInfoThenSignal(
129 net::NetLog* net_log,
130 int quic_idle_connection_timeout_seconds,
131 std::unique_ptr<net::TestURLRequestContext>* context,
132 base::WaitableEvent* done_event) {
eroman 2017/01/27 02:23:23 See comment later on (I think this can be accompli
wangyix1 2017/01/27 18:21:09 Done.
133 context->reset(new net::TestURLRequestContext(true));
134 (*context)->set_net_log(net_log);
135
136 std::unique_ptr<net::HttpNetworkSession::Params> params(
137 new net::HttpNetworkSession::Params);
138 params->quic_idle_connection_timeout_seconds =
139 quic_idle_connection_timeout_seconds;
140
141 (*context)->set_http_network_session_params(std::move(params));
142 (*context)->Init();
143
144 done_event->Signal();
145 }
146
147 // A class that wraps around TestClosure. Provides the ability to wait on a
148 // state callback and retrieve the result.
149 class TestStateCallback {
35 public: 150 public:
36 explicit TestNetLogFileWriter(ChromeNetLog* chrome_net_log) 151 TestStateCallback()
37 : NetLogFileWriter( 152 : callback_(base::Bind(&TestStateCallback::SetResultThenNotify,
38 chrome_net_log, 153 base::Unretained(this))) {}
39 base::CommandLine::ForCurrentProcess()->GetCommandLineString(), 154
40 kChannelString), 155 const base::Callback<void(std::unique_ptr<base::DictionaryValue>)>& callback()
41 lie_about_net_export_log_directory_(false) { 156 const {
42 EXPECT_TRUE(net_log_temp_dir_.CreateUniqueTempDir()); 157 return callback_;
43 } 158 }
44 159
45 ~TestNetLogFileWriter() override { EXPECT_TRUE(net_log_temp_dir_.Delete()); } 160 std::unique_ptr<base::DictionaryValue> WaitForResult() {
46 161 test_closure_.WaitForResult();
47 // NetLogFileWriter implementation: 162 return std::move(result_);
48 bool GetNetExportLogBaseDirectory(base::FilePath* path) const override {
49 if (lie_about_net_export_log_directory_)
50 return false;
51 *path = net_log_temp_dir_.GetPath();
52 return true;
53 }
54
55 void set_lie_about_net_export_log_directory(
56 bool lie_about_net_export_log_directory) {
57 lie_about_net_export_log_directory_ = lie_about_net_export_log_directory;
58 } 163 }
59 164
60 private: 165 private:
61 bool lie_about_net_export_log_directory_; 166 void SetResultThenNotify(std::unique_ptr<base::DictionaryValue> result) {
62 167 result_ = std::move(result);
63 base::ScopedTempDir net_log_temp_dir_; 168 test_closure_.closure().Run();
169 }
170
171 net::TestClosure test_closure_;
172 std::unique_ptr<base::DictionaryValue> result_;
173 base::Callback<void(std::unique_ptr<base::DictionaryValue>)> callback_;
174 };
175
176 // A class that wraps around TestClosure. Provides the ability to wait on a
177 // file path callback and retrieve the result.
178 class TestFilePathCallback {
179 public:
180 TestFilePathCallback()
181 : callback_(base::Bind(&TestFilePathCallback::SetResultThenNotify,
182 base::Unretained(this))) {}
183
184 const base::Callback<void(const base::FilePath&)>& callback() const {
185 return callback_;
186 }
187
188 const base::FilePath& WaitForResult() {
189 test_closure_.WaitForResult();
190 return result_;
191 }
192
193 private:
194 void SetResultThenNotify(const base::FilePath& result) {
195 result_ = result;
196 test_closure_.closure().Run();
197 }
198
199 net::TestClosure test_closure_;
200 base::FilePath result_;
201 base::Callback<void(const base::FilePath&)> callback_;
64 }; 202 };
65 203
66 class NetLogFileWriterTest : public ::testing::Test { 204 class NetLogFileWriterTest : public ::testing::Test {
67 public: 205 public:
68 NetLogFileWriterTest() 206 NetLogFileWriterTest()
69 : net_log_(new ChromeNetLog( 207 : net_log_(base::FilePath(),
70 base::FilePath(), 208 net::NetLogCaptureMode::Default(),
71 net::NetLogCaptureMode::Default(), 209 base::CommandLine::ForCurrentProcess()->GetCommandLineString(),
210 kChannelString),
211 net_log_file_writer_(
212 &net_log_,
72 base::CommandLine::ForCurrentProcess()->GetCommandLineString(), 213 base::CommandLine::ForCurrentProcess()->GetCommandLineString(),
73 kChannelString)), 214 kChannelString),
74 net_log_file_writer_(new TestNetLogFileWriter(net_log_.get())) {} 215 file_thread_("NetLogFileWriter file thread"),
75 216 net_thread_("NetLogFileWriter net thread") {}
76 std::string GetStateString() const { 217
77 std::unique_ptr<base::DictionaryValue> dict( 218 // ::testing::Test implementation
78 net_log_file_writer_->GetState()); 219 void SetUp() override {
79 std::string state; 220 ASSERT_TRUE(log_temp_dir_.CreateUniqueTempDir());
80 EXPECT_TRUE(dict->GetString("state", &state)); 221
81 return state; 222 // Override |net_log_file_writer_|'s default-log-base-directory-getter to
82 } 223 // a getter that returns the temp dir created for the test.
83 224 net_log_file_writer_.SetDefaultLogBaseDirectoryGetterForTest(
84 std::string GetLogTypeString() const { 225 base::Bind(&SetPathToGivenAndReturnTrue, log_temp_dir_.GetPath()));
85 std::unique_ptr<base::DictionaryValue> dict( 226
86 net_log_file_writer_->GetState()); 227 default_log_path_ = log_temp_dir_.GetPath().Append(kLogRelativePath);
87 std::string log_type; 228
88 EXPECT_TRUE(dict->GetString("logType", &log_type)); 229 file_thread_.Start();
eroman 2017/01/27 02:23:23 Can you put an ASSERT_TRUE() around the calls to S
wangyix1 2017/01/27 18:21:09 Done.
89 return log_type; 230 net_thread_.Start();
90 } 231 ASSERT_TRUE(file_thread_.WaitUntilThreadStarted());
eroman 2017/01/27 02:23:24 I don't think these two lines are needed for corre
wangyix1 2017/01/27 18:21:09 Done.
91 232 ASSERT_TRUE(net_thread_.WaitUntilThreadStarted());
92 // Make sure the export file has been created and is non-empty, as net 233
93 // constants will always be written to it on creation. 234 net_log_file_writer_.SetTaskRunners(file_thread_.task_runner(),
94 void VerifyNetExportLogExists() { 235 net_thread_.task_runner());
95 net_export_log_ = net_log_file_writer_->log_path_; 236 }
96 ASSERT_TRUE(base::PathExists(net_export_log_)); 237 void TearDown() override { ASSERT_TRUE(log_temp_dir_.Delete()); }
97 238
98 int64_t file_size; 239 std::unique_ptr<base::DictionaryValue> FileWriterGetState() {
99 // base::GetFileSize returns proper file size on open handles. 240 TestStateCallback test_callback;
100 ASSERT_TRUE(base::GetFileSize(net_export_log_, &file_size)); 241 net_log_file_writer_.GetState(test_callback.callback());
101 EXPECT_GT(file_size, 0); 242 return test_callback.WaitForResult();
102 } 243 }
103 244
104 // Make sure the export file has been created and a valid JSON file. This 245 base::FilePath FileWriterGetFilePathToCompletedLog() {
105 // should always be the case once logging has been stopped. 246 TestFilePathCallback test_callback;
106 void VerifyNetExportLogComplete() { 247 net_log_file_writer_.GetFilePathToCompletedLog(test_callback.callback());
107 VerifyNetExportLogExists(); 248 return test_callback.WaitForResult();
108 249 }
109 std::string log; 250
110 ASSERT_TRUE(ReadFileToString(net_export_log_, &log)); 251 // If |custom_log_path| is empty path, |net_log_file_writer_| will use its
111 base::JSONReader reader; 252 // default log path.
112 std::unique_ptr<base::Value> json = base::JSONReader::Read(log); 253 void StartThenVerifyState(const base::FilePath& custom_log_path,
113 EXPECT_TRUE(json); 254 net::NetLogCaptureMode capture_mode,
114 } 255 const std::string& expected_capture_mode_string) {
115 256 TestStateCallback test_callback;
116 // Verify state and GetFilePath return correct values if EnsureInit() fails. 257 net_log_file_writer_.StartNetLog(custom_log_path, capture_mode,
117 void VerifyFilePathAndStateAfterEnsureInitFailure() { 258 test_callback.callback());
118 EXPECT_EQ("UNINITIALIZED", GetStateString()); 259 VerifyState(test_callback.WaitForResult(), kStateLoggingString, true, true,
eroman 2017/01/27 02:23:23 optional: For readability I suggest extracting tes
wangyix1 2017/01/27 18:21:09 Done.
119 EXPECT_EQ(NetLogFileWriter::STATE_UNINITIALIZED, 260 expected_capture_mode_string);
120 net_log_file_writer_->state()); 261
121 262 // Make sure NetLogFileWriter::GetFilePath() returns empty path when
122 base::FilePath net_export_file_path; 263 // logging.
123 EXPECT_FALSE(net_log_file_writer_->GetFilePath(&net_export_file_path)); 264 EXPECT_TRUE(FileWriterGetFilePathToCompletedLog().empty());
124 } 265 }
125 266
126 // When we lie in NetExportLogExists, make sure state and GetFilePath return 267 // If |custom_log_path| is empty path, it's assumed the log file with be at
127 // correct values. 268 // |default_path_|.
128 void VerifyFilePathAndStateAfterEnsureInit() { 269 void StopThenVerifyStateAndFile(
129 EXPECT_EQ("NOT_LOGGING", GetStateString()); 270 const base::FilePath& custom_log_path,
130 EXPECT_EQ(NetLogFileWriter::STATE_NOT_LOGGING, 271 std::unique_ptr<base::DictionaryValue> polled_data,
131 net_log_file_writer_->state()); 272 scoped_refptr<net::URLRequestContextGetter> context_getter,
132 EXPECT_EQ("NONE", GetLogTypeString()); 273 const std::string& expected_capture_mode_string) {
133 EXPECT_EQ(NetLogFileWriter::LOG_TYPE_NONE, 274 TestStateCallback test_callback;
134 net_log_file_writer_->log_type()); 275 net_log_file_writer_.StopNetLog(std::move(polled_data), context_getter,
135 276 test_callback.callback());
136 base::FilePath net_export_file_path; 277 VerifyState(test_callback.WaitForResult(), kStateNotLoggingString, true,
eroman 2017/01/27 02:23:24 same optional suggestion here.
wangyix1 2017/01/27 18:21:09 Done.
137 EXPECT_FALSE(net_log_file_writer_->GetFilePath(&net_export_file_path)); 278 true, expected_capture_mode_string);
138 EXPECT_FALSE(net_log_file_writer_->NetExportLogExists()); 279
139 } 280 const base::FilePath& log_path =
140 281 custom_log_path.empty() ? default_log_path_ : custom_log_path;
141 // The following methods make sure the export file has been successfully 282 EXPECT_EQ(FileWriterGetFilePathToCompletedLog(), log_path);
142 // initialized by a DO_START command of the given type. 283
143 284 std::unique_ptr<base::DictionaryValue> root;
144 void VerifyFileAndStateAfterDoStart() { 285 ASSERT_TRUE(ReadCompleteLogFile(log_path, &root));
145 VerifyFileAndStateAfterStart( 286 }
146 NetLogFileWriter::LOG_TYPE_NORMAL, "NORMAL", 287
147 net::NetLogCaptureMode::IncludeCookiesAndCredentials()); 288 protected:
148 } 289 ChromeNetLog net_log_;
149 290
150 void VerifyFileAndStateAfterDoStartStripPrivateData() {
151 VerifyFileAndStateAfterStart(NetLogFileWriter::LOG_TYPE_STRIP_PRIVATE_DATA,
152 "STRIP_PRIVATE_DATA",
153 net::NetLogCaptureMode::Default());
154 }
155
156 void VerifyFileAndStateAfterDoStartLogBytes() {
157 VerifyFileAndStateAfterStart(NetLogFileWriter::LOG_TYPE_LOG_BYTES,
158 "LOG_BYTES",
159 net::NetLogCaptureMode::IncludeSocketBytes());
160 }
161
162 // Make sure the export file has been successfully initialized after DO_STOP
163 // command following a DO_START command of the given type.
164
165 void VerifyFileAndStateAfterDoStop() {
166 VerifyFileAndStateAfterDoStop(NetLogFileWriter::LOG_TYPE_NORMAL, "NORMAL");
167 }
168
169 void VerifyFileAndStateAfterDoStopWithStripPrivateData() {
170 VerifyFileAndStateAfterDoStop(NetLogFileWriter::LOG_TYPE_STRIP_PRIVATE_DATA,
171 "STRIP_PRIVATE_DATA");
172 }
173
174 void VerifyFileAndStateAfterDoStopWithLogBytes() {
175 VerifyFileAndStateAfterDoStop(NetLogFileWriter::LOG_TYPE_LOG_BYTES,
176 "LOG_BYTES");
177 }
178
179 std::unique_ptr<ChromeNetLog> net_log_;
180 // |net_log_file_writer_| is initialized after |net_log_| so that it can stop 291 // |net_log_file_writer_| is initialized after |net_log_| so that it can stop
181 // obvserving on destruction. 292 // obvserving on destruction.
182 std::unique_ptr<TestNetLogFileWriter> net_log_file_writer_; 293 NetLogFileWriter net_log_file_writer_;
183 base::FilePath net_export_log_; 294
295 base::ScopedTempDir log_temp_dir_;
296
297 // The default log path that |net_log_file_writer_| will use is cached here.
298 base::FilePath default_log_path_;
299
300 base::Thread file_thread_;
301 base::Thread net_thread_;
184 302
185 private: 303 private:
186 // Checks state after one of the DO_START* commands. 304 // Allows tasks to be posted to the main thread.
187 void VerifyFileAndStateAfterStart(
188 NetLogFileWriter::LogType expected_log_type,
189 const std::string& expected_log_type_string,
190 net::NetLogCaptureMode expected_capture_mode) {
191 EXPECT_EQ(NetLogFileWriter::STATE_LOGGING, net_log_file_writer_->state());
192 EXPECT_EQ("LOGGING", GetStateString());
193 EXPECT_EQ(expected_log_type, net_log_file_writer_->log_type());
194 EXPECT_EQ(expected_log_type_string, GetLogTypeString());
195 EXPECT_EQ(expected_capture_mode,
196 net_log_file_writer_->write_to_file_observer_->capture_mode());
197
198 // Check GetFilePath returns false when still writing to the file.
199 base::FilePath net_export_file_path;
200 EXPECT_FALSE(net_log_file_writer_->GetFilePath(&net_export_file_path));
201
202 VerifyNetExportLogExists();
203 }
204
205 void VerifyFileAndStateAfterDoStop(
206 NetLogFileWriter::LogType expected_log_type,
207 const std::string& expected_log_type_string) {
208 EXPECT_EQ(NetLogFileWriter::STATE_NOT_LOGGING,
209 net_log_file_writer_->state());
210 EXPECT_EQ("NOT_LOGGING", GetStateString());
211 EXPECT_EQ(expected_log_type, net_log_file_writer_->log_type());
212 EXPECT_EQ(expected_log_type_string, GetLogTypeString());
213
214 base::FilePath net_export_file_path;
215 EXPECT_TRUE(net_log_file_writer_->GetFilePath(&net_export_file_path));
216 EXPECT_EQ(net_export_log_, net_export_file_path);
217
218 VerifyNetExportLogComplete();
219 }
220
221 base::MessageLoop message_loop_; 305 base::MessageLoop message_loop_;
222 }; 306 };
223 307
224 TEST_F(NetLogFileWriterTest, EnsureInitFailure) { 308 TEST_F(NetLogFileWriterTest, InitFail) {
225 net_log_file_writer_->set_lie_about_net_export_log_directory(true); 309 // Override net_log_file_writer_'s default log base directory getter to always
226 310 // fail.
227 EXPECT_FALSE(net_log_file_writer_->EnsureInit()); 311 net_log_file_writer_.SetDefaultLogBaseDirectoryGetterForTest(
228 VerifyFilePathAndStateAfterEnsureInitFailure(); 312 base::Bind([](base::FilePath* path) -> bool { return false; }));
229 313
230 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_START); 314 // GetState() will cause |net_log_file_writer_| to initialize. In this case,
231 VerifyFilePathAndStateAfterEnsureInitFailure(); 315 // initialization will fail since |net_log_file_writer_| will fail to
232 } 316 // retrieve the default log base directory.
233 317 VerifyState(FileWriterGetState(), kStateUninitializedString, false, false,
234 TEST_F(NetLogFileWriterTest, EnsureInitAllowStart) { 318 "");
235 EXPECT_TRUE(net_log_file_writer_->EnsureInit()); 319
236 VerifyFilePathAndStateAfterEnsureInit(); 320 // NetLogFileWriter::GetFilePath() should return empty path if uninitialized.
237 321 EXPECT_TRUE(FileWriterGetFilePathToCompletedLog().empty());
238 // Calling EnsureInit() second time should be a no-op. 322 }
239 EXPECT_TRUE(net_log_file_writer_->EnsureInit()); 323
240 VerifyFilePathAndStateAfterEnsureInit(); 324 TEST_F(NetLogFileWriterTest, InitWithoutExistingLog) {
241 325 // GetState() will cause |net_log_file_writer_| to initialize.
242 // GetFilePath() should failed when there's no file. 326 VerifyState(FileWriterGetState(), kStateNotLoggingString, false, false, "");
243 base::FilePath net_export_file_path; 327
244 EXPECT_FALSE(net_log_file_writer_->GetFilePath(&net_export_file_path)); 328 // NetLogFileWriter::GetFilePathToCompletedLog() should return empty path when
245 } 329 // no log file exists.
246 330 EXPECT_TRUE(FileWriterGetFilePathToCompletedLog().empty());
247 TEST_F(NetLogFileWriterTest, EnsureInitAllowStartOrSend) { 331 }
248 net_log_file_writer_->SetUpDefaultNetExportLogPath(); 332
249 net_export_log_ = net_log_file_writer_->log_path_; 333 TEST_F(NetLogFileWriterTest, InitWithExistingLog) {
250 334 // Create and close an empty log file to simulate existence of a previous log
251 // Create and close an empty log file, to simulate an old log file already 335 // file.
252 // existing. 336 ASSERT_TRUE(
253 base::ScopedFILE created_file(base::OpenFile(net_export_log_, "w")); 337 base::CreateDirectoryAndGetError(default_log_path_.DirName(), nullptr));
254 ASSERT_TRUE(created_file.get()); 338 base::ScopedFILE empty_file(base::OpenFile(default_log_path_, "w"));
255 created_file.reset(); 339 ASSERT_TRUE(empty_file.get());
256 340 empty_file.reset();
257 EXPECT_TRUE(net_log_file_writer_->EnsureInit()); 341
258 342 // GetState() will cause |net_log_file_writer_| to initialize.
259 EXPECT_EQ("NOT_LOGGING", GetStateString()); 343 VerifyState(FileWriterGetState(), kStateNotLoggingString, true, false, "");
260 EXPECT_EQ(NetLogFileWriter::STATE_NOT_LOGGING, net_log_file_writer_->state()); 344
261 EXPECT_EQ("UNKNOWN", GetLogTypeString()); 345 EXPECT_EQ(FileWriterGetFilePathToCompletedLog(), default_log_path_);
262 EXPECT_EQ(NetLogFileWriter::LOG_TYPE_UNKNOWN, 346 }
263 net_log_file_writer_->log_type()); 347
264 EXPECT_EQ(net_export_log_, net_log_file_writer_->log_path_); 348 TEST_F(NetLogFileWriterTest, StartAndStopWithAllCaptureModes) {
265 EXPECT_TRUE(base::PathExists(net_export_log_)); 349 const net::NetLogCaptureMode capture_modes[3] = {
266 350 net::NetLogCaptureMode::Default(),
267 base::FilePath net_export_file_path; 351 net::NetLogCaptureMode::IncludeCookiesAndCredentials(),
268 EXPECT_TRUE(net_log_file_writer_->GetFilePath(&net_export_file_path)); 352 net::NetLogCaptureMode::IncludeSocketBytes()};
269 EXPECT_TRUE(base::PathExists(net_export_file_path)); 353
270 EXPECT_EQ(net_export_log_, net_export_file_path); 354 const std::string capture_mode_strings[3] = {
271 } 355 kCaptureModeDefaultString, kCaptureModeIncludeCookiesAndCredentialsString,
272 356 kCaptureModeIncludeSocketBytesString};
273 TEST_F(NetLogFileWriterTest, ProcessCommandDoStartAndStop) { 357
274 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_START); 358 // For each capture mode, start and stop |net_log_file_writer_| in that mode.
275 VerifyFileAndStateAfterDoStart(); 359 for (int i = 0; i < 3; ++i) {
276 360 StartThenVerifyState(base::FilePath(), capture_modes[i],
277 // Calling a second time should be a no-op. 361 capture_mode_strings[i]);
278 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_START); 362
279 VerifyFileAndStateAfterDoStart(); 363 // Starting a second time should be a no-op.
280 364 StartThenVerifyState(base::FilePath(), capture_modes[i],
281 // starting with other log levels should also be no-ops. 365 capture_mode_strings[i]);
282 net_log_file_writer_->ProcessCommand( 366
283 NetLogFileWriter::DO_START_STRIP_PRIVATE_DATA); 367 // Starting with other capture modes should also be no-ops. This should also
284 VerifyFileAndStateAfterDoStart(); 368 // not affect the capture mode reported by |net_log_file_writer_|.
285 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_START_LOG_BYTES); 369 StartThenVerifyState(base::FilePath(), capture_modes[(i + 1) % 3],
286 VerifyFileAndStateAfterDoStart(); 370 capture_mode_strings[i]);
287 371
288 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_STOP); 372 StartThenVerifyState(base::FilePath(), capture_modes[(i + 2) % 3],
289 VerifyFileAndStateAfterDoStop(); 373 capture_mode_strings[i]);
290 374
291 // Calling DO_STOP second time should be a no-op. 375 StopThenVerifyStateAndFile(base::FilePath(), nullptr, nullptr,
292 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_STOP); 376 capture_mode_strings[i]);
293 VerifyFileAndStateAfterDoStop(); 377
294 } 378 // Stopping a second time should be a no-op.
295 379 StopThenVerifyStateAndFile(base::FilePath(), nullptr, nullptr,
296 TEST_F(NetLogFileWriterTest, 380 capture_mode_strings[i]);
297 ProcessCommandDoStartAndStopWithPrivateDataStripping) { 381 }
298 net_log_file_writer_->ProcessCommand( 382 }
299 NetLogFileWriter::DO_START_STRIP_PRIVATE_DATA); 383
300 VerifyFileAndStateAfterDoStartStripPrivateData(); 384 // Verify the file sizes after two consecutive starts/stops are the same (even
301 385 // if some junk data is added in between).
302 // Calling a second time should be a no-op. 386 TEST_F(NetLogFileWriterTest, StartClearsFile) {
303 net_log_file_writer_->ProcessCommand( 387 StartThenVerifyState(base::FilePath(), net::NetLogCaptureMode::Default(),
304 NetLogFileWriter::DO_START_STRIP_PRIVATE_DATA); 388 kCaptureModeDefaultString);
305 VerifyFileAndStateAfterDoStartStripPrivateData(); 389
306 390 StopThenVerifyStateAndFile(base::FilePath(), nullptr, nullptr,
307 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_STOP); 391 kCaptureModeDefaultString);
308 VerifyFileAndStateAfterDoStopWithStripPrivateData();
309
310 // Calling DO_STOP second time should be a no-op.
311 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_STOP);
312 VerifyFileAndStateAfterDoStopWithStripPrivateData();
313 }
314
315 TEST_F(NetLogFileWriterTest, ProcessCommandDoStartAndStopWithByteLogging) {
316 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_START_LOG_BYTES);
317 VerifyFileAndStateAfterDoStartLogBytes();
318
319 // Calling a second time should be a no-op.
320 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_START_LOG_BYTES);
321 VerifyFileAndStateAfterDoStartLogBytes();
322
323 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_STOP);
324 VerifyFileAndStateAfterDoStopWithLogBytes();
325
326 // Calling DO_STOP second time should be a no-op.
327 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_STOP);
328 VerifyFileAndStateAfterDoStopWithLogBytes();
329 }
330
331 TEST_F(NetLogFileWriterTest, DoStartClearsFile) {
332 // Verify file sizes after two consecutive starts/stops are the same (even if
333 // we add some junk data in between).
334 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_START);
335 VerifyFileAndStateAfterDoStart();
336
337 int64_t start_file_size;
338 EXPECT_TRUE(base::GetFileSize(net_export_log_, &start_file_size));
339
340 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_STOP);
341 VerifyFileAndStateAfterDoStop();
342 392
343 int64_t stop_file_size; 393 int64_t stop_file_size;
344 EXPECT_TRUE(base::GetFileSize(net_export_log_, &stop_file_size)); 394 EXPECT_TRUE(base::GetFileSize(default_log_path_, &stop_file_size));
345 EXPECT_GE(stop_file_size, start_file_size);
346 395
347 // Add some junk at the end of the file. 396 // Add some junk at the end of the file.
348 std::string junk_data("Hello"); 397 std::string junk_data("Hello");
398 EXPECT_TRUE(base::AppendToFile(default_log_path_, junk_data.c_str(),
399 junk_data.size()));
400
401 int64_t junk_file_size;
402 EXPECT_TRUE(base::GetFileSize(default_log_path_, &junk_file_size));
403 EXPECT_GT(junk_file_size, stop_file_size);
404
405 // Start and stop again and make sure the file is back to the size it was
406 // before adding the junk data.
407 StartThenVerifyState(base::FilePath(), net::NetLogCaptureMode::Default(),
408 kCaptureModeDefaultString);
409
410 StopThenVerifyStateAndFile(base::FilePath(), nullptr, nullptr,
411 kCaptureModeDefaultString);
412
413 int64_t new_stop_file_size;
414 EXPECT_TRUE(base::GetFileSize(default_log_path_, &new_stop_file_size));
415
416 EXPECT_EQ(new_stop_file_size, stop_file_size);
417 }
418
419 // Adds an event to the log file, then checks that the file is larger than
420 // the file created without that event.
421 TEST_F(NetLogFileWriterTest, AddEvent) {
422 StartThenVerifyState(base::FilePath(), net::NetLogCaptureMode::Default(),
423 kCaptureModeDefaultString);
424
425 StopThenVerifyStateAndFile(base::FilePath(), nullptr, nullptr,
426 kCaptureModeDefaultString);
427
428 // Get file size without the event.
429 int64_t stop_file_size;
430 EXPECT_TRUE(base::GetFileSize(default_log_path_, &stop_file_size));
431
432 StartThenVerifyState(base::FilePath(), net::NetLogCaptureMode::Default(),
433 kCaptureModeDefaultString);
434
435 net_log_.AddGlobalEntry(net::NetLogEventType::CANCELLED);
436
437 StopThenVerifyStateAndFile(base::FilePath(), nullptr, nullptr,
438 kCaptureModeDefaultString);
439
440 int64_t new_stop_file_size;
441 EXPECT_TRUE(base::GetFileSize(default_log_path_, &new_stop_file_size));
442
443 EXPECT_GE(new_stop_file_size, stop_file_size);
444 }
445
446 // Using a custom path to make sure logging can still occur when
447 // the path has changed.
448 TEST_F(NetLogFileWriterTest, AddEventCustomPath) {
449 base::FilePath::CharType kCustomRelativePath[] =
450 FILE_PATH_LITERAL("custom/custom/chrome-net-export-log.json");
451 base::FilePath custom_log_path =
452 log_temp_dir_.GetPath().Append(kCustomRelativePath);
349 EXPECT_TRUE( 453 EXPECT_TRUE(
350 base::AppendToFile(net_export_log_, junk_data.c_str(), junk_data.size())); 454 base::CreateDirectoryAndGetError(custom_log_path.DirName(), nullptr));
351 455
352 int64_t junk_file_size; 456 StartThenVerifyState(custom_log_path, net::NetLogCaptureMode::Default(),
353 EXPECT_TRUE(base::GetFileSize(net_export_log_, &junk_file_size)); 457 kCaptureModeDefaultString);
354 EXPECT_GT(junk_file_size, stop_file_size); 458
355 459 StopThenVerifyStateAndFile(custom_log_path, nullptr, nullptr,
356 // Execute DO_START/DO_STOP commands and make sure the file is back to the 460 kCaptureModeDefaultString);
357 // size before addition of junk data. 461
358 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_START); 462 // Get file size without the event.
359 VerifyFileAndStateAfterDoStart(); 463 int64_t stop_file_size;
360 464 EXPECT_TRUE(base::GetFileSize(custom_log_path, &stop_file_size));
361 int64_t new_start_file_size; 465
362 EXPECT_TRUE(base::GetFileSize(net_export_log_, &new_start_file_size)); 466 StartThenVerifyState(custom_log_path, net::NetLogCaptureMode::Default(),
363 EXPECT_EQ(new_start_file_size, start_file_size); 467 kCaptureModeDefaultString);
364 468
365 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_STOP); 469 net_log_.AddGlobalEntry(net::NetLogEventType::CANCELLED);
366 VerifyFileAndStateAfterDoStop(); 470
471 StopThenVerifyStateAndFile(custom_log_path, nullptr, nullptr,
472 kCaptureModeDefaultString);
367 473
368 int64_t new_stop_file_size; 474 int64_t new_stop_file_size;
369 EXPECT_TRUE(base::GetFileSize(net_export_log_, &new_stop_file_size)); 475 EXPECT_TRUE(base::GetFileSize(custom_log_path, &new_stop_file_size));
370 EXPECT_EQ(new_stop_file_size, stop_file_size);
371 }
372
373 TEST_F(NetLogFileWriterTest, CheckAddEvent) {
374 // Add an event to |net_log_| and then test to make sure that, after we stop
375 // logging, the file is larger than the file created without that event.
376 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_START);
377 VerifyFileAndStateAfterDoStart();
378
379 // Get file size without the event.
380 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_STOP);
381 VerifyFileAndStateAfterDoStop();
382
383 int64_t stop_file_size;
384 EXPECT_TRUE(base::GetFileSize(net_export_log_, &stop_file_size));
385
386 // Perform DO_START and add an Event and then DO_STOP and then compare
387 // file sizes.
388 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_START);
389 VerifyFileAndStateAfterDoStart();
390
391 // Log an event.
392 net_log_->AddGlobalEntry(net::NetLogEventType::CANCELLED);
393
394 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_STOP);
395 VerifyFileAndStateAfterDoStop();
396
397 int64_t new_stop_file_size;
398 EXPECT_TRUE(base::GetFileSize(net_export_log_, &new_stop_file_size));
399 EXPECT_GE(new_stop_file_size, stop_file_size); 476 EXPECT_GE(new_stop_file_size, stop_file_size);
400 } 477 }
401 478
402 TEST_F(NetLogFileWriterTest, CheckAddEventWithCustomPath) { 479 TEST_F(NetLogFileWriterTest, StopWithPolledDataAndContextGetter) {
403 // Using a custom path to make sure logging can still occur when 480 // Create dummy polled data
404 // the path has changed. 481 const char kDummyPolledDataPath[] = "dummy_path";
405 base::FilePath path; 482 const char kDummyPolledDataString[] = "dummy_info";
406 net_log_file_writer_->GetNetExportLogBaseDirectory(&path); 483 std::unique_ptr<base::DictionaryValue> dummy_polled_data =
407 484 base::MakeUnique<base::DictionaryValue>();
408 base::FilePath::CharType kCustomPath[] = 485 dummy_polled_data->SetString(kDummyPolledDataPath, kDummyPolledDataString);
409 FILE_PATH_LITERAL("custom/custom/chrome-net-export-log.json"); 486
410 base::FilePath custom_path = path.Append(kCustomPath); 487 // Create test context getter on |net_thread_| and wait for it to finish.
eroman 2017/01/27 02:23:24 wording: the "context getter" isn't created on the
wangyix1 2017/01/27 18:21:09 Done.
411 488 std::unique_ptr<net::TestURLRequestContext> context;
412 EXPECT_TRUE(base::CreateDirectoryAndGetError(custom_path.DirName(), nullptr)); 489 const int kDummyQuicParam = 75;
413 490
414 net_log_file_writer_->SetUpNetExportLogPath(custom_path); 491 base::WaitableEvent create_context_done_event(
eroman 2017/01/27 02:23:24 Another less verbose way to accomplish this is usi
wangyix1 2017/01/27 18:21:09 Done.
415 net_export_log_ = net_log_file_writer_->log_path_; 492 base::WaitableEvent::ResetPolicy::MANUAL,
416 EXPECT_EQ(custom_path, net_export_log_); 493 base::WaitableEvent::InitialState::NOT_SIGNALED);
417 494 net_thread_.task_runner()->PostTask(
418 // Add an event to |net_log_| and then test to make sure that, after we stop 495 FROM_HERE,
419 // logging, the file is larger than the file created without that event. 496 base::Bind(&SetUpTestContextWithQuicTimeoutInfoThenSignal, &net_log_,
420 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_START); 497 kDummyQuicParam, &context, &create_context_done_event));
421 VerifyFileAndStateAfterDoStart(); 498 create_context_done_event.Wait();
422 499
423 // Get file size without the event. 500 scoped_refptr<net::TestURLRequestContextGetter> context_getter(
eroman 2017/01/27 02:23:24 I would say this can move into SetUpTestContextWit
wangyix1 2017/01/27 18:21:09 Done.
424 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_STOP); 501 new net::TestURLRequestContextGetter(net_thread_.task_runner(),
425 VerifyFileAndStateAfterDoStop(); 502 std::move(context)));
426 503
427 int64_t stop_file_size; 504 StartThenVerifyState(base::FilePath(), net::NetLogCaptureMode::Default(),
428 EXPECT_TRUE(base::GetFileSize(net_export_log_, &stop_file_size)); 505 kCaptureModeDefaultString);
429 506
430 // Perform DO_START and add an Event and then DO_STOP and then compare 507 StopThenVerifyStateAndFile(base::FilePath(), std::move(dummy_polled_data),
431 // file sizes. 508 context_getter, kCaptureModeDefaultString);
432 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_START); 509
433 VerifyFileAndStateAfterDoStart(); 510 // Read polledData from log file.
434 511 std::unique_ptr<base::DictionaryValue> root;
435 // Log an event. 512 ASSERT_TRUE(ReadCompleteLogFile(default_log_path_, &root));
436 net_log_->AddGlobalEntry(net::NetLogEventType::CANCELLED); 513 base::DictionaryValue* polled_data;
437 514 ASSERT_TRUE(root->GetDictionary("polledData", &polled_data));
438 net_log_file_writer_->ProcessCommand(NetLogFileWriter::DO_STOP); 515
439 VerifyFileAndStateAfterDoStop(); 516 // Check that it contains the field from the polled data that was passed in.
440 517 std::string dummy_string;
441 int64_t new_stop_file_size; 518 ASSERT_TRUE(polled_data->GetString(kDummyPolledDataPath, &dummy_string));
442 EXPECT_TRUE(base::GetFileSize(net_export_log_, &new_stop_file_size)); 519 EXPECT_EQ(dummy_string, kDummyPolledDataString);
443 EXPECT_GE(new_stop_file_size, stop_file_size); 520
521 // Check that it also contains the field from the URLRequestContext that was
522 // passed in.
523 base::DictionaryValue* quic_info;
524 ASSERT_TRUE(polled_data->GetDictionary("quicInfo", &quic_info));
525 base::Value* timeout_value = nullptr;
526 int timeout;
527 ASSERT_TRUE(
528 quic_info->Get("idle_connection_timeout_seconds", &timeout_value));
529 ASSERT_TRUE(timeout_value->GetAsInteger(&timeout));
530 EXPECT_EQ(timeout, kDummyQuicParam);
531 }
532
533 TEST_F(NetLogFileWriterTest, ReceiveStartWhileInitializing) {
534 // Trigger initialization of |net_log_file_writer_|.
535 TestStateCallback init_callback;
536 net_log_file_writer_.GetState(init_callback.callback());
537
538 // Before running the main message loop, tell |net_log_file_writer_| to start
539 // logging. Not running the main message loop prevents the initialization
540 // process from completing, so this ensures that StartNetLog() is received
541 // before |net_log_file_writer_| finishes initialization, which means this
542 // should be a no-op.
543 TestStateCallback start_during_init_callback;
544 net_log_file_writer_.StartNetLog(base::FilePath(),
545 net::NetLogCaptureMode::Default(),
546 start_during_init_callback.callback());
547
548 // Now run the main message loop. The state returned by the GetState() call
549 // should be the state after initialization, which should indicate
550 // not-logging.
551 VerifyState(init_callback.WaitForResult(), kStateNotLoggingString, false,
552 false, "");
553
554 // The state returned by the ignored StartNetLog() call should also be the
555 // state after the ongoing initialization finishes, so it should be identical
556 // to the state returned by GetState().
557 VerifyState(start_during_init_callback.WaitForResult(),
558 kStateNotLoggingString, false, false, "");
559
560 // Run an additional GetState() just to make sure |net_log_file_writer_| is
561 // not logging.
562 VerifyState(FileWriterGetState(), kStateNotLoggingString, false, false, "");
563 }
564
565 TEST_F(NetLogFileWriterTest, ReceiveStartWhileStoppingLog) {
566 // Call StartNetLog() on |net_log_file_writer_| and wait for it to run its
567 // state callback.
568 StartThenVerifyState(base::FilePath(),
569 net::NetLogCaptureMode::IncludeSocketBytes(),
570 kCaptureModeIncludeSocketBytesString);
571
572 // Tell |net_log_file_writer_| to stop logging.
573 TestStateCallback stop_callback;
574 net_log_file_writer_.StopNetLog(nullptr, nullptr, stop_callback.callback());
575
576 // Before running the main message loop, tell |net_log_file_writer_| to start
577 // logging. Not running the main message loop prevents the stopping process
578 // from completing, so this ensures StartNetLog() is received before
579 // |net_log_file_writer_| finishes stopping, which means this should be a
580 // no-op.
581 TestStateCallback start_during_stop_callback;
582 net_log_file_writer_.StartNetLog(base::FilePath(),
583 net::NetLogCaptureMode::Default(),
584 start_during_stop_callback.callback());
585
586 // Now run the main message loop. Since StartNetLog() will be a no-op, it will
587 // simply run the state callback. There are no guarantees for when this state
588 // callback will execute if StartNetLog() is called during the stopping
589 // process, so the state it returns could either be stopping-log or
590 // not-logging. For simplicity, the returned state will not be verified.
591 start_during_stop_callback.WaitForResult();
592
593 // The state returned by the StopNetLog() call should be the state after
594 // stopping, which should indicate not-logging. Also, the capture mode should
595 // be the same as the one passed to the first StartNetLog() call, not the
596 // second (ignored) one.
597 VerifyState(stop_callback.WaitForResult(), kStateNotLoggingString, true, true,
598 kCaptureModeIncludeSocketBytesString);
599
600 // Run an additional GetState() just to make sure |net_log_file_writer_| is
601 // not logging.
602 VerifyState(FileWriterGetState(), kStateNotLoggingString, true, true,
603 kCaptureModeIncludeSocketBytesString);
444 } 604 }
445 605
446 } // namespace net_log 606 } // namespace net_log
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698