blob: b3382bccc462f5b8ce94203d21737cb5813cbdb1 [file] [log] [blame]
// 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 <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 DownloadFileWithErrorFactory;
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.
//
// Once created, an error injected via InjectError() will cause any
// DownloadFiles created to fail with that error. Call ClearError() to stop
// injecting errors.
//
// Example:
//
// FileErrorInfo a = { ... };
//
// scoped_refptr<TestFileErrorInjector> injector =
// TestFileErrorInjector::Create(download_manager);
//
// injector->InjectError(a);
//
// download_manager->DownloadUrl(url1, ...); // Will be interrupted due to |a|.
// download_manager->DownloadUrl(url2, ...); // Will be interrupted due to |a|.
//
// injector->ClearError();
//
// download_manager->DownloadUrl(url3, ...); // Won't be interrupted due to |a|.
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 {
FileOperationCode code; // Operation to affect.
int operation_instance; // 0-based count of operation calls, for each code.
DownloadInterruptReason error; // Error to inject.
};
// 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);
// 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 InjectError(const FileErrorInfo& error_to_inject);
// Clears all errors.
// Only affects files created after the next call to InjectErrors().
void ClearError();
// 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 |ClearTotalFileCount()|).
size_t TotalFileCount() const;
// Resets the total file count. Doesn't affect what's returned by
// CurrentFileCount().
void ClearTotalFileCount();
static std::string DebugString(FileOperationCode code);
private:
friend class base::RefCountedThreadSafe<TestFileErrorInjector>;
explicit TestFileErrorInjector(DownloadManager* download_manager);
virtual ~TestFileErrorInjector();
// Callbacks from the download file, to record lifetimes.
// These may be called on any thread.
void RecordDownloadFileConstruction();
void RecordDownloadFileDestruction();
// These run on the UI thread.
void DownloadFileCreated();
void DestroyingDownloadFile();
// All the data is used on the UI thread.
// Keep track of active DownloadFiles.
size_t active_file_count_ = 0;
// Keep track of found DownloadFiles.
size_t total_file_count_ = 0;
// The factory we created. May outlive this class.
DownloadFileWithErrorFactory* created_factory_ = nullptr;
// The download manager we set the factory on.
DownloadManagerImpl* download_manager_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(TestFileErrorInjector);
};
} // namespace content
#endif // CONTENT_PUBLIC_TEST_TEST_FILE_ERROR_INJECTOR_H_