Esempio n. 1
0
    def setUp(self):

      dir_name = os.path.dirname(os.path.abspath(__file__))

      f, self.jobfile = tempfile.mkstemp()
      init_runtime(runtime)
      runtime.configuration.load()
      runtime.job = Job(jobfile = self.jobfile,
                        runtime = runtime,
                        **runtime.configuration.components.job)

      mgr = runtime.tasks
      task = mgr.Task(testscript = os.path.join(dir_name, 'mock_yamls/trigger_datafile.yaml'),
                      taskid = 'awesome')

      self.testbed = load(os.path.join(dir_name, 'mock_testbeds/testbed.yaml'))
      self.mock_testbed_devices()
      Blitz.parameters = ParameterMap()
      Blitz.uid = 'test.dev'
      Blitz.parameters['testbed'] = self.testbed

      self.blitz_obj = Blitz()
      self.uid = self.blitz_obj.uid
      self.blitz_obj.parent = self
      self.blitz_obj.parent.parameters = mock.Mock()

      self.dev = Device( name='PE1', os='iosxe')
      self.dev.custom = {'abstraction': {'order': ['os']}}
      self.blitz_obj.parameters['test_sections'] = [{'section1': [{'execute': {'command': 'cmd', 'device': 'PE1'}}]}]
      sections = self.blitz_obj._discover()
      self.kwargs = {'self': self.blitz_obj,
                     'testbed': self.testbed,
                     'section': sections[0].__testcls__(sections[0]),
                     'name': ''}
Esempio n. 2
0
    def setUp(self):

        dir_name = os.path.dirname(os.path.abspath(__file__))
        mfc = MockFuncClass()
        self.testbed = load(
            os.path.join(dir_name, 'mock_testbeds/testbed.yaml'))
        Blitz.parameters = ParameterMap()
        Blitz.uid = 'test.dev'
        Blitz.parameters['testbed'] = self.testbed
        Blitz.parameters['save_variable_name'] = {
            'dev_name': 'PE2',
            'command': 'sh version',
            'sub_command': 'interface',
            'type_k': 1500,
            'list_item': [177, 24, 13, 45],
            'iter_class': mfc,
            'dict1': {
                'st': "name"
            }
        }

        self.blitz_obj = Blitz()
        self.uid = self.blitz_obj.uid
        self.blitz_obj.parent = self
        self.blitz_obj.parent.parameters = mock.Mock()
        self.blitz_obj.parameters['test_sections'] = [{
            'section1': [{
                'execute': {
                    'command': 'cmd',
                    'device': 'PE1'
                }
            }]
        }]
        sections = self.blitz_obj._discover()
        self.section = sections[0].__testcls__(sections[0])
Esempio n. 3
0
    def setUp(self):

        dir_name = os.path.dirname(os.path.abspath(__file__))
        
        self.testbed = load(os.path.join(dir_name, 'mock_testbeds/testbed.yaml'))
        Blitz.parameters = ParameterMap()
        Blitz.uid = 'test.dev'
        Blitz.parameters['testbed'] = self.testbed
        self.blitz_obj = Blitz()
        self.dev = Device( name='PE1', os='iosxe')
        self.dev.custom = {'abstraction': {'order': ['os']}}
        self.blitz_obj.parameters['test_sections'] = [{'section1': [{'action': {'command': 'a'}}]}]
        sections = self.blitz_obj._discover()
        self.kwargs = {'self': self.blitz_obj, 
                       'section': sections[0],
                       'name': ''}
Esempio n. 4
0
    def test_custom_start_step_messsage_with_variable(self):
        #saved variable
        Blitz.parameters['save_variable_name'] = {'command': 'sh version'}
        self.blitz_obj = Blitz()
        self.blitz_obj.parameters['test_sections'] = [{'section1': [{'action': {'command': 'a'}}]}]
        sections = self.blitz_obj._discover()
        self.section = sections[0].__testcls__(sections[0])

        self.kwargs = {
            'self': self.blitz_obj,
            'section': self.section,
            'custom_start_step_message': 'test command: %VARIABLES{command}'
        }

        #To get the saved variable
        replaced_kwargs = get_variable(**self.kwargs)
        self.assertEqual(replaced_kwargs['custom_start_step_message'], 'test command: sh version')
Esempio n. 5
0
    def setUp(self):

        dir_name = os.path.dirname(os.path.abspath(__file__))

        f, self.jobfile = tempfile.mkstemp()
        init_runtime(runtime)
        runtime.configuration.load()
        runtime.job = Job(jobfile=self.jobfile,
                          runtime=runtime,
                          **runtime.configuration.components.job)

        mgr = runtime.tasks
        task = mgr.Task(testscript=os.path.join(
            dir_name, 'mock_yamls/trigger_datafile.yaml'),
                        taskid='awesome')

        self.testbed = load(
            os.path.join(dir_name, 'mock_testbeds/testbed.yaml'))
        self.mock_testbed_devs()
        Blitz.parameters = ParameterMap()
        Blitz.uid = 'test.dev'
        Blitz.parameters['testbed'] = self.testbed

        self.blitz_obj = Blitz()

        self.blitz_obj.parameters['test_sections'] = [{
            'section1': [{
                'parallel': [{
                    'action': {
                        'arg1': 'cmd'
                    }
                }]
            }]
        }]
        sections = self.blitz_obj._discover()

        self.kwargs = {
            'self': self.blitz_obj,
            'testbed': self.testbed,
            'section': sections[0].__testcls__(sections[0]),
            'name': ''
        }
Esempio n. 6
0
    def setUp(self):

        dir_name = os.path.dirname(os.path.abspath(__file__))
        mfc = MockFuncClass()
        self.testbed = load(
            os.path.join(dir_name, 'mock_testbeds/testbed.yaml'))
        Blitz.parameters = ParameterMap()
        Blitz.uid = 'test.dev'
        Blitz.parameters['testbed'] = self.testbed
        Blitz.parameters['save_variable_name'] = {
            'dev_name': 'PE2',
            'command': 'sh version',
            'sub_command': 'interface',
            'type_k': 1500,
            'list_item': [177, 24, 13, 45],
            'iter_class': mfc,
            'dict1': {
                'st': "name"
            }
        }
        self.blitz_obj = Blitz()
