Skip to content

Commit 874418f

Browse files
committed
Test for class object Processor
1 parent e571ba8 commit 874418f

File tree

3 files changed

+261
-7
lines changed

3 files changed

+261
-7
lines changed

src/class_objectProcessor.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ def processpubkey(self, data):
315315
dataToStore = data[20:readPosition]
316316
sha = hashlib.new('sha512')
317317
sha.update(
318-
'\x04' + publicSigningKey + '\x04' + publicEncryptionKey)
318+
b'\x04' + publicSigningKey + b'\x04' + publicEncryptionKey)
319319
ripe = RIPEMD160Hash(sha.digest()).digest()
320320

321321
if logger.isEnabledFor(logging.DEBUG):
@@ -354,9 +354,9 @@ def processpubkey(self, data):
354354
' Sanity check failed.')
355355
return
356356
readPosition += 4
357-
publicSigningKey = '\x04' + data[readPosition:readPosition + 64]
357+
publicSigningKey = b'\x04' + data[readPosition:readPosition + 64]
358358
readPosition += 64
359-
publicEncryptionKey = '\x04' + data[readPosition:readPosition + 64]
359+
publicEncryptionKey = b'\x04' + data[readPosition:readPosition + 64]
360360
readPosition += 64
361361
specifiedNonceTrialsPerByteLength = decodeVarint(
362362
data[readPosition:readPosition + 10])[1]
@@ -513,9 +513,9 @@ def processmsg(self, data):
513513
return
514514
readPosition += sendersStreamNumberLength
515515
readPosition += 4
516-
pubSigningKey = '\x04' + decryptedData[readPosition:readPosition + 64]
516+
pubSigningKey = b'\x04' + decryptedData[readPosition:readPosition + 64]
517517
readPosition += 64
518-
pubEncryptionKey = '\x04' + decryptedData[readPosition:readPosition + 64]
518+
pubEncryptionKey = b'\x04' + decryptedData[readPosition:readPosition + 64]
519519
readPosition += 64
520520
if sendersAddressVersionNumber >= 3:
521521
requiredAverageProofOfWorkNonceTrialsPerByte, varintLength = \
@@ -862,10 +862,10 @@ def processbroadcast(self, data):
862862
)
863863
readPosition += sendersStreamLength
864864
readPosition += 4
865-
sendersPubSigningKey = '\x04' + \
865+
sendersPubSigningKey = b'\x04' + \
866866
decryptedData[readPosition:readPosition + 64]
867867
readPosition += 64
868-
sendersPubEncryptionKey = '\x04' + \
868+
sendersPubEncryptionKey = b'\x04' + \
869869
decryptedData[readPosition:readPosition + 64]
870870
readPosition += 64
871871
if sendersAddressVersion >= 3:

src/mockbm/class_objectProcessor.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""Mock function/class used in objectProcessor"""
2+
3+
4+
def mockFunctionToPass():
5+
pass
6+
7+
8+
def sqlQueryMock(*args):
9+
return [(None, "mockData"),]
10+
11+
12+
def sqlExecuteMock(*args):
13+
return
14+
15+
16+
class SqlReadyMock(object):
17+
"""Mock helper_sql.sql_ready event with dummy class"""
18+
@staticmethod
19+
def wait(time):
20+
"""Don't wait, return immediately"""
21+
return

src/tests/test_objectProcessor.py

