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

[WIP] [test] Test abortrescan command. #10367

Closed
wants to merge 3 commits into from

Conversation

kallewoof
Copy link
Member

@kallewoof kallewoof commented May 9, 2017

Replaces #10225 as it caused intermittent failures for some users.

Difference: gave up on making a "fast running" test and upped the blockchain size and spam count to avoid the scan finishing before the abort call. Moved test down to extended tests.

Test runs in roughly 2 minutes on my local machine. The blockchain generation part takes roughly 1m20s.

@jnewbery Does this work on your end?

@fanquake fanquake added the Tests label May 9, 2017
Copy link
Contributor

@jnewbery jnewbery left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still flakey for me:

→ ./test_runner.py
WARNING! The following scripts are not being run: ['p2p-fullblocktest.py', 'mempool_spendcoinbase.py', 'fundrawtransaction.py', 'mempool_resurrect_test.py', 'net.py', 'import-rescan.py', 'disconnect_ban.py', 'zapwallettxes.py', 'mempool_limit.py', 'multi_rpc.py', 'preciousblock.py', 'rawtransactions.py', 'importmulti.py', 'blockchain.py', 'bip68-112-113-p2p.py', 'httpbasics.py', 'listsinceblock.py', 'disablewallet.py', 'prioritise_transaction.py', 'invalidtxrequest.py', 'receivedby.py', 'importprunedfunds.py', 'listtransactions.py', 'wallet.py', 'p2p-compactblocks.py', 'wallet-accounts.py', 'signrawtransactions.py', 'nodehandling.py', 'p2p-segwit.py', 'nulldummy.py', 'keypool.py', 'signmessages.py', 'p2p-leaktests.py', 'wallet-hd.py', 'segwit.py', 'merkle_blocks.py', 'reindex.py', 'bumpfee.py', 'mempool_persist.py', 'wallet-dump.py', 'rest.py', 'invalidblockrequest.py', 'getchaintips.py', 'sendheaders.py', 'rpcnamedargs.py', 'proxy_test.py', 'decodescript.py', 'p2p-mempool.py', 'zmq_test.py', 'mempool_reorg.py', 'walletbackup.py', 'maxblocksinflight.py', 'p2p-versionbits-warning.py', 'abandonconflict.py']. Check the test lists in test_runner.py.
...........................................................
import-abort-rescan.py --portseed=3 passed, Duration: 30 s
......
import-abort-rescan.py --portseed=2 failed, Duration: 33 s

stdout:
2017-05-15 18:41:26.479000 TestFramework (INFO): Initializing test directory /tmp/user/1000/test3cj9jwid/166
2017-05-15 18:41:31.202000 TestFramework (INFO): Creating blocks with transactions ...
2017-05-15 18:41:50.352000 TestFramework (INFO): Sending to shared address ...
2017-05-15 18:41:50.422000 TestFramework (INFO): Importing address in background thread ...
2017-05-15 18:41:50.423000 TestFramework (INFO): Attempting to abort scan ...
2017-05-15 18:41:50.437000 TestFramework (INFO): Waiting for import thread to die ...
2017-05-15 18:41:50.538000 TestFramework (ERROR): Assertion failed
Traceback (most recent call last):
  File "/home/ubuntu/bitcoin/test/functional/test_framework/test_framework.py", line 148, in main
    self.run_test()
  File "/home/ubuntu/bitcoin/test/functional/import-abort-rescan.py", line 62, in run_test
    assert_equal(self.nodes[1].getbalance(), balances[1])
  File "/home/ubuntu/bitcoin/test/functional/test_framework/util.py", line 408, in assert_equal
    raise AssertionError("not(%s)" % " == ".join(str(arg) for arg in (thing1, thing2) + args))
AssertionError: not(2475.12300000 == 2475.00000000)
2017-05-15 18:41:50.539000 TestFramework (INFO): Stopping nodes
2017-05-15 18:41:59.604000 TestFramework (WARNING): Not cleaning up dir /tmp/user/1000/test3cj9jwid/166
2017-05-15 18:41:59.604000 TestFramework (ERROR): Test failed. Test logging available at /tmp/user/1000/test3cj9jwid/166/test_framework.log


stderr:


..........
import-abort-rescan.py --portseed=1 failed, Duration: 39 s

stdout:
2017-05-15 18:41:26.476000 TestFramework (INFO): Initializing test directory /tmp/user/1000/test89_pqhmk/167
2017-05-15 18:41:31.503000 TestFramework (INFO): Creating blocks with transactions ...
2017-05-15 18:41:50.205000 TestFramework (INFO): Sending to shared address ...
2017-05-15 18:41:50.333000 TestFramework (INFO): Importing address in background thread ...
2017-05-15 18:41:50.334000 TestFramework (INFO): Attempting to abort scan ...
2017-05-15 18:41:54.919000 TestFramework (ERROR): Assertion failed
Traceback (most recent call last):
  File "/home/ubuntu/bitcoin/test/functional/test_framework/test_framework.py", line 148, in main
    self.run_test()
  File "/home/ubuntu/bitcoin/test/functional/import-abort-rescan.py", line 52, in run_test
    assert abortres # if false, we failed to abort
AssertionError
2017-05-15 18:41:54.919000 TestFramework (INFO): Stopping nodes
2017-05-15 18:42:05.038000 TestFramework (WARNING): Not cleaning up dir /tmp/user/1000/test89_pqhmk/167
2017-05-15 18:42:05.038000 TestFramework (ERROR): Test failed. Test logging available at /tmp/user/1000/test89_pqhmk/167/test_framework.log


stderr:

Try running in parallel with pruning.py to reproduce this.

@kallewoof kallewoof changed the title [test] Test abortrescan command. [WIP] [test] Test abortrescan command. May 16, 2017
@kallewoof
Copy link
Member Author

@jnewbery Sorry for taking so long. Assuming there is a race condition where your side ends up scanning the chain before the abort makes it through, this should definitely fix it, I think. The tests take ~4 mins on my machine, but they're already in extended tests.
If this still shows intermittent failures on your end, I will need to go back to the drawing board, as it has to be something other than the above.

@jnewbery
Copy link
Contributor

This may be specific to my local environment, but if I try to run this test multiple times in parallel, I get failures:

→ ./test_runner.py $(for i in {1..40}; do echo -n 'import-abort-rescan '; done)
Temporary test directory at /tmp/user/1000/bitcoin_test_runner_20170814_134812
WARNING! The following scripts are not being run: ['test_bitcoincli.py', 'bip65-cltv.py', 'wallet-labels.py', 'p2p-fullblocktest2.py', 'bitcoin_cli.py', 'keypool-topup.py', 'wallet-hd-restore.py', 'disablehot.py', 'blocknotify.py', 'getblocktemplate_proposals.py', 'resendwallettransactions.py', 'minchainwork.py', 'walletnotify.py', 'bipdersig.py', 'datalogging.py']. Check the test lists in test_runner.py.
.......................................................................................................................................................................................
import-abort-rescan.py failed, Duration: 97 s

stdout:
2017-08-14 13:48:33.367000 TestFramework (INFO): Initializing test directory /tmp/user/1000/bitcoin_test_runner_20170814_134812/import-abort-rescan_118
2017-08-14 13:48:38.719000 TestFramework (INFO): Creating blocks with transactions ...
2017-08-14 13:48:38.720000 TestFramework (INFO): ...  0%
2017-08-14 13:49:10.376000 TestFramework (ERROR): JSONRPC error
Traceback (most recent call last):
  File "/home/ubuntu/bitcoin/test/functional/test_framework/authproxy.py", line 169, in _get_response
    http_response = self.__conn.getresponse()
  File "/usr/lib/python3.5/http/client.py", line 1197, in getresponse
    response.begin()
  File "/usr/lib/python3.5/http/client.py", line 297, in begin
    version, status, reason = self._read_status()
  File "/usr/lib/python3.5/http/client.py", line 258, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/usr/lib/python3.5/socket.py", line 575, in readinto
    return self._sock.recv_into(b)