Esempio n. 7
0
class TestParallel(unittest.TestCase):

    parser_output = {
        'platform': {
            'name': 'Nexus',
            'os': 'NX-OS',
            'software': {
                'bios_version': '07.33',
                'system_version': '9.3(3) [build 9.3(3)IDI9(0.509)]',
                'bios_compile_time': '08/04/2015',
                'system_image_file':
                'bootflash:///system-image-N93_3-00613722415136',
                'system_compile_time':
                '10/22/2019 10:00:00 [10/22/2019 16:57:31]'
            },
            'hardware': {
                'model': 'Nexus9000 C9396PX',
                'chassis': 'Nexus9000 C9396PX',
                'slots': 'None',
                'rp': 'None',
                'cpu': 'Intel(R) Core(TM) i3- CPU @ 2.50GHz',
                'memory': '16399900 kB',
                'processor_board_id': 'SAL1914CNL6',
                'device_name': 'N93_3',
                'bootflash': '51496280 kB'
            },
            'kernel_uptime': {
                'days': 61,
                'hours': 22,
                'minutes': 8,
                'seconds': 40
            },
            'reason': 'Reset Requested by CLI command reload',
            'system_version': '9.3(3)'
        }
    }

    execute_output = """
        2020-11-24 12:25:43,769: %UNICON-INFO: +++ N93_3: executing command 'show version' +++
        show version
        Cisco Nexus Operating System (NX-OS) Software
        TAC support: http://www.cisco.com/tac
        Copyright (C) 2002-2019, Cisco and/or its affiliates.
        All rights reserved.
        The copyrights to certain works contained in this software are
        owned by other third parties and used and distributed under their own
        licenses, such as open source.  This software is provided "as is," and unless
        otherwise stated, there is no warranty, express or implied, including but not
        limited to warranties of merchantability and fitness for a particular purpose.
        Certain components of this software are licensed under
        the GNU General Public License (GPL) version 2.0 or
        GNU General Public License (GPL) version 3.0  or the GNU
        Lesser General Public License (LGPL) Version 2.1 or
        Lesser General Public License (LGPL) Version 2.0.
        A copy of each such license is available at
        http://www.opensource.org/licenses/gpl-2.0.php and
        http://opensource.org/licenses/gpl-3.0.html and
        http://www.opensource.org/licenses/lgpl-2.1.php and
        http://www.gnu.org/licenses/old-licenses/library.txt.
        Software
          BIOS: version 07.33
         NXOS: version 9.3(3) [build 9.3(3)IDI9(0.509)]
          BIOS compile time:  08/04/2015
          NXOS image file is: bootflash:///system-image-N93_3-00613722415136
          NXOS compile time:  10/22/2019 10:00:00 [10/22/2019 16:57:31]
        Hardware
          cisco Nexus9000 C9396PX Chassis
          Intel(R) Core(TM) i3- CPU @ 2.50GHz with 16399900 kB of memory.
          Processor Board ID SAL1914CNL6
          Device name: N93_3
          bootflash:   51496280 kB
        Kernel uptime is 61 day(s), 22 hour(s), 33 minute(s), 56 second(s)
        Last reset at 930930 usecs after Wed Sep 23 13:59:45 2020
          Reason: Reset Requested by CLI command reload
          System version: 9.3(3)
          Service:
        plugin
          Core Plugin, Ethernet Plugin
        Active Package(s):
    """

    yaml1 = """
            - configure:
                command: feature bgp
                device: PE1
                save:
                  - variable_name: conf1
                description: expected_failure is True passed as a result
            - execute:
                alias: execute_id
                command: show version
                device: PE1
                exclude:
                    - extreme
                include:
                    - host
            - parse:
                command: command
                device: PE1
                include:
                    - contains('software')
                    - get_values('hardware', 0)
            """

    yaml2 = """
            - configure:
                command: feature bgp
                device: PE1
                save:
                  - variable_name: conf1
                description: expected_failure is True passed as a result
            - execute:
                alias: execute_id
                command: show version
                device: PE1
                include:
                    - extreme
            """
    yaml3 = """
            - run_condition:
                if : "%VARIABLES{execute_id} == passed"
                function: failed
                actions:
                    - loop:
                        loop_variable_name: var_name
                        value: ['show vrf', 'show version']
                        loop_until: failed
                        actions:
                          - execute:
                                alias: exec_1
                                device: PE1
                                command: "%VARIABLES{var_name}"
                          - execute:
                                alias: exec_2
                                device: PE2
                                command: "%VARIABLES{var_name}"
                    - loop:
                         loop_variable_name: var_name
                         value: ['show vrf', 'show version']
                         actions:
                           - configure:
                                 device: PE1
                                 command: feature bgp
                           - execute:
                                 device: PE1
                                 command: "%VARIABLES{var_name}"
            - loop:
                loop_variable_name: dev_name
                value: ['PE1','PE2']
                loop_until: passed
                actions:
                    - parse:
                          alias: parse_lopp_w
                          save:
                            - variable_name: parse32
                              filter: contains('hardware')
                          device: "%VARIABLES{dev_name}"
                          command: show version
                    - execute:
                          alias: id
                          device: "%VARIABLES{dev_name}"
                          command: show vrf
            - loop:
                loop_variable_name: dev_name
                value: ['PE1','PE2']
                actions:
                    - execute:
                          device: "%VARIABLES{dev_name}"
                          command: show version
                    - execute:
                          device: "%VARIABLES{dev_name}"
                          command: show version
            - parse:
                alias: parse_id
                command: command
                device: PE1
                include:
                    - contains('software')
                    - get_values('hardware', 0)
            """

    def setUp(self):

        dir_name = os.path.dirname(os.path.abspath(__file__))

        f, self.jobfile = tempfile.mkstemp()
        init_runtime(runtime)
        runtime.configuration.load()
        runtime.job = Job(jobfile=self.jobfile,
                          runtime=runtime,
                          **runtime.configuration.components.job)

        mgr = runtime.tasks
        task = mgr.Task(testscript=os.path.join(
            dir_name, 'mock_yamls/trigger_datafile.yaml'),
                        taskid='awesome')

        self.testbed = load(
            os.path.join(dir_name, 'mock_testbeds/testbed.yaml'))
        self.mock_testbed_devs()
        Blitz.parameters = ParameterMap()
        Blitz.uid = 'test.dev'
        Blitz.parameters['testbed'] = self.testbed

        self.blitz_obj = Blitz()
        self.uid = self.blitz_obj.uid
        self.blitz_obj.parent = self
        self.blitz_obj.parent.parameters = mock.Mock()

        self.blitz_obj.parameters['test_sections'] = [{
            'section1': [{
                'parallel': [{
                    'action': {
                        'arg1': 'cmd'
                    }
                }]
            }]
        }]
        sections = self.blitz_obj._discover()

        self.kwargs = {
            'self': self.blitz_obj,
            'testbed': self.testbed,
            'section': sections[0].__testcls__(sections[0]),
            'name': ''
        }

    def mock_testbed_devs(self):

        side_effects = {
            'configure': ['\n'],
            'execute': ['host execute output', 'oop', 'oot', 'name'],
            'parse': [self.parser_output]
        }

        for dev in self.testbed.devices:
            for action in side_effects.keys():
                setattr(self.testbed.devices[dev], action, mock.Mock())
                setattr(getattr(self.testbed.devices[dev], action),
                        'side_effect', side_effects[action])

    def test_parallel_actions_pass(self):

        steps = Steps()
        data = yaml.safe_load(self.yaml1)
        self.kwargs.update({'data': data, 'steps': steps})
        parallel(**self.kwargs)
        self.assertIn('execute_id',
                      self.blitz_obj.parameters['save_variable_name'])
        self.assertEqual(steps.result, Passed)
        self.assertEqual(
            self.blitz_obj.parameters['save_variable_name']['execute_id'],
            'passed')

    def test_parallel_actions_fail(self):

        steps = Steps()
        data = yaml.safe_load(self.yaml2)
        self.kwargs.update({'data': data, 'steps': steps})
        parallel(**self.kwargs)
        self.assertEqual(steps.result, Failed)
        self.assertEqual(
            self.blitz_obj.parameters['save_variable_name']['execute_id'],
            'failed')

    def test_parallel_loops(self):

        steps = Steps()
        data = yaml.safe_load(self.yaml3)
        self.blitz_obj.parameters['save_variable_name'] = {}
        self.blitz_obj.parameters['save_variable_name'][
            'execute_id'] = 'passed'
        self.kwargs.update({
            'self': self.blitz_obj,
            'data': data,
            'steps': steps
        })

        # TODO alias and saved_vars wont get stored when under loop/run_condition
        # self.assertIn('exec_1', self.blitz_obj.parameters['save_variable_name'])
        parallel(**self.kwargs)
        self.assertIn('parse_id',
                      self.blitz_obj.parameters['save_variable_name'])
        self.assertEqual(steps.result, Failed)
        self.assertEqual(steps.details[0].name,
                         'Executing actions in parallel')
        self.assertEqual(
            steps.details[1].name,
            'Condition %VARIABLES{execute_id} == passed is met and '
            'the step result is failed')
        self.assertEqual(steps.details[1].result, Failed)
Esempio n. 8
0
class TestMarkup(unittest.TestCase):

    dict_output = {'platform': {'name': 'Nexus',
                   'os': 'NX-OS',
                   'software': {'bios_version': '07.33',
                    'system_version': '9.3(3) [build 9.3(3)IDI9(0.509)]',
                    'bios_compile_time': '08/04/2015',
                    'system_image_file': 'bootflash:///system-image-N93_3-00613722415136',
                    'system_compile_time': '10/22/2019 10:00:00 [10/22/2019 16:57:31]'},
                   'hardware': {'model': 'Nexus9000 C9396PX',
                    'chassis': 'Nexus9000 C9396PX',
                    'slots': 'None',
                    'rp': 'None',
                    'cpu': 'Intel(R) Core(TM) i3- CPU @ 2.50GHz',
                    'memory': '16399900 kB',
                    'processor_board_id': 'SAL1914CNL6',
                    'device_name': 'N93_3',
                    'bootflash': '51496280 kB'},
                   'kernel_uptime': {'days': 61, 'hours': 22, 'minutes': 8, 'seconds': 40},
                   'reason': 'Reset Requested by CLI command reload',
                   'system_version': '9.3(3)'}}

    str_output = """

        2020-11-24 12:25:43,769: %UNICON-INFO: +++ N93_3: executing command 'show version' +++
        show version
        Cisco Nexus Operating System (NX-OS) Software
        TAC support: http://www.cisco.com/tac
        Copyright (C) 2002-2019, Cisco and/or its affiliates.
        All rights reserved.
        The copyrights to certain works contained in this software are
        owned by other third parties and used and distributed under their own
        licenses, such as open source.  This software is provided "as is," and unless
        otherwise stated, there is no warranty, express or implied, including but not
        limited to warranties of merchantability and fitness for a particular purpose.
        Certain components of this software are licensed under
        the GNU General Public License (GPL) version 2.0 or
        GNU General Public License (GPL) version 3.0  or the GNU
        Lesser General Public License (LGPL) Version 2.1 or
        Lesser General Public License (LGPL) Version 2.0.
        A copy of each such license is available at
        http://www.opensource.org/licenses/gpl-2.0.php and
        http://opensource.org/licenses/gpl-3.0.html and
        http://www.opensource.org/licenses/lgpl-2.1.php and
        http://www.gnu.org/licenses/old-licenses/library.txt.

        Software
          BIOS: version 07.33
         NXOS: version 9.3(3) [build 9.3(3)IDI9(0.509)]
          BIOS compile time:  08/04/2015
          NXOS image file is: bootflash:///system-image-N93_3-00613722415136
          NXOS compile time:  10/22/2019 10:00:00 [10/22/2019 16:57:31]


        Hardware
          cisco Nexus9000 C9396PX Chassis
          Intel(R) Core(TM) i3- CPU @ 2.50GHz with 16399900 kB of memory.
          Processor Board ID SAL1914CNL6

          Device name: N93_3
          bootflash:   51496280 kB
        Kernel uptime is 61 day(s), 22 hour(s), 33 minute(s), 56 second(s)

        Last reset at 930930 usecs after Wed Sep 23 13:59:45 2020
          Reason: Reset Requested by CLI command reload
          System version: 9.3(3)
          Service:

        plugin
          Core Plugin, Ethernet Plugin

        Active Package(s):
    """

    def setUp(self):

        dir_name = os.path.dirname(os.path.abspath(__file__))
        mfc = MockFuncClass()
        self.testbed = load(os.path.join(dir_name, 'mock_testbeds/testbed.yaml'))
        Blitz.parameters = ParameterMap()
        Blitz.uid = 'test.dev'
        Blitz.parameters['testbed'] = self.testbed
        Blitz.parameters['save_variable_name'] = {'dev_name': 'PE2',
                                                  'command':'sh version',
                                                  'sub_command': 'interface',
                                                  'type_k': 1500,
                                                  'list_item': [177,24,13,45],
                                                  'iter_class': mfc,
                                                  'dict1': {'st': "name"}}

        self.blitz_obj = Blitz()
        self.uid = self.blitz_obj.uid
        self.blitz_obj.parent = self
        self.blitz_obj.parent.parameters = mock.Mock()
        self.blitz_obj.parameters['test_sections'] = [{'section1': [{'execute': {'command': 'cmd', 'device': 'PE1'}}]}]
        sections = self.blitz_obj._discover()
        self.section = sections[0].__testcls__(sections[0])

    def test_dq_filter_list_index(self):

        list_output = [1,2,3,4,6,7,8,9999,854]
        list_index = 3
        filtered_out = apply_list_filter(self.blitz_obj,
                                         list_output,
                                         list_index=list_index)

        self.assertEqual(filtered_out, 4)

    def test_dq_filter_list_slice(self):

        list_output = [1,2,3,4,6,7,8,9999,854]
        list_index = "[1:4]"
        filtered_out = apply_list_filter(self.blitz_obj,
                                         list_output,
                                         list_index=list_index)

        self.assertEqual(filtered_out, [2,3,4])

    def test_dq_filter_list_regex(self):

        list_output = ["aba", "yes"]
        filtered_out = apply_list_filter(self.blitz_obj,
                                         list_output,
                                         filters='yes')
        self.assertEqual(filtered_out, ["yes"])

        filtered_out = apply_list_filter(self.blitz_obj,
                                         list_output,
                                         filters='\d')
        self.assertEqual(filtered_out, [])

    def test_dq_filter(self):

        filters = "contains('software')"
        filtered_out = apply_dictionary_filter(self.blitz_obj, self.dict_output, filters)

        self.assertEqual(filtered_out, {'platform': {'software': {'bios_version': '07.33',
                                        'system_version': '9.3(3) [build 9.3(3)IDI9(0.509)]',
                                        'bios_compile_time': '08/04/2015',
                                        'system_image_file': 'bootflash:///system-image-N93_3-00613722415136',
                                        'system_compile_time': '10/22/2019 10:00:00 [10/22/2019 16:57:31]'}}})
    def test_string_filter(self):

        filters = r"Device\s+name:\s+(?P<dev>.*)"
        filtered_out = apply_regex_filter(self.blitz_obj, self.str_output, filters)
        self.assertEqual(filtered_out, {'dev': 'N93_3'})

        filters = r"Device\s+name:\s+(?P<dev>NO MATCH)"
        filtered_out = apply_regex_filter(self.blitz_obj, self.str_output, filters)
        self.assertEqual(filtered_out, {})

    def test_no_filter(self):
        # with No filter
        filtered_out = apply_dictionary_filter(self.blitz_obj, output=self.dict_output)
        self.assertEqual(filtered_out, self.dict_output)
        filtered_out = apply_regex_filter(self.blitz_obj, output=self.str_output)
        self.assertEqual(filtered_out, self.str_output)

    def test_get_variable_replace(self):

        kwargs = {'command': r"%VARIABLES{command}",
                  'device': 'PE2',
                  'self': self.blitz_obj,
                  'section': self.section}

        replaced_kwargs = get_variable(**kwargs)
        # check if replacement is done
        self.assertEqual(replaced_kwargs['command'], self.blitz_obj.parameters['save_variable_name']['command'])

    def test_get_variable_replace_replace_keep_type(self):

        kwargs = {'self': self.blitz_obj,
                  'item': {'value': r"%VARIABLES{type_k}",
                           'val': 11,
                           'ls': ['a', {'b':1}]},
                  'section': self.section}

        replaced_kwargs = get_variable(**kwargs)
        # check if type would stay the same
        self.assertEqual(type(replaced_kwargs['item']['value']), int)

    def test_get_variable_replace_replace_mid_str(self):

        kwargs = {'cmd': r"show  %VARIABLES{sub_command}",
                  'self': self.blitz_obj,
                  'section': self.section}

        replaced_kwargs = get_variable(**kwargs)
        self.assertEqual(replaced_kwargs['cmd'], 'show  interface')

    def test_get_variable_replace_replace_list_item(self):

        kwargs = {'cmd': r"%VARIABLES{list_item[2]}",
                  'self': self.blitz_obj,
                  'section': self.section}
        replaced_kwargs = get_variable(**kwargs)
        self.assertEqual(replaced_kwargs['cmd'], 13)

    # TODO check why ._keys and ._values doesnt work
    def test_get_variable_replace_dict_item(self):
        pass

    def test_get_variable_replace_replace_iter_fucnt(self):

        kwargs = {'a': r"%VARIABLES{iter_class.mock_func}",
                  'self': self.blitz_obj,
                  'section': self.section}
        replaced_kwargs = get_variable(**kwargs)
        self.assertEqual(replaced_kwargs['a'], 'mock func returned val')

    def test_save_variable(self):

        save_variable(self.blitz_obj, self.section, 'var1', 'aa')
        self.assertEqual(
            self.blitz_obj.parameters['save_variable_name']['var1'], 'aa')

    def test_save_variable_append(self):

        save_variable(self.blitz_obj, self.section, 'sub_command', 'vrf', append=True)
        self.assertEqual(
            self.blitz_obj.parameters['save_variable_name']['sub_command'], 'interface\nvrf')

    def test_save_variable_append_in_empty_list(self):

        save_variable(self.blitz_obj, self.section, 'new_item', 'VRF1', append_in_list=True)
        self.assertEqual(
            self.blitz_obj.parameters['save_variable_name']['new_item'], ['VRF1'])

    def test_save_variable_append_in_existing_list(self):

        save_variable(self.blitz_obj, self.section, 'list_item', 9000, append_in_list=True)
        self.assertEqual(
            self.blitz_obj.parameters['save_variable_name']['list_item'], [177,24,13,45, 9000])
