Minor changes for testing on non-Linux platforms #1838
|
@ -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
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
coverage
|
coverage
|
||||||
python_prctl
|
|
||||||
psutil
|
psutil
|
||||||
pycrypto
|
pycrypto
|
||||||
six
|
|
||||||
PyQt5;python_version>="3.7"
|
PyQt5;python_version>="3.7"
|
||||||
|
python_prctl;platform_system=="Linux"
|
||||||
|
six
|
||||||
|
xvfbwrapper;platform_system=="Linux"
|
||||||
|
|
|
@ -21,16 +21,13 @@ 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.
|
||||||
import signal
|
import signal
|
||||||
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 +36,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 +51,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 +87,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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import defaults
|
import defaults
|
||||||
|
@ -304,6 +307,68 @@ def adjustHalfOpenConnectionsLimit():
|
||||||
state.maximumNumberOfHalfOpenConnections = 9 if is_limited else 64
|
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():
|
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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -192,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')
|
||||||
|
|
|
@ -6,11 +6,17 @@ import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from pybitmessage import protocol, state
|
from pybitmessage import protocol, state
|
||||||
|
from pybitmessage.helper_startup import fixSocket
|
||||||
|
|
||||||
|
|
||||||
class TestProtocol(unittest.TestCase):
|
class TestProtocol(unittest.TestCase):
|
||||||
"""Main protocol test case"""
|
"""Main protocol test case"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
"""Execute fixSocket() before start. Only for Windows?"""
|
||||||
|
fixSocket()
|
||||||
|
|
||||||
def test_checkIPv4Address(self):
|
def test_checkIPv4Address(self):
|
||||||
"""Check the results of protocol.checkIPv4Address()"""
|
"""Check the results of protocol.checkIPv4Address()"""
|
||||||
token = 'HELLO'
|
token = 'HELLO'
|
||||||
|
|
Reference in New Issue
Block a user