Normalize files containing unit test code:

Source files are split to place all unit test code into translation
units ending in .test.cpp with no other business logic in the same file,
and in directories named "test".

A new target is added to the SConstruct, invoked by:
    scons count
This prints the total number of source code lines occupied by unit tests,
in rippled specific code and excluding library subtrees.
This commit is contained in:
Vinnie Falco
2014-12-23 12:28:19 -08:00
parent 9eb7c8344f
commit 9a3214d46e
65 changed files with 2396 additions and 2788 deletions

View File

@@ -1956,14 +1956,6 @@
</ClCompile>
<ClInclude Include="..\..\src\ripple\app\peers\UniqueNodeList.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\app\shamap\FetchPackTests.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\app\shamap\RadixMapTest.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\app\shamap\RadixMapTest.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\app\shamap\SHAMap.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
@@ -2004,6 +1996,15 @@
</ClCompile>
<ClInclude Include="..\..\src\ripple\app\shamap\SHAMapTreeNode.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\app\shamap\tests\FetchPack.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\app\shamap\tests\SHAMap.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\app\shamap\tests\SHAMapSync.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\app\shamap\TreeNodeCache.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\app\transactors\AddWallet.cpp">
@@ -2124,9 +2125,6 @@
<ClCompile Include="..\..\src\ripple\basics\impl\CountedObject.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\basics\impl\KeyCache.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\basics\impl\Log.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
@@ -2145,9 +2143,6 @@
<ClCompile Include="..\..\src\ripple\basics\impl\Sustain.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\basics\impl\TaggedCache.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\basics\impl\TestSuite.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
@@ -2193,6 +2188,18 @@
<ClCompile Include="..\..\src\ripple\basics\tests\CheckLibraryVersions.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\basics\tests\KeyCache.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\basics\tests\RangeSet.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\basics\tests\StringUtilities.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\basics\tests\TaggedCache.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\basics\ThreadName.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\basics\Time.h">
@@ -2243,6 +2250,9 @@
</ClInclude>
<ClInclude Include="..\..\src\ripple\core\LoadMonitor.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\core\tests\LoadFeeTrack.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\crypto\Base58.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\crypto\Base58Data.h">
@@ -2305,6 +2315,9 @@
<ClCompile Include="..\..\src\ripple\crypto\tests\CKey.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\crypto\tests\ECDSACanonical.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\json\impl\JsonPropertyStream.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
@@ -2325,9 +2338,6 @@
<ClCompile Include="..\..\src\ripple\json\impl\json_writer.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\json\impl\Tests.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\json\impl\to_string.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
@@ -2345,6 +2355,9 @@
</ClInclude>
<ClInclude Include="..\..\src\ripple\json\json_writer.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\json\tests\JsonCpp.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\json\to_string.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\net\HTTPClient.h">
@@ -2478,18 +2491,18 @@
</ClInclude>
<ClInclude Include="..\..\src\ripple\nodestore\Task.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\nodestore\tests\BackendTests.cpp">
<ClCompile Include="..\..\src\ripple\nodestore\tests\Backend.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\nodestore\tests\BasicTests.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\nodestore\tests\DatabaseTests.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\nodestore\tests\TestBase.h">
<ClInclude Include="..\..\src\ripple\nodestore\tests\Base.test.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\nodestore\tests\TimingTests.cpp">
<ClCompile Include="..\..\src\ripple\nodestore\tests\Basics.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\nodestore\tests\Database.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\nodestore\tests\Timing.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\nodestore\Types.h">
@@ -2562,9 +2575,6 @@
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\impl\iosformat.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\peerfinder\impl\Livecache.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\peerfinder\impl\Livecache.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\impl\Logic.h">
@@ -2617,6 +2627,9 @@
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\Slot.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\peerfinder\tests\Livecache.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\protocol\Book.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\protocol\BuildInfo.h">
@@ -2640,9 +2653,6 @@
<ClCompile Include="..\..\src\ripple\protocol\impl\Indexes.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\impl\Issue.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\impl\LedgerFormats.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
@@ -2767,9 +2777,27 @@
</ClInclude>
<ClInclude Include="..\..\src\ripple\protocol\TER.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\protocol\tests\BuildInfo.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\Issue.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\RippleAddress.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\Serializer.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\STAmount.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\STObject.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\STTx.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\protocol\TxFlags.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\protocol\TxFormats.h">
@@ -2822,15 +2850,15 @@
<ClCompile Include="..\..\src\ripple\resource\impl\Manager.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\resource\impl\Tests.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\resource\impl\Tuning.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\resource\Manager.h">
</ClInclude>
<None Include="..\..\src\ripple\resource\README.md">
</None>
<ClCompile Include="..\..\src\ripple\resource\tests\Logic.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\Coroutine.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\rpc\handlers\AccountCurrencies.cpp">
@@ -3023,9 +3051,6 @@
<ClCompile Include="..\..\src\ripple\rpc\impl\Coroutine.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\Coroutine.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\impl\DoPrint.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\rpc\impl\GetMasterGenerator.cpp">
@@ -3043,17 +3068,11 @@
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\impl\JsonObject.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\rpc\impl\JsonObject.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\JsonWriter.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\impl\JsonWriter.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\rpc\impl\JsonWriter.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\LegacyPathFind.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
@@ -3078,11 +3097,6 @@
<ClCompile Include="..\..\src\ripple\rpc\impl\Status.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\Status.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\impl\TestOutputSuite.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\rpc\impl\TransactionSign.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
@@ -3098,15 +3112,9 @@
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\impl\WriteJson.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\rpc\impl\WriteJson.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\Yield.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\Yield.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\InternalHandler.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\rpc\Manager.h">
@@ -3119,6 +3127,29 @@
</ClInclude>
<ClInclude Include="..\..\src\ripple\rpc\Status.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\rpc\tests\Coroutine.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\tests\JsonObject.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\tests\JSONRPC.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\tests\JsonWriter.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\tests\Status.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\tests\TestOutputSuite.test.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\rpc\tests\WriteJson.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\tests\Yield.test.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\Yield.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\server\Handler.h">
@@ -3283,9 +3314,6 @@
</ClCompile>
<ClInclude Include="..\..\src\ripple\validators\impl\StoreSqdb.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\validators\impl\Tests.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\validators\impl\Tuning.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\validators\make_Manager.h">

View File

@@ -316,6 +316,9 @@
<Filter Include="ripple\app\shamap">
<UniqueIdentifier>{091DDFB4-76F4-04FB-2787-D51B4A44185E}</UniqueIdentifier>
</Filter>
<Filter Include="ripple\app\shamap\tests">
<UniqueIdentifier>{A42D8FD4-E866-E1A8-9CBC-1C75906F16D2}</UniqueIdentifier>
</Filter>
<Filter Include="ripple\app\transactors">
<UniqueIdentifier>{418BEF0D-AAAB-C368-7D9E-0A97636DE5A6}</UniqueIdentifier>
</Filter>
@@ -340,6 +343,9 @@
<Filter Include="ripple\core\impl">
<UniqueIdentifier>{D9A8899A-B47C-E5BB-DDF1-32A50545A7D3}</UniqueIdentifier>
</Filter>
<Filter Include="ripple\core\tests">
<UniqueIdentifier>{5F73731D-CF59-8478-EDA2-39A71739270E}</UniqueIdentifier>
</Filter>
<Filter Include="ripple\crypto">
<UniqueIdentifier>{165391B0-6CF7-0ECF-2566-2F12A922148E}</UniqueIdentifier>
</Filter>
@@ -355,6 +361,9 @@
<Filter Include="ripple\json\impl">
<UniqueIdentifier>{32043215-B959-04E5-00FF-F97C7F597235}</UniqueIdentifier>
</Filter>
<Filter Include="ripple\json\tests">
<UniqueIdentifier>{BA646284-836B-B151-F2AA-D18535D6F3C1}</UniqueIdentifier>
</Filter>
<Filter Include="ripple\net">
<UniqueIdentifier>{6649BD29-BE86-723F-501A-045E39310112}</UniqueIdentifier>
</Filter>
@@ -391,6 +400,9 @@
<Filter Include="ripple\peerfinder\sim">
<UniqueIdentifier>{F1CDEBFB-0510-764D-010B-F14BCA9456EB}</UniqueIdentifier>
</Filter>
<Filter Include="ripple\peerfinder\tests">
<UniqueIdentifier>{F2EC594B-6D2A-0451-45B8-8E4156D40945}</UniqueIdentifier>
</Filter>
<Filter Include="ripple\proto">
<UniqueIdentifier>{8016685C-6468-9514-D06F-F95060DB5F10}</UniqueIdentifier>
</Filter>
@@ -409,6 +421,9 @@
<Filter Include="ripple\resource\impl">
<UniqueIdentifier>{A05858D1-18F0-3A7E-ECFD-7729C370F65B}</UniqueIdentifier>
</Filter>
<Filter Include="ripple\resource\tests">
<UniqueIdentifier>{B4DC189A-ACB2-1622-78C8-0489DC1F875F}</UniqueIdentifier>
</Filter>
<Filter Include="ripple\rpc">
<UniqueIdentifier>{BCDBB833-2810-D5F5-A023-4E346AD0EED3}</UniqueIdentifier>
</Filter>
@@ -418,6 +433,9 @@
<Filter Include="ripple\rpc\impl">
<UniqueIdentifier>{93AC3675-D183-4DB4-021E-8F4CA1586866}</UniqueIdentifier>
</Filter>
<Filter Include="ripple\rpc\tests">
<UniqueIdentifier>{84FF17C5-6A81-FF13-548E-59940FE0060E}</UniqueIdentifier>
</Filter>
<Filter Include="ripple\server">
<UniqueIdentifier>{8A61DBF7-69CB-9043-8312-D44C40EC6AE9}</UniqueIdentifier>
</Filter>
@@ -2847,15 +2865,6 @@
<ClInclude Include="..\..\src\ripple\app\peers\UniqueNodeList.h">
<Filter>ripple\app\peers</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\app\shamap\FetchPackTests.cpp">
<Filter>ripple\app\shamap</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\app\shamap\RadixMapTest.cpp">
<Filter>ripple\app\shamap</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\app\shamap\RadixMapTest.h">
<Filter>ripple\app\shamap</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\app\shamap\SHAMap.cpp">
<Filter>ripple\app\shamap</Filter>
</ClCompile>
@@ -2904,6 +2913,15 @@
<ClInclude Include="..\..\src\ripple\app\shamap\SHAMapTreeNode.h">
<Filter>ripple\app\shamap</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\app\shamap\tests\FetchPack.test.cpp">
<Filter>ripple\app\shamap\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\app\shamap\tests\SHAMap.test.cpp">
<Filter>ripple\app\shamap\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\app\shamap\tests\SHAMapSync.test.cpp">
<Filter>ripple\app\shamap\tests</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\app\shamap\TreeNodeCache.h">
<Filter>ripple\app\shamap</Filter>
</ClInclude>
@@ -3045,9 +3063,6 @@
<ClCompile Include="..\..\src\ripple\basics\impl\CountedObject.cpp">
<Filter>ripple\basics\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\basics\impl\KeyCache.cpp">
<Filter>ripple\basics\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\basics\impl\Log.cpp">
<Filter>ripple\basics\impl</Filter>
</ClCompile>
@@ -3066,9 +3081,6 @@
<ClCompile Include="..\..\src\ripple\basics\impl\Sustain.cpp">
<Filter>ripple\basics\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\basics\impl\TaggedCache.cpp">
<Filter>ripple\basics\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\basics\impl\TestSuite.test.cpp">
<Filter>ripple\basics\impl</Filter>
</ClCompile>
@@ -3129,6 +3141,18 @@
<ClCompile Include="..\..\src\ripple\basics\tests\CheckLibraryVersions.test.cpp">
<Filter>ripple\basics\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\basics\tests\KeyCache.test.cpp">
<Filter>ripple\basics\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\basics\tests\RangeSet.test.cpp">
<Filter>ripple\basics\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\basics\tests\StringUtilities.test.cpp">
<Filter>ripple\basics\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\basics\tests\TaggedCache.test.cpp">
<Filter>ripple\basics\tests</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\basics\ThreadName.h">
<Filter>ripple\basics</Filter>
</ClInclude>
@@ -3195,6 +3219,9 @@
<ClInclude Include="..\..\src\ripple\core\LoadMonitor.h">
<Filter>ripple\core</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\core\tests\LoadFeeTrack.test.cpp">
<Filter>ripple\core\tests</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\crypto\Base58.h">
<Filter>ripple\crypto</Filter>
</ClInclude>
@@ -3270,6 +3297,9 @@
<ClCompile Include="..\..\src\ripple\crypto\tests\CKey.test.cpp">
<Filter>ripple\crypto\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\crypto\tests\ECDSACanonical.test.cpp">
<Filter>ripple\crypto\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\json\impl\JsonPropertyStream.cpp">
<Filter>ripple\json\impl</Filter>
</ClCompile>
@@ -3294,9 +3324,6 @@
<ClCompile Include="..\..\src\ripple\json\impl\json_writer.cpp">
<Filter>ripple\json\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\json\impl\Tests.cpp">
<Filter>ripple\json\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\json\impl\to_string.cpp">
<Filter>ripple\json\impl</Filter>
</ClCompile>
@@ -3321,6 +3348,9 @@
<ClInclude Include="..\..\src\ripple\json\json_writer.h">
<Filter>ripple\json</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\json\tests\JsonCpp.test.cpp">
<Filter>ripple\json\tests</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\json\to_string.h">
<Filter>ripple\json</Filter>
</ClInclude>
@@ -3483,19 +3513,19 @@
<ClInclude Include="..\..\src\ripple\nodestore\Task.h">
<Filter>ripple\nodestore</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\nodestore\tests\BackendTests.cpp">
<ClCompile Include="..\..\src\ripple\nodestore\tests\Backend.test.cpp">
<Filter>ripple\nodestore\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\nodestore\tests\BasicTests.cpp">
<Filter>ripple\nodestore\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\nodestore\tests\DatabaseTests.cpp">
<Filter>ripple\nodestore\tests</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\nodestore\tests\TestBase.h">
<ClInclude Include="..\..\src\ripple\nodestore\tests\Base.test.h">
<Filter>ripple\nodestore\tests</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\nodestore\tests\TimingTests.cpp">
<ClCompile Include="..\..\src\ripple\nodestore\tests\Basics.test.cpp">
<Filter>ripple\nodestore\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\nodestore\tests\Database.test.cpp">
<Filter>ripple\nodestore\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\nodestore\tests\Timing.test.cpp">
<Filter>ripple\nodestore\tests</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\nodestore\Types.h">
@@ -3588,9 +3618,6 @@
<ClInclude Include="..\..\src\ripple\peerfinder\impl\iosformat.h">
<Filter>ripple\peerfinder\impl</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\peerfinder\impl\Livecache.cpp">
<Filter>ripple\peerfinder\impl</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\peerfinder\impl\Livecache.h">
<Filter>ripple\peerfinder\impl</Filter>
</ClInclude>
@@ -3663,6 +3690,9 @@
<ClInclude Include="..\..\src\ripple\peerfinder\Slot.h">
<Filter>ripple\peerfinder</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\peerfinder\tests\Livecache.test.cpp">
<Filter>ripple\peerfinder\tests</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\protocol\Book.h">
<Filter>ripple\protocol</Filter>
</ClInclude>
@@ -3690,9 +3720,6 @@
<ClCompile Include="..\..\src\ripple\protocol\impl\Indexes.cpp">
<Filter>ripple\protocol\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\impl\Issue.cpp">
<Filter>ripple\protocol\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\impl\LedgerFormats.cpp">
<Filter>ripple\protocol\impl</Filter>
</ClCompile>
@@ -3846,9 +3873,27 @@
<ClInclude Include="..\..\src\ripple\protocol\TER.h">
<Filter>ripple\protocol</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\protocol\tests\BuildInfo.test.cpp">
<Filter>ripple\protocol\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\Issue.test.cpp">
<Filter>ripple\protocol\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\RippleAddress.test.cpp">
<Filter>ripple\protocol\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\Serializer.test.cpp">
<Filter>ripple\protocol\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\STAmount.test.cpp">
<Filter>ripple\protocol\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\STObject.test.cpp">
<Filter>ripple\protocol\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\STTx.test.cpp">
<Filter>ripple\protocol\tests</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\protocol\TxFlags.h">
<Filter>ripple\protocol</Filter>
</ClInclude>
@@ -3906,9 +3951,6 @@
<ClCompile Include="..\..\src\ripple\resource\impl\Manager.cpp">
<Filter>ripple\resource\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\resource\impl\Tests.cpp">
<Filter>ripple\resource\impl</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\resource\impl\Tuning.h">
<Filter>ripple\resource\impl</Filter>
</ClInclude>
@@ -3918,6 +3960,9 @@
<None Include="..\..\src\ripple\resource\README.md">
<Filter>ripple\resource</Filter>
</None>
<ClCompile Include="..\..\src\ripple\resource\tests\Logic.test.cpp">
<Filter>ripple\resource\tests</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\Coroutine.h">
<Filter>ripple\rpc</Filter>
</ClInclude>
@@ -4116,9 +4161,6 @@
<ClCompile Include="..\..\src\ripple\rpc\impl\Coroutine.cpp">
<Filter>ripple\rpc\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\Coroutine.test.cpp">
<Filter>ripple\rpc\impl</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\impl\DoPrint.h">
<Filter>ripple\rpc\impl</Filter>
</ClInclude>
@@ -4140,18 +4182,12 @@
<ClInclude Include="..\..\src\ripple\rpc\impl\JsonObject.h">
<Filter>ripple\rpc\impl</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\rpc\impl\JsonObject.test.cpp">
<Filter>ripple\rpc\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\JsonWriter.cpp">
<Filter>ripple\rpc\impl</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\impl\JsonWriter.h">
<Filter>ripple\rpc\impl</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\rpc\impl\JsonWriter.test.cpp">
<Filter>ripple\rpc\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\LegacyPathFind.cpp">
<Filter>ripple\rpc\impl</Filter>
</ClCompile>
@@ -4179,12 +4215,6 @@
<ClCompile Include="..\..\src\ripple\rpc\impl\Status.cpp">
<Filter>ripple\rpc\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\Status.test.cpp">
<Filter>ripple\rpc\impl</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\impl\TestOutputSuite.h">
<Filter>ripple\rpc\impl</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\rpc\impl\TransactionSign.cpp">
<Filter>ripple\rpc\impl</Filter>
</ClCompile>
@@ -4203,15 +4233,9 @@
<ClInclude Include="..\..\src\ripple\rpc\impl\WriteJson.h">
<Filter>ripple\rpc\impl</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\rpc\impl\WriteJson.test.cpp">
<Filter>ripple\rpc\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\Yield.cpp">
<Filter>ripple\rpc\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\impl\Yield.test.cpp">
<Filter>ripple\rpc\impl</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\InternalHandler.h">
<Filter>ripple\rpc</Filter>
</ClInclude>
@@ -4230,6 +4254,30 @@
<ClInclude Include="..\..\src\ripple\rpc\Status.h">
<Filter>ripple\rpc</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\rpc\tests\Coroutine.test.cpp">
<Filter>ripple\rpc\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\tests\JsonObject.test.cpp">
<Filter>ripple\rpc\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\tests\JSONRPC.test.cpp">
<Filter>ripple\rpc\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\tests\JsonWriter.test.cpp">
<Filter>ripple\rpc\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\tests\Status.test.cpp">
<Filter>ripple\rpc\tests</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\tests\TestOutputSuite.test.h">
<Filter>ripple\rpc\tests</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\rpc\tests\WriteJson.test.cpp">
<Filter>ripple\rpc\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\tests\Yield.test.cpp">
<Filter>ripple\rpc\tests</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\rpc\Yield.h">
<Filter>ripple\rpc</Filter>
</ClInclude>
@@ -4446,9 +4494,6 @@
<ClInclude Include="..\..\src\ripple\validators\impl\StoreSqdb.h">
<Filter>ripple\validators\impl</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\validators\impl\Tests.cpp">
<Filter>ripple\validators\impl</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\validators\impl\Tuning.h">
<Filter>ripple\validators\impl</Filter>
</ClInclude>