Esempio n. 9
0
class TestCondition(unittest.TestCase):

    parser_output = {
        'platform': {
            'name': 'Nexus',
            'os': 'NX-OS',
            'software': {
                'bios_version': '07.33',
                'system_version': '9.3(3) [build 9.3(3)IDI9(0.509)]',
                'bios_compile_time': '08/04/2015',
                'system_image_file':
                'bootflash:///system-image-N93_3-00613722415136',
                'system_compile_time':
                '10/22/2019 10:00:00 [10/22/2019 16:57:31]'
            },
            'hardware': {
                'model': 'Nexus9000 C9396PX',
                'chassis': 'Nexus9000 C9396PX',
                'slots': 'None',
                'rp': 'None',
                'cpu': 'Intel(R) Core(TM) i3- CPU @ 2.50GHz',
                'memory': '16399900 kB',
                'processor_board_id': 'SAL1914CNL6',
                'device_name': 'N93_3',
                'bootflash': '51496280 kB'
            },
            'kernel_uptime': {
                'days': 61,
                'hours': 22,
                'minutes': 8,
                'seconds': 40
            },
            'reason': 'Reset Requested by CLI command reload',
            'system_version': '9.3(3)'
        }
    }

    execute_output = """
        2020-11-24 12:25:43,769: %UNICON-INFO: +++ N93_3: executing command 'show version' +++
        show version
        Cisco Nexus Operating System (NX-OS) Software
        TAC support: http://www.cisco.com/tac
        Copyright (C) 2002-2019, Cisco and/or its affiliates.
        All rights reserved.
        The copyrights to certain works contained in this software are
        owned by other third parties and used and distributed under their own
        licenses, such as open source.  This software is provided "as is," and unless
        otherwise stated, there is no warranty, express or implied, including but not
        limited to warranties of merchantability and fitness for a particular purpose.
        Certain components of this software are licensed under
        the GNU General Public License (GPL) version 2.0 or
        GNU General Public License (GPL) version 3.0  or the GNU
        Lesser General Public License (LGPL) Version 2.1 or
        Lesser General Public License (LGPL) Version 2.0.
        A copy of each such license is available at
        http://www.opensource.org/licenses/gpl-2.0.php and
        http://opensource.org/licenses/gpl-3.0.html and
        http://www.opensource.org/licenses/lgpl-2.1.php and
        http://www.gnu.org/licenses/old-licenses/library.txt.
        Software
          BIOS: version 07.33
         NXOS: version 9.3(3) [build 9.3(3)IDI9(0.509)]
          BIOS compile time:  08/04/2015
          NXOS image file is: bootflash:///system-image-N93_3-00613722415136
          NXOS compile time:  10/22/2019 10:00:00 [10/22/2019 16:57:31]
        Hardware
          cisco Nexus9000 C9396PX Chassis
          Intel(R) Core(TM) i3- CPU @ 2.50GHz with 16399900 kB of memory.
          Processor Board ID SAL1914CNL6
          Device name: N93_3
          bootflash:   51496280 kB
        Kernel uptime is 61 day(s), 22 hour(s), 33 minute(s), 56 second(s)
        Last reset at 930930 usecs after Wed Sep 23 13:59:45 2020
          Reason: Reset Requested by CLI command reload
          System version: 9.3(3)
          Service:
        plugin
          Core Plugin, Ethernet Plugin
        Active Package(s):
    """

    condition_1 = """
          if : "%VARIABLES{execute_id} == id1"
          function: failed
          actions:
              - execute:
                    alias: exec_1
                    device: PE1
                    command: cmd
              - execute:
                    alias: exec_2
                    device: PE2
                    command: another
              - configure:
                    device: PE1
                    command: feature bgp
              - execute:
                    device: PE1
                    command: aa
    """

    condition_2 = """
          if : "%VARIABLES{execute_id} == id2"
          function: failed
          actions:
              - execute:
                    alias: exec_1
                    device: PE1
                    command: cmd
              - execute:
                    alias: exec_2
                    device: PE2
                    command: another
              - configure:
                    device: PE1
                    command: feature bgp
              - execute:
                    device: PE1
                    command: aa
    """

    condition_3 = """
          if : "%VARIABLES{execute_id} == id1"
          function: passed
          actions:
              - parallel:
                - execute:
                      alias: exec_1
                      device: PE1
                      command: cmd
                - execute:
                      alias: exec_2
                      device: PE2
                      command: another
                - configure:
                      device: PE1
                      command: feature bgp
                - execute:
                      device: PE1
                      command: aa
    """

    condition_4 = """

          if : "%VARIABLES{execute_id} == id1"
          actions:
            - parallel:
                - execute:
                      alias: exec_1
                      device: PE1
                      command: cmd
                - execute:
                      alias: exec_2
                      device: PE2
                      command: another
                - configure:
                      device: PE1
                      command: feature bgp
                - execute:
                      device: PE1
                      command: aa
    """

    condition_5 = """

          if : "%VARIABLES{execute_id} == id1"
          actions:
            - execute:
                  alias: exec_1
                  device: PE1
                  command: cmd
            - execute:
                  alias: exec_2
                  device: PE2
                  command: another
            - configure:
                  device: PE1
                  command: feature bgp
            - execute:
                  device: PE1
                  command: aa
    """

    condition_6 = """
          if : "%VARIABLES{nonexist}"
          actions:
            - execute:
                  alias: exec_1
                  device: PE1
                  command: cmd
            - execute:
                  alias: exec_2
                  device: PE2
                  command: another
            - configure:
                  device: PE1
                  command: feature bgp
            - execute:
                  device: PE1
                  command: aa
    """

    condition_7 = """
          if : "%VARIABLES{nonexist} == None"
          actions:
            - execute:
                  alias: exec_1
                  device: PE1
                  command: cmd
            - execute:
                  alias: exec_2
                  device: PE2
                  command: another
            - configure:
                  device: PE1
                  command: feature bgp
            - execute:
                  device: PE1
                  command: aa
    """

    condition_8 = """
        - if : "%VARIABLES{execute_id} == id1"
          actions:
            - execute:
                  alias: exec_1
                  custom_start_step_message: inside if condition
                  device: PE1
                  command: cmd

        - elif : "%VARIABLES{execute_id} == id2"
          actions:
            - configure:
                  custom_start_step_message: inside first elif condition
                  device: PE1
                  command: feature bgp

        - elif : "%VARIABLES{execute_id} == id3"
          actions:
            - configure:
                  custom_start_step_message: inside second elif condition
                  device: PE1
                  command: feature bgp

        - else :
          actions:
           - execute:
                  alias: exec_2
                  custom_start_step_message: inside else condition
                  device: PE2
                  command: another
    """

    condition_9 = """
        - if : "%VARIABLES{nonexist} == None"
          actions:
            - execute:
                  alias: exec_1
                  device: PE1
                  command: cmd
            - execute:
                  alias: exec_2
                  device: PE2
                  command: another
            - configure:
                  device: PE1
                  command: feature bgp
            - execute:
                  device: PE1
                  command: aa
    """

    condition_10 = """
        - if : "%VARIABLES{execute_id} == id1"
          actions:
            - execute:
                  alias: exec_1
                  custom_start_step_message: inside if condition
                  device: PE1
                  command: cmd
        - else :
          actions:
           - execute:
                  alias: exec_2
                  custom_start_step_message: inside else condition
                  device: PE2
                  command: another
    """

    condition_11 = """
        - elif : "%VARIABLES{execute_id} == id1"
          actions:
            - execute:
                  alias: exec_1
                  custom_start_step_message: inside if condition
                  device: PE1
                  command: cmd
        - else :
          actions:
           - execute:
                  alias: exec_2
                  custom_start_step_message: inside else condition
                  device: PE2
                  command: another
    """

    condition_12 = """
        - if : "%VARIABLES{execute_id} == id1"
          actions:
            - execute:
                  alias: exec_1
                  custom_start_step_message: inside if condition
                  device: PE1
                  command: cmd
        - if :
          actions:
           - execute:
                  alias: exec_2
                  custom_start_step_message: inside else condition
                  device: PE2
                  command: another
    """

    condition_13 = """
        - else : "%VARIABLES{execute_id} == id1"
          actions:
            - execute:
                  alias: exec_1
                  custom_start_step_message: inside if condition
                  device: PE1
                  command: cmd
        - else :
          actions:
           - execute:
                  alias: exec_2
                  custom_start_step_message: inside else condition
                  device: PE2
                  command: another
    """

    def setUp(self):

        dir_name = os.path.dirname(os.path.abspath(__file__))

        f, self.jobfile = tempfile.mkstemp()
        init_runtime(runtime)
        runtime.configuration.load()
        runtime.job = Job(jobfile=self.jobfile,
                          runtime=runtime,
                          **runtime.configuration.components.job)

        mgr = runtime.tasks
        task = mgr.Task(testscript=os.path.join(
            dir_name, 'mock_yamls/trigger_datafile.yaml'),
                        taskid='awesome')

        self.testbed = load(
            os.path.join(dir_name, 'mock_testbeds/testbed.yaml'))
        self.mock_testbed_devices()
        Blitz.parameters = ParameterMap()
        Blitz.uid = 'test.dev'
        Blitz.parameters['testbed'] = self.testbed

        self.blitz_obj = Blitz()
        self.uid = self.blitz_obj.uid
        self.blitz_obj.parent = self
        self.blitz_obj.parent.parameters = mock.Mock()

        self.dev = Device(name='PE1', os='iosxe')
        self.dev.custom = {'abstraction': {'order': ['os']}}
        self.blitz_obj.parameters['test_sections'] = [{
            'section1': [{
                'execute': {
                    'command': 'cmd',
                    'device': 'PE1'
                }
            }]
        }]
        sections = self.blitz_obj._discover()
        self.kwargs = {
            'self': self.blitz_obj,
            'testbed': self.testbed,
            'section': sections[0].__testcls__(sections[0]),
            'name': ''
        }

    def mock_testbed_devices(self):

        side_effects = {
            'configure': ['\n', 'end'],
            'execute': ['host execute output', 'oop', 'oot', 'name'],
            'parse': [self.parser_output, 'any output']
        }

        for dev in self.testbed.devices:
            for action in side_effects:
                setattr(self.testbed.devices[dev], action, mock.Mock())
                setattr(getattr(self.testbed.devices[dev], action),
                        'side_effect', side_effects[action])

    # TODO maybe change the way condition is applied
    # need discussion
    def test_condition_pass(self):
        pass

    #   steps = Steps()
    #   data = yaml.safe_load(self.condition_1)
    #   self.kwargs.update({'steps': steps, 'action_item': data})
    #   self.blitz_obj.parameters['save_variable_name'] = {}
    #   self.blitz_obj.parameters['save_variable_name']['execute_id'] = 'id1'
    #   out = control(**self.kwargs)

    def test_condition_fail(self):

        steps = Steps()
        data = yaml.safe_load(self.condition_2)
        self.kwargs.update({'steps': steps, 'action_item': data})
        self.blitz_obj.parameters['save_variable_name'] = {'execute_id': 'id1'}
        run_condition(**self.kwargs)
        self.assertEqual(steps.result, Passed)

        func1 = self.testbed.devices['PE1'].configure
        func1.assert_called_once()
        func2 = self.testbed.devices['PE1'].execute
        self.assertEqual(func2.call_count, 2)
        func3 = self.testbed.devices['PE2'].execute
        func3.assert_called_once()

    def test_condition_parallel(self):

        steps = Steps()
        data = yaml.safe_load(self.condition_3)
        self.kwargs.update({'steps': steps, 'action_item': data})
        self.blitz_obj.parameters['save_variable_name'] = {'execute_id': 'id1'}
        run_condition(**self.kwargs)
        self.assertEqual(steps.result, Passed)

    def test_condition_no_function_pass(self):

        steps = Steps()
        data = yaml.safe_load(self.condition_5)
        self.kwargs.update({'steps': steps, 'action_item': data})
        self.blitz_obj.parameters['save_variable_name'] = {'execute_id': 'id1'}
        run_condition(**self.kwargs)
        self.assertEqual(steps.result, Passed)

    def test_condition_no_function_fail(self):

        steps = Steps()
        data = yaml.safe_load(self.condition_5)
        self.kwargs.update({'steps': steps, 'action_item': data})
        self.blitz_obj.parameters['save_variable_name'] = {'execute_id': 'id9'}
        out = run_condition(**self.kwargs)
        self.assertEqual(out['substeps'], [])
        self.assertEqual(out['run_condition_skipped'], True)

    def test_condition_no_function_parallel(self):

        steps = Steps()
        data = yaml.safe_load(self.condition_4)
        self.kwargs.update({'steps': steps, 'action_item': data})
        self.blitz_obj.parameters['save_variable_name'] = {'execute_id': 'id1'}
        out = run_condition(**self.kwargs)
        self.assertNotEqual(out['substeps'], [])
        self.assertEqual(out['run_condition_skipped'], False)

    def test_condition_no_operator(self):

        steps = Steps()
        data = yaml.safe_load(self.condition_6)
        self.kwargs.update({'steps': steps, 'action_item': data})
        self.blitz_obj.parameters['save_variable_name'] = {}
        out = run_condition(**self.kwargs)
        self.assertEqual(out['substeps'], [])
        self.assertEqual(out['run_condition_skipped'], True)

    def test_condition_eq_none(self):

        steps = Steps()
        data = yaml.safe_load(self.condition_7)
        self.kwargs.update({'steps': steps, 'action_item': data})
        self.blitz_obj.parameters['save_variable_name'] = {}
        out = run_condition(**self.kwargs)
        self.assertNotEqual(out['substeps'], [])
        self.assertEqual(out['run_condition_skipped'], False)

    def test_condition_if(self):

        steps = Steps()
        data = yaml.safe_load(self.condition_8)
        self.kwargs.update({'steps': steps, 'action_item': data})
        self.blitz_obj.parameters['save_variable_name'] = {'execute_id': 'id1'}
        out = run_condition(**self.kwargs)
        self.assertEqual(steps.result, Passed)
        self.assertEqual(steps.details[0].name, 'inside if condition')

    def test_condition_elif_1(self):

        steps = Steps()
        data = yaml.safe_load(self.condition_8)
        self.kwargs.update({'steps': steps, 'action_item': data})
        self.blitz_obj.parameters['save_variable_name'] = {'execute_id': 'id2'}
        out = run_condition(**self.kwargs)
        self.assertEqual(steps.result, Passed)
        self.assertEqual(steps.details[0].name, 'inside first elif condition')

    def test_condition_elif_2(self):

        steps = Steps()
        data = yaml.safe_load(self.condition_8)
        self.kwargs.update({'steps': steps, 'action_item': data})
        self.blitz_obj.parameters['save_variable_name'] = {'execute_id': 'id3'}
        out = run_condition(**self.kwargs)
        self.assertEqual(steps.result, Passed)
        self.assertEqual(steps.details[0].name, 'inside second elif condition')

    def test_condition_else(self):

        steps = Steps()
        data = yaml.safe_load(self.condition_8)
        self.kwargs.update({'steps': steps, 'action_item': data})
        self.blitz_obj.parameters['save_variable_name'] = {'execute_id': 'id5'}
        out = run_condition(**self.kwargs)
        self.assertEqual(steps.result, Passed)
        self.assertEqual(steps.details[0].name, 'inside else condition')

    def test_condition_eq_none_2(self):

        steps = Steps()
        data = yaml.safe_load(self.condition_9)
        self.kwargs.update({'steps': steps, 'action_item': data})
        self.blitz_obj.parameters['save_variable_name'] = {}
        out = run_condition(**self.kwargs)
        self.assertNotEqual(out['substeps'], [])
        self.assertEqual(out['run_condition_skipped'], False)

    def test_condition_if_else(self):

        steps = Steps()
        data = yaml.safe_load(self.condition_10)
        self.kwargs.update({'steps': steps, 'action_item': data})
        self.blitz_obj.parameters['save_variable_name'] = {'execute_id': 'id5'}
        out = run_condition(**self.kwargs)
        self.assertEqual(steps.result, Passed)
        self.assertEqual(steps.details[0].name, 'inside else condition')

    def test_condition_mandatory_if_exception(self):
        steps = Steps()
        data = yaml.safe_load(self.condition_11)
        self.kwargs.update({'steps': steps, 'action_item': data})
        self.blitz_obj.parameters['save_variable_name'] = {'execute_id': 'id5'}
        # To check if the exception is raised when no if condition is passed
        with self.assertRaises(Exception) as err:
            out = run_condition(**self.kwargs)
        self.assertEqual(err.exception.args[0],
                         "At least one if condition should be passed")

    def test_condition_multiple_if_exception(self):

        steps = Steps()
        data = yaml.safe_load(self.condition_12)
        self.kwargs.update({'steps': steps, 'action_item': data})
        self.blitz_obj.parameters['save_variable_name'] = {'execute_id': 'id5'}
        # To check if the exception is raised when multiple if conditions are passed
        with self.assertRaises(Exception) as err:
            out = run_condition(**self.kwargs)
        self.assertEqual(err.exception.args[0], "Multple if conditions have been passed, "\
         "please provide only one if condition")

    def test_condition_multiple_else_exception(self):

        steps = Steps()
        data = yaml.safe_load(self.condition_13)
        self.kwargs.update({'steps': steps, 'action_item': data})
        self.blitz_obj.parameters['save_variable_name'] = {'execute_id': 'id5'}
        # To check if the exception is raised when multiple else conditions are passed
        with self.assertRaises(Exception) as err:
            out = run_condition(**self.kwargs)
        self.assertEqual(err.exception.args[0], "Multiple else conditions have been passed, "\
         "please provide only one else condition")
