price_live_check/price_live_check.cpp¶
Functions¶
| Name | |
|---|---|
| int | main(int argc, char * argv[]) |
Functions Documentation¶
function main¶
Source code¶
// Live smoke check for PriceHttpClient against a real price endpoint.
// Exercises TLS verification with the pinned CA bundle, the SGNS User-Agent,
// and status classification (200 / 403 WAF block / 429 rate limit).
//
// Usage: price_live_check [--url <base>] [--format coingecko|gnus]
// [--ids a,b,c] [--currency usd] [--repeat N] [--delay-ms M]
// Exit code: 0 if every fetch succeeded, 1 otherwise.
#include <coinprices/PriceHttpClient.hpp>
#include <boost/asio.hpp>
#include <chrono>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <thread>
#include <vector>
namespace
{
std::vector<std::string> Split( const std::string &aText )
{
std::vector<std::string> parts;
std::stringstream stream( aText );
std::string item;
while ( std::getline( stream, item, ',' ) )
{
if ( !item.empty() )
{
parts.push_back( item );
}
}
return parts;
}
}
int main( int argc, char *argv[] )
{
std::string url = "https://api.coingecko.com";
std::string format = "coingecko";
std::string currency = "usd";
std::vector<std::string> ids = { "genius-ai", "bitcoin" };
int repeat = 1;
int delayMs = 2000;
for ( int i = 1; i + 1 < argc; i += 2 )
{
const std::string key = argv[i];
const std::string val = argv[i + 1];
if ( key == "--url" )
{
url = val;
}
else if ( key == "--format" )
{
format = val;
}
else if ( key == "--ids" )
{
ids = Split( val );
}
else if ( key == "--currency" )
{
currency = val;
}
else if ( key == "--repeat" )
{
repeat = std::stoi( val );
}
else if ( key == "--delay-ms" )
{
delayMs = std::stoi( val );
}
}
const auto responseFormat = ( format == "gnus" ) ? sgns::ResponseFormat::GnusEnvelope
: sgns::ResponseFormat::CoinGeckoSimplePrice;
sgns::PriceHttpClient client( url,
sgns::RetryConfig{},
std::chrono::seconds( 60 ),
[] { return std::chrono::system_clock::now(); },
std::chrono::milliseconds( 5000 ),
responseFormat );
std::cout << "endpoint=" << url << " format=" << format << " UA=" << sgns::PriceHttpClient::kUserAgent
<< std::endl;
int failures = 0;
for ( int n = 1; n <= repeat; ++n )
{
auto ioc = std::make_shared<boost::asio::io_context>();
auto result = client.FetchPrices( ioc, ids, currency );
if ( result )
{
std::cout << "[" << n << "] OK attempts=" << client.AttemptsLastFetch() << std::endl;
for ( const auto "e : result.value() )
{
std::cout << " " << quote.asset << " " << quote.currency << " = " << quote.price
<< " (fetchedAt=" << quote.FetchedAtEpochSeconds() << ", stale=" << quote.stale << ")"
<< std::endl;
}
}
else
{
++failures;
const auto &failure = result.error();
std::cout << "[" << n << "] FAIL attempts=" << client.AttemptsLastFetch()
<< " code=" << static_cast<int>( failure.code ) << " httpStatus=" << failure.httpStatus
<< " message=\"" << failure.Message() << "\"" << std::endl;
}
if ( n < repeat )
{
std::this_thread::sleep_for( std::chrono::milliseconds( delayMs ) );
}
}
std::cout << "summary: " << ( repeat - failures ) << "/" << repeat << " succeeded" << std::endl;
return failures == 0 ? 0 : 1;
}
Updated on 2026-10-09 at 04:02:49 +0000