|
1 | | -# Toxiproxy Module |
2 | | - |
3 | | -Testcontainers module for Shopify's [Toxiproxy](https://github.com/Shopify/toxiproxy). |
4 | | -This TCP proxy can be used to simulate network failure conditions. |
5 | | - |
6 | | -You can simulate network failures: |
7 | | - |
8 | | -* between NodeJS code and containers, ideal for testing resilience features of client code |
9 | | -* between containers, for testing resilience and emergent behaviour of multi-container systems |
10 | | -* if desired, between NodeJS code/containers and external resources (non-Dockerized!), for scenarios where not all dependencies can be/have been dockerized |
11 | | - |
12 | | -Testcontainers Toxiproxy support allows resilience features to be easily verified as part of isolated dev/CI testing. This allows earlier testing of resilience features, and broader sets of failure conditions to be covered. |
| 1 | +# Toxiproxy |
13 | 2 |
|
14 | 3 | ## Install |
| 4 | + |
15 | 5 | ```bash |
16 | 6 | npm install @testcontainers/toxiproxy --save-dev |
17 | 7 | ``` |
18 | | - |
19 | | -## Usage example |
20 | | - |
21 | | -A Toxiproxy container can be placed in between test code and a container, or in between containers. |
22 | | -In either scenario, it is necessary to create a `ToxiProxyContainer` instance on the same Docker network. |
23 | 8 |
|
24 | | -Next, it is necessary to instruct Toxiproxy to start proxying connections. |
25 | | -Each `ToxiProxyContainer` can proxy to many target containers if necessary. |
| 9 | +## Examples |
26 | 10 |
|
27 | | -A proxy is created by calling `createProxy` on the `ToxiProxyContainer` instance. |
| 11 | +These examples use the following libraries: |
28 | 12 |
|
29 | | -The client connecting to the proxied endpoint then needs to use the exposed port from the returned proxy. |
| 13 | +- [toxiproxy-node-client](https://www.npmjs.com/package/toxiproxy-node-client) |
30 | 14 |
|
31 | | -All of this is done as follows: |
32 | | -<!--codeinclude--> |
33 | | -[Creating, starting and using the container:](../../packages/modules/toxiproxy/src/toxiproxy-container.test.ts) inside_block:create_proxy |
34 | | -<!--/codeinclude--> |
| 15 | + npm install toxiproxy-node-client |
35 | 16 |
|
36 | | -!!! note |
37 | | - Currently, `ToxiProxyContainer` will reserve 31 ports, starting at 8666. After this, trying to create a new proxy instance will throw an error. |
| 17 | +Choose an image from the [container registry](https://github.com/Shopify/toxiproxy/pkgs/container/toxiproxy) and substitute `IMAGE`. |
38 | 18 |
|
39 | | - |
40 | | -Having done all of this, it is possible to trigger failure conditions ('Toxics') through the `proxy.instance.addToxic<TPClient.TOXIC_TYPE>()` object: |
41 | | - |
42 | | -`TPClient` is the internal `toxiproxy-node-client` re-exported in this package. |
43 | | - |
44 | | -* `bandwidth` - Limit a connection to a maximum number of kilobytes per second. |
45 | | -* `latency` - Add a delay to all data going through the proxy. The delay is equal to `latency +/- jitter`. |
46 | | -* `slicer` - Slices TCP data up into small bits, optionally adding a delay between each sliced "packet". |
47 | | -* `slow_close` - Delay the TCP socket from closing until `delay` milliseconds has elapsed. |
48 | | -* `timeout` - Stops all data from getting through, and closes the connection after `timeout`. If `timeout` is `0`, the connection won't close, and data will be delayed until the toxic is removed. |
49 | | -* `limit_data` - Closes connection when transmitted data exceeded limit. |
50 | | -* `reset_peer` - Simulate TCP RESET (Connection reset by peer) on the connections |
51 | | - |
52 | | -Please see the [Toxiproxy documentation](https://github.com/Shopify/toxiproxy#toxics) and the [toxiproxy-node-client](https://github.com/ihsw/toxiproxy-node-client) for full details on the available Toxics. |
53 | | - |
54 | | -As one example, we can introduce latency and random jitter to proxied connections as follows: |
| 19 | +### Create a proxy |
55 | 20 |
|
56 | 21 | <!--codeinclude--> |
57 | | -[Adding latency to a connection](../../packages/modules/toxiproxy/src/toxiproxy-container.test.ts) inside_block:adding_toxic |
| 22 | +[](../../packages/modules/toxiproxy/src/toxiproxy-container.test.ts) inside_block:create_proxy |
58 | 23 | <!--/codeinclude--> |
59 | 24 |
|
60 | | -There is also a helper method to enable / disable specific proxy instances (for more fine-grained control instead of using the `reset_peer` toxic). This can also be done by calling the `proxy.instance.update` method, however it is more complicated as you'll need to supply the upstream again and the internal listening port. |
| 25 | +### Add a toxic |
61 | 26 |
|
62 | 27 | <!--codeinclude--> |
63 | | -[Enable and disable the proxy:](../../packages/modules/toxiproxy/src/toxiproxy-container.test.ts) inside_block:enabled_disabled |
| 28 | +[](../../packages/modules/toxiproxy/src/toxiproxy-container.test.ts) inside_block:adding_toxic |
64 | 29 | <!--/codeinclude--> |
65 | 30 |
|
66 | | -## Acknowledgements |
| 31 | +### Enable/disable the proxy |
67 | 32 |
|
68 | | -This module was inspired by the Java implementation, and under the hood uses the [toxiproxy-node-client](https://github.com/ihsw/toxiproxy-node-client). |
| 33 | +<!--codeinclude--> |
| 34 | +[](../../packages/modules/toxiproxy/src/toxiproxy-container.test.ts) inside_block:enabled_disabled |
| 35 | +<!--/codeinclude--> |
0 commit comments