Skip to content

Commit e19ad6a

Browse files
Updated readme docs
1 parent 18b963e commit e19ad6a

File tree

1 file changed

+97
-13
lines changed

1 file changed

+97
-13
lines changed

README.md

Lines changed: 97 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
</p>
1414

1515
# OpenMock
16+
1617
OpenMock is a Go service that can mock services in integration tests, staging environment, or anywhere.
1718
The goal is to simplify the process of writing mocks in various channels.
1819
Currently it supports the following channels:
@@ -23,22 +24,27 @@ Currently it supports the following channels:
2324
- AMQP (e.g. RabbitMQ)
2425

2526
# Usage
27+
2628
Use it with docker.
29+
2730
```bash
2831
$ docker run -it -p 9999:9999 -v $(pwd)/demo_templates:/data/templates checkr/openmock
2932
```
3033

3134
More complete openmock instance (e.g. redis) with docker-compose.
35+
3236
```bash
3337
$ docker-compose up
3438
```
3539

3640
Test it.
41+
3742
```bash
3843
$ curl localhost:9999/ping
3944
```
4045

4146
Dependencies.
47+
4248
- HTTP (native supported, thanks to https://echo.labstack.com/)
4349
- One can configure HTTP port, set env `OPENMOCK_HTTP_PORT=80`
4450
- GRPC (supported through through HTTP/2 interface)
@@ -57,9 +63,11 @@ Dependencies.
5763
- Used in Makefile during swagger admin API server generation
5864

5965
# OpenMock Templates
66+
6067
Templates are YAML files that describe the behavior of OpenMock.
6168

6269
## Templates Directory
70+
6371
You can put any number of `.yaml` or `.yml` files in a directory, and then point
6472
environment variable `OPENMOCK_TEMPLATES_DIR` to it. OpenMock
6573
will recursively (including subdirectories) load all the YAML files. For example:
@@ -78,8 +86,10 @@ will recursively (including subdirectories) load all the YAML files. For example
7886
```
7987

8088
## Schema
89+
8190
OpenMock is configured a list of behaviors for it to follow. Each behavior is
8291
identified by a key, and a kind:
92+
8393
```yaml
8494
- key: respond-to-resource
8595
kind: Behavior
@@ -116,9 +126,11 @@ we proceed with the actions.
116126
routing_key: key_in
117127
queue: key_in
118128
```
119-
129+
120130
### Actions
131+
121132
Actions are a series of functions to run. Availabe actions are:
133+
122134
- publish_amqp
123135
- publish_kafka
124136
- redis
@@ -152,6 +164,7 @@ Actions are a series of functions to run. Availabe actions are:
152164
```
153165
154166
The actions by default run in the order defined in the mock file; you can adjust this by adding an int 'order' value from lowest to highest number. The default value for 'order' is 0.
167+
155168
```yaml
156169
- key: every-op
157170
kind: Behavior
@@ -174,6 +187,7 @@ The actions by default run in the order defined in the mock file; you can adjust
174187
```
175188
176189
### Templates
190+
177191
Templates can be useful to assemble your payloads from parts
178192
179193
```yaml
@@ -209,10 +223,12 @@ Templates can be useful to assemble your payloads from parts
209223
```
210224
211225
### Abstract Behaviors
226+
212227
Abstract Behaviors can be used to parameterize some data.
213228
214229
When an abstract behavior and a behavior extending it both have actions defined, all of them are run when the behavior matches. Actions will run from lowest to highest value of the 'order' field; if this is the same for two actions the action defined earlier in the abstract behavior runs first, followed by actions in the concrete behavior.
215230
Be aware that values with all digits will be interpreted into `int` type (YAML syntax), and it will fail the condition check given that some helper functions are returning `string` types. Pipe to `toString` before the comparison or alternatively put quotes around the values. See example in `abstract_behaviors.yml`.
231+
216232
```yaml
217233
- key: fruit-of-the-day
218234
kind: AbstractBehavior
@@ -249,56 +265,61 @@ Be aware that values with all digits will be interpreted into `int` type (YAML s
249265
- sleep:
250266
duration: 1s
251267
order: -1000
252-
253268
```
254269

255270
### Dynamic templating
271+
256272
OpenMock leverages [https://golang.org/pkg/text/template/](https://golang.org/pkg/text/template/) to write dynamic templates. Specifically, it supports a lot of _Context_ and _Helper Functions_.
257273

258274
- Usage of `{{ expr }}`. One can put `{{ expr }}` inside three types of places:
275+
259276
- `expect.condition`
260277
- `action.http.body`, `action.grpc.payload`, `action.kafka.payload`, `action.amqp.payload`
261-
- `action.http.body_from_file`, `action.http.body_from_binary_file` `action.grpc.payload_from_file`, `action.kafka.payload_from_file`, `action.amqp.payload_from_file` (`{{ expr }}` will be in the file)
278+
- `action.http.body_from_file`, `action.http.body_from_binary_file`, `action.http.binary_file_name` ,`action.grpc.payload_from_file`, `action.kafka.payload_from_file`, `action.amqp.payload_from_file` (`{{ expr }}` will be in the file)
279+
262280
- Use Context inside `{{ expr }}`.
281+
263282
```bash
264283
.HTTPHeader # type: http.Header; example: {{.HTTPHeader.Get "X-Token"}}
265284
.HTTPBody # type: string; example: {{.HTTPBody}}
266285
.HTTPPath # type: string; example: {{.HTTPPath}}
267286
.HTTPQueryString # type: string; example: {{.HTTPQueryString}}
268-
287+
269288
.GRPCHeader # type: string; example: {{.GRPCHeader}}
270289
.GRPCPayload # type: string; example: {{.GRPCPayload}}
271290
.GRPCService # type: string; example: {{.GRPCService}}
272291
.GRPCMethod # type: string; example: {{.GRPCMethod}}
273292
274293
.KafkaTopic # type: string; example: {{.KafkaTopic}}
275294
.KafkaPayload # type: string; example: {{.KafkaPayload}}
276-
295+
277296
.AMQPExchange # type: string; example: {{.AMQPExchange}}
278297
.AMQPRoutingKey # type: string; example: {{.AMQPRoutingKey}}
279298
.AMQPQueue # type: string; example: {{.AMQPQueue}}
280299
.AMQPPayload # type: string; example: {{.AMQPPayload}}
281300
```
301+
282302
- Use helper functions inside `{{ expr }}`. We recommend pipeline format (`|`) of the functions.
303+
283304
```bash
284305
# Supported functions defined in ./template_helper.go
285-
306+
286307
-
287308
- jsonPath # doc: https://github.com/antchfx/xpath
288309
- gJsonPath # doc: https://github.com/tidwall/gjson
289310
- xmlPath # doc: https://github.com/antchfx/xpath
290311
- uuidv5 # uuid v5 sha1 hash
291312
- redisDo # run redis commands. For example {{redisDo "RPUSH" "arr" "hi"}}
292313
- ...
293-
314+
294315
# Supported functions inherited from
295316
# https://github.com/Masterminds/sprig/blob/master/functions.go
296-
317+
297318
- replace
298319
- uuidv4
299320
- regexMatch
300321
- ...
301-
322+
302323
# Examples
303324
{{.HTTPHeader.Get "X-Token" | eq "t1234"}}
304325
{{.HTTPBody | jsonPath "user/first_name" | replace "A" "a" | uuidv5 }}
@@ -307,25 +328,33 @@ OpenMock leverages [https://golang.org/pkg/text/template/](https://golang.org/pk
307328
```
308329

309330
## Admin Interface
331+
310332
Openmock also by default provides an API on port 9998 to control the running instance. See [api documentation](docs/api_docs/bundle.yaml). You can serve the api documentation by getting [go-swagger](https://github.com/go-swagger/go-swagger) and running:
333+
311334
```
312335
./swagger serve --host 0.0.0.0 --port 9997 docs/api_docs/bundle.yaml"
313336
```
314337

315338
## Command Line Interface
339+
316340
Openmock has a command-line interface to help with certain tasks interacting with openmock instances. This is
317341
invoked with the `omctl` command. This uses the [cobra](https://github.com/spf13/cobra) library to provide a discoverable CLI; run `omctl` for a list of commands / flags.
318342

319343
### CLI: Directory
344+
320345
#### Push
346+
321347
Pushes a local openmock model from the file system to a remote instance.
348+
322349
```
323350
# Adds templates from the ./demo_templates directory to the instance running on localhost.
324351
omctl push --directory ./demo_templates --url http://localhost:9998
325352
```
326353
327354
## Examples
355+
328356
### Example: Mock HTTP
357+
329358
```yaml
330359
# demo_templates/http.yaml
331360
@@ -371,10 +400,53 @@ omctl push --directory ./demo_templates --url http://localhost:9998
371400
- reply_http:
372401
status_code: 401
373402
body: Invalid X-Token
403+
```
374404

405+
### Example: Mock HTTP and reply with binary file
406+
407+
```yaml
408+
- key: get-pdf
409+
expect:
410+
http:
411+
method: GET
412+
path: /api/v1/:ClientID/pdf
413+
condition: '{{
414+
(.HTTPHeader.Get "Authorization" | contains "exp") | and
415+
(.HTTPHeader.Get "x-timestamp" | eq "" | not)
416+
}}'
417+
actions:
418+
- reply_http:
419+
status_code: 200
420+
headers:
421+
Content-Type: application/pdf
422+
body_from_binary_file: ./data/example.pdf
423+
binary_file_name: example_pdf.pdf # optional file name
424+
```
425+
426+
###
427+
428+
### Example: Mock HTTP and reply with body from file
429+
430+
```yaml
431+
- key: get-json
432+
expect:
433+
http:
434+
method: GET
435+
path: /api/v1/:ClientID/json
436+
condition: '{{
437+
(.HTTPHeader.Get "Authorization" | contains "exp") | and
438+
(.HTTPHeader.Get "x-timestamp" | eq "" | not)
439+
}}'
440+
actions:
441+
- reply_http:
442+
status_code: 200
443+
headers:
444+
Content-Type: application/json
445+
body_from_file: ./data/example.json # only text files supported
375446
```
376447
377448
### Example: Mock GRPC
449+
378450
```yaml
379451
# demo_templates/grpc.yaml
380452

@@ -389,6 +461,7 @@ omctl push --directory ./demo_templates --url http://localhost:9998
389461
```
390462
391463
### Example: Mock Kafka
464+
392465
```yaml
393466
# demo_templates/kafka.yaml
394467

@@ -432,6 +505,7 @@ $ kt consume -topic hello_kafka_out -offsets all=newest:newest
432505
```
433506

434507
### Example: Mock AMQP (e.g. RabbitMQ)
508+
435509
```yaml
436510
# demo_templates/amqp.yaml
437511

@@ -467,6 +541,7 @@ $ kt consume -topic hello_kafka_out -offsets all=newest:newest
467541
```
468542
469543
### Example: Use Redis for stateful things (by default, OpenMock uses an in-memory miniredis)
544+
470545
```yaml
471546
# demo_templates/redis.yaml
472547

@@ -505,6 +580,7 @@ $ kt consume -topic hello_kafka_out -offsets all=newest:newest
505580
```
506581

507582
### Example: Send Webhooks
583+
508584
```yaml
509585
# demo_templates/webhook.yaml
510586

@@ -530,6 +606,7 @@ $ kt consume -topic hello_kafka_out -offsets all=newest:newest
530606
```
531607

532608
### Example: Use data in templates
609+
533610
```yaml
534611
# demo_templates/http.yaml
535612

@@ -567,13 +644,14 @@ $ kt consume -topic hello_kafka_out -offsets all=newest:newest
567644
color: purple
568645
```
569646
570-
571647
# Advanced pipeline functions
648+
572649
To enable advanced mocks, for example, your own encoding/decoding of the kafka messages,
573650
one can develop by directly importing the `github.com/checkr/openmock` package, making a copy of the swagger-generated server main, and passing in a custom OpenMock.
574651

575652
For example:
576653
(see [example](https://github.com/sesquipedalian-dev/openmock-custom-example/blob/master/main.go))
654+
577655
```go
578656
package main
579657
@@ -590,7 +668,7 @@ func consumePipelineFunc(c openmock.Context, in []byte) (out []byte, error) {
590668
591669
func main() {
592670
// server set up copy & paste...
593-
671+
594672
// add our custom openmock functionality
595673
om := &openmock.OpenMock{}
596674
om.ParseEnv()
@@ -603,6 +681,7 @@ func main() {
603681
```
604682

605683
## GRPC Configuration Notes
684+
606685
OpenMock uses the APIv2 protobuf module (google.golang.org/protobuf). If your project uses the APIv1 protobuf module,
607686
you can use https://github.com/golang/protobuf/releases/tag/v1.4.0 and convert your messages to be APIv2 compatible
608687
with the `proto.MessageV2` method.
@@ -612,10 +691,11 @@ form of your `Response` protobuf message. The request should be in the `Request
612691
as it is parsed into json to support `jsonPath` and `gJsonPath` operations.
613692

614693
Example configuration by directly importing the `github.com/checkr/openmock` package into a wrapper project.
694+
615695
```
616696
func main() {
617697
// server set up copy & paste...
618-
698+
619699
// add our custom openmock functionality
620700
om := &openmock.OpenMock{}
621701
om.GRPCServiceMap = map[string]openmock.GRPCService{
@@ -632,8 +712,10 @@ func main() {
632712
// rest of server set up copy & paste...
633713
```
634714
635-
## Swagger
715+
## Swagger
716+
636717
### Swagger files / directories:
718+
637719
```
638720
Makefile # contains build process for swagger generation
639721
swagger/ # directory containing swagger definition, split
@@ -661,8 +743,10 @@ brew install go-swagger
661743
```
662744
663745
### Generate
746+
664747
* `make gen` - bundles the separate swagger files and generates swagger_gen
665748
* `make build` - builds the executables `om` and `omctl`
666749
667750
### Run
751+
668752
`OPENMOCK_REDIS_TYPE=redis OPENMOCK_REDIS_URL=<redis Url, e.g. redis://localhost:6379> OPENMOCK_TEMPLATES_DIR=./demo_templates ./om --port 9998`

0 commit comments

Comments
 (0)