Esempio n. 10
0
class TestMaple(unittest.TestCase):

    plugin_input1 = '{"rule-1": {"type": "cli", "commands": "command:{\\n'\
                    '                    \\"method\\":\\"waitfor\\",\\n  '\
                    '                 \\"options\\":[\\n                 '\
                    '  {\\"command\\":\\"show module\\"},\\n             '\
                    '       {\\"match\\":\\"Up\\"},\\n                   '\
                    '{\\"timeout\\":\\"10\\"}\\n       ]}"}}'
  
    plugin_input2 =  '{"rule-1": {"type": "matcher", "commands": "matcher:{\\n'\
                     '    \\"package\\":\\"maple.plugins.user.MatcherPlugins\\"'\
                     ',\\n    \\"method\\":\\"populateObjects\\",\\n    '\
                     '\\"command\\":\\"show version\\",\\n    \\"type\\":\\"cli\\"\\n    }"}}'

    plugin_input3 =  '{"rule-1": {"type": "matcher", "commands": "matcher:{\\n'\
                     '    \\"package\\":\\"maple.plugins.user.MatcherPlugins\\"'\
                     ',\\n    \\"method\\":\\"populateObjects\\",\\n    '\
                     '\\"type\\":\\"cli\\"\\n    }"}}'

    plugin_input4 = '{"rule-1": {"type": "cli", "commands": "confirm:{\\n '\
                    '   \\"package\\":\\"maple.plugins.user.ConfirmPlugins\\",\\n'\
                    '    \\"method\\":\\"checkIfPresent\\",\\n    \\"options\\":[\\n'\
                    '        {\\"count\\":\\"1\\"},\\n        {\\"check1\\": \\"192.168.0.4\\"}\\n    ]}"}}'

    plugin_input5 = '{"rule-1": {"type": "cli", "commands": "command:{\\n'\
                    '                    \\"method\\":\\"ixia\\",\\n  '\
                    '                 \\"options\\":[\\n                 '\
                    '  {\\"command\\":\\"connect\\"}]}"}}'

    execute_output = ''' 
                     Mod Ports             Module-Type                       Model        Status
                    --- ----- -------------------------------------------------------------------
                    1    48   1/10G SFP+ Ethernet Module            N9K-C9396PX           active *  
                    2    12   40G Ethernet Expansion Module         N9K-M12PQ             ok        
                    Mod  Sw                       Hw    Slot
                    ---  ----------------------- ------ ----
                    1    9.3(3)IDI9(0.509)        2.2    NA  
                    2    NA                       1.2    GEM 
                    Mod  MAC-Address(es)                      Serial-Num
                    ---  --------------------------------------  ----------
                    1    84-b8-02-f0-83-90 to 84-b8-02-f0-83-c7  SAL1914CNL6
                    2    88-1d-fc-71-de-38 to 88-1d-fc-71-de-43  SAL1928K4EG
                    Mod  Online Diag Status
                    ---  ------------------
                    1    Pass
    '''

    execute_output_1 = """ 
          Legend:
          (P)=Protected, (F)=FRR active, (*)=more labels in stack.

          IPV4:
          In-Label   Out-Label  FEC name           Out-Interface      Next-Hop
          16005      16005      5.5.5.0/32         Eth1/10            2.3.1.3
          16005      16005      5.5.5.0/32         Eth1/12            2.4.1.4

          Legend:
          (P)=Protected, (F)=FRR active, (*)=more labels in stack.

          IPV4:
          In-Label   Out-Label  FEC name           Out-Interface      Next-Hop
          VRF default
          16002      16002      2.2.2.0/32         Eth1/15            3.5.1.3
          16002      16002      2.2.2.0/32         Eth1/10            4.5.1.4

          Legend:
          (P)=Protected, (F)=FRR active, (*)=more labels in stack.

          IPV4:
          In-Label   Out-Label  FEC name           Out-Interface      Next-Hop
          VRF default
          16002      16002      2.2.2.0/32         Eth1/49            3.6.1.3
          16002      16002      2.2.2.0/32         Eth1/51            4.6.1.4

          Legend:
          (P)=Protected, (F)=FRR active, (*)=more labels in stack.

          IPV4:
          In-Label   Out-Label  FEC name           Out-Interface      Next-Hop
          16006      Pop Label  6.6.6.0/32         Eth1/56            6.8.1.6

          Legend:
          (P)=Protected, (F)=FRR active, (*)=more labels in stack.

          IPV4:
          In-Label   Out-Label  FEC name           Out-Interface      Next-Hop
          16006      Pop Label  6.6.6.0/32         Eth1/8             6.7.1.6
    """ 

    def setUp(self):

        dir_name = os.path.dirname(os.path.abspath(__file__))
        
        self.testbed = load(os.path.join(dir_name, 'mock_testbeds/testbed.yaml'))
        Blitz.parameters = ParameterMap()
        Blitz.uid = 'test.dev'
        Blitz.parameters['testbed'] = self.testbed
        self.blitz_obj = Blitz()
        self.dev = Device( name='PE1', os='iosxe')
        self.dev.custom = {'abstraction': {'order': ['os']}}
        self.blitz_obj.parameters['test_sections'] = [{'section1': [{'action': {'command': 'a'}}]}]
        sections = self.blitz_obj._discover()
        self.kwargs = {'self': self.blitz_obj, 
                       'section': sections[0],
                       'name': ''}

    def test_default_package_pass(self):

      steps = Steps()
      self.kwargs.update({'steps': steps,
                          'device': self.dev,
                          'maple_plugin_input': self.plugin_input1,
                          'maple_action': 'confirm'})

      with patch('plugins.system.Commands.waitfor', 
                 return_value= {'result': [True],'matchObjs':{'a':'b', 'c':12}}) as func:

        maple(**self.kwargs)
        func.assert_called_once()
        self.assertIn('a', self.blitz_obj.parameters['save_variable_name'])
        self.assertEqual(steps.result, Passed)

    def test_default_package_fail(self):

      steps = Steps()
      self.kwargs.update({'steps': steps,
                          'device': self.dev,
                          'maple_plugin_input': self.plugin_input1,
                          'maple_action': 'confirm'})

      with patch('plugins.system.Commands.waitfor', 
                 return_value= {'result': [False],'matchObjs':{'a':'b', 'c':12}}) as func:

        maple(**self.kwargs)
        func.assert_called_once()
        self.assertIn('a', self.blitz_obj.parameters['save_variable_name'])
        self.assertEqual(steps.result, Failed)

    def test_matcher_package_with_output(self):

      steps = Steps()
      self.dev.execute = Mock(return_value='a string out')
      self.kwargs.update({'steps': steps,
                          'device': self.dev,
                          'maple_plugin_input': self.plugin_input2})

      with patch('plugins.user.MatcherPlugins.populateObjects', 
                 return_value= {'matchObjs':{'a':'b', 'c':12}}) as func:

        maple(**self.kwargs)
        func.assert_called_once()
        self.assertIn('c', self.blitz_obj.parameters['save_variable_name'])
        self.assertEqual(steps.result, Passed)


    def test_matcher_package_without_output(self):

      steps = Steps()
      self.dev.execute = Mock(side_effect=Exception)
      with steps.start("Starting action", continue_=True) as step:

        self.kwargs.update({'steps': step,
                            'device': self.dev,
                            'maple_plugin_input': self.plugin_input2})
        maple(**self.kwargs)
        self.assertEqual(step.result, Failed)

    def test_matcher_package_bad_command(self):

      steps = Steps()
      with steps.start("Starting action", continue_=True) as step:

        self.kwargs.update({'steps': step,
                            'device': self.dev,
                            'maple_plugin_input': self.plugin_input3})
        maple(**self.kwargs)
        self.assertEqual(step.result, Failed)

    def test_confirm_package(self):

      steps = Steps()
      self.kwargs.update({'steps': steps,
                          'device': self.dev,
                          'maple_plugin_input': self.plugin_input4,
                          'output': self.execute_output})

      with patch('plugins.user.ConfirmPlugins.checkIfPresent', 
                 return_value= {'result': True, 'matchObjs':{'a':'b', 'c':12}}) as func:

        maple(**self.kwargs)
        func.assert_called_once()
        self.assertEqual(steps.result, Passed)

    def test_default_package_ixia(self):

      steps = Steps()
      self.dev.type = 'ixia'
      self.kwargs.update({'steps': steps,
                          'device': self.dev,
                          'maple_plugin_input': self.plugin_input5,
                          'maple_action': 'confirm'})

      with patch('plugins.system.Commands.ixia', 
                 return_value= {'result': [True],'ixiaObjs':{'a':'b', 'c':12}}) as func:

        maple(**self.kwargs)
        func.assert_called_once()
        self.assertIn('a', self.blitz_obj.parameters['save_variable_name'])
        self.assertEqual(steps.result, Passed)

    def test_maple_search_include_pass(self):

      steps = Steps()
      self.kwargs.update({'steps': steps,
                          'search_string': self.execute_output_1,
                          'device': self.dev,
                          'include': ['^(?=.*\b16006\b)(?=.*\bPop Label\b).*$']})

      maple_search(**self.kwargs)
      self.assertEqual(steps.result, Passed)

    def test_maple_search_include_fail(self):

      steps = Steps()
      self.kwargs.update({'steps': steps,
                          'search_string': self.execute_output_1,
                          'device': self.dev,
                          'include': ['\s*\bSel-Num\b.*']})

      maple_search(**self.kwargs)
      self.assertEqual(steps.result, Failed)


    def test_maple_search_exclude_fail(self):

      steps = Steps()
      self.kwargs.update({'steps': steps,
                          'search_string': self.execute_output_1,
                          'device': self.dev,
                          'exclude': ['^(?=.*\b16006\b)(?=.*\bPop Label\b).*$']})

      maple_search(**self.kwargs)
      self.assertEqual(steps.result, Failed)

    def test_maple_search_exclude_pass(self):

      steps = Steps()
      self.kwargs.update({'steps': steps,
                          'search_string': self.execute_output_1,
                          'device': self.dev,
                          'exclude': ['\s*\bSel-Num\b.*']})

      maple_search(**self.kwargs)
      self.assertEqual(steps.result, Passed)
