Now that you have successfully developed the automation to verify the software version on one device, you will edit the test case to verify the software version on all the devices in your test bed.
From the Job File page:
In order to connect to all the devices in your testbed, you will just need to make a few simple changes to the Connect to Devices step in your Job File. First, you will wrap the code in a FOR loop to iterate over a list of devices.
Secondly, since you will need to change the DEVICES var to a list in the next step, you will need to ensure that the DEVICES var used
in the FOR loop uses the correct Robot Framework variable syntax of @{DEVICES}, prefaced with an "@" sign for a list rather than the
syntax of ${DEVICES}, prefaced with a "$" sign for scalar variables.
*** Test Cases ***
1. CONNECT TO DEVICES
FOR ${DEVICE} IN @{DEVICES}
${status}= Run Keyword And Ignore Error connect to device "${DEVICE}"
IF '${status[0]}' == 'FAIL'
Fail ++UNSUCCESSFUL++ ${DEVICE} not connected
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} connected \n append=True
END
END
In the Script Text editor:
*** Settings ***
Library CXTA
Resource cxta.robot
Library BuiltIn
Library Collections
Suite Setup Run Keywords
... load testbed
Suite Teardown Run Keywords
... Disconnect From All Devices
*** Test Cases ***
1. CONNECT TO DEVICES
FOR ${DEVICE} IN @{DEVICES}
${status}= Run Keyword And Ignore Error connect to device "${DEVICE}"
IF '${status[0]}' == 'FAIL'
Fail ++UNSUCCESSFUL++ ${DEVICE} not connected
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} connected \n append=True
END
END
2. VERIFY SOFTWARE VERSION
${VERSION_OUTPUT}= parse "show version" on device "${DEVICES}"
${CFG_VERSION}= Get From Dictionary ${VERSION_OUTPUT['version']} version
${status}= Run Keyword And Return Status should be true '${CFG_VERSION}' == '${EXP_XE_8K_VERSION}'
IF '${status}' == 'False'
Fail ++UNSUCCESSFUL++ Device ${DEVICES} is not running the expected version ${EXP_XE_8K_VERSION}
ELSE
set test message ++SUCCESSFUL++ ${DEVICES} is running the expected version ${CFG_VERSION}\n append=True
END
As the Parameter File is a YAML file, you will use YAML syntax to define the list, as in the following example.
In the Parameter File editor:
DEVICES:
- C8Kv-01
- CSR1Kv-01
- XR9Kv-01
- N9Kv-01
EXP_XE_8K_VERSION: 17.12.2
Your testbed devices are running 4 different software versions on 3 different Cisco operating systems, so editing this procedure to iterate over all the devices in your testbed and verify that they are all running the expected software version will require a bit more logic than the previous step.
First, as in the step above, you will add a FOR loop to iterate over the devices. Second, you will add logic to conditionally execute keywords based on device attributes that you already provided when creating your device inventory on the Devices page.
*** Settings ***
Library CXTA
Resource cxta.robot
Library BuiltIn
Library Collections
Suite Setup Run Keywords
... load testbed
Suite Teardown Run Keywords
... Disconnect From All Devices
*** Test Cases ***
1. CONNECT TO DEVICES
FOR ${DEVICE} IN @{DEVICES}
${status}= Run Keyword And Ignore Error connect to device "${DEVICE}"
IF '${status[0]}' == 'FAIL'
Fail ++UNSUCCESSFUL++ ${DEVICE} not connected
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} connected \n append=True
END
END
2. VERIFY SOFTWARE VERSION
FOR ${DEVICE} IN @{DEVICES}
You already changed the DEVICES variable to a list of devices in the previous step, so there's no need for any further modifications to the Parameter File yet.
In the nex steps, you will add code to conditionally execute keywords and verify software versions based on the device OS (e.g. IOS-XE vs IOS-XR vs NXOS) and device type (e.g. C8Kv vs CSR1Kv) in your testbed topology. The assumption made here is that the devices in the testbed are running the expected software versions according to each device's OS, platform, role, etc, as defined in a hypothetical network deployment plan. (e.g. the hypothetical deployment plan in this example dictates that a newly inserted C8Kv device should be running IOS-XE version 17.12.2).
The testbed topology in this lab is intentionally small and simple to illustrate concepts. Your own staging environment may be comparatively larger and more complex, but the same logic could apply to conditionally execute the appropriate procedures based on your own device inventory.
Recall the topology file that you previewed earlier in the lab after adding your devices to the Devices page, and the attributes associated with each device.
testbed:
name: ltrops2711
devices:
<snip>
C8Kv-01:
type: router
connections:
ssh:
protocol: ssh
ip: 10.15.121.12
username: admin
password: cisco.123
class: unicon.Unicon
defaults:
via: ssh
os: iosxe
<snip>
*** Settings ***
Library CXTA
Resource cxta.robot
Library BuiltIn
Library Collections
Suite Setup Run Keywords
... load testbed
Suite Teardown Run Keywords
... Disconnect From All Devices
*** Test Cases ***
1. CONNECT TO DEVICES
FOR ${DEVICE} IN @{DEVICES}
${status}= Run Keyword And Ignore Error connect to device "${DEVICE}"
IF '${status[0]}' == 'FAIL'
Fail ++UNSUCCESSFUL++ ${DEVICE} not connected
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} connected \n append=True
END
END
2. VERIFY SOFTWARE VERSION
FOR ${DEVICE} IN @{DEVICES}
${os}= from testbed devices get "${DEVICE}.os"
This step introduces a new keyword. The from testbed devices get "${attr}" keyword from the CXTA.robot.Testbed library gets a specific attribute from the devices in the testbed, based on the attribute key passed to it. The value for the os attribute is fetched in this example, and stored in a local variable for use in subsequent procedures.
You will be able to reuse the code you developed earlier when verifying the software version on a single IOS-XE device, only now you will nest it within IF-ELSE logic.
You have already used IF-ELSE statements to conditionally set test messages based on a returned status. Next, you will use them to conditionally execute code based on the device attributes fetched from your topology file. This is necessary because the parser schema is different for each operating system, and the correct parser key for the operating system must be used. Also, each device in your testbed is running a different version of software, so different variables are used in this example.
*** Settings ***
Library CXTA
Resource cxta.robot
Library BuiltIn
Library Collections
Suite Setup Run Keywords
... load testbed
Suite Teardown Run Keywords
... Disconnect From All Devices
*** Test Cases ***
1. CONNECT TO DEVICES
FOR ${DEVICE} IN @{DEVICES}
${status}= Run Keyword And Ignore Error connect to device "${DEVICE}"
IF '${status[0]}' == 'FAIL'
Fail ++UNSUCCESSFUL++ ${DEVICE} not connected
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} connected \n append=True
END
END
2. VERIFY SOFTWARE VERSION
FOR ${DEVICE} IN @{DEVICES}
${os}= from testbed devices get "${DEVICE}.os"
IF "${os}" == "iosxe" and "8K" in "${DEVICE}"
select device "${DEVICE}"
${VERSION_OUTPUT}= parse "show version" on device "${DEVICE}"
${CFG_VERSION}= Get From Dictionary ${VERSION_OUTPUT['version']} version
${status}= Run Keyword And Return Status should be true '${CFG_VERSION}' == '${EXP_XE_8K_VERSION}'
IF '${status}' == 'False'
Fail ++UNSUCCESSFUL++ Device ${DEVICE} is not running the expected version ${EXP_XE_8K_VERSION}
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} is running the expected version ${CFG_VERSION}\n append=True
END
In the previous step, you added conditional logic to execute code if the os equals "iosxe" and the device hostname includes "8K". Next, you will add conditional logic to execute code for IOS-XE CSR1Kv devices.
*** Settings ***
Library CXTA
Resource cxta.robot
Library BuiltIn
Library Collections
Suite Setup Run Keywords
... load testbed
Suite Teardown Run Keywords
... Disconnect From All Devices
*** Test Cases ***
1. CONNECT TO DEVICES
FOR ${DEVICE} IN @{DEVICES}
${status}= Run Keyword And Ignore Error connect to device "${DEVICE}"
IF '${status[0]}' == 'FAIL'
Fail ++UNSUCCESSFUL++ ${DEVICE} not connected
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} connected \n append=True
END
END
2. VERIFY SOFTWARE VERSION
FOR ${DEVICE} IN @{DEVICES}
${os}= from testbed devices get "${DEVICE}.os"
IF "${os}" == "iosxe" and "8K" in "${DEVICE}"
select device "${DEVICE}"
${VERSION_OUTPUT}= parse "show version" on device "${DEVICE}"
${CFG_VERSION}= Get From Dictionary ${VERSION_OUTPUT['version']} version
${status}= Run Keyword And Return Status should be true '${CFG_VERSION}' == '${EXP_XE_8K_VERSION}'
IF '${status}' == 'False'
Fail ++UNSUCCESSFUL++ Device ${DEVICE} is not running the expected version ${EXP_XE_8K_VERSION}
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} is running the expected version ${CFG_VERSION}\n append=True
END
ELSE IF "${os}" == "iosxe" and "1K" in "${DEVICE}"
select device "${DEVICE}"
${VERSION_OUTPUT}= parse "show version" on device "${DEVICE}"
${CFG_VERSION}= Get From Dictionary ${VERSION_OUTPUT['version']} version
${status}= Run Keyword And Return Status should be true '${CFG_VERSION}' == '${EXP_XE_1K_VERSION}'
IF '${status}' == 'False'
Fail ++UNSUCCESSFUL++ Device ${DEVICE} is not running the expected version ${EXP_XE_1K_VERSION}
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} is running the expected version ${CFG_VERSION}\n append=True
END
There are only three minor changes in this code, relative to the last step. First, notice the ELSE IF in line 39. ELSE IF branches are evaluated in the order in which they are coded in the Job File, and their conditions are evaluated if preceding conditions are not true. The block of code following the ELSE IF will be executed if the condition is true, ignoring any subsequent branches.
Second, the code has changed to check that "1K" is present in the device hostname to catch the CSR1Kv devices in your topology. Since the CSR1Kv device also runs IOS-XE, the parser schema is the same and does not need to change in this IF-ELSE branch.
And third, since the IOS-XE CSR1Kv devices run a different software version than the IOS-XE C8Kv devices in your topology, a new variable, EXP_XE_1K_VERSION, has been introduced. You'll define this variable in a later step.
Next, you will add conditional logic to execute code for the IOS-XR routers in your topology.
*** Settings ***
Library CXTA
Resource cxta.robot
Library BuiltIn
Library Collections
Suite Setup Run Keywords
... load testbed
Suite Teardown Run Keywords
... Disconnect From All Devices
*** Test Cases ***
1. CONNECT TO DEVICES
FOR ${DEVICE} IN @{DEVICES}
${status}= Run Keyword And Ignore Error connect to device "${DEVICE}"
IF '${status[0]}' == 'FAIL'
Fail ++UNSUCCESSFUL++ ${DEVICE} not connected
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} connected \n append=True
END
END
2. VERIFY SOFTWARE VERSION
FOR ${DEVICE} IN @{DEVICES}
${os}= from testbed devices get "${DEVICE}.os"
IF "${os}" == "iosxe" and "8K" in "${DEVICE}"
select device "${DEVICE}"
${VERSION_OUTPUT}= parse "show version" on device "${DEVICE}"
${CFG_VERSION}= Get From Dictionary ${VERSION_OUTPUT['version']} version
${status}= Run Keyword And Return Status should be true '${CFG_VERSION}' == '${EXP_XE_8K_VERSION}'
IF '${status}' == 'False'
Fail ++UNSUCCESSFUL++ Device ${DEVICE} is not running the expected version ${EXP_XE_8K_VERSION}
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} is running the expected version ${CFG_VERSION}\n append=True
END
ELSE IF "${os}" == "iosxe" and "1K" in "${DEVICE}"
select device "${DEVICE}"
${VERSION_OUTPUT}= parse "show version" on device "${DEVICE}"
${CFG_VERSION}= Get From Dictionary ${VERSION_OUTPUT['version']} version
${status}= Run Keyword And Return Status should be true '${CFG_VERSION}' == '${EXP_XE_1K_VERSION}'
IF '${status}' == 'False'
Fail ++UNSUCCESSFUL++ Device ${DEVICE} is not running the expected version ${EXP_XE_1K_VERSION}
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} is running the expected version ${CFG_VERSION}\n append=True
END
ELSE IF "${os}" == "iosxr"
select device "${DEVICE}"
${VERSION_OUTPUT}= parse "show version" on device "${DEVICE}"
${CFG_VERSION}= Get From Dictionary ${VERSION_OUTPUT} software_version
${status}= Run Keyword And Return Status should be true '${CFG_VERSION}' == '${EXP_XR_VERSION}'
IF '${status}' == 'False'
Fail ++UNSUCCESSFUL++ Device ${DEVICE} is not running the expected version ${EXP_XR_VERSION}
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} is running the expected version ${CFG_VERSION}\n append=True
END
Notice that the "os" attribute has been changed to "iosxr". Since there is only one IOS-XR device type in your topology, no additional criteria to identify the device type is needed in this step.
However, the key used to get the IOS-XR software version in the parser has changed in accordance with the published IOS-XR show version parser schema.
{
'operating_system': <class 'str'>,
'software_version': <class 'str'>,
'uptime': <class 'str'>,
Optional (str) image: <class 'str'>,
Optional (str) device_family: <class 'str'>,
Optional (str) processor: <class 'str'>,
Optional (str) processor_memory_bytes: <class 'str'>,
Optional (str) chassis_detail: <class 'str'>,
Optional (str) config_register: <class 'str'>,
Optional (str) rp_config_register: <class 'str'>,
Optional (str) main_mem: <class 'str'>,
Optional (str) built_by: <class 'str'>,
Optional (str) built_on: <class 'str'>,
Optional (str) built_host: <class 'str'>,
}
Also, you have added a new variable for the expected IOS-XR version (EXP_XR_VERSION). You will define this variable in a later step.
Finally, you will add conditional logic to execute code for the NXOS devices in your topology.
*** Settings ***
Library CXTA
Resource cxta.robot
Library BuiltIn
Library Collections
Suite Setup Run Keywords
... load testbed
Suite Teardown Run Keywords
... Disconnect From All Devices
*** Test Cases ***
1. CONNECT TO DEVICES
FOR ${DEVICE} IN @{DEVICES}
${status}= Run Keyword And Ignore Error connect to device "${DEVICE}"
IF '${status[0]}' == 'FAIL'
Fail ++UNSUCCESSFUL++ ${DEVICE} not connected
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} connected \n append=True
END
END
2. VERIFY SOFTWARE VERSION
FOR ${DEVICE} IN @{DEVICES}
${os}= from testbed devices get "${DEVICE}.os"
IF "${os}" == "iosxe" and "8K" in "${DEVICE}"
select device "${DEVICE}"
${VERSION_OUTPUT}= parse "show version" on device "${DEVICE}"
${CFG_VERSION}= Get From Dictionary ${VERSION_OUTPUT['version']} version
${status}= Run Keyword And Return Status should be true '${CFG_VERSION}' == '${EXP_XE_8K_VERSION}'
IF '${status}' == 'False'
Fail ++UNSUCCESSFUL++ Device ${DEVICE} is not running the expected version ${EXP_XE_8K_VERSION}
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} is running the expected version ${CFG_VERSION}\n append=True
END
ELSE IF "${os}" == "iosxe" and "1K" in "${DEVICE}"
select device "${DEVICE}"
${VERSION_OUTPUT}= parse "show version" on device "${DEVICE}"
${CFG_VERSION}= Get From Dictionary ${VERSION_OUTPUT['version']} version
${status}= Run Keyword And Return Status should be true '${CFG_VERSION}' == '${EXP_XE_1K_VERSION}'
IF '${status}' == 'False'
Fail ++UNSUCCESSFUL++ Device ${DEVICE} is not running the expected version ${EXP_XE_1K_VERSION}
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} is running the expected version ${CFG_VERSION}\n append=True
END
ELSE IF "${os}" == "iosxr"
select device "${DEVICE}"
${VERSION_OUTPUT}= parse "show version" on device "${DEVICE}"
${CFG_VERSION}= Get From Dictionary ${VERSION_OUTPUT} software_version
${status}= Run Keyword And Return Status should be true '${CFG_VERSION}' == '${EXP_XR_VERSION}'
IF '${status}' == 'False'
Fail ++UNSUCCESSFUL++ Device ${DEVICE} is not running the expected version ${EXP_XR_VERSION}
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} is running the expected version ${CFG_VERSION}\n append=True
END
ELSE IF "${os}" == "nxos"
select device "${DEVICE}"
${VERSION_OUTPUT}= parse "show version" on device "${DEVICE}"
${CFG_VERSION}= Get From Dictionary ${VERSION_OUTPUT['platform']['software']} system_version
${status}= Run Keyword And Return Status should be true '${CFG_VERSION}' == '${EXP_NXOS_VERSION}'
IF '${status}' == 'False'
Fail ++UNSUCCESSFUL++ Device ${DEVICE} is not running the expected version ${EXP_NXOS_VERSION}
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} is running the expected version ${CFG_VERSION}\n append=True
END
END
END
Notice that the "os" attribute has been changed to "nxos". Similarly to IOS-XR, since there is only one NXOS device type in your topology, an additional device type check is not needed in this step. Also like IOS-XR, NXOS has its own parser schema, so the key used to get the NXOS software version has changed in accordance with the published NXOS show version parser schema.
{
'platform': {
<snip>
},
'software': {
Optional (str) bios_version: <class 'str'>,
Optional (str) bios_compile_time: <class 'str'>,
Optional (str) kickstart_version: <class 'str'>,
Optional (str) kickstart_compile_time: <class 'str'>,
Optional (str) kickstart_image_file: <class 'str'>,
Optional (str) system_version: <class 'str'>,
Optional (str) system_compile_time: <class 'str'>,
Optional (str) system_image_file: <class 'str'>,
},
},
}
Also, you have added a new variable for the expected NXOS version (EXP_NXOS_VERSION). You will define this variable, and the other new variables introduced above, in the next step.
In the Parameter File editor:
DEVICES:
- C8Kv-01
- CSR1Kv-01
- XR9Kv-01
- N9Kv-01
EXP_XE_8K_VERSION: 17.12.2
EXP_XE_1K_VERSION: 17.3.8a
EXP_XR_VERSION: 7.4.1
EXP_NXOS_VERSION: 9.3(13)
While on the Job File Edit page:
When you ran this test case on the on just the C8Kv-01 device in the previous section, the Default Topology was set to Generate topology at runtime by default, which generates a topology based on the devices on the Devices page. Since you will be rerunning this test case on all devices in the testbed, you will need to set the Default Topology to the LTROPS-2711 Topology, which includes all the devices you will be interfacing with in this lab.
Congratulations! You have added all of the procedures and variables needed to the run this test case.
*** Settings ***
Library CXTA
Resource cxta.robot
Library BuiltIn
Library Collections
Suite Setup Run Keywords
... load testbed
Suite Teardown Run Keywords
... Disconnect From All Devices
*** Test Cases ***
1. CONNECT TO DEVICES
FOR ${DEVICE} IN @{DEVICES}
${status}= Run Keyword And Ignore Error connect to device "${DEVICE}"
IF '${status[0]}' == 'FAIL'
Fail ++UNSUCCESSFUL++ ${DEVICE} not connected
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} connected \n append=True
END
END
2. VERIFY SOFTWARE VERSION
FOR ${DEVICE} IN @{DEVICES}
${os}= from testbed devices get "${DEVICE}.os"
IF "${os}" == "iosxe" and "8K" in "${DEVICE}"
select device "${DEVICE}"
${VERSION_OUTPUT}= parse "show version" on device "${DEVICE}"
${CFG_VERSION}= Get From Dictionary ${VERSION_OUTPUT['version']} version
${status}= Run Keyword And Return Status should be true '${CFG_VERSION}' == '${EXP_XE_8K_VERSION}'
IF '${status}' == 'False'
Fail ++UNSUCCESSFUL++ Device ${DEVICE} is not running the expected version ${EXP_XE_8K_VERSION}
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} is running the expected version ${CFG_VERSION}\n append=True
END
ELSE IF "${os}" == "iosxe" and "1K" in "${DEVICE}"
select device "${DEVICE}"
${VERSION_OUTPUT}= parse "show version" on device "${DEVICE}"
${CFG_VERSION}= Get From Dictionary ${VERSION_OUTPUT['version']} version
${status}= Run Keyword And Return Status should be true '${CFG_VERSION}' == '${EXP_XE_1K_VERSION}'
IF '${status}' == 'False'
Fail ++UNSUCCESSFUL++ Device ${DEVICE} is not running the expected version ${EXP_XE_1K_VERSION}
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} is running the expected version ${CFG_VERSION}\n append=True
END
ELSE IF "${os}" == "iosxr"
select device "${DEVICE}"
${VERSION_OUTPUT}= parse "show version" on device "${DEVICE}"
${CFG_VERSION}= Get From Dictionary ${VERSION_OUTPUT} software_version
${status}= Run Keyword And Return Status should be true '${CFG_VERSION}' == '${EXP_XR_VERSION}'
IF '${status}' == 'False'
Fail ++UNSUCCESSFUL++ Device ${DEVICE} is not running the expected version ${EXP_XR_VERSION}
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} is running the expected version ${CFG_VERSION}\n append=True
END
ELSE IF "${os}" == "nxos"
select device "${DEVICE}"
${VERSION_OUTPUT}= parse "show version" on device "${DEVICE}"
${CFG_VERSION}= Get From Dictionary ${VERSION_OUTPUT['platform']['software']} system_version
${status}= Run Keyword And Return Status should be true '${CFG_VERSION}' == '${EXP_NXOS_VERSION}'
IF '${status}' == 'False'
Fail ++UNSUCCESSFUL++ Device ${DEVICE} is not running the expected version ${EXP_NXOS_VERSION}
ELSE
set test message ++SUCCESSFUL++ ${DEVICE} is running the expected version ${CFG_VERSION}\n append=True
END
END
END
DEVICES:
- C8Kv-01
- CSR1Kv-01
- XR9Kv-01
- N9Kv-01
EXP_XE_8K_VERSION: 17.12.2
EXP_XE_1K_VERSION: 17.3.8a
EXP_XR_VERSION: 7.4.1
EXP_NXOS_VERSION: 9.3(13)
After clicking the SAVE AND RUN button, CXTM will return you to the Job File page.
From the test case Job File page:
From the test case Job File page:
Notify your proctor if your test case result is not PASSED before moving on.
From the test case Job File page:
From the Job File Results page:
From your test case Job File Results page:
Now that a test case has been run from your project, take a moment to observe how your project dashboard has changed.
From your CXTM project's Home page:
Continue to the next section to create additional test cases to verify the interface state on your devices.