Merge branch 'windows-test' into ci-testing-windows

This commit is contained in:
Dmitri Bogomolov 2021-07-06 20:38:29 +03:00
commit 05acf7ad37
Signed by untrusted user: g1itch
GPG Key ID: 720A756F18DEED13
8 changed files with 82 additions and 69 deletions

View File

@ -18,5 +18,5 @@ install:
- export PYTHONWARNINGS=all - export PYTHONWARNINGS=all
script: script:
- python checkdeps.py - python checkdeps.py
- xvfb-run src/bitmessagemain.py -t - python src/bitmessagemain.py -t
- python -bm tests - python -bm tests

View File

@ -1,5 +1,6 @@
coverage coverage
python_prctl python_prctl;platform_system=="Linux"
psutil psutil
pycrypto pycrypto
six six
xvfbwrapper;platform_system=="Linux"

View File

@ -21,7 +21,6 @@ app_dir = pathmagic.setup()
import depends import depends
depends.check_dependencies() depends.check_dependencies()
import ctypes
import getopt import getopt
import multiprocessing import multiprocessing
# Used to capture a Ctrl-C keypress so that Bitmessage can shutdown gracefully. # Used to capture a Ctrl-C keypress so that Bitmessage can shutdown gracefully.
@ -30,7 +29,6 @@ import socket
import threading import threading
import time import time
import traceback import traceback
from struct import pack
import defaults import defaults
import shared import shared
@ -39,7 +37,7 @@ import state
from bmconfigparser import BMConfigParser from bmconfigparser import BMConfigParser
from debug import logger # this should go before any threads from debug import logger # this should go before any threads
from helper_startup import ( from helper_startup import (
adjustHalfOpenConnectionsLimit, start_proxyconfig) adjustHalfOpenConnectionsLimit, fixSocket, start_proxyconfig)
from inventory import Inventory from inventory import Inventory
# Network objects and threads # Network objects and threads
from network import ( from network import (
@ -54,67 +52,6 @@ from threads import (
addressGenerator, objectProcessor, singleCleaner, singleWorker, sqlThread) addressGenerator, objectProcessor, singleCleaner, singleWorker, sqlThread)
def _fixSocket():
if sys.platform.startswith('linux'):
socket.SO_BINDTODEVICE = 25
if not sys.platform.startswith('win'):
return
# Python 2 on Windows doesn't define a wrapper for
# socket.inet_ntop but we can make one ourselves using ctypes
if not hasattr(socket, 'inet_ntop'):
addressToString = ctypes.windll.ws2_32.WSAAddressToStringA
def inet_ntop(family, host):
"""Converting an IP address in packed
binary format to string format"""
if family == socket.AF_INET:
if len(host) != 4:
raise ValueError("invalid IPv4 host")
host = pack("hH4s8s", socket.AF_INET, 0, host, "\0" * 8)
elif family == socket.AF_INET6:
if len(host) != 16:
raise ValueError("invalid IPv6 host")
host = pack("hHL16sL", socket.AF_INET6, 0, 0, host, 0)
else:
raise ValueError("invalid address family")
buf = "\0" * 64
lengthBuf = pack("I", len(buf))
addressToString(host, len(host), None, buf, lengthBuf)
return buf[0:buf.index("\0")]
socket.inet_ntop = inet_ntop
# Same for inet_pton
if not hasattr(socket, 'inet_pton'):
stringToAddress = ctypes.windll.ws2_32.WSAStringToAddressA
def inet_pton(family, host):
"""Converting an IP address in string format
to a packed binary format"""
buf = "\0" * 28
lengthBuf = pack("I", len(buf))
if stringToAddress(str(host),
int(family),
None,
buf,
lengthBuf) != 0:
raise socket.error("illegal IP address passed to inet_pton")
if family == socket.AF_INET:
return buf[4:8]
elif family == socket.AF_INET6:
return buf[8:24]
else:
raise ValueError("invalid address family")
socket.inet_pton = inet_pton
# These sockopts are needed on for IPv6 support
if not hasattr(socket, 'IPPROTO_IPV6'):
socket.IPPROTO_IPV6 = 41
if not hasattr(socket, 'IPV6_V6ONLY'):
socket.IPV6_V6ONLY = 27
def signal_handler(signum, frame): def signal_handler(signum, frame):
"""Single handler for any signal sent to pybitmessage""" """Single handler for any signal sent to pybitmessage"""
process = multiprocessing.current_process() process = multiprocessing.current_process()
@ -151,7 +88,7 @@ class Main(object):
def start(self): def start(self):
"""Start main application""" """Start main application"""
# pylint: disable=too-many-statements,too-many-branches,too-many-locals # pylint: disable=too-many-statements,too-many-branches,too-many-locals
_fixSocket() fixSocket()
adjustHalfOpenConnectionsLimit() adjustHalfOpenConnectionsLimit()
config = BMConfigParser() config = BMConfigParser()

View File

@ -3,12 +3,15 @@ Startup operations.
""" """
# pylint: disable=too-many-branches,too-many-statements # pylint: disable=too-many-branches,too-many-statements
import ctypes
import logging import logging
import os import os
import platform import platform
import socket
import sys import sys
import time import time
from distutils.version import StrictVersion from distutils.version import StrictVersion
from struct import pack
import sys import sys
if sys.version_info[0] == 3: if sys.version_info[0] == 3:
@ -307,6 +310,67 @@ def adjustHalfOpenConnectionsLimit():
state.maximumNumberOfHalfOpenConnections = 9 if is_limited else 64 state.maximumNumberOfHalfOpenConnections = 9 if is_limited else 64
def fixSocket():
if sys.platform.startswith('linux'):
socket.SO_BINDTODEVICE = 25
if not sys.platform.startswith('win'):
return
# Python 2 on Windows doesn't define a wrapper for
# socket.inet_ntop but we can make one ourselves using ctypes
if not hasattr(socket, 'inet_ntop'):
addressToString = ctypes.windll.ws2_32.WSAAddressToStringA
def inet_ntop(family, host):
"""Converting an IP address in packed
binary format to string format"""
if family == socket.AF_INET:
if len(host) != 4:
raise ValueError("invalid IPv4 host")
host = pack("hH4s8s", socket.AF_INET, 0, host, "\0" * 8)
elif family == socket.AF_INET6:
if len(host) != 16:
raise ValueError("invalid IPv6 host")
host = pack("hHL16sL", socket.AF_INET6, 0, 0, host, 0)
else:
raise ValueError("invalid address family")
buf = "\0" * 64
lengthBuf = pack("I", len(buf))
addressToString(host, len(host), None, buf, lengthBuf)
return buf[0:buf.index("\0")]
socket.inet_ntop = inet_ntop
# Same for inet_pton
if not hasattr(socket, 'inet_pton'):
stringToAddress = ctypes.windll.ws2_32.WSAStringToAddressA
def inet_pton(family, host):
"""Converting an IP address in string format
to a packed binary format"""
buf = "\0" * 28
lengthBuf = pack("I", len(buf))
if stringToAddress(str(host),
int(family),
None,
buf,
lengthBuf) != 0:
raise socket.error("illegal IP address passed to inet_pton")
if family == socket.AF_INET:
return buf[4:8]
elif family == socket.AF_INET6:
return buf[8:24]
else:
raise ValueError("invalid address family")
socket.inet_pton = inet_pton
# These sockopts are needed on for IPv6 support
if not hasattr(socket, 'IPPROTO_IPV6'):
socket.IPPROTO_IPV6 = 41
if not hasattr(socket, 'IPV6_V6ONLY'):
socket.IPV6_V6ONLY = 27
def start_proxyconfig(): def start_proxyconfig():
"""Check socksproxytype and start any proxy configuration plugin""" """Check socksproxytype and start any proxy configuration plugin"""
if not get_plugin: if not get_plugin:

View File

@ -3,6 +3,7 @@ Tests for core and those that do not work outside
(because of import error for example) (because of import error for example)
""" """
import atexit
import os import os
import pickle # nosec import pickle # nosec
import Queue import Queue
@ -416,8 +417,9 @@ def run():
suite = loader.loadTestsFromTestCase(TestCore) suite = loader.loadTestsFromTestCase(TestCore)
try: try:
import bitmessageqt.tests import bitmessageqt.tests
from xvfbwrapper import Xvfb
except ImportError: except ImportError:
pass Xvfb = None
else: else:
qt_tests = loader.loadTestsFromModule(bitmessageqt.tests) qt_tests = loader.loadTestsFromModule(bitmessageqt.tests)
suite.addTests(qt_tests) suite.addTests(qt_tests)
@ -428,4 +430,8 @@ def run():
sys.excepthook = keep_exc sys.excepthook = keep_exc
if Xvfb:
vdisplay = Xvfb(width=1024, height=768)
vdisplay.start()
atexit.register(vdisplay.stop)
return unittest.TextTestRunner(verbosity=2).run(suite) return unittest.TextTestRunner(verbosity=2).run(suite)

View File

@ -29,7 +29,7 @@ format=%(asctime)s {1} %(message)s
class=FileHandler class=FileHandler
level=NOTSET level=NOTSET
formatter=default formatter=default
args=('{0}', 'w') args=({0!r}, 'w')
[logger_root] [logger_root]
level=DEBUG level=DEBUG

View File

@ -14,8 +14,11 @@ class TestNetworkGroup(unittest.TestCase):
""" """
def test_network_group(self): def test_network_group(self):
"""Test various types of network groups""" """Test various types of network groups"""
from pybitmessage.helper_startup import fixSocket
from pybitmessage.protocol import network_group from pybitmessage.protocol import network_group
fixSocket()
test_ip = '1.2.3.4' test_ip = '1.2.3.4'
self.assertEqual('\x01\x02', network_group(test_ip)) self.assertEqual('\x01\x02', network_group(test_ip))

View File

@ -3,6 +3,7 @@ Common reusable code for tests and tests for pybitmessage process.
""" """
import os import os
import sys
import signal import signal
import subprocess # nosec import subprocess # nosec
import sys import sys
@ -191,6 +192,7 @@ class TestProcessShutdown(TestProcessProto):
class TestProcess(TestProcessProto): class TestProcess(TestProcessProto):
"""A test case for pybitmessage process""" """A test case for pybitmessage process"""
@unittest.skipIf(sys.platform[:5] != 'linux', 'probably needs prctl')
def test_process_name(self): def test_process_name(self):
"""Check PyBitmessage process name""" """Check PyBitmessage process name"""
self.assertEqual(self.process.name(), 'PyBitmessage') self.assertEqual(self.process.name(), 'PyBitmessage')