OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "net/log/file_net_log_observer.h" | 5 #include "net/log/file_net_log_observer.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <string> | 10 #include <string> |
11 #include <utility> | 11 #include <utility> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "base/files/file_path.h" | 14 #include "base/files/file_path.h" |
15 #include "base/files/file_util.h" | 15 #include "base/files/file_util.h" |
16 #include "base/files/scoped_file.h" | 16 #include "base/files/scoped_file.h" |
17 #include "base/files/scoped_temp_dir.h" | 17 #include "base/files/scoped_temp_dir.h" |
18 #include "base/json/json_reader.h" | 18 #include "base/json/json_reader.h" |
19 #include "base/json/json_writer.h" | 19 #include "base/json/json_writer.h" |
20 #include "base/memory/ptr_util.h" | 20 #include "base/memory/ptr_util.h" |
21 #include "base/message_loop/message_loop.h" | 21 #include "base/message_loop/message_loop.h" |
22 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" |
23 #include "base/strings/stringprintf.h" | 23 #include "base/strings/stringprintf.h" |
| 24 #include "base/task_scheduler/task_scheduler.h" |
24 #include "base/threading/thread.h" | 25 #include "base/threading/thread.h" |
25 #include "base/values.h" | 26 #include "base/values.h" |
26 #include "net/base/test_completion_callback.h" | 27 #include "net/base/test_completion_callback.h" |
27 #include "net/log/net_log_entry.h" | 28 #include "net/log/net_log_entry.h" |
28 #include "net/log/net_log_event_type.h" | 29 #include "net/log/net_log_event_type.h" |
29 #include "net/log/net_log_parameters_callback.h" | 30 #include "net/log/net_log_parameters_callback.h" |
30 #include "net/log/net_log_source.h" | 31 #include "net/log/net_log_source.h" |
31 #include "net/log/net_log_source_type.h" | 32 #include "net/log/net_log_source_type.h" |
32 #include "net/log/net_log_util.h" | 33 #include "net/log/net_log_util.h" |
33 #include "net/url_request/url_request.h" | 34 #include "net/url_request/url_request.h" |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 } | 153 } |
153 | 154 |
154 // Used for tests that are common to both bounded and unbounded modes of the | 155 // Used for tests that are common to both bounded and unbounded modes of the |
155 // the FileNetLogObserver. The param is true if bounded mode is used. | 156 // the FileNetLogObserver. The param is true if bounded mode is used. |
156 class FileNetLogObserverTest : public ::testing::TestWithParam<bool> { | 157 class FileNetLogObserverTest : public ::testing::TestWithParam<bool> { |
157 public: | 158 public: |
158 void SetUp() override { | 159 void SetUp() override { |
159 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 160 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
160 bounded_log_dir_ = temp_dir_.GetPath(); | 161 bounded_log_dir_ = temp_dir_.GetPath(); |
161 unbounded_log_path_ = bounded_log_dir_.AppendASCII("net-log.json"); | 162 unbounded_log_path_ = bounded_log_dir_.AppendASCII("net-log.json"); |
162 file_thread_.reset(new base::Thread("NetLog File Thread")); | |
163 file_thread_->StartWithOptions( | |
164 base::Thread::Options(base::MessageLoop::TYPE_DEFAULT, 0)); | |
165 ASSERT_TRUE(file_thread_->WaitUntilThreadStarted()); | |
166 } | 163 } |
167 | 164 |
168 void CreateAndStartObserving(std::unique_ptr<base::Value> constants) { | 165 void CreateAndStartObserving(std::unique_ptr<base::Value> constants) { |
169 bool bounded = GetParam(); | 166 bool bounded = GetParam(); |
170 if (bounded) { | 167 if (bounded) { |
171 logger_ = FileNetLogObserver::CreateBounded( | 168 logger_ = FileNetLogObserver::CreateBounded( |
172 file_thread_->task_runner(), bounded_log_dir_, kLargeFileSize, | 169 bounded_log_dir_, kLargeFileSize, kTotalNumFiles, |
173 kTotalNumFiles, std::move(constants)); | 170 std::move(constants)); |
174 } else { | 171 } else { |
175 logger_ = FileNetLogObserver::CreateUnbounded(file_thread_->task_runner(), | 172 logger_ = FileNetLogObserver::CreateUnbounded(unbounded_log_path_, |
176 unbounded_log_path_, | |
177 std::move(constants)); | 173 std::move(constants)); |
178 } | 174 } |
179 | 175 |
180 logger_->StartObserving(&net_log_, NetLogCaptureMode::Default()); | 176 logger_->StartObserving(&net_log_, NetLogCaptureMode::Default()); |
181 } | 177 } |
182 | 178 |
183 ::testing::AssertionResult ReadNetLogFromDisk( | 179 ::testing::AssertionResult ReadNetLogFromDisk( |
184 std::unique_ptr<base::Value>* root, | 180 std::unique_ptr<base::Value>* root, |
185 base::ListValue** events) { | 181 base::ListValue** events) { |
186 bool bounded = GetParam(); | 182 bool bounded = GetParam(); |
187 std::string input; | 183 std::string input; |
188 if (bounded) { | 184 if (bounded) { |
189 ReadBoundedLogFiles(bounded_log_dir_, &input); | 185 ReadBoundedLogFiles(bounded_log_dir_, &input); |
190 } else { | 186 } else { |
191 base::ReadFileToString(unbounded_log_path_, &input); | 187 base::ReadFileToString(unbounded_log_path_, &input); |
192 } | 188 } |
193 return ParseNetLogString(input, root, events); | 189 return ParseNetLogString(input, root, events); |
194 } | 190 } |
195 | 191 |
196 bool LogFilesExist() { | 192 bool LogFilesExist() { |
| 193 // The log files are written by a sequenced task runner. Drain all the |
| 194 // scheduled tasks to ensure that the file writing ones have run before |
| 195 // checking if they exist. |
| 196 base::TaskScheduler::GetInstance()->FlushForTesting(); |
| 197 |
197 bool bounded = GetParam(); | 198 bool bounded = GetParam(); |
198 if (bounded) { | 199 if (bounded) { |
199 if (base::PathExists(bounded_log_dir_.AppendASCII("constants.json")) || | 200 if (base::PathExists(bounded_log_dir_.AppendASCII("constants.json")) || |
200 base::PathExists(bounded_log_dir_.AppendASCII("end_netlog.json"))) | 201 base::PathExists(bounded_log_dir_.AppendASCII("end_netlog.json"))) |
201 return true; | 202 return true; |
202 for (int i = 0; i < kTotalNumFiles; i++) { | 203 for (int i = 0; i < kTotalNumFiles; i++) { |
203 if (base::PathExists(bounded_log_dir_.AppendASCII( | 204 if (base::PathExists(bounded_log_dir_.AppendASCII( |
204 "event_file_" + std::to_string(i) + ".json"))) | 205 "event_file_" + std::to_string(i) + ".json"))) |
205 return true; | 206 return true; |
206 } | 207 } |
207 return false; | 208 return false; |
208 } else { | 209 } else { |
209 return base::PathExists(unbounded_log_path_); | 210 return base::PathExists(unbounded_log_path_); |
210 } | 211 } |
211 } | 212 } |
212 | 213 |
213 protected: | 214 protected: |
214 NetLog net_log_; | 215 NetLog net_log_; |
215 std::unique_ptr<base::Thread> file_thread_; | |
216 std::unique_ptr<FileNetLogObserver> logger_; | 216 std::unique_ptr<FileNetLogObserver> logger_; |
217 | 217 |
218 private: | 218 private: |
219 base::ScopedTempDir temp_dir_; | 219 base::ScopedTempDir temp_dir_; |
220 base::FilePath bounded_log_dir_; | 220 base::FilePath bounded_log_dir_; |
221 base::FilePath unbounded_log_path_; | 221 base::FilePath unbounded_log_path_; |
222 }; | 222 }; |
223 | 223 |
224 // Used for tests that are exclusive to the bounded mode of FileNetLogObserver. | 224 // Used for tests that are exclusive to the bounded mode of FileNetLogObserver. |
225 class FileNetLogObserverBoundedTest : public ::testing::Test { | 225 class FileNetLogObserverBoundedTest : public ::testing::Test { |
226 public: | 226 public: |
227 void SetUp() override { | 227 void SetUp() override { |
228 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 228 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
229 bounded_log_dir_ = temp_dir_.GetPath(); | 229 bounded_log_dir_ = temp_dir_.GetPath(); |
230 file_thread_.reset(new base::Thread("NetLog File Thread")); | |
231 file_thread_->StartWithOptions( | |
232 base::Thread::Options(base::MessageLoop::TYPE_DEFAULT, 0)); | |
233 ASSERT_TRUE(file_thread_->WaitUntilThreadStarted()); | |
234 } | 230 } |
235 | 231 |
236 void CreateAndStartObserving(std::unique_ptr<base::Value> constants, | 232 void CreateAndStartObserving(std::unique_ptr<base::Value> constants, |
237 int total_file_size, | 233 int total_file_size, |
238 int num_files) { | 234 int num_files) { |
239 logger_ = FileNetLogObserver::CreateBounded( | 235 logger_ = FileNetLogObserver::CreateBounded( |
240 file_thread_->task_runner(), bounded_log_dir_, total_file_size, | 236 bounded_log_dir_, total_file_size, num_files, std::move(constants)); |
241 num_files, std::move(constants)); | |
242 logger_->StartObserving(&net_log_, NetLogCaptureMode::Default()); | 237 logger_->StartObserving(&net_log_, NetLogCaptureMode::Default()); |
243 } | 238 } |
244 | 239 |
245 ::testing::AssertionResult ReadNetLogFromDisk( | 240 ::testing::AssertionResult ReadNetLogFromDisk( |
246 std::unique_ptr<base::Value>* root, | 241 std::unique_ptr<base::Value>* root, |
247 base::ListValue** events) { | 242 base::ListValue** events) { |
248 std::string input; | 243 std::string input; |
249 ReadBoundedLogFiles(bounded_log_dir_, &input); | 244 ReadBoundedLogFiles(bounded_log_dir_, &input); |
250 return ParseNetLogString(input, root, events); | 245 return ParseNetLogString(input, root, events); |
251 } | 246 } |
252 | 247 |
253 base::FilePath GetEventFilePath(int index) const { | 248 base::FilePath GetEventFilePath(int index) const { |
254 return bounded_log_dir_.AppendASCII("event_file_" + std::to_string(index) + | 249 return bounded_log_dir_.AppendASCII("event_file_" + std::to_string(index) + |
255 ".json"); | 250 ".json"); |
256 } | 251 } |
257 | 252 |
258 static int64_t GetFileSize(const base::FilePath& path) { | 253 static int64_t GetFileSize(const base::FilePath& path) { |
259 int64_t file_size; | 254 int64_t file_size; |
260 EXPECT_TRUE(base::GetFileSize(path, &file_size)); | 255 EXPECT_TRUE(base::GetFileSize(path, &file_size)); |
261 return file_size; | 256 return file_size; |
262 } | 257 } |
263 | 258 |
264 protected: | 259 protected: |
265 NetLog net_log_; | 260 NetLog net_log_; |
266 std::unique_ptr<base::Thread> file_thread_; | |
267 std::unique_ptr<FileNetLogObserver> logger_; | 261 std::unique_ptr<FileNetLogObserver> logger_; |
268 | 262 |
269 private: | 263 private: |
270 base::ScopedTempDir temp_dir_; | 264 base::ScopedTempDir temp_dir_; |
271 base::FilePath bounded_log_dir_; | 265 base::FilePath bounded_log_dir_; |
272 }; | 266 }; |
273 | 267 |
274 // Instantiates each FileNetLogObserverTest to use bounded and unbounded modes. | 268 // Instantiates each FileNetLogObserverTest to use bounded and unbounded modes. |
275 INSTANTIATE_TEST_CASE_P(, | 269 INSTANTIATE_TEST_CASE_P(, |
276 FileNetLogObserverTest, | 270 FileNetLogObserverTest, |
277 ::testing::Values(true, false)); | 271 ::testing::Values(true, false)); |
278 | 272 |
| 273 // Tests deleting a FileNetLogObserver without first calling StopObserving(). |
279 TEST_P(FileNetLogObserverTest, ObserverDestroyedWithoutStopObserving) { | 274 TEST_P(FileNetLogObserverTest, ObserverDestroyedWithoutStopObserving) { |
280 CreateAndStartObserving(nullptr); | 275 CreateAndStartObserving(nullptr); |
281 | 276 |
282 // Send dummy event | 277 // Send dummy event |
283 AddEntries(logger_.get(), 1, kDummyEventSize); | 278 AddEntries(logger_.get(), 1, kDummyEventSize); |
284 | 279 |
| 280 // The log files should have been started. |
| 281 ASSERT_TRUE(LogFilesExist()); |
| 282 |
285 logger_.reset(); | 283 logger_.reset(); |
286 file_thread_.reset(); | |
287 | 284 |
| 285 // When the logger is re-set without having called StopObserving(), the |
| 286 // partially written log files are deleted. |
288 ASSERT_FALSE(LogFilesExist()); | 287 ASSERT_FALSE(LogFilesExist()); |
289 } | 288 } |
290 | 289 |
291 TEST_P(FileNetLogObserverTest, GeneratesValidJSONWithNoEvents) { | 290 TEST_P(FileNetLogObserverTest, GeneratesValidJSONWithNoEvents) { |
292 TestClosure closure; | 291 TestClosure closure; |
293 | 292 |
294 CreateAndStartObserving(nullptr); | 293 CreateAndStartObserving(nullptr); |
295 | 294 |
296 logger_->StopObserving(nullptr, closure.closure()); | 295 logger_->StopObserving(nullptr, closure.closure()); |
297 | 296 |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
794 | 793 |
795 void AddEntriesViaNetLog(NetLog* net_log, int num_entries) { | 794 void AddEntriesViaNetLog(NetLog* net_log, int num_entries) { |
796 for (int i = 0; i < num_entries; i++) { | 795 for (int i = 0; i < num_entries; i++) { |
797 net_log->AddGlobalEntry(NetLogEventType::PAC_JAVASCRIPT_ERROR); | 796 net_log->AddGlobalEntry(NetLogEventType::PAC_JAVASCRIPT_ERROR); |
798 } | 797 } |
799 } | 798 } |
800 | 799 |
801 TEST_P(FileNetLogObserverTest, AddEventsFromMultipleThreadsWithStopObserving) { | 800 TEST_P(FileNetLogObserverTest, AddEventsFromMultipleThreadsWithStopObserving) { |
802 const size_t kNumThreads = 10; | 801 const size_t kNumThreads = 10; |
803 std::vector<std::unique_ptr<base::Thread>> threads(kNumThreads); | 802 std::vector<std::unique_ptr<base::Thread>> threads(kNumThreads); |
804 // Start all the threads. Waiting for them to start is to hopefuly improve | 803 // Start all the threads. Waiting for them to start is to hopefully improve |
805 // the odds of hitting interesting races once events start being added. | 804 // the odds of hitting interesting races once events start being added. |
806 for (size_t i = 0; i < threads.size(); ++i) { | 805 for (size_t i = 0; i < threads.size(); ++i) { |
807 threads[i] = base::MakeUnique<base::Thread>( | 806 threads[i] = base::MakeUnique<base::Thread>( |
808 base::StringPrintf("WorkerThread%i", static_cast<int>(i))); | 807 base::StringPrintf("WorkerThread%i", static_cast<int>(i))); |
809 threads[i]->Start(); | 808 threads[i]->Start(); |
810 threads[i]->WaitUntilThreadStarted(); | 809 threads[i]->WaitUntilThreadStarted(); |
811 } | 810 } |
812 | 811 |
813 CreateAndStartObserving(nullptr); | 812 CreateAndStartObserving(nullptr); |
814 | 813 |
815 const size_t kNumEventsAddedPerThread = 200; | 814 const size_t kNumEventsAddedPerThread = 200; |
816 | 815 |
817 // Add events in parallel from all the threads. | 816 // Add events in parallel from all the threads. |
818 for (size_t i = 0; i < kNumThreads; ++i) { | 817 for (size_t i = 0; i < kNumThreads; ++i) { |
819 threads[i]->task_runner()->PostTask( | 818 threads[i]->task_runner()->PostTask( |
820 FROM_HERE, base::Bind(&AddEntriesViaNetLog, base::Unretained(&net_log_), | 819 FROM_HERE, base::Bind(&AddEntriesViaNetLog, base::Unretained(&net_log_), |
821 kNumEventsAddedPerThread)); | 820 kNumEventsAddedPerThread)); |
822 } | 821 } |
823 | 822 |
824 // Stop observing. | 823 // Stop observing. |
825 TestClosure closure; | 824 TestClosure closure; |
826 logger_->StopObserving(nullptr, closure.closure()); | 825 logger_->StopObserving(nullptr, closure.closure()); |
827 closure.WaitForResult(); | 826 closure.WaitForResult(); |
828 | 827 |
829 // Join all the threads. | 828 // Join all the threads. |
830 threads.clear(); | 829 threads.clear(); |
| 830 |
| 831 ASSERT_TRUE(LogFilesExist()); |
831 } | 832 } |
832 | 833 |
833 TEST_P(FileNetLogObserverTest, | 834 TEST_P(FileNetLogObserverTest, |
834 AddEventsFromMultipleThreadsWithoutStopObserving) { | 835 AddEventsFromMultipleThreadsWithoutStopObserving) { |
835 const size_t kNumThreads = 10; | 836 const size_t kNumThreads = 10; |
836 std::vector<std::unique_ptr<base::Thread>> threads(kNumThreads); | 837 std::vector<std::unique_ptr<base::Thread>> threads(kNumThreads); |
837 // Start all the threads. Waiting for them to start is to hopefuly improve | 838 // Start all the threads. Waiting for them to start is to hopefully improve |
838 // the odds of hitting interesting races once events start being added. | 839 // the odds of hitting interesting races once events start being added. |
839 for (size_t i = 0; i < threads.size(); ++i) { | 840 for (size_t i = 0; i < threads.size(); ++i) { |
840 threads[i] = base::MakeUnique<base::Thread>( | 841 threads[i] = base::MakeUnique<base::Thread>( |
841 base::StringPrintf("WorkerThread%i", static_cast<int>(i))); | 842 base::StringPrintf("WorkerThread%i", static_cast<int>(i))); |
842 threads[i]->Start(); | 843 threads[i]->Start(); |
843 threads[i]->WaitUntilThreadStarted(); | 844 threads[i]->WaitUntilThreadStarted(); |
844 } | 845 } |
845 | 846 |
846 CreateAndStartObserving(nullptr); | 847 CreateAndStartObserving(nullptr); |
847 | 848 |
848 const size_t kNumEventsAddedPerThread = 200; | 849 const size_t kNumEventsAddedPerThread = 200; |
849 | 850 |
850 // Add events in parallel from all the threads. | 851 // Add events in parallel from all the threads. |
851 for (size_t i = 0; i < kNumThreads; ++i) { | 852 for (size_t i = 0; i < kNumThreads; ++i) { |
852 threads[i]->task_runner()->PostTask( | 853 threads[i]->task_runner()->PostTask( |
853 FROM_HERE, base::Bind(&AddEntriesViaNetLog, base::Unretained(&net_log_), | 854 FROM_HERE, base::Bind(&AddEntriesViaNetLog, base::Unretained(&net_log_), |
854 kNumEventsAddedPerThread)); | 855 kNumEventsAddedPerThread)); |
855 } | 856 } |
856 | 857 |
857 // Destroy logger. | 858 // Destroy logger. |
858 logger_.reset(); | 859 logger_.reset(); |
859 | 860 |
860 // Join all the threads. | 861 // Join all the threads. |
861 threads.clear(); | 862 threads.clear(); |
| 863 |
| 864 // The log file doesn't exist since StopObserving() was not called. |
| 865 ASSERT_FALSE(LogFilesExist()); |
862 } | 866 } |
863 | 867 |
864 } // namespace | 868 } // namespace |
865 | 869 |
866 } // namespace net | 870 } // namespace net |
OLD | NEW |