如果我使用以下几次运行以下测试用例:
python3 -m unittest test_pyelliptic.py
大约15次中有一次失败。
测试用例:
import unittest, pyelliptic, pickle
class PyellipticTestCase(unittest.TestCase):
def setUp(self):
self.alice = pyelliptic.ECC()
self.bob = pyelliptic.ECC()
def test_pickleSign(self):
tm = {"text":"contract","amount":12}
tms1 = {"doc":tm,"c1":self.bob.get_pubkey(),"s1":self.bob.sign(pickle.dumps(tm))}
tms2bb = {"doc":tms1,"c2":self.alice.get_pubkey(),"s2":self.alice.sign(pickle.dumps(tms1))}
tms2 = pickle.loads(pickle.dumps(tms2bb))
self.assertEqual(tms2['s2'],tms2bb['s2'])
self.assertTrue(pyelliptic.ECC(pubkey=self.alice.get_pubkey()).verify(tms2bb['s2'],pickle.dumps(tms2['doc']))) #<--- FAILs sometimes
我的系统:
我还在Python 3.4.3的类似系统上对此进行了测试,并且可以重现行为。
您可以在系统上重现故障吗? 如果是,是什么原因造成的?
更新
如果我用verbose(python3 -m unittest -v test_pyelliptic2.py)运行测试,它会产生以下输出(运行两次):
X@X:~/test$ python3 -m unittest -v test_pyelliptic2.py
test_pickleSign (test_pyelliptic2.PyellipticTestCase) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.012s
OK
X@X:~/test$ python3 -m unittest -v test_pyelliptic2.py
test_pickleSign (test_pyelliptic2.PyellipticTestCase) ... FAIL
======================================================================
FAIL: test_pickleSign (test_pyelliptic2.PyellipticTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "XX/test/test_pyelliptic2.py", line 14, in test_pickleSign
self.assertTrue(pyelliptic.ECC(pubkey=self.alice.get_pubkey()).verify(tms2bb['s2'],pickle.dumps(tms2['doc']))) #<--- FAILs sometimes
AssertionError: False is not true
----------------------------------------------------------------------
Ran 1 test in 0.013s
FAILED (failures=1)
答案 0 :(得分:0)
经过一些进一步的研究后发现,二进制pickle输出取决于字典中元素的排序。 因此,以下测试用例在二进制数组的比较中失败:
def test_pickleOrder(self):
d1 = {"test1":12,"test2":14.2,"test3":"test"}
d2 = {"test3":"test","test1":12,"test2":14.2}
self.assertEqual(d1,d2)
d1p = pickle.dumps(d1)
d2p = pickle.dumps(d2)
self.assertEqual(d1p,d2p) #<--- fails here
顺便说一句:这不仅适用于泡菜,也适用于json和bson模块