cisco_node_utils 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -1
  3. data/Gemfile +1 -1
  4. data/LICENSE +1 -1
  5. data/README.md +1 -1
  6. data/cisco_node_utils.gemspec +1 -1
  7. data/docs/README-develop-node-utils-APIs.md +2 -0
  8. data/docs/README-maintainers.md +45 -80
  9. data/lib/cisco_node_utils/ace.rb +24 -43
  10. data/lib/cisco_node_utils/bfd_global.rb +1 -0
  11. data/lib/cisco_node_utils/bgp_af_aggr_addr.rb +207 -0
  12. data/lib/cisco_node_utils/bgp_neighbor.rb +8 -5
  13. data/lib/cisco_node_utils/bgp_neighbor_af.rb +8 -6
  14. data/lib/cisco_node_utils/cisco_cmn_utils.rb +40 -0
  15. data/lib/cisco_node_utils/cmd_ref/bfd_global.yaml +1 -1
  16. data/lib/cisco_node_utils/cmd_ref/bgp.yaml +8 -4
  17. data/lib/cisco_node_utils/cmd_ref/bgp_af_aa.yaml +38 -0
  18. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +9 -4
  19. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor_af.yaml +8 -3
  20. data/lib/cisco_node_utils/cmd_ref/dhcp_relay_global.yaml +2 -1
  21. data/lib/cisco_node_utils/cmd_ref/feature.yaml +5 -0
  22. data/lib/cisco_node_utils/cmd_ref/interface.yaml +8 -0
  23. data/lib/cisco_node_utils/cmd_ref/interface_channel_group.yaml +7 -3
  24. data/lib/cisco_node_utils/cmd_ref/inventory.yaml +3 -3
  25. data/lib/cisco_node_utils/cmd_ref/ntp_auth_key.yaml +10 -0
  26. data/lib/cisco_node_utils/cmd_ref/ntp_config.yaml +13 -0
  27. data/lib/cisco_node_utils/cmd_ref/ntp_server.yaml +10 -2
  28. data/lib/cisco_node_utils/cmd_ref/overlay_global.yaml +6 -1
  29. data/lib/cisco_node_utils/cmd_ref/route_map.yaml +8 -0
  30. data/lib/cisco_node_utils/cmd_ref/span_session.yaml +65 -0
  31. data/lib/cisco_node_utils/cmd_ref/stp_global.yaml +2 -1
  32. data/lib/cisco_node_utils/cmd_ref/vpc.yaml +22 -3
  33. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +2 -1
  34. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep_vni.yaml +6 -3
  35. data/lib/cisco_node_utils/cmd_ref/yum.yaml +48 -4
  36. data/lib/cisco_node_utils/command_reference.rb +5 -2
  37. data/lib/cisco_node_utils/feature.rb +14 -1
  38. data/lib/cisco_node_utils/interface.rb +13 -0
  39. data/lib/cisco_node_utils/interface_channel_group.rb +33 -25
  40. data/lib/cisco_node_utils/itd_device_group.rb +17 -37
  41. data/lib/cisco_node_utils/itd_service.rb +9 -32
  42. data/lib/cisco_node_utils/node.rb +12 -4
  43. data/lib/cisco_node_utils/ntp_auth_key.rb +67 -0
  44. data/lib/cisco_node_utils/ntp_config.rb +19 -1
  45. data/lib/cisco_node_utils/ntp_server.rb +28 -27
  46. data/lib/cisco_node_utils/route_map.rb +33 -51
  47. data/lib/cisco_node_utils/snmpuser.rb +2 -2
  48. data/lib/cisco_node_utils/span_session.rb +149 -0
  49. data/lib/cisco_node_utils/upgrade.rb +21 -17
  50. data/lib/cisco_node_utils/version.rb +2 -2
  51. data/lib/cisco_node_utils/vlan.rb +1 -1
  52. data/lib/cisco_node_utils/vpc.rb +40 -0
  53. data/lib/cisco_node_utils/yum.rb +136 -13
  54. data/spec/schema.yaml +2 -0
  55. data/tests/ciscotest.rb +36 -0
  56. data/tests/test_ace.rb +6 -0
  57. data/tests/test_bfd_global.rb +1 -7
  58. data/tests/test_bgp_af.rb +2 -2
  59. data/tests/test_bgp_af_aa.rb +108 -0
  60. data/tests/test_bgp_neighbor.rb +2 -1
  61. data/tests/test_bgp_neighbor_af.rb +6 -6
  62. data/tests/test_dhcp_relay_global.rb +1 -0
  63. data/tests/test_interface.rb +18 -2
  64. data/tests/test_interface_channel_group.rb +47 -0
  65. data/tests/test_interface_svi.rb +1 -1
  66. data/tests/test_ntp_auth_key.rb +77 -0
  67. data/tests/test_ntp_config.rb +51 -4
  68. data/tests/test_ntp_server.rb +69 -9
  69. data/tests/test_overlay_global.rb +1 -0
  70. data/tests/test_route_map.rb +13 -24
  71. data/tests/test_router_bgp.rb +14 -9
  72. data/tests/test_span_session.rb +155 -0
  73. data/tests/test_stp_global.rb +1 -0
  74. data/tests/test_upgrade.rb +2 -3
  75. data/tests/test_vlan.rb +24 -3
  76. data/tests/test_vlan_private.rb +1 -1
  77. data/tests/test_vpc.rb +42 -17
  78. data/tests/test_vxlan_vtep.rb +1 -0
  79. data/tests/test_vxlan_vtep_vni.rb +5 -1
  80. data/tests/test_yum.rb +7 -30
  81. data/tests/yum_package.yaml +20 -0
  82. metadata +13 -3
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2015-2016 Cisco and/or its affiliates.
1
+ # Copyright (c) 2015-2017 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.
@@ -14,7 +14,7 @@
14
14
 
