Line data Source code
1 : #include "fd_tile_unit_test.h"
2 : #include "../../app/platform/fd_file_util.h"
3 : #include "../../app/shared/fd_obj_callbacks.c"
4 : #include "../../app/firedancer/callbacks.c"
5 : #include "../../app/shared/fd_action.h"
6 : #include <errno.h> /* errno */
7 : #include <sys/mman.h> /* MAP_FAILED */
8 :
9 : extern fd_topo_obj_callbacks_t fd_obj_cb_mcache;
10 : extern fd_topo_obj_callbacks_t fd_obj_cb_dcache;
11 : extern fd_topo_obj_callbacks_t fd_obj_cb_fseq;
12 : extern fd_topo_obj_callbacks_t fd_obj_cb_metrics;
13 : extern fd_topo_obj_callbacks_t fd_obj_cb_dbl_buf;
14 : extern fd_topo_obj_callbacks_t fd_obj_cb_neigh4_hmap;
15 : extern fd_topo_obj_callbacks_t fd_obj_cb_fib4;
16 : extern fd_topo_obj_callbacks_t fd_obj_cb_keyswitch;
17 : extern fd_topo_obj_callbacks_t fd_obj_cb_tile;
18 : extern fd_topo_obj_callbacks_t fd_obj_cb_store;
19 : extern fd_topo_obj_callbacks_t fd_obj_cb_fec_sets;
20 : extern fd_topo_obj_callbacks_t fd_obj_cb_txncache;
21 : extern fd_topo_obj_callbacks_t fd_obj_cb_banks;
22 : extern fd_topo_obj_callbacks_t fd_obj_cb_banks_locks;
23 : extern fd_topo_obj_callbacks_t fd_obj_cb_funk;
24 :
25 : fd_topo_obj_callbacks_t * CALLBACKS[] = {
26 : &fd_obj_cb_mcache,
27 : &fd_obj_cb_dcache,
28 : &fd_obj_cb_fseq,
29 : &fd_obj_cb_metrics,
30 : &fd_obj_cb_dbl_buf,
31 : &fd_obj_cb_neigh4_hmap,
32 : &fd_obj_cb_fib4,
33 : &fd_obj_cb_keyswitch,
34 : &fd_obj_cb_tile,
35 : &fd_obj_cb_store,
36 : &fd_obj_cb_fec_sets,
37 : &fd_obj_cb_txncache,
38 : &fd_obj_cb_banks,
39 : &fd_obj_cb_banks_locks,
40 : &fd_obj_cb_funk,
41 : &fd_obj_cb_acc_pool,
42 : NULL,
43 : };
44 :
45 : /* Dummy tiles to fill up the topology. It works with both
46 : fdctl's and firedancer's topologies. */
47 : fd_topo_run_tile_t dummy_tile_net = { .name = "net" };
48 : fd_topo_run_tile_t dummy_tile_netlnk = { .name = "netlnk" };
49 : fd_topo_run_tile_t dummy_tile_sock = { .name = "sock" };
50 : fd_topo_run_tile_t dummy_tile_quic = { .name = "quic" };
51 : fd_topo_run_tile_t dummy_tile_bundle = { .name = "bundle" };
52 : fd_topo_run_tile_t dummy_tile_verify = { .name = "verify" };
53 : fd_topo_run_tile_t dummy_tile_dedup = { .name = "dedup" };
54 : fd_topo_run_tile_t dummy_tile_pack = { .name = "pack" };
55 : fd_topo_run_tile_t dummy_tile_shred = { .name = "shred" };
56 : fd_topo_run_tile_t dummy_tile_sign = { .name = "sign" };
57 : fd_topo_run_tile_t dummy_tile_metric = { .name = "metric" };
58 : fd_topo_run_tile_t dummy_tile_cswtch = { .name = "cswtch" };
59 : fd_topo_run_tile_t dummy_tile_gui = { .name = "gui" };
60 : fd_topo_run_tile_t dummy_tile_rpc = { .name = "rpc" };
61 : fd_topo_run_tile_t dummy_tile_plugin = { .name = "plugin" };
62 : fd_topo_run_tile_t dummy_tile_bencho = { .name = "bencho" };
63 : fd_topo_run_tile_t dummy_tile_benchg = { .name = "benchg" };
64 : fd_topo_run_tile_t dummy_tile_benchs = { .name = "benchs" };
65 : fd_topo_run_tile_t dummy_tile_pktgen = { .name = "pktgen" };
66 : fd_topo_run_tile_t dummy_tile_resolv = { .name = "resolv" };
67 : fd_topo_run_tile_t dummy_tile_poh = { .name = "poh" };
68 : fd_topo_run_tile_t dummy_tile_bank = { .name = "bank" };
69 : fd_topo_run_tile_t dummy_tile_store = { .name = "store" };
70 : fd_topo_run_tile_t dummy_tile_gossvf = { .name = "gossvf" };
71 : fd_topo_run_tile_t dummy_tile_gossip = { .name = "gossip" };
72 : fd_topo_run_tile_t dummy_tile_repair = { .name = "repair" };
73 : fd_topo_run_tile_t dummy_tile_send = { .name = "send" };
74 : fd_topo_run_tile_t dummy_tile_replay = { .name = "replay" };
75 : fd_topo_run_tile_t dummy_tile_exec = { .name = "exec" };
76 : fd_topo_run_tile_t dummy_tile_tower = { .name = "tower" };
77 : fd_topo_run_tile_t dummy_tile_snapct = { .name = "snapct" };
78 : fd_topo_run_tile_t dummy_tile_snapld = { .name = "snapld" };
79 : fd_topo_run_tile_t dummy_tile_snapdc = { .name = "snapdc" };
80 : fd_topo_run_tile_t dummy_tile_snapin = { .name = "snapin" };
81 : fd_topo_run_tile_t dummy_tile_arch_f = { .name = "arch_f" };
82 : fd_topo_run_tile_t dummy_tile_arch_w = { .name = "arch_w" };
83 : fd_topo_run_tile_t dummy_tile_scap = { .name = "scap" };
84 : fd_topo_run_tile_t dummy_tile_genesi = { .name = "genesi" };
85 : fd_topo_run_tile_t dummy_tile_ipecho = { .name = "ipecho" };
86 :
87 : fd_topo_run_tile_t * TILES[] = {
88 : NULL, /* Placeholder for tile under test (it must appear first). */
89 : &dummy_tile_net,
90 : &dummy_tile_netlnk,
91 : &dummy_tile_sock,
92 : &dummy_tile_quic,
93 : &dummy_tile_bundle,
94 : &dummy_tile_verify,
95 : &dummy_tile_dedup,
96 : &dummy_tile_pack,
97 : &dummy_tile_shred,
98 : &dummy_tile_sign,
99 : &dummy_tile_metric,
100 : &dummy_tile_cswtch,
101 : &dummy_tile_gui,
102 : &dummy_tile_rpc,
103 : &dummy_tile_plugin,
104 : &dummy_tile_bencho,
105 : &dummy_tile_benchg,
106 : &dummy_tile_benchs,
107 : &dummy_tile_pktgen,
108 : &dummy_tile_resolv,
109 : &dummy_tile_poh,
110 : &dummy_tile_bank,
111 : &dummy_tile_store,
112 : &dummy_tile_gossvf,
113 : &dummy_tile_gossip,
114 : &dummy_tile_repair,
115 : &dummy_tile_send,
116 : &dummy_tile_replay,
117 : &dummy_tile_exec,
118 : &dummy_tile_tower,
119 : &dummy_tile_snapct,
120 : &dummy_tile_snapld,
121 : &dummy_tile_snapdc,
122 : &dummy_tile_snapin,
123 : &dummy_tile_arch_f,
124 : &dummy_tile_arch_w,
125 : &dummy_tile_scap,
126 : &dummy_tile_genesi,
127 : &dummy_tile_ipecho,
128 : NULL,
129 : };
130 :
131 : action_t * ACTIONS[] = {
132 : NULL,
133 : };
134 :
135 : fd_topo_tile_t *
136 : fd_tile_unit_test_init( char const * default_topo_config_path,
137 : char const * override_topo_config_path,
138 : char const * user_topo_config_path,
139 : int netns,
140 : int is_firedancer,
141 : int is_local_cluster,
142 : void (*fd_topo_initialize_)(config_t *),
143 : fd_topo_run_tile_t * topo_run_tile,
144 0 : config_t * out_config ) {
145 : /* The tile-under-test must be placed at index 0 in TILES. */
146 0 : TILES[0] = topo_run_tile;
147 :
148 : /* Default topo config. */
149 0 : char * default_config = NULL;
150 0 : ulong default_config_sz = 0UL;
151 0 : if( FD_UNLIKELY( default_topo_config_path==NULL ) ) {
152 0 : FD_LOG_WARNING(( "undefined default_config_path" ));
153 0 : return NULL;
154 0 : };
155 0 : default_config = fd_file_util_read_all( default_topo_config_path, &default_config_sz );
156 0 : if( FD_UNLIKELY( default_config==MAP_FAILED ) ) {
157 0 : FD_LOG_WARNING(( "failed to read default config file `%s` (%d-%s)", default_topo_config_path, errno, fd_io_strerror( errno ) ));
158 0 : return NULL;
159 0 : }
160 :
161 : /* Override topo config. */
162 0 : char * override_config = NULL;
163 0 : ulong override_config_sz = 0UL;
164 0 : if( FD_LIKELY( override_topo_config_path ) ) {
165 0 : override_config = fd_file_util_read_all( override_topo_config_path, &override_config_sz );
166 0 : if( FD_UNLIKELY( override_config==MAP_FAILED ) ){
167 0 : FD_LOG_WARNING(( "failed to read user config file `%s` (%d-%s)", override_topo_config_path, errno, fd_io_strerror( errno ) ));
168 0 : return NULL;
169 0 : }
170 0 : }
171 :
172 : /* User topo config. */
173 0 : char * user_config = NULL;
174 0 : ulong user_config_sz = 0UL;
175 0 : if( FD_LIKELY( user_topo_config_path ) ) {
176 0 : user_config = fd_file_util_read_all( user_topo_config_path, &user_config_sz );
177 0 : if( FD_UNLIKELY( user_config==MAP_FAILED ) ){
178 0 : FD_LOG_WARNING(( "failed to read user config file `%s` (%d-%s)", user_topo_config_path, errno, fd_io_strerror( errno ) ));
179 0 : return NULL;
180 0 : }
181 0 : }
182 :
183 : /* Load config. */
184 0 : fd_memset( out_config, 0, sizeof( config_t ) ); /* This step is needed (see w->wksp check). */
185 :
186 0 : fd_config_load( is_firedancer, netns, is_local_cluster,
187 0 : default_config, default_config_sz,
188 0 : override_config, override_topo_config_path, override_config_sz,
189 0 : user_config, user_config_sz, user_topo_config_path,
190 0 : out_config );
191 :
192 : /* Initialize topo. */
193 0 : fd_topo_initialize_( out_config );
194 :
195 : /* Process test tile. */
196 0 : fd_topo_tile_t * test_tile = NULL;
197 0 : for( ulong i=0; i<out_config->topo.tile_cnt; i++ ) {
198 0 : if( !strcmp( out_config->topo.tiles[ i ].name, topo_run_tile->name ) ) {
199 0 : test_tile = &out_config->topo.tiles[ i ];
200 0 : for( ulong j=0; j<test_tile->uses_obj_cnt; j++ ) {
201 0 : if( FD_UNLIKELY( test_tile->uses_obj_id[j] >= out_config->topo.obj_cnt ) ) {
202 0 : FD_LOG_WARNING(( "test_tile->uses_obj_id[%lu] %lu exceeds config->topo.obj_cnt %lu", j, test_tile->uses_obj_id[j], out_config->topo.obj_cnt ));
203 0 : return NULL;
204 0 : }
205 0 : fd_topo_obj_t * o = &out_config->topo.objs[ test_tile->uses_obj_id[j] ];
206 0 : fd_topo_wksp_t * w = &out_config->topo.workspaces[ o->wksp_id ];
207 0 : if( FD_UNLIKELY( w->wksp != NULL ) ) continue; /* the workspace has already been initialized */
208 0 : FD_LOG_NOTICE(( "Creating workspace %s (--page-cnt %lu, --page-sz %lu, --cpu-idx %lu)", w->name, w->page_cnt, w->page_sz, fd_shmem_cpu_idx( w->numa_idx ) ));
209 0 : ulong cpu_idx = fd_shmem_cpu_idx( w->numa_idx );
210 0 : w->wksp = fd_wksp_new_anon( w->name, w->page_sz, 1UL, &w->page_cnt, &cpu_idx, 0U, w->part_max );
211 : // w->wksp = fd_wksp_new_anonymous( w->page_sz, w->page_cnt, fd_shmem_cpu_idx( w->numa_idx ), w->name, 0UL );
212 0 : if( FD_UNLIKELY( w->wksp==NULL ) ) {
213 0 : FD_LOG_WARNING(( "w->wksp==NULL for o->wksp_id %lu for test_tile->uses_obj_id[%lu] %lu", o->wksp_id, j, test_tile->uses_obj_id[j] ));
214 0 : return NULL;
215 0 : }
216 0 : ulong offset = fd_wksp_alloc( w->wksp, fd_topo_workspace_align(), w->known_footprint, 1UL );
217 : /* TODO assert offset==gaddr_lo ? */
218 0 : if( FD_UNLIKELY( !offset ) ) {
219 0 : FD_LOG_WARNING(( "fd_wksp_alloc failed with offset %lu", offset ));
220 0 : return NULL;
221 0 : }
222 0 : fd_topo_wksp_new( &out_config->topo, w, CALLBACKS );
223 0 : }
224 0 : break;
225 0 : }
226 0 : }
227 0 : if( FD_UNLIKELY( test_tile==NULL ) ) {
228 0 : FD_LOG_WARNING(( "test_tile==NULL" ));
229 0 : return NULL;
230 0 : }
231 0 : fd_topo_fill_tile( &out_config->topo, test_tile );
232 0 : return test_tile;
233 0 : }
|