Skip to content

Commit 16ebb29

Browse files
committed
Docs: update obsolete information in IT's READMEs
Signed-off-by: Evgeny Malygin <emalygin@bloomberg.net>
1 parent d69d461 commit 16ebb29

2 files changed

Lines changed: 79 additions & 150 deletions

File tree

src/integration-tests/README.md

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# BlazingMQ Integration Tests
22

3-
[WIP]
4-
53
To run the tests:
64

75
* (create and) activate a Python 3.8 (or above) `venv`
@@ -11,13 +9,35 @@ To run the tests:
119
* `pip3 install -r src/python/requirements-test.txt`
1210
* run the tests
1311
* `cd src/integration-tests`
14-
* `./run-tests [extra pytest options]`
15-
* you might also want to specify custom binary locations as follows
16-
* `BLAZINGMQ_BUILD_DIR` - the root directory where the resulting binaries reside;
17-
default: `cmake.bld/{platform.system()}`
18-
* `BLAZINGMQ_BROKER` - the file name of bmqbrkr (including path);
19-
default: `{build_dir}/src/applications/bmqbrkr/bmqbrkr.tsk`
20-
* `BLAZINGMQ_TOOL` - the file name of bmqtool (including path);
21-
default: `{build_dir}/src/applications/bmqtool/bmqtool.tsk`
22-
* `BLAZINGMQ_PLUGINS` - the directory containing plugins.
12+
* `./run-tests [preset] [extra pytest options]`
13+
14+
## Presets
15+
16+
The first non-option argument to `run-tests` selects a preset, i.e. the set of
17+
test configurations to run. If omitted, the default preset
18+
`"legacy_mode or fsm_mode"` is used. A preset may also be provided through the
19+
`BLAZINGMQ_IT_PRESET` environment variable.
20+
21+
* `./run-tests` (default preset)
22+
* `./run-tests "legacy_mode"`
23+
* `./run-tests "not fsm_mode"`
24+
* `./run-tests "legacy_mode or fsm_mode"`
25+
* `export BLAZINGMQ_IT_PRESET="fsm_mode" && ./run-tests`
26+
27+
Any additional arguments are forwarded to `pytest`, e.g.
28+
`./run-tests "fsm_mode" -k test_breathing`.
29+
30+
## Custom binary locations
31+
32+
You might also want to specify custom binary locations as follows:
2333

34+
* `BLAZINGMQ_BUILD_DIR` - the root directory where the resulting binaries reside;
35+
default: `build/blazingmq`
36+
* `BLAZINGMQ_BROKER` - the file name of bmqbrkr (including path);
37+
default: `{build_dir}/src/applications/bmqbrkr/bmqbrkr.tsk`
38+
* `BLAZINGMQ_TOOL` - the file name of bmqtool (including path);
39+
default: `{build_dir}/src/applications/bmqtool/bmqtool.tsk`
40+
* `BLAZINGMQ_STORAGETOOL` - the file name of bmqstoragetool (including path);
41+
default: `{build_dir}/src/applications/bmqstoragetool/bmqstoragetool.tsk`
42+
* `BLAZINGMQ_PLUGINS` - the directory containing plugins;
43+
default: `{build_dir}/src/plugins`

src/python/blazingmq/dev/it/README.md

Lines changed: 48 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,18 @@ provides methods for opening and closing queues, posting messages, etc.
3838

3939
`blazingmq.dev.it.fixtures` provides the following fixtures:
4040

41-
* `local_cluster`: a local "cluster" setup, consisting of a standalone broker
42-
and no proxies. The fixture is parameterized by the mode, with three
43-
possible values: CSL mode, FSM mode or legacy mode.
41+
* `single_node`: a local "cluster" setup, consisting of a standalone broker
42+
and no proxies.
4443

45-
* `standard_cluster`: a multi-node cluster setup, consisting of four nodes
44+
* `multi_node`: a multi-node cluster setup, consisting of four nodes
4645
in two data centers of two nodes each, and two proxies (one in each
47-
data center). The fixture is parameterized by the mode, with three
48-
possible values: CSL mode, FSM mode or legacy mode.
46+
data center).
4947

50-
* `cluster`: a parametric fixture that combines `local_cluster` and
51-
`standard_cluster`
48+
* `multi7_node`: a multi-node cluster setup, consisting of seven nodes across
49+
four data centers and four proxies (one in each data center).
50+
51+
* `cluster`: a parametric fixture that combines `single_node` and
52+
`multi_node`
5253

