Testing non-deterministic python function behavior

We have a large and complex function that must be deterministic. This is one of the workhorses of our company and covers a large amount of code. This code often becomes non-deterministic due to the python dict iterator. This has happened many times, and it is very difficult to track and often not notice immediately. We would like to write an automated test to detect non-determinism, but I'm not sure how to do this.

We tried to run the function in a loop, and testing the results is always the same, but sometimes, although the function is not deterministic, the function will pass this test because of the arbitrary but somewhat sequential ordering of the dict iterator.

Is there a way to write an automated test to catch such an error?

Perhaps there is a way to crack a python dict so that iterators are random rather than arbitrary during this test? So repeated function calls will be more likely to diverge? This seems like a pretty complicated method, but I can't think of anything else.

EDIT:

We are currently using Python 2.7.

We have single tests of various submodules, however, they often do not exhibit non-determinism due to the arbitrary but consistent nature of the dictate order.

, , . {id: data}, , - python . , - , .

+4
2

-, -R python:

-R     : use a pseudo-random salt to make hash() values of various types be
         unpredictable between separate invocations of the interpreter, as
         a defense against denial-of-service attacks

a la

~$ python -c "print {y:x for x,y in enumerate('foobar')}"
{'a': 4, 'r': 5, 'b': 3, 'o': 2, 'f': 0} #it will always be this
~$ python -R -c "print {y:x for x,y in enumerate('foobar')}"
{'a': 4, 'b': 3, 'r': 5, 'f': 0, 'o': 2}
~$ python -R -c "print {y:x for x,y in enumerate('foobar')}"
{'a': 4, 'b': 3, 'r': 5, 'o': 2, 'f': 0}
~$ python -R -c "print {y:x for x,y in enumerate('foobar')}"
{'f': 0, 'o': 2, 'b': 3, 'r': 5, 'a': 4}
~$ python -R -c "print {y:x for x,y in enumerate('foobar')}"
{'r': 5, 'f': 0, 'o': 2, 'a': 4, 'b': 3}

, python 3.3.

+5

OrderedDict, dict "".

vanilla dict s, dict.

, ( ):

d1 = {'a':1, 'b': 2}
d2 = dict(d1)

j1 = json.dumps(d1)
j2 = json.dumps(d2)

assert j1 == j2:

:

import json
from collections import OrderedDict

d1 = OrderedDict([('a', 1), ('b', 2)])
d2 = OrderedDict([('b', 2), ('a', 1)])

j1 = json.dumps(d1)
j2 = json.dumps(d2)
assert j1 == j2

, . " ", , dict, .

0

Source: https://habr.com/ru/post/1527983/


All Articles