Skip to content

Commit

Permalink
Merge pull request #147 from esl/hex_package
Browse files Browse the repository at this point in the history
Hex package preparations
  • Loading branch information
DenysGonchar authored Jul 25, 2023
2 parents 66eb4d4 + 184c38f commit 46f44f6
Show file tree
Hide file tree
Showing 24 changed files with 218 additions and 222 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ _build
*.iml
rebar3.crashdump
*~
doc/
16 changes: 3 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,9 @@ All the XMPP scenarios can be found [here](https://github.com/esl/amoc-arsenal-x

---------------------------------------------------------------------
In order to implement and run locally your scenarios, follow the chapters about
[developing](doc/scenario.md) and [running](doc/local-run.md) a scenario
[developing](guides/scenario.md) and [running](guides/local-run.md) a scenario
locally.
Before [setting up the distributed environment](doc/distributed.md),
Before [setting up the distributed environment](guides/distributed.md),
please read through the configuration overview.
If you wish to run load tests via http api,
take a look at the [REST API](doc/http-api.md) chapter.

### Table of Contents
- [Developing a scenario](doc/scenario.md)
- [Running locally](doc/local-run.md)
- [Configuration](doc/configuration.md)
- [Setting up distributed environment](doc/distributed.md)
- [Running load test](doc/distributed-run.md)
- [REST API](doc/http-api.md)
- [Amoc throttle](doc/amoc_throttle.md)
- [Amoc coordinator](doc/amoc_coordinator.md)
To see the full documentation, see [hexdocs](https://hexdocs.pm/amoc).
File renamed without changes
55 changes: 51 additions & 4 deletions doc/configuration.md → guides/configuration.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## Configuration

Amoc is configured through environment variables (uppercase with prefix ``AMOC_``).
Note that the environment variables are evaluated as erlang code
Note that the environment variables are evaluated as Erlang code.

Amoc supports the following generic configuration parameters:

Expand All @@ -25,12 +25,60 @@ Amoc supports the following generic configuration parameters:

In the same manner you can also define your own entries to configure the scenario.

## Required Variables

The ``amoc_config:get/1`` and ``amoc_config:get/2`` interfaces can be used to get
parameters required for your scenario, however every scenario must declare (using
`-required_variable(...)` attributes) all the required parameters in advance. For more
information, see the example [scenario module](../integration_test/dummy_scenario.erl)

Scenario configuration also can be set/updated at runtime using REST API.
Scenario configuration also can be set/updated at runtime using an API.

```erlang
-required_variable(#{name => Name, description => Description,
default_value => Value,
update => UpdateFn,
verification => VerificationFn}).
```
where

### `name`
* **Syntax:** atom
* **Example:** `name = var1`
* **Default:** this field is mandatory

### `description`
* **Syntax:** A string describing how this variable is used, can be extracted by APIs to document the behaviour
* **Example:** `description = "a description of this variable"`
* **Default:** this field is mandatory

### `default_value`
* **Syntax:** value of the expected type
* **Example:** `default_value = 10`
* **Default:** `undefined`

### `verification`
* **Syntax:** `none`, a list of allowed values, or an `mfa` of arity `1`
* **Example:** `verification = {?MODULE, is_binary, 1}`
* **Default:** `none`

A verification function that will check the given value is correct. It is trigger for verifying the initial values, including the default value, and before updated values are applied.
- If it is set to `none`, all values are allowed.
- If it is set to a list of values, any given value checks that the new value is in such allowlist.
- If it is an `mfa`, the given function will be called on the given value. This function
must be pure and return a boolean or a `{true, NewValue} | {false, Reason}`. It can also be used for preprocessing of the input value by returning `{true, NewValue}`.

### `update`
* **Syntax:** `read_only`, `none`, or an `mfa` of arity 2
* **Example:** `update = {?MODULE, update, 2}`
* **Default:** `read_only`

An action to take when the value of this variable is updated. It is triggered at runtime when updates to the value are applied.
- If it is set to `read_only`, updates will fail.
- If it is set to `none`, all updates are allowed.
- If it is an `mfa`, the given function will be called on the old and new value.

## Reasonale

NB: the reason why the `-required_variable(...)` is preferred over the usual behaviour
callback is because the orchestration tools can easily extract the attributes even
Expand All @@ -46,7 +94,7 @@ compilation of the module. As an example, a module:
cannot be compiled without the ``some_unavailable_header.hrl`` file, but we still
can parse it and extract the attributes:
```
Eshell V10.3 (abort with ^G)
Eshell V14.0 (press Ctrl+G to abort, type help(). for help)
1> c(example).
example.erl:2: can't find include file "some_unavailable_header.hrl"
error
Expand All @@ -62,5 +110,4 @@ error
[{"some",value},
{another,"value"},
{yet,<<"another">>,"value"}]
```
48 changes: 4 additions & 44 deletions doc/amoc_coordinator.md → guides/coordinator.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# amoc_coordinator
## API

## Module

`amoc_coordinator`
See `amoc_coordinator`.

## Description

Expand All @@ -20,8 +18,8 @@ If more then one of the *Coordination Items* matching the `NumberOfUsers` is tri
For example if the *Coordination Plan* is `[{2, Act1}, {3, Act2}]` then on the 6th user calling `add`, `Act1` will be called with 2 users passed and `Act2` will be called with 3 users passed.

*Coordination Actions* may be one of the following:
- `fun(Event) -> any()` - this type of action does not care about particular users, but only about the number of them;
- `fun(Event, ListOfUsersData) -> any()` - this type of action gets `ListOfUsersData` which is a list of `{Pid, Data}` tuples with `Pid`s passed by users calling `amoc_coordinator:add/2` or `amoc_coordinator:add/3`;
- `fun(Event) -> any()` - this type of action does not care about particular users, but only about the number of them;
- `fun(Event, ListOfUsersData) -> any()` - this type of action gets `ListOfUsersData` which is a list of `{Pid, Data}` tuples with `Pid`s passed by users calling `amoc_coordinator:add/2` or `amoc_coordinator:add/3`;
- `fun(Event, User1, User2) -> any()` - this type of action gets `distinct pairs` from the batch of users `User1` and `User2` which are `{Pid, Data}` tuples with `Pid`s passed by users calling `amoc_coordinator:add/2` or `amoc_coordinator:add/3`;

where an `Event` is a `{EventType, NumOfUsers}` tuple, in which `NumOfUsers` is the number of users passed to the event.
Expand All @@ -37,44 +35,6 @@ It’s guaranteed that all the *Coordination Actions* with `all` are executed af
- Eg. for `[a, b]`, the `distinct pairs` collection is `[{a, b}]`;
- Eg. for `[a, b, c]`, the `distinct pairs` collection is `[{a, b}, {a, c}, {b, c}]`.

## Exports

#### `start(CoordinatorName, CoordinationPlan) -> ok | error`
#### `start(CoordinatorName, CoordinationPlan, Timeout) -> ok | error`

##### Types
```erlang
CoordinatorName :: atom()
CoordinationPlan :: [ CoordinationItem ]
CoordinationItem :: {NumberOfUsers :: pos_integer() | all, CoordinationActions}
CoordinationActions :: [ CoordinationActions ] | CoordinationAction
CoordinationAction ::
fun(Event) -> any() |
fun(Event, ListOfUsersData) -> any() |
fun(Event, MaybeUser, MaybeUser) -> any()
Event :: {EventType, NumOfUsers}
EventType :: coordinate | timeout | stop | reset
NumOfUsers :: non_neg_integer()
ListOfUsersData :: [ User ]
MaybeUser :: undefined | User
User :: {UsersPid :: pid(), Data :: any()}
Timeout :: pos_integer() | infinity
```

This function starts a coordinator. Usually is called in `init/0` of a amoc scenario.

#### `add(CoordinatorName, Data) -> ok`
#### `add(CoordinatorName, Pid, Data) -> ok`

##### Types
```erlang
CoordinatorName :: atom()
UsersPid :: pid()
Data :: any()
```

This function adds the current process data. It is usually called in `start/2` of a amoc scenario.

## Example

This scenario will demonstrate how do the `users` interact with `amoc_coordinator`:
Expand Down
2 changes: 1 addition & 1 deletion doc/distributed-run.md → guides/distributed-run.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ key set to ``2000``.
Also all the user processes trap exit signal.


### Don't stop scenario on exit
## Don't stop scenario on exit

There is one problem with the `bin/amoc console` command. When you exit the Erlang
shell the scenario is stopped (in fact the erlang nodes are killed).
Expand Down
3 changes: 1 addition & 2 deletions doc/distributed.md → guides/distributed.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
## Set-up distributed environment with docker

To build a Docker image with Amoc, run the following command from the root of
the repository:
```
Expand Down Expand Up @@ -49,3 +47,4 @@ docker run --rm -t -d --name amoc-2 -h amoc-2 \
Connect to Amoc console and go to the [next](../doc/distributed-run.md) section.
```
docker exec -it amoc-1 /home/amoc/amoc/bin/amoc remote_console
```
File renamed without changes.
6 changes: 6 additions & 0 deletions doc/scenario.md → guides/scenario.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,9 @@ For developing XMPP scenarios, we recommend the
If additional dependencies are required by your scenario,
a `rebar.config` file can be created inside the `scenario` dir
and `deps` from that file will be merged with Amoc's dependencies.

## Coordinate users
See `amoc_coordinator`.

## Throttle actions
See `amoc_throttle`.
18 changes: 8 additions & 10 deletions doc/telemetry.md → guides/telemetry.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
## Telemetry

Amoc also exposes the following telemetry events:

### Scenario
## Scenario

A telemetry span of a full scenario execution
```erlang
Expand All @@ -11,7 +9,7 @@ measurements: #{}
metadata: #{}
```

### Controller
## Controller

Indicates the number of users added or removed
```erlang
Expand All @@ -20,9 +18,9 @@ measurements: #{count => non_neg_integer()}
metadata: #{type => add | remove}
```

### Throttle
## Throttle

#### Rate
### Rate

Raised when a throttle mechanism is initialised or its configured rate is changed.

Expand All @@ -32,7 +30,7 @@ measurements: #{rate => non_neg_integer()}
metadata: #{name => atom()}
```

#### Request
### Request

Raised when a process client requests to be allowed pass through a throttled mechanism.

Expand All @@ -42,7 +40,7 @@ measurements: #{count => 1}
metadata: #{name => atom()}
```

#### Execute
### Execute

Raised when a process client is allowed to execute after a throttled mechanism.

Expand All @@ -52,11 +50,11 @@ measurements: #{count => 1}
metadata: #{name => atom()}
```

### Coordinate
## Coordinate

Indicates when a coordinating event was raised, like a callback index being reached or a timeout being triggered

#### Event
### Event
```erlang
event_name: [amoc, coordinator, event]
measurements: #{count => 1}
Expand Down
Loading

0 comments on commit 46f44f6

Please sign in to comment.