// Misc stuff used in the tests #include "test_common.h" #include #include #include #include #include #ifndef _WIN32 #include #endif #include #include #ifndef STEAMNETWORKINGSOCKETS_OPENSOURCE #include #endif static FILE *g_fpLog = nullptr; static SteamNetworkingMicroseconds g_logTimeZero; ESteamNetworkingSocketsDebugOutputType g_eTestStdoutDetailLevel = k_ESteamNetworkingSocketsDebugOutputType_Msg; void TEST_SetStdoutDetailLevel( ESteamNetworkingSocketsDebugOutputType eDetailLevel ) { g_eTestStdoutDetailLevel = eDetailLevel; } static void DebugOutput( ESteamNetworkingSocketsDebugOutputType eType, const char *pszMsg ) { // !KLUDGE! if ( strstr( pszMsg, "Send Nagle") ) return; SteamNetworkingMicroseconds time = SteamNetworkingUtils()->GetLocalTimestamp() - g_logTimeZero; if ( g_fpLog ) fprintf( g_fpLog, "%10.6f %s\n", time*1e-6, pszMsg ); if ( eType <= g_eTestStdoutDetailLevel ) { printf( "%10.6f %s\n", time*1e-6, pszMsg ); fflush(stdout); } if ( eType == k_ESteamNetworkingSocketsDebugOutputType_Bug ) { fflush(stdout); fflush(stderr); if ( g_fpLog ) fflush( g_fpLog ); // !KLUDGE! Our logging (which is done while we hold the lock) // is occasionally triggering this assert. Just ignore that one // error for now. // Yes, this is a kludge. if ( strstr( pszMsg, "lock held for" ) || strstr( pszMsg, "waited" ) && strstr( pszMsg, "for lock" ) ) return; fprintf( stderr, "\n\n" "%s\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "!! TEST FAILED !!\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", pszMsg ); fflush( stderr ); _exit(1); } } void TEST_Printf( const char *fmt, ... ) { char text[ 2048 ]; va_list ap; va_start( ap, fmt ); vsprintf( text, fmt, ap ); va_end(ap); char *nl = strchr( text, '\0' ) - 1; if ( nl >= text && *nl == '\n' ) *nl = '\0'; DebugOutput( k_ESteamNetworkingSocketsDebugOutputType_Msg, text ); } void TEST_Fatal( const char *fmt, ... ) { fflush(stdout); va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); fputc('\n', stderr); fflush(stderr); _exit(1); } void TEST_InitLog( const char *pszFilename ) { if ( g_logTimeZero ) return; g_logTimeZero = SteamNetworkingUtils()->GetLocalTimestamp(); SteamNetworkingUtils()->SetDebugOutputFunction( k_ESteamNetworkingSocketsDebugOutputType_Debug, DebugOutput ); SteamNetworkingUtils()->SetGlobalConfigValueInt32( k_ESteamNetworkingConfig_LogLevel_P2PRendezvous, k_ESteamNetworkingSocketsDebugOutputType_Verbose ); if ( !g_fpLog ) g_fpLog = fopen( pszFilename, "wt" ); } void TEST_Init( const SteamNetworkingIdentity *pIdentity ) { TEST_InitLog( "log.txt" ); // Test machines are not always realtime systems and may experience thread starvation. // Set very high lock performance warnings so they don't cause test failures. #if __THREAD_SANITIZER__ SteamNetworkingSockets_SetLockWaitWarningThreshold( 2000*1000); #else SteamNetworkingSockets_SetLockWaitWarningThreshold( 300*1000 ); #endif #ifdef STEAMNETWORKINGSOCKETS_OPENSOURCE SteamDatagramErrMsg errMsg; if ( !GameNetworkingSockets_Init( pIdentity, errMsg ) ) { fprintf( stderr, "GameNetworkingSockets_Init failed. %s", errMsg ); exit(1); } #else //SteamAPI_Init(); SteamDatagram_SetUniverse(); SteamDatagram_SetAppID( 570 ); // Just set something, doesn't matter what SteamDatagramErrMsg errMsg; if ( !SteamDatagramClient_Init( errMsg ) ) { fprintf( stderr, "SteamDatagramClient_Init failed. %s", errMsg ); exit(1); } if ( pIdentity ) SteamNetworkingSockets()->ResetIdentity( pIdentity ); // Disable auth SteamNetworkingUtils()->SetGlobalConfigValueInt32( k_ESteamNetworkingConfig_IP_AllowWithoutAuth, 2 ); #endif } void TEST_Kill() { #ifdef STEAMNETWORKINGSOCKETS_OPENSOURCE GameNetworkingSockets_Kill(); #else SteamDatagramClient_Kill(); SteamDatagramServer_Kill(); #endif } void TEST_PumpCallbacks() { if ( SteamNetworkingSockets() ) SteamNetworkingSockets()->RunCallbacks(); #ifndef STEAMNETWORKINGSOCKETS_OPENSOURCE if ( SteamGameServerNetworkingSockets() ) SteamGameServerNetworkingSockets()->RunCallbacks(); #endif std::this_thread::sleep_for( std::chrono::milliseconds( 2 ) ); }