README
¶
OpenMock
OpenMock is a Go service that can mock services in integration tests, staging environment, or anywhere. The goal is to simplify the process of writing mocks in various channels. Currently it supports the following channels:
- HTTP
- gRPC
- Kafka
- AMQP (e.g. RabbitMQ)
Usage
Use it with docker.
$ docker run -it -p 9999:9999 -v $(pwd)/demo_templates:/data/templates checkr/openmock
More complete openmock instance (e.g. redis) with docker-compose.
$ docker-compose up
Test it.
$ curl localhost:9999/ping
Dependencies.
- HTTP (native supported, thanks to https://echo.labstack.com/)
- One can configure HTTP port, set env
OPENMOCK_HTTP_PORT=80
- One can configure HTTP port, set env
- GRPC (supported through through HTTP/2 interface)
- One can configure GRPC port, set env
OPENMOCK_GRPC_PORT=50051
- One can configure GRPC port, set env
- Kafka (optional)
- To enable mocking kafka, set env
OPENMOCK_KAFKA_ENABLED=true
. - One can also config the following kafka parameters, optionally with separate config for consumers and producers. For example
OPENMOCK_KAFKA_SEED_BROKERS
,OPENMOCK_KAFKA_PRODUCER_SEED_BROKERS
, andOPENMOCK_KAFKA_CONSUMER_SEED_BROKERS
OPENMOCK_KAFKA_SEED_BROKERS
OPENMOCK_KAFKA_SASL_USERNAME
OPENMOCK_KAFKA_SASL_PASSWORD
OPENMOCK_KAFKA_TLS_ENABLED
- To enable mocking kafka, set env
- AMQP (optional)
- To enable mocking amqp, set env
OPENMOCK_AMQP_ENABLED=true
- One can also config
OPENMOCK_AMQP_URL
.
- To enable mocking amqp, set env
- NPM (development only)
- Used in Makefile during swagger admin API server generation
OpenMock Templates
Templates are YAML files that describe the behavior of OpenMock.
Templates Directory
You can put any number of .yaml
or .yml
files in a directory, and then point
environment variable OPENMOCK_TEMPLATES_DIR
to it. OpenMock
will recursively (including subdirectories) load all the YAML files. For example:
# OPENMOCK_TEMPLATES_DIR=./demo_templates
./demo_templates
├── amqp.yaml
├── files
│ └── colors.json
├── http.yaml
├── jsonrpc.yaml
├── kafka.yaml
└── payload_from_file.yaml
Schema
OpenMock is configured a list of behaviors for it to follow. Each behavior is identified by a key, and a kind:
- key: respond-to-resource
kind: Behavior
Expect
It represents the channel to listen on and condition for the actions of the behavior to be performed. Available channels are:
- http
- kafka
- amqp
- grpc
For example, under what condition and from what channel should we proceed with the actions.
- key: no-op
kind: Behavior
expect:
# Condition checks if we need to do the actions or not
# It only proceeds if it evaluates to "true"
condition: '{{.HTTPHeader.Get "X-Token" | eq "t1234"}}'
# Use one (and only one) of the following channels - [http, kafka, amqp]
http:
method: GET
path: /ping
kafka:
topic: hello_kafka_in
amqp:
exchange: exchange_1
routing_key: key_in
queue: key_in
Actions
Actions are a series of functions to run. Availabe actions are:
- publish_amqp
- publish_kafka
- redis
- reply_http
- send_http
- reply_grpc
- sleep
- key: every-op
kind: Behavior
expect:
http:
method: GET
path: /ping
actions:
- publish_kafka:
topic: hello_kafka_out
payload: >
{
"kafka": "OK",
"data": {}
}
- sleep:
duration: 1s
- reply_http:
status_code: 200
body: OK
headers:
Content-Type: text/html
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.
- key: every-op
kind: Behavior
expect:
http:
method: GET
path: /ping
actions:
- publish_kafka:
topic: hello_kafka_out
payload: >
{
"kafka": "OK",
"data": {}
}
- sleep:
duration: 1s
# sleep first
order: -1000
Templates
Templates can be useful to assemble your payloads from parts
- key: dog
kind: Template
template: >
<animal>dog</animal>
- key: cat
kind: Template
template: >
<animal>cat</animal>
# $ curl 0:9999/fred
# <human> <name>fred</name> <pets> <animal>dog</animal> <animal>cat</animal> </pets> </human>
- key: get-freds-pets
kind: Behavior
expect:
http:
method: GET
path: /fred
actions:
- reply_http:
status_code: 200
body: >
<human>
<name>fred</name>
<pets>
{{template "dog"}}
{{template "cat"}}
</pets>
</human>
Abstract Behaviors
Abstract Behaviors can be used to parameterize some data.
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.
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
.
- key: fruit-of-the-day
kind: AbstractBehavior
values:
fruit: potato
expect:
condition: '{{.HTTPQueryString | contains .Values.day}}'
http:
method: GET
path: /fruit-of-the-day
actions:
- reply_http:
status_code: 200
body: '{"fruit": "{{.Values.fruit}}"}'
# $ curl 0:9999/fruit-of-the-day?day=monday
# {"fruit": "apple"}
- key: monday-fruit
kind: Behavior
extend: fruit-of-the-day
values:
day: monday
fruit: apple
# $ curl 0:9999/fruit-of-the-day?day=tuesday
# {"fruit": "potato"}
- key: tuesday-fruit
kind: Behavior
extend: fruit-of-the-day
values:
day: tuesday
actions:
# sleep then reply_http
- sleep:
duration: 1s
order: -1000
Dynamic templating
OpenMock leverages https://golang.org/pkg/text/template/ to write dynamic templates. Specifically, it supports a lot of Context and Helper Functions.
-
Usage of
{{ expr }}
. One can put{{ expr }}
inside three types of places:expect.condition
action.http.body
,action.grpc.payload
,action.kafka.payload
,action.amqp.payload
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)
-
Use Context inside
{{ expr }}
..HTTPHeader # type: http.Header; example: {{.HTTPHeader.Get "X-Token"}} .HTTPBody # type: string; example: {{.HTTPBody}} .HTTPPath # type: string; example: {{.HTTPPath}} .HTTPQueryString # type: string; example: {{.HTTPQueryString}} .GRPCHeader # type: string; example: {{.GRPCHeader}} .GRPCPayload # type: string; example: {{.GRPCPayload}} .GRPCService # type: string; example: {{.GRPCService}} .GRPCMethod # type: string; example: {{.GRPCMethod}} .KafkaTopic # type: string; example: {{.KafkaTopic}} .KafkaPayload # type: string; example: {{.KafkaPayload}} .AMQPExchange # type: string; example: {{.AMQPExchange}} .AMQPRoutingKey # type: string; example: {{.AMQPRoutingKey}} .AMQPQueue # type: string; example: {{.AMQPQueue}} .AMQPPayload # type: string; example: {{.AMQPPayload}}
-
Use helper functions inside
{{ expr }}
. We recommend pipeline format (|
) of the functions.# Supported functions defined in ./template_helper.go - - jsonPath # doc: https://github.com/antchfx/xpath - gJsonPath # doc: https://github.com/tidwall/gjson - xmlPath # doc: https://github.com/antchfx/xpath - uuidv5 # uuid v5 sha1 hash - redisDo # run redis commands. For example {{redisDo "RPUSH" "arr" "hi"}} - ... # Supported functions inherited from # https://github.com/Masterminds/sprig/blob/master/functions.go - replace - uuidv4 - regexMatch - ... # Examples {{.HTTPHeader.Get "X-Token" | eq "t1234"}} {{.HTTPBody | jsonPath "user/first_name" | replace "A" "a" | uuidv5 }} {{.HTTPBody | gJsonPath "users.0.first_name" }} {{.HTTPBody | xmlPath "node1/node2/node3"}}
Admin Interface
Openmock also by default provides an API on port 9998 to control the running instance. See api documentation. You can serve the api documentation by getting go-swagger and running:
./swagger serve --host 0.0.0.0 --port 9997 docs/api_docs/bundle.yaml"
Command Line Interface
Openmock has a command-line interface to help with certain tasks interacting with openmock instances. This is
invoked with the omctl
command. This uses the cobra library to provide a discoverable CLI; run omctl
for a list of commands / flags.
CLI: Directory
Push
Pushes a local openmock model from the file system to a remote instance.
# Adds templates from the ./demo_templates directory to the instance running on localhost.
omctl push --directory ./demo_templates --url http://localhost:9998
Examples
Example: Mock HTTP
# demo_templates/http.yaml
# $ curl 0:9999/ping
# OK
- key: ping
kind: Behavior
expect:
http:
method: GET
path: /ping
actions:
- reply_http:
status_code: 200
body: OK
headers:
Content-Type: text/html
# $ curl 0:9999/token -H X-Token:t1234 -H Y-Token:t1234
# OK
- key: header-token-200
kind: Behavior
expect:
condition: '{{.HTTPHeader.Get "X-Token" | eq "t1234" | and (.HTTPHeader.Get "Y-Token" | eq "t1234")}}'
http:
method: GET
path: /token
actions:
- reply_http:
status_code: 200
body: OK
# $ curl 0:9999/token
# Invalid X-Token
- key: header-token-401
kind: Behavior
expect:
condition: '{{.HTTPHeader.Get "X-Token" | ne "t1234"}}'
http:
method: GET
path: /token
actions:
- reply_http:
status_code: 401
body: Invalid X-Token
Example: Mock HTTP and reply with binary file
- key: get-pdf
expect:
http:
method: GET
path: /api/v1/:ClientID/pdf
condition: '{{
(.HTTPHeader.Get "Authorization" | contains "exp") | and
(.HTTPHeader.Get "x-timestamp" | eq "" | not)
}}'
actions:
- reply_http:
status_code: 200
headers:
Content-Type: application/pdf
body_from_binary_file: ./data/example.pdf
binary_file_name: example_pdf.pdf # optional file name
Example: Mock HTTP and reply with body from file
- key: get-json
expect:
http:
method: GET
path: /api/v1/:ClientID/json
condition: '{{
(.HTTPHeader.Get "Authorization" | contains "exp") | and
(.HTTPHeader.Get "x-timestamp" | eq "" | not)
}}'
actions:
- reply_http:
status_code: 200
headers:
Content-Type: application/json
body_from_file: ./data/example.json # only text files supported
Example: Mock GRPC
# demo_templates/grpc.yaml
- key: example_grpc
expect:
grpc:
service: demo_protobuf.ExampleService
method: ExampleMethod
actions:
- reply_grpc:
payload_from_file: './files/example_grpc_response.json'
Example: Mock Kafka
# demo_templates/kafka.yaml
- key: test_kafka_1
kind: Behavior
expect:
kafka:
topic: hello_kafka_in
actions:
- publish_kafka:
topic: hello_kafka_out
payload: >
{
"kafka": "OK",
"data": {}
}
- key: test_kafka_2
kind: Behavior
expect:
kafka:
topic: hello_kafka_in_2
actions:
- publish_kafka:
topic: hello_kafka_out
payload_from_file: './files/colors.json' # the path is relative to OPENMOCK_TEMPLATES_DIR
If you started the example from docker-compose, you can test the above kafka mocks by using a kt docker container.
# Exec into the container
docker-compose exec kt bash
# Run some kt commands inside the container
# Notice that the container is within the docker-compose network, and it connects to "kafka:9092"
$ kt topic
$ echo '{"123":"hi"}' | kt produce -topic hello_kafka_in -literal
$ kt consume -topic hello_kafka_out -offsets all=newest:newest
Example: Mock AMQP (e.g. RabbitMQ)
# demo_templates/amqp.yaml
- key: test_amqp_1
kind: Behavior
expect:
amqp:
exchange: exchange_1
routing_key: key_in
queue: key_in
actions:
- publish_amqp:
exchange: exchange_1
routing_key: key_out
payload: >
{
"amqp": "OK",
"data": {}
}
- key: test_amqp_2
kind: Behavior
expect:
amqp:
exchange: exchange_1
routing_key: key_in
queue: key_in
actions:
- publish_amqp:
exchange: exchange_1
routing_key: key_out
payload_from_file: './files/colors.json'
Example: Use Redis for stateful things (by default, OpenMock uses an in-memory miniredis)
# demo_templates/redis.yaml
- key: hello_redis
kind: Behavior
expect:
http:
method: GET
path: /test_redis
actions:
- redis:
- '{{.HTTPHeader.Get "X-TOKEN" | redisDo "SET" "k1"}}'
- '{{redisDo "RPUSH" "random" uuidv4}}'
- '{{redisDo "RPUSH" "random" uuidv4}}'
- '{{redisDo "RPUSH" "random" uuidv4}}'
- reply_http:
status_code: 200
body: >
{
"k1": "{{redisDo "GET" "k1"}}",
"randomStr": "{{redisDo "LRANGE" "random" 0 -1}}",
"random": [
{{ $arr := redisDo "LRANGE" "random" 0 -1 | splitList ";;" }}
{{ range $i, $v := $arr }}
{{if isLastIndex $i $arr}}
"{{$v}}"
{{else}}
"{{$v}}",
{{end}}
{{end}}
]
}
# To test
# curl localhost:9999/test_redis -H "X-TOKEN:t123" | jq .
Example: Send Webhooks
# demo_templates/webhook.yaml
- key: webhooks
kind: Behavior
expect:
http:
method: GET
path: /send_webhook_to_httpbin
actions:
- send_http:
url: "https://httpbin.org/post"
method: POST
body: '{"hello": "world"}'
headers:
X-Token: t123
- reply_http:
status_code: 200
body: 'webhooks sent'
# To test
# curl localhost:9999/send_webhook_to_httpbin
Example: Use data in templates
# demo_templates/http.yaml
- key: http-request-template
kind: Template
template: >
{ "http_path": "{{.HTTPPath}}", "http_headers": "{{.HTTPHeader}}" }
- key: color-template
kind: Template
template: >
{ "color": "{{.color}}" }
- key: teapot
kind: AbstractBehavior
expect:
http:
method: GET
path: /teapot
actions:
- reply_http:
status_code: 418
body: >
{
"request-info": {{ template "http-request-template" . }},
"teapot-info": {{ template "color-template" .Values }}
}
# $ curl 0:9999/teapot
# { "request-info": { "http_path": "/teapot", "http_headers": "map[Accept:[*/*] User-Agent:[curl/7.54.0]]" } , "teapot-info": { "color": "purple" } }
- key: purple-teapot
kind: Behavior
extend: teapot
values:
color: purple
Advanced pipeline functions
To enable advanced mocks, for example, your own encoding/decoding of the kafka messages,
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.
For example: (see example)
package main
import (
"github.com/checkr/openmock"
"github.com/checkr/openmock/swagger_gen/restapi"
"github.com/checkr/openmock/swagger_gen/restapi/operations"
/// etc
)
func consumePipelineFunc(c openmock.Context, in []byte) (out []byte, error) {
return decode(in), nil
}
func main() {
// server set up copy & paste...
// add our custom openmock functionality
om := &openmock.OpenMock{}
om.ParseEnv()
om.KafkaConsumePipelineFunc = consumePipelineFunc
server.ConfigureAPI(om)
// rest of server set up copy & paste...
}
GRPC Configuration Notes
OpenMock uses the APIv2 protobuf module (google.golang.org/protobuf). If your project uses the APIv1 protobuf module,
you can use https://github.com/golang/protobuf/releases/tag/v1.4.0 and convert your messages to be APIv2 compatible
with the proto.MessageV2
method.
Please note that OpenMock expects the payload
or payload_from_file
for a reply_grpc action to be in the json
form of your Response
protobuf message. The request should be in the Request
protobuf message format
as it is parsed into json to support jsonPath
and gJsonPath
operations.
Example configuration by directly importing the github.com/checkr/openmock
package into a wrapper project.
func main() {
// server set up copy & paste...
// add our custom openmock functionality
om := &openmock.OpenMock{}
om.GRPCServiceMap = map[string]openmock.GRPCService{
"demo_protobuf.ExampleService": {
"ExampleMethod": openmock.RequestResponsePair{
Request: proto.MessageV2(&demo_protobuf.ExampleRequest{}),
Response: proto.MessageV2(&demo_protobuf.ExampleResponse{}),
},
},
}
om.ParseEnv()
server.ConfigureAPI(om)
// rest of server set up copy & paste...
Swagger
Swagger files / directories:
Makefile # contains build process for swagger generation
swagger/ # directory containing swagger definition, split
# up into a few files
index.yaml # all the model definitions are in here
health.yaml # method definitions relating to e.g. /health
swagger_gen/ # directory where generated swagger files go
restapi/
configure_open_mock.go # this file contains code further customized from the
# generated code to hook an implementation into the API
# the makefiles makes sure it is preserved when
# generating the other files
docs/
api_docs/
bundle.yaml # combined swagger spec file, generated by Makefile
pkg/
admin/ # code implementing the handlers for the swagger API
Install Swagger
brew tap go-swagger/go-swagger
brew install go-swagger
Generate
make gen
- bundles the separate swagger files and generates swagger_genmake build
- builds the executablesom
andomctl
Run
OPENMOCK_REDIS_TYPE=redis OPENMOCK_REDIS_URL=<redis Url, e.g. redis://localhost:6379> OPENMOCK_TEMPLATES_DIR=./demo_templates ./om --port 9998
Documentation
¶
Index ¶
- Constants
- Variables
- type AMQPMocks
- type Action
- type ActionDispatcher
- type ActionPublishAMQP
- type ActionPublishKafka
- type ActionRedis
- type ActionReplyGRPC
- type ActionReplyHTTP
- type ActionSendHTTP
- type ActionSleep
- type Context
- type Expect
- type ExpectAMQP
- type ExpectGRPC
- type ExpectHTTP
- type ExpectKafka
- type GRPCMocks
- type GRPCRequestResponsePair
- type GRPCService
- type HTTPMocks
- type KafkaMocks
- type KafkaPipelineFunc
- type Mock
- type MockRepo
- type MocksArray
- type OpenMock
- func (om *OpenMock) Load() error
- func (om *OpenMock) ParseEnv()
- func (om *OpenMock) RedisDo(commandName string, args ...interface{}) (reply interface{}, err error)
- func (om *OpenMock) RedisTemplatesStore() string
- func (om *OpenMock) SetRedis()
- func (om *OpenMock) SetupLogrus()
- func (om *OpenMock) SetupRepo()
- func (om *OpenMock) Start()
- func (om *OpenMock) Stop()
- func (om *OpenMock) ToArray() []*Mock
- func (om *OpenMock) ToYAML() []byte
- type RedisDoer
Constants ¶
const ( KindBehavior = "Behavior" KindAbstractBehavior = "AbstractBehavior" KindTemplate = "Template" )
Variables ¶
var DefaultPipelineFunc = func(c Context, in []byte) (out []byte, err error) { return in, nil }
DefaultPipelineFunc directly outputs the in bytes
var GetActualAction = func(action ActionDispatcher) Action { if !structs.IsZero(action.ActionPublishAMQP) { return action.ActionPublishAMQP } if !structs.IsZero(action.ActionSendHTTP) { return action.ActionSendHTTP } if !structs.IsZero(action.ActionReplyHTTP) { return action.ActionReplyHTTP } if !structs.IsZero(action.ActionReplyGRPC) { return action.ActionReplyGRPC } if len(action.ActionRedis) > 0 { return action.ActionRedis } if !structs.IsZero(action.ActionPublishKafka) { return action.ActionPublishKafka } return action.ActionSleep }
Functions ¶
This section is empty.
Types ¶
type ActionDispatcher ¶
type ActionDispatcher struct { Order int `yaml:"order,omitempty"` ActionPublishAMQP ActionPublishAMQP `yaml:"publish_amqp,omitempty"` ActionPublishKafka ActionPublishKafka `yaml:"publish_kafka,omitempty"` ActionRedis ActionRedis `yaml:"redis,omitempty"` ActionReplyHTTP ActionReplyHTTP `yaml:"reply_http,omitempty"` ActionSendHTTP ActionSendHTTP `yaml:"send_http,omitempty"` ActionReplyGRPC ActionReplyGRPC `yaml:"reply_grpc,omitempty"` ActionSleep ActionSleep `yaml:"sleep,omitempty"` }
Action represents actions
type ActionPublishAMQP ¶
type ActionPublishAMQP struct { Exchange string `yaml:"exchange,omitempty"` RoutingKey string `yaml:"routing_key,omitempty"` Payload string `yaml:"payload,omitempty"` PayloadFromFile string `yaml:"payload_from_file,omitempty"` }
ActionPublishAMQP represents publish AMQP action
func (ActionPublishAMQP) Perform ¶
func (a ActionPublishAMQP) Perform(ctx Context) error
type ActionPublishKafka ¶
type ActionPublishKafka struct { Topic string `yaml:"topic,omitempty"` Payload string `yaml:"payload,omitempty"` PayloadFromFile string `yaml:"payload_from_file,omitempty"` }
ActionPublishKafka represents publish kafka action
func (ActionPublishKafka) Perform ¶
func (a ActionPublishKafka) Perform(ctx Context) error
type ActionRedis ¶
type ActionRedis []string
ActionRedis represents a list of redis commands
func (ActionRedis) Perform ¶
func (a ActionRedis) Perform(ctx Context) error
type ActionReplyGRPC ¶ added in v0.3.0
type ActionReplyGRPC struct { Headers map[string]string `yaml:"headers,omitempty"` Payload string `yaml:"payload,omitempty"` PayloadFromFile string `yaml:"payload_from_file,omitempty"` }
ActionReplyGRPC represents reply grpc action
func (ActionReplyGRPC) Perform ¶ added in v0.3.0
func (a ActionReplyGRPC) Perform(ctx Context) error
type ActionReplyHTTP ¶
type ActionReplyHTTP struct { StatusCode int `yaml:"status_code,omitempty"` Headers map[string]string `yaml:"headers,omitempty"` Body string `yaml:"body,omitempty"` BodyFromFile string `yaml:"body_from_file,omitempty"` BodyFromBinaryFile string `yaml:"body_from_binary_file,omitempty"` BinaryFileName string `yaml:"binary_file_name,omitempty"` BinaryFile []byte // Just for internal use }
ActionReplyHTTP represents reply http action
func (ActionReplyHTTP) Perform ¶
func (a ActionReplyHTTP) Perform(ctx Context) (err error)
type ActionSendHTTP ¶
type ActionSendHTTP struct { URL string `yaml:"url,omitempty"` Method string `yaml:"method,omitempty"` Headers map[string]string `yaml:"headers,omitempty"` Body string `yaml:"body,omitempty"` BodyFromFile string `yaml:"body_from_file,omitempty"` BodyFromBinaryFile string `yaml:"body_from_binary_file,omitempty"` BinaryFileName string `yaml:"binary_file_name,omitempty"` BinaryFile []byte // Just for internal use }
ActionSendHTTP represents the send http action
func (ActionSendHTTP) Perform ¶
func (a ActionSendHTTP) Perform(ctx Context) error
type ActionSleep ¶
ActionSleep represents the sleep action
func (ActionSleep) Perform ¶
func (a ActionSleep) Perform(ctx Context) error
type Context ¶
type Context struct { HTTPContext echo.Context HTTPHeader http.Header HTTPBody string HTTPPath string HTTPQueryString string GRPCService string GRPCMethod string GRPCContext echo.Context GRPCHeader http.Header GRPCPayload string KafkaTopic string KafkaPayload string AMQPExchange string AMQPRoutingKey string AMQPQueue string AMQPPayload string Values map[string]interface{} // contains filtered or unexported fields }
Context represents the context of the mock expectation
func (Context) MatchCondition ¶
MatchCondition checks the condition given the context
type Expect ¶
type Expect struct { Condition string `yaml:"condition,omitempty"` HTTP ExpectHTTP `yaml:"http,omitempty"` Kafka ExpectKafka `yaml:"kafka,omitempty"` AMQP ExpectAMQP `yaml:"amqp,omitempty"` GRPC ExpectGRPC `yaml:"grpc,omitempty"` }
Expect represents what to expect from a mock
type ExpectAMQP ¶
type ExpectAMQP struct { Exchange string `yaml:"exchange,omitempty"` RoutingKey string `yaml:"routing_key,omitempty"` Queue string `yaml:"queue,omitempty"` }
ExpectAMQP represents amqp expectation
type ExpectGRPC ¶ added in v0.3.0
type ExpectGRPC struct { Service string `yaml:"service,omitempty"` Method string `yaml:"method,omitempty"` }
ExpectGRPC represents grpc expectation
type ExpectHTTP ¶
type ExpectHTTP struct { Method string `yaml:"method,omitempty"` Path string `yaml:"path,omitempty"` }
ExpectHTTP represents http expectation
type ExpectKafka ¶
type ExpectKafka struct {
Topic string `yaml:"topic,omitempty"`
}
ExpectKafka represents kafka expectation
type GRPCMocks ¶ added in v0.3.0
type GRPCMocks map[ExpectGRPC]MocksArray
GRPCMocks is keyed by service/method
type GRPCRequestResponsePair ¶ added in v0.3.0
GRPCRequestResponsePair is a pair of proto.Message to define the message schema of request and response of a method
type GRPCService ¶ added in v0.3.0
type GRPCService map[string]GRPCRequestResponsePair
GRPCService is a map of service_name => GRPCRequestResponsePair
type KafkaPipelineFunc ¶
KafkaPipelineFunc defines pipeline functions For example, decode/encode messages
type Mock ¶
type Mock struct { // Common fields Kind string `yaml:"kind,omitempty"` Key string `yaml:"key,omitempty"` Extend string `yaml:"extend,omitempty"` // KindBehavior fields Expect Expect `yaml:"expect,omitempty"` Actions []ActionDispatcher `yaml:"actions,omitempty"` Values map[string]interface{} `yaml:"values,omitempty"` // KindTemplate fields Template string `yaml:"template,omitempty"` }
Mock represents a mock struct swagger:model
type MockRepo ¶
type MockRepo struct { HTTPMocks HTTPMocks GRPCMocks GRPCMocks KafkaMocks KafkaMocks AMQPMocks AMQPMocks Templates MocksArray Behaviors *orderedmap.OrderedMap }
MockRepo stores a repository of Mocks
type MocksArray ¶
type MocksArray []*Mock
MocksArray represents an array of Mocks
func (MocksArray) DoActions ¶
func (ms MocksArray) DoActions(ctx Context)
type OpenMock ¶
type OpenMock struct { LogLevel string `env:"OPENMOCK_LOG_LEVEL" envDefault:"info"` TemplatesDir string `env:"OPENMOCK_TEMPLATES_DIR" envDefault:"./templates"` TemplatesDirHotReload bool `env:"OPENMOCK_TEMPLATES_DIR_HOT_RELOAD" envDefault:"true"` // HTTP channel HTTPEnabled bool `env:"OPENMOCK_HTTP_ENABLED" envDefault:"true"` HTTPPort int `env:"OPENMOCK_HTTP_PORT" envDefault:"9999"` HTTPHost string `env:"OPENMOCK_HTTP_HOST" envDefault:"0.0.0.0"` CorsEnabled bool `env:"OPENMOCK_CORS_ENABLED" envDefault:"false"` // Admin channel AdminHTTPEnabled bool `env:"OPENMOCK_ADMIN_HTTP_ENABLED" envDefault:"true"` AdminHTTPPort int `env:"OPENMOCK_ADMIN_HTTP_PORT" envDefault:"9998"` AdminHTTPHost string `env:"OPENMOCK_ADMIN_HTTP_HOST" envDefault:"0.0.0.0"` // Kafka channel KafkaEnabled bool `env:"OPENMOCK_KAFKA_ENABLED" envDefault:"false"` KafkaClientID string `env:"OPENMOCK_KAFKA_CLIENT_ID" envDefault:"openmock"` KafkaSeedBrokers []string `env:"OPENMOCK_KAFKA_SEED_BROKERS" envDefault:"kafka:9092" envSeparator:","` KafkaSaslUsername string `env:"OPENMOCK_KAFKA_SASL_USERNAME" envDefault:""` KafkaSaslPassword string `env:"OPENMOCK_KAFKA_SASL_PASSWORD" envDefault:""` KafkaTLSEnabled bool `env:"OPENMOCK_KAFKA_TLS_ENABLED" envDefault:"false"` KafkaProducerSeedBrokers []string `env:"OPENMOCK_KAFKA_PRODUCER_SEED_BROKERS" envDefault:"" envSeparator:","` KafkaSaslProducerUsername string `env:"OPENMOCK_KAFKA_SASL_PRODUCER_USERNAME" envDefault:""` KafkaSaslProducerPassword string `env:"OPENMOCK_KAFKA_SASL_PRODUCER_PASSWORD" envDefault:""` KafkaTLSProducerEnabled bool `env:"OPENMOCK_KAFKA_TLS_PRODUCER_ENABLED" envDefault:""` KafkaConsumerSeedBrokers []string `env:"OPENMOCK_KAFKA_CONSUMER_SEED_BROKERS" envDefault:"" envSeparator:","` KafkaSaslConsumerUsername string `env:"OPENMOCK_KAFKA_SASL_CONSUMER_USERNAME" envDefault:""` KafkaSaslConsumerPassword string `env:"OPENMOCK_KAFKA_SASL_CONSUMER_PASSWORD" envDefault:""` KafkaTLSConsumerEnabled bool `env:"OPENMOCK_KAFKA_TLS_CONSUMER_ENABLED" envDefault:""` // AMQP channel AMQPEnabled bool `env:"OPENMOCK_AMQP_ENABLED" envDefault:"false"` AMQPURL string `env:"OPENMOCK_AMQP_URL" envDefault:"amqp://guest:guest@rabbitmq:5672"` // Redis configuration for admin's ephemeral storage or redis commands RedisType string `env:"OPENMOCK_REDIS_TYPE" envDefault:"memory"` RedisURL string `env:"OPENMOCK_REDIS_URL" envDefault:"redis://redis:6379"` // GRPC channel GRPCEnabled bool `env:"OPENMOCK_GRPC_ENABLED" envDefault:"false"` GRPCPort int `env:"OPENMOCK_GRPC_PORT" envDefault:"50051"` GRPCHost string `env:"OPENMOCK_GRPC_HOST" envDefault:"0.0.0.0"` //////////////////////// Customized functions ////////////////////////////////// // KafkaConsumePipelineFunc is a pipeline function run to when consume a message KafkaConsumePipelineFunc KafkaPipelineFunc // KafkaPublishPipelineFunc is a pipeline function run to when produce a message KafkaPublishPipelineFunc KafkaPipelineFunc // GRPCServiceMap is a map of gRPC [service_name => GRPCService] GRPCServiceMap map[string]GRPCService // contains filtered or unexported fields }
OpenMock holds all the configuration of running openmock
func (*OpenMock) ParseEnv ¶
func (om *OpenMock) ParseEnv()
ParseEnv loads env vars into the openmock struct
func (*OpenMock) RedisTemplatesStore ¶
func (*OpenMock) SetRedis ¶
func (om *OpenMock) SetRedis()
SetRedis sets the Redis store for OpenMock
func (*OpenMock) SetupLogrus ¶
func (om *OpenMock) SetupLogrus()