Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests for freeze/autobridging/discrepancy #420

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 177 additions & 0 deletions test/autobridge-test.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
################################### REQUIRES ###################################

extend = require 'extend'
fs = require 'fs'
assert = require 'assert'
{
Amount
UInt160
Transaction
} = require 'ripple-lib'


testutils = require './testutils'
{
LedgerState
LedgerVerifier
TestAccount
} = require './ledger-state'
{
beast_configured
is_focused_test
pretty_json
server_setup_teardown
skip_or_only
str_ends_with
submit_for_final
} = require './batmans-belt'

#################################### CONFIG ####################################

config = testutils.init_config()

#################################### HELPERS ###################################

make_offer = (remote, account, pays, gets, flag_or_flags) ->
tx = remote.transaction()
tx.offer_create(account, pays, gets)
tx.set_flags(flag_or_flags) if flag_or_flags?
tx

dump_rpc_script = (ledger_state, test_decl) ->
lines = ledger_state.compile_to_rpc_commands()

# Realias etc ;)
# TODO
account = test_decl.offer[0]
[pays, gets, flags] = test_decl.offer[1..]
tx = new Transaction({secrets: {}})
tx.offer_create(account, pays, gets)
tx.set_flags(flags)

tx_json = tx.tx_json
# Account: account
# TransactionType: "OfferCreate"
# TakerPays: pays
# TakerGets: gets

lines += "\nbuild/rippled submit #{account} '#{JSON.stringify tx_json}'"
lines += "\nbuild/rippled ledger_accept\n"
fs.writeFileSync(__dirname + '/../manual-offer-test.sh', lines)

dump_aliased_ledger = (pre_or_post, ledger_state, done) ->
# TODO: generify to post/pre
ledger_state.remote.request_ledger 'validated', {full: true}, (e, m) ->
ledger_dump = ledger_state.pretty_json m.ledger.accountState
fn = __dirname + "/../manual-offer-test-#{pre_or_post}-ledger.json"
fs.writeFileSync(fn, ledger_dump)
done()

################################# TEST FACTORY #################################

make_offer_create_test = (get_context, test_name, test_decl) ->
'''

@get_context {Function}

a getter function, which gets the current context with the ripple-lib remote
etc attached

@test_name {String}

This function will create a `test` using @test_name based on @test_decl

@test_decl {Object}

@pre_ledger
@post_ledger
@offer

'''
test_func = skip_or_only test_name, test
focused_test = is_focused_test test_name

test_func test_name, (done) ->
context = get_context()

remote = context.remote
ledger_state = context.ledger
tx = make_offer(remote, test_decl.offer...)

submit_for_final tx, (m) ->
'assert transaction was successful'
assert.equal m.metadata.TransactionResult, 'tesSUCCESS'

context.ledger.verifier(test_decl.post_ledger).do_verify (errors) ->
this_done = ->
assert Object.keys(errors).length == 0,
"post_ledger errors:\n"+ pretty_json errors
done()

if focused_test
dump_aliased_ledger('post', ledger_state, this_done)
else
this_done()
test_func

ledger_state_setup = (get_context, decls) ->
setup (done) ->
[test_name, test_decl] = decls.shift()

context = get_context()
focused_test = is_focused_test test_name

context.ledger =
new LedgerState(test_decl.pre_ledger, assert, context.remote, config)

if focused_test
dump_rpc_script(context.ledger, test_decl)

context.ledger.setup(
# console.log
->, # noop logging function
->
context.ledger.verifier().do_verify (errors) ->
assert Object.keys(errors).length == 0,
"pre_ledger errors:\n"+ pretty_json errors

if focused_test
dump_aliased_ledger('pre', context.ledger, done)
else
done()
)

############################### TEST DECLARATIONS ##############################

try
offer_create_tests = require("./offer-tests-json")
# console.log offer_create_tests
# offer_create_tests = JSON.parse offer_tests_string
extend offer_create_tests, {}
catch e
console.log e

if beast_configured('RIPPLE_ENABLE_AUTOBRIDGING', '1')
suite_func = suite
else
suite_func = suite.skip

suite_func 'Offer Create Tests', ->
try
get_context = server_setup_teardown()
# tests = ([k,v] for k,v of offer_create_tests)

tests = []
only = false
for k,v of offer_create_tests
f = make_offer_create_test(get_context, k, v)
if not only and f == test.only
only = [[k, v]]
if not str_ends_with k, '_skip'
tests.push [k,v]