15
15
  # Container module for version number only.
16
16
  module CiscoNodeUtils
17
- VERSION = '1.6.0'
17
+ VERSION = '1.7.0'
18
18
  gem_version = Gem::Version.new(Gem::VERSION)
19
19
  min_gem_version = Gem::Version.new('2.1.0')
20
20
  fail 'Required rubygems version >= 2.1.0' if gem_version < min_gem_version
@@ -76,7 +76,7 @@ module Cisco
76
76
  (result[2]['body'].split(errors) - ['']).each_slice(2).map(&:join)
77
77
  error_list.each do |msg|
78
78
  next if ignore_message && msg.to_s.include?(ignore_message)
79
- fail result[2]['body']
79
+ fail Cisco::CliError, result[2]['body']
80
80
  end
81
81
  end
82
82
 
@@ -200,6 +200,7 @@ module Cisco
200
200
  end
201
201
 
202
202
  def layer3_peer_routing=(val)
203
+ return if val == layer3_peer_routing
203
204
  set_args_keys(state: val ? '' : 'no')
204
205
  # This requires peer_gateway to be set first
205
206
  self.peer_gateway = true if !peer_gateway && val
@@ -295,10 +296,49 @@ module Cisco
295
296
  config_set('vpc', 'peer_gateway', @set_args)
296
297
  end
297
298
 
299
+ def peer_switch
300
+ config_get('vpc', 'peer_switch')
301
+ end
302
+
303
+ def peer_switch=(val)
304
+ set_args_keys(state: val ? '' : 'no')
305
+ config_set('vpc', 'peer_switch', @set_args)
306
+ end
307
+
308
+ def arp_synchronize
309
+ config_get('vpc', 'arp_synchronize')
310
+ end
311
+
312
+ def arp_synchronize=(val)
313
+ set_args_keys(state: val ? '' : 'no')
314
+ config_set('vpc', 'arp_synchronize', @set_args)
315
+ end
316
+
317
+ def nd_synchronize
318
+ config_get('vpc', 'nd_synchronize')
319
+ end
320
+
321
+ def nd_synchronize=(val)
322
+ set_args_keys(state: val ? '' : 'no')
323
+ config_set('vpc', 'nd_synchronize', @set_args)
324
+ end
325
+
298
326
  def default_peer_gateway
299
327
  config_get_default('vpc', 'peer_gateway')
