File: test_benchmark.py

package info (click to toggle)
pyrlp 0.5.1-3.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 380 kB
  • sloc: python: 1,715; makefile: 221; sh: 16
file content (99 lines) | stat: -rw-r--r-- 2,823 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
from __future__ import unicode_literals

from itertools import repeat, chain
import sys
import pytest
import rlp
from rlp.sedes import binary, CountableList
from rlp.exceptions import DecodingError, DeserializationError


try:
    import pytest_benchmark
except ImportError:
    do_benchmark = False
else:
    do_benchmark = True


# speed up setup in case tests aren't run anyway
if do_benchmark:
    SIZE = int(1e6)
else:
    SIZE = 1


class Message(rlp.Serializable):

    fields = [
        ('field1', binary),
        ('field2', binary),
        ('field3', CountableList(binary, max_length=100))
    ]


def lazy_test_factory(s, valid):
    @pytest.mark.benchmark(group='lazy')
    def f(benchmark):
        @benchmark
        def result():
            try:
                Message.deserialize(rlp.decode_lazy(s))
            except (DecodingError, DeserializationError):
                return not valid
            else:
                return valid
        assert result
    return f


def eager_test_factory(s, valid):
    @pytest.mark.benchmark(group='eager')
    def f(benchmark):
        @benchmark
        def result():
            try:
                rlp.decode(s, Message)
            except (DecodingError, DeserializationError):
                return not valid
            else:
                return valid
        assert result
    return f


def generate_test_functions():
    valid = {}
    invalid = {}
    long_string = bytes(bytearray((i % 256 for i in range(SIZE))))
    long_list = rlp.encode([c for c in long_string])
    invalid['long_string'] = long_string
    invalid['long_list'] = long_list

    nested_list = rlp.encode('\x00')
    for _ in repeat(None, SIZE):
        nested_list += rlp.codec.length_prefix(len(nested_list), 0xc0)
    invalid['nested_list'] = nested_list

    valid['long_string_object'] = rlp.encode([b'\x00', long_string, []])

    prefix = rlp.codec.length_prefix(1 + 1 + len(long_list), 0xc0)
    invalid['long_list_object'] = prefix + rlp.encode(b'\x00') + rlp.encode(b'\x00') + long_list

    valid['friendly'] = rlp.encode(Message('hello', 'I\'m friendly', ['not', 'many', 'elements']))

    invalid = invalid.items()
    valid = valid.items()
    rlp_strings = [i[1] for i in chain(valid, invalid)]
    valids = [True] * len(valid) + [False] * len(invalid)
    names = [i[0] for i in chain(valid, invalid)]

    current_module = sys.modules[__name__]
    for rlp_string, valid, name in zip(rlp_strings, valids, names):
        f_eager = pytest.mark.skipif('not do_benchmark')(eager_test_factory(rlp_string, valid))
        f_lazy = pytest.mark.skipif('not do_benchmark')(lazy_test_factory(rlp_string, valid))
        setattr(current_module, 'test_eager_' + name, f_eager)
        setattr(current_module, 'test_lazy_' + name, f_lazy)


generate_test_functions()