# f = make_offer_create_test(get_context, k, v) for [k,v] in tests
ledger_state_setup(get_context, if only then only else tests)
catch e
console.log e

106 changes: 106 additions & 0 deletions test/batmans-belt.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
################################### REQUIRES ###################################

fs = require 'fs'
testutils = require './testutils'

################################### REQUIRES ###################################

exports.pretty_json = (v) -> JSON.stringify(v, undefined, 2)

exports.beast_configured = beast_configured = (k, v) ->
'''

A very naive regex search in $repo_root/src/BeastConfig.h

@k the name of the macro
@v the value as a string expected

@return {Boolean} k's configured value, trimmed, is v

'''
beast_configured.buf ?= fs.readFileSync("#{__dirname}/../src/BeastConfig.h")
pattern = "^#define\\s+#{k}\\s+(.*?)$"
res = (new RegExp(pattern, 'm').exec(beast_configured.buf))
return false if res == null
actual = res[1].trim()
return v == actual

exports.server_setup_teardown = (options) ->
{setup_func, teardown_func, post_setup, server_opts} = options ? {}

context = null
setup_func ?= setup
teardown_func ?= teardown

setup_func (done) ->
context = @
testutils.build_setup(server_opts).call @, ->
if post_setup?
post_setup(context, done)
else
done()

teardown_func (done) ->
testutils.build_teardown().call context, done

# We turn a function to access the `context`, if we returned it now, it
# would be null (DUH ;)
-> context

exports.str_ends_with = ends_with = (s, suffix) ->
~s.indexOf(suffix, s.length - suffix.length)

exports.skip_or_only = (title, test_or_suite) ->
if ends_with title, '_only'
test_or_suite.only
else if ends_with title, '_skip'
test_or_suite.skip
else
test_or_suite

exports.is_focused_test = (test_name) -> ends_with test_name, '_only'

class BailError extends Error
constructor: (@message) ->
@message ?= "Failed test due to relying on prior failed tests"

exports.suite_test_bailer = () ->
bailed = false
bail = (e) -> bailed = true

suiteSetup 'suite_test_bailer', ->
process.on 'uncaughtException', bail

suiteTeardown 'suite_test_bailer', ->
process.removeListener 'uncaughtException', bail

wrapper = (test_func) ->
test = (title, fn) ->
wrapped = (done) ->
if not bailed
fn(done)
else
# We could do this, but it's just noisy
if process.env.BAIL_PASSES
done()
else
done(new BailError)
test_func title, wrapped

test.only = test_func.only
test.skip = test_func.skip

return test

wrapper(global.test)

exports.submit_for_final = (tx, done) ->
'''

This helper submits a transaction, and once it's proposed sends a ledger
accept so the transaction will finalize.

'''
tx.on 'proposed', -> tx.remote.ledger_accept()
tx.on 'final', (m) -> done(m)
tx.submit()
2 changes: 2 additions & 0 deletions test/config-example.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ exports.servers = {
'websocket_port' : 5006,
'websocket_ssl' : false,
'local_sequence' : true,
'trace' : false,
// 'trace' : true,
'local_fee' : true,
// 'validation_seed' : "shhDFVsmS2GSu5vUyZSPXYfj1r79h",
// 'validators' : "n9L8LZZCwsdXzKUN9zoVxs4YznYXZ9hEhsQZY7aVpxtFaSceiyDZ beta",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ The tests are written in a declarative style:
$ signifies an order book rather than account

------------------------------------------------------------------------------
Tests can be written in the 'path-tests.json' file in same directory # <--
Tests can be written in the 'path-tests-json.js' file in same directory # <--
------------------------------------------------------------------------------
"""
#################################### HELPERS ###################################
Expand Down Expand Up @@ -455,8 +455,10 @@ define_suites = (path_finding_cases) ->
A0 = (new TestAccount('A0')).address
assert A0 == 'rBmhuVAvi372AerwzwERGjhLjqkMmAwxX'

path_finding_cases_string = fs.readFileSync(__dirname + "/path-tests.json")
path_finding_cases = JSON.parse path_finding_cases_string
try
path_finding_cases = require('./path-tests-json')
catch e
console.log e

# You need two gateways, same currency. A market maker. A source that trusts one
# gateway and holds its currency, and a destination that trusts the other.
Expand Down
Loading