socket.timeout: timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ubuntu/bitcoin/test/functional/test_framework/test_framework.py", line 149, in main
    self.run_test()
  File "/home/ubuntu/bitcoin/test/functional/import-abort-rescan.py", line 32, in run_test
    self.nodes[0].sendtoaddress(addr, 0.1)
  File "/home/ubuntu/bitcoin/test/functional/test_framework/coverage.py", line 46, in __call__
    return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
  File "/home/ubuntu/bitcoin/test/functional/test_framework/authproxy.py", line 152, in __call__
    response = self._request('POST', self.__url.path, postdata.encode('utf-8'))
  File "/home/ubuntu/bitcoin/test/functional/test_framework/authproxy.py", line 126, in _request
    return self._get_response()
  File "/home/ubuntu/bitcoin/test/functional/test_framework/authproxy.py", line 176, in _get_response
    self.__conn.timeout)})
test_framework.authproxy.JSONRPCException: 'sendtoaddress' RPC took longer than 30.000000 seconds. Consider using larger timeout for calls that take longer to return. (-344)
2017-08-14 13:49:10.377000 TestFramework (INFO): Stopping nodes
2017-08-14 13:49:10.377000 TestFramework (ERROR): Unable to stop node
Traceback (most recent call last):
  File "/home/ubuntu/bitcoin/test/functional/test_framework/test_framework.py", line 254, in stop_node
    self.nodes[i].stop()
  File "/home/ubuntu/bitcoin/test/functional/test_framework/coverage.py", line 46, in __call__
    return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
  File "/home/ubuntu/bitcoin/test/functional/test_framework/authproxy.py", line 152, in __call__
    response = self._request('POST', self.__url.path, postdata.encode('utf-8'))
  File "/home/ubuntu/bitcoin/test/functional/test_framework/authproxy.py", line 125, in _request
    self.__conn.request(method, path, postdata, headers)
  File "/usr/lib/python3.5/http/client.py", line 1106, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib/python3.5/http/client.py", line 1141, in _send_request
    self.putrequest(method, url, **skips)
  File "/usr/lib/python3.5/http/client.py", line 974, in putrequest
    raise CannotSendRequest(self.__state)
http.client.CannotSendRequest: Request-sent

I'm running this in an ubuntu VM with quite slow spinning disk i/o.

@kallewoof - if you run ./test_runner.py $(for i in {1..40}; do echo -n 'import-abort-rescan '; done) do you get all success?

@maflcko
Copy link
Member

maflcko commented Aug 14, 2017

Just fyi

./test_runner.py $(for i in {1..40}; do echo -n 'import-abort-rescan '; done)

is passing for me on an ssd.

@jnewbery
Copy link
Contributor

Thanks @MarcoFalke - probably caused by my slow disk in that case.

@maflcko
Copy link
Member

maflcko commented Aug 14, 2017

Yeah. Though, I think tests should run and pass on all platforms that are capable of running Bitcoin Core.

Copy link
Contributor

@jnewbery jnewbery left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few nits.

This still seems flakey for me, so should get some wider testing before being merged.

test/functional/import-abort-rescan.py Outdated Show resolved Hide resolved
import time # for sleep

