| 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 |