300
328
  end
301
329
 
330
+ def default_peer_switch
331
+ config_get_default('vpc', 'peer_switch')
332
+ end
333
+
334
+ def default_arp_synchronize
335
+ config_get_default('vpc', 'arp_synchronize')
336
+ end
337
+
338
+ def default_nd_synchronize
339
+ config_get_default('vpc', 'nd_synchronize')
340
+ end
341
+
302
342
  def peer_gateway_exclude_bridge_domain
303
343
  config_get('vpc', 'peer_gateway_exclude_bridge_domain')
304
344
  end
@@ -3,7 +3,9 @@
3
3
  #
4
4
  # April 2015, Alex Hunsberger
5
5
  #
6
- # Copyright (c) 2015-2016 Cisco and/or its affiliates.
6
+ # March 2017, Re-written by Mike Wiebe
7
+ #
8
+ # Copyright (c) 2015-2017 Cisco and/or its affiliates.
7
9
  #
8
10
  # Licensed under the Apache License, Version 2.0 (the "License");
9
11
  # you may not use this file except in compliance with the License.
@@ -18,6 +20,7 @@
18
20
  # limitations under the License.
19
21
 
20
22
  require_relative 'node_util'
23
+ require_relative 'logger'
21
24
 
22
25
  module Cisco
23
26
  # This Yum class provides cisco package management functions through nxapi.
@@ -52,14 +55,14 @@ module Cisco
52
55
 
53
56
  def self.install(pkg, vrf=nil)
54
57
  vrf = vrf.nil? ? detect_vrf : "vrf #{vrf}"
55
-
56
58
  begin
57
- config_set('yum', 'install', pkg, vrf)
58
-
59
- # HACK: The current nxos host installer is a multi-part command
60
- # which may fail at a later stage yet return a false positive;
61
- # therefore a post-validation check is needed here to verify the
62
- # actual outcome.
59
+ # get package name first
60
+ name = pkg_name(pkg)
61
+ # call remove if pkg exists
62
+ remove(name) unless name.empty?
63
+ add(pkg, vrf)
64
+ activate(pkg)
65
+ commit(pkg_name(pkg))
63
66
  validate_installed(pkg)
64
67
  rescue Cisco::CliError, RuntimeError => e
65
68
  raise Cisco::CliError, "#{e.class}, #{e.message}"
@@ -76,15 +79,135 @@ module Cisco
76
79
  end
77
80
 
78
81
  def self.remove(pkg)
79
- config_set('yum', 'deactivate', pkg)
80
- # May not be able to remove the package immediately after
81
- # deactivation.
82
+ # get committed state
83
+ cstate = query_committed(pkg)
84
+ # get activated state
85
+ astate = query_activated(pkg)
86
+
87
+ if astate && cstate
88
+ # pkg is active and committed
89
+ # so deactivate, commit and remove
90
+ deactivate(pkg)
91
+ commit_deactivate(pkg)
92
+ delete(pkg)
93
+ elsif cstate
94
+ # pkg is inactive and committed
95
+ # so commit and remove
96
+ commit_deactivate(pkg)
97
+ delete(pkg)
98
+ elsif astate
99
+ # pkg is active and not committed
100
+ # so deactivate and remove
101
+ deactivate(pkg)
102
+ delete(pkg)
103
+ else
104
+ # pkg is inactive and not committed
105
+ # so just remove
106
+ delete(pkg)
107
+ end
108
+ rescue Cisco::CliError, RuntimeError => e
109
+ raise Cisco::CliError, "#{e.class}, #{e.message}"
110
+ end
111
+
112
+ def self.add(pkg, vrf=nil)
113
+ try_operation('add', pkg, vrf)
82
114
  while (try ||= 1) < 20
83
- o = config_set('yum', 'remove', pkg)
84
- break unless o[/operation is in progress, please try again later/]
115
+ return if query_added(pkg)
85
116
  sleep 1
86
117
  try += 1
87
118
  end
