cisco_node_utils 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/CHANGELOG.md +126 -1
  4. data/README.md +19 -12
  5. data/Rakefile +1 -0
  6. data/bin/git/hooks/commit-msg/enforce_style +8 -0
  7. data/cisco_node_utils.gemspec +4 -3
  8. data/docs/README-develop-best-practices.md +127 -109
  9. data/docs/README-develop-node-utils-APIs.md +47 -39
  10. data/docs/template-router.rb +3 -7
  11. data/lib/.rubocop.yml +4 -4
  12. data/lib/cisco_node_utils.rb +1 -1
  13. data/lib/cisco_node_utils/aaa_authentication_login.rb +96 -0
  14. data/lib/cisco_node_utils/aaa_authentication_login_service.rb +133 -0
  15. data/lib/cisco_node_utils/aaa_authorization_service.rb +150 -0
  16. data/lib/cisco_node_utils/ace.rb +196 -0
  17. data/lib/cisco_node_utils/acl.rb +100 -0
  18. data/lib/cisco_node_utils/bgp.rb +301 -163
  19. data/lib/cisco_node_utils/bgp_af.rb +187 -19
  20. data/lib/cisco_node_utils/bgp_neighbor.rb +18 -33
  21. data/lib/cisco_node_utils/bgp_neighbor_af.rb +25 -48
  22. data/lib/cisco_node_utils/cisco_cmn_utils.rb +23 -4
  23. data/lib/cisco_node_utils/cmd_ref/README_YAML.md +593 -0
  24. data/lib/cisco_node_utils/cmd_ref/aaa_auth_login_service.yaml +22 -0
  25. data/lib/cisco_node_utils/cmd_ref/aaa_authentication_login.yaml +31 -0
  26. data/lib/cisco_node_utils/cmd_ref/aaa_authorization_service.yaml +22 -0
  27. data/lib/cisco_node_utils/cmd_ref/acl.yaml +43 -0
  28. data/lib/cisco_node_utils/cmd_ref/bgp.yaml +242 -0
  29. data/lib/cisco_node_utils/cmd_ref/bgp_af.yaml +164 -0
  30. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +131 -0
  31. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor_af.yaml +179 -0
  32. data/lib/cisco_node_utils/cmd_ref/dnsclient.yaml +34 -0
  33. data/lib/cisco_node_utils/cmd_ref/evpn_vni.yaml +42 -0
  34. data/lib/cisco_node_utils/cmd_ref/fabricpath.yaml +172 -0
  35. data/lib/cisco_node_utils/cmd_ref/fabricpath_topology.yaml +35 -0
  36. data/lib/cisco_node_utils/cmd_ref/feature.yaml +42 -0
  37. data/lib/cisco_node_utils/cmd_ref/fex.yaml +9 -0
  38. data/lib/cisco_node_utils/cmd_ref/images.yaml +7 -0
  39. data/lib/cisco_node_utils/cmd_ref/interface.yaml +339 -0
  40. data/lib/cisco_node_utils/cmd_ref/interface_channel_group.yaml +28 -0
  41. data/lib/cisco_node_utils/cmd_ref/interface_ospf.yaml +61 -0
  42. data/lib/cisco_node_utils/cmd_ref/interface_portchannel.yaml +54 -0
  43. data/lib/cisco_node_utils/cmd_ref/interface_service_vni.yaml +32 -0
  44. data/lib/cisco_node_utils/cmd_ref/inventory.yaml +45 -0
  45. data/lib/cisco_node_utils/cmd_ref/memory.yaml +13 -0
  46. data/lib/cisco_node_utils/cmd_ref/ntp_config.yaml +7 -0
  47. data/lib/cisco_node_utils/cmd_ref/ntp_server.yaml +14 -0
  48. data/lib/cisco_node_utils/cmd_ref/ospf.yaml +74 -0
  49. data/lib/cisco_node_utils/cmd_ref/overlay_global.yaml +33 -0
  50. data/lib/cisco_node_utils/cmd_ref/pim.yaml +40 -0
  51. data/lib/cisco_node_utils/cmd_ref/portchannel_global.yaml +69 -0
  52. data/lib/cisco_node_utils/cmd_ref/radius_global.yaml +25 -0
  53. data/lib/cisco_node_utils/cmd_ref/radius_server.yaml +64 -0
  54. data/lib/cisco_node_utils/cmd_ref/radius_server_group.yaml +14 -0
  55. data/lib/cisco_node_utils/cmd_ref/show_system.yaml +5 -0
  56. data/lib/cisco_node_utils/cmd_ref/show_version.yaml +72 -0
  57. data/lib/cisco_node_utils/cmd_ref/snmp_community.yaml +23 -0
  58. data/lib/cisco_node_utils/cmd_ref/snmp_group.yaml +7 -0
  59. data/lib/cisco_node_utils/cmd_ref/snmp_notification_receiver.yaml +50 -0
  60. data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +51 -0
  61. data/lib/cisco_node_utils/cmd_ref/snmp_user.yaml +55 -0
  62. data/lib/cisco_node_utils/cmd_ref/snmpnotification.yaml +11 -0
  63. data/lib/cisco_node_utils/cmd_ref/syslog_server.yaml +18 -0
  64. data/lib/cisco_node_utils/cmd_ref/syslog_settings.yaml +7 -0
  65. data/lib/cisco_node_utils/cmd_ref/system.yaml +6 -0
  66. data/lib/cisco_node_utils/cmd_ref/tacacs_server.yaml +49 -0
  67. data/lib/cisco_node_utils/cmd_ref/tacacs_server_group.yaml +33 -0
  68. data/lib/cisco_node_utils/cmd_ref/tacacs_server_host.yaml +35 -0
  69. data/lib/cisco_node_utils/cmd_ref/vdc.yaml +38 -0
  70. data/lib/cisco_node_utils/cmd_ref/virtual_service.yaml +6 -0
  71. data/lib/cisco_node_utils/cmd_ref/vlan.yaml +56 -0
  72. data/lib/cisco_node_utils/cmd_ref/vni.yaml +76 -0
  73. data/lib/cisco_node_utils/cmd_ref/vpc.yaml +197 -0
  74. data/lib/cisco_node_utils/cmd_ref/vrf.yaml +88 -0
  75. data/lib/cisco_node_utils/cmd_ref/vtp.yaml +38 -0
  76. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +60 -0
  77. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep_vni.yaml +39 -0
  78. data/lib/cisco_node_utils/cmd_ref/yum.yaml +13 -0
  79. data/lib/cisco_node_utils/command_reference.rb +359 -187
  80. data/lib/cisco_node_utils/configparser_lib.rb +1 -1
  81. data/lib/cisco_node_utils/dns_domain.rb +19 -5
  82. data/lib/cisco_node_utils/domain_name.rb +4 -8
  83. data/lib/cisco_node_utils/evpn_vni.rb +157 -0
  84. data/lib/cisco_node_utils/fabricpath_global.rb +388 -0
  85. data/lib/cisco_node_utils/fabricpath_topology.rb +150 -0
  86. data/lib/cisco_node_utils/feature.rb +111 -0
  87. data/lib/cisco_node_utils/interface.rb +390 -97
  88. data/lib/cisco_node_utils/interface_channel_group.rb +124 -0
  89. data/lib/cisco_node_utils/interface_ospf.rb +11 -34
  90. data/lib/cisco_node_utils/interface_portchannel.rb +157 -0
  91. data/lib/cisco_node_utils/interface_service_vni.rb +132 -0
  92. data/lib/cisco_node_utils/name_server.rb +1 -1
  93. data/lib/cisco_node_utils/node.rb +55 -249
  94. data/lib/cisco_node_utils/node_util.rb +5 -1
  95. data/lib/cisco_node_utils/ntp_config.rb +2 -2
  96. data/lib/cisco_node_utils/ntp_server.rb +14 -5
  97. data/lib/cisco_node_utils/overlay_global.rb +153 -0
  98. data/lib/cisco_node_utils/pim.rb +124 -0
  99. data/lib/cisco_node_utils/pim_group_list.rb +108 -0
  100. data/lib/cisco_node_utils/pim_rp_address.rb +102 -0
  101. data/lib/cisco_node_utils/platform.rb +8 -9
  102. data/lib/cisco_node_utils/portchannel_global.rb +277 -0
  103. data/lib/cisco_node_utils/radius_global.rb +9 -19
  104. data/lib/cisco_node_utils/radius_server.rb +31 -41
  105. data/lib/cisco_node_utils/radius_server_group.rb +117 -0
  106. data/lib/cisco_node_utils/router_ospf.rb +1 -1
  107. data/lib/cisco_node_utils/router_ospf_vrf.rb +14 -19
  108. data/lib/cisco_node_utils/snmp_notification_receiver.rb +158 -0
  109. data/lib/cisco_node_utils/snmpcommunity.rb +3 -5
  110. data/lib/cisco_node_utils/snmpgroup.rb +1 -1
  111. data/lib/cisco_node_utils/snmpnotification.rb +57 -0
  112. data/lib/cisco_node_utils/snmpserver.rb +8 -17
  113. data/lib/cisco_node_utils/snmpuser.rb +67 -28
  114. data/lib/cisco_node_utils/syslog_server.rb +3 -9
  115. data/lib/cisco_node_utils/syslog_settings.rb +2 -10
  116. data/lib/cisco_node_utils/tacacs_server.rb +9 -14
  117. data/lib/cisco_node_utils/tacacs_server_group.rb +145 -0
  118. data/lib/cisco_node_utils/tacacs_server_host.rb +5 -9
  119. data/lib/cisco_node_utils/vdc.rb +88 -0
  120. data/lib/cisco_node_utils/version.rb +5 -2
  121. data/lib/cisco_node_utils/vlan.rb +71 -8
  122. data/lib/cisco_node_utils/vni.rb +227 -0
  123. data/lib/cisco_node_utils/vpc.rb +377 -0
  124. data/lib/cisco_node_utils/vrf.rb +60 -9
  125. data/lib/cisco_node_utils/vrf_af.rb +191 -0
  126. data/lib/cisco_node_utils/vtp.rb +8 -6
  127. data/lib/cisco_node_utils/vxlan_vtep.rb +151 -0
  128. data/lib/cisco_node_utils/vxlan_vtep_vni.rb +234 -0
  129. data/lib/cisco_node_utils/yum.rb +1 -1
  130. data/tests/.rubocop.yml +1 -1
  131. data/tests/basetest.rb +16 -7
  132. data/tests/ciscotest.rb +55 -13
  133. data/tests/cmd_config.yaml +2 -2
  134. data/tests/platform_info.rb +3 -2
  135. data/tests/test_aaa_authentication_login.rb +219 -0
  136. data/tests/test_aaa_authentication_login_service.rb +759 -0
  137. data/tests/test_aaa_authorization_service.rb +1041 -0
  138. data/tests/test_ace.rb +160 -0
  139. data/tests/test_acl.rb +176 -0
  140. data/tests/test_bgp_af.rb +269 -13
  141. data/tests/test_bgp_neighbor.rb +38 -40
  142. data/tests/test_bgp_neighbor_af.rb +92 -32
  143. data/tests/test_command_config.rb +5 -5
  144. data/tests/test_command_reference.rb +284 -101
  145. data/tests/test_dns_domain.rb +1 -1
  146. data/tests/test_domain_name.rb +1 -1
  147. data/tests/test_evpn_vni.rb +106 -0
  148. data/tests/test_fabricpath_global.rb +243 -0
  149. data/tests/test_fabricpath_topology.rb +98 -0
  150. data/tests/test_interface.rb +292 -74
  151. data/tests/test_interface_channel_group.rb +74 -0
  152. data/tests/test_interface_ospf.rb +9 -4
  153. data/tests/test_interface_portchannel.rb +105 -0
  154. data/tests/test_interface_service_vni.rb +232 -0
  155. data/tests/test_interface_svi.rb +77 -62
  156. data/tests/test_interface_switchport.rb +17 -5
  157. data/tests/test_name_server.rb +1 -1
  158. data/tests/test_node.rb +1 -1
  159. data/tests/test_node_ext.rb +10 -20
  160. data/tests/test_ntp_config.rb +1 -1
  161. data/tests/test_ntp_server.rb +18 -6
  162. data/tests/test_overlay_global.rb +102 -0
  163. data/tests/test_pim.rb +177 -0
  164. data/tests/test_pim_group_list.rb +181 -0
  165. data/tests/test_pim_rp_address.rb +153 -0
  166. data/tests/test_platform.rb +3 -3
  167. data/tests/test_portchannel_global.rb +202 -0
  168. data/tests/test_radius_global.rb +1 -1
  169. data/tests/test_radius_server.rb +92 -57
  170. data/tests/test_radius_server_group.rb +149 -0
  171. data/tests/test_router_bgp.rb +283 -112
  172. data/tests/test_router_ospf.rb +2 -2
  173. data/tests/test_router_ospf_vrf.rb +4 -4
  174. data/tests/test_snmp_notification_receiver.rb +167 -0
  175. data/tests/test_snmpcommunity.rb +1 -1
  176. data/tests/test_snmpgroup.rb +1 -1
  177. data/tests/test_snmpnotification.rb +72 -0
  178. data/tests/test_snmpserver.rb +29 -105
  179. data/tests/test_snmpuser.rb +32 -30
  180. data/tests/test_syslog_server.rb +36 -10
  181. data/tests/test_syslog_settings.rb +1 -1
  182. data/tests/test_tacacs_server.rb +1 -1
  183. data/tests/test_tacacs_server_group.rb +405 -0
  184. data/tests/test_tacacs_server_host.rb +1 -1
  185. data/tests/test_vdc.rb +78 -0
  186. data/tests/test_vlan.rb +74 -19
  187. data/tests/test_vlan_mt_full.rb +95 -0
  188. data/tests/test_vni.rb +106 -0
  189. data/tests/test_vpc.rb +361 -0
  190. data/tests/test_vrf.rb +172 -29
  191. data/tests/test_vtp.rb +1 -1
  192. data/tests/test_vxlan_vtep.rb +214 -0
  193. data/tests/test_vxlan_vtep_vni.rb +201 -0
  194. data/tests/test_yum.rb +1 -1
  195. metadata +120 -11
  196. data/lib/cisco_node_utils/README_YAML.md +0 -325
  197. data/lib/cisco_node_utils/command_reference_common.yaml +0 -1051
  198. data/lib/cisco_node_utils/command_reference_common_bgp.yaml +0 -535
  199. data/lib/cisco_node_utils/command_reference_n3064.yaml +0 -13
  200. data/lib/cisco_node_utils/command_reference_n7k.yaml +0 -52
  201. data/lib/cisco_node_utils/command_reference_n9k.yaml +0 -26
  202. data/tests/platform_info.yaml +0 -10
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2015 Cisco and/or its affiliates.
1
+ # Copyright (c) 2014-2016 Cisco and/or its affiliates.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
data/tests/test_vdc.rb ADDED
@@ -0,0 +1,78 @@
1
+ # Copyright (c) 2015-2016 Cisco and/or its affiliates.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain 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,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative 'ciscotest'
16
+ require_relative '../lib/cisco_node_utils/vdc'
17
+
18
+ include Cisco
19
+
20
+ # TestVdc - Minitest for general functionality of the Vdc class.
21
+ class TestVdc < CiscoTestCase
22
+ # This test suite currently has very limited use because:
23
+ # a) VDC support is limited to a narrow list of platforms.
24
+ # b) License restrictions may limit platforms to a single vdc
25
+ # c) Linecard restrictions may limit some tests to specific linecards
26
+
27
+ def setup
28
+ super
29
+ # Check for supported platform
30
+ skip('Platform does not support VDCs') unless Vdc.vdc_support
31
+ end
32
+
33
+ def test_all_vdcs
34
+ # This test is limited because our vdc provider does not yet support
35
+ # vdc creation. For now just check that we get a non-empty list and
36
+ # that it at least contains the default vdc.
37
+ v = Vdc.vdcs
38
+ refute_empty(v.keys, 'vdc hash should have at least one vdc')
39
+ assert(v.key?(Vdc.default_vdc_name), 'default vdc name not found')
40
+ end
41
+
42
+ def test_create
43
+ assert_raises(ArgumentError) do
44
+ Vdc.new('non_def', 'Currently no support for non-default VDCs')
45
+ end
46
+ end
47
+
48
+ def compatible_interface?
49
+ # MT-full tests require a specific linecard; either because they need a
50
+ # compatible interface or simply to enable the features. Either way
51
+ # we will provide an appropriate interface name if the linecard is present.
52
+ # Example 'show mod' output to match against:
53
+ # '9 12 10/40 Gbps Ethernet Module N7K-F312FQ-25 ok'
54
+ sh_mod = @device.cmd("sh mod | i '^[0-9]+.*N7K-F3'")[/^(\d+)\s.*N7K-F3/]
55
+ slot = sh_mod.nil? ? nil : Regexp.last_match[1]
56
+ skip('Unable to find compatible interface in chassis') if slot.nil?
57
+
58
+ "ethernet#{slot}/1"
59
+ end
60
+
61
+ def test_limit_resource_module_type
62
+ compatible_interface?
63
+ v = Vdc.new('default')
64
+ # Set limit-resource module-type to default (this is variable for each
65
+ # device, so the default is for this device only)
66
+ v.limit_resource_module_type = ''
67
+ default = v.limit_resource_module_type
68
+
69
+ # Limit to F3 cards only
70
+ type = 'f3'
71
+ v.limit_resource_module_type = type
72
+ assert_equal(type, v.limit_resource_module_type)
73
+
74
+ # Reset to device-default
75
+ v.limit_resource_module_type = ''
76
+ assert_equal(default, v.limit_resource_module_type)
77
+ end
78
+ end
data/tests/test_vlan.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2013-2015 Cisco and/or its affiliates.
1
+ # Copyright (c) 2013-2016 Cisco and/or its affiliates.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -20,8 +20,35 @@ include Cisco
20
20
 
