Getting started

Introduction

This quick start guide presents how to use ConfErr by giving a step-by-step procedure that guides the reader in the process of testing the effect of typos in configuration files of the rsync daemon. Rsync is a software that can be used to transfer files to/from remote systems. This application usually comes preinstalled in common Linux distributions. For more information on rsync please refer to its website.

Setup Rsync

Before being able to test configuration errors it is necessary to create a working configuration of the system, scripts to start and stop the daemon and some test scripts to verify its functionality. The initial rsync configuration that is created in this procedure shares two folder “ro” and “rw”, the first is world accessible and is in read only, the second is both readable and writable but only by a user “user1”. The following steps configure such system:

  1. Create a directory that will store all the files for the test:

    > mkdir testkit-rsync && cd testkit-rsync 
    
  2. Create a directory with the files necessary to run rsync:

    > mkdir default-install && cd default-install
    
  3. Create the two directory to share and some content:

    > mkdir ro rw
    > touch ro/public.txt rw/secret.txt
    
  4. Create the configuration file for rsync rsyncd.conf with the following content:

    # use an unprivileged port
    port = 8873
    # log file (useful for debugging)
    log file = rsyncd.log
    # pid file (useful to stop the daemon)
    pid file = rsyncd.pid
    # do not try to chroot (requires root privileges)
    use chroot = false

    # ==========
    # first share, read/write access to user1
    # ==========
    [rwshare]

    # path to the directory published
    path = rw
    # this share can be written
    read only = false
    # users that can access this share
    auth users = user1
    # file containing the passwords
    secrets file = rsyncd.secrets
    # secrets file can be world readable
    strict modes = false

    # ==========
    # second share, read only access to everybody
    # ==========
    [roshare]

    # path to the published directory
    path = ro
    #read only access
    read only = true
  5. Create the file rsyncd.secrets that stores the passwords:

    user1:password
  6. Prepare a script to start rsync called startup.sh with the following content:

    #!/bin/bash

    # change to the correct directory
    cd `dirname $0`

    # kill rsync if already running
    if [[ -f rsyncd.pid ]] ; then
    kill `cat rsyncd.pid`
    fi

    # start rsync
    rsync --daemon --config rsyncd.conf
  7. Prepare a script to stop rsync called shutdown.sh with the following content:

    #!/bin/bash

    # change to the correct directory
    cd `dirname $0`

    # kill rsync if running
    if [[ -f rsyncd.pid ]] ; then
    kill `cat rsyncd.pid`
    fi
  8. Prepare a script called test-read.sh in a new directory tests to test reading a file from the server with the following content:

    #!/bin/bash

    # change to the correct directory
    cd `dirname $0`

    # create a temporary directory
    TEMPDIR=`mktemp -d test.XXXX`

    # try to download from the read only share
    rsync -avz rsync://localhost:8873/roshare/ $TEMPDIR

    # save exit value of rsync
    RESULT=$?

    rm -r $TEMPDIR

    # return the exit code of rsync, this will be used by ConfErr to
    # detect the outcome of the test
    exit $RESULT
  9. Prepare a script called test-write.sh in the same directory tests to test writing a file from the server with the following content:

    #!/bin/bash

    # change to the correct directory
    cd `dirname $0`

    # create a temporary directory
    TEMPDIR=`mktemp -d test.XXXX`

    # create a file in the temporary directory
    echo “test” > $TEMPDIR/testfile

    # try to download from the read only share
    export RSYNC_PASSWORD=password
    rsync -avz $TEMPDIR rsync://user1@localhost:8873/rwshare/

    # save exit value of rsync
    RESULT=$?

    rm -r $TEMPDIR

    # return the exit code of rsync, this will be used by ConfErr to
    # detect the outcome of the test
    exit $RESULT
  10. Set the execution bit on all the scripts created:

    > chmod +x startup.sh shutdown.sh tests/*
  11. Rsync can now be started with the following command:

    > ./startup.sh
  12. To test that the daemon is running correctly you can execute the following commands:

    > rsync rsync://user1@localhost:8873/rwshare/
    Password:  password
    drwxrwxr-x       
    4096 2008/09/27 12:04:06 .
    -rw-rw-r--          
    0 2008/09/27 12:04:06 secret .txt
    
    > rsync rsync://localhost:8873/roshare/
    drwxrwxr-x       
    4096 2008/09/27 12:04:11 . 
    -rw-rw-r--          
    0 2008/09/27 12:04:11 public
    
  13. Now it is possible to test the two scripts:

    > ./tests/test-read.sh && echo Success
    building file list ... done 
    test.8867/ 
    test.8867/testfile 
    sent 163 bytes  received 44 bytes  414.00 bytes/sec 
    total size is 11  speedup is 0.05 
    Success 
    
    
    > ./tests/test-read.sh && echo Success
    building file list ... done 
    test.8867/ 
    test.8867/testfile 
    sent 163 bytes  received 44 bytes  414.00 bytes/sec 
    total size is 11  speedup is 0.05 
    Success
    
  14. After verifying that rsync is correctly working it is possible to shut it down:

    > ./shutdown.sh
  15. It is now possible to change the configuration file name, the rsyncd.conf configuration file will be generated by ConfErr:

    >mv rsyncd.conf rsyncd.conf.template

Prepare the test plan

  1. Setup the main test plan properties:

    Figure 1 General test plan properties


    1. Set the name of the fault plan to Rsync Test, this name is used to generate the report of the fault injection
    2. Set the root directory to the directory where all the scripts created to start, stop and test rsync. This directory will be used to compute all relative paths inserted in the test plan.
  2. Load the standard plugins:


    Figure 2 Plugins properties


    1. Click on Add JAR... and select the file StandardPlugins.jar downloaded from the ConfErr website.
  3. Setup the configuration file that where the errors will be injected:


    Figure 3 Configuration files properties



    1. Click on Add to add a new configuration file
    2. Set the name of the configuration file to Rsync configuration
    3. Set the input to rsyncd.conf.template, this is the file that will be parsed
    4. Set the output to rsyncd.conf, in this file the configuration with the errors will be written
    5. Set the handler to conferr.handlers.LineBasedHandler this handler can parse and serialize rsync configurations. It divides the configuration file in sections, parse directives formed by a name, a separator and a value. This handler can also skip comments.
    6. Configure the regular expression that the handler uses to recognize the comments to #.*$
    7. Configure the regular expression used by the handler to recognize the section headers to ^\[.*\]$
    8. Configure the regular expression that recognizes the separator between directive names and values to \s*=\s*
  4. Create a new error generator:


    Figure 4 Creating a new error generator

    Figure 5 Setting an Union template 


    Figure 6 Adding a new Switch Letters template


    Figure 7 Adding a new Switch Letters template
     

    1. Click on Add to create a new error generator
    2. Set the name of the error generator to Insert typos, this name will be used later to reference the error generator
    3. Click on the first element of the tree that represent the error generator, each element in this tree is a fault template. Fault templates that compose or filter other fault templates are represented as parents.
    4. Set then Name parameter of the selected fault template to Select 10 typos. This template will filter the children template such that only 10 faults are generated.
    5. Set the Template parameter to conferr.templates.RandomSubSetTemplate, this plug-in implements the filtering function.
    6. Set the plug-in parameter size to 10, to test more faults it is possible to increase this parameter
    7. Click on the template that is child of the Select 10 typos template
    8. Insert in the Name field Union of possible typos
    9. Set the Template parameter to conferr.templates.UnionTemplate. This fault template generates a set of faults that is the union of all faults generated by its children fault templates.
    10. Click on the Add button to add a new fault template as a child of the Union of possible typos template
    11. Click on the newly created template
    12. Set the Name parameter to Switch letters
    13. Set the Template parameter to conferr.templates.SwitchLetterTemplate. This template insert typos where two letter are swapped.
    14. Set the target parameter to //directive. This parameter indicates to the template which parts of the configuration are candidates for the injection of errors. In this case the XPath expression selects the value of the directives.
    15. Click again on the Union of possible typos template and then on the Add button to add a new fault template as a child.
    16. Click on the newly created template
    17. Set the Name parameter to Switch letters
    18. Set the Template parameter to conferr.templates.SubstituteLetterTemplate. This template insert typos where a letter is substitued with a letter that is near on the keyboard.
    19. Set the target parameter to //directive. This parameter indicates to the template which parts of the configuration are candidates for the injection of errors. In this case the XPath expression selects the value of the directives.
  5. Setup the plugin that runs the tests:

    Figure 8 Runner properties


    1. Set the runner parameter to conferr.runners.SimpleRunner, this runner plug-in starts and stop the system with by running executables (script) and tests the effect of the error injection by running all the executable (scripts) found in a directory.
    2. Set the startup-script parameter to startup.sh, the startup script prepared in the previous section.
    3. Set the shutdown-script parameter to shutdown.sh, the shutdown script prepared in the previous section.
    4. Set the test-directory parameter to tests, the directory that contains the test scripts prepared in the previous section.

Running the test plan

In the previous two sections all the required scripts have been created and ConfErr has been configured. Now it is possible to run the fault injection.

Figure 9 Running a fault injection


  1. Set the Output directory parameter to an existing, empty directory. This directory will contain a directory for each fault. When the scripts are executed by the runner they receive the path of this directory in the OUTPUTDIR environment variable. The scripts can output some information run-specific data in this directory (for instance a log of the run of the daemon).
  2. Click on Start
  3. While the test injection is running the partial results start appearing by putting the mouse on a line it is possible to see a diff between the template configuration file and the configuration file used for that fault injection.
  4. By double clicking on a result it is possible to have additional information on the output of the different test scripts.
  5. By clicking on the button Save resilience profile it is possible to export the results of the fault injection to an XML file for further processing.