-
Notifications
You must be signed in to change notification settings - Fork 37.8k
Fix RPC failure testing #9707
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
Fix RPC failure testing #9707
Conversation
qa/rpc-tests/test_framework/util.py
Outdated
RPC call. Set to None if checking the error string is not required | ||
fun (function): the function to call. This should be the name of an RPC. | ||
args*: positional argumemts for the function. | ||
kwargs**: named arguments for the function. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kwds
qa/rpc-tests/test_framework/util.py
Outdated
def assert_raises_jsonrpc(code, message, fun, *args, **kwds): | ||
"""Run an RPC and verify that a specific JSONRPC exception code and message is raised. | ||
|
||
Calls function `fun` with arguments `args` and `kwargs`. Catches a JSONRPCException |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kwds?
qa/rpc-tests/test_framework/util.py
Outdated
message (string), optional: [a substring of] the error string returned by the | ||
RPC call. Set to None if checking the error string is not required | ||
fun (function): the function to call. This should be the name of an RPC. | ||
args*: positional argumemts for the function. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
arguments
Concept ACK |
Future PRs will go over all the qa tests, remove the various broken implementations of this pattern and replace them with calls to assert_raises_jsonrpc().
Concept ACK
This should also prevent the same bugs from being introduced in future because it should now be easier to get this right (by calling assert_raises_jsonrpc()) than get it wrong (by trying to reimplement the pattern and failing)
Hmm, it would be still easy to get it wrong by ignoring (or not
knowing) that assert_raises* exists. You can always type in a useless
`try stuff() except: pass`.
…On Tue, Feb 7, 2017 at 4:22 PM, John Newbery ***@***.***> wrote:
RPC interface testing should include failure test cases (ie where we call an
RPC with parameters that we expect to fail). The failure test cases should
follow this pattern:
try:
nodes.rpcfunction(paramters,...)
except JSONRPCException as exp: #(1) must only catch JSONRPCExceptions
assert_equal(exp.error["code"], EXPECTED_ERROR_CODE) #(2) must verify
error code
assert_equal(exp.error["message"], "Expected error message") #(3) must
verify error message
else:
assert(False) #(4) must fail the test if no JSONRPCException raised
Unfortunately, many of the test cases in qa/rpc-tests get this pattern wrong
and don't actually test what they're supposed to.
Exhibit A:
try:
self.nodes[0].generatetoaddress(1,
'mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ')
except JSONRPCException as e:
assert("Invalid address" not in e.error['message'])
assert("ProcessNewBlock, block not accepted" not in
e.error['message'])
assert("Couldn't create new block" not in e.error['message'])
The call to generatetoaddress() actually succeeds here, but there isn't an
else: clause so the test continues (and none of the code in the except:
branch is executing)
Exhibit B:
try:
tmpl = self.nodes[0].getblocktemplate({})
assert(len(tmpl['transactions']) == 1) # Doesn't include
witness tx
assert(tmpl['sigoplimit'] == 20000)
assert(tmpl['transactions'][0]['hash'] == txid)
assert(tmpl['transactions'][0]['sigops'] == 2)
assert(('!segwit' in tmpl['rules']) or ('segwit' not in
tmpl['rules']))
except JSONRPCException:
# This is an acceptable outcome
pass
The call to getblocktemplate() is raising an exception. Apparently This is
an acceptable outcome, but there's no explanation why. None of the asserts
in the try: branch are being executed. There's also no checking of the error
code/message of the JSONRPCException.
Exhibit C:
assert_raises(JSONRPCException, self.nodes[0].gettransaction, [txid3])
#there must be a expection because the unconfirmed wallettx0 must be gone by
now
This is using the helper function assert_raises() and the comment explains
that the call should fail because the unconfirmed transaction is gone.
There's no testing of the error message or code. In fact, gettransaction()
is failing because it's being called with an array [txid3] instead of a
string txid3.
This PR improves the assert_raises_jsonrpc() to verify error cause and error
message and improves the commenting of that function. Future PRs will go
over all the qa tests, remove the various broken implementations of this
pattern and replace them with calls to assert_raises_jsonrpc().
This should also prevent the same bugs from being introduced in future
because it should now be easier to get this right (by calling
assert_raises_jsonrpc()) than get it wrong (by trying to reimplement the
pattern and failing)
________________________________
You can view, comment on, or merge this pull request online at:
#9707
Commit Summary
Fix RPC failure testing
File Changes
M qa/rpc-tests/rpcnamedargs.py (2)
M qa/rpc-tests/test_framework/util.py (23)
Patch Links:
https://github.com/bitcoin/bitcoin/pull/9707.patch
https://github.com/bitcoin/bitcoin/pull/9707.diff
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Indeed. There's no way to stop people from doing this again in future. I think the best we can hope for is to remove all existing cases where try/except has been used explicitly in individual testcases for JSON RPC error testing. When people come to write new testcases and copy the existing ones, they see the |
cd1fb36
to
1100ca0
Compare
Thanks @paveljanik - all typos fixed |
ACK, but could you replace it with `if code is not None`, so that 0, False,
etc does not equal a wild card for code or message.
…On Tue, Feb 7, 2017 at 6:44 PM, John Newbery ***@***.***> wrote:
Thanks @paveljanik <https://github.com/paveljanik> - all typos fixed
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#9707 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AGGmv-JGLqS-4fvVmfE4CJE7nti8UutGks5raK17gaJpZM4L5oD0>
.
|
1100ca0
to
4ce8d57
Compare
@MarcoFalke done. It now explicitly tests code and message for not being None. |
Make sure that RPC tests are actually checking failures correctly by: - Catching JSON RPC exceptions and verifying the error codes and messages. - Failing the test case if the JSON RPC exception isn't raised.
4245b3f
to
106eb88
Compare
On @TheBlueMatt's suggestion in #9713, I've added a new commit that removes the |
106eb88
to
9db8eec
Compare
Actually, on second thoughts I'll save removing |
OK, sounds good. utACK 9db8eec |
Thanks @TheBlueMatt. @MarcoFalke any chance of merging this small PR? I have a lot of fixes that build off this so it'd be good to have this merged into master. |
utACK 9db8eec. This is refactoring, so can go into 0.14. |
9db8eec Fix RPC failure testing (John Newbery)
awsome. Thanks @MarcoFalke |
late utACK 9db8eec |
9db8eec Fix RPC failure testing (John Newbery)
9db8eec Fix RPC failure testing (John Newbery)
9db8eec Fix RPC failure testing (John Newbery)
…9707) c9bd0f6 Fix RPC failure testing (2 of 2) (John Newbery) Tree-SHA512: df30e6e85abe8c4e12910dc60699f1201e9c243457abd738c1fdeac45f0ff05c674f68619ad9a47c847ec557954007d672cd89d3a9a3b2398dd188d9ffa6dcc9 s/serialize_with_witness/serialize/ miss a tx_submit -> sendrawtransaction dropped dip4 fix prioritise_transaction.py and nulldummy.py
…9707) c9bd0f6 Fix RPC failure testing (2 of 2) (John Newbery) Tree-SHA512: df30e6e85abe8c4e12910dc60699f1201e9c243457abd738c1fdeac45f0ff05c674f68619ad9a47c847ec557954007d672cd89d3a9a3b2398dd188d9ffa6dcc9 s/serialize_with_witness/serialize/ miss a tx_submit -> sendrawtransaction dropped dip4 Fix tests Signed-off-by: Pasta <Pasta@dash.org>
…9707) c9bd0f6 Fix RPC failure testing (2 of 2) (John Newbery) Tree-SHA512: df30e6e85abe8c4e12910dc60699f1201e9c243457abd738c1fdeac45f0ff05c674f68619ad9a47c847ec557954007d672cd89d3a9a3b2398dd188d9ffa6dcc9 s/serialize_with_witness/serialize/ miss a tx_submit -> sendrawtransaction dropped dip4 Fix tests Signed-off-by: Pasta <Pasta@dash.org>
…9707) c9bd0f6 Fix RPC failure testing (2 of 2) (John Newbery) Tree-SHA512: df30e6e85abe8c4e12910dc60699f1201e9c243457abd738c1fdeac45f0ff05c674f68619ad9a47c847ec557954007d672cd89d3a9a3b2398dd188d9ffa6dcc9 s/serialize_with_witness/serialize/ miss a tx_submit -> sendrawtransaction dropped dip4 Fix tests Signed-off-by: Pasta <Pasta@dash.org> Fix file permissions
…9707) c9bd0f6 Fix RPC failure testing (2 of 2) (John Newbery) Tree-SHA512: df30e6e85abe8c4e12910dc60699f1201e9c243457abd738c1fdeac45f0ff05c674f68619ad9a47c847ec557954007d672cd89d3a9a3b2398dd188d9ffa6dcc9 s/serialize_with_witness/serialize/ miss a tx_submit -> sendrawtransaction dropped dip4 Fix tests Signed-off-by: Pasta <Pasta@dash.org> Fix file permissions
…9707) c9bd0f6 Fix RPC failure testing (2 of 2) (John Newbery) Tree-SHA512: df30e6e85abe8c4e12910dc60699f1201e9c243457abd738c1fdeac45f0ff05c674f68619ad9a47c847ec557954007d672cd89d3a9a3b2398dd188d9ffa6dcc9 s/serialize_with_witness/serialize/ miss a tx_submit -> sendrawtransaction dropped dip4 Fix tests Signed-off-by: Pasta <Pasta@dash.org>
…9707) c9bd0f6 Fix RPC failure testing (2 of 2) (John Newbery) Tree-SHA512: df30e6e85abe8c4e12910dc60699f1201e9c243457abd738c1fdeac45f0ff05c674f68619ad9a47c847ec557954007d672cd89d3a9a3b2398dd188d9ffa6dcc9 s/serialize_with_witness/serialize/ miss a tx_submit -> sendrawtransaction dropped dip4 Fix tests Signed-off-by: Pasta <Pasta@dash.org> Fix file permissions
…9707) c9bd0f6 Fix RPC failure testing (2 of 2) (John Newbery) Tree-SHA512: df30e6e85abe8c4e12910dc60699f1201e9c243457abd738c1fdeac45f0ff05c674f68619ad9a47c847ec557954007d672cd89d3a9a3b2398dd188d9ffa6dcc9 s/serialize_with_witness/serialize/ miss a tx_submit -> sendrawtransaction dropped dip4 Fix tests Signed-off-by: Pasta <Pasta@dash.org> Fix file permissions
…9707) c9bd0f6 Fix RPC failure testing (2 of 2) (John Newbery) Tree-SHA512: df30e6e85abe8c4e12910dc60699f1201e9c243457abd738c1fdeac45f0ff05c674f68619ad9a47c847ec557954007d672cd89d3a9a3b2398dd188d9ffa6dcc9 s/serialize_with_witness/serialize/ miss a tx_submit -> sendrawtransaction dropped dip4 Fix tests Signed-off-by: Pasta <Pasta@dash.org> Fix file permissions
RPC interface testing should include failure test cases (ie where we call an RPC with parameters that we expect to fail). The failure test cases should follow this pattern:
Unfortunately, many of the test cases in
qa/rpc-tests
get this pattern wrong and don't actually test what they're supposed to.Exhibit A:
The call to
generatetoaddress()
actually succeeds here, but there isn't anelse:
clause so the test continues (and none of the code in theexcept:
branch is executing)Exhibit B:
The call to
getblocktemplate()
is raising an exception. ApparentlyThis is an acceptable outcome
, but there's no explanation why. None of the asserts in thetry:
branch are being executed. There's also no checking of the error code/message of the JSONRPCException.Exhibit C:
This is using the helper function
assert_raises()
and the comment explains that the call should fail because the unconfirmed transaction is gone. There's no testing of the error message or code. In fact,gettransaction()
is failing because it's being called with an array[txid3]
instead of a stringtxid3
.This PR improves the
assert_raises_jsonrpc()
to verify error cause and error message and improves the commenting of that function. Future PRs will go over all the qa tests, remove the various broken implementations of this pattern and replace them with calls toassert_raises_jsonrpc()
.This should also prevent the same bugs from being introduced in future because it should now be easier to get this right (by calling
assert_raises_jsonrpc()
) than get it wrong (by trying to reimplement the pattern and failing)