Skip to content

Instantly share code, notes, and snippets.

@mremond
Last active January 7, 2024 14:29
Show Gist options
  • Select an option

  • Save mremond/a5c1c25aad11dfc40ae7b4f18c000942 to your computer and use it in GitHub Desktop.

Select an option

Save mremond/a5c1c25aad11dfc40ae7b4f18c000942 to your computer and use it in GitHub Desktop.

Revisions

  1. mremond revised this gist Jan 9, 2018. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions writing-a-tsung-plugin.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    # Writing a Tsung plugin

    This is a simple tutorial on writing a tsung plugin and a repost of our ProcessOne tutorial.

    Since tsung is used to test servers lets define a simple server for testing. *myserver.erl* provides 3 operations: echo, add and subtract.
  2. mremond revised this gist Jan 9, 2018. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion d
    Original file line number Diff line number Diff line change
    @@ -1 +0,0 @@
    d
  3. mremond created this gist Jan 9, 2018.
    1 change: 1 addition & 0 deletions d
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    d
    130 changes: 130 additions & 0 deletions writing-a-tsung-plugin.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,130 @@
    This is a simple tutorial on writing a tsung plugin and a repost of our ProcessOne tutorial.

    Since tsung is used to test servers lets define a simple server for testing. *myserver.erl* provides 3 operations: echo, add and subtract.

    *myserver.erl* assumes the first byte to be a control instruction followed by 2 or more byte data. The echo operation merely returns the byte data while add and subtract performs these operations on the 2 byte data before returning the results. See the code of *myserver.erl* for details.

    We assume the source files for tsung-1.2.1 are available. This example was compiled using Erlang OTP R11B-3.

    ## Step 0. Download the source code for this tutorial

    The source code for this tutorial is available for download as tarball ([tutorial\_tsung\_1.tgz](http://www.process-one.net/downloads/tutorials/tutorial_tsung_1.tgz)).

    ## Step 1. Create tsung configuration file

    Based on the 3 operations we want to test we define the *myclient.xml* which
    will take place of *tsung.xml*. You will notice *myclient.xml* looks very much
    like any normal tsung configuration file. The main difference is in the
    session definition. Here we use the *ts_myclient* type. Here is the session definition:

    ```xml
    <session probability="100" name="myclient-example" type="ts_myclient">
    ```

    This indicates which plugin tsung should call when creating a server request.
    We choose to name this plugin *ts_myclient*.

    The next difference is within the request element. Here we define a ‘myclient’
    element indicates the operations to test followed by the relevant data.

    Notice that *myclient* has 2 attributes: *type* and *arith* (optional).

    ### Step 2. Update DTD

    We now need to modify the *tsung-1.0.dtd* or validation would fail.

    In the request element we add the *myclient* tag:

    ```dtd
    <!ELEMENT request ( match*, dyn_variable*, ( http | jabber | raw | pgsql | myclient ) )>
    ```

    Next, we create the *myclient* element:

    ```dtd
    <!ELEMENT myclient (#PCDATA) >
    ```

    Followed by defining the attributes list for *myclient*.

    ```dtd
    <!ATTLIST myclient
    arith (add | sub) #IMPLIED
    type (echo | compute) #REQUIRED >
    ```

    Next, we add the *ts_myclient* option into the element’s *type* attribute list.

    ```dtd
    type (ts_http | ts_jabber | ts_pgsql | ts_myclient ) #IMPLIED
    ```

    We do the same to the session’s *type* attribute list.

    ```dtd
    type (ts_jabber | ts_http | ts_raw | ts_pgsql | ts_myclient ) #REQUIRED>
    ```

    ## Step 3. Create include file

    In `PATH/include` create the include file *ts_myclient.hrl*.
    This include file should have a minimum of two records:

    - *myclient_request*: for storing request information parsed from tsung configuration. Will be use to generate server requests.
    - *myclient_dyndata*: for storing dynamic information. Not used in this case.

    ## Step 4. Config reader

    Create the *ts_config_myclient.erl* in `PATH/src/tsung_controller` to parse the XML file. This file must export `parse_config/2`.
    `ts_config_myclient:parse_config/2` is called from `ts_config:parse/1`.

    However trying to run `ts_config:parse/1` seperately seem to throw an undefined case error.

    The important function definition is:

    ```
    parse_config(Element = #xmlElement{name=myclient}, ...)
    ```

    Within this pattern we gather the various attributes, echo, compute, add, sub, and data creating a *myclient\_request* record as needed. Notice for the case
    of type compute we parse the data into a list of 2 integers. Ensure you keep any data manipulation here consistant with calls in `ts_myclient:get_message/1`.

    If your configuration file support several element types then you will need a *parse_config* function for each.

    ## Step 5. ts\_myclient

    The final file to create is *ts_myclient.erl* in `PATH/src/tsung`.

    The `get_message/1` function builds the actual data to be transmitted to the server. The function returns a binary even if your protocol uses strings.

    In `ts_myclient:get_message/1`, you can see how we create the message from the *myclient_request* record. Compare this with `myserver:test/3` and `myserver:test/1`.

    `parse/2` deals with server responses. It is possible to parse the return data and update monitoring parameters. In the `ts_myclient:parse/1`, we count the number of single and multi bytes returned from the server. Obviously these must match echo and add / \_sub calls.

    The `ts_mon:add/1` parameters are restricted to:

    1. `{count, Type}` – increments a running counter
    2. `{sum, Type, Val}` – adds Val to running counter
    3. `{sample_counter, Type, Value}` – updates sample_counter
    4. `{sample, Type, Value}` – updates counter

    ## Step 6. Build and install

    Return to PATH and type *make* followed by *make install*.

    There is no need to update any makefile.

    ## Step 7. Running

    Start myserver then call `myserver:server()` in the erlang shell to start listening to the socket.

    ```
    sh> erl -s myserver start_link
    1> myserver:server().
    ```

    Run Tsung, passing it *myclient.xml*:

    ```
    sh> tsung -f myclient.xml
    ```