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