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