Skip to content

Commit 8e05e4a

Browse files
author
Lee Miller
committed
A test case for the network start checks that:
- all the threads are started, - it opens connections and updates stats. A base class for partial run essentially mimics bitmessagemain.
1 parent 6b90332 commit 8e05e4a

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

src/tests/partial.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""A test case for partial run class definition"""
2+
3+
import os
4+
import sys
5+
import unittest
6+
7+
from pybitmessage import pathmagic
8+
9+
10+
class TestPartialRun(unittest.TestCase):
11+
"""
12+
A base class for test cases running some parts of the app,
13+
e.g. separate threads or packages.
14+
"""
15+
16+
@classmethod
17+
def setUpClass(cls):
18+
cls.dirs = (os.path.abspath(os.curdir), pathmagic.setup())
19+
20+
import bmconfigparser
21+
import state
22+
23+
from debug import logger # noqa:F401 pylint: disable=unused-variable
24+
25+
state.shutdown = 0
26+
cls.state = state
27+
bmconfigparser.config = cls.config = bmconfigparser.BMConfigParser()
28+
cls.config.read()
29+
30+
@classmethod
31+
def tearDownClass(cls):
32+
cls.state.shutdown = 1
33+
# deactivate pathmagic
34+
os.chdir(cls.dirs[0])
35+
sys.path.remove(cls.dirs[1])

src/tests/test_network.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
"""Test network module"""
2+
3+
import threading
4+
import time
5+
6+
from .common import skip_python3
7+
from .partial import TestPartialRun
8+
9+
skip_python3()
10+
11+
12+
class TestNetwork(TestPartialRun):
13+
"""A test case for running the network subsystem"""
14+
15+
@classmethod
16+
def setUpClass(cls):
17+
super(TestNetwork, cls).setUpClass()
18+
19+
cls.state.maximumNumberOfHalfOpenConnections = 4
20+
21+
cls.config.set('bitmessagesettings', 'sendoutgoingconnections', 'True')
22+
23+
# config variable is still used inside of the network ):
24+
import network
25+
from network import connectionpool, stats
26+
27+
# beware of singleton
28+
connectionpool.config = cls.config
29+
cls.pool = network.BMConnectionPool()
30+
cls.stats = stats
31+
32+
network.start(cls.config, cls.state)
33+
34+
def test_threads(self):
35+
"""Ensure all the network threads started"""
36+
threads = {
37+
"AddrBroadcaster", "Asyncore", "Downloader", "InvBroadcaster",
38+
"Uploader"}
39+
extra = (
40+
self.config.getint('threads', 'receive')
41+
+ self.config.safeGetBoolean('bitmessagesettings', 'udp'))
42+
for thread in threading.enumerate():
43+
try:
44+
threads.remove(thread.name)
45+
except KeyError:
46+
extra -= (
47+
thread.name == "Announcer"
48+
or thread.name.startswith("ReceiveQueue_"))
49+
50+
self.assertEqual(len(threads), 0)
51+
self.assertEqual(extra, 0)
52+
53+
def test_stats(self):
54+
"""Check that network starts connections and updates stats"""
55+
pl = 0
56+
for _ in range(30):
57+
if pl == 0:
58+
pl = len(self.pool)
59+
if (
60+
self.stats.receivedBytes() > 0 and self.stats.sentBytes() > 0
61+
and pl > 0
62+
# and len(self.stats.connectedHostsList()) > 0
63+
):
64+
break
65+
time.sleep(1)
66+
else:
67+
self.fail('Have not started any connection in 30 sec')
68+
69+
@classmethod
70+
def tearDownClass(cls):
71+
super(TestNetwork, cls).tearDownClass()
72+
for thread in threading.enumerate():
73+
if thread.name == "Asyncore":
74+
thread.stopThread()

0 commit comments

Comments
 (0)