35 #include <boost/algorithm/string.hpp>
36 #include <boost/algorithm/string/predicate.hpp>
57 std::vector<String> args;
60 parse_option_single(a);
64 lock_guard<mutex> lock(m_mutex);
65 StateMap::iterator iter = m_state_map.find(label);
66 if (iter != m_state_map.end()) {
67 if ((*iter).second->iteration == (*iter).second->trigger_iteration) {
68 if ((*iter).second->failure_type == FAILURE_TYPE_THROW) {
69 uint32_t iteration = (*iter).second->iteration;
70 int error_code = (*iter).second->error_code;
71 delete (*iter).second;
72 m_state_map.erase(iter);
74 format(
"induced failure code '%d' '%s' iteration=%u",
75 error_code, label.c_str(), iteration));
77 else if ((*iter).second->failure_type == FAILURE_TYPE_PAUSE) {
78 HT_INFOF(
"Induced pause at '%s' iteration=%u for %u milliseconds",
79 label.c_str(), (*iter).second->iteration,
80 (*iter).second->pause_millis);
81 this_thread::sleep_for(chrono::milliseconds((*iter).second->pause_millis));
84 HT_ERRORF(
"induced failure code '%d' '%s' iteration=%u",
85 (*iter).second->error_code, (*iter).first.c_str(),
86 (*iter).second->iteration);
87 quick_exit(EXIT_FAILURE);
90 (*iter).second->iteration++;
95 lock_guard<mutex> lock(m_mutex);
96 StateMap::iterator iter = m_state_map.find(label);
97 if (iter == m_state_map.end())
99 if ((*iter).second->failure_type == FAILURE_TYPE_SIGNAL
100 && (*iter).second->iteration == (*iter).second->trigger_iteration)
102 (*iter).second->iteration++;
107 lock_guard<mutex> lock(m_mutex);
108 for (StateMap::iterator iter = m_state_map.begin();
109 iter != m_state_map.end(); ++iter)
115 char *istr = (
char*)strchr(option.c_str(),
':');
119 const char *failure_type = istr;
120 istr = strchr(istr,
':');
123 size_t failure_type_len = strlen(failure_type);
129 if (!strcmp(failure_type,
"exit"))
131 else if (!strcmp(failure_type,
"signal"))
133 else if (boost::algorithm::starts_with(failure_type,
"pause")) {
135 if (failure_type_len > 5 && failure_type[5] ==
'(') {
136 const char *ptr = failure_type + 6;
140 else if (boost::algorithm::starts_with(failure_type,
"throw")) {
143 if (failure_type_len > 5 && failure_type[5] ==
'(') {
144 const char *error_code = failure_type + 6;
145 if (boost::algorithm::istarts_with(error_code,
"0x"))
146 statep->
error_code = (
int)strtol(error_code, NULL, 16);
148 statep->
error_code = (int)strtol(error_code, NULL, 0);
156 m_state_map[option.c_str()] = statep;
The FailureInducer simulates errors.
uint32_t iteration
Current iteration of the failure.
void clear()
Clears the failure inducer.
std::string String
A String is simply a typedef to std::string.
int failure_type
The failure type; an enum in FailureInducer.cc.
String format(const char *fmt,...)
Returns a String using printf like format facilities Vanilla snprintf is about 1.5x faster than this...
uint32_t trigger_iteration
Number of iterations after which the failure is triggered.
static FailureInducer * instance
This is a singleton class.
void maybe_fail(const String &label)
Tests and executes the induced failures.
Logging routines and macros.
Compatibility Macros for C/C++.
void parse_option(String spec)
Parses a spec string (as explained above) and stores it in an internal structure. ...
int pause_millis
Milliseconds to pause (if type is FAILURE_TYPE_PAUSE)
#define HT_INFOF(msg,...)
bool split(int flags)
Tests the SPLIT bit of flags
A String class based on std::string.
bool failure_signalled(const String &label)
Returns true if a failure was signalled.
#define HT_ERRORF(msg,...)
void parse_option_single(String option)
Helper function to parse a single option.
Error codes, Exception handling, error logging.
#define HT_THROW(_code_, _msg_)
Internal structure to store a single failure setting.
int error_code
The error code which is thrown (if type is FAILURE_TYPE_THROW)