21
21
  # TestVlan - Minitest for Vlan node utility
22
22
  class TestVlan < CiscoTestCase
23
- def interface_ethernet_default(ethernet_id)
24
- config("default interface ethernet #{ethernet_id}")
23
+ @@cleaned = false # rubocop:disable Style/ClassVars
24
+ def cleanup
25
+ Vlan.vlans.each do |vlan, obj|
26
+ # skip reserved vlans
27
+ next if vlan == '1'
28
+ next if node.product_id[/N5K|N6K|N7K/] && (1002..1005).include?(vlan.to_i)
29
+ obj.destroy
30
+ end
31
+ interface_ethernet_default(interfaces[0])
32
+ end
33
+
34
+ def setup
35
+ super
36
+ cleanup unless @@cleaned
37
+ @@cleaned = true # rubocop:disable Style/ClassVars
38
+ end
39
+
40
+ def teardown
41
+ cleanup
42
+ end
43
+
44
+ def interface_ethernet_default(intf)
45
+ config("default interface #{intf}")
46
+ end
47
+
48
+ def linecard_cfg_change_not_allowed?(e)
49
+ skip('Linecard does not support this test') if
50
+ e.message[/requested config change not allowed/]
51
+ flunk(e.message)
25
52
  end
26
53
 
27
54
  def test_vlan_collection_not_empty