5354
When used as method arguments, these fixtures check for the presence of a
5455
`setup_cluster` instance method. If it is found, it is called with the
@@ -135,7 +136,7 @@ Here is a complete example, followed by a breakdown:
135136
```python
136137
# 99doc_test.py #1
137138

138-
from blazingmq.dev.it.fixtures import cluster, local_cluster # 2
139+
from blazingmq.dev.it.fixtures import cluster, single_node # 2
139140
from blazingmq.dev.it.testconstants import * # 3
140141

141142

@@ -162,7 +163,7 @@ class TestDemo: # 4
162163
msgs = self.consumer.list(URI_PRIORITY, block=True) # 13
163164
assert len(msgs) == 0 # 13
164165

165-
def test_post_message_fanout(self, local_cluster): # 14
166+
def test_post_message_fanout(self, single_node): # 14
166167
self.consumer.open(URI_PRIORITY, flags=["read"], succeed=True)
167168
self.consumer.wait_push_event()
168169
msgs = self.consumer.list(URI_PRIORITY, block=True)
@@ -171,7 +172,7 @@ class TestDemo: # 4
171172

172173
1. The file name has to end in `_test.py` for `pytest` to pick it.
173174

174-
2. Import the `cluster` and `local_cluster` fixtures.
175+
2. Import the `cluster` and `single_node` fixtures.
175176

176177
3. Import all the constants. In this test could also just import
177178
`URI_PRIORITY`.
@@ -230,30 +231,21 @@ def test_post_message_priority(self, cluster, domain_urls: tc.DomainUrls):
230231
```
231232
### Tweaking the configuration
232233

233-
Test code can add its own tweaks to the stock configurations, by applying the
234-
`@tweak` and `@tweak_value` decorators, at the function, method, or class
235-
level, as needed.
236-
237-
`@tweak` takes a list of functions and calls them on the `Configurator` object,
238-
before it is deployed. The `Configurator` has three attributes -
239-
`cluster_catalog`, `domain_catalog`, and `routing`. For stock configurations,
240-
they are loaded, respectively, with the content of the `clusters.json`,
241-
`domains.json`, and `domains_routing.json` from `etc`.
234+
Test code can add its own tweaks to the stock configurations by applying the
235+
`tweak` decorators, at the function, method, or class level, as needed. Import
236+
`tweak` from `blazingmq.dev.it.fixtures`.
242237

243-
A tweak can make arbitrary modifications to the `Configurator` before it is
244-
deployed. It can even replace the configurations entirely. Most of the time,
245-
however, a tweak will just perform a few adjustments. For example:
238+
`tweak` is a factory of decorators generated from the configuration schema. It
239+
exposes three roots - `tweak.broker`, `tweak.domain`, and `tweak.cluster` -
240+
which mirror the `broker`, `domain`, and `cluster` definitions of the
241+
`Configurator`. Navigate the attribute path in snake_case to reach the field
242+
you want to change, then call the leaf with the desired value. The result is a
243+
decorator that sets that field on the `Configurator` before it is deployed. For
244+
example:
246245

247246
```python
248-
def limit_consumers(ws):
249-
ws.domain_catalog[DOMAIN_PRIORITY]["*"]["limit.consumers"] = 1
250-
251-
252-
def limit_producers(ws):
253-
ws.domain_catalog[DOMAIN_PRIORITY]["*"]["limit.producers"] = 1
254-
255-
256-
@tweak(limit_consumers, limit_producers)
247+
@tweak.domain.max_consumers(1)
248+
@tweak.domain.max_producers(1)
257249
def test_tweak(cluster):
258250
proxy = next(cluster.proxy_cycle())
259251
assert (
@@ -282,94 +274,21 @@ def test_tweak(cluster):
282274
)
283275
```
284276

285-
`@tweak` may be applied more than once to the same entity, in which case the
286-
effect is cumulative. Tweaks may also be applied at different levels
287-
(e.g. class and test method). In this case, the tweaks are applied from
288-
outside in.
289-
290-
Since tweaks are decorators, i.e. functions that take functions and return
291-
functions, it is easy to write functions that return tweaks, possibly
292-
parameterized. For example:
293-
294-
```python
295-
def limit_consumers(num):
296-
def tweaker(ws):
297-
ws.domain_catalog[DOMAIN_PRIORITY]["*"]["limit.consumers"] = num
298-
299-
return tweak(tweaker)
300-
277+
Nested fields are reached by chaining attributes, e.g.
278+
`@tweak.domain.storage.queue_limits.messages(2)` or
279+
`@tweak.broker.app_config.configure_stream(True)`.
301280

302-
def limit_producers(num):
303-
def tweaker(ws):
304-
ws.domain_catalog[DOMAIN_PRIORITY]["*"]["limit.producers"] = num
281+
Tweaks may be applied more than once to the same entity, in which case the
282+
effect is cumulative. They may also be applied at different levels (e.g. class
283+
and test method). In this case, the tweaks are applied from outside in.
305284

306-
return tweak(tweaker)
285+
Since a tweak is just a decorator, it can be bound to a name and reused:
307286

287+
```python
288+
one_producer_only = tweak.domain.max_producers(1)
308289