+233
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
"""Test cases for ObjectProcessor"""
2+
3+
import threading
4+
import state
5+
import pybitmessage.class_objectProcessor as op
6+
7+
try:
8+
from unittest.mock import patch, MagicMock
9+
except ImportError:
10+
from mock import patch, MagicMock, Mock
11+
12+
from .partial import TestPartialRun
13+
from mockbm.class_objectProcessor import (
14+
mockFunctionToPass,
15+
sqlExecuteMock,
16+
sqlQueryMock,
17+
SqlReadyMock,
18+
)
19+
from .samples import (
20+
sample_pubsigningkey,
21+
sample_pubencryptionkey,
22+
sample_deterministic_addr4,
23+
sample_deterministic_addr3,
24+
sample_privsigningkey
25+
)
26+
27+
28+
class TestObjectProcessor(TestPartialRun):
29+
"""Test class for ObjectProcessor"""
30+
31+
@classmethod
32+
def setUpClass(cls):
33+
super(TestObjectProcessor, cls).setUpClass()
34+
35+
op.sqlQuery = sqlQueryMock
36+
op.sqlExecute = sqlExecuteMock
37+
op.sql_ready = SqlReadyMock
38+
op.shared.reloadBroadcastSendersForWhichImWatching = mockFunctionToPass
39+
op.shared.reloadMyAddressHashes = mockFunctionToPass
40+
cls.queues = op.queues
41+
cls.processor = op.objectProcessor()
42+
cls.processor.start()
43+
44+
@classmethod
45+
def tearDownClass(cls):
46+
super(TestObjectProcessor, cls).tearDownClass()
47+
for thread in threading.enumerate():
48+
if thread.name == "objectProcessor":
49+
op.queues.objectProcessorQueue.put(('checkShutdownVariable', 'no data'))
50+
51+
@patch("pybitmessage.class_objectProcessor.logger.debug")
52+
@patch("pybitmessage.class_objectProcessor.queues.UISignalQueue.put")
53+
def test_checkackdata(self, mock_UISignalQueue_put, mock_logger):
54+
"""test checkdata"""
55+
gpk = b"\x00" * 8 # nonce
56+
gpk += b"\x00" * 8 # expiresTime
57+
gpk += b"\x00" * 4 # getpubkey object type
58+
gpk += b"\x04" # addressVersion
59+
gpk += b"\x01" # streamNumber
60+
gpk += b"\00" * 4 # behaviour bitfield
61+
gpk += sample_pubsigningkey
62+
gpk += sample_pubencryptionkey
63+
64+
# ackdata not in state.ackdataForWhichImWatching
65+
state.ackdataForWhichImWatching = {}
66+
self.processor.checkackdata(gpk)
67+
mock_logger.assert_called_with('This object is not an acknowledgement bound for me.')
68+
69+
# ackdata is in state.ackdataForWhichImWatching
70+
state.ackdataForWhichImWatching = {gpk[16:]: gpk}
71+
self.processor.checkackdata(gpk)
72+
self.assertEqual(len(state.ackdataForWhichImWatching), 0)
73+
mock_UISignalQueue_put.assert_called_once()
74+
75+
76+
@patch("pybitmessage.class_objectProcessor.protocol.checkIPAddress")
77+
@patch("pybitmessage.class_objectProcessor.decodeVarint")
78+
@patch("pybitmessage.class_objectProcessor.knownnodes.addKnownNode")
79+
def test_processonion(self, mock_addknownNode, mock_decodeVarient, mock_checkIPAddress):
80+
"""Test processonion"""
81+
data = b"\x00" * 100
82+
# decode varient called 3 times returns -> addressversion & lenth
83+
# stream & length, port & length
84+
mock_decodeVarient.side_effect = [(3, 1), (2, 1), (8080, 4), ]
85+
mock_checkIPAddress.return_value = "127.0.0.1"
86+
self.processor.processonion(data)
87+
mock_addknownNode.assert_called_once()
88+
89+
@patch("pybitmessage.class_objectProcessor.queues.workerQueue.put")
90+
def test_processgetpubkey_V3(
91+
self, mock_workerqueue_put
92+
):
93+
"""Test processgetpukey with address version 3"""
94+
HASH = b"\x01" * 20
95+
gpk = b"\x00" * 8 # nonce
96+
gpk += b"\x00" * 8 # expiresTime
97+
gpk += b"\x00" * 4 # getpubkey object type
98+
gpk += b"\x03" # addressVersion 4
99+
gpk += b"\x01" # streamNumber
100+
gpk += HASH # hash
101+
102+
# set address corresponding to tag
103+
op.shared.myAddressesByHash[HASH] = sample_deterministic_addr3
104+
105+
self.processor.processgetpubkey(gpk)
106+
mock_workerqueue_put.assert_called_once()
107+
108+
@patch("pybitmessage.class_objectProcessor.queues.workerQueue.put")
109+
def test_processgetpubkey_V4(
110+
self, mock_workerqueue_put
111+
):
112+
"""Test processgetpukey with address version 4"""
113+
TAG = b"\x01" * 32
114+
gpk = b"\x00" * 8 # nonce
115+
gpk += b"\x00" * 8 # expiresTime
116+
gpk += b"\x00" * 4 # getpubkey object type
117+
gpk += b"\x04" # addressVersion 4
118+
gpk += b"\x01" # streamNumber
119+
gpk += TAG # tag
120+
121+
# set address corresponding to tag
122+
op.shared.myAddressesByTag[TAG] = sample_deterministic_addr4
123+
124+
self.processor.processgetpubkey(gpk)
125+
mock_workerqueue_put.assert_called_once()
126+
127+
def test_processpubkey_version2(
128+
self,
129+
):
130+
"""Test processpubkey with version 2"""
131+
pk = b"\x00" * 8 # nonce
132+
pk += b"\x00" * 8 # expiresTime
133+
pk += b"\x00\x00\x00\x01" # getpubkey object type
134+
pk += b"\x02" # addressVersion
135+
pk += b"\x01" # streamNumber
136+
pk += b"\00" * 4 # behaviour bitfield
137+
pk += sample_pubsigningkey
138+
pk += sample_pubencryptionkey
139+
self.processor.processpubkey(pk)
140+
141+
def test_processpubkey_version3(
142+
self,
143+
):
144+
"""Test processpubkey with version 3"""
145+
pk = b"\x00" * 8 # nonce
146+
pk += b"\x00" * 8 # expiresTime
147+
pk += b"\x00\x00\x00\x01" # getpubkey object type
148+
pk += b"\x03" # addressVersion
149+
pk += b"\x01" # streamNumber
150+
pk += b"\00" * 4 # behaviour bitfield
151+
pk += sample_pubsigningkey
152+
pk += sample_pubencryptionkey
153+
pk += b"\x01" # nonce_trials_per_byte
154+
pk += b"\x01" # extra_bytes
155+
signature = op.highlevelcrypto.sign(pk[8:], hexPrivkey=sample_privsigningkey) # signature
156+
pk += hex(len(signature)).encode() # sig_length
157+
pk += signature
158+
self.processor.processpubkey(pk)
159+
160+
def test_processpubkey_version4(
161+
self
162+
):
163+
"""Test processpubkey with version 4"""
164+
pk = b"\x00" * 8 # nonce
165+
pk += b"\x00" * 8 # expiresTime
166+
pk += b"\x00\x00\x00\x01" # getpubkey object type
167+
pk += b"\x04" # addressVersion
168+
pk += b"\x01" # streamNumber
169+
pk += b"\00" * 4 # behaviour bitfield
170+
pk += sample_pubsigningkey
171+
pk += sample_pubencryptionkey
172+
self.processor.processpubkey(pk)
173+
174+
# @patch(
175+
# "pybitmessage.class_objectProcessor.helper_inbox.isMessageAlreadyInInbox",
176+
# return_value=False,
177+
# )
178+
# @patch(
179+
# "pybitmessage.class_objectProcessor.helper_msgcoding.MsgDecode",
180+
# return_value=MagicMock(subject="Test Subject", body="Test Body"),
181+
# )
182+
# @patch("pybitmessage.class_objectProcessor.helper_inbox.insert")
183+
# @patch("pybitmessage.class_objectProcessor.queues.UISignalQueue.put")
184+
# def test_processmsg_valid_message(
185+
# self,
186+
# mock_UISignalQueue_put,
187+
# mock_insert,
188+
# mock_MsgDecode,
189+
# mock_isMessageAlreadyInInbox,
190+
# ):
191+
# msg = b"\x00" * 8 # nonce
192+
# msg += b"\x00" * 8 # expiresTime
193+
# msg += b"\x00\x00\x00\x02" # getpubkey object type
194+
# msg += b"\x04" # addressVersion
195+
# msg += b"\x01" # streamNumber
196+
197+
# with patch(
198+
# "pybitmessage.class_objectProcessor.decodeVarint", return_value=(1, 1)
199+
# ), patch(
200+
# "pybitmessage.class_objectProcessor.highlevelcrypto.verify",
201+
# return_value=True,
202+
# ):
203+
# self.processor.processmsg(data)
204+
# mock_insert.assert_called()
205+
# mock_UISignalQueue_put.assert_called()
206+
207+
@patch(
208+
"pybitmessage.class_objectProcessor.state.neededPubkeys",
209+
{"address1": "data1", "address2": "data2"},
210+
)
211+
@patch("pybitmessage.class_objectProcessor.objectProcessor.sendMessages")
212+
def test_possibleNewPubkey_with_needed_pubkey(self, mock_sendMessages):
213+
self.processor.possibleNewPubkey("address1")
214+
mock_sendMessages.assert_called_with("address1")
215+
216+
@patch(
217+
"pybitmessage.class_objectProcessor.state.neededPubkeys",
218+
{"address1": "data1", "address2": "data2"},
219+
)
220+
@patch("pybitmessage.class_objectProcessor.objectProcessor.sendMessages")
221+
def test_possibleNewPubkey_with_unneeded_pubkey(self, mock_sendMessages):
222+
self.processor.possibleNewPubkey("address3")
223+
mock_sendMessages.assert_not_called()
224+
225+
@patch(
226+
"pybitmessage.class_objectProcessor.state.neededPubkeys",
227+
{"address1": "data1", "address2": "data2"},
228+
)
229+
@patch("pybitmessage.class_objectProcessor.objectProcessor.sendMessages")
230+
def test_possibleNewPubkey_with_multiple_needed_pubkeys(self, mock_sendMessages):
231+
self.processor.possibleNewPubkey("address1")
232+
self.processor.possibleNewPubkey("address2")
233+
self.assertEqual(mock_sendMessages.call_count, 2)

0 commit comments

Comments
 (0)