@@ -110,7 +137,6 @@ class TestVlan < CiscoTestCase
110
137
  1.upto(VLAN_NAME_SIZE - 1) do |i|
111
138
  begin
112
139
  name += alphabet[i % alphabet.size, 1]
113
- # puts "n is #{name}"
114
140
  if i == VLAN_NAME_SIZE - 1
115
141
  v.vlan_name = name
116
142
  assert_equal(name, v.vlan_name)
@@ -148,12 +174,6 @@ class TestVlan < CiscoTestCase
148
174
  v2.destroy
149
175
  end
150
176
 
151
- def test_vlan_state_extended
152
- v = Vlan.new(2000)
153
- v.state = 'suspend'
154
- v.destroy
155
- end
156
-
157
177
  def test_vlan_state_invalid
158
178
  v = Vlan.new(1000)
159
179
  assert_raises(RuntimeError) do
@@ -205,7 +225,8 @@ class TestVlan < CiscoTestCase
205
225
  interfaces_added_to_vlan = []
206
226
  count = 3
207
227
  interfaces.each do |name, interface|
208
- next unless interface.name.match(%r{ethernet[0-9/]}) && count > 0
228
+ next unless interface.name.match(%r{ethernet[0-9/]+$}) && count > 0
229
+ interface_ethernet_default(%r{net(\d+/\d+)}.match(name)[1])
209
230
  interfaces_added_to_vlan << name
