Utility class for failure injection (C++)

  1 #pragma once
  2 
  3 #include <string>
  4 #include <unordered_map>
  5 #include <mutex>
  6 #include <random>
  7 #include <ctime>
  8 
  9 #ifdef FI_FLAG
 10 
 11 // Utility class for failure injection
 12 class FIUtil {
 13 public:
 14     // Failure points table
 15     class FPTable {
 16     public:
 17         void Update(const std::string& name, int percent) {
 18             mu_.lock();
 19             failure_points_[name] = percent;
 20             mu_.unlock();
 21         }
 22 
 23         void Remove(const std::string& name) {
 24             mu_.lock();
 25             failure_points_.erase(name);
 26             mu_.unlock();
 27         }
 28 
 29         int LookUp(const std::string& name) {
 30             std::lock_guard<std::mutex> guard(mu_);
 31             auto iter =  failure_points_.find(name);
 32             if (iter == failure_points_.end()) {
 33                 return -1;  // Not found
 34             }
 35             return iter->second;
 36         }
 37 
 38         void Clear() {
 39             std::unordered_map<std::string, int> tmp;
 40             mu_.lock();
 41             failure_points_.swap(tmp);
 42             mu_.unlock();
 43         }
 44 
 45     private:
 46         std::mutex mu_;
 47         std::unordered_map<std::string, int> failure_points_;
 48     };
 49 
 50     static inline FPTable* GetFPTable() {
 51         static FPTable table;
 52         return &table;
 53     }
 54 
 55     static inline int Random() {
 56         static std::default_random_engine g(std::time(NULL));
 57         std::uniform_int_distribution<int> d(0,99);
 58         return d(g);
 59     }
 60 };
 61 
 62 #define FI_RETURN(name, retval) \
 63     do { \
 64         if (FIUtil::Random() < FIUtil::GetFPTable()->LookUp(name)) { \
 65             return retval; \
 66         } \
 67     } while (0)
 68 
 69 #define FI_ASSIGN(name, var, val) \
 70     do { \
 71         if (FIUtil::Random() < FIUtil::GetFPTable()->LookUp(name)) { \
 72             var = val; \
 73         } \
 74     } while (0)
 75 
 76 #define FI_ENABLE(name) \
 77     do { \
 78         FIUtil::GetFPTable()->Update(name, 100); \
 79     } while (0)
 80 
 81 #define FI_ENABLE_RANDOM(name, percent) \
 82     do { \
 83         FIUtil::GetFPTable()->Update(name, percent); \
 84     } while (0)
 85 
 86 #define FI_DISABLE(name) \
 87     do { \
 88         FIUtil::GetFPTable()->Update(name, 0); \
 89     } while (0)
 90 
 91 #define FI_DISABLE_ALL() \
 92     do { \
 93         FIUtil::GetFPTable()->Clear(); \
 94     } while (0)
 95 
 96 #else
 97 
 98 #define FI_RETURN(name, retval)
 99 #define FI_ASSIGN(name, var, val)
100 #define FI_ENABLE(name)
101 #define FI_ENABLE_RANDOM(name, percent)
102 #define FI_DISABLE(name)
103 #define FI_DISABLE_ALL()
104 
105 #endif  // FI_FLAG

 

posted @ 2024-02-19 15:44  william-cheung  阅读(9)  评论(0编辑  收藏  举报