119
+ fail "Failed to add pkg: #{pkg}, using vrf #{vrf}"
120
+ end
121
+
122
+ def self.activate(pkg)
123
+ try_operation('activate', pkg)
124
+ while (try ||= 1) < 20
125
+ return if query_activated(pkg)
126
+ sleep 1
127
+ try += 1
128
+ end
129
+ fail "Failed to activate pkg: #{pkg}"
130
+ end
131
+
132
+ def self.commit(pkg)
133
+ try_operation('commit', pkg)
134
+ while (try ||= 1) < 20
135
+ return if query_committed(pkg)
136
+ sleep 1
137
+ try += 1
138
+ end
139
+ fail "Failed to commit pkg: #{pkg}"
140
+ end
141
+
142
+ def self.commit_deactivate(pkg)
143
+ try_operation('commit', pkg)
144
+ while (try ||= 1) < 20
145
+ return unless query_committed(pkg)
146
+ sleep 1
147
+ try += 1
148
+ end
149
+ fail "Failed to commit after deactivate pkg: #{pkg}"
150
+ end
151
+
152
+ def self.deactivate(pkg)
153
+ try_operation('deactivate', pkg)
154
+ while (try ||= 1) < 20
155
+ return if query_inactive(pkg)
156
+ sleep 1
157
+ try += 1
158
+ end
159
+ fail "Failed to deactivate pkg: #{pkg}"
160
+ end
161
+
162
+ def self.delete(pkg)
163
+ try_operation('remove', pkg)
164
+ while (try ||= 1) < 20
165
+ return if query_removed(pkg)
166
+ sleep 1
167
+ try += 1
168
+ end
169
+ fail "Failed to delete pkg: #{pkg}"
170
+ end
171
+
172
+ def self.try_operation(operation, pkg, vrf=nil)
173
+ args = vrf.nil? ? { pkg: pkg } : { pkg: pkg, vrf: vrf }
174
+ while (try ||= 1) < 20
175
+ o = config_set('yum', operation, args)
176
+ break unless o[/Another install operation is in progress/]
177
+ sleep 1
178
+ try += 1
179
+ end
180
+ end
181
+
182
+ def self.pkg_name(pkg)
183
+ config_get('yum', 'pkg_name', pkg: pkg)
184
+ end
185
+
186
+ def self.query_activated(pkg)
187
+ config_get('yum', 'query_activated', pkg: pkg)
188
+ end
189
+
190
+ def self.query_added(pkg)
191
+ config_get('yum', 'query_added', pkg: pkg)
192
+ end
193
+
194
+ def self.query_committed(pkg)
195
+ o = config_get('yum', 'query_committed', pkg: pkg)
196
+ return false if o.nil?
197
+ o.include? pkg
198
+ end
199
+
200
+ def self.query_inactive(pkg)
201
+ config_get('yum', 'query_inactive', pkg: pkg)
202
+ end
203
+
204
+ def self.query_removed(pkg)
205
+ val = config_get('yum', 'query_removed', pkg: pkg)
206
+ val ? false : true
207
+ end
208
+
209
+ def self.query_state(pkg)
210
+ config_get('yum', 'query_state', pkg: pkg).downcase
88
211
  end
89
212
  end
90
213
  end
data/spec/schema.yaml CHANGED
@@ -68,6 +68,8 @@ mapping:
68
68
  enum: [boolean, int, string, symbol]
69
69
  multiple:
70
70
  type: bool
71
+ os_version:
72
+ type: str
71
73
  # Setter-specific attributes
72
74
  set_data_format: *data_format
73
75
  set_context: *context
data/tests/ciscotest.rb CHANGED
@@ -172,6 +172,42 @@ class CiscoTestCase < TestCase
172
172
  !node.cmd_ref.supports?(feature, property)
173
173
  end
174
174
 
