blob: 912569d04d2a0ec57c9313d15e8315727129112f [file]
/*------------------------------------------------------------------------------
* Copyright (C) 2003-2010 Ben van Klinken and the CLucene Team
*
* Distributable under the terms of either the Apache License (Version 2.0) or
* the GNU Lesser General Public License, as specified in the COPYING file.
------------------------------------------------------------------------------*/
#ifndef _lucene_store_MockRAMDirectory_
#define _lucene_store_MockRAMDirectory_
#include "CLucene.h"
#include "CLucene/_clucene-config.h"
#include <string>
#include <map>
#include <vector>
#include "CLucene/store/RAMDirectory.h"
#include "CLucene/store/_RAMDirectory.h"
CL_NS_DEF(store)
/**
* This is a subclass of RAMDirectory that adds methods
* intented to be used only by unit tests.
*/
class MockRAMDirectory : public RAMDirectory {
public:
/**
* Objects that represent fail-able conditions. Objects of a derived
* class are created and registered with the mock directory. After
* register, each object will be invoked once for each first write
* of a file, giving the object a chance to throw an IOException.
*/
class Failure {
public:
Failure() { doFail = false; }
void eval(MockRAMDirectory* dir) {}
/**
* reset should set the state of the failure to its default
* (freshly constructed) state. Reset is convenient for tests
* that want to create one failure object and then reuse it in
* multiple cases. This, combined with the fact that Failure
* subclasses are often anonymous classes makes reset difficult to
* do otherwise.
*
* A typical example of use is
* Failure* failure = new Failure();
* ...
* mock.failOn(failure->reset())
*/
Failure* reset() { return this; }
void setDoFail() { doFail = true; };
void clearDoFail() { doFail = false; }
private:
bool doFail;
};
MockRAMDirectory();
MockRAMDirectory(const char* dir);
MockRAMDirectory(Directory* dir);
virtual ~MockRAMDirectory();
virtual IndexOutput* createOutput(const char* name);
virtual bool openInput(const char* name, IndexInput*& ret, CLuceneError& error, int32_t bufferSize = -1);
virtual void close();
virtual bool deleteFile(const char* name, const bool throwError=true);
/**
* Emulate windows whereby deleting an open file is not
* allowed (raise IOException).
*/
void setNoDeleteOpenFile(bool value);
bool getNoDeleteOpenFile() const;
void setMaxUsedSize(int64_t value);
int64_t getMaxUsedSize() const;
void resetMaxUsedSize();
void setMaxSizeInBytes(int64_t value);
int64_t getMaxSizeInBytes() const;
/**
* If 0.0, no exceptions will be thrown. Else this should
* be a double 0.0 - 1.0. We will randomly throw an
* IOException on the first write to an OutputStream based
* on this probability.
*/
void setRandomIOExceptionRate(float_t rate, int32_t seed);
float_t getRandomIOExceptionRate() const;
void maybeThrowIOException();
/** Provided for testing purposes. Use sizeInBytes() instead. */
int64_t getRecomputedSizeInBytes();
/**
* Like getRecomputedSizeInBytes(), but, uses actual file
* lengths rather than buffer allocations (which are
* quantized up to nearest
* RAMOutputStream.BUFFER_SIZE (now 1024) bytes.
*/
int64_t getRecomputedActualSizeInBytes();
void failOn(Failure* fail);
void maybeThrowDeterministicException();
std::map<std::string, int32_t>& getOpenFiles();
DEFINE_MUTABLE_MUTEX(openFiles_mutex);
private:
std::map<std::string, int32_t> openFiles;
std::vector<Failure*> failures;
bool noDeleteOpenFile;
int64_t maxUsedSize;
int64_t maxSize;
float_t randomIOExceptionRate;
};
/**
* Subclass of RAMFile to access RAMFile::directory without making it public in RAMFile.
*/
class MockRAMFile : public RAMFile {
public:
MockRAMFile(RAMDirectory* directory) : RAMFile(directory) {
// empty
}
virtual ~MockRAMFile() {
// empty
}
void setDirectory(RAMDirectory* value) {
directory = value;
}
};
class MockRAMOutputStream : public RAMOutputStream {
public:
MockRAMOutputStream();
MockRAMOutputStream(MockRAMDirectory* d, MockRAMFile* f);
virtual void close(void);
virtual void flush(void);
virtual void writeByte(const uint8_t b);
virtual void writeBytes(const uint8_t* b, const int32_t length);
virtual int64_t length() const;
private:
MockRAMDirectory* dir;
bool first;
uint8_t singleByte[1];
};
class MockRAMInputStream : public RAMInputStream {
public:
MockRAMInputStream(const MockRAMInputStream& clone);
MockRAMInputStream(MockRAMDirectory* d, const char* n, MockRAMFile* f);
void close(void);
DEFINE_MUTABLE_MUTEX(openFiles_mutex);
private:
MockRAMDirectory* dir;
std::string name;
bool isClone;
};
CL_NS_END
#endif // _lucene_store_MockRAMDirectory_