Skip to main content

README.md

# FakeRiak

A small tool that fakes several key-value services on TCP ports, all backed by a
single in-memory store. It speaks four wire protocols so you can point real
clients at it:

| Endpoint  | Protocol                | Buckets?   | Default port |
| --------- | ----------------------- | ---------- | ------------ |
| Riak KV   | Riak HTTP API           | bucketed   | 8098         |
| Redis     | RESP                    | bucketless | 6379         |
| etcd      | etcd v2 HTTP/JSON API   | bucketless | 2379         |
| memcached | memcached text protocol | bucketless | 11211        |

## Build

Build a single self-contained executable:

```console
$ mix escript.build
```

This produces a `fake_riak` script you can copy anywhere Erlang/OTP is
installed.

## Run

Enable one or more endpoints by passing its flag. Each takes an optional port;
without one it uses its well-known default:

```console
$ ./fake_riak --riak --redis            # Riak on 8098, Redis on 6379
$ ./fake_riak --etcd 3000               # etcd on port 3000
$ ./fake_riak --riak=8100 --memcached   # equals form works too
```

At least one endpoint must be enabled. By default it binds `127.0.0.1`; pass
`--host 0.0.0.0` to listen on all interfaces. Press **Ctrl-C** to stop.

Options:

| Flag                | Description                                        |
| ------------------- | -------------------------------------------------- |
| `--riak [PORT]`     | Enable the Riak KV HTTP API (default 8098)         |
| `--etcd [PORT]`     | Enable the etcd v2 HTTP/JSON API (default 2379)    |
| `--redis [PORT]`    | Enable the Redis RESP protocol (default 6379)      |
| `--memcached [PORT]`| Enable the memcached text protocol (default 11211) |
| `--host HOST`       | Interface to bind (default `127.0.0.1`)            |
| `--verbose`         | Log every get/put/del (API, bucket, key, value)    |
| `--version`         | Print the version and exit                         |
| `--help`            | Print usage and exit                               |

## Talk to it

```console
# Riak (bucketed, HTTP)
$ curl -X PUT -d 'meow' http://127.0.0.1:8098/buckets/animals/keys/cat
$ curl http://127.0.0.1:8098/buckets/animals/keys/cat            # -> meow

# etcd (bucketless, v2 HTTP/JSON)
$ curl -X PUT http://127.0.0.1:2379/v2/keys/message -d value=hello
$ curl http://127.0.0.1:2379/v2/keys/message                     # -> {"action":"get",...}

# Redis (bucketless, RESP)
$ redis-cli -p 6379 set foo bar
$ redis-cli -p 6379 get foo                                      # -> "bar"

# memcached (bucketless, text)
$ printf 'set greeting 0 0 5\r\nhello\r\nget greeting\r\n' | nc 127.0.0.1 11211
```

## Notes / limitations

These are deliberately faithful-enough fakes, not full servers:

* **memcached** accepts the `flags`/`exptime` on storage commands but does not
  persist them, so `get` always reports flags of `0` and keys never expire.
  `add`/`replace`/`append`/`prepend` behave properly, but the CAS value that
  `gets` reports is a hash of the value and the `cas` command itself is not
  implemented.
* **Redis** accepts the extra `SET` options (`NX`, `XX`, `EX`, ...) but ignores
  them — `SET` always stores and replies `OK`.
* **etcd** implements the v2 (HTTP/JSON) API, not the v3 (gRPC) API; indices are
  synthetic.
* **Riak** speaks the HTTP API (not the Protocol Buffers interface) and does not
  implement vector clocks, siblings, or 2i.

## Trademarks

Riak, Redis, etcd, and memcached are trademarks of their respective owners. This
project is an independent, unofficial testing tool. It is not affiliated with,
sponsored by, or endorsed by any of those projects — it merely speaks their wire
protocols so real clients can talk to it.