Skip to content

Commit 473aefd

Browse files
niftyneiendothermicdev
authored andcommitted
bkpr tests: return actual error data, not just a blank assert failure
It's really hard to tell what on earth went wrong when a coin movement check fails, since we dont' return good error info. Here we replace almost every `assert` with a proper check + error with message to help make debugging easier. cc @rustyrussell Changelog-None: improve failure messages
1 parent 755c807 commit 473aefd

File tree

1 file changed

+63
-27
lines changed

1 file changed

+63
-27
lines changed

tests/utils.py

Lines changed: 63 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ def _dictify(balances):
114114
def check_balance_snaps(n, expected_bals):
115115
snaps = n.rpc.listsnapshots()['balance_snapshots']
116116
for snap, exp in zip(snaps, expected_bals):
117-
assert snap['blockheight'] == exp['blockheight']
117+
if snap['blockheight'] != exp['blockheight']:
118+
raise Exception('Unexpected balance snap blockheight: {} vs {}'.format(_dictify(snap), _dictify(exp)))
118119
if _dictify(snap) != _dictify(exp):
119120
raise Exception('Unexpected balance snap: {} vs {}'.format(_dictify(snap), _dictify(exp)))
120121

@@ -136,20 +137,26 @@ def check_coin_moves(n, account_id, expected_moves, chainparams):
136137

137138
node_id = n.info['id']
138139
acct_moves = [m for m in moves if m['account_id'] == account_id]
140+
# Stash moves for errors, if needed
141+
_acct_moves = acct_moves
139142
for mv in acct_moves:
140143
print("{{'type': '{}', 'credit_msat': {}, 'debit_msat': {}, 'tags': '{}' , ['fees_msat'?: '{}']}},"
141144
.format(mv['type'],
142145
Millisatoshi(mv['credit_msat']).millisatoshis,
143146
Millisatoshi(mv['debit_msat']).millisatoshis,
144147
mv['tags'],
145148
mv['fees_msat'] if 'fees_msat' in mv else ''))
146-
assert mv['version'] == 2
147-
assert mv['node_id'] == node_id
148-
assert mv['timestamp'] > 0
149-
assert mv['coin_type'] == chainparams['bip173_prefix']
149+
if mv['version'] != 2:
150+
raise ValueError(f'version not 2 {mv}')
151+
if mv['node_id'] != node_id:
152+
raise ValueError(f'node_id not: {mv}')
153+
if mv['timestamp'] <= 0:
154+
raise ValueError(f'timestamp invalid: {mv}')
155+
if mv['coin_type'] != chainparams['bip173_prefix']:
156+
raise ValueError(f'coin_type not {chainparams["bip173_prefix"]}: {mv}')
150157
# chain moves should have blockheights
151-
if mv['type'] == 'chain_mvt' and mv['account_id'] != 'external':
152-
assert mv['blockheight'] is not None
158+
if mv['type'] == 'chain_mvt' and mv['account_id'] != 'external' and 'blockheight' not in mv:
159+
raise ValueError(f'blockheight not set: {mv}')
153160

154161
for num, m in enumerate(expected_moves):
155162
# They can group things which are in any order.
@@ -170,13 +177,15 @@ def check_coin_moves(n, account_id, expected_moves, chainparams):
170177
raise ValueError("Unexpected move {}: {} != {}".format(num, acct_moves[0], m))
171178
acct_moves = acct_moves[1:]
172179

173-
assert acct_moves == []
180+
if acct_moves != []:
181+
raise ValueError(f'check_coin_moves failed: still has acct_moves {acct_moves}. exp: {expected_moves}. actual: {_acct_moves}')
174182

175183

