Index: chrome/browser/browsing_data/cache_test_util.cc |
diff --git a/chrome/browser/browsing_data/cache_test_util.cc b/chrome/browser/browsing_data/cache_test_util.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..bdb9dbf3956731f2d980ce5d1372e9a49d03ef37 |
--- /dev/null |
+++ b/chrome/browser/browsing_data/cache_test_util.cc |
@@ -0,0 +1,146 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "base/synchronization/waitable_event.h" |
+#include "chrome/browser/browsing_data/cache_test_util.h" |
+#include "net/disk_cache/disk_cache.h" |
+#include "net/http/http_cache.h" |
+#include "net/url_request/url_request_context.h" |
+#include "net/url_request/url_request_context_getter.h" |
+ |
+using content::BrowserThread; |
+ |
+CacheTestUtil::CacheTestUtil(content::StoragePartition* partition) |
+ : partition_(partition), remaining_tasks_(0) { |
+ done_callback_ = |
+ base::Bind(&CacheTestUtil::DoneCallback, base::Unretained(this)); |
+ // UI and IO thread synchronization. |
+ waitable_event_ = base::MakeUnique<base::WaitableEvent>( |
+ base::WaitableEvent::ResetPolicy::AUTOMATIC, |
+ base::WaitableEvent::InitialState::NOT_SIGNALED); |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind(&CacheTestUtil::SetUpOnIOThread, base::Unretained(this))); |
+ WaitForTasksOnIOThread(); |
+} |
+ |
+CacheTestUtil::~CacheTestUtil() { |
+ // The cache iterator must be deleted on the thread where it was created, |
+ // which is the IO thread. |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind(&CacheTestUtil::TearDownOnIOThread, base::Unretained(this))); |
+ WaitForTasksOnIOThread(); |
+} |
+ |
+void CacheTestUtil::CreateCacheEntries(const std::set<std::string>& keys) { |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind(&CacheTestUtil::CreateCacheEntriesOnIOThread, |
+ base::Unretained(this), base::ConstRef(keys))); |
+ WaitForTasksOnIOThread(); |
+} |
+ |
+void CacheTestUtil::SetUpOnIOThread() { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ net::URLRequestContextGetter* context = partition_->GetURLRequestContext(); |
+ |
+ net::HttpCache* cache = |
+ context->GetURLRequestContext()->http_transaction_factory()->GetCache(); |
+ |
+ SetNumberOfWaitedTasks(1); |
+ WaitForCompletion(cache->GetBackend(&backend_, done_callback_)); |
+} |
+ |
+void CacheTestUtil::TearDownOnIOThread() { |
+ iterator_.reset(); |
+ for (disk_cache::Entry* entry : entries_) { |
+ entry->Close(); |
+ } |
+ entries_.clear(); |
+ DoneCallback(net::OK); |
+} |
+ |
+void CacheTestUtil::CreateCacheEntriesOnIOThread( |
+ const std::set<std::string>& keys) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
+ int pos = entries_.size(); |
+ entries_.resize(entries_.size() + keys.size()); |
+ SetNumberOfWaitedTasks(keys.size()); |
+ |
+ for (const std::string& key : keys) { |
+ WaitForCompletion( |
+ backend_->CreateEntry(key, &entries_[pos++], done_callback_)); |
+ } |
+} |
+ |
+// Waiting for tasks to be done on IO thread. -------------------------------- |
+ |
+void CacheTestUtil::WaitForTasksOnIOThread() { |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
+ waitable_event_->Wait(); |
+} |
+ |
+void CacheTestUtil::SetNumberOfWaitedTasks(int count) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ remaining_tasks_ = count; |
+} |
+ |
+void CacheTestUtil::WaitForCompletion(int value) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ if (value >= 0) { |
+ // We got the result immediately. |
+ DoneCallback(value); |
+ } else if (value == net::ERR_IO_PENDING) { |
+ // We need to wait for the callback. |
+ } else { |
+ // An error has occurred. |
+ NOTREACHED(); |
+ } |
+} |
+ |
+void CacheTestUtil::DoneCallback(int value) { |
+ DCHECK_GE(value, 0); // Negative values represent an error. |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ if (--remaining_tasks_ > 0) |
+ return; |
+ |
+ waitable_event_->Signal(); |
+} |
+ |
+// Check cache content. |
+std::vector<std::string> CacheTestUtil::GetEntryKeys() { |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
+ base::Bind(&CacheTestUtil::GetEntryKeysOnIOThread, |
+ base::Unretained(this))); |
+ WaitForTasksOnIOThread(); |
+ return keys_; |
+} |
+ |
+void CacheTestUtil::GetEntryKeysOnIOThread() { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ keys_.clear(); |
+ current_entry_ = nullptr; |
+ iterator_ = backend_->CreateIterator(); |
+ GetNextKey(net::OK); |
+} |
+ |
+void CacheTestUtil::GetNextKey(int error) { |
+ while (error != net::ERR_IO_PENDING) { |
+ if (error == net::ERR_FAILED) { |
+ DoneCallback(net::OK); |
+ return; |
+ } |
+ |
+ if (current_entry_) { |
+ keys_.push_back(current_entry_->GetKey()); |
+ } |
+ |
+ error = iterator_->OpenNextEntry( |
+ ¤t_entry_, |
+ base::Bind(&CacheTestUtil::GetNextKey, base::Unretained(this))); |
+ } |
+} |