View File

@@ -26,6 +26,8 @@
vcxproj Generate Visual Studio 2013 project file
count Show line count metrics
If the clang toolchain is detected, then the default target will use it, else
the gcc toolchain will be used. On Windows environments, the MSVC toolchain is
also detected.
@@ -676,3 +678,33 @@ vcxproj = base.VSProject(
VSPROJECT_ROOT_DIRS = ['src/beast', 'src', '.'],
VSPROJECT_CONFIGS = msvc_configs)
base.Alias('vcxproj', vcxproj)
#-------------------------------------------------------------------------------
# Adds a phony target to the environment that always builds
# See: http://www.scons.org/wiki/PhonyTargets
def PhonyTargets(env = None, **kw):
if not env: env = DefaultEnvironment()
for target, action in kw.items():
env.AlwaysBuild(env.Alias(target, [], action))
# Build the list of rippled source files that hold unit tests
def do_count(target, source, env):
def list_testfiles(base, suffixes):
def _iter(base):
for parent, _, files in os.walk(base):
for path in files:
path = os.path.join(parent, path)
r = os.path.splitext(path)
if r[1] in suffixes:
if r[0].endswith('.test'):
yield os.path.normpath(path)
return list(_iter(base))
testfiles = list_testfiles(os.path.join('src', 'ripple'), env.get('CPPSUFFIXES'))
lines = 0
for f in testfiles:
lines = lines + sum(1 for line in open(f))
print "Total unit test lines: %d" % lines
PhonyTargets(env, count = do_count)

View File

@@ -1,49 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <cassert>
namespace ripple {
namespace RadixMap {
std::shared_ptr <Item> make_random_item (beast::Random& r)
{
Serializer s;
for (int d = 0; d < 3; ++d)
s.add32 (r.nextInt ());
return std::make_shared <Item> (
to256(s.getRIPEMD160()), s.peekData ());
}
//------------------------------------------------------------------------------
void add_random_items (std::size_t n, Table& t, beast::Random& r)
{
while (n--)
{
std::shared_ptr <SHAMapItem> item (
make_random_item (r));
auto const result (t.addItem (*item, false, false));
assert (result);
(void) result;
}
}
}
}

View File

@@ -1,41 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <beast/module/core/maths/Random.h>
namespace ripple {
namespace RadixMap {
typedef SHAMap Table;
typedef SHAMapItem Item;
// Utility functions for RadixMap::Table (a.k.a. SHAMap) unit tests
/** Returns a pseudo random Table item. */
std::shared_ptr <Item> make_random_item (beast::Random& r);
/** Adds a set of random items to the Table.
@param n The number of items to add.
@param t The table to add the items to.
@param r A pseudo random number generator.
*/
void add_random_items (std::size_t n, Table& t, beast::Random& r);
}
}

View File

@@ -1165,103 +1165,4 @@ void SHAMap::canonicalize (uint256 const& hash, SHAMapTreeNode::pointer& node)
}
//------------------------------------------------------------------------------
class SHAMap_test : public beast::unit_test::suite
{
public:
// VFALCO TODO Rename this to createFilledVector and pass an unsigned char, tidy up
//
static Blob IntToVUC (int v)
{
Blob vuc;
for (int i = 0; i < 32; ++i)
vuc.push_back (static_cast<unsigned char> (v));
return vuc;
}
void run ()
{
testcase ("add/traverse");
beast::manual_clock <std::chrono::steady_clock> clock; // manual advance clock
beast::Journal const j; // debug journal
FullBelowCache fullBelowCache ("test.full_below", clock);
TreeNodeCache treeNodeCache ("test.tree_node_cache", 65536, 60, clock, j);
// h3 and h4 differ only in the leaf, same terminal node (level 19)
uint256 h1, h2, h3, h4, h5;
h1.SetHex ("092891fe4ef6cee585fdc6fda0e09eb4d386363158ec3321b8123e5a772c6ca7");
h2.SetHex ("436ccbac3347baa1f1e53baeef1f43334da88f1f6d70d963b833afd6dfa289fe");
h3.SetHex ("b92891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8");
h4.SetHex ("b92891fe4ef6cee585fdc6fda2e09eb4d386363158ec3321b8123e5a772c6ca8");
h5.SetHex ("a92891fe4ef6cee585fdc6fda0e09eb4d386363158ec3321b8123e5a772c6ca7");
SHAMap sMap (smtFREE, fullBelowCache, treeNodeCache);
SHAMapItem i1 (h1, IntToVUC (1)), i2 (h2, IntToVUC (2)), i3 (h3, IntToVUC (3)), i4 (h4, IntToVUC (4)), i5 (h5, IntToVUC (5));
unexpected (!sMap.addItem (i2, true, false), "no add");
unexpected (!sMap.addItem (i1, true, false), "no add");
SHAMapItem::pointer i;
i = sMap.peekFirstItem ();
unexpected (!i || (*i != i1), "bad traverse");
i = sMap.peekNextItem (i->getTag ());
unexpected (!i || (*i != i2), "bad traverse");
i = sMap.peekNextItem (i->getTag ());
unexpected (i, "bad traverse");
sMap.addItem (i4, true, false);
sMap.delItem (i2.getTag ());
sMap.addItem (i3, true, false);
i = sMap.peekFirstItem ();
unexpected (!i || (*i != i1), "bad traverse");
i = sMap.peekNextItem (i->getTag ());
unexpected (!i || (*i != i3), "bad traverse");
i = sMap.peekNextItem (i->getTag ());
unexpected (!i || (*i != i4), "bad traverse");
i = sMap.peekNextItem (i->getTag ());
unexpected (i, "bad traverse");
testcase ("snapshot");
uint256 mapHash = sMap.getHash ();
SHAMap::pointer map2 = sMap.snapShot (false);
unexpected (sMap.getHash () != mapHash, "bad snapshot");
unexpected (map2->getHash () != mapHash, "bad snapshot");
unexpected (!sMap.delItem (sMap.peekFirstItem ()->getTag ()), "bad mod");
unexpected (sMap.getHash () == mapHash, "bad snapshot");
unexpected (map2->getHash () != mapHash, "bad snapshot");
}
};
BEAST_DEFINE_TESTSUITE(SHAMap,ripple_app,ripple);
} // ripple

View File

@@ -748,204 +748,4 @@ std::list <Blob> SHAMap::getTrustedPath (uint256 const& index)
return path;
}
//------------------------------------------------------------------------------
#ifdef BEAST_DEBUG
//#define SMS_DEBUG
#endif
class SHAMapSync_test : public beast::unit_test::suite
{
public:
static SHAMapItem::pointer makeRandomAS ()
{
Serializer s;
for (int d = 0; d < 3; ++d) s.add32 (rand ());
return std::make_shared<SHAMapItem> (to256 (s.getRIPEMD160 ()), s.peekData ());
}
bool confuseMap (SHAMap& map, int count)
{
// add a bunch of random states to a map, then remove them
// map should be the same
uint256 beforeHash = map.getHash ();
std::list<uint256> items;
for (int i = 0; i < count; ++i)
{
SHAMapItem::pointer item = makeRandomAS ();
items.push_back (item->getTag ());
if (!map.addItem (*item, false, false))
{
log <<
"Unable to add item to map";
assert (false);
return false;
}
}
for (std::list<uint256>::iterator it = items.begin (); it != items.end (); ++it)
{
if (!map.delItem (*it))
{
log <<
"Unable to remove item from map";
assert (false);
return false;
}
}
if (beforeHash != map.getHash ())
{
log <<
"Hashes do not match " << beforeHash << " " << map.getHash ();
assert (false);
return false;
}
return true;
}
void run ()
{
unsigned int seed;
// VFALCO DEPRECATED Should use C++11
RAND_pseudo_bytes (reinterpret_cast<unsigned char*> (&seed), sizeof (seed));
srand (seed);
beast::manual_clock <std::chrono::steady_clock> clock; // manual advance clock
beast::Journal const j; // debug journal
FullBelowCache fullBelowCache ("test.full_below", clock);
TreeNodeCache treeNodeCache ("test.tree_node_cache", 65536, 60, clock, j);
SHAMap source (smtFREE, fullBelowCache, treeNodeCache);
SHAMap destination (smtFREE, fullBelowCache, treeNodeCache);
int items = 10000;
for (int i = 0; i < items; ++i)
source.addItem (*makeRandomAS (), false, false);
unexpected (!confuseMap (source, 500), "ConfuseMap");
source.setImmutable ();
std::vector<SHAMapNodeID> nodeIDs, gotNodeIDs;
std::list< Blob > gotNodes;
std::vector<uint256> hashes;
std::vector<SHAMapNodeID>::iterator nodeIDIterator;
std::list< Blob >::iterator rawNodeIterator;
int passes = 0;
int nodes = 0;
destination.setSynching ();
unexpected (!source.getNodeFat (SHAMapNodeID (), nodeIDs, gotNodes, (rand () % 2) == 0, (rand () % 2) == 0),
"GetNodeFat");
unexpected (gotNodes.size () < 1, "NodeSize");
unexpected (!destination.addRootNode (*gotNodes.begin (), snfWIRE, nullptr).isGood(), "AddRootNode");
nodeIDs.clear ();
gotNodes.clear ();
#ifdef SMS_DEBUG
int bytes = 0;
#endif
do
{
++clock;
++passes;
hashes.clear ();
// get the list of nodes we know we need
destination.getMissingNodes (nodeIDs, hashes, 2048, nullptr);
if (nodeIDs.empty ()) break;
// get as many nodes as possible based on this information
for (nodeIDIterator = nodeIDs.begin (); nodeIDIterator != nodeIDs.end (); ++nodeIDIterator)
{
if (!source.getNodeFat (*nodeIDIterator, gotNodeIDs, gotNodes, (rand () % 2) == 0, (rand () % 2) == 0))
{
WriteLog (lsFATAL, SHAMap) << "GetNodeFat fails";
fail ("GetNodeFat");
}
else
{
pass ();
}
}
assert (gotNodeIDs.size () == gotNodes.size ());
nodeIDs.clear ();
hashes.clear ();
if (gotNodeIDs.empty ())
{
fail ("Got Node ID");
}
else
{
pass ();
}
for (nodeIDIterator = gotNodeIDs.begin (), rawNodeIterator = gotNodes.begin ();
nodeIDIterator != gotNodeIDs.end (); ++nodeIDIterator, ++rawNodeIterator)
{
++nodes;
#ifdef SMS_DEBUG
bytes += rawNodeIterator->size ();
#endif
if (!destination.addKnownNode (*nodeIDIterator, *rawNodeIterator, nullptr).isGood ())
{
WriteLog (lsTRACE, SHAMap) << "AddKnownNode fails";
fail ("AddKnownNode");
}
else
{
pass ();
}
}
gotNodeIDs.clear ();
gotNodes.clear ();
}
while (true);
destination.clearSynching ();
#ifdef SMS_DEBUG
WriteLog (lsINFO, SHAMap) << "SYNCHING COMPLETE " << items << " items, " << nodes << " nodes, " <<
bytes / 1024 << " KB";
#endif
if (!source.deepCompare (destination))
{
fail ("Deep Compare");
}
else
{
pass ();
}
#ifdef SMS_DEBUG
WriteLog (lsINFO, SHAMap) << "SHAMapSync test passed: " << items << " items, " <<
passes << " passes, " << nodes << " nodes";
#endif
}
};
BEAST_DEFINE_TESTSUITE(SHAMapSync,ripple_app,ripple);
} // ripple

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#include <beast/module/core/maths/Random.h>
#include <beast/unit_test/suite.h>
#include <functional>
namespace ripple {
@@ -32,7 +32,9 @@ public:
tableItemsExtra = 20
};
typedef hash_map <uint256, Blob> Map;
using Map = hash_map <uint256, Blob> ;
using Table = SHAMap;
using Item = SHAMapItem;
struct TestFilter : SHAMapSyncFilter
{
@@ -63,6 +65,28 @@ public:
beast::Journal mJournal;
};
std::shared_ptr <Item>
make_random_item (beast::Random& r)
{
Serializer s;
for (int d = 0; d < 3; ++d)
s.add32 (r.nextInt ());
return std::make_shared <Item> (
to256(s.getRIPEMD160()), s.peekData ());
}
void
add_random_items (std::size_t n, Table& t, beast::Random& r)
{
while (n--)
{
std::shared_ptr <SHAMapItem> item (
make_random_item (r));
auto const result (t.addItem (*item, false, false));
assert (result);
(void) result;
}
}
void on_fetch (Map& map, uint256 const& hash, Blob const& blob)
{
@@ -73,8 +97,6 @@ public:
void run ()
{
using namespace RadixMap;
beast::manual_clock <std::chrono::steady_clock> clock; // manual advance clock
beast::Journal const j; // debug journal

View File

@@ -0,0 +1,95 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <beast/unit_test/suite.h>
#include <beast/chrono/manual_clock.h>
namespace ripple {
class SHAMap_test : public beast::unit_test::suite
{
public:
// VFALCO TODO Rename this to createFilledVector and pass an unsigned char, tidy up
//
static Blob IntToVUC (int v)
{
Blob vuc;
for (int i = 0; i < 32; ++i)
vuc.push_back (static_cast<unsigned char> (v));
return vuc;
}
void run ()
{
testcase ("add/traverse");
beast::manual_clock <std::chrono::steady_clock> clock; // manual advance clock
beast::Journal const j; // debug journal
FullBelowCache fullBelowCache ("test.full_below", clock);
TreeNodeCache treeNodeCache ("test.tree_node_cache", 65536, 60, clock, j);
// h3 and h4 differ only in the leaf, same terminal node (level 19)
uint256 h1, h2, h3, h4, h5;
h1.SetHex ("092891fe4ef6cee585fdc6fda0e09eb4d386363158ec3321b8123e5a772c6ca7");
h2.SetHex ("436ccbac3347baa1f1e53baeef1f43334da88f1f6d70d963b833afd6dfa289fe");
h3.SetHex ("b92891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8");
h4.SetHex ("b92891fe4ef6cee585fdc6fda2e09eb4d386363158ec3321b8123e5a772c6ca8");
h5.SetHex ("a92891fe4ef6cee585fdc6fda0e09eb4d386363158ec3321b8123e5a772c6ca7");
SHAMap sMap (smtFREE, fullBelowCache, treeNodeCache);
SHAMapItem i1 (h1, IntToVUC (1)), i2 (h2, IntToVUC (2)), i3 (h3, IntToVUC (3)), i4 (h4, IntToVUC (4)), i5 (h5, IntToVUC (5));
unexpected (!sMap.addItem (i2, true, false), "no add");
unexpected (!sMap.addItem (i1, true, false), "no add");
SHAMapItem::pointer i;
i = sMap.peekFirstItem ();
unexpected (!i || (*i != i1), "bad traverse");
i = sMap.peekNextItem (i->getTag ());
unexpected (!i || (*i != i2), "bad traverse");
i = sMap.peekNextItem (i->getTag ());
unexpected (i, "bad traverse");
sMap.addItem (i4, true, false);
sMap.delItem (i2.getTag ());
sMap.addItem (i3, true, false);
i = sMap.peekFirstItem ();
unexpected (!i || (*i != i1), "bad traverse");
i = sMap.peekNextItem (i->getTag ());
unexpected (!i || (*i != i3), "bad traverse");
i = sMap.peekNextItem (i->getTag ());
unexpected (!i || (*i != i4), "bad traverse");
i = sMap.peekNextItem (i->getTag ());
unexpected (i, "bad traverse");
testcase ("snapshot");
uint256 mapHash = sMap.getHash ();
SHAMap::pointer map2 = sMap.snapShot (false);
unexpected (sMap.getHash () != mapHash, "bad snapshot");
unexpected (map2->getHash () != mapHash, "bad snapshot");
unexpected (!sMap.delItem (sMap.peekFirstItem ()->getTag ()), "bad mod");
unexpected (sMap.getHash () == mapHash, "bad snapshot");
unexpected (map2->getHash () != mapHash, "bad snapshot");
}
};
BEAST_DEFINE_TESTSUITE(SHAMap,ripple_app,ripple);
} // ripple

View File

@@ -0,0 +1,224 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/nodestore/Database.h>
#include <beast/unit_test/suite.h>
#include <openssl/rand.h> // DEPRECATED
namespace ripple {
#ifdef BEAST_DEBUG
//#define SMS_DEBUG
#endif
class SHAMapSync_test : public beast::unit_test::suite
{
public:
static SHAMapItem::pointer makeRandomAS ()
{
Serializer s;
for (int d = 0; d < 3; ++d) s.add32 (rand ());
return std::make_shared<SHAMapItem> (to256 (s.getRIPEMD160 ()), s.peekData ());
}
bool confuseMap (SHAMap& map, int count)
{
// add a bunch of random states to a map, then remove them
// map should be the same
uint256 beforeHash = map.getHash ();
std::list<uint256> items;
for (int i = 0; i < count; ++i)
{
SHAMapItem::pointer item = makeRandomAS ();
items.push_back (item->getTag ());
if (!map.addItem (*item, false, false))
{
log <<
"Unable to add item to map";
assert (false);
return false;
}
}
for (std::list<uint256>::iterator it = items.begin (); it != items.end (); ++it)
{
if (!map.delItem (*it))
{
log <<
"Unable to remove item from map";
assert (false);
return false;
}
}
if (beforeHash != map.getHash ())
{
log <<
"Hashes do not match " << beforeHash << " " << map.getHash ();
assert (false);
return false;
}
return true;
}
void run ()
{
unsigned int seed;
// VFALCO DEPRECATED Should use C++11
RAND_pseudo_bytes (reinterpret_cast<unsigned char*> (&seed), sizeof (seed));
srand (seed);
beast::manual_clock <std::chrono::steady_clock> clock; // manual advance clock
beast::Journal const j; // debug journal
FullBelowCache fullBelowCache ("test.full_below", clock);
TreeNodeCache treeNodeCache ("test.tree_node_cache", 65536, 60, clock, j);
SHAMap source (smtFREE, fullBelowCache, treeNodeCache);
SHAMap destination (smtFREE, fullBelowCache, treeNodeCache);
int items = 10000;
for (int i = 0; i < items; ++i)
source.addItem (*makeRandomAS (), false, false);
unexpected (!confuseMap (source, 500), "ConfuseMap");
source.setImmutable ();
std::vector<SHAMapNodeID> nodeIDs, gotNodeIDs;
std::list< Blob > gotNodes;
std::vector<uint256> hashes;
std::vector<SHAMapNodeID>::iterator nodeIDIterator;
std::list< Blob >::iterator rawNodeIterator;
int passes = 0;
int nodes = 0;
destination.setSynching ();
unexpected (!source.getNodeFat (SHAMapNodeID (), nodeIDs, gotNodes, (rand () % 2) == 0, (rand () % 2) == 0),
"GetNodeFat");
unexpected (gotNodes.size () < 1, "NodeSize");
unexpected (!destination.addRootNode (*gotNodes.begin (), snfWIRE, nullptr).isGood(), "AddRootNode");
nodeIDs.clear ();
gotNodes.clear ();
#ifdef SMS_DEBUG
int bytes = 0;
#endif
do
{
++clock;
++passes;
hashes.clear ();
// get the list of nodes we know we need
destination.getMissingNodes (nodeIDs, hashes, 2048, nullptr);
if (nodeIDs.empty ()) break;
// get as many nodes as possible based on this information
for (nodeIDIterator = nodeIDs.begin (); nodeIDIterator != nodeIDs.end (); ++nodeIDIterator)
{
if (!source.getNodeFat (*nodeIDIterator, gotNodeIDs, gotNodes, (rand () % 2) == 0, (rand () % 2) == 0))
{
WriteLog (lsFATAL, SHAMap) << "GetNodeFat fails";
fail ("GetNodeFat");
}
else
{
pass ();
}
}
assert (gotNodeIDs.size () == gotNodes.size ());
nodeIDs.clear ();
hashes.clear ();
if (gotNodeIDs.empty ())
{
fail ("Got Node ID");
}
else
{
pass ();
}
for (nodeIDIterator = gotNodeIDs.begin (), rawNodeIterator = gotNodes.begin ();
nodeIDIterator != gotNodeIDs.end (); ++nodeIDIterator, ++rawNodeIterator)
{
++nodes;
#ifdef SMS_DEBUG
bytes += rawNodeIterator->size ();
#endif
if (!destination.addKnownNode (*nodeIDIterator, *rawNodeIterator, nullptr).isGood ())
{
WriteLog (lsTRACE, SHAMap) << "AddKnownNode fails";
fail ("AddKnownNode");
}
else
{
pass ();
}
}
gotNodeIDs.clear ();
gotNodes.clear ();
}
while (true);
destination.clearSynching ();
#ifdef SMS_DEBUG
WriteLog (lsINFO, SHAMap) << "SYNCHING COMPLETE " << items << " items, " << nodes << " nodes, " <<
bytes / 1024 << " KB";
#endif
if (!source.deepCompare (destination))
{
fail ("Deep Compare");
}
else
{
pass ();
}
#ifdef SMS_DEBUG
WriteLog (lsINFO, SHAMap) << "SHAMapSync test passed: " << items << " items, " <<
passes << " passes, " << nodes << " nodes";
#endif
}
};
BEAST_DEFINE_TESTSUITE(SHAMapSync,ripple_app,ripple);
} // ripple

View File

@@ -236,7 +236,7 @@ void RangeSet::simplify ()
void RangeSet::checkInternalConsistency () const noexcept
{
#if BEAST_DEBUG
#ifndef NDEBUG
if (mRanges.size () > 1)
{
const_iterator const last = std::prev (mRanges.end ());
@@ -244,92 +244,17 @@ void RangeSet::checkInternalConsistency () const noexcept
for (const_iterator cur = mRanges.begin (); cur != last; ++cur)
{
const_iterator const next = std::next (cur);
bassert (cur->first <= cur->second);
bassert (next->first <= next->second);
bassert (cur->second + 1 < next->first);
assert (cur->first <= cur->second);
assert (next->first <= next->second);
assert (cur->second + 1 < next->first);
}
}
else if (mRanges.size () == 1)
{
const_iterator const iter = mRanges.begin ();
bassert (iter->first <= iter->second);
assert (iter->first <= iter->second);
}
#endif
}
//------------------------------------------------------------------------------
class RangeSet_test : public beast::unit_test::suite
{
public:
RangeSet createPredefinedSet ()
{
RangeSet set;
// Set will include:
// [ 0, 5]
// [10,15]
// [20,25]
// etc...
for (int i = 0; i < 10; ++i)
set.setRange (10 * i, 10 * i + 5);
return set;
}
void testMembership ()
{
testcase ("membership");
RangeSet r1, r2;
r1.setRange (1, 10);
r1.clearValue (5);
r1.setRange (11, 20);
r2.setRange (1, 4);
r2.setRange (6, 10);
r2.setRange (10, 20);
expect (!r1.hasValue (5));
expect (r2.hasValue (9));
}
void testPrevMissing ()
{
testcase ("prevMissing");
RangeSet const set = createPredefinedSet ();
for (int i = 0; i < 100; ++i)
{
int const oneBelowRange = (10*(i/10))-1;
int const expectedPrevMissing =
((i % 10) > 6) ? (i-1) : oneBelowRange;
expect (set.prevMissing (i) == expectedPrevMissing);
}
}
void run ()
{
testMembership ();
testPrevMissing ();
// TODO: Traverse functions must be tested
}
};
BEAST_DEFINE_TESTSUITE(RangeSet,ripple_basics,ripple);
} // ripple

View File

@@ -260,112 +260,4 @@ beast::StringPairArray parseDelimitedKeyValueString (beast::String parameters,
return keyValues;
}
//------------------------------------------------------------------------------
class StringUtilities_test : public beast::unit_test::suite
{
public:
void testUnHexSuccess (std::string strIn, std::string strExpected)
{
std::string strOut;
expect (strUnHex (strOut, strIn) == strExpected.length (),
"strUnHex: parsing correct input failed");
expect (strOut == strExpected,
"strUnHex: parsing doesn't produce expected result");
}
void testUnHexFailure (std::string strIn)
{
std::string strOut;
expect (strUnHex (strOut, strIn) == -1,
"strUnHex: parsing incorrect input succeeded");
expect (strOut.empty (),
"strUnHex: parsing incorrect input returned data");
}
void testUnHex ()
{
testcase ("strUnHex");
testUnHexSuccess ("526970706c6544", "RippleD");
testUnHexSuccess ("A", "\n");
testUnHexSuccess ("0A", "\n");
testUnHexSuccess ("D0A", "\r\n");
testUnHexSuccess ("0D0A", "\r\n");
testUnHexSuccess ("200D0A", " \r\n");
testUnHexSuccess ("282A2B2C2D2E2F29", "(*+,-./)");
// Check for things which contain some or only invalid characters
testUnHexFailure ("123X");
testUnHexFailure ("V");
testUnHexFailure ("XRP");
}
void testParseUrl ()
{
testcase ("parseUrl");
std::string strScheme;
std::string strDomain;
int iPort;
std::string strPath;
unexpected (!parseUrl ("lower://domain", strScheme, strDomain, iPort, strPath),
"parseUrl: lower://domain failed");
unexpected (strScheme != "lower",
"parseUrl: lower://domain : scheme failed");
unexpected (strDomain != "domain",
"parseUrl: lower://domain : domain failed");
unexpected (iPort != -1,
"parseUrl: lower://domain : port failed");
unexpected (strPath != "",
"parseUrl: lower://domain : path failed");
unexpected (!parseUrl ("UPPER://domain:234/", strScheme, strDomain, iPort, strPath),
"parseUrl: UPPER://domain:234/ failed");
unexpected (strScheme != "upper",
"parseUrl: UPPER://domain:234/ : scheme failed");
unexpected (iPort != 234,
boost::str (boost::format ("parseUrl: UPPER://domain:234/ : port failed: %d") % iPort));
unexpected (strPath != "/",
"parseUrl: UPPER://domain:234/ : path failed");
unexpected (!parseUrl ("Mixed://domain/path", strScheme, strDomain, iPort, strPath),
"parseUrl: Mixed://domain/path failed");
unexpected (strScheme != "mixed",
"parseUrl: Mixed://domain/path tolower failed");
unexpected (strPath != "/path",
"parseUrl: Mixed://domain/path path failed");
}
void testToString ()
{
testcase ("toString");
auto result = to_string("hello");
expect(result == "hello", result);
}
void run ()
{
testParseUrl ();
testUnHex ();
testToString ();
}
};
BEAST_DEFINE_TESTSUITE(StringUtilities, ripple_basics, ripple);
} // ripple