Esempio n. 11
0
class TestBlitz(unittest.TestCase):

    actions_dict = {'execute': 'sample output',
                    'parse': {'a':'b'},
                    'learn': {'a':'b'},
                    'api': 1500}
    yaml1 = '''
        test:
          groups: ['test']
          description: Modifying the testcase description
          source:
              pkg: genie.libs.sdk
              class: triggers.blitz.blitz.Blitz
          devices: ['PE1']
          test_sections:
              - section:
                  - description: "section description"
                  - execute:
                      save:
                        - filter: (?P<host>host).*
                          regex: True
                      device: PE1
                      command: show version
    '''
    yaml2 = '''
        test:
          groups: ['test']
          description: Modifying the testcase description
          source:
              pkg: genie.libs.sdk
              class: triggers.blitz.blitz.Blitz
          devices: ['PE1']
          test_sections:
              - section:
                  - description: "section description"
                  - parse:
                      device: PE1
                      alias: parse1
                      description: Mocked action description
                      save:
                        - variable_name: name1
                          filter: contains('hardware')
                      command: show version
    '''
    yaml3 = '''
        test:
          groups: ['test']
          description: Modifying the testcase description
          source:
              pkg: genie.libs.sdk
              class: triggers.blitz.blitz.Blitz
          devices: ['PE1']
          test_sections:
              - section1:
                  - continue: False
                  - execute:
                      device: PE1
                      command: show version
                      include:
                        - [0-9]
                  - execute:
                      device: PE1
                      command: show vrf
              - section2:
                  - description: "section description"
                  - execute:

                      device: PE1
                      command: show version
    '''
    yaml4 = '''
        test:
          groups: ['test']
          description: Modifying the testcase description
          source:
              pkg: genie.libs.sdk
              class: triggers.blitz.blitz.Blitz
          devices: ['PE1']
          test_sections:
              - section1:
                  - execute:
                      continue: False
                      device: PE1
                      command: show version
                      include:
                        - [0-9]
                  - execute:
                      device: PE1
                      command: show vrf
    '''

    yaml5 = '''
        test:
          groups: ['test']
          description: Modifying the testcase description
          source:
              pkg: genie.libs.sdk
              class: triggers.blitz.blitz.Blitz
          devices: ['PE1']
          test_sections:
              - section:
                  - execute:
                      save:
                        - variable_name: execute_output
                          regex_findall: ([a-z]+)
                      device: PE1
                      command: show version
    '''

    yaml6 = '''
            test:
              groups: ['test']
              description: Modifying the testcase description
              source:
                  pkg: genie.libs.sdk
                  class: triggers.blitz.blitz.Blitz
              devices: ['PE1']
              test_sections:
                  - section:
                      - description: "section description"
                      - execute:
                          device: PE1
                          command: show version
                          save:
                              - variable_name: execute_action_output
                                as_dict:
                                  rt_2_if2:
                                    rt_22: "%VARIABLES{action_output}"         
        '''



    bad_yaml1 = '''
        test:
          groups: ['test']
          source:
              pkg: genie.libs.sdk
              class: triggers.blitz.blitz.Blitz
          devices: ['PE1']
          test_sections:
              - section:
                  - bad_action:
                      device: PE1
                      command: show version
    '''
    bad_yaml2 = '''
        test:
          groups: ['test']
          source:
              pkg: genie.libs.sdk
              class: triggers.blitz.blitz.Blitz
          devices: ['PE1']
          test_sections:

              - section1:
                  - invalid_action

    '''

    bad_yaml3 = '''
        test:
          groups: ['test']
          source:
              pkg: genie.libs.sdk
              class: triggers.blitz.blitz.Blitz
          devices: ['PE1']
          test_sections:
                  - section2:
                    - empty_kwargs:
                  '''
    bad_yaml4 = '''
        test:
          groups: ['test']
          source:
              pkg: genie.libs.sdk
              class: triggers.blitz.blitz.Blitz
          devices: ['PE1']
          test_sections:
                  - section3:
                    - parse:
                        device: PE3
                        command: show version
    '''

    def setUp(self):

      dir_name = os.path.dirname(os.path.abspath(__file__))
      f, self.jobfile = tempfile.mkstemp()
      init_runtime(runtime)
      runtime.configuration.load()
      runtime.job = Job(jobfile = self.jobfile,
                        runtime = runtime,
                        **runtime.configuration.components.job)

      mgr = runtime.tasks
      task = mgr.Task(testscript = os.path.join(dir_name, 'mock_yamls/trigger_datafile.yaml'),
                      taskid = 'awesome')

      self._initiate_blitz_cls(self.yaml1)

    def test_init(self):

      self.assertEqual(self.blitz_cls().uid, 'test.PE1')
      self.assertEqual(self.blitz_cls().description, 'Modifying the testcase description')


    def test_dispatcher_1(self):

      blitz_discoverer = self.blitz_cls()._discover()
      for section in blitz_discoverer:

        new_section = section.__testcls__(section)
        steps = Steps()
        blitz_obj = self.blitz_cls()
        self.uid = blitz_obj.uid
        blitz_obj.parent = self
        blitz_obj.parent.parameters = mock.Mock()

        output = blitz_obj.dispatcher(steps,
                                             self.testbed,
                                             new_section,
                                             section.parameters['data'])

        self.assertEqual(output, { 'action': 'execute',
                                             'alias': None,
                                             'continue_': True,
                                             'description': '',
                                             'device': 'PE1',
                                             'saved_vars': {'host': 'host'},
                                             'filters': '(?P<host>host).*',
                                             'step_result': Passed})

        self.assertEqual(new_section.description, "section description")

    def test_dispatcher_2(self):

      self._initiate_blitz_cls(self.yaml2)
      blitz_discoverer = self.blitz_cls()._discover()

      for section in blitz_discoverer:

        new_section = section.__testcls__(section)
        steps = Steps()
        blitz_obj = self.blitz_cls()
        self.uid = blitz_obj.uid
        blitz_obj.parent = self
        blitz_obj.parent.parameters = mock.Mock()

        output = blitz_obj.dispatcher(steps,
                                      self.testbed,
                                      new_section,
                                      section.parameters['data'])

        desc = section.parameters['data'][1]['parse']['description']
        self.assertEqual(output['description'], desc)
        self.assertIn('parse1', blitz_obj.parameters['save_variable_name'])
        self.assertIn('name1', output['saved_vars'])

    # TODO might have an issue, in real script it does stop
    # probably because of dummy steps investigate
    def test_dispatcher_section_continue_false(self):
      pass
      # self._initiate_blitz_cls(self.yaml3)
      # blitz_discoverer = self.blitz_cls()._discover()
      # for section in blitz_discoverer:
      #   new_section = section.__testcls__(section)
      #   steps = Steps()
      #   blitz_obj = self.blitz_cls()
      #   new_section.result = Failed
      #   with self.assertRaises(AEtestFailedSignal):
      #       blitz_obj.dispatcher(steps,
      #                            self.testbed,
      #                            new_section,
      #                            section.parameters['data'])

    def test_bad_action(self):
      self._initiate_blitz_cls(self.bad_yaml1)
      blitz_discoverer = self.blitz_cls()._discover()
      for section in blitz_discoverer:
        new_section = section.__testcls__(section)
        steps = Steps()

        with self.assertRaises(Exception):
           self.blitz_cls().dispatcher(steps,
                                       self.testbed,
                                       new_section,
                                       section.parameters['data'])

    def test_invalid_action(self):
      self._initiate_blitz_cls(self.bad_yaml2)
      blitz_discoverer = self.blitz_cls()._discover()
      for section in blitz_discoverer:
        new_section = section.__testcls__(section)
        steps = Steps()

        with self.assertRaises(Exception):
           self.blitz_cls().dispatcher(steps,
                                       self.testbed,
                                       new_section,
                                       section.parameters['data'])

    def test_save_findall(self):
      self._initiate_blitz_cls(self.yaml5)
      blitz_discoverer = self.blitz_cls()._discover()
      for section in blitz_discoverer:

        new_section = section.__testcls__(section)
        steps = Steps()
        blitz_obj = self.blitz_cls()
        self.uid = blitz_obj.uid
        blitz_obj.parent = self
        blitz_obj.parent.parameters = mock.Mock()

        output = blitz_obj.dispatcher(steps,
                                      self.testbed,
                                      new_section,
                                      section.parameters['data'])

        self.assertEqual(output, {
                          'action': 'execute',
                          'device': 'PE1',
                          'alias': None,
                          'continue_': True,
                          'description': '',
                          'saved_vars': {
                            'execute_output': [
                              'host', 'execute', 'output'
                            ]
                          },
                          'step_result': Passed
                        })

    def test_save_regex_var(self):
      self._initiate_blitz_cls(self.yaml1)
      blitz_discoverer = self.blitz_cls()._discover()
      for section in blitz_discoverer:

        new_section = section.__testcls__(section)
        steps = Steps()
        blitz_obj = self.blitz_cls()
        self.uid = blitz_obj.uid
        blitz_obj.parent = self
        blitz_obj.parent.parameters = mock.Mock()

        output = blitz_obj.dispatcher(steps,
                                      self.testbed,
                                      new_section,
                                      section.parameters['data'])

        self.assertEqual(output['saved_vars'], {'host': 'host'})
        self.assertEqual(output['filters'], '(?P<host>host).*')

    def test_invalid_device(self):
      self._initiate_blitz_cls(self.bad_yaml4)
      blitz_discoverer = self.blitz_cls()._discover()
      for section in blitz_discoverer:
        new_section = section.__testcls__(section)
        steps = Steps()

        with self.assertRaises(Exception):
           self.blitz_cls().dispatcher(steps,
                                       self.testbed,
                                       new_section,
                                       section.parameters['data'])

    def _initiate_blitz_cls(self, yaml_file):

      dir_name = os.path.dirname(os.path.abspath(__file__))
      self.blitz_cls = Blitz
      self.testbed = load(os.path.join(dir_name, 'mock_testbeds/testbed.yaml'))

      self.blitz_cls.parameters = ParameterMap()
      self.blitz_cls.parameters['testbed'] = self.testbed
      self._mock_testbed_devs()
      self.datafile = yaml.safe_load(yaml_file)

      for key, value in self.datafile.items():
        self.blitz_cls.uid = "{}.{}".format(key, value['devices'][0])
        self.blitz_cls.parameters['test_sections'] = value['test_sections']
        if value.get('description'):
          self.blitz_cls.description = value['description']

    def _mock_testbed_devs(self):

      side_effects = {'configure': ['\n'],
                      'execute': ['host execute output', 'oop', 'oot', 'name'],
                      'parse': [{'a': '1', 'hardware': 'hardware_name'}]}

      actions = ['configure', 'execute', 'parse']
      for dev in self.testbed.devices:
        for action in actions:
            setattr(self.testbed.devices[dev], action, mock.Mock())
            setattr(getattr(self.testbed.devices[dev], action), 'side_effect', side_effects[action])

    def test_custom_start_step_messsage_with_variable(self):
        #saved variable
        Blitz.parameters['save_variable_name'] = {'command': 'sh version'}
        self.blitz_obj = Blitz()
        self.blitz_obj.parameters['test_sections'] = [{'section1': [{'action': {'command': 'a'}}]}]
        sections = self.blitz_obj._discover()
        self.section = sections[0].__testcls__(sections[0])

        self.kwargs = {
            'self': self.blitz_obj,
            'section': self.section,
            'custom_start_step_message': 'test command: %VARIABLES{command}'
        }

        #To get the saved variable
        replaced_kwargs = get_variable(**self.kwargs)
        self.assertEqual(replaced_kwargs['custom_start_step_message'], 'test command: sh version')

    def test_save_as_dict(self):
        self._initiate_blitz_cls(self.yaml6)
        blitz_discoverer = self.blitz_cls()._discover()
        for section in blitz_discoverer:
            new_section = section.__testcls__(section)
            steps = Steps()
            blitz_obj = self.blitz_cls()
            self.uid = blitz_obj.uid
            blitz_obj.parent = self
            blitz_obj.parent.parameters = mock.Mock()

            output = blitz_obj.dispatcher(steps,
                                          self.testbed,
                                          new_section,
                                          section.parameters['data'])
            self.assertEqual(output['saved_vars']['execute_action_output'], {'rt_2_if2': {'rt_22': 'host execute output'}})