175
+ def skip_incompat_version?(feature, property)
176
+ ov = node.os_version_get(feature, property)
177
+ return if ov.nil?
178
+ im = Platform.image_version
179
+ pid = node.product_id
180
+
181
+ ver = nil
182
+ array = ov.split(';')
183
+ array.each do |e|
184
+ break if ver
185
+ key_values = e.split(':')
186
+ larr = key_values[0].split(',')
187
+ larr.each do |lkey|
188
+ fail "Unrecognized product_id: #{lkey}" unless
189
+ lkey.downcase[/n(3|5|6|7|9)/]
190
+ next unless lkey.downcase.strip == product_tag
191
+ ver = key_values[1]
192
+ break if ver
193
+ end
194
+ end
195
+
196
+ return if ver.nil?
197
+ over = ver
198
+ lim = im.split[0].tr('(', '.').tr(')', '.').chomp('.')
199
+ # due to a bug in Gem::Version, we need to append a letter
200
+ # to the version field if only one of compared versions
201
+ # has a letter at the end
202
+ # For ex:
203
+ # 7.0.3.I2.2e < 7.0.3.I2.2 is TRUE instead of FALSE
204
+ # Once we add a letter 'a' to the end,
205
+ # 7.0.3.I2.2e < 7.0.3.I2.2a is FALSE
206
+ ver << 'a' if lim[-1, 1] =~ /[[:alpha:]]/
207
+ skip("The #{feature} #{property} property is only supported on OS version #{over} or later on #{pid}") if
208
+ Gem::Version.new(lim) < Gem::Version.new(ver)
209
+ end
210
+
175
211
  def skip_nexus_i2_image?
176
212
  skip("This property is not supported on Nexus 'I2' images") if
177
213
  Utils.nexus_i2_image
data/tests/test_ace.rb CHANGED
@@ -112,15 +112,20 @@ class TestAce < CiscoTestCase
112
112
  assert_equal(val, a.src_addr)
113
113
  assert_equal(val, a.dst_addr)
114
114
 
115
+ config_no_warn('object-group ip address my_addrgroup_ipv4')
116
+ config_no_warn('object-group ipv6 address my_addrgroup_ipv6')
115
117
  %w(ipv4 ipv6).each do |afi|
116
118
  val = "addrgroup my_addrgroup_#{afi}"
117
119
  a = ace_helper(afi, src_addr: val, dst_addr: val)
118
120
  assert_equal(val, a.src_addr)
119
121
  assert_equal(val, a.dst_addr)
120
122
  end
123
+ config_no_warn('no object-group ip address my_addrgroup_ipv4')
124
+ config_no_warn('no object-group ipv6 address my_addrgroup_ipv6')
121
125
  end
122
126
 
123
127
  def test_ports
128
+ config_no_warn('object-group ip port my_pg')
124
129
  %w(ipv4 ipv6).each do |afi|
125
130
  ['eq 2', 'neq 2', 'gt 2', 'lt 2',
126
131
  'portgroup my_pg'].each do |val|
@@ -129,6 +134,7 @@ class TestAce < CiscoTestCase
129
134
  assert_equal(val, a.dst_port)
130
135
  end
131
136
  end
137
+ config_no_warn('no object-group ip port my_pg')
132
138
  end
133
139
 
134
140
  def test_dscp
@@ -211,13 +211,7 @@ class TestBfdGlobal < CiscoTestCase
211
211
  def test_interval
212
212
  bg = BfdGlobal.new
213
213
  arr = %w(100 100 25)
214
- if validate_property_excluded?('bfd_global', 'interval')
215
- assert_nil(bg.interval)
216
- assert_raises(Cisco::UnsupportedError) do
217
- bg.interval = arr
218
- end
219
- return
220
- end
214
+ skip_incompat_version?('bfd_global', 'interval')
221
215
  assert_equal(bg.default_interval, bg.interval)
222
216
  bg.interval = arr
223
217
  assert_equal(arr, bg.interval)
data/tests/test_bgp_af.rb CHANGED
@@ -169,9 +169,9 @@ class TestBgpAF < CiscoTestCase
169
169
  # triggers a version check below.
170
170
  if expect == :runtime
171
171
  case Platform.image_version
172
- when /8.0/
172
+ when /8.0|8.1/
173
173
  expect = :success
174
- when /I5.2/
174
+ when /I5.2|I5.3|I6/
175
175
  expect = :success if test == :maximum_paths || test == :maximum_paths_ibgp
176
176
  else
177
177
  expect = :CliError
