1.. highlight:: bash
2
3.. _github: https://github.com/aio-libs/aioredis
4
5Contributing
6============
7
8To start contributing you must read all the following.
9
10First you must fork/clone repo from `github`_::
11
12   $ git clone git@github.com:aio-libs/aioredis.git
13
14Next, you should install all python dependencies, it is as easy as running
15single command::
16
17   $ make devel
18
19this command will install:
20
21* ``sphinx`` for building documentation;
22* ``pytest`` for running tests;
23* ``flake8`` for code linting;
24* and few other packages.
25
26Make sure you have provided a ``towncrier`` note.
27Just add short description running following commands::
28
29    $ echo "Short description" > CHANGES/filename.type
30
31This will create new file in ``CHANGES`` directory.
32Filename should consist of the ticket ID or other unique identifier.
33Five default types are:
34
35* .feature - signifying new feature
36* .bugfix - signifying a bug fix
37* .doc - documentation improvement
38* .removal - deprecation or removal of public API
39* .misc - a ticket has been closed, but not in interest of users
40
41You can check if everything is correct by typing::
42
43    $ towncrier --draft
44
45To produce the news file::
46
47    $ towncrier
48
49Code style
50----------
51
52Code **must** be pep8 compliant.
53
54You can check it with following command::
55
56   $ make flake
57
58
59Running tests
60-------------
61
62You can run tests in any of the following ways::
63
64   # will run tests in a verbose mode
65   $ make test
66   # or
67   $ pytest
68
69   # or with particular Redis server
70   $ pytest --redis-server=/usr/local/bin/redis-server tests/errors_test.py
71
72   # will run tests with coverage report
73   $ make cov
74   # or
75   $ pytest --cov
76
77SSL tests
78~~~~~~~~~
79
80Running SSL tests requires following additional programs to be installed:
81
82* ``openssl`` -- to generate test key and certificate;
83
84* ``socat`` -- to make SSL proxy;
85
86To install these on Ubuntu and generate test key & certificate run::
87
88   $ sudo apt-get install socat openssl
89   $ make certificate
90
91Different Redis server versions
92~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
93
94To run tests against different redises use ``--redis-server`` command line
95option::
96
97   $ pytest --redis-server=/path/to/custom/redis-server
98
99UVLoop
100~~~~~~
101
102To run tests with :term:`uvloop`::
103
104   $ pip install uvloop
105   $ pytest --uvloop
106
107.. note:: Until Python 3.5.2 EventLoop has no ``create_future`` method
108   so aioredis won't benefit from uvloop's futures.
109
110
111Writing tests
112-------------
113
114:mod:`aioredis` uses :term:`pytest` tool.
115
116Tests are located under ``/tests`` directory.
117
118
119Fixtures
120~~~~~~~~
121
122There is a number of fixtures that can be used to write tests:
123
124
125.. attribute:: loop
126
127   Current event loop used for test.
128   This is a function-scope fixture.
129   Using this fixture will always create new event loop and
130   set global one to None.
131
132   .. code-block:: python
133
134      def test_with_loop(loop):
135          @asyncio.coroutine
136          def do_something():
137              pass
138          loop.run_until_complete(do_something())
139
140.. function:: unused_port()
141
142   Finds and returns free TCP port.
143
144   .. code-block:: python
145
146      def test_bind(unused_port):
147          port = unused_port()
148          assert 1024 < port <= 65535
149
150.. cofunction:: create_connection(\*args, \**kw)
151
152   Wrapper around :func:`aioredis.create_connection`.
153   Only difference is that it registers connection to be closed after test case,
154   so you should not be worried about unclosed connections.
155
156.. cofunction:: create_redis(\*args, \**kw)
157
158   Wrapper around :func:`aioredis.create_redis`.
159
160.. cofunction:: create_pool(\*args, \**kw)
161
162   Wrapper around :func:`aioredis.create_pool`.
163
164.. attribute:: redis
165
166   Redis client instance.
167
168.. attribute:: pool
169
170   RedisPool instance.
171
172.. attribute:: server
173
174   Redis server instance info. Namedtuple with following properties:
175
176      name
177         server instance name.
178
179      port
180         Bind port.
181
182      unixsocket
183         Bind unixsocket path.
184
185      version
186         Redis server version tuple.
187
188.. attribute:: serverB
189
190   Second predefined Redis server instance info.
191
192.. function:: start_server(name)
193
194   Start Redis server instance.
195   Redis instances are cached by name.
196
197   :return: server info tuple, see :attr:`server`.
198   :rtype: tuple
199
200.. function:: ssl_proxy(unsecure_port)
201
202   Start SSL proxy.
203
204   :param int unsecure_port: Redis server instance port
205   :return: secure_port and ssl_context pair
206   :rtype: tuple
207
208
209``redis_version`` tests helper
210~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
211
212In ``tests`` directory there is a :mod:`_testutils` module with a simple
213helper --- :func:`redis_version` --- a function that add a pytest mark to a test
214allowing to run it with requested Redis server versions.
215
216.. function:: _testutils.redis_version(\*version, reason)
217
218   Marks test with minimum redis version to run.
219
220   Example:
221
222   .. code-block:: python
223
224      from _testutil import redis_version
225
226      @redis_version(3, 2, 0, reason="HSTRLEN new in redis 3.2.0")
227      def test_hstrlen(redis):
228          pass
229