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