~bkerensa/ubuntu/raring/puppet/new-upstream-release

« back to all changes in this revision

Viewing changes to spec/unit/util/network_device/cisco/device_spec.rb

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2011-07-25 01:00:37 UTC
  • mfrom: (1.1.24 upstream) (3.1.25 sid)
  • Revision ID: james.westby@ubuntu.com-20110725010037-875vuxs10eboqgw3
Tags: 2.7.1-1ubuntu1
* Merge from debian unstable.  Remaining changes:
  - debian/puppetmaster-passenger.postinst: Use cacrl instead of hostcrl to
    set the location of the CRL in apache2 configuration. Fix apache2
    configuration on upgrade as well (LP: #641001)
  - move all puppet dependencies to puppet-common since all the code
    actually located in puppet-common.
  - move libagueas from a recommend to a dependency.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env rspec
 
2
 
 
3
require File.dirname(__FILE__) + '/../../../../spec_helper'
 
4
 
 
5
require 'puppet/util/network_device/cisco/device'
 
6
 
 
7
describe Puppet::Util::NetworkDevice::Cisco::Device do
 
8
  before(:each) do
 
9
    @transport = stub_everything 'transport', :is_a? => true, :command => ""
 
10
    @cisco = Puppet::Util::NetworkDevice::Cisco::Device.new("telnet://user:password@localhost:23/")
 
11
    @cisco.transport = @transport
 
12
  end
 
13
 
 
14
  describe "when creating the device" do
 
15
    it "should find the enable password from the url" do
 
16
      cisco = Puppet::Util::NetworkDevice::Cisco::Device.new("telnet://user:password@localhost:23/?enable=enable_password")
 
17
      cisco.enable_password.should == "enable_password"
 
18
    end
 
19
 
 
20
    it "should find the enable password from the options" do
 
21
      cisco = Puppet::Util::NetworkDevice::Cisco::Device.new("telnet://user:password@localhost:23/?enable=enable_password", :enable_password => "mypass")
 
22
      cisco.enable_password.should == "mypass"
 
23
    end
 
24
  end
 
25
 
 
26
  describe "when connecting to the physical device" do
 
27
    it "should connect to the transport" do
 
28
      @transport.expects(:connect)
 
29
      @cisco.command
 
30
    end
 
31
 
 
32
    it "should attempt to login" do
 
33
      @cisco.expects(:login)
 
34
      @cisco.command
 
35
    end
 
36
 
 
37
    it "should tell the device to not page" do
 
38
      @transport.expects(:command).with("terminal length 0")
 
39
      @cisco.command
 
40
    end
 
41
 
 
42
    it "should enter the enable password if returned prompt is not privileged" do
 
43
      @transport.stubs(:command).yields("Switch>").returns("")
 
44
      @cisco.expects(:enable)
 
45
      @cisco.command
 
46
    end
 
47
 
 
48
    it "should find device capabilities" do
 
49
      @cisco.expects(:find_capabilities)
 
50
      @cisco.command
 
51
    end
 
52
 
 
53
    it "should execute given command" do
 
54
      @transport.expects(:command).with("mycommand")
 
55
      @cisco.command("mycommand")
 
56
    end
 
57
 
 
58
    it "should yield to the command block if one is provided" do
 
59
      @transport.expects(:command).with("mycommand")
 
60
      @cisco.command do |c|
 
61
        c.command("mycommand")
 
62
      end
 
63
    end
 
64
 
 
65
    it "should close the device transport" do
 
66
      @transport.expects(:close)
 
67
      @cisco.command
 
68
    end
 
69
 
 
70
    describe "when login in" do
 
71
      it "should not login if transport handles login" do
 
72
        @transport.expects(:handles_login?).returns(true)
 
73
        @transport.expects(:command).never
 
74
        @transport.expects(:expect).never
 
75
        @cisco.login
 
76
      end
 
77
 
 
78
      it "should send username if one has been provided" do
 
79
        @transport.expects(:command).with("user", :prompt => /^Password:/)
 
80
        @cisco.login
 
81
      end
 
82
 
 
83
      it "should send password after the username" do
 
84
        @transport.expects(:command).with("user", :prompt => /^Password:/)
 
85
        @transport.expects(:command).with("password")
 
86
        @cisco.login
 
87
      end
 
88
 
 
89
      it "should expect the Password: prompt if no user was sent" do
 
90
        @cisco.url.user = ''
 
91
        @transport.expects(:expect).with(/^Password:/)
 
92
        @transport.expects(:command).with("password")
 
93
        @cisco.login
 
94
      end
 
95
    end
 
96
 
 
97
    describe "when entering enable password" do
 
98
      it "should raise an error if no enable password has been set" do
 
99
        @cisco.enable_password = nil
 
100
        lambda{ @cisco.enable }.should raise_error
 
101
      end
 
102
 
 
103
      it "should send the enable command and expect an enable prompt" do
 
104
        @cisco.enable_password = 'mypass'
 
105
        @transport.expects(:command).with("enable", :prompt => /^Password:/)
 
106
        @cisco.enable
 
107
      end
 
108
 
 
109
      it "should send the enable password" do
 
110
        @cisco.enable_password = 'mypass'
 
111
        @transport.stubs(:command).with("enable", :prompt => /^Password:/)
 
112
        @transport.expects(:command).with("mypass")
 
113
        @cisco.enable
 
114
      end
 
115
    end
 
116
  end
 
117
 
 
118
  describe "when finding network device capabilities" do
 
119
    it "should try to execute sh vlan brief" do
 
120
      @transport.expects(:command).with("sh vlan brief").returns("")
 
121
      @cisco.find_capabilities
 
122
    end
 
123
 
 
124
    it "should detect errors" do
 
125
      @transport.stubs(:command).with("sh vlan brief").returns(<<eos)
 
126
Switch#sh vlan brief  
 
127
% Ambiguous command:  "sh vlan brief"
 
128
Switch#
 
129
eos
 
130
 
 
131
      @cisco.find_capabilities
 
132
      @cisco.should_not be_support_vlan_brief
 
133
    end
 
134
  end
 
135
 
 
136
 
 
137
  {
 
138
    "Fa 0/1" => "FastEthernet0/1",
 
139
    "Fa0/1" => "FastEthernet0/1",
 
140
    "FastEth 0/1" => "FastEthernet0/1",
 
141
    "Gi1" => "GigEthernet1",
 
142
    "Di9" => "Dialer9",
 
143
    "Ethernet 0/0/1" => "Ethernet0/0/1",
 
144
    "E0" => "Ethernet0",
 
145
    "ATM 0/1.1" => "ATM0/1.1",
 
146
    "VLAN99" => "VLAN99"
 
147
  }.each do |input,expected|
 
148
    it "should canonicalize #{input} to #{expected}", :'fails_on_ruby_1.9.2' => true do
 
149
      @cisco.canonalize_ifname(input).should == expected
 
150
    end
 
151
  end
 
152
 
 
153
  describe "when updating device vlans" do
 
154
    describe "when removing a vlan" do
 
155
      it "should issue the no vlan command" do
 
156
        @transport.expects(:command).with("no vlan 200")
 
157
        @cisco.update_vlan("200", {:ensure => :present, :name => "200"}, { :ensure=> :absent})
 
158
      end
 
159
    end
 
160
 
 
161
    describe "when updating a vlan" do
 
162
      it "should issue the vlan command to enter global vlan modifications" do
 
163
        @transport.expects(:command).with("vlan 200")
 
164
        @cisco.update_vlan("200", {:ensure => :present, :name => "200"}, { :ensure=> :present, :name => "200"})
 
165
      end
 
166
 
 
167
      it "should issue the name command to modify the vlan description" do
 
168
        @transport.expects(:command).with("name myvlan")
 
169
        @cisco.update_vlan("200", {:ensure => :present, :name => "200"}, { :ensure=> :present, :name => "200", :description => "myvlan"})
 
170
      end
 
171
    end
 
172
  end
 
173
 
 
174
  describe "when parsing interface" do
 
175
 
 
176
    it "should parse interface output" do
 
177
      @cisco.expects(:parse_interface).returns({ :ensure => :present })
 
178
 
 
179
      @cisco.interface("FastEthernet0/1").should == { :ensure => :present }
 
180
    end
 
181
 
 
182
    it "should parse trunking and merge results" do
 
183
      @cisco.stubs(:parse_interface).returns({ :ensure => :present })
 
184
      @cisco.expects(:parse_trunking).returns({ :native_vlan => "100" })
 
185
 
 
186
      @cisco.interface("FastEthernet0/1").should == { :ensure => :present, :native_vlan => "100" }
 
187
    end
 
188
 
 
189
    it "should return an absent interface if parse_interface returns nothing" do
 
190
      @cisco.stubs(:parse_interface).returns({})
 
191
 
 
192
      @cisco.interface("FastEthernet0/1").should == { :ensure => :absent }
 
193
    end
 
194
 
 
195
    it "should parse ip address information and merge results" do
 
196
      @cisco.stubs(:parse_interface).returns({ :ensure => :present })
 
197
      @cisco.expects(:parse_interface_config).returns({ :ipaddress => [24,IPAddr.new('192.168.0.24'), nil] })
 
198
 
 
199
      @cisco.interface("FastEthernet0/1").should == { :ensure => :present, :ipaddress => [24,IPAddr.new('192.168.0.24'), nil] }
 
200
    end
 
201
 
 
202
    it "should parse the sh interface command" do
 
203
      @transport.stubs(:command).with("sh interface FastEthernet0/1").returns(<<eos)
 
204
Switch#sh interfaces FastEthernet 0/1
 
205
FastEthernet0/1 is down, line protocol is down 
 
206
  Hardware is Fast Ethernet, address is 00d0.bbe2.19c1 (bia 00d0.bbe2.19c1)
 
207
  MTU 1500 bytes, BW 100000 Kbit, DLY 100 usec, 
 
208
     reliability 255/255, txload 1/255, rxload 1/255
 
209
  Encapsulation ARPA, loopback not set
 
210
  Keepalive not set
 
211
  Auto-duplex , Auto Speed , 100BaseTX/FX
 
212
  ARP type: ARPA, ARP Timeout 04:00:00
 
213
  Last input never, output 5d04h, output hang never
 
214
  Last clearing of "show interface" counters never
 
215
  Queueing strategy: fifo
 
216
  Output queue 0/40, 0 drops; input queue 0/75, 0 drops
 
217
  5 minute input rate 0 bits/sec, 0 packets/sec
 
218
  5 minute output rate 0 bits/sec, 0 packets/sec
 
219
     580 packets input, 54861 bytes
 
220
     Received 6 broadcasts, 0 runts, 0 giants, 0 throttles
 
221
     0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored
 
222
     0 watchdog, 1 multicast
 
223
     0 input packets with dribble condition detected
 
224
     845 packets output, 80359 bytes, 0 underruns
 
225
     0 output errors, 0 collisions, 1 interface resets
 
226
     0 babbles, 0 late collision, 0 deferred
 
227
     0 lost carrier, 0 no carrier
 
228
     0 output buffer failures, 0 output buffers swapped out
 
229
Switch#
 
230
eos
 
231
 
 
232
      @cisco.parse_interface("FastEthernet0/1").should == { :ensure => :absent, :duplex => :auto, :speed => :auto }
 
233
    end
 
234
 
 
235
    it "should be able to parse the sh vlan brief command output", :'fails_on_ruby_1.9.2' => true do
 
236
      @cisco.stubs(:support_vlan_brief?).returns(true)
 
237
      @transport.stubs(:command).with("sh vlan brief").returns(<<eos)
 
238
Switch#sh vlan brief
 
239
VLAN Name                             Status    Ports
 
240
---- -------------------------------- --------- -------------------------------
 
241
1    default                          active    Fa0/3, Fa0/4, Fa0/5, Fa0/6,
 
242
                                                Fa0/7, Fa0/8, Fa0/9, Fa0/10,
 
243
                                                Fa0/11, Fa0/12, Fa0/13, Fa0/14,
 
244
                                                Fa0/15, Fa0/16, Fa0/17, Fa0/18,
 
245
                                                Fa0/23, Fa0/24
 
246
10   VLAN0010                         active    
 
247
100  management                       active    Fa0/1, Fa0/2
 
248
Switch#
 
249
eos
 
250
 
 
251
      @cisco.parse_vlans.should == {"100"=>{:status=>"active", :interfaces=>["FastEthernet0/1", "FastEthernet0/2"], :description=>"management", :name=>"100"}, "1"=>{:status=>"active", :interfaces=>["FastEthernet0/3", "FastEthernet0/4", "FastEthernet0/5", "FastEthernet0/6", "FastEthernet0/7", "FastEthernet0/8", "FastEthernet0/9", "FastEthernet0/10", "FastEthernet0/11", "FastEthernet0/12", "FastEthernet0/13", "FastEthernet0/14", "FastEthernet0/15", "FastEthernet0/16", "FastEthernet0/17", "FastEthernet0/18", "FastEthernet0/23", "FastEthernet0/24"], :description=>"default", :name=>"1"}, "10"=>{:status=>"active", :interfaces=>[], :description=>"VLAN0010", :name=>"10"}}
 
252
    end
 
253
 
 
254
    it "should parse trunk switchport information" do
 
255
      @transport.stubs(:command).with("sh interface FastEthernet0/21 switchport").returns(<<eos)
 
256
Switch#sh interfaces FastEthernet 0/21 switchport
 
257
Name: Fa0/21
 
258
Switchport: Enabled
 
259
Administrative mode: trunk
 
260
Operational Mode: trunk
 
261
Administrative Trunking Encapsulation: dot1q
 
262
Operational Trunking Encapsulation: dot1q
 
263
Negotiation of Trunking: Disabled
 
264
Access Mode VLAN: 0 ((Inactive))
 
265
Trunking Native Mode VLAN: 1 (default)
 
266
Trunking VLANs Enabled: ALL
 
267
Trunking VLANs Active: 1,10,100
 
268
Pruning VLANs Enabled: 2-1001
 
269
 
 
270
Priority for untagged frames: 0
 
271
Override vlan tag priority: FALSE
 
272
Voice VLAN: none
 
273
Appliance trust: none
 
274
Self Loopback: No
 
275
Switch#
 
276
eos
 
277
 
 
278
      @cisco.parse_trunking("FastEthernet0/21").should == { :mode => :trunk, :encapsulation => :dot1q, :allowed_trunk_vlans=>:all, }
 
279
    end
 
280
 
 
281
    it "should parse trunk switchport information with allowed vlans" do
 
282
      @transport.stubs(:command).with("sh interface GigabitEthernet 0/1 switchport").returns(<<eos)
 
283
c2960#sh interfaces GigabitEthernet 0/1 switchport 
 
284
Name: Gi0/1
 
285
Switchport: Enabled
 
286
Administrative Mode: trunk
 
287
Operational Mode: trunk
 
288
Administrative Trunking Encapsulation: dot1q
 
289
Operational Trunking Encapsulation: dot1q
 
290
Negotiation of Trunking: On
 
291
Access Mode VLAN: 1 (default)
 
292
Trunking Native Mode VLAN: 1 (default)
 
293
Administrative Native VLAN tagging: enabled
 
294
Voice VLAN: none
 
295
Administrative private-vlan host-association: none 
 
296
Administrative private-vlan mapping: none 
 
297
Administrative private-vlan trunk native VLAN: none
 
298
Administrative private-vlan trunk Native VLAN tagging: enabled
 
299
Administrative private-vlan trunk encapsulation: dot1q
 
300
Administrative private-vlan trunk normal VLANs: none
 
301
Administrative private-vlan trunk associations: none
 
302
Administrative private-vlan trunk mappings: none
 
303
Operational private-vlan: none
 
304
Trunking VLANs Enabled: 1,99
 
305
Pruning VLANs Enabled: 2-1001
 
306
Capture Mode Disabled
 
307
Capture VLANs Allowed: ALL
 
308
 
 
309
Protected: false
 
310
Unknown unicast blocked: disabled
 
311
Unknown multicast blocked: disabled
 
312
Appliance trust: none
 
313
c2960#
 
314
eos
 
315
 
 
316
      @cisco.parse_trunking("GigabitEthernet 0/1").should == { :mode => :trunk, :encapsulation => :dot1q, :allowed_trunk_vlans=>"1,99", }
 
317
    end
 
318
 
 
319
    it "should parse access switchport information" do
 
320
      @transport.stubs(:command).with("sh interface FastEthernet0/1 switchport").returns(<<eos)
 
321
Switch#sh interfaces FastEthernet 0/1 switchport  
 
322
Name: Fa0/1
 
323
Switchport: Enabled
 
324
Administrative mode: static access
 
325
Operational Mode: static access
 
326
Administrative Trunking Encapsulation: isl
 
327
Operational Trunking Encapsulation: isl
 
328
Negotiation of Trunking: Disabled
 
329
Access Mode VLAN: 100 (SHDSL)
 
330
Trunking Native Mode VLAN: 1 (default)
 
331
Trunking VLANs Enabled: NONE
 
332
Pruning VLANs Enabled: NONE
 
333
 
 
334
Priority for untagged frames: 0
 
335
Override vlan tag priority: FALSE
 
336
Voice VLAN: none
 
337
Appliance trust: none
 
338
Self Loopback: No
 
339
Switch#
 
340
eos
 
341
 
 
342
      @cisco.parse_trunking("FastEthernet0/1").should == { :mode => :access, :native_vlan => "100" }
 
343
    end
 
344
 
 
345
    it "should parse ip addresses" do
 
346
      @transport.stubs(:command).with("sh running-config interface Vlan 1 | begin interface").returns(<<eos)
 
347
router#sh running-config interface Vlan 1 | begin interface
 
348
interface Vlan1
 
349
 description $ETH-SW-LAUNCH$$INTF-INFO-HWIC 4ESW$$FW_INSIDE$
 
350
 ip address 192.168.0.24 255.255.255.0 secondary
 
351
 ip address 192.168.0.1 255.255.255.0
 
352
 ip access-group 100 in
 
353
 no ip redirects
 
354
 no ip proxy-arp
 
355
 ip nbar protocol-discovery
 
356
 ip dns view-group dow
 
357
 ip nat inside
 
358
 ip virtual-reassembly
 
359
 ip route-cache flow
 
360
 ipv6 address 2001:7A8:71C1::/64 eui-64
 
361
 ipv6 enable
 
362
 ipv6 traffic-filter DENY-ACL6 out
 
363
 ipv6 mtu 1280
 
364
 ipv6 nd prefix 2001:7A8:71C1::/64
 
365
 ipv6 nd ra interval 60
 
366
 ipv6 nd ra lifetime 180
 
367
 ipv6 verify unicast reverse-path
 
368
 ipv6 inspect STD6 out
 
369
end
 
370
 
 
371
router#
 
372
eos
 
373
      @cisco.parse_interface_config("Vlan 1").should == {:ipaddress=>[[24, IPAddr.new('192.168.0.24'), 'secondary'],
 
374
                                                                      [24, IPAddr.new('192.168.0.1'), nil],
 
375
                                                                      [64, IPAddr.new('2001:07a8:71c1::'), "eui-64"]]}
 
376
    end
 
377
 
 
378
    it "should parse etherchannel membership" do
 
379
      @transport.stubs(:command).with("sh running-config interface Gi0/17 | begin interface").returns(<<eos)
 
380
c2960#sh running-config interface Gi0/17 | begin interface
 
381
interface GigabitEthernet0/17
 
382
 description member of Po1
 
383
 switchport mode access
 
384
 channel-protocol lacp
 
385
 channel-group 1 mode passive
 
386
 spanning-tree portfast
 
387
 spanning-tree bpduguard enable
 
388
end
 
389
 
 
390
c2960#
 
391
eos
 
392
      @cisco.parse_interface_config("Gi0/17").should == {:etherchannel=>"1"}
 
393
    end
 
394
  end
 
395
 
 
396
  describe "when finding device facts" do
 
397
    it "should delegate to the cisco facts entity" do
 
398
      facts = stub 'facts'
 
399
      Puppet::Util::NetworkDevice::Cisco::Facts.expects(:new).returns(facts)
 
400
 
 
401
      facts.expects(:retrieve).returns(:facts)
 
402
 
 
403
      @cisco.facts.should == :facts
 
404
    end
 
405
  end
 
406
 
 
407
end
 
408