Multi-vendor Modular Layer 2 (ML2) driver.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_juniper.py 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. # Copyright (c) 2018 StackHPC Ltd.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  4. # not use this file except in compliance with the License. You may obtain
  5. # a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. # License for the specific language governing permissions and limitations
  13. # under the License.
  14. import mock
  15. import netmiko
  16. import tenacity
  17. from networking_generic_switch.devices import netmiko_devices
  18. from networking_generic_switch.devices.netmiko_devices import juniper
  19. from networking_generic_switch import exceptions as exc
  20. from networking_generic_switch.tests.unit.netmiko import test_netmiko_base
  21. class TestNetmikoJuniper(test_netmiko_base.NetmikoSwitchTestBase):
  22. def _make_switch_device(self, extra_cfg={}):
  23. device_cfg = {'device_type': 'netmiko_juniper'}
  24. device_cfg.update(extra_cfg)
  25. return juniper.Juniper(device_cfg)
  26. def test_constants(self):
  27. self.assertIsNone(self.switch.SAVE_CONFIGURATION)
  28. @mock.patch('networking_generic_switch.devices.netmiko_devices.'
  29. 'NetmikoSwitch.send_commands_to_device')
  30. def test_add_network(self, m_exec):
  31. self.switch.add_network(33, '0ae071f5-5be9-43e4-80ea-e41fefe85b21')
  32. m_exec.assert_called_with(
  33. ['set vlans 0ae071f55be943e480eae41fefe85b21 vlan-id 33'])
  34. @mock.patch('networking_generic_switch.devices.netmiko_devices.'
  35. 'NetmikoSwitch.send_commands_to_device')
  36. def test_add_network_with_trunk_ports(self, mock_exec):
  37. switch = self._make_switch_device({'ngs_trunk_ports': 'port1,port2'})
  38. switch.add_network(33, '0ae071f5-5be9-43e4-80ea-e41fefe85b21')
  39. mock_exec.assert_called_with(
  40. ['set vlans 0ae071f55be943e480eae41fefe85b21 vlan-id 33',
  41. 'set interface port1 unit 0 family ethernet-switching '
  42. 'vlan members 33',
  43. 'set interface port2 unit 0 family ethernet-switching '
  44. 'vlan members 33'])
  45. @mock.patch('networking_generic_switch.devices.netmiko_devices.'
  46. 'NetmikoSwitch.send_commands_to_device')
  47. def test_del_network(self, mock_exec):
  48. self.switch.del_network(33, '0ae071f55be943e480eae41fefe85b21')
  49. mock_exec.assert_called_with(
  50. ['delete vlans 0ae071f55be943e480eae41fefe85b21'])
  51. @mock.patch('networking_generic_switch.devices.netmiko_devices.'
  52. 'NetmikoSwitch.send_commands_to_device')
  53. def test_del_network_with_trunk_ports(self, mock_exec):
  54. switch = self._make_switch_device({'ngs_trunk_ports': 'port1,port2'})
  55. switch.del_network(33, '0ae071f55be943e480eae41fefe85b21')
  56. mock_exec.assert_called_with(
  57. ['delete interface port1 unit 0 family ethernet-switching '
  58. 'vlan members 33',
  59. 'delete interface port2 unit 0 family ethernet-switching '
  60. 'vlan members 33',
  61. 'delete vlans 0ae071f55be943e480eae41fefe85b21'])
  62. @mock.patch('networking_generic_switch.devices.netmiko_devices.'
  63. 'NetmikoSwitch.send_commands_to_device')
  64. def test_plug_port_to_network(self, mock_exec):
  65. self.switch.plug_port_to_network(3333, 33)
  66. mock_exec.assert_called_with(
  67. ['delete interface 3333 unit 0 family ethernet-switching '
  68. 'vlan members',
  69. 'set interface 3333 unit 0 family ethernet-switching '
  70. 'vlan members 33'])
  71. @mock.patch('networking_generic_switch.devices.netmiko_devices.'
  72. 'NetmikoSwitch.send_commands_to_device')
  73. def test_delete_port(self, mock_exec):
  74. self.switch.delete_port(3333, 33)
  75. mock_exec.assert_called_with(
  76. ['delete interface 3333 unit 0 family ethernet-switching '
  77. 'vlan members'])
  78. def test_send_config_set(self):
  79. connect_mock = mock.MagicMock(netmiko.base_connection.BaseConnection)
  80. connect_mock.send_config_set.return_value = 'fake output'
  81. result = self.switch.send_config_set(connect_mock, ['spam ham aaaa'])
  82. self.assertFalse(connect_mock.enable.called)
  83. connect_mock.send_config_set.assert_called_once_with(
  84. config_commands=['spam ham aaaa'], exit_config_mode=False)
  85. self.assertEqual('fake output', result)
  86. def test_save_configuration(self):
  87. mock_connection = mock.Mock()
  88. self.switch.save_configuration(mock_connection)
  89. mock_connection.commit.assert_called_once_with()
  90. @mock.patch.object(netmiko_devices.tenacity, 'wait_fixed',
  91. return_value=tenacity.wait_fixed(0.01))
  92. @mock.patch.object(netmiko_devices.tenacity, 'stop_after_delay',
  93. return_value=tenacity.stop_after_delay(0.1))
  94. def test_save_configuration_timeout(self, m_stop, m_wait):
  95. mock_connection = mock.Mock()
  96. output = """
  97. error: configuration database locked by:
  98. user terminal p0 (pid 1234) on since 2017-1-1 00:00:00 UTC
  99. exclusive private [edit]
  100. {master:0}[edit]"""
  101. mock_connection.commit.side_effect = ValueError(
  102. "Commit failed with the following errors:\n\n{0}".format(output))
  103. self.assertRaisesRegexp(exc.GenericSwitchNetmikoConfigError,
  104. "Reached timeout waiting for",
  105. self.switch.save_configuration,
  106. mock_connection)
  107. self.assertGreater(mock_connection.commit.call_count, 1)
  108. m_stop.assert_called_once_with(60)
  109. m_wait.assert_called_once_with(5)
  110. def test_save_configuration_error(self):
  111. mock_connection = mock.Mock()
  112. output = """
  113. [edit vlans]
  114. 'duplicate-vlan'
  115. l2ald: Duplicate vlan-id exists for vlan duplicate-vlan
  116. [edit vlans]
  117. Failed to parse vlan hierarchy completely
  118. error: configuration check-out failed
  119. {master:0}[edit]"""
  120. mock_connection.commit.side_effect = ValueError(
  121. "Commit failed with the following errors:\n\n{0}".format(output))
  122. self.assertRaisesRegexp(exc.GenericSwitchNetmikoConfigError,
  123. "Failed to commit configuration",
  124. self.switch.save_configuration,
  125. mock_connection)
  126. mock_connection.commit.assert_called_once_with()
  127. @mock.patch.object(netmiko_devices.tenacity, 'wait_fixed',
  128. return_value=tenacity.wait_fixed(0.01))
  129. @mock.patch.object(netmiko_devices.tenacity, 'stop_after_delay',
  130. return_value=tenacity.stop_after_delay(0.1))
  131. def test_save_configuration_non_default_timing(self, m_stop, m_wait):
  132. self.switch = self._make_switch_device({'ngs_commit_timeout': 42,
  133. 'ngs_commit_interval': 43})
  134. mock_connection = mock.MagicMock(
  135. netmiko.base_connection.BaseConnection)
  136. self.switch.save_configuration(mock_connection)
  137. mock_connection.commit.assert_called_once_with()
  138. m_stop.assert_called_once_with(42)
  139. m_wait.assert_called_once_with(43)
  140. def test__format_commands(self):
  141. cmd_set = self.switch._format_commands(
  142. juniper.Juniper.ADD_NETWORK,
  143. segmentation_id=22,
  144. network_id=22)
  145. self.assertEqual(cmd_set, ['set vlans 22 vlan-id 22'])
  146. cmd_set = self.switch._format_commands(
  147. juniper.Juniper.DELETE_NETWORK,
  148. segmentation_id=22,
  149. network_id=22)
  150. self.assertEqual(cmd_set, ['delete vlans 22'])
  151. cmd_set = self.switch._format_commands(
  152. juniper.Juniper.PLUG_PORT_TO_NETWORK,
  153. port=3333,
  154. segmentation_id=33)
  155. self.assertEqual(cmd_set,
  156. ['delete interface 3333 unit 0 '
  157. 'family ethernet-switching '
  158. 'vlan members',
  159. 'set interface 3333 unit 0 '
  160. 'family ethernet-switching '
  161. 'vlan members 33'])
  162. cmd_set = self.switch._format_commands(
  163. juniper.Juniper.DELETE_PORT,
  164. port=3333,
  165. segmentation_id=33)
  166. self.assertEqual(cmd_set,
  167. ['delete interface 3333 unit 0 '
  168. 'family ethernet-switching '
  169. 'vlan members'])
  170. cmd_set = self.switch._format_commands(
  171. juniper.Juniper.ADD_NETWORK_TO_TRUNK,
  172. port=3333,
  173. segmentation_id=33)
  174. self.assertEqual(cmd_set,
  175. ['set interface 3333 unit 0 '
  176. 'family ethernet-switching '
  177. 'vlan members 33'])
  178. cmd_set = self.switch._format_commands(
  179. juniper.Juniper.REMOVE_NETWORK_FROM_TRUNK,
  180. port=3333,
  181. segmentation_id=33)
  182. self.assertEqual(cmd_set,
  183. ['delete interface 3333 unit 0 '
  184. 'family ethernet-switching '
  185. 'vlan members 33'])