cisco_node_utils 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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