test_file_error_injector.h revision 424c4d7b64af9d0d8fd9624f381f469654d5e3d2
1// Copyright (c) 2012 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. 4 5#ifndef CONTENT_PUBLIC_TEST_TEST_FILE_ERROR_INJECTOR_H_ 6#define CONTENT_PUBLIC_TEST_TEST_FILE_ERROR_INJECTOR_H_ 7 8#include <map> 9#include <set> 10#include <string> 11 12#include "base/memory/ref_counted.h" 13#include "base/memory/scoped_ptr.h" 14#include "base/memory/ref_counted.h" 15#include "content/public/browser/download_interrupt_reasons.h" 16#include "url/gurl.h" 17 18namespace content { 19 20class DownloadId; 21class DownloadFileWithErrorsFactory; 22class DownloadManager; 23class DownloadManagerImpl; 24 25// Test helper for injecting errors into download file operations. 26// All errors for a download must be injected before it starts. 27// This class needs to be |RefCountedThreadSafe| because the implementation 28// is referenced by other classes that live past the time when the user is 29// nominally done with it. These classes are internal to content/. 30// 31// NOTE: No more than one download with the same URL can be in progress at 32// the same time. You can have multiple simultaneous downloads as long as the 33// URLs are different, as the URLs are used as keys to get information about 34// the download. 35// 36// Example: 37// 38// FileErrorInfo a = { url1, ... }; 39// FileErrorInfo b = { url2, ... }; 40// 41// scoped_refptr<TestFileErrorInjector> injector = 42// TestFileErrorInjector::Create(download_manager); 43// 44// injector->AddError(a); 45// injector->AddError(b); 46// injector->InjectErrors(); 47// 48// download_manager->DownloadUrl(url1, ...); 49// download_manager->DownloadUrl(url2, ...); 50// ... wait for downloads to finish or get an injected error ... 51class TestFileErrorInjector 52 : public base::RefCountedThreadSafe<TestFileErrorInjector> { 53 public: 54 enum FileOperationCode { 55 FILE_OPERATION_INITIALIZE, 56 FILE_OPERATION_WRITE, 57 FILE_OPERATION_RENAME_UNIQUIFY, 58 FILE_OPERATION_RENAME_ANNOTATE, 59 }; 60 61 // Structure that encapsulates the information needed to inject a file error. 62 struct FileErrorInfo { 63 std::string url; // Full URL of the download. Identifies the download. 64 FileOperationCode code; // Operation to affect. 65 int operation_instance; // 0-based count of operation calls, for each code. 66 DownloadInterruptReason error; // Error to inject. 67 }; 68 69 typedef std::map<std::string, FileErrorInfo> ErrorMap; 70 71 // Creates an instance. May only be called once. 72 // Lives until all callbacks (in the implementation) are complete and the 73 // creator goes out of scope. 74 // TODO(rdsmith): Allow multiple calls for different download managers. 75 static scoped_refptr<TestFileErrorInjector> Create( 76 DownloadManager* download_manager); 77 78 // Adds an error. 79 // Must be called before |InjectErrors()| for a particular download file. 80 // It is an error to call |AddError()| more than once for the same file 81 // (URL), unless you call |ClearErrors()| in between them. 82 bool AddError(const FileErrorInfo& error_info); 83 84 // Clears all errors. 85 // Only affects files created after the next call to InjectErrors(). 86 void ClearErrors(); 87 88 // Injects the errors such that new download files will be affected. 89 // The download system must already be initialized before calling this. 90 // Multiple calls are allowed, but only useful if the errors have changed. 91 // Replaces the injected error list. 92 bool InjectErrors(); 93 94 // Tells how many files are currently open. 95 size_t CurrentFileCount() const; 96 97 // Tells how many files have ever been open (since construction or the 98 // last call to |ClearFoundFiles()|). 99 size_t TotalFileCount() const; 100 101 // Returns whether or not a file matching |url| has been created. 102 bool HadFile(const GURL& url) const; 103 104 // Resets the found file list. 105 void ClearFoundFiles(); 106 107 static std::string DebugString(FileOperationCode code); 108 109 private: 110 friend class base::RefCountedThreadSafe<TestFileErrorInjector>; 111 112 typedef std::set<GURL> FileSet; 113 114 explicit TestFileErrorInjector(DownloadManager* download_manager); 115 116 virtual ~TestFileErrorInjector(); 117 118 // Callbacks from the download file, to record lifetimes. 119 // These may be called on any thread. 120 void RecordDownloadFileConstruction(const GURL& url); 121 void RecordDownloadFileDestruction(const GURL& url); 122 123 // These run on the UI thread. 124 void DownloadFileCreated(GURL url); 125 void DestroyingDownloadFile(GURL url); 126 127 // All the data is used on the UI thread. 128 // Our injected error list, mapped by URL. One per file. 129 ErrorMap injected_errors_; 130 131 // Keep track of active DownloadFiles. 132 FileSet files_; 133 134 // Keep track of found DownloadFiles. 135 FileSet found_files_; 136 137 // The factory we created. May outlive this class. 138 DownloadFileWithErrorsFactory* created_factory_; 139 140 // The download manager we set the factory on. 141 DownloadManagerImpl* download_manager_; 142 143 DISALLOW_COPY_AND_ASSIGN(TestFileErrorInjector); 144}; 145 146} // namespace content 147 148#endif // CONTENT_PUBLIC_TEST_TEST_FILE_ERROR_INJECTOR_H_ 149