309-
@limit_producers(1)
310-
def test_exceed_max_producers(cluster):
311-
proxy = next(cluster.proxy_cycle())
312-
assert (
313-
proxy.create_client("producer1").open(
314-
URI_PRIORITY, flags=["write,ack"], block=True
315-
)
316-
== Client.e_SUCCESS
317-
)
318-
assert (
319-
proxy.create_client("producer2").open(
320-
URI_PRIORITY, flags=["write,ack"], block=True
321-
)
322-
!= Client.e_SUCCESS
323-
)
324-
assert (
325-
proxy.create_client("consumer1").open(
326-
URI_PRIORITY, flags=["read,ack"], block=True
327-
)
328-
== Client.e_SUCCESS
329-
)
330-
assert (
331-
proxy.create_client("consumer2").open(
332-
URI_PRIORITY, flags=["read,ack"], block=True
333-
)
334-
== Client.e_SUCCESS
335-
)
336-
337-
338-
@limit_consumers(1)
339-
@limit_producers(1)
340-
def test_exceed_both(cluster):
341-
proxy = next(cluster.proxy_cycle())
342-
assert (
343-
proxy.create_client("producer1").open(
344-
URI_PRIORITY, flags=["write,ack"], block=True
345-
)
346-
== Client.e_SUCCESS
347-
)
348-
assert (
349-
proxy.create_client("producer2").open(
350-
URI_PRIORITY, flags=["write,ack"], block=True
351-
)
352-
!= Client.e_SUCCESS
353-
)
354-
assert (
355-
proxy.create_client("consumer1").open(
356-
URI_PRIORITY, flags=["read,ack"], block=True
357-
)
358-
== Client.e_SUCCESS
359-
)
360-
assert (
361-
proxy.create_client("consumer2").open(
362-
URI_PRIORITY, flags=["read,ack"], block=True
363-
)
364-
!= Client.e_SUCCESS
365-
)
366-
```
367-
368-
Simple tweaks can be implemented easily via `tweak_value`. It takes a
369-
XmlPath-like path in the `Workspace` object and a value:
370290

371-
```python
372-
@tweak_value(f"domain_catalog/{DOMAIN_PRIORITY}/*/limit.producers", 1)
291+
@one_producer_only
373292
def test_tweak(cluster):
374293
proxy = next(cluster.proxy_cycle())
375294
assert (
@@ -386,29 +305,17 @@ def test_tweak(cluster):
386305
)
387306
```
388307

389-
Again, it is easy to factorize tweaks:
308+
For changes that the generated attribute paths do not cover, `tweak` can also be
309+
called directly with a function that receives the `Configurator` and makes
310+
arbitrary modifications before deployment:
390311

391312
```python
392-
one_producer_only = tweak_value(
393-
f"domain_catalog/{DOMAIN_PRIORITY}/*/limit.producers", 1
394-
)
313+
def raise_max_queues(configurator):
314+
configurator.proto.domain.max_queues = 1000
395315

396316

397-
@one_producer_only
398-
def test_tweak(cluster):
399-
proxy = next(cluster.proxy_cycle())
400-
assert (
401-
proxy.create_client("producer1").open(
402-
URI_PRIORITY, flags=["write,ack"], block=True
403-
)
404-
== Client.e_SUCCESS
405-
)
406-
assert (
407-
proxy.create_client("producer2").open(
408-
URI_PRIORITY, flags=["write,ack"], block=True
409-
)
410-
!= Client.e_SUCCESS
411-
)
317+
@tweak(raise_max_queues)
318+
def test_tweak(cluster): ...
412319
```
413320

414321
## Running Tests
@@ -454,8 +361,10 @@ Tests can be selected using keywords (using the `-k` switch) and/or markers
454361
| `single` | tests that use a local cluster fixture |
455362
| `multi` | tests that use a 4-node, 2-proxy cluster fixture |
456363
| `multi7` | tests that use a 7-node, 4-proxy cluster fixture |
457-
| `legacy_mode` | choice between: legacy, FSM (with CSL) |
458-
| `fsm_mode` | choice between: legacy, FSM (with CSL) |
364+
| `legacy_mode` | tests using a cluster in legacy mode (CSL and FSM workflow disabled) |
365+
| `fsm_mode` | tests using a cluster in FSM mode (CSL and FSM workflow enabled) |
366+
| `eventual_consistency` | tests using an eventually consistent domain |
367+
| `strong_consistency` | tests using a strongly consistent domain |
459368
| `flakey` | tests that occasionally fail; excluded from the Jenkins PR check |
460369

461370
### Erroneous Exits
@@ -526,7 +435,7 @@ so, we insert `breakpoint()` inside `restart_nodes()` in `cluster.py`:
526435
Now, we open a terminal and from the BlazingMQ root directory:
527436

528437
```
529-
$ rit.sh --pdb -s -x -k migrate_domain --log-cli-level info
438+
$ src/integration-tests/run-tests --pdb -s -x -k migrate_domain --log-cli-level info
530439
```
531440

532441
`pdb`, the Python Debugger, will run until it hits the `breakpoint()`. Then, we
@@ -586,8 +495,8 @@ documentation](https://pypi.org/project/pytest-xdist/) for more information.
586495

587496
Example:
588497

589-
```python
590-
rit.sh -n 16
498+
```
499+
src/integration-tests/run-tests -n 16
591500
```
592501

593502
When parallelism is used, The `--bmq-log-dir DIR` switch should be used in

0 commit comments

Comments
 (0)