Skip to content

Commit a11d4dc

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

File tree

3 files changed

+257
-7
lines changed

3 files changed

+257
-7
lines changed

src/class_objectProcessor.py

Lines changed: 7 additions & 7 deletions
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

Lines changed: 21 additions & 0 deletions
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

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
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+
# thread.join()
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+
gpk = b"\x00" * 8 # nonce
132+
gpk += b"\x00" * 8 # expiresTime
133+
gpk += b"\x00\x00\x00\x01" # getpubkey object type
134+
gpk += b"\x02" # addressVersion
135+
gpk += b"\x01" # streamNumber
136+
gpk += b"\00" * 4 # behaviour bitfield
137+
gpk += sample_pubsigningkey
138+
gpk += sample_pubencryptionkey
139+
self.processor.processpubkey(gpk)
140+
141+
def test_processpubkey_version3(
142+
self,
143+
):
144+
"""Test processpubkey with version 3"""
145+
gpk = b"\x00" * 8 # nonce
146+
gpk += b"\x00" * 8 # expiresTime
147+
gpk += b"\x00\x00\x00\x01" # getpubkey object type
148+
gpk += b"\x03" # addressVersion
149+
gpk += b"\x01" # streamNumber
150+
gpk += b"\00" * 4 # behaviour bitfield
151+
gpk += sample_pubsigningkey
152+
gpk += sample_pubencryptionkey
153+
gpk += b"\x01" # nonce_trials_per_byte
154+
gpk += b"\x01" # extra_bytes
155+
signature = op.highlevelcrypto.sign(gpk[8:], hexPrivkey=sample_privsigningkey) # signature
156+
print(len(sample_privsigningkey))
157+
gpk += b"\x40" # sig_length
158+
gpk += signature
159+
self.processor.processpubkey(gpk)
160+
161+
def test_processpubkey_version4(
162+
self
163+
):
164+
"""Test processpubkey with version 4"""
165+
gpk = b"\x00" * 8 # nonce
166+
gpk += b"\x00" * 8 # expiresTime
167+
gpk += b"\x00\x00\x00\x01" # getpubkey object type
168+
gpk += b"\x04" # addressVersion
169+
gpk += b"\x01" # streamNumber
170+
gpk += b"\00" * 4 # behaviour bitfield
171+
gpk += sample_pubsigningkey
172+
gpk += sample_pubencryptionkey
173+
self.processor.processpubkey(gpk)
174+
175+
# @patch(
176+
# "pybitmessage.class_objectProcessor.helper_inbox.isMessageAlreadyInInbox",
177+
# return_value=False,
178+
# )
179+
# @patch(
180+
# "pybitmessage.class_objectProcessor.helper_msgcoding.MsgDecode",
181+
# return_value=MagicMock(subject="Test Subject", body="Test Body"),
182+
# )
183+
# @patch("pybitmessage.class_objectProcessor.helper_inbox.insert")
184+
# @patch("pybitmessage.class_objectProcessor.queues.UISignalQueue.put")
185+
# def test_processmsg_valid_message(
186+
# self,
187+
# mock_UISignalQueue_put,
188+
# mock_insert,
189+
# mock_MsgDecode,
190+
# mock_isMessageAlreadyInInbox,
191+
# ):
192+
# data = b"\x00" * 100
193+
# with patch(
194+
# "pybitmessage.class_objectProcessor.decodeVarint", return_value=(1, 1)
195+
# ), patch(
196+
# "pybitmessage.class_objectProcessor.highlevelcrypto.verify",
197+
# return_value=True,
198+
# ):
199+
# self.processor.processmsg(data)
200+
# mock_insert.assert_called()
201+
# mock_UISignalQueue_put.assert_called()
202+
203+
@patch(
204+
"pybitmessage.class_objectProcessor.state.neededPubkeys",
205+
{"address1": "data1", "address2": "data2"},
206+
)
207+
@patch("pybitmessage.class_objectProcessor.objectProcessor.sendMessages")
208+
def test_possibleNewPubkey_with_needed_pubkey(self, mock_sendMessages):
209+
self.processor.possibleNewPubkey("address1")
210+
mock_sendMessages.assert_called_with("address1")
211+
212+
@patch(
213+
"pybitmessage.class_objectProcessor.state.neededPubkeys",
214+
{"address1": "data1", "address2": "data2"},
215+
)
216+
@patch("pybitmessage.class_objectProcessor.objectProcessor.sendMessages")
217+
def test_possibleNewPubkey_with_unneeded_pubkey(self, mock_sendMessages):
218+
self.processor.possibleNewPubkey("address3")
219+
mock_sendMessages.assert_not_called()
220+
221+
@patch(
222+
"pybitmessage.class_objectProcessor.state.neededPubkeys",
223+
{"address1": "data1", "address2": "data2"},
224+
)
225+
@patch("pybitmessage.class_objectProcessor.objectProcessor.sendMessages")
226+
def test_possibleNewPubkey_with_multiple_needed_pubkeys(self, mock_sendMessages):
227+
self.processor.possibleNewPubkey("address1")
228+
self.processor.possibleNewPubkey("address2")
229+
self.assertEqual(mock_sendMessages.call_count, 2)

0 commit comments

Comments
 (0)