1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
/**
* Helpers to setup a raft cluster in test fixtures.
*
* Each raft instance will use its own dqlite FSM, which in turn will be created
* using its own config, registry and logger.
*
* The fixture will also register a VFS and a SQLite replication object for each
* raft instance, using "test<i>" as registration name, where <i> is the raft
* instance index.
*
* This fixture is meant to be used as base-line fixture for most higher-level
* tests.
*/
#ifndef TEST_CLUSTER_H
#define TEST_CLUSTER_H
#include "../../src/config.h"
#include "../../src/fsm.h"
#include "../../src/raft.h"
#include "../../src/registry.h"
#include "../../src/vfs.h"
#include "../lib/fs.h"
#include "../lib/heap.h"
#include "../lib/logger.h"
#include "../lib/sqlite.h"
#define N_SERVERS 3
#define V1 0
#define V2 1
struct server
{
struct logger logger;
struct config config;
sqlite3_vfs vfs;
struct registry registry;
};
#define FIXTURE_CLUSTER \
struct server servers[N_SERVERS]; \
struct raft_fsm fsms[N_SERVERS]; \
struct raft_fixture cluster;
#define SETUP_CLUSTER(VERSION) \
{ \
struct raft_configuration _configuration; \
unsigned _i; \
int _rv; \
SETUP_HEAP; \
SETUP_SQLITE; \
_rv = raft_fixture_init(&f->cluster); \
munit_assert_int(_rv, ==, 0); \
for (_i = 0; _i < N_SERVERS; _i++) { \
SETUP_SERVER(_i, VERSION); \
raft_fixture_grow(&f->cluster, &f->fsms[_i]); \
} \
_rv = raft_fixture_configuration(&f->cluster, N_SERVERS, \
&_configuration); \
munit_assert_int(_rv, ==, 0); \
_rv = raft_fixture_bootstrap(&f->cluster, &_configuration); \
munit_assert_int(_rv, ==, 0); \
raft_configuration_close(&_configuration); \
_rv = raft_fixture_start(&f->cluster); \
munit_assert_int(_rv, ==, 0); \
}
#define SETUP_SERVER(I, VERSION) \
do { \
struct server *_s = &f->servers[I]; \
struct raft_fsm *_fsm = &f->fsms[I]; \
char address[16]; \
int _rc; \
\
test_logger_setup(params, &_s->logger); \
\
sprintf(address, "%d", I + 1); \
\
_rc = config__init(&_s->config, I + 1, address, NULL); \
munit_assert_int(_rc, ==, 0); \
\
_rc = VfsInit(&_s->vfs, &_s->config.vfs); \
munit_assert_int(_rc, ==, 0); \
_rc = sqlite3_vfs_register(&_s->vfs, 0); \
munit_assert_int(_rc, ==, 0); \
\
registry__init(&_s->registry, &_s->config); \
\
_rc = fsm__init(_fsm, &_s->config, &_s->registry); \
munit_assert_int(_rc, ==, 0); \
} while (0)
#define TEAR_DOWN_CLUSTER \
{ \
int _i; \
for (_i = 0; _i < N_SERVERS; _i++) { \
TEAR_DOWN_SERVER(_i); \
} \
raft_fixture_close(&f->cluster); \
TEAR_DOWN_SQLITE; \
TEAR_DOWN_HEAP; \
}
#define TEAR_DOWN_SERVER(I) \
{ \
struct server *s = &f->servers[I]; \
struct raft_fsm *fsm = &f->fsms[I]; \
fsm__close(fsm); \
registry__close(&s->registry); \
sqlite3_vfs_unregister(&s->vfs); \
VfsClose(&s->vfs); \
config__close(&s->config); \
test_logger_tear_down(&s->logger); \
}
#define CLUSTER_CONFIG(I) &f->servers[I].config
#define CLUSTER_LOGGER(I) &f->servers[I].logger
#define CLUSTER_LEADER(I) &f->servers[I].leader
#define CLUSTER_REGISTRY(I) &f->servers[I].registry
#define CLUSTER_RAFT(I) raft_fixture_get(&f->cluster, I)
#define CLUSTER_LAST_INDEX(I) raft_last_index(CLUSTER_RAFT(I))
#define CLUSTER_DISCONNECT(I, J) raft_fixture_disconnect(&f->cluster, I, J)
#define CLUSTER_RECONNECT(I, J) raft_fixture_reconnect(&f->cluster, I, J)
#define CLUSTER_ELECT(I) raft_fixture_elect(&f->cluster, I)
#define CLUSTER_DEPOSE raft_fixture_depose(&f->cluster)
#define CLUSTER_APPLIED(N) \
do { \
bool done = raft_fixture_step_until_applied( \
&f->cluster, N_SERVERS, N, 1000); \
munit_assert_true(done); \
} while (0)
#define CLUSTER_COMMITTED(N) \
do { \
bool done = raft_fixture_step_until_committed( \
&f->cluster, N_SERVERS, N, 1000); \
munit_assert_true(done); \
} while (0)
#define CLUSTER_STEP raft_fixture_step(&f->cluster)
#define CLUSTER_SNAPSHOT_THRESHOLD(I, N) \
raft_set_snapshot_threshold(CLUSTER_RAFT(I), N)
#define CLUSTER_SNAPSHOT_TRAILING(I, N) \
raft_set_snapshot_trailing(CLUSTER_RAFT(I), N)
#endif /* TEST_CLUSTER_H */
|