View File

@@ -0,0 +1,93 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/basics/RangeSet.h>
#include <beast/unit_test/suite.h>
namespace ripple {
class RangeSet_test : public beast::unit_test::suite
{
public:
RangeSet createPredefinedSet ()
{
RangeSet set;
// Set will include:
// [ 0, 5]
// [10,15]
// [20,25]
// etc...
for (int i = 0; i < 10; ++i)
set.setRange (10 * i, 10 * i + 5);
return set;
}
void testMembership ()
{
testcase ("membership");
RangeSet r1, r2;
r1.setRange (1, 10);
r1.clearValue (5);
r1.setRange (11, 20);
r2.setRange (1, 4);
r2.setRange (6, 10);
r2.setRange (10, 20);
expect (!r1.hasValue (5));
expect (r2.hasValue (9));
}
void testPrevMissing ()
{
testcase ("prevMissing");
RangeSet const set = createPredefinedSet ();
for (int i = 0; i < 100; ++i)
{
int const oneBelowRange = (10*(i/10))-1;
int const expectedPrevMissing =
((i % 10) > 6) ? (i-1) : oneBelowRange;
expect (set.prevMissing (i) == expectedPrevMissing);
}
}
void run ()
{
testMembership ();
testPrevMissing ();
// TODO: Traverse functions must be tested
}
};
BEAST_DEFINE_TESTSUITE(RangeSet,ripple_basics,ripple);
} // ripple

View File

@@ -0,0 +1,131 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/basics/StringUtilities.h>
#include <beast/unit_test/suite.h>
namespace ripple {
class StringUtilities_test : public beast::unit_test::suite
{
public:
void testUnHexSuccess (std::string strIn, std::string strExpected)
{
std::string strOut;
expect (strUnHex (strOut, strIn) == strExpected.length (),
"strUnHex: parsing correct input failed");
expect (strOut == strExpected,
"strUnHex: parsing doesn't produce expected result");
}
void testUnHexFailure (std::string strIn)
{
std::string strOut;
expect (strUnHex (strOut, strIn) == -1,
"strUnHex: parsing incorrect input succeeded");
expect (strOut.empty (),
"strUnHex: parsing incorrect input returned data");
}
void testUnHex ()
{
testcase ("strUnHex");
testUnHexSuccess ("526970706c6544", "RippleD");
testUnHexSuccess ("A", "\n");
testUnHexSuccess ("0A", "\n");
testUnHexSuccess ("D0A", "\r\n");
testUnHexSuccess ("0D0A", "\r\n");
testUnHexSuccess ("200D0A", " \r\n");
testUnHexSuccess ("282A2B2C2D2E2F29", "(*+,-./)");
// Check for things which contain some or only invalid characters
testUnHexFailure ("123X");
testUnHexFailure ("V");
testUnHexFailure ("XRP");
}
void testParseUrl ()
{
testcase ("parseUrl");
std::string strScheme;
std::string strDomain;
int iPort;
std::string strPath;
unexpected (!parseUrl ("lower://domain", strScheme, strDomain, iPort, strPath),
"parseUrl: lower://domain failed");
unexpected (strScheme != "lower",
"parseUrl: lower://domain : scheme failed");
unexpected (strDomain != "domain",
"parseUrl: lower://domain : domain failed");
unexpected (iPort != -1,
"parseUrl: lower://domain : port failed");
unexpected (strPath != "",
"parseUrl: lower://domain : path failed");
unexpected (!parseUrl ("UPPER://domain:234/", strScheme, strDomain, iPort, strPath),
"parseUrl: UPPER://domain:234/ failed");
unexpected (strScheme != "upper",
"parseUrl: UPPER://domain:234/ : scheme failed");
unexpected (iPort != 234,
boost::str (boost::format ("parseUrl: UPPER://domain:234/ : port failed: %d") % iPort));
unexpected (strPath != "/",
"parseUrl: UPPER://domain:234/ : path failed");
unexpected (!parseUrl ("Mixed://domain/path", strScheme, strDomain, iPort, strPath),
"parseUrl: Mixed://domain/path failed");
unexpected (strScheme != "mixed",
"parseUrl: Mixed://domain/path tolower failed");
unexpected (strPath != "/path",
"parseUrl: Mixed://domain/path path failed");
}
void testToString ()
{
testcase ("toString");
auto result = to_string("hello");
expect(result == "hello", result);
}
void run ()
{
testParseUrl ();
testUnHex ();
testToString ();
}
};
BEAST_DEFINE_TESTSUITE(StringUtilities, ripple_basics, ripple);
} // ripple

View File

@@ -19,7 +19,6 @@
#include <ripple/core/impl/LoadFeeTrackImp.h>
#include <ripple/core/Config.h>
#include <beast/unit_test/suite.h>
namespace ripple {
@@ -28,30 +27,4 @@ LoadFeeTrack* LoadFeeTrack::New (beast::Journal journal)
return new LoadFeeTrackImp (journal);
}
//------------------------------------------------------------------------------
class LoadFeeTrack_test : public beast::unit_test::suite
{
public:
void run ()
{
Config d; // get a default configuration object
LoadFeeTrackImp l;
expect (l.scaleFeeBase (10000, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE) == 10000);
expect (l.scaleFeeLoad (10000, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE, false) == 10000);
expect (l.scaleFeeBase (1, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE) == 1);
expect (l.scaleFeeLoad (1, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE, false) == 1);
// Check new default fee values give same fees as old defaults
expect (l.scaleFeeBase (d.FEE_DEFAULT, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE) == 10);
expect (l.scaleFeeBase (d.FEE_ACCOUNT_RESERVE, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE) == 200 * SYSTEM_CURRENCY_PARTS);
expect (l.scaleFeeBase (d.FEE_OWNER_RESERVE, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE) == 50 * SYSTEM_CURRENCY_PARTS);
expect (l.scaleFeeBase (d.FEE_OFFER, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE) == 10);
expect (l.scaleFeeBase (d.FEE_CONTRACT_OPERATION, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE) == 1);
}
};
BEAST_DEFINE_TESTSUITE(LoadFeeTrack,ripple_core,ripple);
} // ripple

View File

@@ -0,0 +1,49 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/core/impl/LoadFeeTrackImp.h>
#include <beast/unit_test/suite.h>
namespace ripple {
class LoadFeeTrack_test : public beast::unit_test::suite
{
public:
void run ()
{
Config d; // get a default configuration object
LoadFeeTrackImp l;
expect (l.scaleFeeBase (10000, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE) == 10000);
expect (l.scaleFeeLoad (10000, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE, false) == 10000);
expect (l.scaleFeeBase (1, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE) == 1);
expect (l.scaleFeeLoad (1, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE, false) == 1);
// Check new default fee values give same fees as old defaults
expect (l.scaleFeeBase (d.FEE_DEFAULT, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE) == 10);
expect (l.scaleFeeBase (d.FEE_ACCOUNT_RESERVE, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE) == 200 * SYSTEM_CURRENCY_PARTS);
expect (l.scaleFeeBase (d.FEE_OWNER_RESERVE, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE) == 50 * SYSTEM_CURRENCY_PARTS);
expect (l.scaleFeeBase (d.FEE_OFFER, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE) == 10);
expect (l.scaleFeeBase (d.FEE_CONTRACT_OPERATION, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE) == 1);
}
};
BEAST_DEFINE_TESTSUITE(LoadFeeTrack,ripple_core,ripple);
} // ripple

View File

