@ -167,26 +167,39 @@ static int g_dl_done = 0, g_dl_err = 0;
static void dl_done_cb ( void * arg , int err ) { ( void ) arg ; g_dl_done = 1 ; g_dl_err = err ; }
static void phase_b1_file_transfer ( void ) {
char src_path [ 512 ] ; snprintf ( src_path , sizeof ( src_path ) , " %s/test_src.bin " , g_tdir ) ;
char dst_path [ 512 ] ; snprintf ( dst_path , sizeof ( dst_path ) , " %s/test_dst.bin " , g_tdir ) ;
char media_base [ 512 ] ; snprintf ( media_base , sizeof ( media_base ) , " %s " , g_tdir ) ;
/* create source file in /tmp */
char src_tmp [ 512 ] ; snprintf ( src_tmp , sizeof ( src_tmp ) , " /tmp/mdl_test_%d.bin " , getpid ( ) ) ;
char media_dir [ 512 ] ; snprintf ( media_dir , sizeof ( media_dir ) , " %s/media " , g_db_dir [ 0 ] ) ;
utun_mkdir ( media_dir , 0755 ) ;
char dst_path [ 512 ] ; snprintf ( dst_path , sizeof ( dst_path ) , " %s/test_src.bin " , media_dir ) ;
char media_base [ 512 ] ; snprintf ( media_base , sizeof ( media_base ) , " %s " , g_db_dir [ 0 ] ) ;
uint8_t file_data [ 2048 ] ;
for ( int i = 0 ; i < 2048 ; i + + ) file_data [ i ] = ( uint8_t ) ( i & 0xFF ) ;
FILE * f = fopen ( src_path , " wb " ) ;
FILE * f = fopen ( src_tm p , " wb " ) ;
if ( f ) { fwrite ( file_data , 1 , 2048 , f ) ; fclose ( f ) ; }
TEST ( " create file → media_index_commit " ) ; {
/* copy to media dir (simulates what media_index_register_async does with copy=1) */
{
FILE * fin = fopen ( src_tmp , " rb " ) ;
FILE * fout = fopen ( dst_path , " wb " ) ;
if ( fin & & fout ) { uint8_t buf [ 4096 ] ; size_t rd ; while ( ( rd = fread ( buf , 1 , sizeof ( buf ) , fin ) ) > 0 ) fwrite ( buf , 1 , rd , fout ) ; }
if ( fin ) fclose ( fin ) ;
if ( fout ) fclose ( fout ) ;
}
TEST ( " media_index_commit + ui_state " ) ; {
uint8_t hash [ 32 ] ;
EVP_MD_CTX * ctx = EVP_MD_CTX_new ( ) ;
EVP_DigestInit_ex ( ctx , EVP_sha256 ( ) , NULL ) ;
EVP_DigestUpdate ( ctx , file_data , 2048 ) ;
EVP_DigestFinal_ex ( ctx , hash , NULL ) ;
EVP_MD_CTX_free ( ctx ) ;
media_index_init ( g_inst [ 0 ] - > topo_sqlite_db ) ;
/* store media_base for streaming handler to find the file */
/* ui_state: streaming handler reads media_base */
sqlite3_exec ( g_inst [ 0 ] - > topo_sqlite_db , " CREATE TABLE IF NOT EXISTS ui_state(key TEXT PRIMARY KEY, value TEXT) " , NULL , NULL , NULL ) ;
{
sqlite3_exec ( g_inst [ 0 ] - > topo_sqlite_db , " CREATE TABLE IF NOT EXISTS ui_state (key TEXT PRIMARY KEY, value TEXT) " , NULL , NULL , NULL ) ;
sqlite3_stmt * us = NULL ;
sqlite3_prepare_v2 ( g_inst [ 0 ] - > topo_sqlite_db , " INSERT OR REPLACE INTO ui_state(key,value) VALUES('media_base',?) " , - 1 , & us , NULL ) ;
sqlite3_bind_text ( us , 1 , media_base , - 1 , SQLITE_STATIC ) ;
@ -210,28 +223,29 @@ static void phase_b1_file_transfer(void) {
sc_ed25519_sign ( g_inst [ 0 ] - > my_ed25519_privkey , smsg , soff , result . block_sigs + i * 64 ) ;
}
int rc = media_index_commit ( g_inst [ 0 ] - > topo_sqlite_db , & result , g_nid [ 0 ] ,
g_inst [ 0 ] - > my_ed25519_privkey , " test_ch " , src _path, media_base ) ;
g_inst [ 0 ] - > my_ed25519_privkey , " test_ch " , dst _path, media_base ) ;
if ( rc ! = 0 ) { FAIL ( " commit rc=%d " , rc ) ; media_index_result_free ( & result ) ; return ; }
memcpy ( g_test_mid , result . media_id , 16 ) ;
memcpy ( g_test_bid0 , result . block_ids , 16 ) ;
memcpy ( g_test_bid1 , result . block_ids + 16 , 16 ) ;
media_index_result_free ( & result ) ;
/* verify data exists in DB */
int ndb = db_count ( g_inst [ 0 ] - > topo_sqlite_db , " media_files " , NULL , 0 ) ;
media_index_result_free ( & result ) ;
if ( ndb = = 2 ) OK ( ) ; else FAIL ( " media_files has %d rows (expected 2) " , ndb) ;
}
TEST ( " n2→n1 BLOCK_REQ streams data " ) ; {
fflush ( stdout ) ;
debug_set_level ( DEBUG_LEVEL_TRACE ) ;
struct media_pkt_block_req req ; memset ( & req , 0 , sizeof ( req ) ) ;
req . subcmd = MEDIA_SUBCMD_BLOCK_REQ ;
memcpy ( req . media_id , g_test_mid , 16 ) ; memcpy ( req . block_id , g_test_bid0 , 16 ) ;
req . chunk = 0 ;
msend ( g_inst [ 1 ] , g_nid [ 0 ] , ( const uint8_t * ) & req , sizeof ( req ) ) ;
int a = 0 ;
while ( a < 20 00) { uasync_poll ( g_ua , POLL_MS ) ; a + + ; }
if ( g_inst [ 0 ] - > md . active_streams > = 1 ) OK ( ) ; else FAIL ( " active_streams=%d after %dms " ,
g_inst [ 0 ] - > md . active_streams , 20 00 * POLL_MS ) ;
int a = 0 , stream_was_active = 0 ;
while ( a < 5 00) { uasync_poll ( g_ua , POLL_MS ) ; if ( g_inst [ 0 ] - > md . active_streams > = 1 ) stream_was_active = 1 ; a + + ; }
debug_set_level ( DEBUG_LEVEL_ERROR ) ;
if ( stream_was_active ) OK ( ) ; else FAIL ( " active_streams=%d after %dms " , g_inst [ 0 ] - > md . active_streams , 5 00 * POLL_MS ) ;
}
}