Skip to content

Commit 3073ef1

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

File tree

3 files changed

+237
-7
lines changed

3 files changed

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

0 commit comments

Comments
 (0)