Integration tests: SSL service, RocksDB in the CI matrix
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cba58d7e25
commit
e30364c21b
4 files changed
+47
-11
No files matched your search
@@ -11,6 +11,7 @@ import base64
|
||||
import json
|
||||
import os
|
||||
import socket
|
||||
import ssl
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
@@ -100,8 +101,10 @@ def scripthash(node, address):
|
||||
class ElectrumClient:
|
||||
'''Newline-delimited JSON-RPC over TCP, one request at a time (notifications are skipped).'''
|
||||
|
||||
def __init__(self, port):
|
||||
def __init__(self, port, ssl_context=None):
|
||||
self.sock = socket.create_connection(('127.0.0.1', port), timeout=30)
|
||||
if ssl_context:
|
||||
self.sock = ssl_context.wrap_socket(self.sock, server_hostname='localhost')
|
||||
self.file = self.sock.makefile('rwb')
|
||||
self.next_id = 0
|
||||
|
||||
@@ -122,6 +125,10 @@ class ElectrumClient:
|
||||
self.sock.close()
|
||||
|
||||
|
||||
# set by the electrumx fixture: the SSL port of the server under test and the certificate it presents
|
||||
SSL_SERVICE = {}
|
||||
|
||||
|
||||
def free_port():
|
||||
with socket.socket() as s:
|
||||
s.bind(('127.0.0.1', 0))
|
||||
@@ -136,11 +143,19 @@ def electrumx(node, wallet):
|
||||
if node.call('getblockcount') < MIN_HEIGHT:
|
||||
node.mine(MIN_HEIGHT - node.call('getblockcount'), miner)
|
||||
port = free_port()
|
||||
ssl_port = free_port()
|
||||
with tempfile.TemporaryDirectory() as db_dir:
|
||||
certfile = os.path.join(db_dir, 'server.crt')
|
||||
keyfile = os.path.join(db_dir, 'server.key')
|
||||
subprocess.run(['openssl', 'req', '-x509', '-newkey', 'rsa:2048', '-nodes', '-days', '1', '-subj', '/CN=localhost',
|
||||
'-addext', 'subjectAltName=DNS:localhost,IP:127.0.0.1', '-keyout', keyfile, '-out', certfile],
|
||||
check=True, capture_output=True)
|
||||
SSL_SERVICE.update(port=ssl_port, certfile=certfile)
|
||||
env = dict(os.environ,
|
||||
COIN='Palladium', NET='regtest',
|
||||
DB_ENGINE=os.environ.get('PLM_TEST_DB_ENGINE', 'leveldb'), DB_DIRECTORY=db_dir,
|
||||
DAEMON_URL=DAEMON_URL, SERVICES=f'tcp://127.0.0.1:{port}',
|
||||
DAEMON_URL=DAEMON_URL, SERVICES=f'tcp://127.0.0.1:{port},ssl://127.0.0.1:{ssl_port}',
|
||||
SSL_CERTFILE=certfile, SSL_KEYFILE=keyfile,
|
||||
PEER_DISCOVERY='off', PEER_ANNOUNCE='', LOG_LEVEL='info')
|
||||
log = open(os.path.join(db_dir, 'electrumx.log'), 'w+')
|
||||
proc = subprocess.Popen([sys.executable, str(REPO_ROOT / 'electrumx_server')], cwd=REPO_ROOT, env=env,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
'''Electrum protocol methods per protocol version, daemon limits and reorgs, against the regtest node (see conftest.py).'''
|
||||
import pytest
|
||||
|
||||
from tests.integration.conftest import ElectrumClient, new_address, scripthash, wait_for
|
||||
import ssl
|
||||
|
||||
from tests.integration.conftest import SSL_SERVICE, ElectrumClient, new_address, scripthash, wait_for
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -60,7 +62,7 @@ def test_daemon_limits_are_reported_as_errors(client):
|
||||
'''The Palladium daemon has no submitpackage and no gettxspendingprevout: clients get an error.
|
||||
If a newer daemon gains them, update CLAUDE.md, README.md and DEPLOY.md and this test.'''
|
||||
negotiate(client, '1.7')
|
||||
with pytest.raises(RuntimeError, match='rejected by network rules'):
|
||||
with pytest.raises(RuntimeError, match='does not support package submission'):
|
||||
client.call('blockchain.transaction.broadcast_package', ['00'])
|
||||
# a subscription would be accepted for an outpoint in the mempool and then close the session at the next block
|
||||
with pytest.raises(RuntimeError, match='outpoint subscriptions are not supported'):
|
||||
@@ -116,3 +118,17 @@ def test_reorg_replaces_blocks(node, wallet, electrumx, client):
|
||||
'the balance after the reorg')
|
||||
history = client.call('blockchain.scripthash.get_history', sh)
|
||||
assert [(h['tx_hash'], h['height']) for h in history] == [(txid, height)]
|
||||
|
||||
|
||||
def test_ssl_service(node, electrumx):
|
||||
'''The SSL port serves the same protocol, with the certificate given by SSL_CERTFILE/SSL_KEYFILE'''
|
||||
context = ssl.create_default_context(cafile=SSL_SERVICE['certfile'])
|
||||
client = ElectrumClient(SSL_SERVICE['port'], context)
|
||||
try:
|
||||
assert negotiate(client, '1.4')[1] == '1.4'
|
||||
assert client.call('blockchain.block.header', 0)
|
||||
finally:
|
||||
client.close()
|
||||
# a client that does not trust the (self-signed) certificate refuses it
|
||||
with pytest.raises(ssl.SSLCertVerificationError):
|
||||
ElectrumClient(SSL_SERVICE['port'], ssl.create_default_context())
|
||||
Reference in new issue
Block a user