class ImportAbortRescanTest(BitcoinTestFramework):
def __init__(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to override method if you're just calling into super()

self.log.info("Creating blocks with transactions ...")
# Make blocks with spam to cause rescan delay
for i in range(200):
if i % 50 == 0: self.log.info("... %2.f%%", 100.0 / 200.0 * i)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: if block should appear on the next line. Same for the if xxxxx: break lines below

deadres = not importthread.isAlive()
if deadres: break

assert deadres # if false, importthread did not die soon enough
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: prefer assert deadres, "importthread did not die soon enough" (so the error message is delivered to the user)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice.. I didn't know you could do that.

@kallewoof
Copy link
Member Author

@jnewbery your bash line runs fine on my end.

socket.timeout: timed out? Hum.. any ideas on how to fix that one?

from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (assert_equal, get_rpc_proxy)

class ImportAbortRescanTest(BitcoinTestFramework):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems you are not specifying the constructor (__init__). Thus 2 additional nodes are spun up and remain unused.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Fixed.

@jnewbery
Copy link
Contributor

socket.timeout: timed out probably means that running this test 4 times in parallel is too much for my VM, and one of the rpc calls timed out.

Copy link
Contributor

@jnewbery jnewbery left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small nit, but otherwise looks good.

abortres = self.nodes[1].abortrescan()
if abortres:
break
assert abortres # if false, we failed to abort
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could change this to:

assert abortres, "abortrescan call failed"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks!

@maflcko
Copy link
Member

maflcko commented Aug 15, 2017

Please squash your commits if this is no longer WIP

@kallewoof kallewoof changed the title [WIP] [test] Test abortrescan command. [test] Test abortrescan command. Aug 16, 2017
@kallewoof
Copy link
Member Author

@MarcoFalke Squashed & removed '[WIP]' from title.

Copy link
Member

@promag promag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test for when abortrescan returns false.

from test_framework.util import (assert_equal, get_rpc_proxy)

class ImportAbortRescanTest(BitcoinTestFramework):
def __init__(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace with

    def set_test_params(self):
        self.num_nodes = 2


from decimal import Decimal
import threading # for bg importprivkey
import time # for sleep
Copy link
Member

@promag promag Sep 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change and remove comment:

from time import sleep

The same above.


Test rescan behavior of importprivkey when aborted. The test ensures that:
1. The abortrescan command indeed stops the rescan process.
2. Subsequent rescan catches the aborted address UTXO
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, missing period.

"""Test wallet import RPCs.

Test rescan behavior of importprivkey when aborted. The test ensures that:
1. The abortrescan command indeed stops the rescan process.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, use unordered, ie, - The abortrescan ... .

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what the reason for this is. It is easier to refer to a point by number, e.g. "this test is no longer checking the 3rd point mentioned in the comment".

def run_test(self):
# Generate for BTC
self.nodes[0].generate(300)
self.log.info("Creating blocks with transactions ...")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jnewbery wdyt about moving this to util.py, like def generate_load(node, blocks, transactions): or whatever?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it makes sense to move code up into the test_framework directory unless it's being used by more than one test script. I don't see the need here (unless you think you can refactor other test scripts to use this and reduce LOC)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to take advantage of mine_large_block or is that overkill in this context? Might make this test more concise.


from decimal import Decimal
import threading # for bg importprivkey
import sleep from time
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

invalid syntax. Should be from time import sleep

@maxgiraldo
Copy link

maxgiraldo commented Dec 10, 2017

I was able to get most of the tests to pass running in parallel on the following:

  • Ubuntu 16.04.2 LTS x86_64
    1 Core
    2.50GHz CPU
    1GB RAM
    HDD

  • Debian GNU/Linux 8.9 x86_64
    1 Core
    2.80 GHz CPU
    2GB RAM
    HDD

  • MacOS High Sierra x86_64
    2 Cores
    3.3 GHz CPU
    16GB RAM
    SSD
    39/40 tests passed successfully

Error:

stdout:
2017-12-09 22:59:54.102000 TestFramework (INFO): Initializing test directory /var/folders/db/5xcqh4b57l7380mcv8c0kj8r0000gn/T/bitcoin_test_runner_20171209_170923/import-abort-rescan_85
2017-12-09 23:00:20.768000 TestFramework (INFO): Creating blocks with transactions ...
2017-12-09 23:00:20.782000 TestFramework (INFO): ...  0%
2017-12-09 23:02:37.124000 TestFramework (INFO): ... 25%
2017-12-09 23:04:59.728000 TestFramework (INFO): ... 50%
2017-12-09 23:07:31.909000 TestFramework (INFO): ... 75%
2017-12-09 23:10:03.214000 TestFramework (INFO): Sending to shared address ...
2017-12-09 23:10:04.581000 TestFramework (ERROR): Unexpected exception caught during testing
Traceback (most recent call last):
  File "/bitcoin/test/functional/test_framework/test_framework.py", line 120, in main
    self.run_test()
  File "/bitcoin/test/functional/import-abort-rescan.py", line 40, in run_test
    self.sync_all()
  File "/bitcoin/test/functional/test_framework/test_framework.py", line 328, in sync_all
    sync_blocks(group)
  File "/bitcoin/test/functional/test_framework/util.py", line 368, in sync_blocks
    maxheight = max(x.getblockcount() for x in rpc_connections)
  File "/bitcoin/test/functional/test_framework/util.py", line 368, in <genexpr>
    maxheight = max(x.getblockcount() for x in rpc_connections)
  File "/bitcoin/test/functional/test_framework/coverage.py", line 47, in __call__
    return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
  File "/bitcoin/test/functional/test_framework/authproxy.py", line 136, in __call__
    response = self._request('POST', self.__url.path, postdata.encode('utf-8'))
  File "/bitcoin/test/functional/test_framework/authproxy.py", line 106, in _request
    self.__conn.request(method, path, postdata, headers)
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1239, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1285, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1234, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1065, in _send_output
    self.send(chunk)
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 986, in send
    self.sock.sendall(data)
OSError: [Errno 41] Protocol wrong type for socket
2017-12-09 23:10:04.605000 TestFramework (INFO): Stopping nodes
2017-12-09 23:10:04.623000 TestFramework.node1 (ERROR): Unable to stop node.
Traceback (most recent call last):
  File "/bitcoin/test/functional/test_framework/test_node.py", line 125, in stop_node
    self.stop()
  File "/bitcoin/test/functional/test_framework/coverage.py", line 47, in __call__
    return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
  File "/bitcoin/test/functional/test_framework/authproxy.py", line 136, in __call__
    response = self._request('POST', self.__url.path, postdata.encode('utf-8'))
  File "/bitcoin/test/functional/test_framework/authproxy.py", line 106, in _request
    self.__conn.request(method, path, postdata, headers)
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1239, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1250, in _send_request
    self.putrequest(method, url, **skips)
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1108, in putrequest
    raise CannotSendRequest(self.__state)
http.client.CannotSendRequest: Request-sent

stderr:
Traceback (most recent call last):
  File "/bitcoin/test/functional/import-abort-rescan.py", line 77, in <module>
    ImportAbortRescanTest().main()
  File "/bitcoin/test/functional/test_framework/test_framework.py", line 143, in main
    self.stop_nodes()
  File "/bitcoin/test/functional/test_framework/test_framework.py", line 277, in stop_nodes
    node.wait_until_stopped()
  File "/bitcoin/test/functional/test_framework/test_node.py", line 151, in wait_until_stopped
    wait_until(self.is_node_stopped, timeout=timeout)
  File "/bitcoin/test/functional/test_framework/util.py", line 222, in wait_until
    assert_greater_than(timeout, time.time())
  File "/bitcoin/test/functional/test_framework/util.py", line 42, in assert_greater_than
    raise AssertionError("%s <= %s" % (str(thing1), str(thing2)))
AssertionError: 1512861065.40589 <= 1512861065.4063418

@kallewoof
Copy link
Member Author

@maxgiraldo Thanks for testing! I tried on same mac set up (except more cores) doing

./test_runner.py $(for i in {1..40}; do echo -n 'import-abort-rescan '; done)

and it is working on my end. What command are you using to run the tests?

@maxgiraldo
Copy link

@kallewoof No problem! I'm using ./test_runner.py $(for i in {1..40}; do echo -n 'import-abort-rescan '; done) as well. I ran the tests again on Mac about three more times and got the same error, but only on the last run.

@kallewoof
Copy link
Member Author

@maxgiraldo After running it for a long time I managed to reproduce. Looking into it now.

@kallewoof
Copy link
Member Author

Hum. I can't reproduce this without running for hours. It feels like something is being exhausted, triggering the issue, but even after running for several hours I don't see any spikes in resource usage and drive has 100 GB free. @jnewbery any thoughts on why "OSError: [Errno 41] Protocol wrong type for socket" would happen occasionally for

    return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)

(test_framework/coverage.py#46)?

@maxgiraldo
Copy link

maxgiraldo commented Dec 13, 2017

@kallewoof Seems to be a MacOS/OS X-specific kernel issue, which throws the error code EPROTOTYPE when you attempt to do a TCP send syscall while a socket is not yet connected or is in the process of being torn down.*

Source Code
*Source

@jnewbery
Copy link
Contributor

Hmmm, I've definitely read that blog post before, but I can't remember what exactly the context was!

@maxgiraldo - perhaps you could add additional exception handling here:

except http.client.BadStatusLine as e:

Something like:

        except OSError as e:
            if e.errno == 42:
                # EPROTOTYPE - OS X issue: a TCP send syscall while a socket is
                # not yet connected or is in the process of being torn down.
                self.__conn.close()
                self.__conn.request(method, path, postdata, headers)
                return self._get_response()
            else:
                raise

You could add a print statement or pdb breakpoint in there to confirm that you can reproduce and that this fixes this:

        except OSError as e:
            if e.errno == 42:
                # EPROTOTYPE - OS X issue: a TCP send syscall while a socket is
                import pdb; pbd.set_trace()

Do you think this error is specific to this new test, or are you able to reproduce it on other tests? If it's not specific to this test, perhaps you can open a new issue or PR to track it.

@kallewoof
Copy link
Member Author

I can reproduce as well, but it sometimes takes hours. Will try your patch in a couple hours on my end. I'll push a commit so @maxgiraldo can test it too if he hasn't tried it manually already.

@kallewoof
Copy link
Member Author

Different error now. Something very weird is going on with networking here.

2017-12-18 03:53:15.458000 TestFramework (INFO): Initializing test directory /var/folders/b8/znqr8hj918772gfmd875gzgdd3ypz1/T/bitcoin_test_runner_20171218_125257/import-abort-rescan_635
2017-12-18 03:53:21.588000 TestFramework (INFO): Creating blocks with transactions ...
2017-12-18 03:53:21.592000 TestFramework (INFO): ...  0%
2017-12-18 03:54:49.215000 TestFramework (INFO): ... 25%
2017-12-18 03:56:23.323000 TestFramework (INFO): ... 50%
2017-12-18 03:57:56.488000 TestFramework (INFO): ... 75%
2017-12-18 03:59:29.920000 TestFramework (INFO): Sending to shared address ...
2017-12-18 03:59:30.218000 TestFramework (ERROR): Unexpected exception caught during testing
Traceback (most recent call last):
  File "<dir>/bitcoin/test/functional/test_framework/test_framework.py", line 117, in main
    self.run_test()
  File "<dir>/bitcoin/test/functional/import-abort-rescan.py", line 39, in run_test
    self.sync_all()
  File "<dir>/bitcoin/test/functional/test_framework/test_framework.py", line 320, in sync_all
    sync_blocks(group)
  File "<dir>/bitcoin/test/functional/test_framework/util.py", line 350, in sync_blocks
    maxheight = max(x.getblockcount() for x in rpc_connections)
  File "<dir>/bitcoin/test/functional/test_framework/util.py", line 350, in <genexpr>
    maxheight = max(x.getblockcount() for x in rpc_connections)
  File "<dir>/bitcoin/test/functional/test_framework/coverage.py", line 46, in __call__
    return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
  File "<dir>/bitcoin/test/functional/test_framework/authproxy.py", line 162, in __call__
    response = self._request('POST', self.__url.path, postdata.encode('utf-8'))
  File "<dir>/bitcoin/test/functional/test_framework/authproxy.py", line 126, in _request
    return self._get_response()
  File "<dir>/bitcoin/test/functional/test_framework/authproxy.py", line 179, in _get_response
    http_response = self.__conn.getresponse()
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1331, in getresponse
    response.begin()
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 297, in begin
    version, status, reason = self._read_status()
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 258, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 586, in readinto
    return self._sock.recv_into(b)
ConnectionResetError: [Errno 54] Connection reset by peer
2017-12-18 03:59:30.332000 TestFramework (INFO): Stopping nodes
2017-12-18 03:59:32.775000 TestFramework (WARNING): Not cleaning up dir /var/folders/b8/znqr8hj918772gfmd875gzgdd3ypz1/T/bitcoin_test_runner_20171218_125257/import-abort-rescan_635
2017-12-18 03:59:32.775000 TestFramework (ERROR): Test failed. Test logging available at /var/folders/b8/znqr8hj918772gfmd875gzgdd3ypz1/T/bitcoin_test_runner_20171218_125257/import-abort-rescan_635/test_framework.log

@kallewoof
Copy link
Member Author

Pushed commit with fix in it. This still breaks on my end after running for awhile.

@@ -112,6 +112,16 @@ def _request(self, method, path, postdata):
return self._get_response()
else:
raise
except OSError as e:
if e.errno == 42:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The errno is actually 41; to avoid hardcoding the value, I would use from errno import EPROTOTYPE and then:

if e.errno == EPROTOTYPE:
   ...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, good catch.

@kallewoof
Copy link
Member Author

Connection reset by peer after a shortish while. Very curious.

2017-12-21 01:10:24.464000 TestFramework (INFO): Initializing test directory /var/folders/b8/znqr8hj918772gfmd875gzgdd3ypz1/T/bitcoin_test_runner_20171221_100356/import-abort-rescan_961
2017-12-21 01:10:40.349000 TestFramework (INFO): Creating blocks with transactions ...
2017-12-21 01:10:40.352000 TestFramework (INFO): ...  0%
2017-12-21 01:11:50.257000 TestFramework (INFO): ... 25%
2017-12-21 01:13:02.097000 TestFramework (INFO): ... 50%
2017-12-21 01:14:12.874000 TestFramework (INFO): ... 75%
2017-12-21 01:15:22.978000 TestFramework (INFO): Sending to shared address ...
2017-12-21 01:15:23.566000 TestFramework (ERROR): Unexpected exception caught during testing
Traceback (most recent call last):
  File "/Users/karljohan-alm/workspace/bitcoin-kw/test/functional/test_framework/test_framework.py", line 118, in main
    self.run_test()
  File "/Users/karljohan-alm/workspace/bitcoin-kw/test/functional/import-abort-rescan.py", line 39, in run_test
    self.sync_all()
  File "/Users/karljohan-alm/workspace/bitcoin-kw/test/functional/test_framework/test_framework.py", line 313, in sync_all
    sync_blocks(group)
  File "/Users/karljohan-alm/workspace/bitcoin-kw/test/functional/test_framework/util.py", line 368, in sync_blocks
    maxheight = max(x.getblockcount() for x in rpc_connections)
  File "/Users/karljohan-alm/workspace/bitcoin-kw/test/functional/test_framework/util.py", line 368, in <genexpr>
    maxheight = max(x.getblockcount() for x in rpc_connections)
  File "/Users/karljohan-alm/workspace/bitcoin-kw/test/functional/test_framework/coverage.py", line 47, in __call__
    return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
  File "/Users/karljohan-alm/workspace/bitcoin-kw/test/functional/test_framework/authproxy.py", line 147, in __call__
    response = self._request('POST', self.__url.path, postdata.encode('utf-8'))
  File "/Users/karljohan-alm/workspace/bitcoin-kw/test/functional/test_framework/authproxy.py", line 108, in _request
    return self._get_response()
  File "/Users/karljohan-alm/workspace/bitcoin-kw/test/functional/test_framework/authproxy.py", line 164, in _get_response
    http_response = self.__conn.getresponse()
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1331, in getresponse
    response.begin()
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 297, in begin
    version, status, reason = self._read_status()
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 258, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 586, in readinto
    return self._sock.recv_into(b)
ConnectionResetError: [Errno 54] Connection reset by peer
2017-12-21 01:15:23.570000 TestFramework (INFO): Stopping nodes
2017-12-21 01:15:24.265000 TestFramework (WARNING): Not cleaning up dir /var/folders/b8/znqr8hj918772gfmd875gzgdd3ypz1/T/bitcoin_test_runner_20171221_100356/import-abort-rescan_961
2017-12-21 01:15:24.269000 TestFramework (ERROR): Test failed. Test logging available at /var/folders/b8/znqr8hj918772gfmd875gzgdd3ypz1/T/bitcoin_test_runner_20171221_100356/import-abort-rescan_961/test_framework.log
2017-12-21 01:15:24.270000 TestFramework (ERROR): Hint: Call /Users/karljohan-alm/workspace/bitcoin-kw/test/functional/combine_logs.py '/var/folders/b8/znqr8hj918772gfmd875gzgdd3ypz1/T/bitcoin_test_runner_20171221_100356/import-abort-rescan_961' to consolidate all logs

@kallewoof kallewoof changed the title [test] Test abortrescan command. [WIP] [test] Test abortrescan command. Feb 5, 2018
@laanwj
Copy link
Member

laanwj commented Mar 7, 2018

Closing for now, as this PR seems to be dormant, let me know when you want to pick it up again and I'll reopen.

@laanwj laanwj closed this Mar 7, 2018
@kallewoof kallewoof deleted the test-abort-rescan-2 branch October 17, 2019 08:59
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Dec 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants