1 /* 2 * Copyright (C) 2015-2020 Codership Oy <info@codership.com> 3 */ 4 5 #ifndef __gcs_test_utils__ 6 #define __gcs_test_utils__ 7 8 #include "../gcs_group.hpp" 9 #include "../../../gcache/src/GCache.hpp" 10 11 namespace gcs_test 12 { 13 class InitConfig 14 { 15 public: 16 InitConfig(gu::Config& cfg); 17 InitConfig(gu::Config& cfg, const std::string& base_name); 18 private: 19 void common_ctor(gu::Config& cfg); 20 }; 21 22 class GcsGroup 23 { 24 public: 25 26 GcsGroup(); 27 GcsGroup(const std::string& node_id, 28 const std::string& inc_addr, 29 gcs_proto_t gver = 1, int pver = 2, int aver = 3); 30 31 ~GcsGroup(); 32 33 void init(const char* node_name, 34 const char* inc_addr, 35 gcs_proto_t gcs_proto_ver, 36 int repl_proto_ver, 37 int appl_proto_ver); 38 group()39 struct gcs_group* group() { return &group_; } operator ()()40 struct gcs_group* operator()(){ return group(); } operator ->()41 struct gcs_group* operator->(){ return &group_; } 42 config()43 gu::Config& config() { return conf_; } gcache()44 gcache::GCache* gcache() { return gcache_; } 45 state() const46 gcs_group_state_t state() const { return group_.state; } 47 node_state() const48 gcs_node_state_t node_state() const 49 { return group_.nodes[group_.my_idx].status; } 50 51 private: 52 53 void common_ctor(const char* node_name, const char* inc_addr, 54 gcs_proto_t gver, int rver, int aver); 55 56 void common_dtor(); 57 58 gu::Config conf_; 59 InitConfig init_; 60 gcache::GCache* gcache_; 61 struct gcs_group group_; 62 bool initialized_; 63 }; 64 } /* namespace gcs_test */ 65 66 struct gt_node 67 { 68 gcs_test::GcsGroup group; 69 char id[GCS_COMP_MEMB_ID_MAX_LEN + 1]; /// ID assigned by the backend 70 71 explicit gt_node(const char* name = NULL, int gcs_proto_ver = 0); 72 ~gt_node(); 73 stategt_node74 gcs_node_state_t state() const { return group.node_state(); } 75 76 gcs_seqno_t deliver_last_applied(int from, gcs_seqno_t last_applied); 77 78 }; 79 80 #define GT_MAX_NODES 10 81 82 struct gt_group 83 { 84 struct gt_node* nodes[GT_MAX_NODES]; 85 int nodes_num; 86 bool primary; 87 88 explicit gt_group(int num = 0, int gcs_proto_ver = 0, bool prim = true); 89 ~gt_group(); 90 91 /* deliver new component message to all memebers */ 92 int deliver_component_msg(bool prim); 93 94 /* perform state exchange between the members */ 95 int perform_state_exchange(); 96 97 /* add node to group (deliver new component and perform state exchange) 98 * @param new_id should node get new ID? */ 99 int add_node(struct gt_node*, bool new_id); 100 101 /* NOTE: this function uses simplified and determinitstic algorithm where 102 * dropped node is always replaced by the last one in group. 103 * For our purposes (reproduction of #465) it fits perfectly. 104 * @return dropped node handle */ 105 struct gt_node* drop_node(int idx); 106 107 /* deliver GCS_MSG_SYNC or GCS_MSG_JOIN msg*/ 108 int deliver_join_sync_msg (int src_idx, gcs_msg_type_t type); 109 110 /* deliver last_applied message from node from */ 111 gcs_seqno_t deliver_last_applied(int from, gcs_seqno_t last_applied); 112 113 /* @return true if all nodes in the group see node @param idx with a state 114 * @param check */ 115 bool verify_node_state_across(int idx, gcs_node_state_t check) const; 116 117 /* start SST on behalf of node idx (joiner) 118 * @return donor idx or negative error code */ 119 int sst_start (int joiner_idx, const char* donor_name); 120 121 /* Finish SST on behalf of a node idx (joiner or donor) */ 122 int sst_finish(int idx); 123 124 /* join and sync added node (sst_start() + sst_finish()) */ 125 int sync_node(int joiner_idx); 126 }; 127 128 #endif /* __gu_test_utils__ */ 129