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 18 namespace content { 19 20 class DownloadId; 21 class DownloadFileWithErrorsFactory; 22 class DownloadManager; 23 class 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 ... 51 class 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