176184
def account_balance(n, account_id):
177185
moves = dedupe_moves(n.rpc.call('listcoinmoves_plugin')['coin_moves'])
178186
chan_moves = [m for m in moves if m['account_id'] == account_id]
179-
assert len(chan_moves) > 0
187+
if len(chan_moves) == 0:
188+
raise ValueError(f"No channel moves found for {account_id}. {moves}")
180189
m_sum = Millisatoshi(0)
181190
for m in chan_moves:
182191
m_sum += Millisatoshi(m['credit_msat'])
@@ -201,7 +210,8 @@ def extract_utxos(moves):
201210
for ev in evs:
202211
if ev[0]['vout'] == m['vout']:
203212
ev[1] = m
204-
assert ev[0]['output_msat'] == m['output_msat']
213+
if ev[0]['output_msat'] != m['output_msat']:
214+
raise ValueError(f'output_msat does not match. expected {ev[0]}. actual {m}')
205215
break
206216
return utxos
207217

@@ -246,9 +256,14 @@ def _add_relevant(txid, utxo):
246256

247257

248258
def matchup_events(u_set, evs, chans, tag_list):
249-
assert len(u_set) == len(evs) and len(u_set) > 0
259+
if len(u_set) != len(evs):
260+
raise ValueError(f"utxo-set does not match expected (diff lens). exp {evs}, actual {u_set}")
261+
if len(u_set) == 0:
262+
raise ValueError(f"utxo-set is empty. exp {evs}, actual {u_set}")
250263

251264
txid = u_set[0][0]['utxo_txid']
265+
# Stash the set for logging at end, if error
266+
_u_set = u_set
252267
for ev in evs:
253268
found = False
254269
for u in u_set:
@@ -266,15 +281,17 @@ def matchup_events(u_set, evs, chans, tag_list):
266281
continue
267282

268283
if ev[2] is None:
269-
assert u[1] is None
284+
if u[1] is not None:
285+
raise ValueError(f"Expected unspent utxo. exp {ev}, actual {u}")
270286
found = True
271287
u_set.remove(u)
272288
break
273289

274290
# ugly hack to annotate two possible futures for a utxo
275291
if type(ev[2]) is tuple:
276292
tag = u[1]['tags'] if u[1] else u[1]
277-
assert tag in [x[0] for x in ev[2]]
293+
if tag not in [x[0] for x in ev[2]]:
294+
raise ValueError(f"Unable to find {tag} in event set {ev}")
278295
if not u[1]:
279296
found = True
280297
u_set.remove(u)
@@ -284,18 +301,22 @@ def matchup_events(u_set, evs, chans, tag_list):
284301
# Save the 'spent to' txid in the tag-list
285302
tag_list[x[1]] = u[1]['txid']
286303
else:
287-
assert ev[2] == u[1]['tags']
304+
if ev[2] != u[1]['tags']:
305+
raise ValueError(f"tags dont' match. exp {ev}, actual ({u[1]}) full utxo info: {u}")
288306
# Save the 'spent to' txid in the tag-list
289307
if 'to_miner' not in u[1]['tags']:
290308
tag_list[ev[3]] = u[1]['txid']
291309

292310
found = True
293311
u_set.remove(u)
294312

295-
assert found
313+
if not found:
314+
raise ValueError(f"Unable to find expected event in utxos. exp {ev}, utxos {u_set}")
296315

297316
# Verify we used them all up
298-
assert len(u_set) == 0
317+
if len(u_set) != 0:
318+
raise ValueError(f"Too many utxo events. exp {ev}, actual {_u_set} (extra: {u_set})")
319+
299320
return txid
300321

301322

@@ -316,7 +337,9 @@ def dedupe_moves(moves):
316337

317338

