Automatic Reruns

Rerun Plugin provides an important functionality that allows users to rerun some of their testcases. These testcases are determined either through explicit selection, or the results of the same testcases in a previous run. Any testcases that do not match the provided criteria are not executed and do not appear in the final report.

Rerun Results File

Users may use the --rerun-file argument to provide a “rerun.results” file which details the results of all testcases from a previous run in YAML format. This file is generated by Rerun Plugin when execution is complete. --rerun-file also accepts the “.zip” archive created from a previous run which contains a “rerun.results” file. --rerun-file executes all testcases with a result other than Passed, or as defined by --rerun-condition.

Rerun Condition

--rerun-condition accepts a list of Result Objects to determine which testcases to rerun. The result of each testcase in the “rerun.results” file must match one of the results in the --rerun-condition list to be executed. Passed is not accepted as a rerun condition, and the default list is all result types except Passed.

Rerun Selection File

Users may also wish to specify testcases to rerun regardless of their previous results. To do this, a YAML file with a similar format as “rerun.results” can be created. This file does not hold any testcase results and is not affected by the --rerun-condition list. Testcases are executed based on inclusion in the file. Any testcases to be ignored are simply omitted from the file. This file is specified with --rerun-file just like a “rerun.results” file.

Rerun CLI

Users can alternatively provide a series of CLI arguments to specify tasks and testcases to run. The --rerun-task argument is used once for each task to run, which means it is used multiple times if there are multple tasks to run. The --rerun-task argument is followed by the ID of the task to run, then the path to the testscript of that task, then optionally by any testcases to be run. If no testcases are provided, the entire task will be run. For example, to run tc1, and tc2 from Task-1 and everything from Task-2, the arguments would be:

--rerun-task Task-1 /path/to/script1 tc1 tc2 --rerun-task Task-2 /path/to/script2

File Format

# The task-id is the key for each task
Task-1:
  # the path to this task's testscript is mandatory.
  testscript: /path/to/testscript.py
  # commonSetup and commonCleanup are seperate from Testcases, and they will
  # only be executed if present in the file.
  commonSetup:
    name: common_setup
    result: PASSED
  commonCleanup:
    name: common_cleanup
    result: PASSED
  # list of all testcases in Task-1
  testcases:
  - name: tc_one
    # result is only necessary for a results rerun file. A selection rerun
    # file would omit these.
    result: PASSED
  - name: tc_two
    result: PASSED
Task-2:
  testscript: /path/to/testscript.py
  commonSetup:
    name: common_setup
    result: PASSED
  commonCleanup:
    name: common_setup
    result: PASSED
  testcases:
  - name: tc_one
    result: FAILED
  - name: tc_two
    result: ERRORED

Some notes:

  • If Passed is provided as --rerun-condition an exception will be thrown. Because it’s not an allowed result type for Rerun Plugin.

  • If neither --rerun-file nor --rerun-task is provided, the entire script will be run again, no matter what the value of --rerun-condition specified.

  • The testscript path is manditory for each task passed to Rerun Plugin.

  • When rerunning from previous results, if none of the testcases of a task matches the --rerun-condition, that task will be skipped entirely and won’t be included in the reports.

  • If the result of common_setup matches the --rerun-condition, all testcases for that task will be executed.

Examples

Rerunning from Results

In this example we will assume that the job file was ran once so that we have the rerun.results. Then, we will run the same job file while using the --rerun-file parameter to pass it.

Job File:

import os
from pyats.easypy import run

# All run() must be inside a main function
def main(runtime):
    # Find the location of the script in relation to the job file
    test_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    testscript = os.path.join(test_path, 'basic_example_script.py')

    # Execute the testscript
    run(testscript=testscript, runtime = runtime)
    run(testscript=testscript, runtime = runtime)

rerun.results:

# rerun.results file that contains the information of each task and their
# testcases.
Task-1:
  commonCleanup: {name: common_cleanup, result: PASSED}
  commonSetup: {name: common_setup, result: PASSED}
  testcases:
  - {name: tc_one, result: FAILED}
  - {name: tc_two, result: PASSED}
  testscript:   path/to/script
Task-2:
  commonCleanup: {name: common_cleanup, result: PASSED}
  commonSetup: {name: common_setup, result: PASSED}
  testcases:
  - {name: tc_one, result: PASSED}
  - {name: tc_two, result: PASSED}
  testscript:   path/to/script

Output:

bash$ pyats run job basic_example_job.py --rerun-file path/to/rerun.results --rerun-condition Failed
%EASYPY-INFO: Starting job run: basic_example_job
%EASYPY-INFO: Starting task execution: Task-1
%EASYPY-INFO:     test harness = ats.aetest
%EASYPY-INFO:     testscript   = path/to/script
%AETEST-INFO: +------------------------------------------------------------------------------+
%AETEST-INFO: |                            Starting common setup                             |
%AETEST-INFO: +------------------------------------------------------------------------------+
%AETEST-INFO: +------------------------------------------------------------------------------+
%AETEST-INFO: |                   Starting subsection sample_subsection_1                    |
%AETEST-INFO: +------------------------------------------------------------------------------+
%SCRIPT-INFO: Aetest Common Setup
%AETEST-INFO: The result of subsection sample_subsection_1 is => PASSED
%AETEST-INFO: +------------------------------------------------------------------------------+
%AETEST-INFO: |                   Starting subsection sample_subsection_2                    |
%AETEST-INFO: +------------------------------------------------------------------------------+
%SCRIPT-INFO: Inside subsection sample_subsection_2
%SCRIPT-INFO: Inside class common_setup
%AETEST-INFO: The result of subsection sample_subsection_2 is => PASSED
%AETEST-INFO: The result of common setup is => PASSED
%AETEST-INFO: +------------------------------------------------------------------------------+
%AETEST-INFO: |                           Starting testcase tc_one                           |
%AETEST-INFO: +------------------------------------------------------------------------------+
%AETEST-INFO: +------------------------------------------------------------------------------+
%AETEST-INFO: |                      Starting section prepare_testcase                       |
%AETEST-INFO: +------------------------------------------------------------------------------+
%SCRIPT-INFO: Preparing the test
%SCRIPT-INFO: section prepare_testcase
%AETEST-INFO: The result of section prepare_testcase is => PASSED
%AETEST-INFO: +------------------------------------------------------------------------------+
%AETEST-INFO: |                        Starting section simple_test_1                        |
%AETEST-INFO: +------------------------------------------------------------------------------+
%SCRIPT-INFO: First test section
%AETEST-INFO: The result of section simple_test_1 is => PASSED
%AETEST-INFO: +------------------------------------------------------------------------------+
%AETEST-INFO: |                        Starting section simple_test_2                        |
%AETEST-INFO: +------------------------------------------------------------------------------+
%SCRIPT-INFO: Second test section
%AETEST-INFO: The result of section simple_test_2 is => PASSED
%AETEST-INFO: +------------------------------------------------------------------------------+
%AETEST-INFO: |                       Starting section clean_testcase                        |
%AETEST-INFO: +------------------------------------------------------------------------------+
%SCRIPT-INFO: Pass testcase cleanup
%AETEST-INFO: The result of section clean_testcase is => PASSED
%AETEST-INFO: The result of testcase tc_one is => PASSED
%AETEST-INFO: +------------------------------------------------------------------------------+
%AETEST-INFO: |                           Starting testcase tc_two                           |
%AETEST-INFO: +------------------------------------------------------------------------------+
%AETEST-WARNING: Section 'tc_two' does not match up to: Or('common_setup', 'tc_one', 'common_cleanup')
%AETEST-WARNING: Skipping section...
%AETEST-INFO: The result of testcase tc_two is => SKIPPED
%AETEST-INFO: +------------------------------------------------------------------------------+
%AETEST-INFO: |                           Starting common cleanup                            |
%AETEST-INFO: +------------------------------------------------------------------------------+
%AETEST-INFO: +------------------------------------------------------------------------------+
%AETEST-INFO: |                     Starting subsection clean_everything                     |
%AETEST-INFO: +------------------------------------------------------------------------------+
%SCRIPT-INFO: Aetest Common Cleanup
%AETEST-INFO: The result of subsection clean_everything is => PASSED
%AETEST-INFO: The result of common cleanup is => PASSED
%EASYPY-INFO: Task-2 doesn't exist in the rerun_file or it doesn't have any testcase matching the condition: ['FAILED']. Therefore, it will be skipped
%EASYPY-INFO: Job finished. Wrapping up...
%EASYPY-INFO: Creating archive file /path/to/zip/file
%EASYPY-INFO: +------------------------------------------------------------------------------+
%EASYPY-INFO: |                                Easypy Report                                 |
%EASYPY-INFO: +------------------------------------------------------------------------------+
%EASYPY-INFO: pyATS Instance   : /path/to/instance
%EASYPY-INFO: Python Version   : cpython-3.4.1
%EASYPY-INFO: CLI Arguments    : easypy basic_example_job.py
%EASYPY-INFO: User             : tyilder
%EASYPY-INFO: Host Server      : nostg-ott-lnx-1
%EASYPY-INFO: Host OS Version  : Red Hat Enterprise Linux Client 5.5 Tikanga (x86_64)
%EASYPY-INFO:
%EASYPY-INFO: Job Information
%EASYPY-INFO:     Name         : basic_example_job
%EASYPY-INFO:     Start time   : 2016-04-13 17:24:18.439174
%EASYPY-INFO:     Stop time    : 2016-04-13 17:24:18.787723
%EASYPY-INFO:     Elapsed time : 0:00:00.348549
%EASYPY-INFO:     Archive      : /path/to/zip/file
%EASYPY-INFO:
%EASYPY-INFO: Total Tasks    : 1
%EASYPY-INFO:
%EASYPY-INFO: Overall Stats
%EASYPY-INFO:     Passed     : 3
%EASYPY-INFO:     Passx      : 0
%EASYPY-INFO:     Failed     : 0
%EASYPY-INFO:     Aborted    : 0
%EASYPY-INFO:     Blocked    : 0
%EASYPY-INFO:     Skipped    : 1
%EASYPY-INFO:     Errored    : 0
%EASYPY-INFO:
%EASYPY-INFO:     TOTAL      : 4
%EASYPY-INFO:
%EASYPY-INFO: Success Rate   : 100.00 %
%EASYPY-INFO:
%EASYPY-INFO: +------------------------------------------------------------------------------+
%EASYPY-INFO: |                             Task Result Summary                              |
%EASYPY-INFO: +------------------------------------------------------------------------------+
%EASYPY-INFO: Task-1: basic_example_script.commonSetup                                 PASSED
%EASYPY-INFO: Task-1: basic_example_script.tc_one                                      PASSED
%EASYPY-INFO: Task-1: basic_example_script.commonCleanup                               PASSED
%EASYPY-INFO:
%EASYPY-INFO: +------------------------------------------------------------------------------+
%EASYPY-INFO: |                             Task Result Details                              |
%EASYPY-INFO: +------------------------------------------------------------------------------+
%EASYPY-INFO: Task-1: basic_example_script
%EASYPY-INFO: |-- commonSetup                                                           PASSED
%EASYPY-INFO: |   |-- sample_subsection_1                                               PASSED
%EASYPY-INFO: |   `-- sample_subsection_2                                               PASSED
%EASYPY-INFO: |-- tc_one                                                                PASSED
%EASYPY-INFO: |   |-- prepare_testcase                                                  PASSED
%EASYPY-INFO: |   |-- simple_test_1                                                     PASSED
%EASYPY-INFO: |   |-- simple_test_2                                                     PASSED
%EASYPY-INFO: |   `-- clean_testcase                                                    PASSED
%EASYPY-INFO: `-- commonCleanup                                                         PASSED
%EASYPY-INFO:     `-- clean_everything                                                  PASSED

Note

tc_two from Task-1 and the entirety of Task-2 are omitted because they did not match the condition Failed.

Rerun Selection

In this example, assume we have the same job, but we wish to run tc_two for Task-1 and tc_one for Task-2. We could create the following file.

Task-1:
  testcases:
  - name: tc_two
  testscript: path/to/script
Task-2:
  testcases:
  - name: tc_one
  testscript: path/to/script

The final result would look like this:

%EASYPY-INFO: Total Tasks    : 2
%EASYPY-INFO:
%EASYPY-INFO: Overall Stats
%EASYPY-INFO:     Passed     : 6
%EASYPY-INFO:     Passx      : 0
%EASYPY-INFO:     Failed     : 0
%EASYPY-INFO:     Aborted    : 0
%EASYPY-INFO:     Blocked    : 0
%EASYPY-INFO:     Skipped    : 0
%EASYPY-INFO:     Errored    : 0
%EASYPY-INFO:
%EASYPY-INFO:     TOTAL      : 6
%EASYPY-INFO:
%EASYPY-INFO: Success Rate   : 100.00 %
%EASYPY-INFO:
%EASYPY-INFO: +------------------------------------------------------------------------------+
%EASYPY-INFO: |                             Task Result Summary                              |
%EASYPY-INFO: +------------------------------------------------------------------------------+
%EASYPY-INFO: Task-1: basic_example_script.commonSetup                                 PASSED
%EASYPY-INFO: Task-1: basic_example_script.tc_two                                      PASSED
%EASYPY-INFO: Task-1: basic_example_script.commonCleanup                               PASSED
%EASYPY-INFO: Task-2: basic_example_script.commonSetup                                 PASSED
%EASYPY-INFO: Task-2: basic_example_script.tc_one                                      PASSED
%EASYPY-INFO: Task-2: basic_example_script.commonCleanup                               PASSED
%EASYPY-INFO:
%EASYPY-INFO: +------------------------------------------------------------------------------+
%EASYPY-INFO: |                             Task Result Details                              |
%EASYPY-INFO: +------------------------------------------------------------------------------+
%EASYPY-INFO: Task-1: basic_example_script
%EASYPY-INFO: |-- commonSetup                                                           PASSED
%EASYPY-INFO: |   |-- sample_subsection_1                                               PASSED
%EASYPY-INFO: |   `-- sample_subsection_2                                               PASSED
%EASYPY-INFO: |-- tc_two                                                                PASSED
%EASYPY-INFO: |   |-- prepare_testcase                                                  PASSED
%EASYPY-INFO: |   |-- simple_test_1                                                     PASSED
%EASYPY-INFO: |   |-- simple_test_2                                                     PASSED
%EASYPY-INFO: |   `-- clean_testcase                                                    PASSED
%EASYPY-INFO: `-- commonCleanup                                                         PASSED
%EASYPY-INFO:     `-- clean_everything                                                  PASSED
%EASYPY-INFO: Task-2: basic_example_script
%EASYPY-INFO: |-- commonSetup                                                           PASSED
%EASYPY-INFO: |   |-- sample_subsection_1                                               PASSED
%EASYPY-INFO: |   `-- sample_subsection_2                                               PASSED
%EASYPY-INFO: |-- tc_one                                                                PASSED
%EASYPY-INFO: |   |-- prepare_testcase                                                  PASSED
%EASYPY-INFO: |   |-- simple_test_1                                                     PASSED
%EASYPY-INFO: |   |-- simple_test_2                                                     PASSED
%EASYPY-INFO: |   `-- clean_testcase                                                    PASSED
%EASYPY-INFO: `-- commonCleanup                                                         PASSED
%EASYPY-INFO:     `-- clean_everything                                                  PASSED