210
231
  interface.switchport_mode = :access
211
232
  v.add_interface(interface)
@@ -228,10 +249,13 @@ class TestVlan < CiscoTestCase
228
249
  def test_vlan_add_interface_invalid
229
250
  v = Vlan.new(1000)
230
251
  interface = Interface.new(interfaces[0])
231
- interface.switchport_mode = :disabled
232
- assert_raises(RuntimeError) { v.add_interface(interface) }
233
- v.destroy
234
- interface_ethernet_default(interfaces_id[0])
252
+ begin
253
+ interface.switchport_mode = :disabled
254
+ assert_raises(RuntimeError) { v.add_interface(interface) }
255
+ v.destroy
256
+ end
257
+ rescue RuntimeError => e
258
+ linecard_cfg_change_not_allowed?(e)
235
259
  end
236
260
 
237
261
  def test_vlan_remove_interface_invalid
@@ -239,10 +263,41 @@ class TestVlan < CiscoTestCase
239
263
  interface = Interface.new(interfaces[0])
240
264
  interface.switchport_mode = :access
241
265
  v.add_interface(interface)
242
- interface.switchport_mode = :disabled
243
- assert_raises(RuntimeError) { v.remove_interface(interface) }
266
+ begin
267
+ interface.switchport_mode = :disabled
268
+ assert_raises(RuntimeError) { v.remove_interface(interface) }
269
+ v.destroy
270
+ end
271
+ rescue RuntimeError => e
272
+ linecard_cfg_change_not_allowed?(e)
273
+ end
244
274
 
245
- v.destroy
246
- interface_ethernet_default(interfaces_id[0])
275
+ def test_vlan_mapped_vnis
276
+ # Map
277
+ skip('Feature vn-segment-vlan-based is not supported on this platform.') if
278
+ node.product_id =~ /N3K-C3048/
279
+ v1 = Vlan.new(100)
280
+ vni1 = 10_000
281
+ v1.mapped_vni = vni1
282
+ assert_equal(vni1, v1.mapped_vni)
283
+
284
+ v2 = Vlan.new(500)
285
+ vni2 = 50_000
286
+ v2.mapped_vni = vni2
287
+ assert_equal(vni2, v2.mapped_vni)
288
+
289
+ v3 = Vlan.new(900)
290
+ vni3 = 90_000
291
+ v3.mapped_vni = vni3
292
+ assert_equal(vni3, v3.mapped_vni)
293
+ # Unmap
294
+ v1.mapped_vni = v1.default_mapped_vni
295
+ assert_equal(v1.default_mapped_vni, v1.mapped_vni)
296
+
297
+ v2.mapped_vni = v2.default_mapped_vni
298
+ assert_equal(v2.default_mapped_vni, v2.mapped_vni)
299
+
300
+ v3.mapped_vni = v3.default_mapped_vni
301
+ assert_equal(v3.default_mapped_vni, v3.mapped_vni)
247
302
  end
248
303
  end
