2017-11-09 19:34:51 +01:00
/*
* This file is part of the Flowee project
* Copyright (C) 2011-2015 The Bitcoin Core developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2014-03-18 10:11:00 +01:00
2011-09-28 21:35:58 +02:00
2014-06-26 14:41:53 +02:00
# include "random.h"
2014-08-21 16:11:09 +02:00
# include "utilmoneystr.h"
2015-03-12 09:34:42 +01:00
# include "test/test_bitcoin.h"
2018-07-23 18:05:43 +02:00
# include <utilstrencodings.h>
# include <utiltime.h>
# include <allowed_args.h>
# include <util.h>
2013-04-13 00:13:08 -05:00
# include <boost/test/unit_test.hpp>
2015-03-12 09:34:42 +01:00
BOOST_FIXTURE_TEST_SUITE ( util_tests , BasicTestingSetup )
2011-09-28 21:35:58 +02:00
2011-11-02 18:10:41 -04:00
BOOST_AUTO_TEST_CASE ( util_criticalsection )
{
CCriticalSection cs ;
do {
2012-04-06 18:39:12 +02:00
LOCK ( cs ) ;
break ;
2011-11-02 18:10:41 -04:00
BOOST_ERROR ( " break was swallowed! " ) ;
} while ( 0 ) ;
do {
2012-04-06 18:39:12 +02:00
TRY_LOCK ( cs , lockTest ) ;
if ( lockTest )
2011-11-02 18:10:41 -04:00
break ;
BOOST_ERROR ( " break was swallowed! " ) ;
} while ( 0 ) ;
}
2011-10-01 02:47:47 +02:00
BOOST_AUTO_TEST_CASE ( util_DateTimeStrFormat )
{
2013-01-01 19:48:28 -05:00
BOOST_CHECK_EQUAL ( DateTimeStrFormat ( " %Y-%m-%d %H:%M:%S " , 0 ) , " 1970-01-01 00:00:00 " ) ;
BOOST_CHECK_EQUAL ( DateTimeStrFormat ( " %Y-%m-%d %H:%M:%S " , 0x7FFFFFFF ) , " 2038-01-19 03:14:07 " ) ;
BOOST_CHECK_EQUAL ( DateTimeStrFormat ( " %Y-%m-%d %H:%M:%S " , 1317425777 ) , " 2011-09-30 23:36:17 " ) ;
BOOST_CHECK_EQUAL ( DateTimeStrFormat ( " %Y-%m-%d %H:%M " , 1317425777 ) , " 2011-09-30 23:36 " ) ;
2014-05-08 18:01:10 +02:00
BOOST_CHECK_EQUAL ( DateTimeStrFormat ( " %a, %d %b %Y %H:%M:%S +0000 " , 1317425777 ) , " Fri, 30 Sep 2011 23:36:17 +0000 " ) ;
2011-10-01 02:47:47 +02:00
}
BOOST_AUTO_TEST_CASE ( util_ParseParameters )
{
2019-04-22 20:33:35 +02:00
const char * argv_test [ ] = { " -ignored " , " -reindex " , " -api " , " -connect=argument " , " -connect=multiple " , " f " , " -d=e " } ;
2011-10-01 02:47:47 +02:00
2019-04-02 17:45:04 +02:00
ParseParameters ( 0 , ( char * * ) argv_test , Settings : : Hub ( ) ) ;
2011-10-01 02:47:47 +02:00
BOOST_CHECK ( mapArgs . empty ( ) & & mapMultiArgs . empty ( ) ) ;
2019-04-02 17:45:04 +02:00
ParseParameters ( 1 , ( char * * ) argv_test , Settings : : Hub ( ) ) ;
2011-10-01 02:47:47 +02:00
BOOST_CHECK ( mapArgs . empty ( ) & & mapMultiArgs . empty ( ) ) ;
2019-04-02 17:45:04 +02:00
ParseParameters ( 5 , ( char * * ) argv_test , Settings : : Hub ( ) ) ;
2013-04-28 17:37:50 +02:00
// expectation: -ignored is ignored (program name argument),
2019-04-22 20:33:35 +02:00
// -reindex, -api and -connect end up in map, -d ignored because it is after
2011-10-01 02:47:47 +02:00
// a non-option argument (non-GNU option parsing)
BOOST_CHECK ( mapArgs . size ( ) = = 3 & & mapMultiArgs . size ( ) = = 3 ) ;
2019-04-22 20:33:35 +02:00
BOOST_CHECK ( mapArgs . count ( " -reindex " ) & & mapArgs . count ( " -api " ) & & mapArgs . count ( " -connect " )
2011-10-01 02:47:47 +02:00
& & ! mapArgs . count ( " f " ) & & ! mapArgs . count ( " -d " ) ) ;
2019-04-22 20:33:35 +02:00
BOOST_CHECK ( mapMultiArgs . count ( " -reindex " ) & & mapMultiArgs . count ( " -api " ) & & mapMultiArgs . count ( " -connect " )
2011-10-01 02:47:47 +02:00
& & ! mapMultiArgs . count ( " f " ) & & ! mapMultiArgs . count ( " -d " ) ) ;
2017-01-23 01:56:55 -08:00
BOOST_CHECK ( mapArgs [ " -reindex " ] = = " " & & mapArgs [ " -connect " ] = = " multiple " ) ;
BOOST_CHECK ( mapMultiArgs [ " -connect " ] . size ( ) = = 2 ) ;
}
2011-10-01 02:47:47 +02:00
BOOST_AUTO_TEST_CASE ( util_GetArg )
{
mapArgs . clear ( ) ;
mapArgs [ " strtest1 " ] = " string... " ;
// strtest2 undefined on purpose
mapArgs [ " inttest1 " ] = " 12345 " ;
mapArgs [ " inttest2 " ] = " 81985529216486895 " ;
// inttest3 undefined on purpose
mapArgs [ " booltest1 " ] = " " ;
// booltest2 undefined on purpose
mapArgs [ " booltest3 " ] = " 0 " ;
mapArgs [ " booltest4 " ] = " 1 " ;
BOOST_CHECK_EQUAL ( GetArg ( " strtest1 " , " default " ) , " string... " ) ;
BOOST_CHECK_EQUAL ( GetArg ( " strtest2 " , " default " ) , " default " ) ;
BOOST_CHECK_EQUAL ( GetArg ( " inttest1 " , - 1 ) , 12345 ) ;
2011-10-03 13:10:31 -04:00
BOOST_CHECK_EQUAL ( GetArg ( " inttest2 " , - 1 ) , 81985529216486895LL ) ;
2011-10-01 02:47:47 +02:00
BOOST_CHECK_EQUAL ( GetArg ( " inttest3 " , - 1 ) , - 1 ) ;
2013-04-28 17:37:50 +02:00
BOOST_CHECK_EQUAL ( GetBoolArg ( " booltest1 " , false ) , true ) ;
BOOST_CHECK_EQUAL ( GetBoolArg ( " booltest2 " , false ) , false ) ;
BOOST_CHECK_EQUAL ( GetBoolArg ( " booltest3 " , false ) , false ) ;
BOOST_CHECK_EQUAL ( GetBoolArg ( " booltest4 " , false ) , true ) ;
2011-10-01 02:47:47 +02:00
}
BOOST_AUTO_TEST_CASE ( util_FormatMoney )
{
2015-06-04 14:43:02 +02:00
BOOST_CHECK_EQUAL ( FormatMoney ( 0 ) , " 0.00 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( ( COIN / 10000 ) * 123456789 ) , " 12345.6789 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( - COIN ) , " -1.00 " ) ;
2011-10-01 02:47:47 +02:00
2015-06-04 14:43:02 +02:00
BOOST_CHECK_EQUAL ( FormatMoney ( COIN * 100000000 ) , " 100000000.00 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( COIN * 10000000 ) , " 10000000.00 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( COIN * 1000000 ) , " 1000000.00 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( COIN * 100000 ) , " 100000.00 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( COIN * 10000 ) , " 10000.00 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( COIN * 1000 ) , " 1000.00 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( COIN * 100 ) , " 100.00 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( COIN * 10 ) , " 10.00 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( COIN ) , " 1.00 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( COIN / 10 ) , " 0.10 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( COIN / 100 ) , " 0.01 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( COIN / 1000 ) , " 0.001 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( COIN / 10000 ) , " 0.0001 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( COIN / 100000 ) , " 0.00001 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( COIN / 1000000 ) , " 0.000001 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( COIN / 10000000 ) , " 0.0000001 " ) ;
BOOST_CHECK_EQUAL ( FormatMoney ( COIN / 100000000 ) , " 0.00000001 " ) ;
2011-10-01 02:47:47 +02:00
}
BOOST_AUTO_TEST_CASE ( util_ParseMoney )
{
2021-01-20 19:21:53 +01:00
int64_t ret = 0 ;
2011-10-01 02:47:47 +02:00
BOOST_CHECK ( ParseMoney ( " 0.0 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , 0 ) ;
BOOST_CHECK ( ParseMoney ( " 12345.6789 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , ( COIN / 10000 ) * 123456789 ) ;
BOOST_CHECK ( ParseMoney ( " 100000000.00 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN * 100000000 ) ;
BOOST_CHECK ( ParseMoney ( " 10000000.00 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN * 10000000 ) ;
BOOST_CHECK ( ParseMoney ( " 1000000.00 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN * 1000000 ) ;
BOOST_CHECK ( ParseMoney ( " 100000.00 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN * 100000 ) ;
BOOST_CHECK ( ParseMoney ( " 10000.00 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN * 10000 ) ;
BOOST_CHECK ( ParseMoney ( " 1000.00 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN * 1000 ) ;
BOOST_CHECK ( ParseMoney ( " 100.00 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN * 100 ) ;
BOOST_CHECK ( ParseMoney ( " 10.00 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN * 10 ) ;
BOOST_CHECK ( ParseMoney ( " 1.00 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN ) ;
2016-01-19 17:47:55 +01:00
BOOST_CHECK ( ParseMoney ( " 1 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN ) ;
2011-10-01 02:47:47 +02:00
BOOST_CHECK ( ParseMoney ( " 0.1 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN / 10 ) ;
BOOST_CHECK ( ParseMoney ( " 0.01 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN / 100 ) ;
BOOST_CHECK ( ParseMoney ( " 0.001 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN / 1000 ) ;
BOOST_CHECK ( ParseMoney ( " 0.0001 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN / 10000 ) ;
BOOST_CHECK ( ParseMoney ( " 0.00001 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN / 100000 ) ;
BOOST_CHECK ( ParseMoney ( " 0.000001 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN / 1000000 ) ;
BOOST_CHECK ( ParseMoney ( " 0.0000001 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN / 10000000 ) ;
BOOST_CHECK ( ParseMoney ( " 0.00000001 " , ret ) ) ;
BOOST_CHECK_EQUAL ( ret , COIN / 100000000 ) ;
// Attempted 63 bit overflow should fail
BOOST_CHECK ( ! ParseMoney ( " 92233720368.54775808 " , ret ) ) ;
2016-01-19 17:47:55 +01:00
// Parsing negative amounts must fail
BOOST_CHECK ( ! ParseMoney ( " -1 " , ret ) ) ;
2011-09-28 21:35:58 +02:00
}
2013-02-15 15:27:57 -08:00
BOOST_AUTO_TEST_CASE ( util_seed_insecure_rand )
{
int i ;
int count = 0 ;
2013-06-25 12:06:43 -07:00
seed_insecure_rand ( true ) ;
2013-02-15 15:27:57 -08:00
for ( int mod = 2 ; mod < 11 ; mod + + )
{
int mask = 1 ;
// Really rough binomal confidence approximation.
int err = 30 * 10000. / mod * sqrt ( ( 1. / mod * ( 1 - 1. / mod ) ) / 10000. ) ;
//mask is 2^ceil(log2(mod))-1
while ( mask < mod - 1 ) mask = ( mask < < 1 ) + 1 ;
count = 0 ;
//How often does it get a zero from the uniform range [0,mod)?
for ( i = 0 ; i < 10000 ; i + + )
{
uint32_t rval ;
do {
rval = insecure_rand ( ) & mask ;
} while ( rval > = ( uint32_t ) mod ) ;
count + = rval = = 0 ;
}
BOOST_CHECK ( count < = 10000 / mod + err ) ;
BOOST_CHECK ( count > = 10000 / mod - err ) ;
}
}
2013-08-08 19:58:57 +10:00
BOOST_AUTO_TEST_CASE ( util_TimingResistantEqual )
{
BOOST_CHECK ( TimingResistantEqual ( std : : string ( " " ) , std : : string ( " " ) ) ) ;
BOOST_CHECK ( ! TimingResistantEqual ( std : : string ( " abc " ) , std : : string ( " " ) ) ) ;
BOOST_CHECK ( ! TimingResistantEqual ( std : : string ( " " ) , std : : string ( " abc " ) ) ) ;
BOOST_CHECK ( ! TimingResistantEqual ( std : : string ( " a " ) , std : : string ( " aa " ) ) ) ;
BOOST_CHECK ( ! TimingResistantEqual ( std : : string ( " aa " ) , std : : string ( " a " ) ) ) ;
BOOST_CHECK ( TimingResistantEqual ( std : : string ( " abc " ) , std : : string ( " abc " ) ) ) ;
BOOST_CHECK ( ! TimingResistantEqual ( std : : string ( " abc " ) , std : : string ( " aba " ) ) ) ;
}
2014-01-09 11:35:38 +01:00
/* Check for mingw/wine issue #3494
* Remove this test before time.ctime(0xffffffff) == 'Sun Feb 7 07:28:15 2106'
*/
BOOST_AUTO_TEST_CASE ( gettime )
{
BOOST_CHECK ( ( GetTime ( ) & ~ 0xFFFFFFFFLL ) = = 0 ) ;
}
2014-06-10 16:02:29 +02:00
BOOST_AUTO_TEST_CASE ( test_FormatParagraph )
{
BOOST_CHECK_EQUAL ( FormatParagraph ( " " , 79 , 0 ) , " " ) ;
BOOST_CHECK_EQUAL ( FormatParagraph ( " test " , 79 , 0 ) , " test " ) ;
BOOST_CHECK_EQUAL ( FormatParagraph ( " test " , 79 , 0 ) , " test " ) ;
BOOST_CHECK_EQUAL ( FormatParagraph ( " test test " , 79 , 0 ) , " test test " ) ;
BOOST_CHECK_EQUAL ( FormatParagraph ( " test test " , 4 , 0 ) , " test \n test " ) ;
BOOST_CHECK_EQUAL ( FormatParagraph ( " testerde test " , 4 , 0 ) , " testerde \n test " ) ;
BOOST_CHECK_EQUAL ( FormatParagraph ( " test test " , 4 , 4 ) , " test \n test " ) ;
2014-12-06 22:49:07 +01:00
BOOST_CHECK_EQUAL ( FormatParagraph ( " This is a very long test string. This is a second sentence in the very long test string. " ) , " This is a very long test string. This is a second sentence in the very long \n test string. " ) ;
2014-06-10 16:02:29 +02:00
}
2015-07-06 10:49:24 +02:00
BOOST_AUTO_TEST_CASE ( test_ParseFixedPoint )
{
int64_t amount = 0 ;
BOOST_CHECK ( ParseFixedPoint ( " 0 " , 8 , & amount ) ) ;
BOOST_CHECK_EQUAL ( amount , 0LL ) ;
BOOST_CHECK ( ParseFixedPoint ( " 1 " , 8 , & amount ) ) ;
BOOST_CHECK_EQUAL ( amount , 100000000LL ) ;
BOOST_CHECK ( ParseFixedPoint ( " 0.0 " , 8 , & amount ) ) ;
BOOST_CHECK_EQUAL ( amount , 0LL ) ;
BOOST_CHECK ( ParseFixedPoint ( " -0.1 " , 8 , & amount ) ) ;
BOOST_CHECK_EQUAL ( amount , - 10000000LL ) ;
BOOST_CHECK ( ParseFixedPoint ( " 1.1 " , 8 , & amount ) ) ;
BOOST_CHECK_EQUAL ( amount , 110000000LL ) ;
BOOST_CHECK ( ParseFixedPoint ( " 1.10000000000000000 " , 8 , & amount ) ) ;
BOOST_CHECK_EQUAL ( amount , 110000000LL ) ;
BOOST_CHECK ( ParseFixedPoint ( " 1.1e1 " , 8 , & amount ) ) ;
BOOST_CHECK_EQUAL ( amount , 1100000000LL ) ;
BOOST_CHECK ( ParseFixedPoint ( " 1.1e-1 " , 8 , & amount ) ) ;
BOOST_CHECK_EQUAL ( amount , 11000000LL ) ;
BOOST_CHECK ( ParseFixedPoint ( " 1000 " , 8 , & amount ) ) ;
BOOST_CHECK_EQUAL ( amount , 100000000000LL ) ;
BOOST_CHECK ( ParseFixedPoint ( " -1000 " , 8 , & amount ) ) ;
BOOST_CHECK_EQUAL ( amount , - 100000000000LL ) ;
BOOST_CHECK ( ParseFixedPoint ( " 0.00000001 " , 8 , & amount ) ) ;
BOOST_CHECK_EQUAL ( amount , 1LL ) ;
BOOST_CHECK ( ParseFixedPoint ( " 0.0000000100000000 " , 8 , & amount ) ) ;
BOOST_CHECK_EQUAL ( amount , 1LL ) ;
BOOST_CHECK ( ParseFixedPoint ( " -0.00000001 " , 8 , & amount ) ) ;
BOOST_CHECK_EQUAL ( amount , - 1LL ) ;
BOOST_CHECK ( ParseFixedPoint ( " 1000000000.00000001 " , 8 , & amount ) ) ;
BOOST_CHECK_EQUAL ( amount , 100000000000000001LL ) ;
BOOST_CHECK ( ParseFixedPoint ( " 9999999999.99999999 " , 8 , & amount ) ) ;
BOOST_CHECK_EQUAL ( amount , 999999999999999999LL ) ;
BOOST_CHECK ( ParseFixedPoint ( " -9999999999.99999999 " , 8 , & amount ) ) ;
BOOST_CHECK_EQUAL ( amount , - 999999999999999999LL ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " - " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " a-1000 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " -a1000 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " -1000a " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " -01000 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " 00.1 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " .1 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " --0.1 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " 0.000000001 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " -0.000000001 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " 0.00000001000000001 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " -10000000000.00000000 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " 10000000000.00000000 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " -10000000000.00000001 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " 10000000000.00000001 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " -10000000000.00000009 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " 10000000000.00000009 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " -99999999999.99999999 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " 99999909999.09999999 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " 92233720368.54775807 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " 92233720368.54775808 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " -92233720368.54775808 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " -92233720368.54775809 " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " 1.1e " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " 1.1e- " , 8 , & amount ) ) ;
BOOST_CHECK ( ! ParseFixedPoint ( " 1. " , 8 , & amount ) ) ;
}
2011-09-28 21:35:58 +02:00
BOOST_AUTO_TEST_SUITE_END ( )