Compare commits
No commits in common. "efeabcb4cf28bb743634934683cbd16b4024ec37" and "c9a3877b9248d2a1ec5d02b773dc1b2d72b247ee" have entirely different histories.
efeabcb4cf
...
c9a3877b92
|
@ -1,21 +1,16 @@
|
||||||
FROM ubuntu:jammy
|
FROM ubuntu:focal
|
||||||
|
|
||||||
RUN apt-get update
|
RUN apt-get update
|
||||||
|
|
||||||
RUN apt-get install -yq software-properties-common
|
RUN apt-get install -yq software-properties-common
|
||||||
|
|
||||||
RUN apt-add-repository ppa:purplei2p/i2pd && apt-get update -qq
|
RUN apt-add-repository ppa:purplei2p/i2pd
|
||||||
|
RUN apt-get update
|
||||||
|
|
||||||
RUN apt-get install -yq --no-install-suggests --no-install-recommends \
|
RUN apt-get install -yq --no-install-suggests --no-install-recommends \
|
||||||
python3-dev python3-pip python-is-python3 python3.11-dev python3.11-venv
|
python3-dev python3-pip python3.9 python3.9-dev python3.9-venv sudo i2pd
|
||||||
|
|
||||||
RUN apt-get install -yq --no-install-suggests --no-install-recommends sudo i2pd
|
|
||||||
|
|
||||||
RUN echo 'builder ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
|
RUN echo 'builder ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
|
||||||
|
|
||||||
RUN pip install setuptools wheel
|
RUN python3.9 -m pip install setuptools wheel
|
||||||
RUN pip install --upgrade pip tox virtualenv
|
RUN python3.9 -m pip install --upgrade pip tox virtualenv
|
||||||
|
|
||||||
ADD . .
|
|
||||||
|
|
||||||
CMD .buildbot/ubuntu/test.sh
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
.git
|
|
||||||
.tox
|
|
||||||
dist
|
|
54
.github/workflows/test.yml
vendored
54
.github/workflows/test.yml
vendored
|
@ -1,20 +1,44 @@
|
||||||
name: Testing
|
name: Blind Test
|
||||||
on: [push]
|
|
||||||
|
on: push
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
default:
|
default:
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, macos-latest]
|
||||||
|
python-version: [3.8]
|
||||||
|
include:
|
||||||
|
- os: ubuntu-latest
|
||||||
|
python-version: 3.9
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Install dependencies
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.python-version }}
|
||||||
|
- name: Install python dependencies
|
||||||
run: |
|
run: |
|
||||||
apt-get update
|
python -m pip install --upgrade pip
|
||||||
apt-get install -yq --no-install-suggests --no-install-recommends \
|
pip install wheel
|
||||||
python3-dev python3-pip python3-venv python-is-python3
|
pip install bandit flake8 pylint
|
||||||
pip install setuptools wheel
|
pip install -r requirements.txt
|
||||||
pip install --upgrade pip tox virtualenv
|
python setup.py install
|
||||||
- name: Check out repository code
|
- name: Lint
|
||||||
uses: actions/checkout@v3
|
if: ${{ matrix.os == 'ubuntu-latest' && matrix.python-version == '3.8' }}
|
||||||
- name: Quick lint
|
run: |
|
||||||
run: tox -e lint-basic
|
# stop the build if there are Python syntax errors or undefined names
|
||||||
- name: Run tests
|
flake8 minode --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||||
run: tox
|
flake8 minode --count --statistics
|
||||||
|
pylint minode --exit-zero --rcfile=tox.ini
|
||||||
|
bandit -r --exit-zero -x tests minode
|
||||||
|
- name: Test
|
||||||
|
run: |
|
||||||
|
export PYTHONWARNINGS=all
|
||||||
|
coverage run -a -m tests
|
||||||
|
- name: Summary
|
||||||
|
run: coverage report
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# MiNode
|
# MiNode
|
||||||
|
|
||||||
[![Testing](https://git.bitmessage.org/Bitmessage/MiNode/actions/workflows/test.yml/badge.svg)](https://git.bitmessage.org/Bitmessage/MiNode/actions?workflow=test.yml)
|
[![Quick Test](https://github.com/g1itch/MiNode/actions/workflows/test.yml/badge.svg)](https://github.com/g1itch/MiNode/actions/workflows/test.yml)
|
||||||
|
|
||||||
Python 3 implementation of the Bitmessage protocol. Designed only to route
|
Python 3 implementation of the Bitmessage protocol. Designed only to route
|
||||||
objects inside the network.
|
objects inside the network.
|
||||||
|
|
|
@ -207,13 +207,6 @@ class Connection(threading.Thread):
|
||||||
context.options = (
|
context.options = (
|
||||||
ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3
|
ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3
|
||||||
| ssl.OP_SINGLE_ECDH_USE | ssl.OP_CIPHER_SERVER_PREFERENCE)
|
| ssl.OP_SINGLE_ECDH_USE | ssl.OP_CIPHER_SERVER_PREFERENCE)
|
||||||
# OP_NO_SSL* is deprecated since 3.6
|
|
||||||
try:
|
|
||||||
# TODO: ssl.TLSVersion.TLSv1 is deprecated
|
|
||||||
context.minimum_version = ssl.TLSVersion.TLSv1
|
|
||||||
context.maximum_version = ssl.TLSVersion.TLSv1_2
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.s = context.wrap_socket(
|
self.s = context.wrap_socket(
|
||||||
self.s, server_side=self.server, do_handshake_on_connect=False)
|
self.s, server_side=self.server, do_handshake_on_connect=False)
|
||||||
|
@ -231,14 +224,11 @@ class Connection(threading.Thread):
|
||||||
'Disconnecting from %s:%s. Reason: %s',
|
'Disconnecting from %s:%s. Reason: %s',
|
||||||
self.host_print, self.port, e)
|
self.host_print, self.port, e)
|
||||||
self.status = 'disconnecting'
|
self.status = 'disconnecting'
|
||||||
if isinstance(e, ssl.SSLError): # pylint: disable=no-member
|
break
|
||||||
logging.debug('ssl.SSLError reason: %s', e.reason)
|
|
||||||
shared.node_pool.discard((self.host, self.port))
|
|
||||||
return
|
|
||||||
self.tls = True
|
self.tls = True
|
||||||
logging.debug(
|
logging.debug(
|
||||||
'Established TLS connection with %s:%s (%s)',
|
'Established TLS connection with %s:%s',
|
||||||
self.host_print, self.port, self.s.version())
|
self.host_print, self.port)
|
||||||
|
|
||||||
def _send_message(self, m):
|
def _send_message(self, m):
|
||||||
if isinstance(m, message.Message) and m.command == b'object':
|
if isinstance(m, message.Message) and m.command == b'object':
|
||||||
|
@ -266,11 +256,11 @@ class Connection(threading.Thread):
|
||||||
if len(shared.node_pool) > 10:
|
if len(shared.node_pool) > 10:
|
||||||
addr.update({
|
addr.update({
|
||||||
structure.NetAddr(1, a[0], a[1])
|
structure.NetAddr(1, a[0], a[1])
|
||||||
for a in random.sample(tuple(shared.node_pool), 10)})
|
for a in random.sample(shared.node_pool, 10)})
|
||||||
if len(shared.unchecked_node_pool) > 10:
|
if len(shared.unchecked_node_pool) > 10:
|
||||||
addr.update({
|
addr.update({
|
||||||
structure.NetAddr(1, a[0], a[1])
|
structure.NetAddr(1, a[0], a[1])
|
||||||
for a in random.sample(tuple(shared.unchecked_node_pool), 10)})
|
for a in random.sample(shared.unchecked_node_pool, 10)})
|
||||||
if len(addr) != 0:
|
if len(addr) != 0:
|
||||||
self.send_queue.put(message.Addr(addr))
|
self.send_queue.put(message.Addr(addr))
|
||||||
|
|
||||||
|
@ -284,7 +274,7 @@ class Connection(threading.Thread):
|
||||||
# We limit size of inv messaged to 10000 entries
|
# We limit size of inv messaged to 10000 entries
|
||||||
# because they might time out
|
# because they might time out
|
||||||
# in very slow networks (I2P)
|
# in very slow networks (I2P)
|
||||||
pack = random.sample(tuple(to_send), 10000)
|
pack = random.sample(to_send, 10000)
|
||||||
self.send_queue.put(message.Inv(pack))
|
self.send_queue.put(message.Inv(pack))
|
||||||
to_send.difference_update(pack)
|
to_send.difference_update(pack)
|
||||||
else:
|
else:
|
||||||
|
@ -456,7 +446,7 @@ class Connection(threading.Thread):
|
||||||
logging.info(
|
logging.info(
|
||||||
'Queued %s vectors to get', len(self.vectors_to_get))
|
'Queued %s vectors to get', len(self.vectors_to_get))
|
||||||
if len(self.vectors_to_get) > 64:
|
if len(self.vectors_to_get) > 64:
|
||||||
pack = random.sample(tuple(self.vectors_to_get), 64)
|
pack = random.sample(self.vectors_to_get, 64)
|
||||||
self.send_queue.put(message.GetData(pack))
|
self.send_queue.put(message.GetData(pack))
|
||||||
self.vectors_requested.update({
|
self.vectors_requested.update({
|
||||||
vector: time.time() for vector in pack
|
vector: time.time() for vector in pack
|
||||||
|
@ -486,7 +476,7 @@ class Connection(threading.Thread):
|
||||||
logging.info(
|
logging.info(
|
||||||
'Preparing to send %s objects', len(self.vectors_to_send))
|
'Preparing to send %s objects', len(self.vectors_to_send))
|
||||||
if len(self.vectors_to_send) > 16:
|
if len(self.vectors_to_send) > 16:
|
||||||
to_send = random.sample(tuple(self.vectors_to_send), 16)
|
to_send = random.sample(self.vectors_to_send, 16)
|
||||||
self.vectors_to_send.difference_update(to_send)
|
self.vectors_to_send.difference_update(to_send)
|
||||||
else:
|
else:
|
||||||
to_send = self.vectors_to_send.copy()
|
to_send = self.vectors_to_send.copy()
|
||||||
|
|
|
@ -98,26 +98,24 @@ class Manager(threading.Thread):
|
||||||
if shared.ip_enabled:
|
if shared.ip_enabled:
|
||||||
if len(shared.unchecked_node_pool) > 16:
|
if len(shared.unchecked_node_pool) > 16:
|
||||||
to_connect.update(random.sample(
|
to_connect.update(random.sample(
|
||||||
tuple(shared.unchecked_node_pool), 16))
|
shared.unchecked_node_pool, 16))
|
||||||
else:
|
else:
|
||||||
to_connect.update(shared.unchecked_node_pool)
|
to_connect.update(shared.unchecked_node_pool)
|
||||||
shared.unchecked_node_pool.difference_update(to_connect)
|
shared.unchecked_node_pool.difference_update(to_connect)
|
||||||
if len(shared.node_pool) > 8:
|
if len(shared.node_pool) > 8:
|
||||||
to_connect.update(random.sample(
|
to_connect.update(random.sample(shared.node_pool, 8))
|
||||||
tuple(shared.node_pool), 8))
|
|
||||||
else:
|
else:
|
||||||
to_connect.update(shared.node_pool)
|
to_connect.update(shared.node_pool)
|
||||||
|
|
||||||
if shared.i2p_enabled:
|
if shared.i2p_enabled:
|
||||||
if len(shared.i2p_unchecked_node_pool) > 16:
|
if len(shared.i2p_unchecked_node_pool) > 16:
|
||||||
to_connect.update(random.sample(
|
to_connect.update(
|
||||||
tuple(shared.i2p_unchecked_node_pool), 16))
|
random.sample(shared.i2p_unchecked_node_pool, 16))
|
||||||
else:
|
else:
|
||||||
to_connect.update(shared.i2p_unchecked_node_pool)
|
to_connect.update(shared.i2p_unchecked_node_pool)
|
||||||
shared.i2p_unchecked_node_pool.difference_update(to_connect)
|
shared.i2p_unchecked_node_pool.difference_update(to_connect)
|
||||||
if len(shared.i2p_node_pool) > 8:
|
if len(shared.i2p_node_pool) > 8:
|
||||||
to_connect.update(random.sample(
|
to_connect.update(random.sample(shared.i2p_node_pool, 8))
|
||||||
tuple(shared.i2p_node_pool), 8))
|
|
||||||
else:
|
else:
|
||||||
to_connect.update(shared.i2p_node_pool)
|
to_connect.update(shared.i2p_node_pool)
|
||||||
|
|
||||||
|
@ -216,18 +214,17 @@ class Manager(threading.Thread):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def pickle_nodes():
|
def pickle_nodes():
|
||||||
if len(shared.node_pool) > 10000:
|
if len(shared.node_pool) > 10000:
|
||||||
shared.node_pool = set(random.sample(
|
shared.node_pool = set(random.sample(shared.node_pool, 10000))
|
||||||
tuple(shared.node_pool), 10000))
|
|
||||||
if len(shared.unchecked_node_pool) > 1000:
|
if len(shared.unchecked_node_pool) > 1000:
|
||||||
shared.unchecked_node_pool = set(random.sample(
|
shared.unchecked_node_pool = set(
|
||||||
tuple(shared.unchecked_node_pool), 1000))
|
random.sample(shared.unchecked_node_pool, 1000))
|
||||||
|
|
||||||
if len(shared.i2p_node_pool) > 1000:
|
if len(shared.i2p_node_pool) > 1000:
|
||||||
shared.i2p_node_pool = set(random.sample(
|
shared.i2p_node_pool = set(
|
||||||
tuple(shared.i2p_node_pool), 1000))
|
random.sample(shared.i2p_node_pool, 1000))
|
||||||
if len(shared.i2p_unchecked_node_pool) > 100:
|
if len(shared.i2p_unchecked_node_pool) > 100:
|
||||||
shared.i2p_unchecked_node_pool = set(random.sample(
|
shared.i2p_unchecked_node_pool = set(
|
||||||
tuple(shared.i2p_unchecked_node_pool), 100))
|
random.sample(shared.i2p_unchecked_node_pool, 100))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(
|
with open(
|
||||||
|
|
|
@ -69,15 +69,12 @@ class TestProcessProto(unittest.TestCase):
|
||||||
|
|
||||||
class TestProcessShutdown(TestProcessProto):
|
class TestProcessShutdown(TestProcessProto):
|
||||||
"""Separate test case for SIGTERM"""
|
"""Separate test case for SIGTERM"""
|
||||||
_wait_time = 30
|
|
||||||
# longer wait time because it's not a benchmark
|
|
||||||
|
|
||||||
def test_shutdown(self):
|
def test_shutdown(self):
|
||||||
"""Send to minode SIGTERM and ensure it stopped"""
|
"""Send to minode SIGTERM and ensure it stopped"""
|
||||||
|
# longer wait time because it's not a benchmark
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
self._stop_process(self._wait_time),
|
self._stop_process(20),
|
||||||
'%s has not stopped in %i sec' % (
|
'%s has not stopped in 20 sec' % ' '.join(self._process_cmd))
|
||||||
' '.join(self._process_cmd), self._wait_time))
|
|
||||||
|
|
||||||
|
|
||||||
class TestProcess(TestProcessProto):
|
class TestProcess(TestProcessProto):
|
||||||
|
@ -108,8 +105,8 @@ class TestProcess(TestProcessProto):
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
else:
|
else:
|
||||||
self.fail(
|
self.fail(
|
||||||
'Failed establish at least %i connections in %s sec'
|
'Failed establish at least %s connections in %s sec'
|
||||||
% (int(self._connection_limit / 2), self._wait_time))
|
% (self._connection_limit / 2, self._wait_time))
|
||||||
|
|
||||||
if self._check_limit:
|
if self._check_limit:
|
||||||
continue_check_limit(_time_to_connect)
|
continue_check_limit(_time_to_connect)
|
||||||
|
@ -131,6 +128,7 @@ class TestProcessI2P(TestProcess):
|
||||||
"""Test minode process with --i2p and no IP"""
|
"""Test minode process with --i2p and no IP"""
|
||||||
_process_cmd = ['minode', '--i2p', '--no-ip']
|
_process_cmd = ['minode', '--i2p', '--no-ip']
|
||||||
_connection_limit = 4
|
_connection_limit = 4
|
||||||
|
_wait_time = 120
|
||||||
_listen = True
|
_listen = True
|
||||||
_listening_port = 8448
|
_listening_port = 8448
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user