Hypothesis extension to allow generating protobuf messages matching a schema.
Project description
# hypothesis-protobuf
[![Build Status](https://travis-ci.org/hchasestevens/hypothesis-protobuf.svg?branch=master)](https://travis-ci.org/hchasestevens/hypothesis-protobuf)
[![PyPI version](https://badge.fury.io/py/hypothesis-pb.svg)](https://pypi.org/project/hypothesis-pb)
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/hypothesis-pb.svg)
[Hypothesis](http://hypothesis.works/) extension to allow generating [protobuf](https://developers.google.com/protocol-buffers/) messages matching a schema.
## Installation
```
pip install hypothesis-pb
```
## Usage
Given a compiled protobuf schema module, `hypothesis-protobuf` allows for hypothesis strategies to be generated which match the types of the protobuf messages.
### Simple example
Using an example protobuf schema for an instant messaging application:
```proto
syntax = "proto3";
package im;
enum Client {
CLIENT_UNKNOWN = 0;
CLIENT_NATIVE_APP = 1;
CLIENT_WEB_APP = 2;
CLIENT_API = 3;
}
message User {
uint64 id = 1;
string screen_name = 2;
}
message InstantMessage {
uint64 timestamp = 1;
Client client = 2;
fixed32 sender_ip = 3;
User sender = 4;
User recipient = 5;
string message = 6;
repeated bytes image_attachments = 7;
}
```
a strategy for `InstantMessage` can be generated from the compiled schema (`im_pb2.py`) by executing:
```python
from hypothesis_protobuf import modules_to_strategies
import im_pb2
protobuf_strategies = modules_to_strategies(im_pb2)
instant_message_strategy = protobuf_strategies[im_pb2.InstantMessage]
```
which in turn can be used to generate `InstantMessage` examples:
```python
>>> instant_message_strategy.example()
timestamp: 14420265017158477352
client: CLIENT_NATIVE_APP
sender_ip: 1465109037
sender {
id: 9509488734701077048
screen_name: "\364\210\240\2233\007\352\212\222i\354\217\251"
}
recipient {
id: 14863054719025962687
screen_name: "\351\274\240"
}
message: "M\361\265\247\224\310\224\362\202\r\347\227\245\n\352\202M]\361\253\237\2700"
image_attachments: "\236rN\267\252\363-s\235"
image_attachments: "\256\376ZP-"
image_attachments: "\340"
```
or as a strategy for use in testing (see the [hypothesis quick-start guide](https://hypothesis.readthedocs.io/en/latest/quickstart.html)):
```python
from hypothesis import given
@given(instant_message=protobuf_strategies[im_pb2.InstantMessage])
def test_instant_message_processor(instant_message):
assert process_message(instant_message) # will be run using multiple InstantMessage examples
```
### Overriding strategies
When generating strategies for a given protobuf module, field-specific overrides can be provided. These overrides must be mappings from full field names to strategies, like so:
```python
from hypothesis_protobuf import modules_to_strategies
from hypothesis import strategies as st
import im_pb2
strategy_overrides = {
'im.InstantMessage.timestamp': st.floats(
min_value=0,
max_value=2e9
)
}
protobuf_strategies = modules_to_strategies(im_pb2, **strategy_overrides)
instant_message_strategy = protobuf_strategies[im_pb2.InstantMessage]
```
`hypothesis-protobuf` also offers a `full_field_name` utility, allowing the above override to be specified as:
```python
from hypothesis_protobuf import full_field_name
from hypothesis import strategies as st
import im_pb2
strategy_overrides = {
full_field_name(im_pb2.InstantMessage, 'timestamp'): st.floats(
min_value=0,
max_value=2e9
)
}
```
In cases where the message strategy should choose either from the override provided or from the default field value, the `optional` function can be used:
```python
from hypothesis_protobuf import optional
from hypothesis import strategies as st
strategy_overrides = {
'im.InstantMessage.timestamp': optional(
st.floats(min_value=0, max_value=2e9)
)
}
```
Finally, overrides can also be provided as functions, taking the field's default strategy and returning a new strategy. Using this method, the above can be rewritten as:
```python
strategy_overrides = {
'im.InstantMessage.timestamp': (
lambda strategy: strategy.filter(lambda value: value <= 2e9)
)
}
```
## License
`hypothesis-protobuf` is available under the MIT license.
[![Build Status](https://travis-ci.org/hchasestevens/hypothesis-protobuf.svg?branch=master)](https://travis-ci.org/hchasestevens/hypothesis-protobuf)
[![PyPI version](https://badge.fury.io/py/hypothesis-pb.svg)](https://pypi.org/project/hypothesis-pb)
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/hypothesis-pb.svg)
[Hypothesis](http://hypothesis.works/) extension to allow generating [protobuf](https://developers.google.com/protocol-buffers/) messages matching a schema.
## Installation
```
pip install hypothesis-pb
```
## Usage
Given a compiled protobuf schema module, `hypothesis-protobuf` allows for hypothesis strategies to be generated which match the types of the protobuf messages.
### Simple example
Using an example protobuf schema for an instant messaging application:
```proto
syntax = "proto3";
package im;
enum Client {
CLIENT_UNKNOWN = 0;
CLIENT_NATIVE_APP = 1;
CLIENT_WEB_APP = 2;
CLIENT_API = 3;
}
message User {
uint64 id = 1;
string screen_name = 2;
}
message InstantMessage {
uint64 timestamp = 1;
Client client = 2;
fixed32 sender_ip = 3;
User sender = 4;
User recipient = 5;
string message = 6;
repeated bytes image_attachments = 7;
}
```
a strategy for `InstantMessage` can be generated from the compiled schema (`im_pb2.py`) by executing:
```python
from hypothesis_protobuf import modules_to_strategies
import im_pb2
protobuf_strategies = modules_to_strategies(im_pb2)
instant_message_strategy = protobuf_strategies[im_pb2.InstantMessage]
```
which in turn can be used to generate `InstantMessage` examples:
```python
>>> instant_message_strategy.example()
timestamp: 14420265017158477352
client: CLIENT_NATIVE_APP
sender_ip: 1465109037
sender {
id: 9509488734701077048
screen_name: "\364\210\240\2233\007\352\212\222i\354\217\251"
}
recipient {
id: 14863054719025962687
screen_name: "\351\274\240"
}
message: "M\361\265\247\224\310\224\362\202\r\347\227\245\n\352\202M]\361\253\237\2700"
image_attachments: "\236rN\267\252\363-s\235"
image_attachments: "\256\376ZP-"
image_attachments: "\340"
```
or as a strategy for use in testing (see the [hypothesis quick-start guide](https://hypothesis.readthedocs.io/en/latest/quickstart.html)):
```python
from hypothesis import given
@given(instant_message=protobuf_strategies[im_pb2.InstantMessage])
def test_instant_message_processor(instant_message):
assert process_message(instant_message) # will be run using multiple InstantMessage examples
```
### Overriding strategies
When generating strategies for a given protobuf module, field-specific overrides can be provided. These overrides must be mappings from full field names to strategies, like so:
```python
from hypothesis_protobuf import modules_to_strategies
from hypothesis import strategies as st
import im_pb2
strategy_overrides = {
'im.InstantMessage.timestamp': st.floats(
min_value=0,
max_value=2e9
)
}
protobuf_strategies = modules_to_strategies(im_pb2, **strategy_overrides)
instant_message_strategy = protobuf_strategies[im_pb2.InstantMessage]
```
`hypothesis-protobuf` also offers a `full_field_name` utility, allowing the above override to be specified as:
```python
from hypothesis_protobuf import full_field_name
from hypothesis import strategies as st
import im_pb2
strategy_overrides = {
full_field_name(im_pb2.InstantMessage, 'timestamp'): st.floats(
min_value=0,
max_value=2e9
)
}
```
In cases where the message strategy should choose either from the override provided or from the default field value, the `optional` function can be used:
```python
from hypothesis_protobuf import optional
from hypothesis import strategies as st
strategy_overrides = {
'im.InstantMessage.timestamp': optional(
st.floats(min_value=0, max_value=2e9)
)
}
```
Finally, overrides can also be provided as functions, taking the field's default strategy and returning a new strategy. Using this method, the above can be rewritten as:
```python
strategy_overrides = {
'im.InstantMessage.timestamp': (
lambda strategy: strategy.filter(lambda value: value <= 2e9)
)
}
```
## License
`hypothesis-protobuf` is available under the MIT license.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
hypothesis-pb-1.2.0.tar.gz
(5.5 kB
view details)
File details
Details for the file hypothesis-pb-1.2.0.tar.gz
.
File metadata
- Download URL: hypothesis-pb-1.2.0.tar.gz
- Upload date:
- Size: 5.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.11.0 pkginfo/1.4.2 requests/2.19.1 setuptools/40.2.0 requests-toolbelt/0.8.0 tqdm/4.24.0 CPython/2.7.12
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6361add3371277959c7cc2dc8a0d225dbbcb99e49f670f405304ac0f1ad5ff3d |
|
MD5 | aea1fad77fcb4995fcd3088f1e1694fe |
|
BLAKE2b-256 | 009b837eef75deb3d517bb0c2cf7373884bc98e67065278bfa0c01ae66bd5edc |