@@ -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
5354When 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
139140from 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
1721731 . 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
1761773 . 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 )
257249def 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
373292def 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`:
526435Now, 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
587496Example:
588497
589- ``` python
590- rit.sh - n 16
498+ ```
499+ src/integration-tests/run-tests -n 16
591500```
592501
593502When parallelism is used, The ` --bmq-log-dir DIR ` switch should be used in
0 commit comments