@@ -310,325 +310,4 @@ void hex_to_binary (FwdIter first, FwdIter last, Container& out)
}
}
class ECDSACanonical_test : public beast::unit_test::suite
{
public:
Blob loadSignature (std::string const& hex)
{
Blob b;
hex_to_binary (hex.begin (), hex.end (), b);
return b;
}
/** Verifies that a signature is syntactically valid.
*/
bool isValid (std::string const& hex)
{
Blob j (loadSignature(hex));
return isCanonicalECDSASig (&j[0], j.size(), ECDSA::not_strict);
}
/** Verifies that a signature is syntactically valid and in canonical form.
*/
bool isStrictlyCanonical (std::string const& hex)
{
Blob j (loadSignature(hex));
return isCanonicalECDSASig (&j[0], j.size (), ECDSA::strict);
}
/** Verify that we correctly identify strictly canonical signatures */
void testStrictlyCanonicalSignatures ()
{
testcase ("Strictly canonical signature checks", abort_on_fail);
expect (isStrictlyCanonical("3045"
"022100FF478110D1D4294471EC76E0157540C2181F47DEBD25D7F9E7DDCCCD47EEE905"
"0220078F07CDAE6C240855D084AD91D1479609533C147C93B0AEF19BC9724D003F28"),
"Strictly canonical signature");
expect (isStrictlyCanonical("3045"
"0221009218248292F1762D8A51BE80F8A7F2CD288D810CE781D5955700DA1684DF1D2D"
"022041A1EE1746BFD72C9760CC93A7AAA8047D52C8833A03A20EAAE92EA19717B454"),
"Strictly canonical signature");
expect (isStrictlyCanonical("3044"
"02206A9E43775F73B6D1EC420E4DDD222A80D4C6DF5D1BEECC431A91B63C928B7581"
"022023E9CC2D61DDA6F73EAA6BCB12688BEB0F434769276B3127E4044ED895C9D96B"),
"Strictly canonical signature");
expect (isStrictlyCanonical("3044"
"022056E720007221F3CD4EFBB6352741D8E5A0968D48D8D032C2FBC4F6304AD1D04E"
"02201F39EB392C20D7801C3E8D81D487E742FA84A1665E923225BD6323847C71879F"),
"Strictly canonical signature");
expect (isStrictlyCanonical("3045"
"022100FDFD5AD05518CEA0017A2DCB5C4DF61E7C73B6D3A38E7AE93210A1564E8C2F12"
"0220214FF061CCC123C81D0BB9D0EDEA04CD40D96BF1425D311DA62A7096BB18EA18"),
"Strictly canonical signature");
// These are canonical signatures, but *not* strictly canonical.
expect (!isStrictlyCanonical ("3046"
"022100F477B3FA6F31C7CB3A0D1AD94A231FDD24B8D78862EE334CEA7CD08F6CBC0A1B"
"022100928E6BCF1ED2684679730C5414AEC48FD62282B090041C41453C1D064AF597A1"),
"Not strictly canonical signature");
expect (!isStrictlyCanonical ("3045"
"022063E7C7CA93CB2400E413A342C027D00665F8BAB9C22EF0A7B8AE3AAF092230B6"
"0221008F2E8BB7D09521ABBC277717B14B93170AE6465C5A1B36561099319C4BEB254C"),
"Not strictly canonical signature");
expect (!isStrictlyCanonical ("3046"
"02210099DCA1188663DDEA506A06A7B20C2B7D8C26AFF41DECE69D6C5F7C967D32625F"
"022100897658A6B1F9EEE5D140D7A332DA0BD73BB98974EA53F6201B01C1B594F286EA"),
"Not strictly canonical signature");
expect (!isStrictlyCanonical ("3045"
"02200855DE366E4E323AA2CE2A25674401A7D11F72EC432770D07F7B57DF7387AEC0"
"022100DA4C6ADDEA14888858DE2AC5B91ED9050D6972BB388DEF582628CEE32869AE35"),
"Not strictly canonical signature");
}
/** Verify that we correctly identify valid signatures */
void testValidSignatures ()
{
testcase ("Canonical signature checks", abort_on_fail);
// r and s 1 byte 1
expect (isValid ("3006"
"020101"
"020102"),
"Well-formed short signature");
expect (isValid ("3044"
"02203932c892e2e550f3af8ee4ce9c215a87f9bb831dcac87b2838e2c2eaa891df0c"
"022030b61dd36543125d56b9f9f3a1f53189e5af33cdda8d77a5209aec03978fa001"),
"Canonical signature");
expect (isValid ("3045"
"0220076045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f90a"
"0221008fffd599910eefe00bc803c688eca1d2ba7f6b180620eaa03488e6585db6ba01"),
"Canonical signature");
expect (isValid("3046"
"022100876045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f90a"
"0221008fffd599910eefe00bc803c688c2eca1d2ba7f6b180620eaa03488e6585db6ba"),
"Canonical signature");
expect (isStrictlyCanonical("3045"
"022100FF478110D1D4294471EC76E0157540C2181F47DEBD25D7F9E7DDCCCD47EEE905"
"0220078F07CDAE6C240855D084AD91D1479609533C147C93B0AEF19BC9724D003F28"),
"Canonical signature");
expect (isStrictlyCanonical("3045"
"0221009218248292F1762D8A51BE80F8A7F2CD288D810CE781D5955700DA1684DF1D2D"
"022041A1EE1746BFD72C9760CC93A7AAA8047D52C8833A03A20EAAE92EA19717B454"),
"Canonical signature");
expect (isStrictlyCanonical("3044"
"02206A9E43775F73B6D1EC420E4DDD222A80D4C6DF5D1BEECC431A91B63C928B7581"
"022023E9CC2D61DDA6F73EAA6BCB12688BEB0F434769276B3127E4044ED895C9D96B"),
"Canonical signature");
expect (isStrictlyCanonical("3044"
"022056E720007221F3CD4EFBB6352741D8E5A0968D48D8D032C2FBC4F6304AD1D04E"
"02201F39EB392C20D7801C3E8D81D487E742FA84A1665E923225BD6323847C71879F"),
"Canonical signature");
expect (isStrictlyCanonical("3045"
"022100FDFD5AD05518CEA0017A2DCB5C4DF61E7C73B6D3A38E7AE93210A1564E8C2F12"
"0220214FF061CCC123C81D0BB9D0EDEA04CD40D96BF1425D311DA62A7096BB18EA18"),
"Canonical signature");
}
/** Verify that we correctly identify malformed or invalid signatures */
void testMalformedSignatures ()
{
testcase ("Non-canonical signature checks", abort_on_fail);
expect (!isValid("3005"
"0201FF"
"0200"),
"tooshort");
expect (!isValid ("3006"
"020101"
"020202"),
"Slen-Overlong");
expect (!isValid ("3006"
"020701"
"020102"),
"Rlen-Overlong-OOB");
expect (!isValid ("3006"
"020401"
"020102"),
"Rlen-Overlong-OOB");
expect (!isValid ("3006"
"020501"
"020102"),
"Rlen-Overlong-OOB");
expect (!isValid ("3006"
"020201"
"020102"),
"Rlen-Overlong");
expect (!isValid ("3006"
"020301"
"020202"),
"Rlen Overlong and Slen-Overlong");
expect (!isValid ("3006"
"020401"
"020202"),
"Rlen Overlong and OOB and Slen-Overlong");
expect (!isValid("3047"
"0221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"022200002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"toolong");
expect (!isValid("3144"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"type");
expect (!isValid("3045"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"totallength");
expect (!isValid("301F"
"01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1"),
"Slenoob");
expect (!isValid("3045"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed00"),
"R+S");
expect (!isValid("3044"
"01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"Rtype");
expect (!isValid("3024"
"0200"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"Rlen=0");
expect (!isValid("3044"
"02208990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"R<0");
expect (!isValid("3045"
"0221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"Rpadded");
expect (!isValid("3044"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105012"
"02d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"Stype");
expect (!isValid("3024"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"0200"),
"Slen=0");
expect (!isValid("3044"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"0220fd5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"S<0");
expect (!isValid("3045"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"0221002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"Spadded");
}
void convertNonCanonical(std::string const& hex, std::string const& canonHex)
{
Blob b (loadSignature(hex));
// The signature ought to at least be valid before we begin.
expect (isValid (hex), "invalid signature");
size_t len = b.size ();
expect (!makeCanonicalECDSASig (&b[0], len),
"non-canonical signature was already canonical");
expect (b.size () >= len,
"canonicalized signature length longer than non-canonical");
b.resize (len);
expect (isCanonicalECDSASig (&b[0], len, ECDSA::strict),
"canonicalized signature is not strictly canonical");
Blob canonicalForm (loadSignature (canonHex));
expect (b.size () == canonicalForm.size (),
"canonicalized signature doesn't have the expected length");
expect (std::equal (b.begin (), b.end (), canonicalForm.begin ()),
"canonicalized signature isn't what we expected");
}
/** Verifies correctness of non-canonical to canonical conversion */
void testCanonicalConversions()
{
testcase ("Non-canonical signature canonicalization", abort_on_fail);
convertNonCanonical (
"3046"
"022100F477B3FA6F31C7CB3A0D1AD94A231FDD24B8D78862EE334CEA7CD08F6CBC0A1B"
"022100928E6BCF1ED2684679730C5414AEC48FD62282B090041C41453C1D064AF597A1",
"3045"
"022100F477B3FA6F31C7CB3A0D1AD94A231FDD24B8D78862EE334CEA7CD08F6CBC0A1B"
"02206D719430E12D97B9868CF3ABEB513B6EE48C5A361F4483FA7A9641868540A9A0");
convertNonCanonical (
"3045"
"022063E7C7CA93CB2400E413A342C027D00665F8BAB9C22EF0A7B8AE3AAF092230B6"
"0221008F2E8BB7D09521ABBC277717B14B93170AE6465C5A1B36561099319C4BEB254C",
"3044"
"022063E7C7CA93CB2400E413A342C027D00665F8BAB9C22EF0A7B8AE3AAF092230B6"
"022070D174482F6ADE5443D888E84EB46CE7AFC8968A552D69E5AF392CF0844B1BF5");
convertNonCanonical (
"3046"
"02210099DCA1188663DDEA506A06A7B20C2B7D8C26AFF41DECE69D6C5F7C967D32625F"
"022100897658A6B1F9EEE5D140D7A332DA0BD73BB98974EA53F6201B01C1B594F286EA",
"3045"
"02210099DCA1188663DDEA506A06A7B20C2B7D8C26AFF41DECE69D6C5F7C967D32625F"
"02207689A7594E06111A2EBF285CCD25F4277EF55371C4F4AA1BA4D09CD73B43BA57");
convertNonCanonical (
"3045"
"02200855DE366E4E323AA2CE2A25674401A7D11F72EC432770D07F7B57DF7387AEC0"
"022100DA4C6ADDEA14888858DE2AC5B91ED9050D6972BB388DEF582628CEE32869AE35",
"3044"
"02200855DE366E4E323AA2CE2A25674401A7D11F72EC432770D07F7B57DF7387AEC0"
"022025B3952215EB7777A721D53A46E126F9AD456A2B76BAB0E399A98FA9A7CC930C");
}
void run ()
{
testValidSignatures ();
testStrictlyCanonicalSignatures ();
testMalformedSignatures ();
testCanonicalConversions ();
}
};
BEAST_DEFINE_TESTSUITE(ECDSACanonical,sslutil,ripple);
}

View File

@@ -0,0 +1,379 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/crypto/ECDSACanonical.h>
#include <beast/unit_test/suite.h>
#include <algorithm>
#include <iterator>
#include <openssl/bn.h>
#include <openssl/ecdsa.h>
namespace ripple {
class ECDSACanonical_test : public beast::unit_test::suite
{
public:
template <class FwdIter, class Container>
static
void
hex_to_binary (FwdIter first, FwdIter last, Container& out)
{
struct Table
{
int val[256];
Table ()
{
std::fill (val, val+256, 0);
for (int i = 0; i < 10; ++i)
val ['0'+i] = i;
for (int i = 0; i < 6; ++i)
{
val ['A'+i] = 10 + i;
val ['a'+i] = 10 + i;
}
}
int operator[] (int i)
{
return val[i];
}
};
static Table lut;
out.reserve (std::distance (first, last) / 2);
while (first != last)
{
auto const hi (lut[(*first++)]);
auto const lo (lut[(*first++)]);
out.push_back ((hi*16)+lo);
}
}
Blob loadSignature (std::string const& hex)
{
Blob b;
hex_to_binary (hex.begin (), hex.end (), b);
return b;
}
// Verifies that a signature is syntactically valid.
bool isValid (std::string const& hex)
{
Blob j (loadSignature(hex));
return isCanonicalECDSASig (&j[0], j.size(), ECDSA::not_strict);
}
// Verifies that a signature is syntactically valid and in canonical form.
bool isStrictlyCanonical (std::string const& hex)
{
Blob j (loadSignature(hex));
return isCanonicalECDSASig (&j[0], j.size (), ECDSA::strict);
}
// Verify that we correctly identify strictly canonical signatures
void testStrictlyCanonicalSignatures ()
{
testcase ("Strictly canonical signature checks", abort_on_fail);
expect (isStrictlyCanonical("3045"
"022100FF478110D1D4294471EC76E0157540C2181F47DEBD25D7F9E7DDCCCD47EEE905"
"0220078F07CDAE6C240855D084AD91D1479609533C147C93B0AEF19BC9724D003F28"),
"Strictly canonical signature");
expect (isStrictlyCanonical("3045"
"0221009218248292F1762D8A51BE80F8A7F2CD288D810CE781D5955700DA1684DF1D2D"
"022041A1EE1746BFD72C9760CC93A7AAA8047D52C8833A03A20EAAE92EA19717B454"),
"Strictly canonical signature");
expect (isStrictlyCanonical("3044"
"02206A9E43775F73B6D1EC420E4DDD222A80D4C6DF5D1BEECC431A91B63C928B7581"
"022023E9CC2D61DDA6F73EAA6BCB12688BEB0F434769276B3127E4044ED895C9D96B"),
"Strictly canonical signature");
expect (isStrictlyCanonical("3044"
"022056E720007221F3CD4EFBB6352741D8E5A0968D48D8D032C2FBC4F6304AD1D04E"
"02201F39EB392C20D7801C3E8D81D487E742FA84A1665E923225BD6323847C71879F"),
"Strictly canonical signature");
expect (isStrictlyCanonical("3045"
"022100FDFD5AD05518CEA0017A2DCB5C4DF61E7C73B6D3A38E7AE93210A1564E8C2F12"
"0220214FF061CCC123C81D0BB9D0EDEA04CD40D96BF1425D311DA62A7096BB18EA18"),
"Strictly canonical signature");
// These are canonical signatures, but *not* strictly canonical.
expect (!isStrictlyCanonical ("3046"
"022100F477B3FA6F31C7CB3A0D1AD94A231FDD24B8D78862EE334CEA7CD08F6CBC0A1B"
"022100928E6BCF1ED2684679730C5414AEC48FD62282B090041C41453C1D064AF597A1"),
"Not strictly canonical signature");
expect (!isStrictlyCanonical ("3045"
"022063E7C7CA93CB2400E413A342C027D00665F8BAB9C22EF0A7B8AE3AAF092230B6"
"0221008F2E8BB7D09521ABBC277717B14B93170AE6465C5A1B36561099319C4BEB254C"),
"Not strictly canonical signature");
expect (!isStrictlyCanonical ("3046"
"02210099DCA1188663DDEA506A06A7B20C2B7D8C26AFF41DECE69D6C5F7C967D32625F"
"022100897658A6B1F9EEE5D140D7A332DA0BD73BB98974EA53F6201B01C1B594F286EA"),
"Not strictly canonical signature");
expect (!isStrictlyCanonical ("3045"
"02200855DE366E4E323AA2CE2A25674401A7D11F72EC432770D07F7B57DF7387AEC0"
"022100DA4C6ADDEA14888858DE2AC5B91ED9050D6972BB388DEF582628CEE32869AE35"),
"Not strictly canonical signature");
}
// Verify that we correctly identify valid signatures
void testValidSignatures ()
{
testcase ("Canonical signature checks", abort_on_fail);
// r and s 1 byte 1
expect (isValid ("3006"
"020101"
"020102"),
"Well-formed short signature");
expect (isValid ("3044"
"02203932c892e2e550f3af8ee4ce9c215a87f9bb831dcac87b2838e2c2eaa891df0c"
"022030b61dd36543125d56b9f9f3a1f53189e5af33cdda8d77a5209aec03978fa001"),
"Canonical signature");
expect (isValid ("3045"
"0220076045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f90a"
"0221008fffd599910eefe00bc803c688eca1d2ba7f6b180620eaa03488e6585db6ba01"),
"Canonical signature");
expect (isValid("3046"
"022100876045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f90a"
"0221008fffd599910eefe00bc803c688c2eca1d2ba7f6b180620eaa03488e6585db6ba"),
"Canonical signature");
expect (isStrictlyCanonical("3045"
"022100FF478110D1D4294471EC76E0157540C2181F47DEBD25D7F9E7DDCCCD47EEE905"
"0220078F07CDAE6C240855D084AD91D1479609533C147C93B0AEF19BC9724D003F28"),
"Canonical signature");
expect (isStrictlyCanonical("3045"
"0221009218248292F1762D8A51BE80F8A7F2CD288D810CE781D5955700DA1684DF1D2D"
"022041A1EE1746BFD72C9760CC93A7AAA8047D52C8833A03A20EAAE92EA19717B454"),
"Canonical signature");
expect (isStrictlyCanonical("3044"
"02206A9E43775F73B6D1EC420E4DDD222A80D4C6DF5D1BEECC431A91B63C928B7581"
"022023E9CC2D61DDA6F73EAA6BCB12688BEB0F434769276B3127E4044ED895C9D96B"),
"Canonical signature");
expect (isStrictlyCanonical("3044"
"022056E720007221F3CD4EFBB6352741D8E5A0968D48D8D032C2FBC4F6304AD1D04E"
"02201F39EB392C20D7801C3E8D81D487E742FA84A1665E923225BD6323847C71879F"),
"Canonical signature");
expect (isStrictlyCanonical("3045"
"022100FDFD5AD05518CEA0017A2DCB5C4DF61E7C73B6D3A38E7AE93210A1564E8C2F12"
"0220214FF061CCC123C81D0BB9D0EDEA04CD40D96BF1425D311DA62A7096BB18EA18"),
"Canonical signature");
}
// Verify that we correctly identify malformed or invalid signatures
void testMalformedSignatures ()
{
testcase ("Non-canonical signature checks", abort_on_fail);
expect (!isValid("3005"
"0201FF"
"0200"),
"tooshort");
expect (!isValid ("3006"
"020101"
"020202"),
"Slen-Overlong");
expect (!isValid ("3006"
"020701"
"020102"),
"Rlen-Overlong-OOB");
expect (!isValid ("3006"
"020401"
"020102"),
"Rlen-Overlong-OOB");
expect (!isValid ("3006"
"020501"
"020102"),
"Rlen-Overlong-OOB");
expect (!isValid ("3006"
"020201"
"020102"),
"Rlen-Overlong");
expect (!isValid ("3006"
"020301"
"020202"),
"Rlen Overlong and Slen-Overlong");
expect (!isValid ("3006"
"020401"
"020202"),
"Rlen Overlong and OOB and Slen-Overlong");
expect (!isValid("3047"
"0221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"022200002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"toolong");
expect (!isValid("3144"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"type");
expect (!isValid("3045"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"totallength");
expect (!isValid("301F"
"01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1"),
"Slenoob");
expect (!isValid("3045"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed00"),
"R+S");
expect (!isValid("3044"
"01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"Rtype");
expect (!isValid("3024"
"0200"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"Rlen=0");
expect (!isValid("3044"
"02208990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"R<0");
expect (!isValid("3045"
"0221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"Rpadded");
expect (!isValid("3044"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105012"
"02d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"Stype");
expect (!isValid("3024"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"0200"),
"Slen=0");
expect (!isValid("3044"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"0220fd5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"S<0");
expect (!isValid("3045"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"0221002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"),
"Spadded");
}
void convertNonCanonical(std::string const& hex, std::string const& canonHex)
{
Blob b (loadSignature(hex));
// The signature ought to at least be valid before we begin.
expect (isValid (hex), "invalid signature");
size_t len = b.size ();
expect (!makeCanonicalECDSASig (&b[0], len),
"non-canonical signature was already canonical");
expect (b.size () >= len,
"canonicalized signature length longer than non-canonical");
b.resize (len);
expect (isCanonicalECDSASig (&b[0], len, ECDSA::strict),
"canonicalized signature is not strictly canonical");
Blob canonicalForm (loadSignature (canonHex));
expect (b.size () == canonicalForm.size (),
"canonicalized signature doesn't have the expected length");
expect (std::equal (b.begin (), b.end (), canonicalForm.begin ()),
"canonicalized signature isn't what we expected");
}
// Verifies correctness of non-canonical to canonical conversion
void testCanonicalConversions()
{
testcase ("Non-canonical signature canonicalization", abort_on_fail);
convertNonCanonical (
"3046"
"022100F477B3FA6F31C7CB3A0D1AD94A231FDD24B8D78862EE334CEA7CD08F6CBC0A1B"
"022100928E6BCF1ED2684679730C5414AEC48FD62282B090041C41453C1D064AF597A1",
"3045"
"022100F477B3FA6F31C7CB3A0D1AD94A231FDD24B8D78862EE334CEA7CD08F6CBC0A1B"
"02206D719430E12D97B9868CF3ABEB513B6EE48C5A361F4483FA7A9641868540A9A0");
convertNonCanonical (
"3045"
"022063E7C7CA93CB2400E413A342C027D00665F8BAB9C22EF0A7B8AE3AAF092230B6"
"0221008F2E8BB7D09521ABBC277717B14B93170AE6465C5A1B36561099319C4BEB254C",
"3044"
"022063E7C7CA93CB2400E413A342C027D00665F8BAB9C22EF0A7B8AE3AAF092230B6"
"022070D174482F6ADE5443D888E84EB46CE7AFC8968A552D69E5AF392CF0844B1BF5");
convertNonCanonical (
"3046"
"02210099DCA1188663DDEA506A06A7B20C2B7D8C26AFF41DECE69D6C5F7C967D32625F"
"022100897658A6B1F9EEE5D140D7A332DA0BD73BB98974EA53F6201B01C1B594F286EA",
"3045"
"02210099DCA1188663DDEA506A06A7B20C2B7D8C26AFF41DECE69D6C5F7C967D32625F"
"02207689A7594E06111A2EBF285CCD25F4277EF55371C4F4AA1BA4D09CD73B43BA57");
convertNonCanonical (
"3045"
"02200855DE366E4E323AA2CE2A25674401A7D11F72EC432770D07F7B57DF7387AEC0"
"022100DA4C6ADDEA14888858DE2AC5B91ED9050D6972BB388DEF582628CEE32869AE35",
"3044"
"02200855DE366E4E323AA2CE2A25674401A7D11F72EC432770D07F7B57DF7387AEC0"
"022025B3952215EB7777A721D53A46E126F9AD456A2B76BAB0E399A98FA9A7CC930C");
}
void run ()
{
testValidSignatures ();
testStrictlyCanonicalSignatures ();
testMalformedSignatures ();
testCanonicalConversions ();
}
};
BEAST_DEFINE_TESTSUITE(ECDSACanonical,sslutil,ripple);
}

View File

@@ -17,6 +17,7 @@
*/
//==============================================================================
#include <ripple/nodestore/tests/Base.test.h>
#include <beast/module/core/diagnostic/UnitTestUtilities.h>
namespace ripple {

View File

@@ -17,6 +17,8 @@
*/
//==============================================================================
#include <ripple/nodestore/tests/Base.test.h>
namespace ripple {
namespace NodeStore {

View File

@@ -17,6 +17,8 @@
*/
//==============================================================================
#include <ripple/nodestore/tests/Base.test.h>
namespace ripple {
namespace NodeStore {

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#include <ripple/nodestore/tests/Base.test.h>
#include <limits>
#include <beast/Config.h>
namespace ripple {
namespace NodeStore {

View File

@@ -25,6 +25,7 @@
#include <ripple/peerfinder/impl/Fixed.h>
#include <ripple/peerfinder/impl/iosformat.h>
#include <ripple/peerfinder/impl/Handouts.h>
#include <ripple/peerfinder/impl/Livecache.h>
#include <ripple/peerfinder/impl/Reporting.h>
#include <ripple/peerfinder/impl/SlotImp.h>
#include <ripple/peerfinder/impl/Source.h>
@@ -32,6 +33,7 @@
#include <beast/smart_ptr/SharedPtr.h>
#include <functional>
#include <map>
#include <set>
namespace ripple {
namespace PeerFinder {

View File

@@ -154,96 +154,4 @@ to_packed (ProtocolVersion const& p)
return (static_cast<std::uint32_t> (p.first) << 16) + p.second;
}
//------------------------------------------------------------------------------
class BuildInfo_test : public beast::unit_test::suite
{
public:
void testVersion ()
{
testcase ("version");
beast::SemanticVersion v;
expect (v.parse (BuildInfo::getRawVersionString ()));
}
ProtocolVersion
from_version (std::uint16_t major, std::uint16_t minor)
{
return ProtocolVersion (major, minor);
}
void testValues ()
{
testcase ("comparison");
expect (from_version (1,2) == from_version (1,2));
expect (from_version (3,4) >= from_version (3,4));
expect (from_version (5,6) <= from_version (5,6));
expect (from_version (7,8) > from_version (6,7));
expect (from_version (7,8) < from_version (8,9));
expect (from_version (65535,0) < from_version (65535,65535));
expect (from_version (65535,65535) >= from_version (65535,65535));
}
void testStringVersion ()
{
testcase ("string version");
for (std::uint16_t major = 0; major < 8; major++)
{
for (std::uint16_t minor = 0; minor < 8; minor++)
{
expect (to_string (from_version (major, minor)) ==
std::to_string (major) + "." + std::to_string (minor));
}
}
}
void testVersionPacking ()
{
testcase ("version packing");
expect (to_packed (from_version (0, 0)) == 0);
expect (to_packed (from_version (0, 1)) == 1);
expect (to_packed (from_version (0, 255)) == 255);
expect (to_packed (from_version (0, 65535)) == 65535);
expect (to_packed (from_version (1, 0)) == 65536);
expect (to_packed (from_version (1, 1)) == 65537);
expect (to_packed (from_version (1, 255)) == 65791);
expect (to_packed (from_version (1, 65535)) == 131071);
expect (to_packed (from_version (255, 0)) == 16711680);
expect (to_packed (from_version (255, 1)) == 16711681);
expect (to_packed (from_version (255, 255)) == 16711935);
expect (to_packed (from_version (255, 65535)) == 16777215);
expect (to_packed (from_version (65535, 0)) == 4294901760);
expect (to_packed (from_version (65535, 1)) == 4294901761);
expect (to_packed (from_version (65535, 255)) == 4294902015);
expect (to_packed (from_version (65535, 65535)) == 4294967295);
}
void run ()
{
testVersion ();
testValues ();
testStringVersion ();
testVersionPacking ();
auto const current_protocol = BuildInfo::getCurrentProtocol ();
auto const minimum_protocol = BuildInfo::getMinimumProtocol ();
expect (current_protocol >= minimum_protocol);
log << " Ripple Version: " << BuildInfo::getVersionString();
log << " Protocol Version: " << to_string (current_protocol);
}
};
BEAST_DEFINE_TESTSUITE(BuildInfo,ripple_data,ripple);
} // ripple

View File

@@ -868,115 +868,4 @@ RippleAddress RippleAddress::createSeedGeneric (std::string const& strText)
return naNew;
}
//------------------------------------------------------------------------------
class RippleAddress_test : public beast::unit_test::suite
{
public:
void run()
{
// Construct a seed.
RippleAddress naSeed;
expect (naSeed.setSeedGeneric ("masterpassphrase"));
expect (naSeed.humanSeed () == "snoPBrXtMeMyMHUVTgbuqAfg1SUTb", naSeed.humanSeed ());
// Create node public/private key pair
RippleAddress naNodePublic = RippleAddress::createNodePublic (naSeed);
RippleAddress naNodePrivate = RippleAddress::createNodePrivate (naSeed);
expect (naNodePublic.humanNodePublic () == "n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9", naNodePublic.humanNodePublic ());
expect (naNodePrivate.humanNodePrivate () == "pnen77YEeUd4fFKG7iycBWcwKpTaeFRkW2WFostaATy1DSupwXe", naNodePrivate.humanNodePrivate ());
// Check node signing.
Blob vucTextSrc = strCopy ("Hello, nurse!");
uint256 uHash = Serializer::getSHA512Half (vucTextSrc);
Blob vucTextSig;
naNodePrivate.signNodePrivate (uHash, vucTextSig);
expect (naNodePublic.verifyNodePublic (uHash, vucTextSig, ECDSA::strict), "Verify failed.");
// Construct a public generator from the seed.
RippleAddress generator = RippleAddress::createGeneratorPublic (naSeed);
expect (generator.humanGenerator () == "fhuJKrhSDzV2SkjLn9qbwm5AaRmrxDPfFsHDCP6yfDZWcxDFz4mt", generator.humanGenerator ());
// Create account #0 public/private key pair.
RippleAddress naAccountPublic0 = RippleAddress::createAccountPublic (generator, 0);
RippleAddress naAccountPrivate0 = RippleAddress::createAccountPrivate (generator, naSeed, 0);
expect (naAccountPublic0.humanAccountID () == "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", naAccountPublic0.humanAccountID ());
expect (naAccountPublic0.humanAccountPublic () == "aBQG8RQAzjs1eTKFEAQXr2gS4utcDiEC9wmi7pfUPTi27VCahwgw", naAccountPublic0.humanAccountPublic ());
// Create account #1 public/private key pair.
RippleAddress naAccountPublic1 = RippleAddress::createAccountPublic (generator, 1);
RippleAddress naAccountPrivate1 = RippleAddress::createAccountPrivate (generator, naSeed, 1);
expect (naAccountPublic1.humanAccountID () == "r4bYF7SLUMD7QgSLLpgJx38WJSY12ViRjP", naAccountPublic1.humanAccountID ());
expect (naAccountPublic1.humanAccountPublic () == "aBPXpTfuLy1Bhk3HnGTTAqnovpKWQ23NpFMNkAF6F1Atg5vDyPrw", naAccountPublic1.humanAccountPublic ());
// Check account signing.
expect (naAccountPrivate0.accountPrivateSign (uHash, vucTextSig), "Signing failed.");
expect (naAccountPublic0.accountPublicVerify (uHash, vucTextSig, ECDSA::strict), "Verify failed.");
expect (!naAccountPublic1.accountPublicVerify (uHash, vucTextSig, ECDSA::not_strict), "Anti-verify failed.");
expect (!naAccountPublic1.accountPublicVerify (uHash, vucTextSig, ECDSA::strict), "Anti-verify failed.");
expect (naAccountPrivate1.accountPrivateSign (uHash, vucTextSig), "Signing failed.");
expect (naAccountPublic1.accountPublicVerify (uHash, vucTextSig, ECDSA::strict), "Verify failed.");
expect (!naAccountPublic0.accountPublicVerify (uHash, vucTextSig, ECDSA::not_strict), "Anti-verify failed.");
expect (!naAccountPublic0.accountPublicVerify (uHash, vucTextSig, ECDSA::strict), "Anti-verify failed.");
// Check account encryption.
Blob vucTextCipher
= naAccountPrivate0.accountPrivateEncrypt (naAccountPublic1, vucTextSrc);
Blob vucTextRecovered
= naAccountPrivate1.accountPrivateDecrypt (naAccountPublic0, vucTextCipher);
expect (vucTextSrc == vucTextRecovered, "Encrypt-decrypt failed.");
{
RippleAddress nSeed;
uint128 seed1, seed2;
seed1.SetHex ("71ED064155FFADFA38782C5E0158CB26");
nSeed.setSeed (seed1);
expect (nSeed.humanSeed() == "shHM53KPZ87Gwdqarm1bAmPeXg8Tn",
"Incorrect human seed");
expect (nSeed.humanSeed1751() == "MAD BODY ACE MINT OKAY HUB WHAT DATA SACK FLAT DANA MATH",
"Incorrect 1751 seed");
}
}
};
//------------------------------------------------------------------------------
class RippleIdentifier_test : public beast::unit_test::suite
{
public:
void run ()
{
testcase ("Seed");
RippleAddress seed;
expect (seed.setSeedGeneric ("masterpassphrase"));
expect (seed.humanSeed () == "snoPBrXtMeMyMHUVTgbuqAfg1SUTb", seed.humanSeed ());
testcase ("RipplePublicKey");
RippleAddress deprecatedPublicKey (RippleAddress::createNodePublic (seed));
expect (deprecatedPublicKey.humanNodePublic () ==
"n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9",
deprecatedPublicKey.humanNodePublic ());
RipplePublicKey publicKey = deprecatedPublicKey.toPublicKey();
expect (publicKey.to_string() == deprecatedPublicKey.humanNodePublic(),
publicKey.to_string());
testcase ("Generator");
RippleAddress generator (RippleAddress::createGeneratorPublic (seed));
expect (generator.humanGenerator () ==
"fhuJKrhSDzV2SkjLn9qbwm5AaRmrxDPfFsHDCP6yfDZWcxDFz4mt",
generator.humanGenerator ());
}
};
BEAST_DEFINE_TESTSUITE(RippleAddress,ripple_data,ripple);
BEAST_DEFINE_TESTSUITE(RippleIdentifier,ripple_data,ripple);
} // ripple

View File

@@ -26,7 +26,6 @@
#include <ripple/protocol/STObject.h>
#include <ripple/protocol/STParsedJSON.h>
#include <beast/module/core/text/LexicalCast.h>
#include <beast/unit_test/suite.h>
#include <beast/cxx14/memory.h> // <memory>
namespace ripple {
@@ -906,171 +905,4 @@ bool STObject::operator== (const STObject& obj) const
return true;
}
//------------------------------------------------------------------------------
class SerializedObject_test : public beast::unit_test::suite
{
public:
void run()
{
testSerialization();
testParseJSONArray();
testParseJSONArrayWithInvalidChildrenObjects();
}
bool parseJSONString (std::string const& json, Json::Value& to)
{
Json::Reader reader;
return (reader.parse(json, to) &&
!to.isNull() &&
to.isObject());
}
void testParseJSONArrayWithInvalidChildrenObjects ()
{
testcase ("parse json array invalid children");
try
{
/*
STArray/STObject constructs don't really map perfectly to json
arrays/objects.
STObject is an associative container, mapping fields to value, but
an STObject may also have a Field as it's name, stored outside the
associative structure. The name is important, so to maintain
fidelity, it will take TWO json objects to represent them.
*/
std::string faulty ("{\"Template\":[{"
"\"ModifiedNode\":{\"Sequence\":1}, "
"\"DeletedNode\":{\"Sequence\":1}"
"}]}");
std::unique_ptr<STObject> so;
Json::Value faultyJson;
bool parsedOK (parseJSONString(faulty, faultyJson));
unexpected(!parsedOK, "failed to parse");
STParsedJSONObject parsed ("test", faultyJson);
expect (parsed.object.get() == nullptr,
"It should have thrown. "
"Immediate children of STArray encoded as json must "
"have one key only.");
}
catch(std::runtime_error& e)
{
std::string what(e.what());
unexpected (what.find("First level children of `Template`") != 0);
}
}
void testParseJSONArray ()
{
testcase ("parse json array");
std::string const json (
"{\"Template\":[{\"ModifiedNode\":{\"Sequence\":1}}]}\n");
Json::Value jsonObject;
bool parsedOK (parseJSONString(json, jsonObject));
if (parsedOK)
{
STParsedJSONObject parsed ("test", jsonObject);
std::string const& serialized (
to_string (parsed.object->getJson(0)));
expect (serialized == json, serialized + " should equal: " + json);
}
else
{
fail ("Couldn't parse json: " + json);
}
}
void testSerialization ()
{
testcase ("serialization");
unexpected (sfGeneric.isUseful (), "sfGeneric must not be useful");
SField const& sfTestVL = SField::getField (STI_VL, 255);
SField const& sfTestH256 = SField::getField (STI_HASH256, 255);
SField const& sfTestU32 = SField::getField (STI_UINT32, 255);
SField const& sfTestObject = SField::getField (STI_OBJECT, 255);
SOTemplate elements;
elements.push_back (SOElement (sfFlags, SOE_REQUIRED));
elements.push_back (SOElement (sfTestVL, SOE_REQUIRED));
elements.push_back (SOElement (sfTestH256, SOE_OPTIONAL));
elements.push_back (SOElement (sfTestU32, SOE_REQUIRED));
STObject object1 (elements, sfTestObject);
STObject object2 (object1);
unexpected (object1.getSerializer () != object2.getSerializer (),
"STObject error 1");
unexpected (object1.isFieldPresent (sfTestH256) ||
!object1.isFieldPresent (sfTestVL), "STObject error");
object1.makeFieldPresent (sfTestH256);
unexpected (!object1.isFieldPresent (sfTestH256), "STObject Error 2");
unexpected (object1.getFieldH256 (sfTestH256) != uint256 (),
"STObject error 3");
if (object1.getSerializer () == object2.getSerializer ())
{
WriteLog (lsINFO, STObject) << "O1: " << object1.getJson (0);
WriteLog (lsINFO, STObject) << "O2: " << object2.getJson (0);
fail ("STObject error 4");
}
else
{
pass ();
}
object1.makeFieldAbsent (sfTestH256);
unexpected (object1.isFieldPresent (sfTestH256), "STObject error 5");
unexpected (object1.getFlags () != 0, "STObject error 6");
unexpected (object1.getSerializer () != object2.getSerializer (),
"STObject error 7");
STObject copy (object1);
unexpected (object1.isFieldPresent (sfTestH256), "STObject error 8");
unexpected (copy.isFieldPresent (sfTestH256), "STObject error 9");
unexpected (object1.getSerializer () != copy.getSerializer (),
"STObject error 10");
copy.setFieldU32 (sfTestU32, 1);
unexpected (object1.getSerializer () == copy.getSerializer (),
"STObject error 11");
for (int i = 0; i < 1000; i++)
{
Blob j (i, 2);
object1.setFieldVL (sfTestVL, j);
Serializer s;
object1.add (s);
SerializerIterator it (s);
STObject object3 (elements, it, sfTestObject);
unexpected (object1.getFieldVL (sfTestVL) != j, "STObject error");
unexpected (object3.getFieldVL (sfTestVL) != j, "STObject error");
}
}
};
BEAST_DEFINE_TESTSUITE(SerializedObject,ripple_data,ripple);
} // ripple

View File

@@ -349,63 +349,4 @@ bool passesLocalChecks (STObject const& st)
return passesLocalChecks (st, reason);
}
//------------------------------------------------------------------------------
class STTx_test : public beast::unit_test::suite
{
public:
void run()
{
RippleAddress seed;
seed.setSeedRandom ();
RippleAddress generator = RippleAddress::createGeneratorPublic (seed);
RippleAddress publicAcct = RippleAddress::createAccountPublic (generator, 1);
RippleAddress privateAcct = RippleAddress::createAccountPrivate (generator, seed, 1);
STTx j (ttACCOUNT_SET);
j.setSourceAccount (publicAcct);
j.setSigningPubKey (publicAcct);
j.setFieldVL (sfMessageKey, publicAcct.getAccountPublic ());
j.sign (privateAcct);
unexpected (!j.checkSign (), "Transaction fails signature test");
Serializer rawTxn;
j.add (rawTxn);
SerializerIterator sit (rawTxn);
STTx copy (sit);
if (copy != j)
{
log << j.getJson (0);
log << copy.getJson (0);
fail ("Transaction fails serialize/deserialize test");
}
else
{
pass ();
}
STParsedJSONObject parsed ("test", j.getJson (0));
std::unique_ptr <STObject> new_obj (std::move (parsed.object));
if (new_obj.get () == nullptr)
fail ("Unable to build object from json");
if (STObject (j) != *new_obj)
{
log << "ORIG: " << j.getJson (0);
log << "BUILT " << new_obj->getJson (0);
fail ("Built a different transaction");
}
else
{
pass ();
}
}
};
BEAST_DEFINE_TESTSUITE(STTx,ripple_app,ripple);
} // ripple

View File

@@ -19,7 +19,6 @@
#include <ripple/basics/Log.h>
#include <ripple/protocol/Serializer.h>
#include <beast/unit_test/suite.h>
#include <openssl/ripemd.h>
#include <openssl/pem.h>
@@ -648,25 +647,4 @@ Blob SerializerIterator::getRaw (int iLength)
return mSerializer.getRaw (iPos, iLength);
}
//------------------------------------------------------------------------------
class Serializer_test : public beast::unit_test::suite
{
public:
void run ()
{
Serializer s1;
s1.add32 (3);
s1.add256 (uint256 ());
Serializer s2;
s2.add32 (0x12345600);
s2.addRaw (s1.peekData ());
expect (s1.getPrefixHash (0x12345600) == s2.getSHA512Half ());
}
};
BEAST_DEFINE_TESTSUITE(Serializer,ripple_data,ripple);
} // ripple

View File

@@ -0,0 +1,115 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/protocol/BuildInfo.h>
#include <beast/unit_test/suite.h>
namespace ripple {
class BuildInfo_test : public beast::unit_test::suite
{
public:
void testVersion ()
{
testcase ("version");
beast::SemanticVersion v;
expect (v.parse (BuildInfo::getRawVersionString ()));
}
ProtocolVersion
from_version (std::uint16_t major, std::uint16_t minor)
{
return ProtocolVersion (major, minor);
}
void testValues ()
{
testcase ("comparison");
expect (from_version (1,2) == from_version (1,2));
expect (from_version (3,4) >= from_version (3,4));
expect (from_version (5,6) <= from_version (5,6));
expect (from_version (7,8) > from_version (6,7));
expect (from_version (7,8) < from_version (8,9));
expect (from_version (65535,0) < from_version (65535,65535));
expect (from_version (65535,65535) >= from_version (65535,65535));
}
void testStringVersion ()
{
testcase ("string version");
for (std::uint16_t major = 0; major < 8; major++)
{
for (std::uint16_t minor = 0; minor < 8; minor++)
{
expect (to_string (from_version (major, minor)) ==
std::to_string (major) + "." + std::to_string (minor));
}
}
}
void testVersionPacking ()
{
testcase ("version packing");
expect (to_packed (from_version (0, 0)) == 0);
expect (to_packed (from_version (0, 1)) == 1);
expect (to_packed (from_version (0, 255)) == 255);
expect (to_packed (from_version (0, 65535)) == 65535);
expect (to_packed (from_version (1, 0)) == 65536);
expect (to_packed (from_version (1, 1)) == 65537);
expect (to_packed (from_version (1, 255)) == 65791);
expect (to_packed (from_version (1, 65535)) == 131071);
expect (to_packed (from_version (255, 0)) == 16711680);
expect (to_packed (from_version (255, 1)) == 16711681);
expect (to_packed (from_version (255, 255)) == 16711935);
expect (to_packed (from_version (255, 65535)) == 16777215);
expect (to_packed (from_version (65535, 0)) == 4294901760);
expect (to_packed (from_version (65535, 1)) == 4294901761);
expect (to_packed (from_version (65535, 255)) == 4294902015);
expect (to_packed (from_version (65535, 65535)) == 4294967295);
}
void run ()
{
testVersion ();
testValues ();
testStringVersion ();
testVersionPacking ();
auto const current_protocol = BuildInfo::getCurrentProtocol ();
auto const minimum_protocol = BuildInfo::getMinimumProtocol ();
expect (current_protocol >= minimum_protocol);
log << " Ripple Version: " << BuildInfo::getVersionString();
log << " Protocol Version: " << to_string (current_protocol);
}
};
BEAST_DEFINE_TESTSUITE(BuildInfo,ripple_data,ripple);
} // ripple

View File

@@ -0,0 +1,135 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/protocol/RippleAddress.h>
#include <ripple/protocol/RipplePublicKey.h>
#include <beast/unit_test/suite.h>
namespace ripple {
class RippleAddress_test : public beast::unit_test::suite
{
public:
void run()
{
// Construct a seed.
RippleAddress naSeed;
expect (naSeed.setSeedGeneric ("masterpassphrase"));
expect (naSeed.humanSeed () == "snoPBrXtMeMyMHUVTgbuqAfg1SUTb", naSeed.humanSeed ());
// Create node public/private key pair
RippleAddress naNodePublic = RippleAddress::createNodePublic (naSeed);
RippleAddress naNodePrivate = RippleAddress::createNodePrivate (naSeed);
expect (naNodePublic.humanNodePublic () == "n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9", naNodePublic.humanNodePublic ());
expect (naNodePrivate.humanNodePrivate () == "pnen77YEeUd4fFKG7iycBWcwKpTaeFRkW2WFostaATy1DSupwXe", naNodePrivate.humanNodePrivate ());
// Check node signing.
Blob vucTextSrc = strCopy ("Hello, nurse!");
uint256 uHash = Serializer::getSHA512Half (vucTextSrc);
Blob vucTextSig;
naNodePrivate.signNodePrivate (uHash, vucTextSig);
expect (naNodePublic.verifyNodePublic (uHash, vucTextSig, ECDSA::strict), "Verify failed.");
// Construct a public generator from the seed.
RippleAddress generator = RippleAddress::createGeneratorPublic (naSeed);
expect (generator.humanGenerator () == "fhuJKrhSDzV2SkjLn9qbwm5AaRmrxDPfFsHDCP6yfDZWcxDFz4mt", generator.humanGenerator ());
// Create account #0 public/private key pair.
RippleAddress naAccountPublic0 = RippleAddress::createAccountPublic (generator, 0);
RippleAddress naAccountPrivate0 = RippleAddress::createAccountPrivate (generator, naSeed, 0);
expect (naAccountPublic0.humanAccountID () == "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", naAccountPublic0.humanAccountID ());
expect (naAccountPublic0.humanAccountPublic () == "aBQG8RQAzjs1eTKFEAQXr2gS4utcDiEC9wmi7pfUPTi27VCahwgw", naAccountPublic0.humanAccountPublic ());
// Create account #1 public/private key pair.
RippleAddress naAccountPublic1 = RippleAddress::createAccountPublic (generator, 1);
RippleAddress naAccountPrivate1 = RippleAddress::createAccountPrivate (generator, naSeed, 1);
expect (naAccountPublic1.humanAccountID () == "r4bYF7SLUMD7QgSLLpgJx38WJSY12ViRjP", naAccountPublic1.humanAccountID ());
expect (naAccountPublic1.humanAccountPublic () == "aBPXpTfuLy1Bhk3HnGTTAqnovpKWQ23NpFMNkAF6F1Atg5vDyPrw", naAccountPublic1.humanAccountPublic ());
// Check account signing.
expect (naAccountPrivate0.accountPrivateSign (uHash, vucTextSig), "Signing failed.");
expect (naAccountPublic0.accountPublicVerify (uHash, vucTextSig, ECDSA::strict), "Verify failed.");
expect (!naAccountPublic1.accountPublicVerify (uHash, vucTextSig, ECDSA::not_strict), "Anti-verify failed.");
expect (!naAccountPublic1.accountPublicVerify (uHash, vucTextSig, ECDSA::strict), "Anti-verify failed.");
expect (naAccountPrivate1.accountPrivateSign (uHash, vucTextSig), "Signing failed.");
expect (naAccountPublic1.accountPublicVerify (uHash, vucTextSig, ECDSA::strict), "Verify failed.");
expect (!naAccountPublic0.accountPublicVerify (uHash, vucTextSig, ECDSA::not_strict), "Anti-verify failed.");
expect (!naAccountPublic0.accountPublicVerify (uHash, vucTextSig, ECDSA::strict), "Anti-verify failed.");
// Check account encryption.
Blob vucTextCipher
= naAccountPrivate0.accountPrivateEncrypt (naAccountPublic1, vucTextSrc);
Blob vucTextRecovered
= naAccountPrivate1.accountPrivateDecrypt (naAccountPublic0, vucTextCipher);
expect (vucTextSrc == vucTextRecovered, "Encrypt-decrypt failed.");
{
RippleAddress nSeed;
uint128 seed1, seed2;
seed1.SetHex ("71ED064155FFADFA38782C5E0158CB26");
nSeed.setSeed (seed1);
expect (nSeed.humanSeed() == "shHM53KPZ87Gwdqarm1bAmPeXg8Tn",
"Incorrect human seed");
expect (nSeed.humanSeed1751() == "MAD BODY ACE MINT OKAY HUB WHAT DATA SACK FLAT DANA MATH",
"Incorrect 1751 seed");
}
}
};
//------------------------------------------------------------------------------
class RippleIdentifier_test : public beast::unit_test::suite
{
public:
void run ()
{
testcase ("Seed");
RippleAddress seed;
expect (seed.setSeedGeneric ("masterpassphrase"));
expect (seed.humanSeed () == "snoPBrXtMeMyMHUVTgbuqAfg1SUTb", seed.humanSeed ());
testcase ("RipplePublicKey");
RippleAddress deprecatedPublicKey (RippleAddress::createNodePublic (seed));
expect (deprecatedPublicKey.humanNodePublic () ==
"n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9",
deprecatedPublicKey.humanNodePublic ());
RipplePublicKey publicKey = deprecatedPublicKey.toPublicKey();
expect (publicKey.to_string() == deprecatedPublicKey.humanNodePublic(),
publicKey.to_string());
testcase ("Generator");
RippleAddress generator (RippleAddress::createGeneratorPublic (seed));
expect (generator.humanGenerator () ==
"fhuJKrhSDzV2SkjLn9qbwm5AaRmrxDPfFsHDCP6yfDZWcxDFz4mt",
generator.humanGenerator ());
}
};
BEAST_DEFINE_TESTSUITE(RippleAddress,ripple_data,ripple);
BEAST_DEFINE_TESTSUITE(RippleIdentifier,ripple_data,ripple);
} // ripple

View File

@@ -0,0 +1,195 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/protocol/STBase.h>
#include <ripple/protocol/STAccount.h>
#include <ripple/protocol/STArray.h>
#include <ripple/protocol/STObject.h>
#include <ripple/protocol/STParsedJSON.h>
#include <beast/unit_test/suite.h>
#include <beast/cxx14/memory.h> // <memory>
namespace ripple {
class SerializedObject_test : public beast::unit_test::suite
{
public:
void run()
{
testSerialization();
testParseJSONArray();
testParseJSONArrayWithInvalidChildrenObjects();
}
bool parseJSONString (std::string const& json, Json::Value& to)
{
Json::Reader reader;
return (reader.parse(json, to) &&
!to.isNull() &&
to.isObject());
}
void testParseJSONArrayWithInvalidChildrenObjects ()
{
testcase ("parse json array invalid children");
try
{
/*
STArray/STObject constructs don't really map perfectly to json
arrays/objects.
STObject is an associative container, mapping fields to value, but
an STObject may also have a Field as it's name, stored outside the
associative structure. The name is important, so to maintain
fidelity, it will take TWO json objects to represent them.
*/
std::string faulty ("{\"Template\":[{"
"\"ModifiedNode\":{\"Sequence\":1}, "
"\"DeletedNode\":{\"Sequence\":1}"
"}]}");
std::unique_ptr<STObject> so;
Json::Value faultyJson;
bool parsedOK (parseJSONString(faulty, faultyJson));
unexpected(!parsedOK, "failed to parse");
STParsedJSONObject parsed ("test", faultyJson);
expect (parsed.object.get() == nullptr,
"It should have thrown. "
"Immediate children of STArray encoded as json must "
"have one key only.");
}
catch(std::runtime_error& e)
{
std::string what(e.what());
unexpected (what.find("First level children of `Template`") != 0);
}
}
void testParseJSONArray ()
{
testcase ("parse json array");
std::string const json (
"{\"Template\":[{\"ModifiedNode\":{\"Sequence\":1}}]}\n");
Json::Value jsonObject;
bool parsedOK (parseJSONString(json, jsonObject));
if (parsedOK)
{
STParsedJSONObject parsed ("test", jsonObject);
std::string const& serialized (
to_string (parsed.object->getJson(0)));
expect (serialized == json, serialized + " should equal: " + json);
}
else
{
fail ("Couldn't parse json: " + json);
}
}
void testSerialization ()
{
testcase ("serialization");
unexpected (sfGeneric.isUseful (), "sfGeneric must not be useful");
SField const& sfTestVL = SField::getField (STI_VL, 255);
SField const& sfTestH256 = SField::getField (STI_HASH256, 255);
SField const& sfTestU32 = SField::getField (STI_UINT32, 255);
SField const& sfTestObject = SField::getField (STI_OBJECT, 255);
SOTemplate elements;
elements.push_back (SOElement (sfFlags, SOE_REQUIRED));
elements.push_back (SOElement (sfTestVL, SOE_REQUIRED));
elements.push_back (SOElement (sfTestH256, SOE_OPTIONAL));
elements.push_back (SOElement (sfTestU32, SOE_REQUIRED));
STObject object1 (elements, sfTestObject);
STObject object2 (object1);
unexpected (object1.getSerializer () != object2.getSerializer (),
"STObject error 1");
unexpected (object1.isFieldPresent (sfTestH256) ||
!object1.isFieldPresent (sfTestVL), "STObject error");
object1.makeFieldPresent (sfTestH256);
unexpected (!object1.isFieldPresent (sfTestH256), "STObject Error 2");
unexpected (object1.getFieldH256 (sfTestH256) != uint256 (),
"STObject error 3");
if (object1.getSerializer () == object2.getSerializer ())
{
WriteLog (lsINFO, STObject) << "O1: " << object1.getJson (0);
WriteLog (lsINFO, STObject) << "O2: " << object2.getJson (0);
fail ("STObject error 4");
}
else
{
pass ();
}
object1.makeFieldAbsent (sfTestH256);
unexpected (object1.isFieldPresent (sfTestH256), "STObject error 5");
unexpected (object1.getFlags () != 0, "STObject error 6");
unexpected (object1.getSerializer () != object2.getSerializer (),
"STObject error 7");
STObject copy (object1);
unexpected (object1.isFieldPresent (sfTestH256), "STObject error 8");
unexpected (copy.isFieldPresent (sfTestH256), "STObject error 9");
unexpected (object1.getSerializer () != copy.getSerializer (),
"STObject error 10");
copy.setFieldU32 (sfTestU32, 1);
unexpected (object1.getSerializer () == copy.getSerializer (),
"STObject error 11");
for (int i = 0; i < 1000; i++)
{
Blob j (i, 2);
object1.setFieldVL (sfTestVL, j);
Serializer s;
object1.add (s);
SerializerIterator it (s);
STObject object3 (elements, it, sfTestObject);
unexpected (object1.getFieldVL (sfTestVL) != j, "STObject error");
unexpected (object3.getFieldVL (sfTestVL) != j, "STObject error");
}
}
};
BEAST_DEFINE_TESTSUITE(SerializedObject,ripple_data,ripple);
} // ripple

View File

@@ -0,0 +1,81 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/protocol/STTx.h>
#include <beast/unit_test/suite.h>
namespace ripple {
class STTx_test : public beast::unit_test::suite
{
public:
void run()
{
RippleAddress seed;
seed.setSeedRandom ();
RippleAddress generator = RippleAddress::createGeneratorPublic (seed);
RippleAddress publicAcct = RippleAddress::createAccountPublic (generator, 1);
RippleAddress privateAcct = RippleAddress::createAccountPrivate (generator, seed, 1);
STTx j (ttACCOUNT_SET);
j.setSourceAccount (publicAcct);
j.setSigningPubKey (publicAcct);
j.setFieldVL (sfMessageKey, publicAcct.getAccountPublic ());
j.sign (privateAcct);
unexpected (!j.checkSign (), "Transaction fails signature test");
Serializer rawTxn;
j.add (rawTxn);
SerializerIterator sit (rawTxn);
STTx copy (sit);
if (copy != j)
{
log << j.getJson (0);
log << copy.getJson (0);
fail ("Transaction fails serialize/deserialize test");
}
else
{
pass ();
}
STParsedJSONObject parsed ("test", j.getJson (0));
std::unique_ptr <STObject> new_obj (std::move (parsed.object));
if (new_obj.get () == nullptr)
fail ("Unable to build object from json");
if (STObject (j) != *new_obj)
{
log << "ORIG: " << j.getJson (0);
log << "BUILT " << new_obj->getJson (0);
fail ("Built a different transaction");
}
else
{
pass ();
}
}
};
BEAST_DEFINE_TESTSUITE(STTx,ripple_app,ripple);
} // ripple

View File

@@ -17,23 +17,28 @@
*/
//==============================================================================
#include <ripple/validators/impl/Logic.h>
#include <ripple/protocol/Serializer.h>
#include <beast/unit_test/suite.h>
namespace ripple {
namespace Validators {
class Logic_test : public beast::unit_test::suite
class Serializer_test : public beast::unit_test::suite
{
public:
void
run()
void run ()
{
pass();
Serializer s1;
s1.add32 (3);
s1.add256 (uint256 ());
Serializer s2;
s2.add32 (0x12345600);
s2.addRaw (s1.peekData ());
expect (s1.getPrefixHash (0x12345600) == s2.getSHA512Half ());
}
};
BEAST_DEFINE_TESTSUITE_MANUAL(Logic,validators,ripple);
BEAST_DEFINE_TESTSUITE(Serializer,ripple_data,ripple);
}
}
} // ripple

View File

@@ -18,7 +18,7 @@
//==============================================================================
#include <ripple/rpc/Coroutine.h>
#include <ripple/rpc/impl/TestOutputSuite.h>
#include <ripple/rpc/tests/TestOutputSuite.test.h>
namespace ripple {
namespace RPC {

View File

@@ -550,551 +550,5 @@ transactionSign (
}
}
//------------------------------------------------------------------------------
// Struct used to test calls to transactionSign and transactionSubmit.
struct TxnTestData
{
// Gah, without constexpr I can't make this an enum and initialize
// OR operators at compile time. Punting with integer constants.
static unsigned int const allGood = 0x0;
static unsigned int const signFail = 0x1;
static unsigned int const submitFail = 0x2;
char const* const json;
unsigned int result;
TxnTestData () = delete;
TxnTestData (TxnTestData const&) = delete;
TxnTestData& operator= (TxnTestData const&) = delete;
TxnTestData (char const* jsonIn, unsigned int resultIn)
: json (jsonIn)
, result (resultIn)
{ }
};
// Declare storage for statics to avoid link errors.
unsigned int const TxnTestData::allGood;
unsigned int const TxnTestData::signFail;
unsigned int const TxnTestData::submitFail;
static TxnTestData const txnTestArray [] =
{
// Minimal payment.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// Pass in Fee with minimal payment.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Fee": 10,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// Pass in Sequence.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Sequence": 0,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// Pass in Sequence and Fee with minimal payment.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Sequence": 0,
"Fee": 10,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// Add "fee_mult_max" field.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"fee_mult_max": 7,
"tx_json": {
"Sequence": 0,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// "fee_mult_max is ignored if "Fee" is present.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"fee_mult_max": 0,
"tx_json": {
"Sequence": 0,
"Fee": 10,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// Invalid "fee_mult_max" field.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"fee_mult_max": "NotAFeeMultiplier",
"tx_json": {
"Sequence": 0,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Invalid value for "fee_mult_max" field.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"fee_mult_max": 0,
"tx_json": {
"Sequence": 0,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Missing "Amount".
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Invalid "Amount".
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "NotAnAmount",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Missing "Destination".
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Invalid "Destination".
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "NotADestination",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Cannot create XRP to XRP paths.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"build_path": 1,
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Successful "build_path".
{R"({
"command": "submit",
"secret": "masterpassphrase",
"build_path": 1,
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": {
"value": "10",
"currency": "USD",
"issuer": "0123456789012345678901234567890123456789"
},
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// Not valid to include both "Paths" and "build_path".
{R"({
"command": "submit",
"secret": "masterpassphrase",
"build_path": 1,
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": {
"value": "10",
"currency": "USD",
"issuer": "0123456789012345678901234567890123456789"
},
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"Paths": "",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Successful "SendMax".
{R"({
"command": "submit",
"secret": "masterpassphrase",
"build_path": 1,
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": {
"value": "10",
"currency": "USD",
"issuer": "0123456789012345678901234567890123456789"
},
"SendMax": {
"value": "5",
"currency": "USD",
"issuer": "0123456789012345678901234567890123456789"
},
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// Even though "Amount" may not be XRP for pathfinding, "SendMax" may be XRP.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"build_path": 1,
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": {
"value": "10",
"currency": "USD",
"issuer": "0123456789012345678901234567890123456789"
},
"SendMax": 10000,
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// "secret" must be present.
{R"({
"command": "submit",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// "secret" must be non-empty.
{R"({
"command": "submit",
"secret": "",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// "tx_json" must be present.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"rx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// "TransactionType" must be present.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// The "TransactionType" must be one of the pre-established transaction types.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "tt"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// The "TransactionType", however, may be represented with an integer.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": 0
}
})", TxnTestData::allGood},
// "Account" must be present.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// "Account" must be well formed.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "NotAnAccount",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// The "offline" tag may be added to the transaction.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"offline": 0,
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// If "offline" is true then a "Sequence" field must be supplied.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"offline": 1,
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Valid transaction if "offline" is true.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"offline": 1,
"tx_json": {
"Sequence": 0,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// A "Flags' field may be specified.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Flags": 0,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// The "Flags" field must be numeric.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Flags": "NotGoodFlags",
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// It's okay to add a "debug_signing" field.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"debug_signing": 0,
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
};
class JSONRPC_test : public beast::unit_test::suite
{
public:
void testAutoFillFees ()
{
RippleAddress rootSeedMaster
= RippleAddress::createSeedGeneric ("masterpassphrase");
RippleAddress rootGeneratorMaster
= RippleAddress::createGeneratorPublic (rootSeedMaster);
RippleAddress rootAddress
= RippleAddress::createAccountPublic (rootGeneratorMaster, 0);
std::uint64_t startAmount (100000);
Ledger::pointer ledger (std::make_shared <Ledger> (
rootAddress, startAmount));
using namespace RPCDetail;
LedgerFacade facade (LedgerFacade::noNetOPs, ledger);
{
Json::Value req;
Json::Value result;
Json::Reader ().parse (
R"({ "fee_mult_max" : 1, "tx_json" : { } } )"
, req);
autofill_fee (req, facade, result, true);
expect (! contains_error (result));
}
{
Json::Value req;
Json::Value result;
Json::Reader ().parse (
R"({ "fee_mult_max" : 0, "tx_json" : { } } )"
, req);
autofill_fee (req, facade, result, true);
expect (contains_error (result));
}
}
void testTransactionRPC ()
{
// This loop is forward-looking for when there are separate
// transactionSign () and transcationSubmit () functions. For now
// they just have a bool (false = sign, true = submit) and a flag
// to help classify failure types.
using TestStuff = std::pair <bool, unsigned int>;
static TestStuff const testFuncs [] =
{
TestStuff {false, TxnTestData::signFail},
TestStuff {true, TxnTestData::submitFail},
};
for (auto testFunc : testFuncs)
{
// For each JSON test.
for (auto const& txnTest : txnTestArray)
{
Json::Value req;
Json::Reader ().parse (txnTest.json, req);
if (contains_error (req))
throw std::runtime_error (
"Internal JSONRPC_test error. Bad test JSON.");
static Role const testedRoles[] =
{Role::GUEST, Role::USER, Role::ADMIN, Role::FORBID};
for (Role testRole : testedRoles)
{
// Mock so we can run without a ledger.
RPCDetail::LedgerFacade fakeNetOPs (
RPCDetail::LedgerFacade::noNetOPs);
Json::Value result = transactionSign (
req,
testFunc.first,
true,
fakeNetOPs,
testRole);
expect (contains_error (result) ==
static_cast <bool> (txnTest.result & testFunc.second));
}
}
}
}
void run ()
{
testAutoFillFees ();
testTransactionRPC ();
}
};
BEAST_DEFINE_TESTSUITE(JSONRPC,ripple_app,ripple);
} // RPC
} // ripple

View File

@@ -18,7 +18,7 @@
//==============================================================================
#include <ripple/rpc/Yield.h>
#include <ripple/rpc/impl/TestOutputSuite.h>
#include <ripple/rpc/tests/TestOutputSuite.test.h>
namespace ripple {
namespace RPC {

View File

@@ -19,7 +19,7 @@
#include <ripple/rpc/Coroutine.h>
#include <ripple/rpc/Yield.h>
#include <ripple/rpc/impl/TestOutputSuite.h>
#include <ripple/rpc/tests/TestOutputSuite.test.h>
namespace ripple {
namespace RPC {

View File

@@ -0,0 +1,576 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012-2014 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/app/paths/FindPaths.h>
#include <ripple/basics/StringUtilities.h>
#include <ripple/json/json_reader.h>
#include <ripple/protocol/TxFlags.h>
#include <ripple/rpc/impl/TransactionSign.h>
#include <beast/unit_test.h>
namespace ripple {
namespace RPC {
// Struct used to test calls to transactionSign and transactionSubmit.
struct TxnTestData
{
// Gah, without constexpr I can't make this an enum and initialize
// OR operators at compile time. Punting with integer constants.
static unsigned int const allGood = 0x0;
static unsigned int const signFail = 0x1;
static unsigned int const submitFail = 0x2;
char const* const json;
unsigned int result;
TxnTestData () = delete;
TxnTestData (TxnTestData const&) = delete;
TxnTestData& operator= (TxnTestData const&) = delete;
TxnTestData (char const* jsonIn, unsigned int resultIn)
: json (jsonIn)
, result (resultIn)
{ }
};
// Declare storage for statics to avoid link errors.
unsigned int const TxnTestData::allGood;
unsigned int const TxnTestData::signFail;
unsigned int const TxnTestData::submitFail;
static TxnTestData const txnTestArray [] =
{
// Minimal payment.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// Pass in Fee with minimal payment.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Fee": 10,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// Pass in Sequence.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Sequence": 0,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// Pass in Sequence and Fee with minimal payment.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Sequence": 0,
"Fee": 10,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// Add "fee_mult_max" field.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"fee_mult_max": 7,
"tx_json": {
"Sequence": 0,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// "fee_mult_max is ignored if "Fee" is present.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"fee_mult_max": 0,
"tx_json": {
"Sequence": 0,
"Fee": 10,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// Invalid "fee_mult_max" field.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"fee_mult_max": "NotAFeeMultiplier",
"tx_json": {
"Sequence": 0,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Invalid value for "fee_mult_max" field.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"fee_mult_max": 0,
"tx_json": {
"Sequence": 0,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Missing "Amount".
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Invalid "Amount".
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "NotAnAmount",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Missing "Destination".
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Invalid "Destination".
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "NotADestination",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Cannot create XRP to XRP paths.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"build_path": 1,
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Successful "build_path".
{R"({
"command": "submit",
"secret": "masterpassphrase",
"build_path": 1,
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": {
"value": "10",
"currency": "USD",
"issuer": "0123456789012345678901234567890123456789"
},
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// Not valid to include both "Paths" and "build_path".
{R"({
"command": "submit",
"secret": "masterpassphrase",
"build_path": 1,
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": {
"value": "10",
"currency": "USD",
"issuer": "0123456789012345678901234567890123456789"
},
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"Paths": "",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Successful "SendMax".
{R"({
"command": "submit",
"secret": "masterpassphrase",
"build_path": 1,
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": {
"value": "10",
"currency": "USD",
"issuer": "0123456789012345678901234567890123456789"
},
"SendMax": {
"value": "5",
"currency": "USD",
"issuer": "0123456789012345678901234567890123456789"
},
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// Even though "Amount" may not be XRP for pathfinding, "SendMax" may be XRP.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"build_path": 1,
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": {
"value": "10",
"currency": "USD",
"issuer": "0123456789012345678901234567890123456789"
},
"SendMax": 10000,
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// "secret" must be present.
{R"({
"command": "submit",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// "secret" must be non-empty.
{R"({
"command": "submit",
"secret": "",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// "tx_json" must be present.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"rx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// "TransactionType" must be present.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// The "TransactionType" must be one of the pre-established transaction types.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "tt"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// The "TransactionType", however, may be represented with an integer.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": 0
}
})", TxnTestData::allGood},
// "Account" must be present.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// "Account" must be well formed.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Account": "NotAnAccount",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// The "offline" tag may be added to the transaction.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"offline": 0,
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// If "offline" is true then a "Sequence" field must be supplied.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"offline": 1,
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// Valid transaction if "offline" is true.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"offline": 1,
"tx_json": {
"Sequence": 0,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// A "Flags' field may be specified.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Flags": 0,
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
// The "Flags" field must be numeric.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"tx_json": {
"Flags": "NotGoodFlags",
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::signFail | TxnTestData::submitFail},
// It's okay to add a "debug_signing" field.
{R"({
"command": "submit",
"secret": "masterpassphrase",
"debug_signing": 0,
"tx_json": {
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Amount": "1000000000",
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
"TransactionType": "Payment"
}
})", TxnTestData::allGood},
};
class JSONRPC_test : public beast::unit_test::suite
{
public:
void testAutoFillFees ()
{
RippleAddress rootSeedMaster
= RippleAddress::createSeedGeneric ("masterpassphrase");
RippleAddress rootGeneratorMaster
= RippleAddress::createGeneratorPublic (rootSeedMaster);
RippleAddress rootAddress
= RippleAddress::createAccountPublic (rootGeneratorMaster, 0);
std::uint64_t startAmount (100000);
Ledger::pointer ledger (std::make_shared <Ledger> (
rootAddress, startAmount));
using namespace RPCDetail;
LedgerFacade facade (LedgerFacade::noNetOPs, ledger);
{
Json::Value req;
Json::Value result;
Json::Reader ().parse (
R"({ "fee_mult_max" : 1, "tx_json" : { } } )"
, req);
autofill_fee (req, facade, result, true);
expect (! contains_error (result));
}
{
Json::Value req;
Json::Value result;
Json::Reader ().parse (
R"({ "fee_mult_max" : 0, "tx_json" : { } } )"
, req);
autofill_fee (req, facade, result, true);
expect (contains_error (result));
}
}
void testTransactionRPC ()
{
// This loop is forward-looking for when there are separate
// transactionSign () and transcationSubmit () functions. For now
// they just have a bool (false = sign, true = submit) and a flag
// to help classify failure types.
using TestStuff = std::pair <bool, unsigned int>;
static TestStuff const testFuncs [] =
{
TestStuff {false, TxnTestData::signFail},
TestStuff {true, TxnTestData::submitFail},
};
for (auto testFunc : testFuncs)
{
// For each JSON test.
for (auto const& txnTest : txnTestArray)
{
Json::Value req;
Json::Reader ().parse (txnTest.json, req);
if (contains_error (req))
throw std::runtime_error (
"Internal JSONRPC_test error. Bad test JSON.");
static Role const testedRoles[] =
{Role::GUEST, Role::USER, Role::ADMIN, Role::FORBID};
for (Role testRole : testedRoles)
{
// Mock so we can run without a ledger.
RPCDetail::LedgerFacade fakeNetOPs (
RPCDetail::LedgerFacade::noNetOPs);
Json::Value result = transactionSign (
req,
testFunc.first,
true,
fakeNetOPs,
testRole);
expect (contains_error (result) ==
static_cast <bool> (txnTest.result & testFunc.second));
}
}
}
}
void run ()
{
testAutoFillFees ();
testTransactionRPC ();
}
};
BEAST_DEFINE_TESTSUITE(JSONRPC,ripple_app,ripple);
} // RPC
} // ripple

View File

@@ -18,7 +18,7 @@
//==============================================================================
#include <ripple/rpc/impl/JsonObject.h>
#include <ripple/rpc/impl/TestOutputSuite.h>
#include <ripple/rpc/tests/TestOutputSuite.test.h>
#include <beast/unit_test/suite.h>
namespace ripple {

View File

@@ -20,7 +20,7 @@
#include <ripple/json/json_writer.h>
#include <ripple/rpc/impl/JsonWriter.h>
#include <ripple/rpc/impl/TestOutputSuite.h>
#include <ripple/rpc/tests/TestOutputSuite.test.h>
#include <beast/unit_test/suite.h>
namespace ripple {

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#ifndef RIPPLED_RIPPLE_RPC_IMPL_TESTOUTPUT_H
#define RIPPLED_RIPPLE_RPC_IMPL_TESTOUTPUT_H
#ifndef RIPPLE_RPC_TESTOUTPUTSUITE_H_INCLUDED
#define RIPPLE_RPC_TESTOUTPUTSUITE_H_INCLUDED
#include <ripple/rpc/Output.h>
#include <ripple/rpc/impl/JsonWriter.h>

View File

@@ -18,7 +18,7 @@
//==============================================================================
#include <ripple/rpc/impl/WriteJson.h>
#include <ripple/rpc/impl/TestOutputSuite.h>
#include <ripple/rpc/tests/TestOutputSuite.test.h>
namespace ripple {
namespace RPC {

View File

@@ -18,7 +18,7 @@
//==============================================================================
#include <ripple/rpc/Yield.h>
#include <ripple/rpc/impl/TestOutputSuite.h>
#include <ripple/rpc/tests/TestOutputSuite.test.h>
namespace ripple {
namespace RPC {

View File

@@ -1,89 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TESTOVERLAY_RESULTS_H_INCLUDED
#define RIPPLE_TESTOVERLAY_RESULTS_H_INCLUDED
namespace TestOverlay
{
/** Accumulates statistics on one or more simulation steps. */
struct Results
{
Results ()
: steps (0)
, sent (0)
, received (0)
, dropped (0)
{
}
Results (Results const& other)
: steps (other.steps)
, sent (other.sent)
, received (other.received)
, dropped (other.dropped)
{
}
Results& operator= (Results const& other)
{
steps = other.steps;
sent = other.sent;
received = other.received;
dropped = other.dropped;
return *this;
}
std::string to_string () const
{
return "steps=" + std::to_string (steps) +
", sent=" + std::to_string (sent) +
", received=" + std::to_string (received) +
", dropped=" + std::to_string (dropped);
}
Results& operator+= (Results const& other)
{
steps += other.steps;
sent += other.sent;
received += other.received;
dropped += other.dropped;
return *this;
}
Results operator+ (Results const& other)
{
Results results;
results.steps = steps + other.steps;
results.sent = sent + other.sent;
results.received = received + other.received;
results.dropped = dropped + other.dropped;
return results;
}
int steps;
int sent;
int received;
int dropped;
};
}
#endif

View File

@@ -1,69 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TESTOVERLAY_SIMPLEPAYLOAD_H_INCLUDED
#define RIPPLE_TESTOVERLAY_SIMPLEPAYLOAD_H_INCLUDED
namespace TestOverlay
{
/** A simple message payload. */
class SimplePayload
{
public:
SimplePayload () = default;
SimplePayload (SimplePayload const& other) = default;
SimplePayload& operator= (SimplePayload const& other) = default;
SimplePayload (int what, std::string const& data = "", int hops = 0)
: m_hops (hops)
, m_what (what)
, m_data (data)
{
}
SimplePayload withHop () const
{
return SimplePayload (m_what, m_data, m_hops + 1);
}
int hops () const
{
return m_hops;
}
int what () const
{
return m_what;
}
std::string data () const
{
return m_data;
}
private:
int m_hops;
int m_what;
std::string m_data;
};
}
#endif

View File

@@ -1,542 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/common/UnorderedContainers.h>
#include <beast/unit_test/suite.h>
namespace ripple {
namespace TestOverlay {
class Network1_test : public beast::unit_test::suite
{
public:
template <class Config>
class SeenState : public StateBase <Config>
{
public:
SeenState ()
: m_seen (0)
{
}
void increment ()
{
++m_seen;
}
int seen () const
{
return m_seen;
}
private:
int m_seen;
};
//--------------------------------------------------------------------------
template <class Config>
class PeerLogic : public PeerLogicBase <Config>
{
public:
typedef PeerLogicBase <Config> Base;
typedef typename Config::Payload Payload;
typedef typename Base::Connection Connection;
typedef typename Base::Peer Peer;
typedef typename Base::Message Message;
typedef typename Config::SizeType SizeType;
explicit PeerLogic (Peer& peer)
: PeerLogicBase <Config> (peer)
{
}
~PeerLogic ()
{
}
void step ()
{
if (this->peer().id () == 1)
{
if (this->peer().network().steps() == 0)
{
this->peer().network().state().increment();
this->peer().send_all (Payload (1));
}
}
}
void receive (Connection const& c, Message const& m)
{
if (this->peer().id () != 1)
{
this->peer().network().state().increment();
this->peer().send_all_if (Message (m.id(),
m.payload().withHop ()),
typename Connection::IsNotPeer (c.peer()));
}
}
};
//--------------------------------------------------------------------------
struct Params : ConfigType <
Params,
SeenState,
PeerLogic
>
{
typedef PremadeInitPolicy <250, 3> InitPolicy;
};
typedef Params::Network Network;
//--------------------------------------------------------------------------
void testCreation ()
{
Network network;
Results result;
for (int i = 0; result.received < 249 && i < 100; ++i)
{
auto s = "step #" + std::to_string (network.steps()) + " ";
result += network.step ();
log << s << result.to_string ();
}
int const seen (network.state().seen());
log << "Seen = " << std::to_string (seen);
pass ();
}
void run ()
{
testCreation ();
}
};
//------------------------------------------------------------------------------
//
//
//
//------------------------------------------------------------------------------
/*
Concepts:
Link
Logic
Message
Network
Peer
*/
/** UnaryPredicate, returns `true` if the 'to' peer on a Link matches. */
template <typename PeerType>
class is_to_pred
{
public:
typedef PeerType Peer;
is_to_pred (Peer const& to)
: m_to (to)
{
}
template <typename Link>
bool operator() (Link const& l) const
{
return &m_to == &l.to();
}
private:
Peer const& m_to;
};
/** Returns a new is_to_pred for the specified peer. */
template <typename PeerType>
is_to_pred <PeerType> is_to (PeerType const& to)
{
return is_to_pred <PeerType> (to);
}
/** Returns `true` if the peers are connected. */
template <typename PeerType>
bool is_connected (PeerType const& from, PeerType const& to)
{
return std::find_if (from.links().begin(), from.links().end(),
is_to (to)) != from.links().end();
}
//------------------------------------------------------------------------------
class BasicMessage
{
public:
typedef std::size_t UniqueID;
BasicMessage ()
: m_id (0)
{
}
explicit BasicMessage (UniqueID id)
: m_id (id)
{
}
private:
UniqueID m_id;
};
//------------------------------------------------------------------------------
template <typename PeerType, typename MessageType>
class BasicLink
{
public:
typedef PeerType Peer;
typedef MessageType Message;
typedef std::vector <Message> Messages;
BasicLink (Peer& to, Peer& from, bool inbound)
: m_to (&to)
, m_from (&from)
, m_inbound (inbound)
{
}
Peer const& to () const
{
return *m_to;
}
Peer& to ()
{
return *m_to;
}
Peer& from ()
{
return *m_from;
}
Peer const& from () const
{
return *m_from;
}
bool inbound() const
{
return m_inbound;
}
bool outbound() const
{
return ! m_inbound;
}
void send (MessageType const& m)
{
m_later.push_back (m);
}
void pre_step ()
{
std::swap (m_now, m_later);
}
void step ()
{
for (typename Messages::const_iterator iter (m_now.begin());
iter != m_now.end(); ++iter)
m_to->receive (*iter);
m_now.clear();
}
private:
Peer* m_to;
Peer* m_from;
bool m_inbound;
Messages m_now;
Messages m_later;
};
//------------------------------------------------------------------------------
/** Models a peer. */
template <typename PeerType, typename MessageType>
class BasicPeer
{
public:
typedef PeerType Peer;
typedef MessageType Message;
typedef BasicLink <Peer, Message> Link;
typedef std::vector <Link> Links;
~BasicPeer ()
{
for (typename Links::iterator iter (links().begin());
iter != links().end(); ++iter)
iter->to().links().erase (std::find_if (
iter->to().links().begin(), iter->to().links().end(),
is_to (peer())));
}
bool operator== (Peer const& rhs) const
{
return this == &rhs;
}
Peer& peer()
{
return *static_cast<Peer*>(this);
}
Peer const& peer() const
{
return *static_cast<Peer const*>(this);
}
Links& links()
{
return m_links;
}
Links const& links() const
{
return m_links;
}
void connect (Peer& to)
{
m_links.emplace_back (to, peer(), false);
to.m_links.emplace_back (peer(), to, true);
}
void disconnect (Peer& to)
{
typename Links::iterator const iter (std::find_if (
links().begin(), links().end(), is_to (to)));
iter->to().links().erase (std::find_if (
iter->to().links().begin(), iter->to().links.end(),
is_to (peer())));
}
void send (Message const& m)
{
for (typename Links::iterator iter (links().begin());
iter != links().end(); ++iter)
iter->send (m);
}
void pre_step ()
{
for (typename Links::iterator iter (links().begin());
iter != links().end(); ++iter)
iter->pre_step ();
}
void step ()
{
for (typename Links::iterator iter (links().begin());
iter != links().end(); ++iter)
iter->step ();
}
private:
Links m_links;
};
//------------------------------------------------------------------------------
template <typename PeerContainer>
void iterate (PeerContainer& s)
{
for (typename PeerContainer::iterator iter (s.begin()); iter != s.end();)
{
typename PeerContainer::iterator const cur (iter++);
cur->pre_step();
}
for (typename PeerContainer::iterator iter (s.begin()); iter != s.end();)
{
typename PeerContainer::iterator const cur (iter++);
cur->step();
}
}
//------------------------------------------------------------------------------
template <
typename LogicType
>
class BasicNetwork
{
public:
typedef LogicType Logic;
class Peer
{
public:
explicit Peer (int)
{
}
};
typedef hash_map <Peer, Logic> PeerMap;
BasicNetwork()
{
}
typename PeerMap::iterator emplace ()
{
m_map.emplace (1);
}
private:
PeerMap m_map;
};
//------------------------------------------------------------------------------
class Network2_test : public beast::unit_test::suite
{
public:
class Message : public BasicMessage
{
public:
};
class Peer : public BasicPeer <Peer, Message>
{
public:
bool m_received;
int* m_count;
Peer (int* count)
: m_received (false)
, m_count (count)
{
}
~Peer ()
{
}
void receive (Message const& m)
{
if (m_received)
return;
++*m_count;
m_received = true;
send (m);
}
};
struct PeerLogic
{
};
//--------------------------------------------------------------------------
template <typename PeerContainer>
void make_peers (PeerContainer& s,
typename PeerContainer::size_type n,
int* count)
{
while (n--)
s.emplace_back(count);
}
template <typename RandomType, typename PeerContainer>
void make_connections (
PeerContainer& s,
typename PeerContainer::size_type outDegree,
RandomType r = RandomType())
{
// Turn the PeerContainer into a PeerSequence
typedef typename PeerContainer::pointer pointer;
typedef std::vector <pointer> PeerSequence;
PeerSequence v;
v.reserve (s.size());
for (typename PeerContainer::iterator iter (s.begin());
iter != s.end(); ++iter)
v.push_back (&(*iter));
// Make random connections
typedef typename PeerSequence::size_type size_type;
size_type const n (v.size());
for (typename PeerSequence::iterator iter (v.begin());
iter != v.end(); ++iter)
{
for (size_type i (0); i < outDegree; ++i)
{
for(;;)
{
size_type const j (r.nextInt (n));
// prohibit self connection
if (*iter == v[j])
continue;
// prohibit duplicate connection
if (is_connected (**iter, *v[j]))
continue;
(*iter)->connect (*v [j]);
break;
}
}
}
}
void test1 ()
{
int count (0);
std::vector <Peer> peers;
make_peers (peers, 10000, &count);
make_connections (peers, 3, beast::Random());
peers[0].send (Message ());
for (int i = 0; i < 10; ++i)
{
iterate (peers);
log <<
"count = " << count;
}
pass();
}
void run ()
{
test1 ();
}
};
BEAST_DEFINE_TESTSUITE_MANUAL(Network1,overlay,ripple);
BEAST_DEFINE_TESTSUITE_MANUAL(Network2,overlay,ripple);
}
}

View File

@@ -31,10 +31,12 @@
#include <ripple/app/main/LoadManager.cpp>
#include <ripple/app/misc/CanonicalTXSet.cpp>
#include <ripple/app/misc/SHAMapStoreImp.cpp>
#include <ripple/app/shamap/SHAMap.cpp>
#include <ripple/app/shamap/SHAMapItem.cpp>
#include <ripple/app/shamap/SHAMapSync.cpp>
#include <ripple/app/shamap/SHAMapMissingNode.cpp>
#include <ripple/app/shamap/RadixMapTest.h>
#include <ripple/app/shamap/RadixMapTest.cpp>
#include <ripple/app/shamap/FetchPackTests.cpp>
#include <ripple/app/shamap/tests/FetchPack.test.cpp>
#include <ripple/app/shamap/tests/SHAMap.test.cpp>
#include <ripple/app/shamap/tests/SHAMapSync.test.cpp>

View File

@@ -34,9 +34,11 @@
#include <ripple/basics/impl/ThreadName.cpp>
#include <ripple/basics/impl/Time.cpp>
#include <ripple/basics/impl/UptimeTimer.cpp>
#include <ripple/basics/impl/KeyCache.cpp>
#include <ripple/basics/impl/make_SSLContext.cpp>
#include <ripple/basics/impl/ResolverAsio.cpp>
#include <ripple/basics/impl/TaggedCache.cpp>
#include <ripple/basics/tests/CheckLibraryVersions.test.cpp>
#include <ripple/basics/tests/KeyCache.test.cpp>
#include <ripple/basics/tests/RangeSet.test.cpp>
#include <ripple/basics/tests/StringUtilities.test.cpp>
#include <ripple/basics/tests/TaggedCache.test.cpp>

View File

@@ -25,3 +25,5 @@
#include <ripple/core/impl/LoadMonitor.cpp>
#include <ripple/core/impl/Job.cpp>
#include <ripple/core/impl/JobQueue.cpp>
#include <ripple/core/tests/LoadFeeTrack.test.cpp>

View File

@@ -34,4 +34,6 @@
#include <ripple/crypto/impl/GenerateDeterministicKey.cpp>
#include <ripple/crypto/impl/RandomNumbers.cpp>
#include <ripple/crypto/impl/RFC1751.cpp>
#include <ripple/crypto/tests/CKey.test.cpp>
#include <ripple/crypto/tests/ECDSACanonical.test.cpp>

View File

@@ -42,7 +42,6 @@
#include <ripple/json/impl/json_value.cpp>
#include <ripple/json/impl/json_writer.cpp>
#include <ripple/json/impl/to_string.cpp>
#include <ripple/json/impl/Tests.cpp>
#include <ripple/json/impl/JsonPropertyStream.cpp>
#include <ripple/json/tests/JsonCpp.test.cpp>

View File

@@ -35,6 +35,7 @@
#include <ripple/nodestore/impl/DecodedBlob.h>
#include <ripple/nodestore/impl/EncodedBlob.h>
#include <ripple/nodestore/impl/BatchWriter.h>
#include <ripple/nodestore/backend/HyperDBFactory.h>
#include <ripple/nodestore/backend/HyperDBFactory.cpp>
#include <ripple/nodestore/backend/LevelDBFactory.h>
@@ -63,8 +64,7 @@
#include <ripple/nodestore/impl/Scheduler.cpp>
#include <ripple/nodestore/impl/Task.cpp>
#include <ripple/nodestore/tests/TestBase.h>
#include <ripple/nodestore/tests/BackendTests.cpp>
#include <ripple/nodestore/tests/BasicTests.cpp>
#include <ripple/nodestore/tests/DatabaseTests.cpp>
#include <ripple/nodestore/tests/TimingTests.cpp>
#include <ripple/nodestore/tests/Backend.test.cpp>
#include <ripple/nodestore/tests/Basics.test.cpp>
#include <ripple/nodestore/tests/Database.test.cpp>
#include <ripple/nodestore/tests/Timing.test.cpp>

View File

@@ -32,7 +32,6 @@
#include <ripple/peerfinder/impl/Bootcache.cpp>
#include <ripple/peerfinder/impl/Config.cpp>
#include <ripple/peerfinder/impl/Endpoint.cpp>
#include <ripple/peerfinder/impl/Livecache.cpp>
#include <ripple/peerfinder/impl/Manager.cpp>
#include <ripple/peerfinder/impl/SlotImp.cpp>
#include <ripple/peerfinder/impl/SourceStrings.cpp>
@@ -45,3 +44,5 @@
#include <ripple/peerfinder/sim/NodeSnapshot.h>
#include <ripple/peerfinder/sim/Params.h>
#include <ripple/peerfinder/sim/Tests.cpp>
#include <ripple/peerfinder/tests/Livecache.test.cpp>

View File

@@ -28,7 +28,6 @@
#include <ripple/protocol/impl/ErrorCodes.cpp>
#include <ripple/protocol/impl/HashPrefix.cpp>
#include <ripple/protocol/impl/Indexes.cpp>
#include <ripple/protocol/impl/Issue.cpp>
#include <ripple/protocol/impl/LedgerFormats.cpp>
#include <ripple/protocol/impl/RippleAddress.cpp>
#include <ripple/protocol/impl/Serializer.cpp>
@@ -53,4 +52,10 @@
#include <ripple/protocol/impl/STValidation.cpp>
#include <ripple/protocol/impl/STVector256.cpp>
#include <ripple/protocol/tests/BuildInfo.test.cpp>
#include <ripple/protocol/tests/Issue.test.cpp>
#include <ripple/protocol/tests/RippleAddress.test.cpp>
#include <ripple/protocol/tests/Serializer.test.cpp>
#include <ripple/protocol/tests/STAmount.test.cpp>
#include <ripple/protocol/tests/STObject.test.cpp>
#include <ripple/protocol/tests/STTx.test.cpp>

View File

@@ -29,5 +29,6 @@
#include <ripple/resource/impl/Key.h>
#include <ripple/resource/impl/Kind.h>
#include <ripple/resource/impl/Manager.cpp>
#include <ripple/resource/impl/Tests.cpp>
#include <ripple/resource/impl/Tuning.h>
#include <ripple/resource/tests/Logic.test.cpp>

View File

@@ -103,9 +103,10 @@
#include <ripple/rpc/impl/ParseAccountIds.cpp>
#include <ripple/rpc/impl/TransactionSign.cpp>
#include <ripple/rpc/impl/Coroutine.test.cpp>
#include <ripple/rpc/impl/JsonObject.test.cpp>
#include <ripple/rpc/impl/JsonWriter.test.cpp>
#include <ripple/rpc/impl/Status.test.cpp>
#include <ripple/rpc/impl/WriteJson.test.cpp>
#include <ripple/rpc/impl/Yield.test.cpp>
#include <ripple/rpc/tests/Coroutine.test.cpp>
#include <ripple/rpc/tests/JsonObject.test.cpp>
#include <ripple/rpc/tests/JSONRPC.test.cpp>
#include <ripple/rpc/tests/JsonWriter.test.cpp>
#include <ripple/rpc/tests/Status.test.cpp>
#include <ripple/rpc/tests/WriteJson.test.cpp>
#include <ripple/rpc/tests/Yield.test.cpp>

View File

@@ -23,6 +23,5 @@
#include <ripple/validators/impl/Logic.cpp>
#include <ripple/validators/impl/Manager.cpp>
#include <ripple/validators/impl/StoreSqdb.cpp>
#include <ripple/validators/impl/Tests.cpp>
#include <ripple/validators/tests/Validators.test.cpp>