Fake-O-Matic is a utility tool for creating and sending fake payloads to endpoints in order to test throughput. On each iteration, Fake-O-Matic will generate a payload based on a provided template and a set of rules for generating fake data.
Fake-O-Matic is published in Quay.io, and the library is published in Central Maven Repo under the following properties:
- groupId
-
io.backpackcloud
- artifactId
-
fakeomatic
Navigate to https://requestbin.com/ and create a request bin (uncheck the private option and choose the old bin). Copy the Endpoint url.
Now build a JVM version of Fake-O-Matic with mvn package
and run it (yeah, I know… downloading the internet is not
quick):
$ java -jar target/fakeomatic-$VERSION-runner.jar \
--endpoint-url https://YOUR_REQUEST_BIN_ID.x.pipedream.net/ \
--template examples/example1.json
Note
|
You may also download the binaries from the releases page. |
Fake-O-Matic is build with Quarkus and supports native compilation. THe build is a good and old
mvn package
command. If you wish to build a native binary, just activate the native
profile
(mvn -P native package
).
It’s also possible to build Fake-O-Matic using source-to-image:
s2i build . quay.io/quarkus/ubi-quarkus-native-s2i:19.3.2-java11 backpackcloud/fakeomatic
Fake-O-Matic is configured through a set of yaml
files that forms a hierarchy. If some configuration is not found on
one file, then the next file is used. That also means that you can override configurations by leaving the default values
as the last in the hierarchy.
A Fake-O-Matic configuration has:
endpoints: # (1)
endpoint_name:
# configuration ...
samples: # (2)
sample_name:
# configuration
placeholders: # (3)
"PLACEHOLDER_CHARACTER": sample_name
-
At least one endpoint
-
Ideally as much samples as needed
-
Optional placeholders for creating expressions
The configuration for each part is covered through this document.
Some configuration values can be externalized by different ways additionally to the normal String value:
- env
-
Fetches the value from an Environment Variable.
param:
env: PARAM # reads the value from the PARAM environment variable (export PARAM=foo)
- property
-
Fetches the value from a System Property.
param:
property: my.parameter # reads the value from the my.parameter system property (-Dmy.parameter=foo)
- file
-
Reads the value from a
file
.
param:
file: /tmp/myfile # reads the value from the /tmp/myfile content
- resource
-
Reads the value using a
class.getResourceAsStream
.
param:
resource: /com/example/configuration.yaml # reads the value from the configuration.yaml
# file inside the com.example package
- url
-
Reads the value from the given URL by using GET
url
.
param:
url: http://something.example.com/some-param
- value
-
Supplies a raw value.
param:
value: bar # uses "bar" as the value if the PARAM environment variable is not present
It is also possible to combine different approaches for getting the value by passing all the desired options. The first one that holds a value will be used (see the priority bellow):
param:
env: PARAM
property: my.parameter
value: bar
The priority for getting the value is:
-
env
-
property
-
file
-
resource
-
url
-
value
It’s also possible to supply a raw value without specifying the type value
if it’s the only value:
param: some value # implies a configuration of type "value"
Some samples take other samples as configuration. In most cases, there are two ways of passing a sample as configuration:
-
Referring through a
ref
property. -
Directly through a
sample
property.
An endpoint is primarily used to send generated payloads but can also be used as a source of data for the samples.
- url
-
A configuration value defining the API endpoint.
- method
-
Which HTTP method to use (defaults to
GET
). - payload
-
An optional payload object to use for calling the API. Useful for
POST
requests.- template
-
A configuration defining which template to use
- content-type
-
The content type of the template (defaults to
application/json
).
- insecure
-
Defines if the certificates should be trusted without checking (defaults to
false
). - concurrency
-
A configuration
int
value that defines the max ongoing connections to this endpoint. (Defaults to10
.) - buffer
-
A configuration
int
value that defines how many requests can be enqueued when the max ongoing requests number is reached. (Defaults to10
.)
This is useful in cases where generating the payloads can take more time than it takes to send them (like depending on several external APIs).
- headers
-
A
string,configuration
map containing the headers to use. - params
-
A
string,configuration
map containing all the values that forms the url (example:/api/{uuid}
will be replaced by the value from the path_varuuid
).
Fake-O-Matic defines a default
endpoint which can be customized via configuration values:
endpoints:
default:
url:
env: ENDPOINT_URL
property: endpoint.url
value: http://localhost:8080
payload:
content-type:
env: ENDPOINT_CONTENT_TYPE
property: endpoint.content_type
value: application/json
template:
env: ENDPOINT_TEMPLATE
property: endpoint.template
resource: /META-INF/resources/config/payload.json
method:
env: ENDPOINT_METHOD
property: endpoint.method
value: POST
concurrency:
env: ENDPOINT_CONCURRENCY
property: endpoint.concurrency
value: 10
buffer:
env: ENDPOINT_BUFFER
property: endpoint.buffer
value: 10
insecure:
env: ENDPOINT_INSECURE
property: endpoint.insecure
value: false
Please see Configuration Properties for more information.
The rules for generating data can contain sample
and placeholders
. Samples are a set of data that Fake-O-Matic can
randomly pick and placeholders are characters that can be associated with the samples for to allow the use of
expressions for generating data.
This sample can pick any character from a given string. Useful for defining a set of characters that can be used to produce IDs or any other information that is not meant to be read.
This sample can pick any item from a given list of objects.
- type
-
list
- values
-
List of raw values to use.
- samples
-
List of Samples to use.
- source
-
A configuration pointing to where to locate the list of values.
Note
|
You need to supply only one way of loading the values (values , sample or source ).
|
samples:
cause:
type: list
values:
- "clock speed"
- "solar flares"
- "electromagnetic radiation from satellite debris"
- "static from nylon underwear"
- "static from plastic slide rules"
- "global warming"
- "poor power conditioning"
- "static buildup"
- "doppler effect"
first_name:
type: list
samples:
- man_name
- woman_name
story:
type: list
source:
env: STORIES
property: stories
default: stories.txt
This sample actually calls a given API to get data to use every time it’s asked for a data.
Warning
|
Due to the nature of this sample, it’s not possible to reproduce the same payloads without relying on the dependent API. |
- type
-
api
- endpoint
-
An endpoint configuration for the api to use.
Note
|
Although this sample uses an Endpoint object, which supports concurrency and buffers, the sample is synchronous
so configuring those values will not have any effect on this sample.
|
samples:
chuck_norris:
type: api
endpoint:
url: https://api.chucknorris.io/jokes/random
example:
type: api
endpoint:
url: https://api.example.com/{version}/some/path
headers:
token:
env: EXAMPLE_API_TOKEN
property: example.api.token
params:
version:
env: EXAMPLE_API_VERSION
property: example.api.version
value: v1
This sample extracts a value from a JSON object. Useful when used in combination with the API Sample.
- type
-
json
- path
-
A JSON Pointer to specify which value to take from the JSON object.
- source
-
Which sample sample should be used to obtain the JSON object.
This sample will produce a universally unique identifier.
This sample will gather other samples and join them into one data.
- type
-
join
- samples
-
Which samples to join
- separator
-
Which separator to use (defaults to an empty string).
A sample that allows you to define specific weights to each element.
- type
-
weight
- values
-
The list of values.
- weight
-
The weight of the value.
- value
-
The value to use.
- source
-
Which sample sample should be used instead of the
value
.
samples:
color:
type: weight
values:
- weight: 30
value: blue
- weight: 45
value: yellow
- weight: 10
value: red
- weight: 20
value: brown
- weight: 25
value: cyan
Note
|
The sum of the weights don’t necessary need to be 100 , but using a total weight of 100 helps to see the
weights as percentage.
|
This sample generates numbers from a given interval.
A sample that generates data based on expressions.
- type
-
expression
- sample
-
The sample to use as an expression.
- expression
-
The expression to use.
Note
|
You need to supply a sample or an expression .
|
A sample that can generate dates based on a given interval.
- type
-
date
- from
-
Defines the start date.
- to
-
Defines the end date.
- period
-
Defines a period instead of an end date. See the docs for
java.time.Period#parse
. - format
-
The format to parse the supplied dates. Defaults to
dd-MM-yyyy
. See the docs forjava.time.format.DateTimeFormatter#ofPatter
. - inclusive
-
Sets if the end date is part of the interval or not.
Note
|
It is possible to use today , yesterday or tomorrow instead of the actual date values.
|
A sample that caches the value. Useful when used with an API sample that posts data in order to create a data dependency.
- type
-
cache
- source
-
Which sample sample should be used to obtain the value to cache.
- ttl
-
How many hits the value should last until the cache gets another one. This is a configuration value.
The placeholders are a single character that can be associated with any of the configured sample. Bellow is an example of a configuration file:
placeholders:
"#": digit (1)
"%": letter (2)
samples:
letter:
type: chars
value: "abcdefghijklmnopqrstuvwxyz"
digit:
type: chars
value: "0123456789"
-
Associated with the
digit
sample -
Associated with the
letter
sample
Fake-O-Matic uses Qute templates to produce the payloads. A couple of methods can be used to get a fake data, the main one are:
- some(sampleName)
-
Gets a random sample from the given sample name.
- expression(placeholders)
-
Gets a random data produced by replacing each placeholder by a random sample associated with it.
The following properties can be configured as a JVM argument (prefix -D
), environment variable (with upper cases
and underscores), or a command line parameter:
- endpoint.name|ENDPOINT_NAME|--endpoint-name
-
Which endpoint in the configuration to use. Defaults to
default
. - endpoint.url|ENDPOINT_URL|--endpoint-url
-
The endpoint url to use for the default endpoint. Defaults to
http://localhost:8080
. - endpoint.method|ENDPOINT_METHOD|--method
-
Which HTTP method to use for calling the endpoint. Defaults to
POST
. - endpoint.concurrency|ENDPOINT_CONCURRENCY|--concurrency
-
The maximum number of concurrent requests to the endpoint. Defaults to
10
. - endpoint.buffer|ENDPOINT_BUFFER|--buffer
-
How many payloads should be buffered while we have ongoing requests. Defaults to
10
. - endpoint.insecure|ENDPOINT_INSECURE|--insecure
-
Marks the endpoint as insecure or not. An insecure endpoint will not have its certificate check. Defaults to
false
. - endpoint.template|ENDPOINT_TEMPLATE|--template
-
Where to locate the template for generating the payloads. Defaults to
./payload.json
. - endpoint.content_type|ENDPOINT_CONTENT_TYPE|--content-type
-
Which
Content-Type
to pass to the endpoint. Defaults toapplication/json
. - generator.total|GENERATOR_TOTAL|--total
-
The number of generated payloads. Defaults to
10
. - generator.config|GENERATOR_CONFIG|--config
-
Which configuration files should be used. Fake-O-Matic allows you to define parent configurations, so you can reuse them in the way it suits you better. The configurations should be comma separated from the most specific to the least specific (so the last configuration file becomes the parent one). The built-in configuration can be included with a simple
fakeomatic
name. The built-in configuration can be found atsrc/main/resources/META-INF/config/fakeomatic.yaml
.
Note
|
The --config param can be also used once for each file to include.
|
- generator.seed|GENERATOR_SEED|--seed
-
The seed to use for the random functions. Fake-O-Matic will generate one if empty.
- fakeomatic.events.log.level|FAKEOMATIC_EVENTS_LOG_LEVEL|--events-log-level
-
Sets the log level for the events. To see all the payloads and responses, set the log level to DEBUG.
Note
|
You can still make use of the endpoint properties if you use the same approach as the built-in one for defining an endpoint. |