@@ -0,0 +1,108 @@
1
+ # Copyright (c) 2017 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/bgp_af'
17
+ require_relative '../lib/cisco_node_utils/bgp_af_aggr_addr'
18
+
19
+ include Cisco
20
+ # TestBgpAfAggrAddr - Minitest for BgpAFAggrAddr class
21
+ class TestBgpAfAggrAddr < CiscoTestCase
22
+ @@pre_clean_needed = true # rubocop:disable Style/ClassVars
23
+
24
+ def setup
25
+ super
26
+ config('no feature bgp')
27
+ remove_all_vrfs if @@pre_clean_needed
28
+ @@pre_clean_needed = false # rubocop:disable Style/ClassVars
29
+ end
30
+
31
+ def teardown
32
+ config('no feature bgp')
33
+ remove_all_vrfs
34
+ super
35
+ end
36
+
37
+ def test_collection_empty
38
+ node.cache_flush
39
+ aas = RouterBgpAFAggrAddr.aas
40
+ assert_empty(aas, 'BGP AF Aggregate Address collection is not empty')
41
+ end
42
+
43
+ def test_collection_not_empty
44
+ bgp_af = []
45
+ bgp_af_aa = []
46
+ %w(default red).each do |vrf|
47
+ [%w(ipv4 unicast), %w(ipv6 unicast),
48
+ %w(ipv4 multicast), %w(ipv6 multicast)].each do |af|
49
+ bgp_af.push(RouterBgpAF.new(55, vrf, af))
50
+ if af[0] == 'ipv4'
51
+ ['1.1.1.0/24', '2.2.2.2/32'].each do |addr|
52
+ bgp_af_aa.push(RouterBgpAFAggrAddr.new(55, vrf, af, addr))
53
+ end
54
+ else
55
+ ['2001::12/128', '2000::31/128'].each do |addr|
56
+ bgp_af_aa.push(RouterBgpAFAggrAddr.new(55, vrf, af, addr))
57
+ end
58
+ end
59
+ assert_equal(2, RouterBgpAFAggrAddr.aas[55][vrf][af].size)
60
+ end
61
+ end
62
+ end
63
+
64
+ def test_destroy
65
+ af = %w(ipv4 unicast)
66
+ RouterBgpAF.new(55, 'red', af)
67
+ obj = RouterBgpAFAggrAddr.new(55, 'red', af, '1.1.1.0/24')
68
+ aas = RouterBgpAFAggrAddr.aas[55]['red'][af]
69
+ assert_equal(1, aas.size)
70
+ obj.destroy
71
+ aas = RouterBgpAFAggrAddr.aas[55]['red'][af]
72
+ assert_empty(aas, 'BGP AF Aggregate Address collection is not empty')
73
+ end
74
+
75
+ def aa_helper(props)
76
+ af = %w(ipv4 unicast)
77
+ RouterBgpAF.new(55, 'red', af)
78
+ obj = RouterBgpAFAggrAddr.new(55, 'red', af, '1.1.1.0/24')
79
+ test_hash = {
80
+ advertise_map: obj.default_advertise_map,
81
+ as_set: obj.default_as_set,
82
+ attribute_map: obj.default_attribute_map,
83
+ summary_only: obj.default_summary_only,
84
+ suppress_map: obj.default_suppress_map,
85
+ }.merge!(props)
86
+ obj.aa_set(test_hash)
87
+ obj
88
+ end
89
+
90
+ def test_aa
91
+ obj = aa_helper(advertise_map: 'adm',
92
+ as_set: true,
93
+ attribute_map: 'atm',
94
+ suppress_map: 'sum')
95
+ assert(obj.as_set)
96
+ assert_equal('adm', obj.advertise_map)
97
+ assert_equal('atm', obj.attribute_map)
98
+ assert_equal('sum', obj.suppress_map)
99
+ obj = aa_helper(advertise_map: 'adm',
100
+ as_set: true,
101
+ attribute_map: 'atm',
102
+ summary_only: true)
103
+ assert(obj.as_set)
104
+ assert(obj.summary_only)
105
+ assert_equal('adm', obj.advertise_map)
106
+ assert_equal('atm', obj.attribute_map)
107
+ end
108
+ end