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