Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Toxiproxy Php Client Laravel Package

ihsw/toxiproxy-php-client

A PHP client for Toxiproxy, the TCP proxy for simulating network conditions in tests. Create and manage proxies and toxics to inject latency, bandwidth limits, timeouts, and connection failures from PHP applications and test suites.

Deep Wiki
Context7

Getting Started

Install the client as a dev dependency — it is only useful in test/CI environments:

composer require --dev ihsw/toxiproxy-php-client

The client does not start Toxiproxy; you must run the Toxiproxy server separately. The quickest path is Docker:

docker run -d --name toxiproxy \
  -p 8474:8474 \
  -p 26379:26379 \
  shopify/toxiproxy

Then point the client at the HTTP API and create your first proxy:

use Toxiproxy\Toxiproxy;

$toxiproxy = new Toxiproxy('http://127.0.0.1:8474');

// name, upstream target, optional listen address
$proxy = $toxiproxy->create('redis', '127.0.0.1:6379', '127.0.0.1:26379');

// Simulate 500ms of downstream latency
$proxy->addToxic('latency', ['latency' => 500]);

Point your application’s Redis/MySQL/HTTP config at the proxy’s listen address (127.0.0.1:26379 above), and the test exercises your retry, timeout, fallback, or circuit-breaker logic instead of the real service.

Where to look first:

  • Toxiproxy\Toxiproxy — proxy lifecycle (create, get, all, delete, reset)
  • Toxiproxy\Proxy — per-proxy state and toxic management (addToxic, removeToxic, getToxics, setEnabled)
  • Toxiproxy\Toxic — returned toxic attributes
  • The Toxiproxy HTTP API docs for toxic attribute names, units, and stream direction

First useful use case: a PHPUnit test that adds a latency toxic to a Redis proxy and asserts your client retries or degrades gracefully, then removes the toxic and verifies recovery.

Implementation Patterns

Centralize lifecycle in a base test case or trait. Create proxies in setUp, tear them down in tearDown, and never leave proxies behind after a failure:

abstract class ToxiproxyTestCase extends TestCase
{
    protected Toxiproxy $toxiproxy;
    protected array $created = [];

    protected function setUp(): void
    {
        parent::setUp();
        $this->toxiproxy = new Toxiproxy(env('TOXIPROXY_URL', 'http://127.0.0.1:8474'));
    }

    protected function tearDown(): void
    {
        foreach ($this->created as $name) {
            try {
                $this->toxiproxy->delete($name);
            } catch (\Throwable $e) {
                // already gone or server unreachable
            }
        }
        parent::tearDown();
    }

    protected function proxy(string $name, string $upstream, ?string $listen = null): Proxy
    {
        $proxy = $this->toxiproxy->create($name, $upstream, $listen);
        $this->created[] = $name;
        return $proxy;
    }
}

Use one proxy per dependency, named per test class. Avoid a single shared proxy across a whole suite. Names like redis_retry_test, mysql_timeout_test, or http_fallback_test keep failures readable and prevent accidental cross-test toxic leakage.

Reuse proxies with reset() only when tests are serialized. POST /reset enables all proxies and removes all active toxics — convenient in setUp, but suite-wide and hostile to parallel test workers. For parallel runs, create and delete per test or per worker.

Point framework configs at the proxy before the connection is resolved. With Laravel, set the host/port in defineEnvironment / getEnvironmentSetUp, then purge pooled connections:

config([
    'database.connections.redis.host' => '127.0.0.1',
    'database.connections.redis.port' => 26379,
]);
DB::purge('redis');

Existing pooled connections bypass newly injected toxics; always purge or reconnect after changing toxics mid-test.

Pattern toxics by failure mode. Use latency for slow calls and retry/backoff assertions; bandwidth (KB/s) for large-transfer or streaming tests; timeout to close the connection after N ms; slicer to fragment packets; and proxy disablement for hard outages. For round-trip latency, add toxics on both downstream (server→client) and upstream (client→server) — a single latency toxic is one-directional.

Test the behavior, not Toxiproxy. Assert retry counts, fallback responses, cache writes, or circuit-breaker state. Toxiproxy introspection ($proxy->getToxics()) belongs in setup/debugging, not in assertions.

Expose a small fixture API in your suite. A Chaos::redis() helper that returns a configured proxy keeps test bodies short and ensures cleanup is always registered.

Gotchas and Tips

  • Server lifecycle is yours. The client only wraps HTTP calls. If Toxiproxy is not running, setup fails; fail fast with a clear message or skip explicitly rather than letting tests silently pass.
  • Create is not idempotent. Creating a proxy whose name already exists fails. Delete stale proxies first, or use get() when you intentionally reuse one.
  • Port collisions are the most common flake. Omit the listen address to let Toxiproxy assign a free port, then read it back from $proxy->getListen() and configure the app accordingly. Never hardcode ports in parallel CI jobs.
  • Clean up on fatal errors, not just assertions. Use try/finally, PHPUnit’s tearDownAfterClass, or a shutdown hook; a crashed test that leaves proxies behind poisons every later run.
  • Toxic direction and scope matter. Toxics are per-proxy, per-stream, and have unique names. Re-adding an existing toxic name may fail or behave unexpectedly; remove it first or intentionally update by name.
  • Units are easy to miss. Latency and timeout are milliseconds; bandwidth is KB/s. A “1000” latency is one second, not one millisecond.
  • Timeout toxics surface as connection resets. Applications may report ECONNRESET rather than a clean timeout; assert on the observed exception, not the expected one.
  • Disabled proxies refuse new connections but may not kill existing ones. Purge connection pools to make outage simulations reliable.
  • Docker networking differs from host networking. The upstream host is resolved from inside the Toxiproxy container, not from the PHP container. Use Docker service names (e.g. mysql:3306), not 127.0.0.1, when running in Compose/CI services.
  • Pin compatible versions. Match the Toxiproxy server image to the client’s expected API version (v2 API) and pin it in CI to avoid surprise behavior changes.
  • Debug with curl. curl -s http://127.0.0.1:8474/proxies | jq and /proxies/{name}/toxics show live state and are often faster than adding test logging.
  • Extend at the edges. A thin wrapper class (or PHPUnit extension) that owns naming, retries, health checks, and cleanup is more maintainable than sprinkling raw Toxiproxy calls through tests.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package