Changeset View
Changeset View
Standalone View
Standalone View
contrib/devtools/test/update-chainparams-test.py
- This file was added.
Property | Old Value | New Value |
---|---|---|
File Mode | null | 100755 |
#!/usr/bin/env python3 | |||||
# Copyright (c) 2019 The Bitcoin developers | |||||
# Distributed under the MIT software license, see the accompanying | |||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | |||||
from enum import Enum | |||||
from http.server import HTTPServer, BaseHTTPRequestHandler | |||||
import subprocess | |||||
import threading | |||||
import unittest | |||||
class Chain(Enum): | |||||
main = 1 | |||||
test = 2 | |||||
class MockRequestHandler(BaseHTTPRequestHandler): | |||||
chain = None | |||||
def do_GET(self): | |||||
if self.path == '/rest/chaininfo.json': | |||||
self.wfile.write(str('{"chain":"' + self.chain.name + | |||||
'","bestblockhash":"0000000000073b088995d4dac03809c1c647c231523f69e2db99bbfb1c574c44"' | |||||
',"chainwork":"00000000000000000000000000000000000000000000004b3c801b9507361f33"}').encode()) | |||||
elif self.path == '/rest/block/0000000000073b088995d4dac03809c1c647c231523f69e2db99bbfb1c574c44.json': | |||||
# Valid block hash | |||||
self.wfile.write( | |||||
'{"chainwork":"00000000000000000000000000000000000000000000004b3c801b9507361f33"}'.encode()) | |||||
elif self.path == '/rest/block/0000000000073b088995d4dac03809c1c647c231523f69e2db99bbfb1c574c45.json': | |||||
# Valid hash for non-existent block | |||||
self.wfile.write( | |||||
"0000000000073b088995d4dac03809c1c647c231523f69e2db99bbfb1c574c45 not found".encode()) | |||||
elif self.path == '/rest/block/abc.json': | |||||
# Invalid hash | |||||
self.wfile.write("Invalid hash: abc".encode()) | |||||
else: | |||||
self.server.failTest = "Unexpected request sent to mock server: {}".format( | |||||
self.path) | |||||
self.send_response(404) | |||||
return | |||||
self.send_response(200) | |||||
def log_request(self, code): | |||||
# Do not log requests otherwise it messes with the test framework output | |||||
pass | |||||
class MainnetMockRequestHandler(MockRequestHandler): | |||||
chain = Chain.main | |||||
class TestnetMockRequestHandler(MockRequestHandler): | |||||
chain = Chain.test | |||||
def CheckResult(test, args, expectedExitCode, expectedPatch=None): | |||||
# Sanity check that chainparams doesn't have uncommitted changes prior to running the script | |||||
test.assertEqual(1, subprocess.run('git diff-index HEAD | grep "src/chainparams.cpp"', shell=True, stdout=subprocess.PIPE, | |||||
stderr=subprocess.PIPE).returncode, "src/chainparams.cpp cannot have uncommitted changes prior to running this test!") | |||||
try: | |||||
test.assertEqual(expectedExitCode, | |||||
subprocess.run('../update-chainparams.py {}'.format(args), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).returncode, "Incorrect exit code. Expected exit code was {}.".format(expectedExitCode)) | |||||
except: | |||||
raise | |||||
else: | |||||
Fabien: Why don't you want to catch exceptions from this code ? | |||||
jasonbcoxAuthorUnsubmitted Done Inline ActionsExceptions are being re-raised, not ignored. jasonbcox: Exceptions are being re-raised, not ignored. | |||||
# This produces a condensed patch file that removes the line numbers | |||||
# without breaking context. This allows us to test that the patch | |||||
# contents are correct without breaking these tests whenever code is | |||||
# changed elsewhere in the file. | |||||
p = subprocess.Popen( | |||||
'git diff :/src/chainparams.cpp | grep -A 1 "[-] "', shell=True, stdout=subprocess.PIPE) | |||||
FabienUnsubmitted Not Done Inline Actionsgit diff -- :/src/chainparams.cpp, otherwise I get: fatal: ambiguous argument ':/src/chainparams.cpp': both revision and filename Use '--' to separate paths from revisions, like this: 'git <command> [<revision>...] -- [<file>...]' Fabien: `git diff -- :/src/chainparams.cpp`, otherwise I get:
```
fatal: ambiguous argument '… | |||||
(output, err) = p.communicate() | |||||
FabienUnsubmitted Not Done Inline Actionserr is not used, you can remove it Fabien: `err` is not used, you can remove it | |||||
output = output.decode('utf-8') | |||||
if expectedPatch is None: | |||||
test.assertEqual('', output) | |||||
else: | |||||
test.assertEqual(expectedPatch, output) | |||||
finally: | |||||
# Cleanup changes to chainparams | |||||
subprocess.run('git checkout HEAD :/src/chainparams.cpp', | |||||
FabienUnsubmitted Not Done Inline Actionsgit checkout HEAD -- :/src/chainparams.cpp Fabien: `git checkout HEAD -- :/src/chainparams.cpp` | |||||
shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |||||
class MockHTTPServer(HTTPServer): | |||||
timeout = 1 | |||||
failTest = None | |||||
def __init__(self, addr, handler, test): | |||||
self.test = test | |||||
super(HTTPServer, self).__init__(addr, handler) | |||||
def handle_timeout(self): | |||||
self.test.fail("Request timed out.") | |||||
class MainnetTests(unittest.TestCase): | |||||
maxDiff = None | |||||
def setUp(self): | |||||
self.expectedPatch = ('--- a/src/chainparams.cpp\n' | |||||
'+++ b/src/chainparams.cpp\n' | |||||
'--\n' | |||||
'- "000000000000000000000000000000000000000000eff3c3a458ba78bf184946");\n' | |||||
'+ "00000000000000000000000000000000000000000000004b3c801b9507361f33");\n' | |||||
'--\n' | |||||
'- "0000000000000000023b7cce03f549ba13097b7f9dba787e8b7e7e9f231e0463");\n' | |||||
'+ "0000000000073b088995d4dac03809c1c647c231523f69e2db99bbfb1c574c44");\n') | |||||
self.server = MockHTTPServer( | |||||
('', 8332), MainnetMockRequestHandler, self) | |||||
threading.Thread(target=self.server.serve_forever, daemon=True).start() | |||||
def tearDown(self): | |||||
self.server.shutdown() | |||||
self.server.server_close() | |||||
if self.server.failTest is not None: | |||||
self.fail(self.server.failTest) | |||||
def test_help(self): | |||||
CheckResult(self, '-h', 0) | |||||
CheckResult(self, '-t -h', 0) | |||||
def test_mainnet_args_on_mainnet(self): | |||||
CheckResult(self, '', 0, self.expectedPatch) | |||||
CheckResult(self, '-a localhost', 0, self.expectedPatch) | |||||
CheckResult(self, '-a notlocalhost', 1) | |||||
CheckResult(self, '-p 9999', 1) | |||||
CheckResult(self, '-p 8332', 0, self.expectedPatch) | |||||
CheckResult(self, '-a localhost -p 8332', 0, self.expectedPatch) | |||||
CheckResult(self, '-a notlocalhost -p 8332', 1) | |||||
CheckResult(self, '-b abc', 2) | |||||
CheckResult( | |||||
self, '-b 0000000000073b088995d4dac03809c1c647c231523f69e2db99bbfb1c574c45', 2) | |||||
CheckResult( | |||||
self, '-b 0000000000073b088995d4dac03809c1c647c231523f69e2db99bbfb1c574c44', 0, self.expectedPatch) | |||||
def test_testnet_args_on_mainnet(self): | |||||
CheckResult(self, '-t', 1) | |||||
CheckResult(self, '-t -a localhost', 1) | |||||
CheckResult(self, '-t -a notlocalhost', 1) | |||||
CheckResult(self, '-t -p 9999', 1) | |||||
CheckResult(self, '-t -p 8332', 3) | |||||
CheckResult(self, '-t -a localhost -p 8332', 3) | |||||
CheckResult(self, '-t -a notlocalhost -p 8332', 1) | |||||
CheckResult(self, '-t -p 8332 -b abc', 3) | |||||
CheckResult( | |||||
self, '-t -p 8332 -b 0000000000073b088995d4dac03809c1c647c231523f69e2db99bbfb1c574c45', 3) | |||||
CheckResult( | |||||
self, '-t -p 8332 -b 0000000000073b088995d4dac03809c1c647c231523f69e2db99bbfb1c574c44', 3) | |||||
class TestnetTests(unittest.TestCase): | |||||
maxDiff = None | |||||
def setUp(self): | |||||
self.expectedPatch = ('--- a/src/chainparams.cpp\n' | |||||
'+++ b/src/chainparams.cpp\n' | |||||
'--\n' | |||||
'- "00000000000000000000000000000000000000000000004ec11c53d25a577f28");\n' | |||||
'+ "00000000000000000000000000000000000000000000004b3c801b9507361f33");\n' | |||||
'--\n' | |||||
'- "000000000000001b564c7e20d8f002203a6b7029f440edece8c7b2e549b8202f");\n' | |||||
'+ "0000000000073b088995d4dac03809c1c647c231523f69e2db99bbfb1c574c44");\n') | |||||
self.server = MockHTTPServer( | |||||
('', 18332), TestnetMockRequestHandler, self) | |||||
threading.Thread(target=self.server.serve_forever, daemon=True).start() | |||||
def tearDown(self): | |||||
self.server.shutdown() | |||||
self.server.server_close() | |||||
def test_help(self): | |||||
CheckResult(self, '-h', 0) | |||||
CheckResult(self, '-t -h', 0) | |||||
def test_mainnet_args_on_testnet(self): | |||||
CheckResult(self, '', 1) | |||||
CheckResult(self, '-a localhost', 1) | |||||
CheckResult(self, '-a notlocalhost', 1) | |||||
CheckResult(self, '-p 99999', 1) | |||||
CheckResult(self, '-p 18332', 3) | |||||
CheckResult(self, '-a localhost -p 18332', 3) | |||||
CheckResult(self, '-a notlocalhost -p 18332', 1) | |||||
CheckResult(self, '-p 18332 -b abc', 3) | |||||
CheckResult( | |||||
self, '-p 18332 -b 0000000000073b088995d4dac03809c1c647c231523f69e2db99bbfb1c574c45', 3) | |||||
CheckResult( | |||||
self, '-p 18332 -b 0000000000073b088995d4dac03809c1c647c231523f69e2db99bbfb1c574c44', 3) | |||||
def test_testnet_args_on_mainnet(self): | |||||
CheckResult(self, '-t', 0, self.expectedPatch) | |||||
CheckResult(self, '-t -a localhost', 0, self.expectedPatch) | |||||
CheckResult(self, '-t -a notlocalhost', 1) | |||||
CheckResult(self, '-t -p 99999', 1) | |||||
CheckResult(self, '-t -p 18332', 0, self.expectedPatch) | |||||
CheckResult(self, '-t -a localhost -p 18332', 0, self.expectedPatch) | |||||
CheckResult(self, '-t -a notlocalhost -p 18332', 1) | |||||
CheckResult(self, '-t -b abc', 2) | |||||
CheckResult( | |||||
self, '-t -b 0000000000073b088995d4dac03809c1c647c231523f69e2db99bbfb1c574c45', 2) | |||||
CheckResult( | |||||
self, '-t -b 0000000000073b088995d4dac03809c1c647c231523f69e2db99bbfb1c574c44', 0, self.expectedPatch) | |||||
unittest.main() |
Why don't you want to catch exceptions from this code ?