Esempio n. 12
0
class TestLoop(unittest.TestCase):

    parser_output = {
        'platform': {
            'name': 'Nexus',
            'os': 'NX-OS',
            'software': {
                'bios_version': '07.33',
                'system_version': '9.3(3) [build 9.3(3)IDI9(0.509)]',
                'bios_compile_time': '08/04/2015',
                'system_image_file':
                'bootflash:///system-image-N93_3-00613722415136',
                'system_compile_time':
                '10/22/2019 10:00:00 [10/22/2019 16:57:31]'
            },
            'hardware': {
                'model': 'Nexus9000 C9396PX',
                'chassis': 'Nexus9000 C9396PX',
                'slots': 'None',
                'rp': 'None',
                'cpu': 'Intel(R) Core(TM) i3- CPU @ 2.50GHz',
                'memory': '16399900 kB',
                'processor_board_id': 'SAL1914CNL6',
                'device_name': 'N93_3',
                'bootflash': '51496280 kB'
            },
            'kernel_uptime': {
                'days': 61,
                'hours': 22,
                'minutes': 8,
                'seconds': 40
            },
            'reason': 'Reset Requested by CLI command reload',
            'system_version': '9.3(3)'
        }
    }

    execute_output = """
        2020-11-24 12:25:43,769: %UNICON-INFO: +++ N93_3: executing command 'show version' +++
        show version
        Cisco Nexus Operating System (NX-OS) Software
        TAC support: http://www.cisco.com/tac
        Copyright (C) 2002-2019, Cisco and/or its affiliates.
        All rights reserved.
        The copyrights to certain works contained in this software are
        owned by other third parties and used and distributed under their own
        licenses, such as open source.  This software is provided "as is," and unless
        otherwise stated, there is no warranty, express or implied, including but not
        limited to warranties of merchantability and fitness for a particular purpose.
        Certain components of this software are licensed under
        the GNU General Public License (GPL) version 2.0 or
        GNU General Public License (GPL) version 3.0  or the GNU
        Lesser General Public License (LGPL) Version 2.1 or
        Lesser General Public License (LGPL) Version 2.0.
        A copy of each such license is available at
        http://www.opensource.org/licenses/gpl-2.0.php and
        http://opensource.org/licenses/gpl-3.0.html and
        http://www.opensource.org/licenses/lgpl-2.1.php and
        http://www.gnu.org/licenses/old-licenses/library.txt.
        Software
          BIOS: version 07.33
         NXOS: version 9.3(3) [build 9.3(3)IDI9(0.509)]
          BIOS compile time:  08/04/2015
          NXOS image file is: bootflash:///system-image-N93_3-00613722415136
          NXOS compile time:  10/22/2019 10:00:00 [10/22/2019 16:57:31]
        Hardware
          cisco Nexus9000 C9396PX Chassis
          Intel(R) Core(TM) i3- CPU @ 2.50GHz with 16399900 kB of memory.
          Processor Board ID SAL1914CNL6
          Device name: N93_3
          bootflash:   51496280 kB
        Kernel uptime is 61 day(s), 22 hour(s), 33 minute(s), 56 second(s)
        Last reset at 930930 usecs after Wed Sep 23 13:59:45 2020
          Reason: Reset Requested by CLI command reload
          System version: 9.3(3)
          Service:
        plugin
          Core Plugin, Ethernet Plugin
        Active Package(s):
    """

    loop_with_val = """
            loop_variable_name: var_name
            value: ['show version', 'show vrf']
            actions:
              - execute:
                  alias: execute_id
                  command: "%VARIABLES{var_name}"
                  device: PE1
                  exclude:
                      - extreme
                  include:
                      - host
              - parse:
                  command: "%VARIABLES{var_name}"
                  device: PE1
            """
    loop_over_device = """
            loop_variable_name: dev_name
            value: ['PE1', 'PE2']
            actions:
              - configure:
                  command: feature bgp
                  device: "%VARIABLES{dev_name}"
            """

    loop_with_until = """
            until: "'%VARIABLES{nbc}' == '07.33'"
            maxtime: 5
            actions:
              - parse:
                  command: "show version"
                  save:
                    - variable_name: nbc
                      filter: get_values('bios_version', 0)
                  device: PE1
        """

    loop_with_do_until_1 = """
            do_until: "'%VARIABLES{nbc}' == '07.33'"
            max_time: 5
            actions:
              - parse:
                  command: "show version"
                  save:
                    - variable_name: nbc
                      filter: get_values('bios_version', 0)
                  device: PE1
        """

    loop_with_do_until_2 = """
            do_until: "'%VARIABLES{nbc}' == '06.33'"
            max_time: 2
            actions:
              - parse:
                  command: "show version"
                  save:
                    - variable_name: nbc
                      filter: get_values('bios_version', 0)
                  device: PE1
        """

    loop_with_dict_val = """
            loop_variable_name: var_name
            value: {'PE1':'show version', 'PE2': 'show version'}
            actions:
              - execute:
                  alias: execute_id
                  command: "%VARIABLES{var_name._values}"
                  device: "%VARIABLES{var_name._keys}"
                  exclude:
                      - extreme
                  include:
                      - host
            """
    loop_until = """
            loop_variable_name: var_name
            value: ['cmd', 'amd', 'show vrf']
            loop_until: passed
            actions:
              - execute:
                  command: "%VARIABLES{var_name}"
                  device: PE1
            """

    loop_parallel = """
            loop_variable_name: dev_name
            value: ['PE1', 'PE2']
            parallel: True
            actions:
              - execute:
                  command: show version
                  device: "%VARIABLES{dev_name}"
            """
    loop_parallel_error = """
            loop_variable_name: dev_name
            value: ['PE', 'PE2']
            parallel: True
            actions:
              - execute:
                  command: show version
          """

    loop_nested = """
          range: 2
          loop_variable_name: nest_loop
          actions:
              - parse:
                  device: PE2
                  command: show version
              - loop:
                  loop_variable_name: var_name
                  value: ['show vrf', 'show version']
                  actions:
                      - execute:
                            device: PE1
                            command: "%VARIABLES{var_name}"
    """

    loop_range = """
            range: 1,5
            loop_variable_name: range
            actions:
                - execute:
                    device: PE1
                    command: show version
                - print:
                    item:
                      value: "%VARIABLES{range}"
    """

    def setUp(self):

        dir_name = os.path.dirname(os.path.abspath(__file__))

        f, self.jobfile = tempfile.mkstemp()
        init_runtime(runtime)
        runtime.configuration.load()
        runtime.job = Job(jobfile=self.jobfile,
                          runtime=runtime,
                          **runtime.configuration.components.job)

        mgr = runtime.tasks
        task = mgr.Task(testscript=os.path.join(
            dir_name, 'mock_yamls/trigger_datafile.yaml'),
                        taskid='awesome')

        self.testbed = load(
            os.path.join(dir_name, 'mock_testbeds/testbed.yaml'))
        self.mock_testbed_devices()
        Blitz.parameters = ParameterMap()
        Blitz.uid = 'test.dev'
        Blitz.parameters['testbed'] = self.testbed

        self.blitz_obj = Blitz()
        self.uid = self.blitz_obj.uid
        self.blitz_obj.parent = self
        self.blitz_obj.parent.parameters = mock.Mock()

        self.dev = Device(name='PE1', os='iosxe')
        self.dev.custom = {'abstraction': {'order': ['os']}}
        self.blitz_obj.parameters['test_sections'] = [{
            'section1': [{
                'execute': {
                    'command': 'cmd',
                    'device': 'PE1'
                }
            }]
        }]
        sections = self.blitz_obj._discover()
        self.kwargs = {
            'self': self.blitz_obj,
            'testbed': self.testbed,
            'section': sections[0].__testcls__(sections[0]),
            'name': ''
        }

    def mock_testbed_devices(self):

        side_effects = {
            'configure': ['\n', 'end'],
            'execute': ['host execute output', 'oop', 'oot', 'name'],
            'parse': [self.parser_output, 'any output']
        }

        for dev in self.testbed.devices:
            for action in side_effects.keys():
                setattr(self.testbed.devices[dev], action, mock.Mock())
                setattr(getattr(self.testbed.devices[dev], action),
                        'side_effect', side_effects[action])

    def test_loop_init(self):

        steps = Steps()
        data = yaml.safe_load(self.loop_with_val)
        self.kwargs.update({'steps': steps, 'action_item': data})
        out = loop(**self.kwargs)
        expected = {
            "action":
            "loop",
            "step_result":
            Failed,
            "substeps": [{
                "device": "PE1",
                "continue_": True,
                "action": "execute",
                "description": "",
                "step_result": Passed,
                "alias": "execute_id",
                "saved_vars": {
                    "execute_id": "passed"
                }
            }, {
                "device": "PE1",
                "continue_": True,
                "action": "parse",
                "description": "",
                "step_result": Passed,
                "alias": None,
                "saved_vars": {}
            }, {
                "device": "PE1",
                "continue_": True,
                "action": "execute",
                "description": "",
                "step_result": Failed,
                "alias": "execute_id",
                "saved_vars": {
                    "execute_id": "failed"
                }
            }, {
                "device": "PE1",
                "continue_": True,
                "action": "parse",
                "description": "",
                "step_result": Passed,
                "alias": None,
                "saved_vars": {}
            }],
            "advanced_action":
            True,
            "loop_until":
            None
        }

        self.assertEqual(out, expected)
        self.assertEqual(steps.result, Failed)
        self.assertEqual(steps.details[2].result, Passed)

    def test_loop_over_device(self):

        steps = Steps()
        data = yaml.safe_load(self.loop_over_device)
        self.kwargs.update({'steps': steps, 'action_item': data})
        out = loop(**self.kwargs)
        expected = {
            "action":
            "loop",
            "step_result":
            Passed,
            "substeps": [{
                "device": "PE1",
                "continue_": True,
                "action": "configure",
                "description": "",
                "step_result": Passed,
                "alias": None,
                "saved_vars": {}
            }, {
                "device": "PE2",
                "continue_": True,
                "action": "configure",
                "description": "",
                "step_result": Passed,
                "alias": None,
                "saved_vars": {}
            }],
            "advanced_action":
            True,
            "loop_until":
            None
        }

        self.assertEqual(out, expected)
        self.assertEqual(steps.result, out['step_result'])

    def test_until_condition_false(self):

        steps = Steps()
        data = yaml.safe_load(self.loop_with_until)
        self.blitz_obj.parameters.setdefault('save_variable_name', {})
        self.blitz_obj.parameters['save_variable_name']['nbc'] = '06.33'
        self.kwargs.update({'steps': steps, 'action_item': data})
        out = loop(**self.kwargs)
        expected = [{
            'device': 'PE1',
            'continue_': True,
            'action': 'parse',
            'description': '',
            'step_result': Passed,
            'alias': None,
            'saved_vars': {
                'nbc': '07.33'
            },
            'filters': "get_values('bios_version', 0)"
        }]

        func = self.testbed.devices['PE1'].parse
        func.assert_called_once()
        self.assertEqual(out['substeps'], expected)

    def test_until_condition_true(self):

        steps = Steps()
        data = yaml.safe_load(self.loop_with_until)
        self.blitz_obj.parameters.setdefault('save_variable_name', {})
        self.blitz_obj.parameters['save_variable_name']['nbc'] = '07.33'
        self.kwargs.update({
            'self': self.blitz_obj,
            'steps': steps,
            'action_item': data
        })

        out = loop(**self.kwargs)

        func = self.testbed.devices['PE1'].parse
        func.assert_not_called()
        self.assertEqual(out['substeps'], [])

    def test_do_until_condition_true(self):

        steps = Steps()
        data = yaml.safe_load(self.loop_with_do_until_1)
        self.blitz_obj.parameters.setdefault('save_variable_name', {})
        self.blitz_obj.parameters['save_variable_name']['nbc'] = '07.33'
        self.kwargs.update({
            'self': self.blitz_obj,
            'steps': steps,
            'action_item': data
        })

        out = loop(**self.kwargs)
        expected = {
            "action":
            "loop",
            "step_result":
            Passed,
            "substeps": [{
                "device": "PE1",
                "continue_": True,
                "action": "parse",
                "description": "",
                "step_result": Passed,
                "alias": None,
                "saved_vars": {
                    "nbc": "07.33"
                },
                "filters": "get_values('bios_version', 0)"
            }],
            "advanced_action":
            True,
            "loop_until":
            None
        }

        func = self.testbed.devices['PE1'].parse
        func.assert_called_once()
        self.assertEqual(out, expected)

    # def test_do_until_condition_false(self):

    #   steps = Steps()
    #   data = yaml.safe_load(self.loop_with_do_until_2)
    #   self.blitz_obj.parameters.setdefault('save_variable_name', {})
    #   self.blitz_obj.parameters['save_variable_name']['nbc'] = '07.33'
    #   self.kwargs.update({'self': self.blitz_obj,
    #                       'steps': steps,
    #                       'action_item': data})

    #   out = loop(**self.kwargs)
    #   # TODO - The saved_vars on the second action should be like below,
    #   # But it saves nbc: any_output Investigate
    #   expected = {
    #      "substeps":[
    #         {
    #            "device":"PE1",
    #            "continue_":True,
    #            "action":"parse",
    #            "description":"",
    #            "step_result":Passed,
    #            "alias":None,
    #            "saved_vars":{
    #               "nbc":"07.33"
    #            },
    #            "filters":"get_values('bios_version', 0)"
    #         },
    #         {
    #            "device":"PE1",
    #            "continue_":True,
    #            "action":"parse",
    #            "description":"",
    #            "step_result":Passed,
    #            "alias":None,
    #            "saved_vars":{},
    #            "filters":"get_values('bios_version', 0)"
    #         }
    #      ]
    #   }

    #   self.assertEqual(out, expected)

    def test_loop_with_dict_val(self):

        steps = Steps()
        data = yaml.safe_load(self.loop_with_dict_val)
        self.kwargs.update({'steps': steps, 'action_item': data})
        out = loop(**self.kwargs)
        self.assertEqual(len(out['substeps']), 2)
        self.assertEqual(out['substeps'][0]['device'], 'PE1')
        self.assertEqual(out['substeps'][1]['device'], 'PE2')

    def test_loop_everyseconds(self):

        steps = Steps()
        data = yaml.safe_load(self.loop_with_dict_val)
        self.kwargs.update({'steps': steps, 'action_item': data})

        out = loop(**self.kwargs)
        self.assertEqual(len(out['substeps']), 2)
        self.assertEqual(out['substeps'][0]['device'], 'PE1')
        self.assertEqual(out['substeps'][1]['device'], 'PE2')

    def test_loop_with_loop_until(self):

        self.testbed.devices['PE1'].side_effect = [Exception, Exception, 'oop']
        steps = Steps()
        data = yaml.safe_load(self.loop_until)
        self.kwargs.update({'steps': steps, 'action_item': data})
        out = loop(**self.kwargs)
        self.assertEqual(out['substeps'], [])
        self.assertEqual(steps.result, Passed)

    def test_loop_with_parallel(self):

        steps = Steps()
        data = yaml.safe_load(self.loop_parallel)
        self.kwargs.update({'steps': steps, 'action_item': data})
        out = loop(**self.kwargs)
        self.assertEqual(steps.result, Passed)

    def test_loop_with_parallel_errored(self):

        steps = Steps()
        data = yaml.safe_load(self.loop_parallel_error)
        self.kwargs.update({'steps': steps, 'action_item': data})
        out = loop(**self.kwargs)
        self.assertEqual(steps.result, Errored)

    def test_nested_loop(self):

        steps = Steps()
        data = yaml.safe_load(self.loop_nested)
        self.kwargs.update({'steps': steps, 'action_item': data})
        out = loop(**self.kwargs)
        self.assertEqual(steps.result, Passed)

    def test_loop_range(self):

        steps = Steps()
        data = yaml.safe_load(self.loop_range)
        self.kwargs.update({'steps': steps, 'action_item': data})
        out = loop(**self.kwargs)
        self.assertEqual(steps.result, Passed)