@@ -0,0 +1,95 @@
1
+ # Copyright (c) 2016 Cisco and/or its affiliates.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain 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,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative 'ciscotest'
16
+ require_relative '../lib/cisco_node_utils/vlan'
17
+ require_relative '../lib/cisco_node_utils/interface'
18
+ require_relative '../lib/cisco_node_utils/vdc'
19
+ require_relative '../lib/cisco_node_utils/vxlan_vtep'
20
+
21
+ include Cisco
22
+
23
+ # TestVlanMtFull - Minitest for Vlan node utility (MT-Full testing only)
24
+ #
25
+ # This test requires specific platform & linecard support:
26
+ # - vdc support with 'limit-resource module-type' set to 'f3'
27
+ #
28
+ class TestVlanMtFull < CiscoTestCase
29
+ @@cleaned = false # rubocop:disable Style/ClassVars
30
+ def cleanup
31
+ Vlan.vlans.each do |vlan, obj|
32
+ # skip reserved vlans
33
+ next if vlan == '1'
34
+ next if node.product_id[/N5K|N6K|N7K/] && (1002..1005).include?(vlan.to_i)
35
+ obj.destroy
36
+ end
37
+ interface_ethernet_default(interfaces[0])
38
+ end
39
+
40
+ def setup
41
+ super
42
+ cleanup unless @@cleaned
43
+ @@cleaned = true # rubocop:disable Style/ClassVars
44
+ end
45
+
46
+ def teardown
47
+ cleanup
48
+ end
49
+
50
+ def interface_ethernet_default(ethernet_id)
51
+ config("default interface ethernet #{ethernet_id}")
52
+ end
53
+
54
+ def compatible_interface?
55
+ # MT-full tests require a specific linecard; either because they need a
56
+ # compatible interface or simply to enable the features. Either way
57
+ # we will provide an appropriate interface name if the linecard is present.
58
+ # Example 'show mod' output to match against:
59
+ # '9 12 10/40 Gbps Ethernet Module N7K-F312FQ-25 ok'
60
+ sh_mod = @device.cmd("sh mod | i '^[0-9]+.*N7K-F3'")[/^(\d+)\s.*N7K-F3/]
61
+ slot = sh_mod.nil? ? nil : Regexp.last_match[1]
62
+ skip('Unable to find a compatible interface in chassis') if slot.nil?
63
+
64
+ "ethernet#{slot}/1"
65
+ end
66
+
67
+ def mt_full_env_setup
68
+ skip('Platform does not support MT-full') unless VxlanVtep.mt_full_support
69
+ compatible_interface?
70
+ v = Vdc.new('default')
71
+ v.limit_resource_module_type = 'f3' unless
72
+ v.limit_resource_module_type == 'f3'
73
+ end
74
+
75
+ def test_vlan_mode_fabricpath
76
+ mt_full_env_setup
77
+
78
+ # Test for valid mode
79
+ v = Vlan.new(2000)
80
+ assert_equal('ce', v.mode,
81
+ 'Mode should have been default to ce')
82
+ v.mode = 'fabricpath'
83
+ assert_equal(:enabled, v.fabricpath_feature,
84
+ 'Fabricpath feature should have been enabled')
85
+ assert_equal('fabricpath', v.mode,
86
+ 'Mode should have been set to fabricpath')
87
+
88
+ # Test for invalid mode
89
+ v = Vlan.new(100)
90
+ assert_equal('ce', v.mode,
91
+ 'Mode should have been default to ce')
92
+
93
+ assert_raises(RuntimeError) { v.mode = 'junk' }
94
+ end
95
+ end
data/tests/test_vni.rb ADDED
@@ -0,0 +1,106 @@
1
+ # Copyright (c) 2013-2016 Cisco and/or its affiliates.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain 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,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative 'ciscotest'
16
+ require_relative '../lib/cisco_node_utils/feature'
17
+ require_relative '../lib/cisco_node_utils/vni'
18
+ require_relative '../lib/cisco_node_utils/vdc'
19
+
20
+ include Cisco
21
+
22
+ # TestVni - Minitest for Vni node utility
23
+ class TestVni < CiscoTestCase
24
+ def setup
25
+ super
26
+ skip('Platform does not support MT-full or MT-lite') unless
27
+ Vni.mt_full_support || Vni.mt_lite_support
28
+ end
29
+
30
+ def teardown
31
+ return unless Vdc.vdc_support
32
+ # Reset the vdc module type back to default
33
+ v = Vdc.new('default')
34
+ v.limit_resource_module_type = '' if v.limit_resource_module_type == 'f3'
35
+ end
36
+
37
+ def compatible_interface?
38
+ # This test requires specific linecards; find a compatible linecard
39
+ # and create an appropriate interface name from it.
40
+ # Example 'show mod' output to match against:
41
+ # '9 12 10/40 Gbps Ethernet Module N7K-F312FQ-25 ok'
42
+ sh_mod = @device.cmd("sh mod | i '^[0-9]+.*N7K-F3'")[/^(\d+)\s.*N7K-F3/]
43
+ slot = sh_mod.nil? ? nil : Regexp.last_match[1]
44
+ skip('Unable to find compatible interface in chassis') if slot.nil?
45
+
46
+ "ethernet#{slot}/1"
47
+ end
48
+
49
+ def mt_full_env_setup
50
+ skip('Platform does not support MT-full') unless Vni.mt_full_support
51
+ compatible_interface?
52
+ v = Vdc.new('default')
53
+ v.limit_resource_module_type = 'f3' unless
54
+ v.limit_resource_module_type == 'f3'
55
+ config('no feature vni')
56
+ config('no feature nv overlay')
57
+ end
58
+
59
+ def mt_lite_env_setup
60
+ skip('Platform does not support MT-lite') unless Vni.mt_lite_support
61
+ config('no feature vn-segment-vlan-based')
62
+ config('no feature nv overlay')
63
+ end
64
+
65
+ def test_mt_full_vni_create_destroy
66
+ mt_full_env_setup
67
+
68
+ v1 = Vni.new(10_001)
69
+ v2 = Vni.new(10_002)
70
+ v3 = Vni.new(10_003)
71
+ assert_equal(3, Vni.vnis.keys.count)
72
+
73
+ v2.destroy
74
+ assert_equal(2, Vni.vnis.keys.count)
75
+
76
+ v1.destroy
77
+ v3.destroy
78
+ assert_equal(0, Vni.vnis.keys.count)
79
+ end
80
+
81
+ # def test_mt_full_encapsulation_dot1q
82
+ # TBD
83
+ # mt_full_env_setup
84
+ # end
85
+
86
+ # def test_mt_full_mapped_bd
87
+ # TBD
88
+ # mt_full_env_setup
89
+ # end
90
+
91
+ def test_mt_full_shutdown
92
+ mt_full_env_setup
93
+ vni = Vni.new(10_000)
94
+ vni.shutdown = true
95
+ assert(vni.shutdown)
96
+
97
+ vni.shutdown = false
98
+ refute(vni.shutdown)
99
+
100
+ vni.shutdown = !vni.default_shutdown
101
+ assert_equal(!vni.default_shutdown, vni.shutdown)
102
+
103
+ vni.shutdown = vni.default_shutdown
104
+ assert_equal(vni.default_shutdown, vni.shutdown)
105
+ end
106
+ end
data/tests/test_vpc.rb ADDED
@@ -0,0 +1,361 @@
1
+ # Copyright (c) 2015-2016 Cisco and/or its affiliates.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain 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,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require_relative 'ciscotest'
15
+ require_relative '../lib/cisco_node_utils/vpc'
16
+ require_relative '../lib/cisco_node_utils/interface'
17
+ require_relative '../lib/cisco_node_utils/interface_channel_group'
18
+
19
+ include Cisco
20
+
21
+ # TestVpc - Minitest for Vpc node utility class
22
+ class TestVpc < CiscoTestCase
23
+ def setup
24
+ super
25
+ no_feature_vpc
26
+ end
27
+
28
+ def teardown
29
+ no_feature_vpc
30
+ super
31
+ end
32
+
33
+ def no_feature_vpc
34
+ config('terminal dont-ask ; no feature vpc')
35
+ end
36
+
37
+ def n5k6k_platforms?
38
+ /N[56]K/ =~ node.product_id
39
+ end
40
+
41
+ def n3k9k_platforms?
42
+ /N[39]K/ =~ node.product_id
43
+ end
44
+
45
+ # TESTS
46
+
47
+ def test_vpc_create
48
+ @vpc = Vpc.new(100)
49
+ assert(@vpc.domain == 100,
50
+ "VPC domain not set correctly #{@vpc.domain}")
51
+ assert(Vpc.enabled,
52
+ 'VPC feature should have been enabled')
53
+ refute(Vpc.domains.empty?,
54
+ 'Domain collection should not be empty after create')
55
+ end
56
+
57
+ def test_vpc_destroy
58
+ # create and test again
59
+ @vpc = Vpc.new(100)
60
+ @vpc.destroy
61
+ refute(Vpc.enabled, 'VPC feature should have been disabled')
62
+ end
63
+
64
+ def test_auto_recovery
65
+ skip("Test not supported on #{node.product_id}") if
66
+ cmd_ref.lookup('vpc', 'auto_recovery').default_value.nil?
67
+ @vpc = Vpc.new(100)
68
+ default_val = @vpc.auto_recovery
69
+ assert_equal(default_val, @vpc.auto_recovery,
70
+ "Auto recovery should be #{default_val} by default")
71
+ @vpc.auto_recovery = false
72
+ refute(@vpc.auto_recovery, 'Auto recovery not getting disabled')
73
+ @vpc.auto_recovery = true
74
+ assert(@vpc.auto_recovery, 'Auto recovery not getting set')
75
+ end
76
+
77
+ def test_auto_recovery_reload_delay
78
+ @vpc = Vpc.new(100)
79
+ default_value = @vpc.default_auto_recovery_reload_delay
80
+ assert_equal(default_value, @vpc.auto_recovery_reload_delay,
81
+ "Auto recovery delay should be #{default_value}")
82
+ @vpc.auto_recovery_reload_delay = 300
83
+ assert_equal(300, @vpc.auto_recovery_reload_delay,
84
+ 'Auto recovery delay should be 300')
85
+ end
86
+
87
+ def test_delay_restore
88
+ @vpc = Vpc.new(100)
89
+ default_value = @vpc.default_delay_restore
90
+ assert_equal(default_value, @vpc.delay_restore,
91
+ "delay_restore should be #{default_value}")
92
+ @vpc.delay_restore = 1000
93
+ assert_equal(1000, @vpc.delay_restore,
94
+ 'delay restore should be 1000')
95
+ end
96
+
97
+ def test_delay_restore_interface_vlan
98
+ @vpc = Vpc.new(100)
99
+ default_value = @vpc.default_delay_restore_interface_vlan
100
+ assert_equal(default_value, @vpc.delay_restore_interface_vlan,
101
+ "delay_restore should be #{default_value}")
102
+ @vpc.delay_restore_interface_vlan = 2000
103
+ assert_equal(2000, @vpc.delay_restore_interface_vlan,
104
+ 'delay restore should be 2000')
105
+ end
106
+
107
+ def test_dual_active_exclude_interface_vlan_bridge_domain
108
+ @vpc = Vpc.new(100)
109
+ default_value =
110
+ @vpc.default_dual_active_exclude_interface_vlan_bridge_domain
111
+ assert_equal(default_value,
112
+ @vpc.dual_active_exclude_interface_vlan_bridge_domain,
113
+ "delay_restore should be #{default_value}")
114
+ @vpc.dual_active_exclude_interface_vlan_bridge_domain = '2-20,900'
115
+ assert_equal('2-20,900',
116
+ @vpc.dual_active_exclude_interface_vlan_bridge_domain,
117
+ 'exclude vlan/bd should be 2-20,900')
118
+ end
119
+
120
+ def test_graceful_consistency_check
121
+ @vpc = Vpc.new(100)
122
+ default_val = @vpc.default_graceful_consistency_check
123
+ assert_equal(default_val, @vpc.graceful_consistency_check,
124
+ "graceful_consistency_check must be #{default_val} by default")
125
+ @vpc.graceful_consistency_check = false
126
+ refute(@vpc.graceful_consistency_check,
127
+ 'graceful_consistency_check not getting disabled')
128
+ @vpc.graceful_consistency_check = true
129
+ assert(@vpc.graceful_consistency_check,
130
+ 'graceful_consistency_check not getting set')
131
+ end
132
+
133
+ def test_layer3_peer_routing
134
+ skip("Test not supported on #{node.product_id}") if
135
+ cmd_ref.lookup('vpc', 'layer3_peer_routing').default_value.nil?
136
+ @vpc = Vpc.new(100)
137
+ default_val = @vpc.default_layer3_peer_routing
138
+ assert_equal(default_val, @vpc.layer3_peer_routing,
139
+ "layer3_peer_routing should be #{default_val} by default")
140
+ @vpc.layer3_peer_routing = true
141
+ assert(@vpc.layer3_peer_routing, 'layer3_peer_routing not getting set')
142
+ @vpc.layer3_peer_routing = false
143
+ refute(@vpc.layer3_peer_routing, 'layer3_peer_routing not getting disabled')
144
+ end
145
+
146
+ def test_peer_keepalive
147
+ @vpc = Vpc.new(100)
148
+
149
+ # Check default values
150
+ dest = @vpc.default_peer_keepalive_dest
151
+ assert_equal('', dest, 'destination should be 1.1.1.2')
152
+ source = @vpc.default_peer_keepalive_src
153
+ assert_equal('', source, 'source should be 1.1.1.1')
154
+ udp_port = @vpc.default_peer_keepalive_udp_port
155
+ assert_equal(3200, udp_port, 'udp port should be 3200')
156
+ vrf = @vpc.default_peer_keepalive_vrf
157
+ assert_equal('management', vrf, 'vrf should be management')
158
+ interval = @vpc.default_peer_keepalive_interval
159
+ assert_equal(1000, interval, 'interval should be 1000')
160
+ timeout = @vpc.default_peer_keepalive_interval_timeout
161
+ assert_equal(5, timeout, 'interval timeout should be 5')
162
+ precedence = @vpc.default_peer_keepalive_precedence
163
+ assert_equal(6, precedence, 'precedence should be 6')
164
+ hold_timeout = @vpc.default_peer_keepalive_hold_timeout
165
+ assert_equal(3, hold_timeout, 'hold timeout should be 3')
166
+
167
+ @vpc.peer_keepalive_set('1.1.1.2', '1.1.1.1', 3800, 'management', 400, 3,
168
+ 6, 3)
169
+ dest = @vpc.peer_keepalive_dest
170
+ assert_equal('1.1.1.2', dest, 'destination should be 1.1.1.2')
171
+ source = @vpc.peer_keepalive_src
172
+ assert_equal('1.1.1.1', source, 'source should be 1.1.1.1')
173
+ udp_port = @vpc.peer_keepalive_udp_port
174
+ assert_equal(3800, udp_port, 'udp port should be 3800')
175
+ vrf = @vpc.peer_keepalive_vrf
176
+ assert_equal('management', vrf, 'vrf should be management')
177
+ interval = @vpc.peer_keepalive_interval
178
+ assert_equal(400, interval, 'interval should be 400')
179
+ timeout = @vpc.peer_keepalive_interval_timeout
180
+ assert_equal(3, timeout, 'interval timeout should be 3')
181
+ precedence = @vpc.peer_keepalive_precedence
182
+ assert_equal(6, precedence, 'precedence should be 6')
183
+ hold_timeout = @vpc.peer_keepalive_hold_timeout
184
+ assert_equal(3, hold_timeout, 'hold timeout should be 3')
185
+ end
186
+
187
+ def test_peer_gateway
188
+ @vpc = Vpc.new(100)
189
+ default_val = @vpc.default_peer_gateway
190
+ assert_equal(default_val, @vpc.peer_gateway,
191
+ "peer_gateway should be #{default_val} by default")
192
+ @vpc.peer_gateway = true
193
+ assert(@vpc.peer_gateway, 'peer_gateway not getting set')
194
+ @vpc.peer_gateway = false
195
+ refute(@vpc.peer_gateway, 'peer_gateway not getting disabled')
196
+ end
197
+
198
+ def test_peer_gateway_exclude_bridge_domain
199
+ skip("Test not supported on #{node.product_id}") if
200
+ cmd_ref.lookup('vpc', 'peer_gateway_exclude_bridge_domain').default_value
201
+ .nil?
202
+ @vpc = Vpc.new(100)
203
+ default_val = @vpc.default_peer_gateway_exclude_bridge_domain
204
+ assert_equal(default_val, @vpc.peer_gateway_exclude_bridge_domain,
205
+ "peer_gateway exclude BD should be #{default_val} default")
206
+ @vpc.peer_gateway_exclude_bridge_domain = '10-20,400'
207
+ assert_equal('10-20,400', @vpc.peer_gateway_exclude_bridge_domain,
208
+ 'peer_gateway exclude list not getting set')
209
+ end
210
+
211
+ def test_peer_gateway_exclude_vlan
212
+ skip("Test not supported on #{node.product_id}") if
213
+ cmd_ref.lookup('vpc', 'peer_gateway_exclude_vlan').default_value.nil?
214
+ @vpc = Vpc.new(100)
215
+ default_val = @vpc.default_peer_gateway_exclude_vlan
216
+ assert_equal(default_val, @vpc.peer_gateway_exclude_vlan,
217
+ "peer_gateway exclude vlan should be #{default_val} default")
218
+ @vpc.peer_gateway_exclude_vlan = '10-20,400'
219
+ assert_equal('10-20,400', @vpc.peer_gateway_exclude_vlan,
220
+ 'peer_gateway exclude list not getting set')
221
+ end
222
+
223
+ def test_role_priority
224
+ @vpc = Vpc.new(100)
225
+ default_value = @vpc.default_role_priority
226
+ assert_equal(default_value, @vpc.role_priority,
227
+ "Role priority should be #{default_value}")
228
+ @vpc.role_priority = 200
229
+ assert_equal(200, @vpc.role_priority,
230
+ 'Role priority should be 200')
231
+ end
232
+
233
+ def test_self_isolation
234
+ skip('Only supported on N7K') unless node.product_id[/N7/]
235
+
236
+ @vpc = Vpc.new(100)
237
+ @vpc.self_isolation = true
238
+ assert_equal(true, @vpc.self_isolation,
239
+ 'Self isolation should have been configured')
240
+ end
241
+
242
+ def test_shutdown
243
+ skip("Test not supported on #{node.product_id}") if
244
+ cmd_ref.lookup('vpc', 'layer3_peer_routing').default_value.nil?
245
+ @vpc = Vpc.new(100)
246
+
247
+ @vpc.shutdown = @vpc.default_shutdown
248
+ refute(@vpc.shutdown, 'Vpc domain should not be shutdown')
249
+
250
+ @vpc.shutdown = true
251
+ assert(@vpc.shutdown, 'Vpc domain should be shutdown')
252
+
253
+ @vpc.shutdown = false
254
+ refute(@vpc.shutdown, 'Vpc domain should not be shutdown')
255
+ end
256
+
257
+ def test_system_mac
258
+ @vpc = Vpc.new(100)
259
+ default_value = @vpc.default_system_mac
260
+ assert_equal(default_value, @vpc.system_mac,
261
+ "Default system_mac should be #{default_value}")
262
+
263
+ @vpc.system_mac = '1.1.1'
264
+ assert_equal('00:01:00:01:00:01', @vpc.system_mac,
265
+ 'Error: system_mac mismatch')
266
+ end
267
+
268
+ def test_system_priority
269
+ @vpc = Vpc.new(100)
270
+ default_value = @vpc.default_system_priority
271
+ assert_equal(default_value, @vpc.system_priority,
272
+ "System priority should be #{default_value}")
273
+ @vpc.system_priority = 200
274
+ assert_equal(200, @vpc.system_priority,
275
+ 'System priority should be 200')
276
+ end
277
+
278
+ def test_track
279
+ skip("Test not supported on #{node.product_id}") if
280
+ cmd_ref.lookup('vpc', 'track').default_value.nil?
281
+ @vpc = Vpc.new(100)
282
+
283
+ default_value = @vpc.default_track
284
+ assert_equal(default_value, @vpc.track,
285
+ 'default track should be 0')
286
+
287
+ @vpc.track = 44
288
+ assert_equal(44, @vpc.track, 'track should be 44')
289
+ end
290
+
291
+ def test_interface_vpc_id
292
+ @vpc = Vpc.new(100)
293
+ # test phy port vpc
294
+ interface = Interface.new(interfaces[0])
295
+ assert_equal(interface.vpc_id, interface.default_vpc_id,
296
+ 'default vpc_id should be null')
297
+ # Make sure PKA is set
298
+ @vpc.peer_keepalive_set('1.1.1.2', '1.1.1.1', 3800, 'management', 400, 3,
299
+ 6, 3)
300
+ # Phy port vPC is supported only on N7K
301
+ if /N7/ =~ node.product_id
302
+ interface.switchport_mode = :trunk
303
+ interface.vpc_id = 10
304
+ assert_equal(10, interface.vpc_id, 'vpc_id should be 10')
305
+
306
+ # negative - cannot config peer link on this
307
+ e = assert_raises(CliError) do
308
+ interface.vpc_peer_link = true
309
+ end
310
+ assert_match(/Invalid number/i, e.message)
311
+
312
+ # turn off vpc id
313
+ interface.vpc_id = false
314
+ refute(interface.vpc_id, 'vpc_id should be unset')
315
+ end
316
+ # test port-channel vpc
317
+ interface = InterfaceChannelGroup.new(interfaces[0])
318
+ interface.channel_group = 10
319
+ interface_pc = Interface.new('port-channel10')
320
+ interface_pc.switchport_mode = :trunk
321
+ interface_pc.vpc_id = 20
322
+ assert_equal(20, interface_pc.vpc_id, 'vpc_id should be 20')
323
+ # test limits
324
+ interface_pc.vpc_id = false
325
+ refute(interface_pc.vpc_id, 'vpc_id should be empty')
326
+ interface_pc.vpc_id = 4095
327
+ assert_equal(4095, interface_pc.vpc_id, 'vpc_id should be empty')
328
+ # clean-up
329
+ interface_pc.vpc_id = false
330
+ # remove PC
331
+ interface.channel_group = false
332
+ refute(interface.channel_group, 'Port channel not cleaned up')
333
+ end
334
+
335
+ def test_interface_vpc_peer_link
336
+ @vpc = Vpc.new(100)
337
+ # Make sure PKA is set
338
+ @vpc.peer_keepalive_set('1.1.1.2', '1.1.1.1', 3800, 'management', 400, 3,
339
+ 6, 3)
340
+ interface = InterfaceChannelGroup.new(interfaces[1])
341
+ interface.channel_group = 100
342
+ interface_pc = Interface.new('port-channel100')
343
+ interface_pc.switchport_mode = :trunk
344
+ refute(interface_pc.vpc_peer_link,
345
+ 'vpc_peer_link should not be set by default')
346
+ interface_pc.vpc_peer_link = true
347
+ assert(interface_pc.vpc_peer_link, 'vpc_peer_link should be set')
348
+ interface_pc.vpc_peer_link = false
349
+ refute(interface_pc.vpc_peer_link, 'vpc_peer_link should not be set')
350
+ # clean up
351
+ interface.channel_group = false
352
+ refute(interface.channel_group, 'channel group should be unset')
353
+ # try with a phy port
354
+ interface = Interface.new(interfaces[1])
355
+ # negative - cannot config peer link on this
356
+ e = assert_raises(CliError) do
357
+ interface.vpc_peer_link = true
358
+ end
359
+ assert_match(/Invalid/i, e.message)
360
+ end
361
+ end