318339
def inspect_check_actual(txids, channel_id, actual, exp):
319-
assert len(actual['outputs']) == len(exp)
340+
if len(actual['outputs']) != len(exp):
341+
raise ValueError(f"actual outputs != exp. exp: {exp}. actual: {actual['outputs']}")
342+
320343
for e in exp:
321344
# find the event in actual that matches
322345
found = False
@@ -330,20 +353,26 @@ def inspect_check_actual(txids, channel_id, actual, exp):
330353
if e[1][0] != a['output_tag']:
331354
continue
332355
if e[2]:
333-
assert e[2][0] == a['spend_tag']
356+
if e[2][0] != a['spend_tag']:
357+
raise ValueError(f'spend_tag mismatch. expected: {e}, actual {a}')
334358
txids.append((e[3], a['spending_txid']))
335-
else:
336-
assert 'spend_tag' not in a
359+
elif 'spend_tag' in a:
360+
raise ValueError(f'{a} contains "spend_tag", expecting {e}')
361+
337362
found = True
338363
break
339-
assert found
364+
if not found:
365+
raise ValueError(f'Unable to find actual tx {a} in expected {exp}')
340366

341367
return txids
342368

343369

344370
def check_inspect_channel(n, channel_id, expected_txs):
345371
actual_txs = n.rpc.bkpr_inspect(channel_id)['txs']
346-
assert len(actual_txs) == len(expected_txs.keys())
372+
# Stash a copy in case we need to print on error/assert at end
373+
_actual_txs = actual_txs
374+
if len(actual_txs) != len(expected_txs.keys()):
375+
raise ValueError(f'count actual_txs != expected exp: {expected_txs}')
347376
# start at the top
348377
exp = list(expected_txs.values())[0]
349378
actual = actual_txs[0]
@@ -360,7 +389,8 @@ def check_inspect_channel(n, channel_id, expected_txs):
360389
if a['txid'] == txid:
361390
actual = a
362391
break
363-
assert actual
392+
if not actual:
393+
raise ValueError(f'No "actual" tx found, looking for {txid}. {actual_txs}')
364394
exp = expected_txs[marker]
365395
inspect_check_actual(txids, channel_id, actual, exp)
366396

@@ -369,8 +399,10 @@ def check_inspect_channel(n, channel_id, expected_txs):
369399
exp_counter += 1
370400

371401
# Did we inspect everything?
372-
assert len(actual_txs) == 0
373-
assert exp_counter == len(expected_txs.keys())
402+
if len(actual_txs) != 0:
403+
raise ValueError(f'Had more txs than expected. expected: {expected_txs}. actual: {_actual_txs}')
404+
if exp_counter != len(expected_txs.keys()):
405+
raise ValueError(f'Had less txs than expected. expected: {expected_txs}. actual txs: {_actual_txs}')
374406

375407

376408
def check_utxos_channel(n, chans, expected, exp_tag_list=None, filter_channel=None):
@@ -382,6 +414,8 @@ def check_utxos_channel(n, chans, expected, exp_tag_list=None, filter_channel=No
382414
if filter_channel:
383415
utxos = utxos_for_channel(utxos, filter_channel)
384416

417+
# Stash for errors, if we get them
418+
_utxos = utxos
385419
for tag, evs in expected.items():
386420
if tag not in tag_list:
387421
u_set = list(utxos.values())[0]
@@ -397,13 +431,15 @@ def check_utxos_channel(n, chans, expected, exp_tag_list=None, filter_channel=No
397431
del utxos[txid]
398432

399433
# Verify that we went through all of the utxos
400-
assert len(utxos) == 0
434+
if len(utxos) != 0:
435+
raise ValueError(f"leftover utxos? expected: {expected}, actual: {_utxos}")
401436

402437
# Verify that the expected tags match the found tags
403438
if exp_tag_list:
404439
for tag, txid in tag_list.items():
405440
if tag in exp_tag_list:
406-
assert exp_tag_list[tag] == txid
441+
if exp_tag_list[tag] != txid:
442+
raise ValueError(f"expected tags txid {exp_tag_list[tag]} != actual {txid}. expected: {exp_tag_list}, actual: {tag_list}")
407443

408444
return tag_list
409445

0 commit comments

Comments
 (0)