Update account_objects test:

* Use Request over json-rpc
* Use lodash to filter irrelevant fields from expectations
* Use LedgerState for state setup
* Test using limit and marker

Conflicts:
	test/account_objects-test.js
This commit is contained in:
Nicholas Dudfield
2015-03-23 15:30:39 +07:00
committed by Vinnie Falco
parent 4d0ed3d857
commit 4c5308da8d
2 changed files with 248 additions and 196 deletions

View File

@@ -10,6 +10,7 @@
"async": "~0.2.9", "async": "~0.2.9",
"deep-equal": "0.0.0", "deep-equal": "0.0.0",
"extend": "~1.2.0", "extend": "~1.2.0",
"lodash": "^3.5.0",
"request": "^2.47.0", "request": "^2.47.0",
"ripple-lib": "0.10.0", "ripple-lib": "0.10.0",
"simple-jsonrpc": "~0.0.2" "simple-jsonrpc": "~0.0.2"

View File

@@ -1,237 +1,288 @@
var async = require("async"); /* -------------------------------- REQUIRES -------------------------------- */
var assert = require('assert');
var http = require("http"); var async = require('async');
var jsonrpc = require("simple-jsonrpc"); var assert = require('assert-diff');
var EventEmitter = require('events').EventEmitter; var lodash = require('lodash');
var Remote = require("ripple-lib").Remote;
var testutils = require("./testutils"); var Remote = require('ripple-lib').Remote;
var Request = require('ripple-lib').Request;
var Account = require('ripple-lib').UInt160;
var testutils = require('./testutils');
var LedgerState = require('./ledger-state').LedgerState;
var config = testutils.init_config(); var config = testutils.init_config();
// We just use equal instead of strictEqual everywhere.
assert.options.strict = true;
function build_setup(options) { /* --------------------------------- HELPERS -------------------------------- */
var setup = testutils.build_setup(options);
return function (done) { function noop() {}
var self = this;
var http_config = config.http_servers["zed"]; function account_objects(remote, account, params, callback) {
if (lodash.isFunction(params)) {
callback = params;
params = null;
}
self.server_events = new EventEmitter; var request = new Request(remote, 'account_objects');
request.message.account = Account.json_rewrite(account);
lodash.forOwn(params || {}, function(v, k) { request.message[k] = v; });
self.server = http.createServer(function (req, res) { request.callback(callback);
// console.log("REQUEST"); }
var input = "";
req.setEncoding('utf8'); function filter_threading_fields(entries) {
return entries.map(function(entry) {
return lodash.omit(entry, ['PreviousTxnID', 'PreviousTxnLgrSeq']);
});
}
req.on('data', function (buffer) { /* ---------------------------------- TEST ---------------------------------- */
// console.log("DATA: %s", buffer);
input = input + buffer;
});
req.on('end', function () { suite('account_objects', function() {
var request = JSON.parse(input); // A declarative description of the ledger
// console.log("REQ: %s", JSON.stringify(request, undefined, 2)); var ledger_state = {
self.server_events.emit('request', request, res); accounts: {
}); // Gateways
G1 : {balance: ["1000.0"]},
G2 : {balance: ["1000.0"]},
req.on('close', function () { }); // Bob has two RippleState and two Offer account objects.
}); bob : {
balance: ["1000.0", "1000/USD/G1",
self.server.listen(http_config.port, http_config.ip, void(0), function () { "1000/USD/G2"],
// console.log("server up: %s %d", http_config.ip, http_config.port); // these offers will be in `Sequence`
setup.call(self, done); offers: [["100.0", "1/USD/bob"],
}); ["100.0", "1/USD/G1"]]
}
}
}; };
};
function build_teardown() { // build_(setup|teardown) utils functions set state on this context var.
var teardown = testutils.build_teardown(); var context = {};
return function (done) { // After setup we bind the remote to `account_objects` helper above.
var self = this; var request_account_objects;
var bob;
var G1;
var G2;
self.server.close(function () { // This runs only once
// console.log("server closed"); suiteSetup(function(done) {
testutils.build_setup().call(context, function() {
request_account_objects = account_objects.bind(null, context.remote);
var ledger = new LedgerState(ledger_state,
assert, context.remote,
config);
teardown.call(self, done); // Get references to the account objects for usage later.
bob = Account.json_rewrite('bob');
G1 = Account.json_rewrite('G1');
G2 = Account.json_rewrite('G2');
// Run the ledger setup util. This compiles the declarative description
// into a series of transactions and executes them.
ledger.setup(noop /*logger*/, function(){
done();
})
}); });
};
};
suite('ACCOUNT_OBJECTS', function() {
var $ = { };
setup(function(done) {
build_setup().call($, done);
}); });
teardown(function(done) { suiteTeardown(function(done) {
build_teardown().call($, done); testutils.build_teardown().call(context, done);
}); });
test('account_objects', function(done) { // With PreviousTxnID, PreviousTxnLgrSeq omitted.
var self = this; var bobs_objects = [
{
"Balance": {
"currency": "USD",
"issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji",
"value": "-1000"
},
"Flags": 131072,
"HighLimit": {
"currency": "USD",
"issuer": "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
"value": "1000"
},
"HighNode": "0000000000000000",
"LedgerEntryType": "RippleState",
"LowLimit": {
"currency": "USD",
"issuer": "r32rQHyesiTtdWFU7UJVtff4nCR5SHCbJW",
"value": "0"
},
"LowNode": "0000000000000000",
"index":
"D89BC239086183EB9458C396E643795C1134963E6550E682A190A5F021766D43"
},
{
"Balance": {
"currency": "USD",
"issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji",
"value": "-1000"
},
"Flags": 131072,
"HighLimit": {
"currency": "USD",
"issuer": "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
"value": "1000"
},
"HighNode": "0000000000000000",
"LedgerEntryType": "RippleState",
"LowLimit": {
"currency": "USD",
"issuer": "r9cZvwKU3zzuZK9JFovGg1JC5n7QiqNL8L",
"value": "0"
},
"LowNode": "0000000000000000",
"index":
"D13183BCFFC9AAC9F96AEBB5F66E4A652AD1F5D10273AEB615478302BEBFD4A4"
},
{
"Account": "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
"BookDirectory":
"50AD0A9E54D2B381288D535EB724E4275FFBF41580D28A925D038D7EA4C68000",
"BookNode": "0000000000000000",
"Flags": 65536,
"LedgerEntryType": "Offer",
"OwnerNode": "0000000000000000",
"Sequence": 4,
"TakerGets": {
"currency": "USD",
"issuer": "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
"value": "1"
},
"TakerPays": "100000000",
"index":
"A984D036A0E562433A8377CA57D1A1E056E58C0D04818F8DFD3A1AA3F217DD82"
},
{
"Account": "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
"BookDirectory":
"B025997A323F5C3E03DDF1334471F5984ABDE31C59D463525D038D7EA4C68000",
"BookNode": "0000000000000000",
"Flags": 65536,
"LedgerEntryType": "Offer",
"OwnerNode": "0000000000000000",
"Sequence": 5,
"TakerGets": {
"currency": "USD",
"issuer": "r32rQHyesiTtdWFU7UJVtff4nCR5SHCbJW",
"value": "1"
},
"TakerPays": "100000000",
"index":
"CAFE32332D752387B01083B60CC63069BA4A969C9730836929F841450F6A718E"
}
]
var rippled_config = testutils.get_server_config(config); test('stepped 1 at a time using marker/limit', function(done) {
var client = jsonrpc.client("http://" + rippled_config.rpc_ip + ":" +
rippled_config.rpc_port); // We step through bob's account objects one at a time by using `limit` and
var http_config = config.http_servers["zed"]; // `marker` and for each object we see, we `push` them onto this array so we
// can later check it against an un`limit`ed request.
var objects_stepped = [];
var steps = [ var steps = [
function (callback) { function first_ripple_state(next) {
self.what = 'Create accounts'; request_account_objects('bob', {limit: 1}, function(e, m) {
assert.ifError(e);
testutils.create_accounts( var objects = m.account_objects;
$.remote, var ripple_state = m.account_objects[0];
'root',
'20000.0',
[ 'mtgox', 'alice', 'bob' ],
callback
);
},
function waitLedgers(callback) { assert.equal(m.limit, 1);
self.what = 'Wait ledger'; assert.equal(objects.length, 1);
assert.equal(ripple_state.LedgerEntryType, 'RippleState');
assert.equal(ripple_state.HighLimit.issuer, bob);
assert.equal(ripple_state.LowLimit.issuer, G1);
$.remote.once('ledger_closed', function() { objects_stepped.push(ripple_state);
callback(); next(null, m.marker);
}); });
$.remote.ledger_accept();
}, },
function verifyBalance(callback) { function second_ripple_state(resume_marker, next) {
self.what = 'Verify balance'; request_account_objects('bob', {limit: 1, marker: resume_marker},
function(e, m) {
assert.ifError(e);
testutils.verify_balance( var objects = m.account_objects;
$.remote, var ripple_state = m.account_objects[0];
[ 'mtgox', 'alice', 'bob' ],
'19999999988',
callback
);
},
function (callback) {
self.what = 'Set transfer rate';
var tx = $.remote.transaction('AccountSet', { assert.equal(m.limit, 1);
account: 'mtgox' assert.equal(objects.length, 1);
assert.equal(ripple_state.LedgerEntryType, 'RippleState');
assert.equal(ripple_state.HighLimit.issuer, bob);
assert.equal(ripple_state.LowLimit.issuer, G2);
objects_stepped.push(ripple_state);
next(null, m.marker);
}); });
tx.transferRate(1.1 * 1e9);
tx.submit(function(err, m) {
assert.ifError(err);
assert.strictEqual(m.engine_result, 'tesSUCCESS');
callback();
});
testutils.ledger_wait($.remote, tx);
}, },
function (callback) { function first_offer(resume_marker, next) {
self.what = 'Set limits'; request_account_objects('bob', {limit: 1, marker: resume_marker},
function(e, m) {
assert.ifError(e);
testutils.credit_limits($.remote, { var objects = m.account_objects;
'alice' : '1000/USD/mtgox', var offer = m.account_objects[0];
'bob' : '1000/USD/mtgox'
}, assert.equal(m.limit, 1);
callback); assert.equal(objects.length, 1);
assert.equal(offer.LedgerEntryType, 'Offer');
assert.equal(offer.TakerGets.issuer, bob);
assert.equal(offer.Account, bob);
objects_stepped.push(offer);
next(null, m.marker);
});
}, },
function (callback) { function second_offer(resume_marker, next) {
self.what = 'Distribute funds'; request_account_objects('bob', {limit: 1, marker: resume_marker},
function(e, m) {
assert.ifError(e);
testutils.payments($.remote, { var objects = m.account_objects;
'mtgox' : [ '100/USD/alice', '50/USD/bob' ] var offer = m.account_objects[0];
},
callback); assert.equal(objects.length, 1);
assert.equal(offer.Account, bob);
assert.equal(offer.LedgerEntryType, 'Offer');
assert.equal(offer.TakerGets.issuer, G1);
assert.equal(m.marker, undefined);
objects_stepped.push(offer);
next();
});
}, },
function (callback) {
self.what = 'Create offer';
// get 4000/XRP pay 10/USD : offer pays 10 USD for 4000 XRP
var tx = $.remote.transaction('OfferCreate', {
account: 'alice',
taker_pays: '4000',
taker_gets: '10/USD/mtgox'
});
tx.submit(function(err, m) {
assert.ifError(err);
assert.strictEqual(m.engine_result, 'tesSUCCESS');
callback();
});
testutils.ledger_wait($.remote, tx);
},
function (callback) {
self.what = "Get account objects.";
client.call('account_objects', [{
"account": "rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn",
"limit": 10
}], function (result) {
// console.log(JSON.stringify(result, undefined, 2));
assert(typeof result === 'object');
assert('account' in result);
assert.deepEqual(result['account'], 'rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn');
assert('account_objects' in result);
var expected = [{
Balance: {
currency: 'USD',
issuer: 'rrrrrrrrrrrrrrrrrrrrBZbvji',
value: '-100'
},
Flags: 131072,
HighLimit: {
currency: 'USD',
issuer: 'rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn',
value: '1000'
},
HighNode: '0000000000000000',
LedgerEntryType: 'RippleState',
LowLimit: {
currency: 'USD',
issuer: 'rGihwhaqU8g7ahwAvTq6iX5rvsfcbgZw6v',
value: '0'
},
LowNode: '0000000000000000',
PreviousTxnID: result['account_objects'][0]['PreviousTxnID'],
PreviousTxnLgrSeq: result['account_objects'][0]['PreviousTxnLgrSeq'],
index: 'DE9CF5B006C8EA021CAB2ED20F01FC9D3260875C885155E7FA7A4DB534E36D8A'
}, {
Account: 'rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn',
BookDirectory:
'AE0A97F385FFE42E3096BA3F98A0173090FE66A3C2482FE0570E35FA931A0000',
BookNode: '0000000000000000',
Flags: 0,
LedgerEntryType: 'Offer',
OwnerNode: '0000000000000000',
PreviousTxnID: result['account_objects'][1]['PreviousTxnID'],
PreviousTxnLgrSeq: result['account_objects'][1]['PreviousTxnLgrSeq'],
Sequence: 3,
TakerGets: {
currency: 'USD',
issuer: 'rGihwhaqU8g7ahwAvTq6iX5rvsfcbgZw6v',
value: '10'
},
TakerPays: '4000',
index: '2A432F386EF28151AF60885CE201CC9331FF494A163D40531A9D253C97E81D61'
}];
assert.deepEqual(result['account_objects'], expected);
callback();
});
}
]; ];
async.waterfall(steps, function(error) { async.waterfall(steps, function (err, result) {
assert(!error, self.what + ': ' + error); assert.ifError(err);
var filtered = filter_threading_fields(objects_stepped);
// Compare against a known/inspected exchaustive response.
assert.deepEqual(filtered, bobs_objects);
done();
});
});
test('unstepped', function(done) {
request_account_objects('bob', function(e, m){
var objects = m.account_objects;
assert.equal(m.marker, undefined);
var filtered = filter_threading_fields(objects);
// Compare against a known/inspected exchaustive response.
assert.deepEqual(filtered, bobs_objects);
done(); done();
}); });
}); });