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
3 // found in the LICENSE file.
5 #include "chrome/browser/net/net_log_temp_file.h"
7 #include "base/basictypes.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/json/json_reader.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/values.h"
14 #include "build/build_config.h"
15 #include "chrome/browser/net/chrome_net_log.h"
16 #include "content/public/test/test_browser_thread.h"
17 #include "net/log/write_to_file_net_log_observer.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 using content::BrowserThread
;
22 class TestNetLogTempFile
: public NetLogTempFile
{
24 explicit TestNetLogTempFile(ChromeNetLog
* chrome_net_log
)
25 : NetLogTempFile(chrome_net_log
),
26 lie_about_net_export_log_directory_(false),
27 lie_about_file_existence_(false) {
30 // NetLogTempFile implementation:
31 bool GetNetExportLogDirectory(base::FilePath
* path
) override
{
32 if (lie_about_net_export_log_directory_
)
34 return NetLogTempFile::GetNetExportLogDirectory(path
);
37 bool NetExportLogExists() override
{
38 if (lie_about_file_existence_
)
40 return NetLogTempFile::NetExportLogExists();
43 void set_lie_about_net_export_log_directory(
44 bool lie_about_net_export_log_directory
) {
45 lie_about_net_export_log_directory_
= lie_about_net_export_log_directory
;
48 void set_lie_about_file_existence(bool lie_about_file_existence
) {
49 lie_about_file_existence_
= lie_about_file_existence
;
53 bool lie_about_net_export_log_directory_
;
54 bool lie_about_file_existence_
;
57 class NetLogTempFileTest
: public ::testing::Test
{
60 : net_log_(new ChromeNetLog
),
61 net_log_temp_file_(new TestNetLogTempFile(net_log_
.get())),
62 file_user_blocking_thread_(BrowserThread::FILE_USER_BLOCKING
,
66 // ::testing::Test implementation:
67 void SetUp() override
{
68 // Get a temporary file name for unit tests.
69 base::FilePath net_log_dir
;
70 ASSERT_TRUE(net_log_temp_file_
->GetNetExportLogDirectory(&net_log_dir
));
71 ASSERT_TRUE(base::CreateTemporaryFileInDir(net_log_dir
, &net_export_log_
));
73 net_log_temp_file_
->log_filename_
= net_export_log_
.BaseName().value();
75 // CreateTemporaryFileInDir may return a legacy 8.3 file name on windows.
76 // Need to use the original directory name for string comparisons.
77 ASSERT_TRUE(net_log_temp_file_
->GetNetExportLog());
78 net_export_log_
= net_log_temp_file_
->log_path_
;
79 ASSERT_FALSE(net_export_log_
.empty());
82 void TearDown() override
{
83 // Delete the temporary file we have created.
84 ASSERT_TRUE(base::DeleteFile(net_export_log_
, false));
87 std::string
GetStateString() const {
88 scoped_ptr
<base::DictionaryValue
> dict(net_log_temp_file_
->GetState());
90 EXPECT_TRUE(dict
->GetString("state", &state
));
94 std::string
GetLogTypeString() const {
95 scoped_ptr
<base::DictionaryValue
> dict(net_log_temp_file_
->GetState());
97 EXPECT_TRUE(dict
->GetString("logType", &log_type
));
101 // Make sure the export file has been created and is non-empty, as net
102 // constants will always be written to it on creation.
103 void VerifyNetExportLogExists() const {
104 EXPECT_EQ(net_export_log_
, net_log_temp_file_
->log_path_
);
105 ASSERT_TRUE(base::PathExists(net_export_log_
));
108 // base::GetFileSize returns proper file size on open handles.
109 ASSERT_TRUE(base::GetFileSize(net_export_log_
, &file_size
));
110 EXPECT_GT(file_size
, 0);
113 // Make sure the export file has been created and a valid JSON file. This
114 // should always be the case once logging has been stopped.
115 void VerifyNetExportLogComplete() const {
116 VerifyNetExportLogExists();
119 ASSERT_TRUE(ReadFileToString(net_export_log_
, &log
));
120 base::JSONReader reader
;
121 scoped_ptr
<base::Value
> json
= base::JSONReader::Read(log
);
125 // Verify state and GetFilePath return correct values if EnsureInit() fails.
126 void VerifyFilePathAndStateAfterEnsureInitFailure() {
127 EXPECT_EQ("UNINITIALIZED", GetStateString());
128 EXPECT_EQ(NetLogTempFile::STATE_UNINITIALIZED
,
129 net_log_temp_file_
->state());
131 base::FilePath net_export_file_path
;
132 EXPECT_FALSE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
135 // When we lie in NetExportLogExists, make sure state and GetFilePath return
137 void VerifyFilePathAndStateAfterEnsureInit() {
138 EXPECT_EQ("NOT_LOGGING", GetStateString());
139 EXPECT_EQ(NetLogTempFile::STATE_NOT_LOGGING
, net_log_temp_file_
->state());
140 EXPECT_EQ("NONE", GetLogTypeString());
141 EXPECT_EQ(NetLogTempFile::LOG_TYPE_NONE
, net_log_temp_file_
->log_type());
143 base::FilePath net_export_file_path
;
144 EXPECT_FALSE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
145 EXPECT_FALSE(net_log_temp_file_
->NetExportLogExists());
148 // The following methods make sure the export file has been successfully
149 // initialized by a DO_START command of the given type.
151 void VerifyFileAndStateAfterDoStart() {
152 VerifyFileAndStateAfterStart(
153 NetLogTempFile::LOG_TYPE_NORMAL
, "NORMAL",
154 net::NetLogCaptureMode::IncludeCookiesAndCredentials());
157 void VerifyFileAndStateAfterDoStartStripPrivateData() const {
158 VerifyFileAndStateAfterStart(NetLogTempFile::LOG_TYPE_STRIP_PRIVATE_DATA
,
159 "STRIP_PRIVATE_DATA",
160 net::NetLogCaptureMode::Default());
163 void VerifyFileAndStateAfterDoStartLogBytes() const {
164 VerifyFileAndStateAfterStart(NetLogTempFile::LOG_TYPE_LOG_BYTES
,
166 net::NetLogCaptureMode::IncludeSocketBytes());
169 // Make sure the export file has been successfully initialized after DO_STOP
170 // command following a DO_START command of the given type.
172 void VerifyFileAndStateAfterDoStop() const {
173 VerifyFileAndStateAfterDoStop(NetLogTempFile::LOG_TYPE_NORMAL
, "NORMAL");
176 void VerifyFileAndStateAfterDoStopWithStripPrivateData() const {
177 VerifyFileAndStateAfterDoStop(NetLogTempFile::LOG_TYPE_STRIP_PRIVATE_DATA
,
178 "STRIP_PRIVATE_DATA");
181 void VerifyFileAndStateAfterDoStopWithLogBytes() const {
182 VerifyFileAndStateAfterDoStop(NetLogTempFile::LOG_TYPE_LOG_BYTES
,
186 scoped_ptr
<ChromeNetLog
> net_log_
;
187 // |net_log_temp_file_| is initialized after |net_log_| so that it can stop
188 // obvserving on destruction.
189 scoped_ptr
<TestNetLogTempFile
> net_log_temp_file_
;
190 base::FilePath net_export_log_
;
193 // Checks state after one of the DO_START* commands.
194 void VerifyFileAndStateAfterStart(
195 NetLogTempFile::LogType expected_log_type
,
196 const std::string
& expected_log_type_string
,
197 net::NetLogCaptureMode expected_capture_mode
) const {
198 EXPECT_EQ(NetLogTempFile::STATE_LOGGING
, net_log_temp_file_
->state());
199 EXPECT_EQ("LOGGING", GetStateString());
200 EXPECT_EQ(expected_log_type
, net_log_temp_file_
->log_type());
201 EXPECT_EQ(expected_log_type_string
, GetLogTypeString());
202 EXPECT_EQ(expected_capture_mode
,
203 net_log_temp_file_
->write_to_file_observer_
->capture_mode());
205 // Check GetFilePath returns false when still writing to the file.
206 base::FilePath net_export_file_path
;
207 EXPECT_FALSE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
209 VerifyNetExportLogExists();
212 void VerifyFileAndStateAfterDoStop(
213 NetLogTempFile::LogType expected_log_type
,
214 const std::string
& expected_log_type_string
) const {
215 EXPECT_EQ(NetLogTempFile::STATE_NOT_LOGGING
, net_log_temp_file_
->state());
216 EXPECT_EQ("NOT_LOGGING", GetStateString());
217 EXPECT_EQ(expected_log_type
, net_log_temp_file_
->log_type());
218 EXPECT_EQ(expected_log_type_string
, GetLogTypeString());
220 base::FilePath net_export_file_path
;
221 EXPECT_TRUE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
222 EXPECT_EQ(net_export_log_
, net_export_file_path
);
224 VerifyNetExportLogComplete();
227 base::MessageLoop message_loop_
;
228 content::TestBrowserThread file_user_blocking_thread_
;
231 TEST_F(NetLogTempFileTest
, EnsureInitFailure
) {
232 net_log_temp_file_
->set_lie_about_net_export_log_directory(true);
234 EXPECT_FALSE(net_log_temp_file_
->EnsureInit());
235 VerifyFilePathAndStateAfterEnsureInitFailure();
237 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
238 VerifyFilePathAndStateAfterEnsureInitFailure();
241 TEST_F(NetLogTempFileTest
, EnsureInitAllowStart
) {
242 net_log_temp_file_
->set_lie_about_file_existence(true);
244 EXPECT_TRUE(net_log_temp_file_
->EnsureInit());
245 VerifyFilePathAndStateAfterEnsureInit();
247 // Calling EnsureInit() second time should be a no-op.
248 EXPECT_TRUE(net_log_temp_file_
->EnsureInit());
249 VerifyFilePathAndStateAfterEnsureInit();
252 TEST_F(NetLogTempFileTest
, EnsureInitAllowStartOrSend
) {
253 EXPECT_TRUE(net_log_temp_file_
->EnsureInit());
255 EXPECT_EQ("NOT_LOGGING", GetStateString());
256 EXPECT_EQ(NetLogTempFile::STATE_NOT_LOGGING
, net_log_temp_file_
->state());
257 EXPECT_EQ("UNKNOWN", GetLogTypeString());
258 EXPECT_EQ(NetLogTempFile::LOG_TYPE_UNKNOWN
, net_log_temp_file_
->log_type());
259 EXPECT_EQ(net_export_log_
, net_log_temp_file_
->log_path_
);
260 EXPECT_TRUE(base::PathExists(net_export_log_
));
262 base::FilePath net_export_file_path
;
263 EXPECT_TRUE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
264 EXPECT_TRUE(base::PathExists(net_export_file_path
));
265 EXPECT_EQ(net_export_log_
, net_export_file_path
);
267 // GetFilePath should return false if NetExportLogExists() fails.
268 net_log_temp_file_
->set_lie_about_file_existence(true);
269 EXPECT_FALSE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
272 TEST_F(NetLogTempFileTest
, ProcessCommandDoStartAndStop
) {
273 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
274 VerifyFileAndStateAfterDoStart();
276 // Calling a second time should be a no-op.
277 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
278 VerifyFileAndStateAfterDoStart();
280 // starting with other log levels should also be no-ops.
281 net_log_temp_file_
->ProcessCommand(
282 NetLogTempFile::DO_START_STRIP_PRIVATE_DATA
);
283 VerifyFileAndStateAfterDoStart();
284 net_log_temp_file_
->ProcessCommand(
285 NetLogTempFile::DO_START_LOG_BYTES
);
286 VerifyFileAndStateAfterDoStart();
288 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
289 VerifyFileAndStateAfterDoStop();
291 // Calling DO_STOP second time should be a no-op.
292 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
293 VerifyFileAndStateAfterDoStop();
296 TEST_F(NetLogTempFileTest
,
297 ProcessCommandDoStartAndStopWithPrivateDataStripping
) {
298 net_log_temp_file_
->ProcessCommand(
299 NetLogTempFile::DO_START_STRIP_PRIVATE_DATA
);
300 VerifyFileAndStateAfterDoStartStripPrivateData();
302 // Calling a second time should be a no-op.
303 net_log_temp_file_
->ProcessCommand(
304 NetLogTempFile::DO_START_STRIP_PRIVATE_DATA
);
305 VerifyFileAndStateAfterDoStartStripPrivateData();
307 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
308 VerifyFileAndStateAfterDoStopWithStripPrivateData();
310 // Calling DO_STOP second time should be a no-op.
311 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
312 VerifyFileAndStateAfterDoStopWithStripPrivateData();
315 TEST_F(NetLogTempFileTest
,
316 ProcessCommandDoStartAndStopWithByteLogging
) {
317 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START_LOG_BYTES
);
318 VerifyFileAndStateAfterDoStartLogBytes();
320 // Calling a second time should be a no-op.
321 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START_LOG_BYTES
);
322 VerifyFileAndStateAfterDoStartLogBytes();
324 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
325 VerifyFileAndStateAfterDoStopWithLogBytes();
327 // Calling DO_STOP second time should be a no-op.
328 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
329 VerifyFileAndStateAfterDoStopWithLogBytes();
332 TEST_F(NetLogTempFileTest
, DoStartClearsFile
) {
333 // Verify file sizes after two consecutives start/stop are the same (even if
334 // we add some junk data in between).
335 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
336 VerifyFileAndStateAfterDoStart();
338 int64 start_file_size
;
339 EXPECT_TRUE(base::GetFileSize(net_export_log_
, &start_file_size
));
341 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
342 VerifyFileAndStateAfterDoStop();
344 int64 stop_file_size
;
345 EXPECT_TRUE(base::GetFileSize(net_export_log_
, &stop_file_size
));
346 EXPECT_GE(stop_file_size
, start_file_size
);
348 // Add some junk at the end of the file.
349 std::string
junk_data("Hello");
350 EXPECT_TRUE(base::AppendToFile(net_export_log_
, junk_data
.c_str(),
353 int64 junk_file_size
;
354 EXPECT_TRUE(base::GetFileSize(net_export_log_
, &junk_file_size
));
355 EXPECT_GT(junk_file_size
, stop_file_size
);
357 // Execute DO_START/DO_STOP commands and make sure the file is back to the
358 // size before addition of junk data.
359 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
360 VerifyFileAndStateAfterDoStart();
362 int64 new_start_file_size
;
363 EXPECT_TRUE(base::GetFileSize(net_export_log_
, &new_start_file_size
));
364 EXPECT_EQ(new_start_file_size
, start_file_size
);
366 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
367 VerifyFileAndStateAfterDoStop();
369 int64 new_stop_file_size
;
370 EXPECT_TRUE(base::GetFileSize(net_export_log_
, &new_stop_file_size
));
371 EXPECT_EQ(new_stop_file_size
, stop_file_size
);
374 TEST_F(NetLogTempFileTest
, CheckAddEvent
) {
375 // Add an event to |net_log_| and then test to make sure that, after we stop
376 // logging, the file is larger than the file created without that event.
377 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
378 VerifyFileAndStateAfterDoStart();
380 // Get file size without the event.
381 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
382 VerifyFileAndStateAfterDoStop();
384 int64 stop_file_size
;
385 EXPECT_TRUE(base::GetFileSize(net_export_log_
, &stop_file_size
));
387 // Perform DO_START and add an Event and then DO_STOP and then compare
389 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
390 VerifyFileAndStateAfterDoStart();
393 net_log_
->AddGlobalEntry(net::NetLog::TYPE_CANCELLED
);
395 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
396 VerifyFileAndStateAfterDoStop();
398 int64 new_stop_file_size
;
399 EXPECT_TRUE(base::GetFileSize(net_export_log_
, &new_stop_file_size
));
400 EXPECT_GE(new_stop_file_size
, stop_file_size
);