Minor changes for testing on non-Linux platforms #1838

Merged
g1itch merged 4 commits from windows-test into v0.6 2021-09-05 14:22:43 +02:00
8 changed files with 86 additions and 71 deletions

View File

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

View File

@ -1,6 +1,7 @@
coverage
python_prctl
psutil
pycrypto
six
PyQt5;python_version>="3.7"
python_prctl;platform_system=="Linux"
six
xvfbwrapper;platform_system=="Linux"

View File

@ -21,16 +21,13 @@ app_dir = pathmagic.setup()
import depends
depends.check_dependencies()
import ctypes
import getopt
import multiprocessing
# Used to capture a Ctrl-C keypress so that Bitmessage can shutdown gracefully.
import signal
import socket
import threading
import time
import traceback
from struct import pack
import defaults
import shared
@ -39,7 +36,7 @@ import state
from bmconfigparser import BMConfigParser
from debug import logger # this should go before any threads
from helper_startup import (
adjustHalfOpenConnectionsLimit, start_proxyconfig)
adjustHalfOpenConnectionsLimit, fixSocket, start_proxyconfig)
from inventory import Inventory
# Network objects and threads
from network import (
@ -54,67 +51,6 @@ from threads import (
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):
"""Single handler for any signal sent to pybitmessage"""
process = multiprocessing.current_process()
@ -151,7 +87,7 @@ class Main(object):
def start(self):
"""Start main application"""
# pylint: disable=too-many-statements,too-many-branches,too-many-locals
_fixSocket()
fixSocket()
adjustHalfOpenConnectionsLimit()
config = BMConfigParser()

View File

@ -3,12 +3,15 @@ Startup operations.
"""
# pylint: disable=too-many-branches,too-many-statements
import ctypes
import logging
import os
import platform
import socket
import sys
import time
from distutils.version import StrictVersion
from struct import pack
try:
import defaults
@ -304,6 +307,68 @@ def adjustHalfOpenConnectionsLimit():
state.maximumNumberOfHalfOpenConnections = 9 if is_limited else 64
def fixSocket():
"""Add missing socket options and methods mainly on Windows"""
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():
"""Check socksproxytype and start any proxy configuration 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)
"""
import atexit
import os
import pickle # nosec
import Queue
@ -416,8 +417,9 @@ def run():
suite = loader.loadTestsFromTestCase(TestCore)
try:
import bitmessageqt.tests
from xvfbwrapper import Xvfb
except ImportError:
pass
Xvfb = None
else:
qt_tests = loader.loadTestsFromModule(bitmessageqt.tests)
suite.addTests(qt_tests)
@ -428,4 +430,8 @@ def run():
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)

View File

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

View File

@ -192,6 +192,7 @@ class TestProcessShutdown(TestProcessProto):
class TestProcess(TestProcessProto):
"""A test case for pybitmessage process"""
@unittest.skipIf(sys.platform[:5] != 'linux', 'probably needs prctl')
def test_process_name(self):
"""Check PyBitmessage process name"""
self.assertEqual(self.process.name(), 'PyBitmessage')

View File

@ -6,11 +6,17 @@ import sys
import unittest
from pybitmessage import protocol, state
from pybitmessage.helper_startup import fixSocket
class TestProtocol(unittest.TestCase):
"""Main protocol test case"""
@classmethod
def setUpClass(cls):
"""Execute fixSocket() before start. Only for Windows?"""
fixSocket()
def test_checkIPv4Address(self):
"""Check the results of protocol.checkIPv4Address()"""
token = 'HELLO'