diff --git a/modules/ripple_app/basics/ripple_Version.h b/modules/ripple_app/basics/ripple_Version.h index 05cfc437aa..f5fb669e4a 100644 --- a/modules/ripple_app/basics/ripple_Version.h +++ b/modules/ripple_app/basics/ripple_Version.h @@ -14,7 +14,7 @@ // VFALCO TODO Roll this together into ripple_BuildVersion #define SERVER_VERSION_MAJOR 0 #define SERVER_VERSION_MINOR 9 -#define SERVER_VERSION_SUB "-b" +#define SERVER_VERSION_SUB "-c" #define SERVER_NAME "Ripple" #define SV_STRINGIZE(x) SV_STRINGIZE2(x) diff --git a/modules/ripple_app/node/ripple_MemoryBackendFactory.cpp b/modules/ripple_app/node/ripple_MemoryBackendFactory.cpp new file mode 100644 index 0000000000..d0536b3505 --- /dev/null +++ b/modules/ripple_app/node/ripple_MemoryBackendFactory.cpp @@ -0,0 +1,101 @@ +//------------------------------------------------------------------------------ +/* + Copyright (c) 2011-2013, OpenCoin, Inc. +*/ +//============================================================================== + +class MemoryBackendFactory::Backend : public NodeStore::Backend +{ +private: + typedef std::map Map; + +public: + Backend (size_t keyBytes, StringPairArray const& keyValues) + : m_keyBytes (keyBytes) + { + } + + ~Backend () + { + } + + std::string getDataBaseName () + { + return "memory"; + } + + //-------------------------------------------------------------------------- + + NodeObject::pointer retrieve (uint256 const &hash) + { + Map::iterator iter = m_map.find (hash); + + if (iter != m_map.end ()) + return iter->second; + + return NodeObject::pointer (); + } + + bool store (NodeObject::ref object) + { + Map::iterator iter = m_map.find (object->getHash ()); + + if (iter == m_map.end ()) + { + m_map.insert (std::make_pair (object->getHash (), object)); + } + + return true; + } + + bool bulkStore (const std::vector< NodeObject::pointer >& batch) + { + for (int i = 0; i < batch.size (); ++i) + store (batch [i]); + + return true; + } + + void visitAll (FUNCTION_TYPE f) + { + for (Map::const_iterator iter = m_map.begin (); iter != m_map.end (); ++iter) + f (iter->second); + } + + //-------------------------------------------------------------------------- + +private: + size_t const m_keyBytes; + + Map m_map; +}; + +//------------------------------------------------------------------------------ + +MemoryBackendFactory::MemoryBackendFactory () +{ +} + +MemoryBackendFactory::~MemoryBackendFactory () +{ +} + +MemoryBackendFactory& MemoryBackendFactory::getInstance () +{ + static MemoryBackendFactory instance; + + return instance; +} + +String MemoryBackendFactory::getName () const +{ + return "Memory"; +} + +NodeStore::Backend* MemoryBackendFactory::createInstance (StringPairArray const& keyValues) +{ + return new MemoryBackendFactory::Backend (32, keyValues); +} + +//------------------------------------------------------------------------------ + diff --git a/modules/ripple_app/node/ripple_MemoryBackendFactory.h b/modules/ripple_app/node/ripple_MemoryBackendFactory.h new file mode 100644 index 0000000000..5bb4cf2700 --- /dev/null +++ b/modules/ripple_app/node/ripple_MemoryBackendFactory.h @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +/* + Copyright (c) 2011-2013, OpenCoin, Inc. +*/ +//============================================================================== + +#ifndef RIPPLE_MEMORYBACKENDFACTORY_H_INCLUDED +#define RIPPLE_MEMORYBACKENDFACTORY_H_INCLUDED + +/** Factory to produce a RAM based backend for the NodeStore. + + @see NodeStore +*/ +class MemoryBackendFactory : public NodeStore::BackendFactory +{ +private: + class Backend; + + MemoryBackendFactory (); + ~MemoryBackendFactory (); + +public: + static MemoryBackendFactory& getInstance (); + + String getName () const; + + NodeStore::Backend* createInstance (StringPairArray const& keyValues); +}; + +#endif diff --git a/modules/ripple_app/ripple_app.cpp b/modules/ripple_app/ripple_app.cpp index 4660d7caa7..b263b583dc 100644 --- a/modules/ripple_app/ripple_app.cpp +++ b/modules/ripple_app/ripple_app.cpp @@ -103,6 +103,7 @@ namespace ripple #include "node/ripple_NodeObject.h" #include "node/ripple_NodeStore.h" #include "node/ripple_LevelDBBackendFactory.h" +#include "node/ripple_MemoryBackendFactory.h" #include "node/ripple_HyperLevelDBBackendFactory.h" #include "node/ripple_MdbBackendFactory.h" #include "node/ripple_NullBackendFactory.h" @@ -246,6 +247,7 @@ static const uint64 tenTo17m1 = tenTo17 - 1; #include "node/ripple_NodeObject.cpp" #include "node/ripple_NodeStore.cpp" #include "node/ripple_LevelDBBackendFactory.cpp" +#include "node/ripple_MemoryBackendFactory.cpp" #include "node/ripple_HyperLevelDBBackendFactory.cpp" #include "node/ripple_MdbBackendFactory.cpp" #include "node/ripple_NullBackendFactory.cpp" diff --git a/package.json b/package.json index 9b13c2daab..3009ee8227 100644 --- a/package.json +++ b/package.json @@ -10,17 +10,18 @@ }, "dependencies": { - "ripple-lib": "0.7.10", + "ripple-lib": "0.7.18", "async": "~0.1.22", "extend": "~1.1.1", "simple-jsonrpc": "~0.0.1" }, "devDependencies": { - "buster": "~0.6.12" + "buster": "~0.6.12", + "mocha": "~1.12.0" }, "scripts": { - "test": "./node_modules/buster/bin/buster test" + "test": "./node_modules/buster/bin/buster-test" }, "repository": { diff --git a/src/cpp/ripple/ripple_Main.cpp b/src/cpp/ripple/ripple_Main.cpp index 40f8dbf68f..9c4e758546 100644 --- a/src/cpp/ripple/ripple_Main.cpp +++ b/src/cpp/ripple/ripple_Main.cpp @@ -194,8 +194,10 @@ int rippleMain (int argc, char** argv) p.add ("parameters", -1); // These must be added before the Application object is created + NodeStore::addBackendFactory (MemoryBackendFactory::getInstance ()); NodeStore::addBackendFactory (SqliteBackendFactory::getInstance ()); NodeStore::addBackendFactory (LevelDBBackendFactory::getInstance ()); + NodeStore::addBackendFactory (NullBackendFactory::getInstance ()); #if RIPPLE_HYPERLEVELDB_AVAILABLE NodeStore::addBackendFactory (HyperLevelDBBackendFactory::getInstance ()); #endif @@ -243,7 +245,7 @@ int rippleMain (int argc, char** argv) if (HaveSustain () && !iResult && !vm.count ("parameters") && !vm.count ("fg") && !vm.count ("standalone") && !vm.count ("unittest")) { - std::string logMe = DoSustain (theConfig.DEBUG_LOGFILE.c_str()); + std::string logMe = DoSustain (theConfig.DEBUG_LOGFILE.string()); if (!logMe.empty ()) Log (lsWARNING) << logMe; diff --git a/test/account_set-test.js b/test/account_set-test.js index 65352c3524..be89b23259 100644 --- a/test/account_set-test.js +++ b/test/account_set-test.js @@ -7,8 +7,7 @@ var Request = require("ripple-lib").Request; var Server = require("./server").Server; var testutils = require("./testutils"); - -var config = require('ripple-lib').config.load(require('./config')); +var config = testutils.init_config(); // How long to wait for server to start. var serverDelay = 1500; diff --git a/test/account_tx-test.js b/test/account_tx-test.js index 6c7a8babec..56b81c64c4 100644 --- a/test/account_tx-test.js +++ b/test/account_tx-test.js @@ -6,9 +6,8 @@ var Remote = require("ripple-lib").Remote; var Transaction = require("ripple-lib").Transaction; var Server = require("./server").Server; -var testutils = require("./testutils"); - -require('ripple-lib').config.load(require('./config')); +var testutils = require("./testutils"); +var config = testutils.init_config(); buster.testRunner.timeout = 350000; //This is a very long test! diff --git a/test/config-example.js b/test/config-example.js index 45bb945967..4191a745ca 100644 --- a/test/config-example.js +++ b/test/config-example.js @@ -7,11 +7,13 @@ var testconfig = require("./testconfig.js"); exports.accounts = testconfig.accounts; -// Where to find the binary. -exports.rippled = path.resolve("build/rippled"); - exports.server_default = "alpha"; +exports.default_server_config = { + // Where to find the binary. + rippled_path: path.resolve(__dirname, "../build/rippled") +}; + // // Configuration for servers. // @@ -33,6 +35,7 @@ exports.servers = { // 'validation_seed' : "shhDFVsmS2GSu5vUyZSPXYfj1r79h", // 'validators' : "n9L8LZZCwsdXzKUN9zoVxs4YznYXZ9hEhsQZY7aVpxtFaSceiyDZ beta", 'local_signing' : false, + 'node_db': 'type=Memory' } }; diff --git a/test/jsonrpc-test.js b/test/jsonrpc-test.js index c19c2636e1..7a6b9d61dd 100644 --- a/test/jsonrpc-test.js +++ b/test/jsonrpc-test.js @@ -10,7 +10,7 @@ var Server = require("./server").Server; var testutils = require("./testutils"); -var config = require('ripple-lib').config.load(require('./config')); +var config = testutils.init_config(); // How long to wait for server to start. var serverDelay = 1500; diff --git a/test/monitor-test.js b/test/monitor-test.js index 342dd7e4fb..e2ef06a738 100644 --- a/test/monitor-test.js +++ b/test/monitor-test.js @@ -6,8 +6,7 @@ var Remote = require("ripple-lib").Remote; var Server = require("./server").Server; var testutils = require("./testutils"); - -require('ripple-lib').config.load(require('./config')); +var config = testutils.init_config(); buster.testRunner.timeout = 5000; diff --git a/test/offer-test.js b/test/offer-test.js index 6d4af9584f..ed015ab7a6 100644 --- a/test/offer-test.js +++ b/test/offer-test.js @@ -7,9 +7,8 @@ var Remote = require("ripple-lib").Remote; var Transaction = require("ripple-lib").Transaction; var Server = require("./server").Server; -var testutils = require("./testutils"); - -require('ripple-lib').config.load(require('./config')); +var testutils = require("./testutils"); +var config = testutils.init_config(); buster.testRunner.timeout = 5000; @@ -67,7 +66,7 @@ buster.testCase("Offer tests", { } ], function (error) { // console.log("result: error=%s", error); - buster.refute(error); + buster.refute(error, self.what || "Unspecifide Error"); done(); }); @@ -95,7 +94,7 @@ buster.testCase("Offer tests", { buster.assert.equals('tesSUCCESS', m.metadata.TransactionResult); buster.assert(final_create); - if (3 === ++dones) + if (3 === ++dones) done(); }) .submit(); @@ -116,7 +115,7 @@ buster.testCase("Offer tests", { buster.assert.equals('tesSUCCESS', m.metadata.TransactionResult); buster.assert(final_create); - if (3 === ++dones) + if (3 === ++dones) done(); }) .submit(); @@ -146,7 +145,7 @@ buster.testCase("Offer tests", { buster.assert.equals('tesSUCCESS', m.metadata.TransactionResult); buster.assert(final_create); - if (3 === ++dones) + if (3 === ++dones) done(); }) .submit(); @@ -161,7 +160,7 @@ buster.testCase("Offer tests", { } ], function (error) { // console.log("result: error=%s", error); - buster.refute(error); + buster.refute(error, self.what); done(); }); @@ -207,21 +206,23 @@ buster.testCase("Offer tests", { function (done) { var self = this; + var alices_initial_balance = 499946999680; + var bobs_initial_balance = 10199999920; + async.waterfall([ function (callback) { self.what = "Create mtgox account."; - - testutils.payment(self.remote, "root", "mtgox", "1149999730", callback); + testutils.payment(self.remote, "root", "mtgox", 1149999730, callback); }, function (callback) { self.what = "Create alice account."; - testutils.payment(self.remote, "root", "alice", "499946999680", callback); + testutils.payment(self.remote, "root", "alice", alices_initial_balance, callback); }, function (callback) { self.what = "Create bob account."; - testutils.payment(self.remote, "root", "bob", "10199999920", callback); + testutils.payment(self.remote, "root", "bob", bobs_initial_balance, callback); }, function (callback) { self.what = "Set transfer rate."; @@ -286,7 +287,7 @@ buster.testCase("Offer tests", { callback); }, function (callback) { - self.what = "Verify balances."; + self.what = "Verify balances. 1"; testutils.verify_balances(self.remote, { @@ -308,12 +309,36 @@ buster.testCase("Offer tests", { .submit(); }, function (callback) { - self.what = "Verify balances."; + self.what = "Verify balances. 2"; + + var alices_fees, alices_num_transactions, alices_tx_fee_units_total, + alices_tx_fee_units_total, alices_final_balance, + + bobs_fees, bobs_num_transactions, bobs_tx_fee_units_total, + bobs_tx_fee_units_total, bobs_final_balance; + + alices_num_transactions = 3; + alices_tx_fee_units_total = alices_num_transactions * Transaction.fee_units["default"] + alices_tx_fees_total = self.remote.fee_tx(alices_tx_fee_units_total); + alices_final_balance = Amount.from_json(alices_initial_balance) + .subtract(alices_tx_fees_total); + + bobs_num_transactions = 2; + bobs_tx_fee_units_total = bobs_num_transactions * Transaction.fee_units["default"] + bobs_tx_fees_total = self.remote.fee_tx(bobs_tx_fee_units_total); + bobs_final_balance = Amount.from_json(bobs_initial_balance) + .subtract(bobs_tx_fees_total); testutils.verify_balances(self.remote, { - "alice" : [ "-50/USD/mtgox", String(499946999680-3*(Transaction.fees['default'].to_number())) ], - "bob" : [ "2710505431213761e-33/USD/mtgox", String(10199999920-2*(Transaction.fees['default'].to_number())) ], + "alice" : [ "-50/USD/mtgox", alices_final_balance.to_json()], + "bob" : [ "2710505431213761e-33/USD/mtgox", + + bobs_final_balance.to_json() + + // bobs_final_balance.to_json() + // String(10199999920-(self.remote.fee_tx(2*(Transaction.fee_units['default'])))).to_number() + ], }, callback); }, @@ -397,8 +422,9 @@ buster.testCase("Offer tests", { testutils.verify_balances(self.remote, { - "alice" : [ "499/USD/mtgox", String(100000000000+4000000000-2*(Transaction.fees['default'].to_number())) ], - "bob" : [ "1/USD/mtgox", String(100000000000-4000000000-2*(Transaction.fees['default'].to_number())) ], + // "bob" : [ "1/USD/mtgox", String(100000000000-4000000000-(Number(self.remote.fee_tx(Transaction.fee_units['default'] * 2).to_json()))) ], + "bob" : [ "1/USD/mtgox", String(100000000000-4000000000-(self.remote.fee_tx(Transaction.fee_units['default'] * 2).to_number())) ], + "alice" : [ "499/USD/mtgox", String(100000000000+4000000000-(self.remote.fee_tx(Transaction.fee_units['default'] * 2).to_number())) ], }, callback); }, @@ -482,8 +508,8 @@ buster.testCase("Offer tests", { testutils.verify_balances(self.remote, { - "alice" : [ "499/USD/mtgox", String(100000000000+3000000000-2*(Transaction.fees['default'].to_number())) ], - "bob" : [ "1/USD/mtgox", String(100000000000-3000000000-2*(Transaction.fees['default'].to_number())) ], + "alice" : [ "499/USD/mtgox", String(100000000000+3000000000-(self.remote.fee_tx(2*(Transaction.fee_units['default'])).to_number())) ], + "bob" : [ "1/USD/mtgox", String(100000000000-3000000000-(self.remote.fee_tx(2*(Transaction.fee_units['default'])).to_number())) ], }, callback); }, @@ -561,7 +587,7 @@ buster.testCase("Offer tests", { self.what = "Create crossing offer."; self.remote.transaction() - .offer_create("bob", "1/USD/mtgox", "3000.0") // + .offer_create("bob", "1/USD/mtgox", "3000.0") // .on('proposed', function (m) { // console.log("PROPOSED: offer_create: %s", JSON.stringify(m)); @@ -574,8 +600,8 @@ buster.testCase("Offer tests", { testutils.verify_balances(self.remote, { - "alice" : [ "499/USD/mtgox", String(100000000000+3000000000-2*(Transaction.fees['default'].to_number())) ], - "bob" : [ "1/USD/mtgox", String(100000000000-3000000000-1*(Transaction.fees['default'].to_number())) ], + "alice" : [ "499/USD/mtgox", String(100000000000+3000000000-(self.remote.fee_tx(2*(Transaction.fee_units['default'])).to_number())) ], + "bob" : [ "1/USD/mtgox", String(100000000000-3000000000-(self.remote.fee_tx(1*(Transaction.fee_units['default'])).to_number())) ], }, callback); }, @@ -676,7 +702,7 @@ buster.testCase("Offer tests", { }, ], function (error) { // console.log("result: error=%s", error); - buster.refute(error); + buster.refute(error, self.what); if (error) done(); }); @@ -771,7 +797,7 @@ buster.testCase("Offer tests", { }, ], function (error) { // console.log("result: error=%s", error); - buster.refute(error); + buster.refute(error, self.what); if (error) done(); }); }, @@ -849,7 +875,7 @@ buster.testCase("Offer tests", { } ], function (error) { // console.log("result: error=%s", error); - buster.refute(error); + buster.refute(error, self.what); done(); }); @@ -947,7 +973,7 @@ buster.testCase("Offer tests", { testutils.verify_balances(self.remote, { - "alice" : [ "0/USD/mtgox", String(10000000000+500-2*(Transaction.fees['default'].to_number())) ], + "alice" : [ "0/USD/mtgox", String(10000000000+500-(self.remote.fee_tx(2*(Transaction.fee_units['default'])).to_number())) ], "bob" : "100/USD/mtgox", }, callback); @@ -1110,7 +1136,7 @@ buster.testCase("Offer tests", { testutils.verify_balances(self.remote, { - "alice" : [ "160/USD/mtgox", String(10000000000+200-2*(Transaction.fees['default'].to_number())) ], + "alice" : [ "160/USD/mtgox", String(10000000000+200-(self.remote.fee_tx(2*(Transaction.fee_units['default'])).to_number())) ], "bob" : "40/USD/mtgox", }, callback); @@ -1152,7 +1178,7 @@ buster.testCase("Offer tests", { testutils.verify_balances(self.remote, { - "alice" : [ "100/USD/mtgox", String(10000000000+200+300-4*(Transaction.fees['default'].to_number())) ], + "alice" : [ "100/USD/mtgox", String(10000000000+200+300-(self.remote.fee_tx(4*(Transaction.fee_units['default'])).to_number())) ], "bob" : "100/USD/mtgox", }, callback); @@ -1456,15 +1482,43 @@ buster.testCase("Offer tests 3", { // Provide micro amounts to compensate for fees to make results round nice. self.what = "Create accounts."; - testutils.create_accounts(self.remote, "root", "350.000020", ["alice", "bob", "mtgox"], callback); + // Alice has 3 entries in the ledger, via trust lines + var max_owner_count = 3; // + // We start off with a + var reserve_amount = self.remote.reserve(max_owner_count); + // console.log("\n"); + // console.log("reserve_amount reserve(max_owner_count=%s): %s", max_owner_count, reserve_amount.to_human()); + + // this.tx_json.Fee = this.remote.fee_tx(this.fee_units()).to_json(); + + // 1 for each trust limit == 3 (alice < mtgox/amazon/bitstamp) + // 1 for payment == 4 + var max_txs_per_user = 4; + + // We don't have access to the tx object[s] created below so we + // just dig into fee_units straight away + var fee_units_for_all_txs = ( Transaction.fee_units["default"] * + max_txs_per_user ); + + starting_xrp = reserve_amount.add(self.remote.fee_tx(fee_units_for_all_txs)) + // console.log("starting_xrp after %s fee units: ", fee_units_for_all_txs, starting_xrp.to_human()); + + starting_xrp = starting_xrp.add(Amount.from_json('100.0')); + // console.log("starting_xrp adding 100 xrp to sell", starting_xrp.to_human()); + + testutils.create_accounts(self.remote, + "root", + starting_xrp.to_json(), + ["alice", "bob", "mtgox", "amazon", "bitstamp"], + callback); }, function (callback) { self.what = "Set limits."; testutils.credit_limits(self.remote, { - "alice" : "1000/USD/mtgox", - "bob" : "1000/USD/mtgox", + "alice" : ["1000/USD/mtgox", "1000/USD/amazon","1000/USD/bitstamp"], + "bob" : ["1000/USD/mtgox", "1000/USD/amazon"], }, callback); }, @@ -1485,7 +1539,6 @@ buster.testCase("Offer tests 3", { .on('proposed', function (m) { // console.log("proposed: offer_create: %s", json.stringify(m)); callback(m.result !== 'tesSUCCESS'); - seq_carol = m.tx_json.sequence; }) .submit(); @@ -1521,14 +1574,14 @@ buster.testCase("Offer tests 3", { testutils.verify_balances(self.remote, { - "alice" : [ "100/USD/mtgox", "250.0" ], - "bob" : "400/USD/mtgox", + "alice" : [ "100/USD/mtgox", "350.0"], + "bob" : ["400/USD/mtgox", ], }, callback); }, ], function (error) { // console.log("result: error=%s", error); - buster.refute(error); + buster.refute(error, self.what); done(); }); @@ -1635,7 +1688,7 @@ buster.testCase("Offer tests 3", { }, ], function (error) { // console.log("result: error=%s", error); - buster.refute(error); + buster.refute(error, self.what); done(); }); @@ -1651,14 +1704,16 @@ buster.testCase("Offer tfSell", { "basic sell" : function (done) { var self = this; - var final_create; + var final_create, seq_carol; async.waterfall([ function (callback) { // Provide micro amounts to compensate for fees to make results round nice. self.what = "Create accounts."; - testutils.create_accounts(self.remote, "root", "350.000020", ["alice", "bob", "mtgox"], callback); + var req_amount = self.remote.reserve(1).add(self.remote.fee_tx(20)).add(100000000); + testutils.create_accounts(self.remote, "root", req_amount.to_json(), + ["alice", "bob", "mtgox"], callback); }, function (callback) { self.what = "Set limits."; @@ -1687,19 +1742,21 @@ buster.testCase("Offer tfSell", { .set_flags('Sell') // Should not matter at all. .on('proposed', function (m) { // console.log("proposed: offer_create: %s", json.stringify(m)); - callback(m.result !== 'tesSUCCESS'); + if (m.result !== 'tesSUCCESS') { + throw new Error("Bob's OfferCreate tx did not succeed: "+m.result); + } else callback(null); seq_carol = m.tx_json.sequence; }) .submit(); }, function (callback) { - // Alice has 350 fees - a reserve of 50 = 250 reserve = 100 available. + // Alice has 350 + fees - a reserve of 50 = 250 reserve = 100 available. // Ask for more than available to prove reserve works. self.what = "Create offer alice."; self.remote.transaction() - .offer_create("alice", "100/USD/mtgox", "100.0") + .offer_create("alice", "200/USD/mtgox", "200.0") .set_flags('Sell') // Should not matter at all. .on('proposed', function (m) { // console.log("proposed: offer_create: %s", json.stringify(m)); @@ -1732,7 +1789,7 @@ buster.testCase("Offer tfSell", { }, ], function (error) { // console.log("result: error=%s", error); - buster.refute(error); + buster.refute(error, self.what); done(); }); @@ -1741,14 +1798,19 @@ buster.testCase("Offer tfSell", { "2x sell exceed limit" : function (done) { var self = this; - var final_create; + var final_create, seq_carol; async.waterfall([ function (callback) { // Provide micro amounts to compensate for fees to make results round nice. self.what = "Create accounts."; - - testutils.create_accounts(self.remote, "root", "350.000020", ["alice", "bob", "mtgox"], callback); + + var starting_xrp = self.amount_for({ + ledger_entries: 1, + default_transactions: 2, + extra: '100.0' + }); + testutils.create_accounts(self.remote, "root", starting_xrp, ["alice", "bob", "mtgox"], callback); }, function (callback) { self.what = "Set limits."; @@ -1779,7 +1841,6 @@ buster.testCase("Offer tfSell", { .on('proposed', function (m) { // console.log("proposed: offer_create: %s", json.stringify(m)); callback(m.result !== 'tesSUCCESS'); - seq_carol = m.tx_json.sequence; }) .submit(); @@ -1797,7 +1858,9 @@ buster.testCase("Offer tfSell", { .set_flags('Sell') .on('proposed', function (m) { // console.log("proposed: offer_create: %s", json.stringify(m)); - callback(m.result !== 'tesSUCCESS'); + if (m.result !== 'tesSUCCESS') { + callback(new Error("Alice's OfferCreate didn't succeed: "+m.result)); + } else callback(null); seq_carol = m.tx_json.sequence; }) @@ -1826,7 +1889,7 @@ buster.testCase("Offer tfSell", { }, ], function (error) { // console.log("result: error=%s", error); - buster.refute(error); + buster.refute(error, self.what); done(); }); @@ -1848,8 +1911,14 @@ buster.testCase("Client Issue #535", { function (callback) { // Provide micro amounts to compensate for fees to make results round nice. self.what = "Create accounts."; + + var starting_xrp = self.amount_for({ + ledger_entries: 1, + default_transactions: 2, + extra: '100.0' + }); - testutils.create_accounts(self.remote, "root", "350.000020", ["alice", "bob", "mtgox"], callback); + testutils.create_accounts(self.remote, "root", starting_xrp, ["alice", "bob", "mtgox"], callback); }, function (callback) { self.what = "Set limits."; @@ -1922,7 +1991,7 @@ buster.testCase("Client Issue #535", { ], function (error) { if (error) console.log("result: %s: error=%s", self.what, error); - buster.refute(error); + buster.refute(error, self.what); done(); }); diff --git a/test/path-test.js b/test/path-test.js index 31aea5f4a6..3616122b3b 100644 --- a/test/path-test.js +++ b/test/path-test.js @@ -6,9 +6,9 @@ var Remote = require("ripple-lib").Remote; var Transaction = require("ripple-lib").Transaction; var Server = require("./server").Server; -var testutils = require("./testutils"); +var testutils = require("./testutils"); +var config = testutils.init_config(); -require('ripple-lib').config.load(require('./config')); buster.testRunner.timeout = 5000; diff --git a/test/remote-test.js b/test/remote-test.js index 841f3df0d0..0b390e3005 100644 --- a/test/remote-test.js +++ b/test/remote-test.js @@ -5,8 +5,7 @@ var Remote = require("ripple-lib").Remote; var Server = require("./server.js").Server; var testutils = require("./testutils.js"); - -var config = require('ripple-lib').config.load(require('./config')); +var config = testutils.init_config(); // How long to wait for server to start. var serverDelay = 1500; // XXX Not implemented. diff --git a/test/send-test.js b/test/send-test.js index dd98c41bc4..15d363ddf5 100644 --- a/test/send-test.js +++ b/test/send-test.js @@ -6,8 +6,7 @@ var Remote = require("ripple-lib").Remote; var Server = require("./server").Server; var testutils = require("./testutils"); - -var config = require('ripple-lib').config.load(require('./config')); +var config = testutils.init_config(); // How long to wait for server to start. var serverDelay = 1500; diff --git a/test/server-test.js b/test/server-test.js index 434563c166..b2800e1d31 100644 --- a/test/server-test.js +++ b/test/server-test.js @@ -1,6 +1,9 @@ -var buster = require("buster"); +var buster = require("buster"); +var extend = require("extend"); +var Server = require("./server").Server; + var testutils = require("./testutils"); -var Server = require("./server").Server; +var config = testutils.init_config(); // How long to wait for server to start. // var serverDelay = 1500; @@ -9,19 +12,22 @@ var alpha; buster.testCase("Standalone server startup", { "server start and stop" : function (done) { - alpha = Server.from_config("alpha", false); //ADD ,true for verbosity + var cfg = extend({}, config.default_server_config, + config.servers.alpha); - alpha - .on('started', function () { - alpha - .on('stopped', function () { - buster.assert(true); + alpha = Server.from_config("alpha", cfg); - done(); - }) - .stop(); + alpha + .on('started', function () { + alpha + .on('stopped', function () { + buster.assert(true); + + done(); }) - .start(); + .stop(); + }) + .start(); } }); diff --git a/test/server.js b/test/server.js index f47189cafd..cbdf68475d 100644 --- a/test/server.js +++ b/test/server.js @@ -22,7 +22,6 @@ var path = require("path"); var util = require("util"); var EventEmitter = require('events').EventEmitter; -var config = require("./config"); var nodeutils = require("./nodeutils"); // Create a server object @@ -58,8 +57,8 @@ var Server = function (name, config, verbose) { util.inherits(Server, EventEmitter); -Server.from_config = function (name, verbose) { - return new Server(name, config.servers[name], verbose); +Server.from_config = function (name, config, verbose) { + return new Server(name, config, verbose); }; Server.prototype.on = function (e, c) { @@ -106,7 +105,7 @@ Server.prototype._serverSpawnSync = function() { // Spawn in standalone mode for now. this.child = child.spawn( - config.rippled, + this.config.rippled_path, args, { cwd: this.serverPath(), @@ -116,7 +115,10 @@ Server.prototype._serverSpawnSync = function() { if (!this.quiet) console.log("server: start %s: %s --conf=%s", - this.child.pid, config.rippled, args.join(" "), this.configPath()); + this.child.pid, + this.config.rippled_path, + args.join(" "), + this.configPath()); // By default, just log exits. this.child.on('exit', function(code, signal) { diff --git a/test/testutils.js b/test/testutils.js index 53bc3c8560..0e06d28992 100644 --- a/test/testutils.js +++ b/test/testutils.js @@ -1,10 +1,10 @@ -var async = require("async"); +var async = require("async"); +var extend = require("extend"); -var Amount = require("ripple-lib").Amount; -var Remote = require("ripple-lib").Remote; -var Server = require("./server").Server; - -var config = require('ripple-lib').config.load(require('./config')); +var Amount = require("ripple-lib").Amount; +var Remote = require("ripple-lib").Remote; +var Server = require("./server").Server; +var Transaction = require("ripple-lib").Transaction; var account_dump = function (remote, account, callback) { var self = this; @@ -64,6 +64,8 @@ var account_dump = function (remote, account, callback) { * @param host {String} Identifier for the host configuration to be used. */ var build_setup = function (opts, host) { + var config = get_config(); + opts = opts || {}; // Normalize options @@ -74,6 +76,18 @@ var build_setup = function (opts, host) { return function (done) { var self = this; + + self.compute_fees_amount_for_txs = function(txs) { + var fee_units = Transaction.fee_units["default"] * txs; + return self.remote.fee_tx(fee_units); + }; + + self.amount_for = function(options) { + var reserve = self.remote.reserve(options.ledger_entries || 0); + var fees = self.compute_fees_amount_for_txs(options.default_transactions || 0) + return reserve.add(fees) + .add(options.extra || 0); + }; host = host || config.server_default; @@ -87,8 +101,12 @@ var build_setup = function (opts, host) { function runServerStep(callback) { if (opts.no_server) return callback(); + var server_config = extend({}, config.default_server_config, + config.servers[host]); + data.server = Server - .from_config(host, !!opts.verbose_server) + .from_config(host, server_config, + !!opts.verbose_server) .on('started', callback) .on('exited', function () { // If know the remote, tell it server is gone. @@ -114,6 +132,7 @@ var build_setup = function (opts, host) { * @param host {String} Identifier for the host configuration to be used. */ var build_teardown = function (host) { + var config = get_config(); return function (done) { host = host || config.server_default; @@ -160,7 +179,9 @@ var create_accounts = function (remote, src, amount, accounts, callback) { .on('proposed', function (m) { // console.log("proposed: %s", JSON.stringify(m)); - callback(m.result != 'tesSUCCESS'); + if (m.result != 'tesSUCCESS') { + callback(new Error("Payment to create account did not succeed.")); + } else callback(null); }) .on('error', function (m) { // console.log("error: %s", JSON.stringify(m)); @@ -203,6 +224,24 @@ var credit_limit = function (remote, src, amount, callback) { } }; +function get_config() { + var cfg = require('./config-example'); + + // See if the person testing wants to override the configuration by creating a + // file called test/config.js. + try { + cfg = extend({}, cfg, require('./config')); + } catch (e) { } + + return cfg; +} + +function init_config() { + var cfg = get_config(); + + return require('ripple-lib').config.load(cfg); +} + var verify_limit = function (remote, src, amount, callback) { assert(4 === arguments.length); @@ -214,6 +253,7 @@ var verify_limit = function (remote, src, amount, callback) { } else { + // console.log("_m", _m.length, _m); // console.log("verify_limit: parsed: %s", JSON.stringify(_m, undefined, 2)); var _account_limit = _m[1]; var _quality_in = _m[2]; @@ -470,6 +510,8 @@ exports.build_teardown = build_teardown; exports.create_accounts = create_accounts; exports.credit_limit = credit_limit; exports.credit_limits = credit_limits; +exports.get_config = get_config; +exports.init_config = init_config; exports.ledger_close = ledger_close; exports.payment = payment; exports.payments = payments; diff --git a/test/websocket-test.js b/test/websocket-test.js index e0a9704984..2415288f02 100644 --- a/test/websocket-test.js +++ b/test/websocket-test.js @@ -1,18 +1,35 @@ -var buster = require("buster"); +var buster = require("buster"); +var extend = require("extend"); -var Server = require("./server").Server; -var Remote = require("ripple-lib").Remote; +var Server = require("./server").Server; +var Remote = require("ripple-lib").Remote; -var config = require('ripple-lib').config.load(require('./config')); +var testutils = require('./testutils'); +var config = testutils.init_config(); buster.testRunner.timeout = 5000; +var server; buster.testCase("WebSocket connection", { 'setUp' : - function (done) { if (config.servers.alpha.no_server) done(); else server = Server.from_config("alpha").on('started', done).start(); }, + function (done) { + var cfg = extend({}, config.default_server_config, + config.servers.alpha); + if (cfg.no_server) { + done(); + } else { + server = Server.from_config("alpha", cfg).on('started', done).start(); + } + }, 'tearDown' : - function (done) { if (config.servers.alpha.no_server) done(); else server.on('stopped', done).stop(); }, + function (done) { + if (config.servers.alpha.no_server) { + done(); + } else { + server.on('stopped', done).stop(); + } + }, "websocket connect and disconnect" : function (done) {