static void test_foreach_stat_fails_if_callback_function_is_NULL() { assert_true( init_stat() ); expect_assert_failure( foreach_stat( NULL, NULL ) ); assert_true( finalize_stat() ); }
static void test_foreach_stat_succeeds_without_entries() { assert_true( init_stat() ); foreach_stat( mock_callback, NULL ); assert_true( finalize_stat() ); }
static void test_foreach_stat_succeeds() { assert_true( init_stat() ); const char *keys[] = { "key0", "key1" }; increment_stat( keys[ 0 ] ); increment_stat( keys[ 1 ] ); increment_stat( keys[ 1 ] ); void *user_data = ( void * ) ( intptr_t ) 0x1; expect_string( mock_callback, key, keys[ 1 ] ); expect_value( mock_callback, value, 2 ); expect_value( mock_callback, user_data, user_data ); expect_string( mock_callback, key, keys[ 0 ] ); expect_value( mock_callback, value, 1 ); expect_value( mock_callback, user_data, user_data ); foreach_stat( mock_callback, user_data ); assert_true( finalize_stat() ); }
static void test_foreach_stat_fails_if_not_initialized() { expect_assert_failure( foreach_stat( mock_callback, NULL ) ); }
static void handle_show_stats_request( const messenger_context_handle *handle, management_show_stats_request *request ) { assert( handle != NULL ); assert( request != NULL ); assert( ntohs( request->header.type ) == MANAGEMENT_SHOW_STATS_REQUEST ); assert( ntohl( request->header.length ) == sizeof( management_show_stats_request ) ); debug( "Handling a show stats request from %s.", handle->service_name ); list_element *stats = NULL; create_list( &stats ); foreach_stat( append_stat, &stats ); unsigned int n_stats = list_length_of( stats ); const size_t send_queue_length = 400000; // MESSENGER_RECV_BUFFER * 4 const size_t send_queue_margin = 256; // headroom for various headers unsigned int n_max_entries = ( unsigned int ) ( send_queue_length - send_queue_margin ) / sizeof( stat_entry ); management_show_stats_reply *reply = NULL; size_t length = 0; if ( n_stats <= n_max_entries ) { length = offsetof( management_show_stats_reply, entries ) + sizeof( stat_entry ) * n_stats; reply = xmalloc( length ); memset( reply, 0, length ); reply->header.type = htons( MANAGEMENT_SHOW_STATS_REPLY ); reply->header.length = htonl( ( uint32_t ) length ); reply->header.status = MANAGEMENT_REQUEST_SUCCEEDED; stat_entry *p = reply->entries; for ( list_element *e = stats; e != NULL; e = e->next ) { assert( e->data != NULL ); memcpy( p, e->data, sizeof( stat_entry ) ); p++; } } else { // TODO: Send statistics via out-of-band channel or by multiple replies. error( "Too many statistic entries ( %u > %u ).", n_stats, n_max_entries ); length = offsetof( management_show_stats_reply, entries ); reply = xmalloc( length ); memset( reply, 0, length ); reply->header.type = htons( MANAGEMENT_SHOW_STATS_REPLY ); reply->header.length = htonl( ( uint32_t ) length ); reply->header.status = MANAGEMENT_REQUEST_FAILED; } if ( stats != NULL ) { for ( list_element *e = stats; e != NULL; e = e->next ) { assert( e->data != NULL ); xfree( e->data ); } delete_list( stats ); } bool ret = send_reply_message( handle, MESSENGER_MANAGEMENT_REPLY, reply, length ); if ( ret == false ) { error( "Failed to send a show stats reply." ); } xfree( reply ); }