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