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/file_util.h"
9 #include "base/files/file_path.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/values.h"
12 #include "build/build_config.h"
13 #include "chrome/browser/net/chrome_net_log.h"
14 #include "content/public/test/test_browser_thread.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 using content::BrowserThread
;
19 class TestNetLogTempFile
: public NetLogTempFile
{
21 explicit TestNetLogTempFile(ChromeNetLog
* chrome_net_log
)
22 : NetLogTempFile(chrome_net_log
),
23 lie_about_net_export_log_directory_(false),
24 lie_about_file_existence_(false) {
27 // NetLogTempFile implementation:
28 virtual bool GetNetExportLogDirectory(base::FilePath
* path
) OVERRIDE
{
29 if (lie_about_net_export_log_directory_
)
31 return NetLogTempFile::GetNetExportLogDirectory(path
);
34 virtual bool NetExportLogExists() OVERRIDE
{
35 if (lie_about_file_existence_
)
37 return NetLogTempFile::NetExportLogExists();
40 void set_lie_about_net_export_log_directory(
41 bool lie_about_net_export_log_directory
) {
42 lie_about_net_export_log_directory_
= lie_about_net_export_log_directory
;
45 void set_lie_about_file_existence(bool lie_about_file_existence
) {
46 lie_about_file_existence_
= lie_about_file_existence
;
50 bool lie_about_net_export_log_directory_
;
51 bool lie_about_file_existence_
;
54 class NetLogTempFileTest
: public ::testing::Test
{
57 : net_log_(new ChromeNetLog
),
58 net_log_temp_file_(new TestNetLogTempFile(net_log_
.get())),
59 file_user_blocking_thread_(BrowserThread::FILE_USER_BLOCKING
,
63 // ::testing::Test implementation:
64 virtual void SetUp() OVERRIDE
{
65 // Get a temporary file name for unit tests.
66 base::FilePath net_log_dir
;
67 ASSERT_TRUE(net_log_temp_file_
->GetNetExportLogDirectory(&net_log_dir
));
68 ASSERT_TRUE(file_util::CreateTemporaryFileInDir(net_log_dir
,
71 net_log_temp_file_
->log_filename_
= net_export_log_
.BaseName().value();
73 // CreateTemporaryFileInDir may return a legacy 8.3 file name on windows.
74 // Need to use the original directory name for string comparisons.
75 ASSERT_TRUE(net_log_temp_file_
->GetNetExportLog());
76 net_export_log_
= net_log_temp_file_
->log_path_
;
77 ASSERT_FALSE(net_export_log_
.empty());
80 virtual void TearDown() OVERRIDE
{
81 // Delete the temporary file we have created.
82 ASSERT_TRUE(base::DeleteFile(net_export_log_
, false));
85 std::string
GetStateString() const {
86 scoped_ptr
<base::DictionaryValue
> dict(net_log_temp_file_
->GetState());
88 EXPECT_TRUE(dict
->GetString("state", &state
));
92 // Make sure the export file has been created and is non-empty, as net
93 // constants will always be written to it on creation.
94 void VerifyNetExportLog() {
95 EXPECT_EQ(net_export_log_
, net_log_temp_file_
->log_path_
);
96 EXPECT_TRUE(base::PathExists(net_export_log_
));
99 // file_util::GetFileSize returns proper file size on open handles.
100 EXPECT_TRUE(file_util::GetFileSize(net_export_log_
, &file_size
));
101 EXPECT_GT(file_size
, 0);
104 // Verify state and GetFilePath return correct values if EnsureInit() fails.
105 void VerifyFilePathAndStateAfterEnsureInitFailure() {
106 EXPECT_EQ("UNINITIALIZED", GetStateString());
107 EXPECT_EQ(NetLogTempFile::STATE_UNINITIALIZED
,
108 net_log_temp_file_
->state());
110 base::FilePath net_export_file_path
;
111 EXPECT_FALSE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
114 // When we lie in NetExportLogExists, make sure state and GetFilePath return
116 void VerifyFilePathAndStateAfterEnsureInit() {
117 EXPECT_EQ("ALLOW_START", GetStateString());
118 EXPECT_EQ(NetLogTempFile::STATE_ALLOW_START
, net_log_temp_file_
->state());
120 base::FilePath net_export_file_path
;
121 EXPECT_FALSE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
122 EXPECT_FALSE(net_log_temp_file_
->NetExportLogExists());
125 // Make sure the export file has been successfully initialized.
126 void VerifyFileAndStateAfterDoStart() {
127 EXPECT_EQ("ALLOW_STOP", GetStateString());
128 EXPECT_EQ(NetLogTempFile::STATE_ALLOW_STOP
, net_log_temp_file_
->state());
130 // Check GetFilePath returns false, if we are still writing to file.
131 base::FilePath net_export_file_path
;
132 EXPECT_FALSE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
134 VerifyNetExportLog();
137 // Make sure the export file has been successfully initialized.
138 void VerifyFileAndStateAfterDoStop() {
139 EXPECT_EQ("ALLOW_START_SEND", GetStateString());
140 EXPECT_EQ(NetLogTempFile::STATE_ALLOW_START_SEND
,
141 net_log_temp_file_
->state());
143 base::FilePath net_export_file_path
;
144 EXPECT_TRUE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
145 EXPECT_TRUE(base::PathExists(net_export_file_path
));
146 EXPECT_EQ(net_export_log_
, net_export_file_path
);
148 VerifyNetExportLog();
151 scoped_ptr
<ChromeNetLog
> net_log_
;
152 // |net_log_temp_file_| is initialized after |net_log_| so that it can stop
153 // obvserving on destruction.
154 scoped_ptr
<TestNetLogTempFile
> net_log_temp_file_
;
155 base::FilePath net_export_log_
;
158 base::MessageLoop message_loop_
;
159 content::TestBrowserThread file_user_blocking_thread_
;
162 TEST_F(NetLogTempFileTest
, EnsureInitFailure
) {
163 net_log_temp_file_
->set_lie_about_net_export_log_directory(true);
165 EXPECT_FALSE(net_log_temp_file_
->EnsureInit());
166 VerifyFilePathAndStateAfterEnsureInitFailure();
168 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
169 VerifyFilePathAndStateAfterEnsureInitFailure();
172 TEST_F(NetLogTempFileTest
, EnsureInitAllowStart
) {
173 net_log_temp_file_
->set_lie_about_file_existence(true);
175 EXPECT_TRUE(net_log_temp_file_
->EnsureInit());
176 VerifyFilePathAndStateAfterEnsureInit();
178 // Calling EnsureInit() second time should be a no-op.
179 EXPECT_TRUE(net_log_temp_file_
->EnsureInit());
180 VerifyFilePathAndStateAfterEnsureInit();
183 TEST_F(NetLogTempFileTest
, EnsureInitAllowStartOrSend
) {
184 EXPECT_TRUE(net_log_temp_file_
->EnsureInit());
186 EXPECT_EQ("ALLOW_START_SEND", GetStateString());
187 EXPECT_EQ(NetLogTempFile::STATE_ALLOW_START_SEND
,
188 net_log_temp_file_
->state());
189 EXPECT_EQ(net_export_log_
, net_log_temp_file_
->log_path_
);
190 EXPECT_TRUE(base::PathExists(net_export_log_
));
192 base::FilePath net_export_file_path
;
193 EXPECT_TRUE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
194 EXPECT_TRUE(base::PathExists(net_export_file_path
));
195 EXPECT_EQ(net_export_log_
, net_export_file_path
);
197 // GetFilePath should return false if NetExportLogExists() fails.
198 net_log_temp_file_
->set_lie_about_file_existence(true);
199 EXPECT_FALSE(net_log_temp_file_
->GetFilePath(&net_export_file_path
));
202 TEST_F(NetLogTempFileTest
, ProcessCommandDoStartAndStop
) {
203 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
204 VerifyFileAndStateAfterDoStart();
206 // Calling DO_START second time should be a no-op.
207 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
208 VerifyFileAndStateAfterDoStart();
210 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
211 VerifyFileAndStateAfterDoStop();
213 // Calling DO_STOP second time should be a no-op.
214 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
215 VerifyFileAndStateAfterDoStop();
218 TEST_F(NetLogTempFileTest
, DoStartClearsFile
) {
219 // Verify file sizes after two consecutives start/stop are the same (even if
220 // we add some junk data in between).
221 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
222 VerifyFileAndStateAfterDoStart();
224 int64 start_file_size
;
225 EXPECT_TRUE(file_util::GetFileSize(net_export_log_
, &start_file_size
));
227 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
228 VerifyFileAndStateAfterDoStop();
230 int64 stop_file_size
;
231 EXPECT_TRUE(file_util::GetFileSize(net_export_log_
, &stop_file_size
));
232 EXPECT_GE(stop_file_size
, start_file_size
);
234 // Add some junk at the end of the file.
235 std::string
junk_data("Hello");
236 EXPECT_GT(file_util::AppendToFile(
237 net_export_log_
, junk_data
.c_str(), junk_data
.size()), 0);
239 int64 junk_file_size
;
240 EXPECT_TRUE(file_util::GetFileSize(net_export_log_
, &junk_file_size
));
241 EXPECT_GT(junk_file_size
, stop_file_size
);
243 // Execute DO_START/DO_STOP commands and make sure the file is back to the
244 // size before addition of junk data.
245 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
246 VerifyFileAndStateAfterDoStart();
248 int64 new_start_file_size
;
249 EXPECT_TRUE(file_util::GetFileSize(net_export_log_
, &new_start_file_size
));
250 EXPECT_EQ(new_start_file_size
, start_file_size
);
252 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
253 VerifyFileAndStateAfterDoStop();
255 int64 new_stop_file_size
;
256 EXPECT_TRUE(file_util::GetFileSize(net_export_log_
, &new_stop_file_size
));
257 EXPECT_EQ(new_stop_file_size
, stop_file_size
);
260 TEST_F(NetLogTempFileTest
, CheckAddEvent
) {
261 // Add an event to |net_log_| and then test to make sure that, after we stop
262 // logging, the file is larger than the file created without that event.
263 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
264 VerifyFileAndStateAfterDoStart();
266 // Get file size without the event.
267 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
268 VerifyFileAndStateAfterDoStop();
270 int64 stop_file_size
;
271 EXPECT_TRUE(file_util::GetFileSize(net_export_log_
, &stop_file_size
));
273 // Perform DO_START and add an Event and then DO_STOP and then compare
275 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_START
);
276 VerifyFileAndStateAfterDoStart();
279 net_log_
->AddGlobalEntry(net::NetLog::TYPE_CANCELLED
);
281 net_log_temp_file_
->ProcessCommand(NetLogTempFile::DO_STOP
);
282 VerifyFileAndStateAfterDoStop();
284 int64 new_stop_file_size
;
285 EXPECT_TRUE(file_util::GetFileSize(net_export_log_
, &new_stop_file_size
));
286 EXPECT_GE(new_stop_file_size
, stop_file_size
);