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 "testing/gtest/include/gtest/gtest.h"
19 using content::BrowserThread
;
21 class TestNetLogTempFile
: public NetLogTempFile
{
23 explicit TestNetLogTempFile(ChromeNetLog
* chrome_net_log
)
24 : NetLogTempFile(chrome_net_log
),
25 lie_about_net_export_log_directory_(false),
26 lie_about_file_existence_(false) {
29 // NetLogTempFile implementation:
30 bool GetNetExportLogDirectory(base::FilePath
* path
) override
{
31 if (lie_about_net_export_log_directory_
)
33 return NetLogTempFile::GetNetExportLogDirectory(path
);
36 bool NetExportLogExists() override
{
37 if (lie_about_file_existence_
)
39 return NetLogTempFile::NetExportLogExists();
42 void set_lie_about_net_export_log_directory(
43 bool lie_about_net_export_log_directory
) {
44 lie_about_net_export_log_directory_
= lie_about_net_export_log_directory
;
47 void set_lie_about_file_existence(bool lie_about_file_existence
) {
48 lie_about_file_existence_
= lie_about_file_existence
;
52 bool lie_about_net_export_log_directory_
;
53 bool lie_about_file_existence_
;
56 class NetLogTempFileTest
: public ::testing::Test
{
59 : net_log_(new ChromeNetLog
),
60 net_log_temp_file_(new TestNetLogTempFile(net_log_
.get())),
61 file_user_blocking_thread_(BrowserThread::FILE_USER_BLOCKING
,
65 // ::testing::Test implementation:
66 void SetUp() override
{
67 // Get a temporary file name for unit tests.
68 base::FilePath net_log_dir
;
69 ASSERT_TRUE(net_log_temp_file_
->GetNetExportLogDirectory(&net_log_dir
));
70 ASSERT_TRUE(base::CreateTemporaryFileInDir(net_log_dir
, &net_export_log_
));
72 net_log_temp_file_
->log_filename_
= net_export_log_
.BaseName().value();
74 // CreateTemporaryFileInDir may return a legacy 8.3 file name on windows.
75 // Need to use the original directory name for string comparisons.
76 ASSERT_TRUE(net_log_temp_file_
->GetNetExportLog());
77 net_export_log_
= net_log_temp_file_
->log_path_
;
78 ASSERT_FALSE(net_export_log_
.empty());
81 void TearDown() override
{
82 // Delete the temporary file we have created.
83 ASSERT_TRUE(base::DeleteFile(net_export_log_
, false));
86 std::string
GetStateString() const {
87 scoped_ptr
<base::DictionaryValue
> dict(net_log_temp_file_
->GetState());
89 EXPECT_TRUE(dict
->GetString("state", &state
));
93 std::string
GetLogTypeString() const {
94 scoped_ptr
<base::DictionaryValue
> dict(net_log_temp_file_
->GetState());
96 EXPECT_TRUE(dict
->GetString("logType", &log_type
));
100 // Make sure the export file has been created and is non-empty, as net
101 // constants will always be written to it on creation.
102 void VerifyNetExportLogExists() const {
103 EXPECT_EQ(net_export_log_
, net_log_temp_file_
->log_path_
);
104 ASSERT_TRUE(base::PathExists(net_export_log_
));
107 // base::GetFileSize returns proper file size on open handles.
108 ASSERT_TRUE(base::GetFileSize(net_export_log_
, &file_size
));
109 EXPECT_GT(file_size
, 0);
112 // Make sure the export file has been created and a valid JSON file. This
113 // should always be the case once logging has been stopped.
114 void VerifyNetExportLogComplete() const {
115 VerifyNetExportLogExists();
118 ASSERT_TRUE(ReadFileToString(net_export_log_
, &log
));
119 base::JSONReader reader
;
120 scoped_ptr
<base::Value
> json(base::JSONReader::Read(log
));
124 // Verify state and GetFilePath return correct values if EnsureInit() fails.
125 void VerifyFilePathAndStateAfterEnsureInitFailure() {
126 EXPECT_EQ("UNINITIALIZED", GetStateString());
127 EXPECT_EQ(NetLogTempFile::STATE_UNINITIALIZED
,
128 net_log_temp_file_
->state());
130 base::FilePath net_export_file_path
;
131 EXPECT_FALSE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
134 // When we lie in NetExportLogExists, make sure state and GetFilePath return
136 void VerifyFilePathAndStateAfterEnsureInit() {
137 EXPECT_EQ("NOT_LOGGING", GetStateString());
138 EXPECT_EQ(NetLogTempFile::STATE_NOT_LOGGING
, net_log_temp_file_
->state());
139 EXPECT_EQ("NONE", GetLogTypeString());
140 EXPECT_EQ(NetLogTempFile::LOG_TYPE_NONE
, net_log_temp_file_
->log_type());
142 base::FilePath net_export_file_path
;
143 EXPECT_FALSE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
144 EXPECT_FALSE(net_log_temp_file_
->NetExportLogExists());
147 // The following methods make sure the export file has been successfully
148 // initialized by a DO_START command of the given type.
150 void VerifyFileAndStateAfterDoStart() {
151 VerifyFileAndStateAfterStart(NetLogTempFile::LOG_TYPE_NORMAL
, "NORMAL",
152 net::NetLog::LOG_ALL_BUT_BYTES
);
155 void VerifyFileAndStateAfterDoStartStripPrivateData() const {
156 VerifyFileAndStateAfterStart(NetLogTempFile::LOG_TYPE_STRIP_PRIVATE_DATA
,
157 "STRIP_PRIVATE_DATA",
158 net::NetLog::LOG_STRIP_PRIVATE_DATA
);
161 void VerifyFileAndStateAfterDoStartLogBytes() const {
162 VerifyFileAndStateAfterStart(NetLogTempFile::LOG_TYPE_LOG_BYTES
,
163 "LOG_BYTES", net::NetLog::LOG_ALL
);
166 // Make sure the export file has been successfully initialized after DO_STOP
167 // command following a DO_START command of the given type.
169 void VerifyFileAndStateAfterDoStop() const {
170 VerifyFileAndStateAfterDoStop(NetLogTempFile::LOG_TYPE_NORMAL
, "NORMAL");
173 void VerifyFileAndStateAfterDoStopWithStripPrivateData() const {
174 VerifyFileAndStateAfterDoStop(NetLogTempFile::LOG_TYPE_STRIP_PRIVATE_DATA
,
175 "STRIP_PRIVATE_DATA");
178 void VerifyFileAndStateAfterDoStopWithLogBytes() const {
179 VerifyFileAndStateAfterDoStop(NetLogTempFile::LOG_TYPE_LOG_BYTES
,
183 scoped_ptr
<ChromeNetLog
> net_log_
;
184 // |net_log_temp_file_| is initialized after |net_log_| so that it can stop
185 // obvserving on destruction.
186 scoped_ptr
<TestNetLogTempFile
> net_log_temp_file_
;
187 base::FilePath net_export_log_
;
190 // Checks state after one of the DO_START* commands.
191 void VerifyFileAndStateAfterStart(
192 NetLogTempFile::LogType expected_log_type
,
193 const std::string
& expected_log_type_string
,
194 net::NetLog::LogLevel expected_log_level
) const {
195 EXPECT_EQ(NetLogTempFile::STATE_LOGGING
, net_log_temp_file_
->state());
196 EXPECT_EQ("LOGGING", GetStateString());
197 EXPECT_EQ(expected_log_type
, net_log_temp_file_
->log_type());
198 EXPECT_EQ(expected_log_type_string
, GetLogTypeString());
200 EXPECT_EQ(expected_log_level
, net_log_
->GetLogLevel());
202 // Check GetFilePath returns false when still writing to the file.
203 base::FilePath net_export_file_path
;
204 EXPECT_FALSE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
206 VerifyNetExportLogExists();
209 void VerifyFileAndStateAfterDoStop(
210 NetLogTempFile::LogType expected_log_type
,
211 const std::string
& expected_log_type_string
) const {
212 EXPECT_EQ(NetLogTempFile::STATE_NOT_LOGGING
, net_log_temp_file_
->state());
213 EXPECT_EQ("NOT_LOGGING", GetStateString());
214 EXPECT_EQ(expected_log_type
, net_log_temp_file_
->log_type());
215 EXPECT_EQ(expected_log_type_string
, GetLogTypeString());
217 base::FilePath net_export_file_path
;
218 EXPECT_TRUE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
219 EXPECT_EQ(net_export_log_
, net_export_file_path
);
221 VerifyNetExportLogComplete();
224 base::MessageLoop message_loop_
;
225 content::TestBrowserThread file_user_blocking_thread_
;
228 TEST_F(NetLogTempFileTest
, EnsureInitFailure
) {
229 net_log_temp_file_
->set_lie_about_net_export_log_directory(true);
231 EXPECT_FALSE(net_log_temp_file_
->EnsureInit());
232 VerifyFilePathAndStateAfterEnsureInitFailure();
234 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
235 VerifyFilePathAndStateAfterEnsureInitFailure();
238 TEST_F(NetLogTempFileTest
, EnsureInitAllowStart
) {
239 net_log_temp_file_
->set_lie_about_file_existence(true);
241 EXPECT_TRUE(net_log_temp_file_
->EnsureInit());
242 VerifyFilePathAndStateAfterEnsureInit();
244 // Calling EnsureInit() second time should be a no-op.
245 EXPECT_TRUE(net_log_temp_file_
->EnsureInit());
246 VerifyFilePathAndStateAfterEnsureInit();
249 TEST_F(NetLogTempFileTest
, EnsureInitAllowStartOrSend
) {
250 EXPECT_TRUE(net_log_temp_file_
->EnsureInit());
252 EXPECT_EQ("NOT_LOGGING", GetStateString());
253 EXPECT_EQ(NetLogTempFile::STATE_NOT_LOGGING
, net_log_temp_file_
->state());
254 EXPECT_EQ("UNKNOWN", GetLogTypeString());
255 EXPECT_EQ(NetLogTempFile::LOG_TYPE_UNKNOWN
, net_log_temp_file_
->log_type());
256 EXPECT_EQ(net_export_log_
, net_log_temp_file_
->log_path_
);
257 EXPECT_TRUE(base::PathExists(net_export_log_
));
259 base::FilePath net_export_file_path
;
260 EXPECT_TRUE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
261 EXPECT_TRUE(base::PathExists(net_export_file_path
));
262 EXPECT_EQ(net_export_log_
, net_export_file_path
);
264 // GetFilePath should return false if NetExportLogExists() fails.
265 net_log_temp_file_
->set_lie_about_file_existence(true);
266 EXPECT_FALSE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
269 TEST_F(NetLogTempFileTest
, ProcessCommandDoStartAndStop
) {
270 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
271 VerifyFileAndStateAfterDoStart();
273 // Calling a second time should be a no-op.
274 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
275 VerifyFileAndStateAfterDoStart();
277 // starting with other log levels should also be no-ops.
278 net_log_temp_file_
->ProcessCommand(
279 NetLogTempFile::DO_START_STRIP_PRIVATE_DATA
);
280 VerifyFileAndStateAfterDoStart();
281 net_log_temp_file_
->ProcessCommand(
282 NetLogTempFile::DO_START_LOG_BYTES
);
283 VerifyFileAndStateAfterDoStart();
285 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
286 VerifyFileAndStateAfterDoStop();
288 // Calling DO_STOP second time should be a no-op.
289 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
290 VerifyFileAndStateAfterDoStop();
293 TEST_F(NetLogTempFileTest
,
294 ProcessCommandDoStartAndStopWithPrivateDataStripping
) {
295 net_log_temp_file_
->ProcessCommand(
296 NetLogTempFile::DO_START_STRIP_PRIVATE_DATA
);
297 VerifyFileAndStateAfterDoStartStripPrivateData();
299 // Calling a second time should be a no-op.
300 net_log_temp_file_
->ProcessCommand(
301 NetLogTempFile::DO_START_STRIP_PRIVATE_DATA
);
302 VerifyFileAndStateAfterDoStartStripPrivateData();
304 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
305 VerifyFileAndStateAfterDoStopWithStripPrivateData();
307 // Calling DO_STOP second time should be a no-op.
308 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
309 VerifyFileAndStateAfterDoStopWithStripPrivateData();
312 TEST_F(NetLogTempFileTest
,
313 ProcessCommandDoStartAndStopWithByteLogging
) {
314 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START_LOG_BYTES
);
315 VerifyFileAndStateAfterDoStartLogBytes();
317 // Calling a second time should be a no-op.
318 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START_LOG_BYTES
);
319 VerifyFileAndStateAfterDoStartLogBytes();
321 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
322 VerifyFileAndStateAfterDoStopWithLogBytes();
324 // Calling DO_STOP second time should be a no-op.
325 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
326 VerifyFileAndStateAfterDoStopWithLogBytes();
329 TEST_F(NetLogTempFileTest
, DoStartClearsFile
) {
330 // Verify file sizes after two consecutives start/stop are the same (even if
331 // we add some junk data in between).
332 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
333 VerifyFileAndStateAfterDoStart();
335 int64 start_file_size
;
336 EXPECT_TRUE(base::GetFileSize(net_export_log_
, &start_file_size
));
338 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
339 VerifyFileAndStateAfterDoStop();
341 int64 stop_file_size
;
342 EXPECT_TRUE(base::GetFileSize(net_export_log_
, &stop_file_size
));
343 EXPECT_GE(stop_file_size
, start_file_size
);
345 // Add some junk at the end of the file.
346 std::string
junk_data("Hello");
347 EXPECT_TRUE(base::AppendToFile(net_export_log_
, junk_data
.c_str(),
350 int64 junk_file_size
;
351 EXPECT_TRUE(base::GetFileSize(net_export_log_
, &junk_file_size
));
352 EXPECT_GT(junk_file_size
, stop_file_size
);
354 // Execute DO_START/DO_STOP commands and make sure the file is back to the
355 // size before addition of junk data.
356 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
357 VerifyFileAndStateAfterDoStart();
359 int64 new_start_file_size
;
360 EXPECT_TRUE(base::GetFileSize(net_export_log_
, &new_start_file_size
));
361 EXPECT_EQ(new_start_file_size
, start_file_size
);
363 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
364 VerifyFileAndStateAfterDoStop();
366 int64 new_stop_file_size
;
367 EXPECT_TRUE(base::GetFileSize(net_export_log_
, &new_stop_file_size
));
368 EXPECT_EQ(new_stop_file_size
, stop_file_size
);
371 TEST_F(NetLogTempFileTest
, CheckAddEvent
) {
372 // Add an event to |net_log_| and then test to make sure that, after we stop
373 // logging, the file is larger than the file created without that event.
374 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
375 VerifyFileAndStateAfterDoStart();
377 // Get file size without the event.
378 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
379 VerifyFileAndStateAfterDoStop();
381 int64 stop_file_size
;
382 EXPECT_TRUE(base::GetFileSize(net_export_log_
, &stop_file_size
));
384 // Perform DO_START and add an Event and then DO_STOP and then compare
386 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
387 VerifyFileAndStateAfterDoStart();
390 net_log_
->AddGlobalEntry(net::NetLog::TYPE_CANCELLED
);
392 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
393 VerifyFileAndStateAfterDoStop();
395 int64 new_stop_file_size
;
396 EXPECT_TRUE(base::GetFileSize(net_export_log_
, &new_stop_file_size
));
397 EXPECT_GE(new_stop_file_size
, stop_file_size
);