45 #include <boost/program_options.hpp>
46 #include <boost/bind.hpp>
47 #include <boost/foreach.hpp>
48 #include <boost/mem_fn.hpp>
63 const double uniformRandom =
static_cast<double> ( rand() ) / RAND_MAX;
65 const double inverseRandom = 0.5 * pow (
static_cast<double> ( ( maxSize+1 ) / 0.5 ) , uniformRandom );
66 uint32_t retVal =
static_cast<uint32_t
>( floor(inverseRandom) );
68 if ( retVal > maxSize )
71 " * uniformRandom=", uniformRandom,
"\n",
72 " * inverseRandom=", inverseRandom,
"\n",
73 "Correcting block size as temporary fix." );
85 buffer.reserve ( size );
88 for (
unsigned i = 0 ; i < size ; ++i )
90 buffer.push_back ( rand() + rand() );
100 std::ostringstream oss_details;
101 oss_details <<
"Single-register write-read @ 0x" <<
std::hex <<
addr << ( perTransactionDispatch ?
" (multiple dispatches)" :
" (single dispatch)" );
105 cout << oss_details.str() << endl;
108 const uint32_t
x = rand();
114 if ( perTransactionDispatch )
124 cout <<
"TEST FAILED: " << oss_details.str() <<
". Wrote value 0x" <<
std::hex <<
x <<
" but read-back 0x" <<
reg.
value() <<
std::dec << endl;
128 catch (
const std::exception& e )
130 cout <<
"TEST FAILED: " << oss_details.str() <<
". Exception of type '" <<
typeid ( e ).
name() <<
"' thrown ..." << endl << e.what() << endl;
141 std::ostringstream oss_details;
142 oss_details << depth <<
"-word write-read @ 0x" <<
std::hex <<
addr;
149 oss_details << ( perTransactionDispatch ?
" (multiple dispatches)" :
" (single dispatch)" );
153 cout <<
"Running test: " << oss_details.str() << endl;
156 const U32Vec xx = getRandomBuffer ( depth );
162 if ( perTransactionDispatch )
169 std::vector<uint32_t>::const_iterator valVecIt = ram.
begin();
170 std::vector<uint32_t>::const_iterator xxIt =
xx.begin();
172 for ( ; valVecIt != ram.
end(); valVecIt++, xxIt++ )
174 if ( ( *valVecIt ) != ( *xxIt ) )
176 uint32_t reg_addr =
addr + ( valVecIt - ram.
begin() );
177 cout <<
"TEST FAILED: " << oss_details.str() <<
". Wrote value Ox" <<
std::hex << *xxIt <<
" to register 0x" << reg_addr <<
" but read-back 0x" << *valVecIt <<
std::dec << std::endl;
182 log (
Notice(),
"TEST PASSED: ", oss_details.str() );
184 catch (
const std::exception& e )
186 cout <<
"TEST FAILED: " << oss_details.str() <<
"! EXCEPTION of type '" <<
typeid ( e ).
name() <<
"' thrown ..." << endl << e.what() << endl;
197 std::ostringstream oss_details;
198 oss_details <<
"RMW-bits @ 0x" <<
std::hex <<
addr << ( perTransactionDispatch ?
" (multiple dispatches)" :
" (single dispatch)" );
202 cout <<
"TESTING: " << oss_details.str() << endl;
205 const uint32_t x0 = rand();
207 const uint32_t a = rand();
209 const uint32_t b = rand();
211 const uint32_t x1 = ( x0 & a ) | b;
213 std::ostringstream oss_values;
215 oss_values <<
"Wrote value 0x" <<
std::hex << x0 <<
", then did RMW-bits with AND-term 0x" << a <<
", OR-term 0x" << b;
217 const bool ipbus2 = ( (
c.
uri().find (
"ipbusudp-2.0" ) != string::npos ) || (
c.
uri().find (
"ipbustcp-2.0" ) != string::npos ) || (
c.
uri().find (
"chtcp-2.0" ) != string::npos ) || (
c.
uri().find (
"ipbuspcie-2.0" ) != string::npos ) || (
c.
uri().find (
"ipbusmmap-2.0" ) != string::npos ) );
223 if ( perTransactionDispatch )
231 if ( ipbus2 ? ( x0 != reg_rmw.
value() ) : ( x1 != reg_rmw.
value() ) )
233 cout <<
"TEST FAILED: " << oss_details.str() <<
" ... RMW-bits returned value 0x" <<
std::hex << reg_rmw.
value() <<
", but expected 0x" << ( ipbus2 ? x0 : x1 ) <<
std::dec << endl << oss_values.str() << endl;
240 if ( x1 != reg_read.
value() )
242 cout <<
"TEST FAILED: " << oss_details.str() <<
" ... Read after RMW-bits returned value 0x" <<
std::hex << reg_read.
value() <<
", but expected 0x" << x1 <<
std::dec << endl << oss_values.str() << endl;
246 catch (
const std::exception& e )
248 cout <<
"TEST FAILED: " << oss_values.str() <<
". Exception of type '" <<
typeid ( e ).
name() <<
"' thrown ..." << endl << e.what() << endl;
258 std::ostringstream oss_details;
259 oss_details <<
"RMW-sum @ 0x" <<
std::hex <<
addr << ( perTransactionDispatch ?
" (multiple dispatches)" :
" (single dispatch)" );
263 cout <<
"TESTING: " << oss_details.str() << endl;
266 const uint32_t x0 = rand();
268 const uint32_t a = rand();
270 const uint32_t x1 = x0 + a;
272 std::ostringstream oss_values;
274 oss_values <<
"Wrote value 0x" <<
std::hex << x0 <<
", then did RMW-sum with ADDEND 0x" << a;
276 const bool ipbus2 = ( (
c.
uri().find (
"ipbusudp-2.0" ) != string::npos ) || (
c.
uri().find (
"ipbustcp-2.0" ) != string::npos ) || (
c.
uri().find (
"chtcp-2.0" ) != string::npos ) || (
c.
uri().find (
"ipbuspcie-2.0" ) != string::npos ) || (
c.
uri().find (
"ipbusmmap-2.0" ) != string::npos ) );
282 if ( perTransactionDispatch )
290 if ( ipbus2 ? ( x0 != reg_sum.
value() ) : ( x1 != reg_sum.
value() ) )
292 cout <<
"TEST FAILED: " << oss_details.str() <<
" ... RMW-sum returned value 0x" <<
std::hex << reg_sum.
value() <<
", but expected 0x" << ( ipbus2 ? x0 : x1 ) <<
std::dec << endl << oss_values.str() << endl;
299 if ( x1 != reg_read.
value() )
301 cout <<
"TEST FAILED: " << oss_details.str() <<
" ... Read after RMW-sum returned value 0x" <<
std::hex << reg_read.
value() <<
", but expected 0x" << x1 <<
std::dec << endl << oss_values.str() << endl;
305 catch (
const std::exception& e )
307 cout <<
"TEST FAILED: " << oss_values.str() <<
". Exception of type '" <<
typeid ( e ).
name() <<
"' thrown ..." << endl << e.what() << endl;
315 bool uhal::tests::PerfTester::runValidationTest(
const std::vector<ClientInterface*>& aClients,
const uint32_t aBaseAddr,
const uint32_t aDepth,
const size_t aNrIterations,
const bool aDispatchEachIteration,
const bool aVerbose)
317 unsigned nrTestsFailed = 0;
318 unsigned nrTestsTotal = 0;
322 typedef std::vector<ClientInterface*>::const_iterator ClientIt_t;
323 for ( ClientIt_t clientIt = aClients.begin(); clientIt != aClients.end(); clientIt++ )
326 cout <<
"\n\nWRITE READ-BACK TESTS for device at '" <<
client->
uri() <<
"'" << endl;
327 vector<uint32_t> addr_vec;
328 addr_vec.push_back ( aBaseAddr );
329 addr_vec.push_back ( aBaseAddr + aDepth - 1 );
331 for (
unsigned i = 0; i < 2498; i++ )
333 addr_vec.push_back ( aBaseAddr + ( rand() % aDepth ) );
336 cout <<
"\n 1. Single-register write/read (" << addr_vec.size() * 2 <<
" tests)" << endl;
338 for (
unsigned i = 0; i < addr_vec.size(); i++ )
342 if ( ! validation_test_single_write_read ( *
client, addr_vec.at ( i ),
true, aVerbose ) )
350 if ( ! validation_test_single_write_read ( *
client, addr_vec.at ( i ),
false || aDispatchEachIteration, aVerbose ) )
357 cout <<
"\n 2. Block write/read (" << addr_vec.size() * 2 <<
" tests)" << endl;
359 for (
unsigned i = 0; i < addr_vec.size(); i++ )
361 uint32_t
addr = addr_vec.at ( i );
362 uint32_t max_depth = aBaseAddr + aDepth -
addr;
363 uint32_t depth = rand() % ( max_depth + 1 );
367 if ( ! validation_test_block_write_read ( *
client,
addr, depth,
true, aVerbose ) )
375 if ( ! validation_test_block_write_read ( *
client,
addr, depth,
false || aDispatchEachIteration, aVerbose ) )
382 cout <<
"\n 3. Testing RMW-bits (write, RMWbits, read; " << addr_vec.size() * 2 <<
" tests)" << endl;
384 for ( std::vector<uint32_t>::const_iterator it = addr_vec.begin(); it != addr_vec.end(); it++ )
388 if ( ! validation_test_write_rmwbits_read ( *
client, *it,
true, aVerbose ) )
396 if ( ! validation_test_write_rmwbits_read ( *
client, *it,
false || aDispatchEachIteration, aVerbose ) )
403 cout <<
"\n 4. Testing RMW-sum (write, RMW-sum, read; " << addr_vec.size() * 2 <<
" tests)" << endl;
405 for ( std::vector<uint32_t>::const_iterator it = addr_vec.begin(); it != addr_vec.end(); it++ )
409 if ( ! validation_test_write_rmwsum_read ( *
client, *it,
true, aVerbose ) )
417 if ( ! validation_test_write_rmwsum_read ( *
client, *it,
false || aDispatchEachIteration, aVerbose ) )
425 if ( nrTestsFailed == 0 )
427 cout <<
"\n\nBASIC TESTS SUMMARY: All " << nrTestsTotal <<
" tests passed!" << endl << endl << endl;
431 cout <<
"\n\nBASIC TESTS SUMMARY: Total of " << nrTestsTotal <<
" tests run -- " << nrTestsFailed <<
" tests FAILED , " << ( nrTestsTotal - nrTestsFailed ) <<
" tests PASSED" << endl;
437 for ( ClientIt_t clientIt = aClients.begin(); clientIt != aClients.end(); clientIt++ )
440 cout <<
"\nSOAK TEST to device '" <<
client->
uri() <<
"'\n Random sequence of " << aNrIterations <<
" transactions will be sent to hardware" << endl << endl;
443 size_t found =
client->
uri().find (
"-1.3" );
445 if ( found!=std::string::npos )
453 if ( found!=std::string::npos )
459 log (
Error() ,
"Cannot deduce protocol from URI " ,
Quote (
client->
uri() ),
" Exiting before performing soak test." );
465 std::vector< uint32_t > registers ( aDepth , 0x00000000 );
469 uint32_t type,
addr, blockSize;
470 uint32_t tempUInt1, tempUInt2;
471 vector< boost::shared_ptr<QueuedTransaction> > queuedTransactions;
472 uint32_t nrQueuedWords = 0;
474 for (
unsigned i = 1; i <= aNrIterations; i++ )
476 type = ( rand() % 4 );
477 addr = aBaseAddr + ( rand() % aDepth );
483 blockSize = getRandomBlockSize ( aBaseAddr + aDepth -
addr );
488 nrQueuedWords += blockSize;
493 blockSize = getRandomBlockSize ( aBaseAddr + aDepth -
addr );
496 vector<uint32_t> randomData = getRandomBuffer ( blockSize );
498 std::copy ( randomData.begin(), randomData.end(), registers.begin() + (
addr - aBaseAddr ) );
500 nrQueuedWords += blockSize;
508 vector<uint32_t>::iterator regIt = registers.begin() + (
addr - aBaseAddr );
510 if ( ipbus_vsn == 1 )
520 if ( ipbus_vsn == 2 )
532 vector<uint32_t>::iterator regIt = registers.begin() + (
addr - aBaseAddr );
534 if ( ipbus_vsn == 1 )
543 if ( ipbus_vsn == 2 )
552 if ( aDispatchEachIteration || ( nrQueuedWords > 20000000 ) || ( i == aNrIterations ) )
554 log (
Notice(),
"Soak test - issuing dispatch" );
556 log (
Notice(),
"Soak test - issuing empty dispatch" );
561 if ( ! ( *it )->check_values() )
563 cout <<
"ERROR OCCURED IN SOAK TEST to '" <<
client->
uri() <<
"' - after " << i <<
" successful transactions" << endl;
568 queuedTransactions.clear();
573 std::cout <<
"No errors after " << i <<
" transactions -- " << setiosflags (
ios::fixed ) << setprecision ( 1 ) << ( 100.0 * i ) / aNrIterations <<
"% done\r";
580 cout << endl <<
"Reached end of soak testing successfully!" << endl;
588 m_depth ( valVector.size() ),
590 m_valVector ( valVector )
600 std::vector<uint32_t>::const_iterator valVecIt = m_valVector.begin();
601 std::vector<uint32_t>::const_iterator expdIt = m_expected.begin();
603 for ( ; valVecIt != m_valVector.end(); valVecIt++, expdIt++ )
605 if ( ( *valVecIt ) != ( *expdIt ) )
607 uint32_t
addr = m_addr + ( valVecIt - m_valVector.begin() );
608 log (
Error(),
"TEST FAILED: In ",
Integer ( m_depth ),
"-word read @ ",
Integer ( m_addr,
IntFmt<hex,fixed>() ),
", register ",
Integer (
addr,
IntFmt<hex,fixed>() ),
" has value ",
Integer ( *valVecIt,
IntFmt<hex,fixed>() ),
", but expected value ",
Integer ( *expdIt,
IntFmt<hex,fixed>() ) );
613 log (
Notice(),
"TEST PASSED: Incrementing ",
Integer ( m_depth ),
"-word read @ ",
Integer ( m_addr,
IntFmt<hex,fixed>() ),
" --> ",
Integer ( m_addr + m_depth - 1,
IntFmt<hex,fixed>() ) );
623 m_valHeader ( valHeader )
631 if ( ! m_valHeader.valid() )
637 log (
Notice(),
"TEST PASSED: Incrementing ",
Integer ( m_depth ),
"-word write @ ",
Integer ( m_addr,
IntFmt<hex,fixed>() ),
" --> ",
Integer ( m_addr + m_depth - 1,
IntFmt<hex,fixed>() ) );
648 m_valWord ( valWord ),
649 m_expected ( expected )
657 if ( m_valWord.value() != m_expected )
659 log (
Error(),
"TEST FAILED: RMW-bits @ ",
Integer ( m_addr,
IntFmt<hex,fixed>() ),
" (AND=",
Integer ( m_and,
IntFmt<hex,fixed>() ),
", OR=",
Integer ( m_or,
IntFmt<hex,fixed>() ),
"). Transaction returned ",
Integer ( m_valWord.value(),
IntFmt<hex,fixed>() ),
", but expected ",
Integer ( m_expected,
IntFmt<hex,fixed>() ) );
673 m_valWord ( valWord ),
674 m_expected ( expected )
682 if ( m_valWord.value() != m_expected )
684 log (
Error(),
"TEST FAILED: RMW-sum @ ",
Integer ( m_addr,
IntFmt<hex,fixed>() ),
", ADDEND=",
Integer ( m_addend,
IntFmt<hex,fixed>() ),
". Transaction returned ",
Integer ( m_valWord.value(),
IntFmt<hex,fixed>() ),
", but I expected ",
Integer ( m_expected,
IntFmt<>() ) );