wiki:GENIExperimenter/Tutorials/AutomatedTutorialTesting

Version 1 (modified by yzhao@bbn.com, 4 years ago) (diff)

--

Automated Tutorial Testing with Ansible

This page shows how to create an Ansible playbook to do automated testing. HelloGeni tutorial is used as an example to demonstrate how to perform automatd testing with Ansible. HelloGeni tutorial has a very simple topology with one server and one clients that are connected with a layer 2 link. We will demonstrate important factors in ansible script to start iperf server on server and then do iperf test from client to server.

1. What are Ansible Playbook?

Ansible is a configuration management system that can be used to automate configuration tasks for distributed nodes. Ansible playbook is a way of sending commands in script format instead of using individual commands to remotely configure systems. Ansible playbooks are written in YAML format.

2. Playbook Basics

  • Play: Each playbook contains one or more 'plays' in a list. The play maps a groups of hosts to a series of tasks. Each play could contains a list of tasks which are executed.
  • Task: A task can be regarded as a configuration step in the remote system. We could add more than one task for a play. Tasks run from top to bottom. When a task fails, the host with the failed task are taken out of the entire playbook. Tasks belonging to other hosts will be executed normally.
  • Playbook: A playbook can contain multiple plays. For example, we could have a playbook that targets first the server, and then the client. The first play checks whether iperf server is running on server node using 'ps' command and then the second play starts the iperf client.
- name: test server
  hosts: server
  sudo: True
  tasks:
   - name: check iperf running
     shell: ps aux | grep iperf
     register: iperf_running
     failed_when: "'iperf -s -i 10 &> /var/www/iperflogs/iperf-server.log' not in iperf_running.stdout"
   - debug: var=iperf_running.stdout_lines
- name: test client
  hosts: client
  sudo: True
  tasks:
   - name: iperf test
     command: iperf -c server -P 2
     register: iperf_test
     failed_when: "'failed' in iperf_test.stderr"
     async: 30
     poll: 10
   - debug: var=iperf_test.stdout_lines

3. Error Handling in Playbooks

Generally playbooks will stop executing any more tasks on a host that has a failure. If we want the playbook to ignore a task failure and continue executing, we could set the ignore_errors to 'yes'. Here's an example:

- name: this will not be counted as a failure
  command: /bin/false
  ignore_errors: yes

Sometimes, the error code of a command cannot really tell if there is a failure and we need the output of the command to decide whether it is a failure. In this case, we should register the task to a variable and define the failure by command output. For example, 'failed' string in iperf test output means the test fails:

   - name: iperf test
     command: iperf -c server -P 2
     register: iperf_test
     failed_when: "'failed' in iperf_test.stderr"

4. Print the command output

We could use 'debug' module to print command output during execution. This is useful for debugging. This example demonstrates how to print out the iperf test result:

   - name: iperf test
     command: iperf -c server -P 2
     register: iperf_test
   - debug: var=iperf_test.stdout_lines

5. Set Task Timeout

Generally, tasks in playbooks are in blocking mode, which means the connection stay open until the task is done. This may not always be desirable for some failure: the connection will keep open until the SSH timeout. We could use asynchronous mode to set timeout for a task. 'async' sets the maximum runtime and 'poll' sets how frequently you would like to poll for status. For example, in our iperf test, we want to abort the task after 30s and polls the status every 10s, we could use the following script:

- name: iperf test
     command: iperf -c server -P 2
     register: iperf_test
     failed_when: "'failed' in iperf_test.stderr"
     async: 30
     poll: 10

6. Run Shell Script

The shell module takes the command name followed by a list of space-delimited arguments. It is almost exactly like the command module but runs the command through a shell (/bin/sh) on the remote node. Here's an example of checking whether a file exists on remote node. If the file does not exist, the task is regarded as failure:

   - name: test whether installed file exists or not
     shell:  if [ -f /local/installed.txt ] ; then echo "yes" ; else echo "no" ; fi
     register: installation_test
     failed_when: "'no' in installation_test.stdout_lines"

7. Execute Tests

Run the playbook with the following command on the local machines:

ansible-playbook <your_yml_file_directory> -i inventory