summaryrefslogtreecommitdiffstats
path: root/spec
diff options
context:
space:
mode:
authorPieter van de Bruggen <pieter@puppetlabs.com>2011-04-18 13:40:31 -0700
committerPieter van de Bruggen <pieter@puppetlabs.com>2011-04-18 14:08:32 -0700
commit07b677c5f6af8def03c5c30393fd83bc3986239a (patch)
treeb28d3376b4ea835a2348ebfea898d674cb593e34 /spec
parentb142973a94ced6c0ff43da882189abe806c18c68 (diff)
downloadpuppet-07b677c5f6af8def03c5c30393fd83bc3986239a.tar.gz
puppet-07b677c5f6af8def03c5c30393fd83bc3986239a.tar.xz
puppet-07b677c5f6af8def03c5c30393fd83bc3986239a.zip
Merge remote-tracking branch 'community/feature/puppet-device' into 2.7.x
Reviewed-By: Mike Stahnke
Diffstat (limited to 'spec')
-rwxr-xr-xspec/integration/transaction_spec.rb56
-rw-r--r--spec/unit/application/device_spec.rb349
-rw-r--r--spec/unit/indirector/facts/network_device_spec.rb89
-rw-r--r--spec/unit/provider/cisco_spec.rb16
-rwxr-xr-xspec/unit/provider/interface/cisco_spec.rb20
-rwxr-xr-xspec/unit/provider/network_device_spec.rb21
-rwxr-xr-xspec/unit/provider/vlan/cisco_spec.rb20
-rwxr-xr-xspec/unit/resource/catalog_spec.rb1
-rwxr-xr-xspec/unit/transaction_spec.rb18
-rwxr-xr-xspec/unit/type/interface_spec.rb5
-rwxr-xr-xspec/unit/type/schedule_spec.rb8
-rwxr-xr-xspec/unit/type/vlan_spec.rb5
-rwxr-xr-xspec/unit/util/network_device/cisco/device_spec.rb137
-rw-r--r--spec/unit/util/network_device/cisco/facts_spec.rb63
-rw-r--r--spec/unit/util/network_device/config_spec.rb102
-rwxr-xr-xspec/unit/util/network_device/transport/ssh_spec.rb8
-rw-r--r--spec/unit/util/network_device_spec.rb46
17 files changed, 805 insertions, 159 deletions
diff --git a/spec/integration/transaction_spec.rb b/spec/integration/transaction_spec.rb
index 41a1ebac3..78d62fc51 100755
--- a/spec/integration/transaction_spec.rb
+++ b/spec/integration/transaction_spec.rb
@@ -75,6 +75,62 @@ describe Puppet::Transaction do
transaction.evaluate
end
+ it "should not apply device resources on normal host" do
+ catalog = Puppet::Resource::Catalog.new
+ resource = Puppet::Type.type(:interface).new :name => "FastEthernet 0/1"
+ catalog.add_resource resource
+
+ transaction = Puppet::Transaction.new(catalog)
+ transaction.for_network_device = false
+
+ transaction.expects(:apply).never.with(resource, nil)
+
+ transaction.evaluate
+ transaction.resource_status(resource).should be_skipped
+ end
+
+ it "should not apply host resources on device" do
+ catalog = Puppet::Resource::Catalog.new
+ resource = Puppet::Type.type(:file).new :path => "/foo/bar", :backup => false
+ catalog.add_resource resource
+
+ transaction = Puppet::Transaction.new(catalog)
+ transaction.for_network_device = true
+
+ transaction.expects(:apply).never.with(resource, nil)
+
+ transaction.evaluate
+ transaction.resource_status(resource).should be_skipped
+ end
+
+ it "should apply device resources on device" do
+ catalog = Puppet::Resource::Catalog.new
+ resource = Puppet::Type.type(:interface).new :name => "FastEthernet 0/1"
+ catalog.add_resource resource
+
+ transaction = Puppet::Transaction.new(catalog)
+ transaction.for_network_device = true
+
+ transaction.expects(:apply).with(resource, nil)
+
+ transaction.evaluate
+ transaction.resource_status(resource).should_not be_skipped
+ end
+
+ it "should apply resources appliable on host and device on a device" do
+ catalog = Puppet::Resource::Catalog.new
+ resource = Puppet::Type.type(:schedule).new :name => "test"
+ catalog.add_resource resource
+
+ transaction = Puppet::Transaction.new(catalog)
+ transaction.for_network_device = true
+
+ transaction.expects(:apply).with(resource, nil)
+
+ transaction.evaluate
+ transaction.resource_status(resource).should_not be_skipped
+ end
+
# Verify that one component requiring another causes the contained
# resources in the requiring component to get refreshed.
it "should propagate events from a contained resource through its container to its dependent container's contained resources" do
diff --git a/spec/unit/application/device_spec.rb b/spec/unit/application/device_spec.rb
new file mode 100644
index 000000000..c3c220918
--- /dev/null
+++ b/spec/unit/application/device_spec.rb
@@ -0,0 +1,349 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/application/device'
+require 'puppet/util/network_device/config'
+require 'ostruct'
+require 'puppet/configurer'
+
+describe Puppet::Application::Device do
+ before :each do
+ @device = Puppet::Application[:device]
+# @device.stubs(:puts)
+ @device.preinit
+ Puppet::Util::Log.stubs(:newdestination)
+ Puppet::Util::Log.stubs(:level=)
+
+ Puppet::Node.stubs(:terminus_class=)
+ Puppet::Node.stubs(:cache_class=)
+ Puppet::Node::Facts.stubs(:terminus_class=)
+ end
+
+ it "should operate in agent run_mode" do
+ @device.class.run_mode.name.should == :agent
+ end
+
+ it "should ask Puppet::Application to parse Puppet configuration file" do
+ @device.should_parse_config?.should be_true
+ end
+
+ it "should declare a main command" do
+ @device.should respond_to(:main)
+ end
+
+ it "should declare a preinit block" do
+ @device.should respond_to(:preinit)
+ end
+
+ describe "in preinit" do
+ before :each do
+ @device.stubs(:trap)
+ end
+
+ it "should catch INT" do
+ @device.expects(:trap).with { |arg,block| arg == :INT }
+
+ @device.preinit
+ end
+ end
+
+ describe "when handling options" do
+ before do
+ @device.command_line.stubs(:args).returns([])
+ end
+
+ [:centrallogging, :debug, :verbose,].each do |option|
+ it "should declare handle_#{option} method" do
+ @device.should respond_to("handle_#{option}".to_sym)
+ end
+
+ it "should store argument value when calling handle_#{option}" do
+ @device.options.expects(:[]=).with(option, 'arg')
+ @device.send("handle_#{option}".to_sym, 'arg')
+ end
+ end
+
+ it "should set waitforcert to 0 with --onetime and if --waitforcert wasn't given" do
+ Puppet[:onetime] = true
+ Puppet::SSL::Host.any_instance.expects(:wait_for_cert).with(0)
+ @device.setup_host
+ end
+
+ it "should use supplied waitforcert when --onetime is specified" do
+ Puppet[:onetime] = true
+ @device.handle_waitforcert(60)
+ Puppet::SSL::Host.any_instance.expects(:wait_for_cert).with(60)
+ @device.setup_host
+ end
+
+ it "should use a default value for waitforcert when --onetime and --waitforcert are not specified" do
+ Puppet::SSL::Host.any_instance.expects(:wait_for_cert).with(120)
+ @device.setup_host
+ end
+
+ it "should set the log destination with --logdest" do
+ @device.options.stubs(:[]=).with { |opt,val| opt == :setdest }
+ Puppet::Log.expects(:newdestination).with("console")
+
+ @device.handle_logdest("console")
+ end
+
+ it "should put the setdest options to true" do
+ @device.options.expects(:[]=).with(:setdest,true)
+
+ @device.handle_logdest("console")
+ end
+
+ it "should parse the log destination from the command line" do
+ @device.command_line.stubs(:args).returns(%w{--logdest /my/file})
+
+ Puppet::Util::Log.expects(:newdestination).with("/my/file")
+
+ @device.parse_options
+ end
+
+ it "should store the waitforcert options with --waitforcert" do
+ @device.options.expects(:[]=).with(:waitforcert,42)
+
+ @device.handle_waitforcert("42")
+ end
+
+ it "should set args[:Port] with --port" do
+ @device.handle_port("42")
+ @device.args[:Port].should == "42"
+ end
+
+ end
+
+ describe "during setup" do
+ before :each do
+ @device.options.stubs(:[])
+ Puppet.stubs(:info)
+ FileTest.stubs(:exists?).returns(true)
+ Puppet[:libdir] = "/dev/null/lib"
+ Puppet::SSL::Host.stubs(:ca_location=)
+ Puppet::Transaction::Report.stubs(:terminus_class=)
+ Puppet::Resource::Catalog.stubs(:terminus_class=)
+ Puppet::Resource::Catalog.stubs(:cache_class=)
+ Puppet::Node::Facts.stubs(:terminus_class=)
+ @host = stub_everything 'host'
+ Puppet::SSL::Host.stubs(:new).returns(@host)
+ Puppet.stubs(:settraps)
+ end
+
+ it "should call setup_logs" do
+ @device.expects(:setup_logs)
+ @device.setup
+ end
+
+ describe "when setting up logs" do
+ before :each do
+ Puppet::Util::Log.stubs(:newdestination)
+ end
+
+ it "should set log level to debug if --debug was passed" do
+ @device.options.stubs(:[]).with(:debug).returns(true)
+
+ Puppet::Util::Log.expects(:level=).with(:debug)
+
+ @device.setup_logs
+ end
+
+ it "should set log level to info if --verbose was passed" do
+ @device.options.stubs(:[]).with(:verbose).returns(true)
+
+ Puppet::Util::Log.expects(:level=).with(:info)
+
+ @device.setup_logs
+ end
+
+ [:verbose, :debug].each do |level|
+ it "should set console as the log destination with level #{level}" do
+ @device.options.stubs(:[]).with(level).returns(true)
+
+ Puppet::Util::Log.expects(:newdestination).with(:console)
+
+ @device.setup_logs
+ end
+ end
+
+ it "should set syslog as the log destination if no --logdest" do
+ @device.options.stubs(:[]).with(:setdest).returns(false)
+
+ Puppet::Util::Log.expects(:newdestination).with(:syslog)
+
+ @device.setup_logs
+ end
+
+ end
+
+ it "should set a central log destination with --centrallogs" do
+ @device.options.stubs(:[]).with(:centrallogs).returns(true)
+ Puppet[:server] = "puppet.reductivelabs.com"
+ Puppet::Util::Log.stubs(:newdestination).with(:syslog)
+
+ Puppet::Util::Log.expects(:newdestination).with("puppet.reductivelabs.com")
+
+ @device.setup
+ end
+
+ it "should use :main, :agent, :device and :ssl config" do
+ Puppet.settings.expects(:use).with(:main, :agent, :device, :ssl)
+
+ @device.setup
+ end
+
+ it "should install a remote ca location" do
+ Puppet::SSL::Host.expects(:ca_location=).with(:remote)
+
+ @device.setup
+ end
+
+ it "should tell the report handler to use REST" do
+ Puppet::Transaction::Report.indirection.expects(:terminus_class=).with(:rest)
+
+ @device.setup
+ end
+
+ it "should change the catalog_terminus setting to 'rest'" do
+ Puppet[:catalog_terminus] = :foo
+ @device.setup
+ Puppet[:catalog_terminus].should == :rest
+ end
+
+ it "should tell the catalog handler to use cache" do
+ Puppet::Resource::Catalog.indirection.expects(:cache_class=).with(:yaml)
+
+ @device.setup
+ end
+
+ it "should change the facts_terminus setting to 'network_device'" do
+ Puppet[:facts_terminus] = :foo
+
+ @device.setup
+ Puppet[:facts_terminus].should == :network_device
+ end
+ end
+
+ describe "when initializing each devices SSL" do
+ before(:each) do
+ @host = stub_everything 'host'
+ Puppet::SSL::Host.stubs(:new).returns(@host)
+ end
+
+ it "should create a new ssl host" do
+ Puppet::SSL::Host.expects(:new).returns(@host)
+ @device.setup_host
+ end
+
+ it "should wait for a certificate" do
+ @device.options.stubs(:[]).with(:waitforcert).returns(123)
+ @host.expects(:wait_for_cert).with(123)
+
+ @device.setup_host
+ end
+ end
+
+
+ describe "when running" do
+ before :each do
+ @device.options.stubs(:[]).with(:fingerprint).returns(false)
+ Puppet.stubs(:notice)
+ @device.options.stubs(:[]).with(:client)
+ Puppet::Util::NetworkDevice::Config.stubs(:devices).returns({})
+ end
+
+ it "should dispatch to main" do
+ @device.stubs(:main)
+ @device.run_command
+ end
+
+ it "should get the device list" do
+ device_hash = stub_everything 'device hash'
+ Puppet::Util::NetworkDevice::Config.expects(:devices).returns(device_hash)
+ @device.main
+ end
+
+ it "should exit if the device list is empty" do
+ @device.expects(:exit).with(1)
+ @device.main
+ end
+
+ describe "for each device" do
+ before(:each) do
+ Puppet[:vardir] = "/dummy"
+ Puppet[:confdir] = "/dummy"
+ Puppet[:certname] = "certname"
+ @device_hash = {
+ "device1" => OpenStruct.new(:name => "device1", :url => "url", :provider => "cisco"),
+ "device2" => OpenStruct.new(:name => "device2", :url => "url", :provider => "cisco"),
+ }
+ Puppet::Util::NetworkDevice::Config.stubs(:devices).returns(@device_hash)
+ Puppet.settings.stubs(:set_value)
+ Puppet.settings.stubs(:use)
+ @device.stubs(:setup_host)
+ Puppet::Util::NetworkDevice.stubs(:init)
+ @configurer = stub_everything 'configurer'
+ Puppet::Configurer.stubs(:new).returns(@configurer)
+ end
+
+ it "should set vardir to the device vardir" do
+ Puppet.settings.expects(:set_value).with(:vardir, "/dummy/devices/device1", :cli)
+ @device.main
+ end
+
+ it "should set confdir to the device confdir" do
+ Puppet.settings.expects(:set_value).with(:confdir, "/dummy/devices/device1", :cli)
+ @device.main
+ end
+
+ it "should set certname to the device certname" do
+ Puppet.settings.expects(:set_value).with(:certname, "device1", :cli)
+ Puppet.settings.expects(:set_value).with(:certname, "device2", :cli)
+ @device.main
+ end
+
+ it "should make sure all the required folders and files are created" do
+ Puppet.settings.expects(:use).with(:main, :agent, :ssl).twice
+ @device.main
+ end
+
+ it "should initialize the device singleton" do
+ Puppet::Util::NetworkDevice.expects(:init).with(@device_hash["device1"]).then.with(@device_hash["device2"])
+ @device.main
+ end
+
+ it "should setup the SSL context" do
+ @device.expects(:setup_host).twice
+ @device.main
+ end
+
+ it "should launch a configurer for this device" do
+ @configurer.expects(:run).twice
+ @device.main
+ end
+
+ [:vardir, :confdir].each do |setting|
+ it "should cleanup the #{setting} setting after the run" do
+ configurer = states('configurer').starts_as('notrun')
+ Puppet.settings.expects(:set_value).with(setting, "/dummy/devices/device1", :cli).when(configurer.is('notrun'))
+ @configurer.expects(:run).twice.then(configurer.is('run'))
+ Puppet.settings.expects(:set_value).with(setting, "/dummy", :cli).when(configurer.is('run'))
+
+ @device.main
+ end
+ end
+
+ it "should cleanup the certname setting after the run" do
+ configurer = states('configurer').starts_as('notrun')
+ Puppet.settings.expects(:set_value).with(:certname, "device1", :cli).when(configurer.is('notrun'))
+ @configurer.expects(:run).twice.then(configurer.is('run'))
+ Puppet.settings.expects(:set_value).with(:certname, "certname", :cli).when(configurer.is('run'))
+
+ @device.main
+ end
+
+ end
+ end
+end
diff --git a/spec/unit/indirector/facts/network_device_spec.rb b/spec/unit/indirector/facts/network_device_spec.rb
new file mode 100644
index 000000000..302a810e8
--- /dev/null
+++ b/spec/unit/indirector/facts/network_device_spec.rb
@@ -0,0 +1,89 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2007-9-23.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/facts/network_device'
+
+describe Puppet::Node::Facts::NetworkDevice do
+ it "should be a subclass of the Code terminus" do
+ Puppet::Node::Facts::NetworkDevice.superclass.should equal(Puppet::Indirector::Code)
+ end
+
+ it "should have documentation" do
+ Puppet::Node::Facts::NetworkDevice.doc.should_not be_nil
+ end
+
+ it "should be registered with the configuration store indirection" do
+ indirection = Puppet::Indirector::Indirection.instance(:facts)
+ Puppet::Node::Facts::NetworkDevice.indirection.should equal(indirection)
+ end
+
+ it "should have its name set to :facter" do
+ Puppet::Node::Facts::NetworkDevice.name.should == :network_device
+ end
+end
+
+describe Puppet::Node::Facts::NetworkDevice do
+ before :each do
+ @remote_device = stub 'remote_device', :facts => {}
+ Puppet::Util::NetworkDevice.stubs(:current).returns(@remote_device)
+ @device = Puppet::Node::Facts::NetworkDevice.new
+ @name = "me"
+ @request = stub 'request', :key => @name
+ end
+
+ describe Puppet::Node::Facts::NetworkDevice, " when finding facts" do
+ it "should return a Facts instance" do
+ @device.find(@request).should be_instance_of(Puppet::Node::Facts)
+ end
+
+ it "should return a Facts instance with the provided key as the name" do
+ @device.find(@request).name.should == @name
+ end
+
+ it "should return the device facts as the values in the Facts instance" do
+ @remote_device.expects(:facts).returns("one" => "two")
+ facts = @device.find(@request)
+ facts.values["one"].should == "two"
+ end
+
+ it "should add local facts" do
+ facts = Puppet::Node::Facts.new("foo")
+ Puppet::Node::Facts.expects(:new).returns facts
+ facts.expects(:add_local_facts)
+
+ @device.find(@request)
+ end
+
+ it "should convert all facts into strings" do
+ facts = Puppet::Node::Facts.new("foo")
+ Puppet::Node::Facts.expects(:new).returns facts
+ facts.expects(:stringify)
+
+ @device.find(@request)
+ end
+
+ it "should call the downcase hook" do
+ facts = Puppet::Node::Facts.new("foo")
+ Puppet::Node::Facts.expects(:new).returns facts
+ facts.expects(:downcase_if_necessary)
+
+ @device.find(@request)
+ end
+ end
+
+ describe Puppet::Node::Facts::NetworkDevice, " when saving facts" do
+ it "should fail" do
+ proc { @device.save(@facts) }.should raise_error(Puppet::DevError)
+ end
+ end
+
+ describe Puppet::Node::Facts::NetworkDevice, " when destroying facts" do
+ it "should fail" do
+ proc { @device.destroy(@facts) }.should raise_error(Puppet::DevError)
+ end
+ end
+end
diff --git a/spec/unit/provider/cisco_spec.rb b/spec/unit/provider/cisco_spec.rb
new file mode 100644
index 000000000..08320731c
--- /dev/null
+++ b/spec/unit/provider/cisco_spec.rb
@@ -0,0 +1,16 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/provider/cisco'
+
+describe Puppet::Provider::Cisco do
+ it "should implement a device class method" do
+ Puppet::Provider::Cisco.should respond_to(:device)
+ end
+
+ it "should create a cisco device instance" do
+ Puppet::Util::NetworkDevice::Cisco::Device.expects(:new).returns :device
+ Puppet::Provider::Cisco.device(:url).should == :device
+ end
+end \ No newline at end of file
diff --git a/spec/unit/provider/interface/cisco_spec.rb b/spec/unit/provider/interface/cisco_spec.rb
index d1f70609f..c18f87cf8 100755
--- a/spec/unit/provider/interface/cisco_spec.rb
+++ b/spec/unit/provider/interface/cisco_spec.rb
@@ -8,12 +8,13 @@ provider_class = Puppet::Type.type(:interface).provider(:cisco)
describe provider_class do
before do
+ @device = stub_everything 'device'
@resource = stub("resource", :name => "Fa0/1")
- @provider = provider_class.new(@resource)
+ @provider = provider_class.new(@device, @resource)
end
- it "should have a parent of Puppet::Provider::NetworkDevice" do
- provider_class.should < Puppet::Provider::NetworkDevice
+ it "should have a parent of Puppet::Provider::Cisco" do
+ provider_class.should < Puppet::Provider::Cisco
end
it "should have an instances method" do
@@ -22,31 +23,24 @@ describe provider_class do
describe "when looking up instances at prefetch" do
before do
- @device = stub_everything 'device'
- Puppet::Util::NetworkDevice::Cisco::Device.stubs(:new).returns(@device)
@device.stubs(:command).yields(@device)
end
- it "should initialize the network device with the given url" do
- Puppet::Util::NetworkDevice::Cisco::Device.expects(:new).with(:url).returns(@device)
- provider_class.lookup(:url, "Fa0/1")
- end
-
it "should delegate to the device interface fetcher" do
@device.expects(:interface)
- provider_class.lookup("", "Fa0/1")
+ provider_class.lookup(@device, "Fa0/1")
end
it "should return the given interface data" do
@device.expects(:interface).returns({ :description => "thisone", :mode => :access})
- provider_class.lookup("", "Fa0").should == {:description => "thisone", :mode => :access }
+ provider_class.lookup(@device, "Fa0").should == {:description => "thisone", :mode => :access }
end
end
describe "when an instance is being flushed" do
it "should call the device interface update method with current and past properties" do
- @instance = provider_class.new(:ensure => :present, :name => "Fa0/1", :description => "myinterface")
+ @instance = provider_class.new(@device, :ensure => :present, :name => "Fa0/1", :description => "myinterface")
@instance.description = "newdesc"
@instance.resource = @resource
@resource.stubs(:[]).with(:name).returns("Fa0/1")
diff --git a/spec/unit/provider/network_device_spec.rb b/spec/unit/provider/network_device_spec.rb
index 83d2bdc01..e2a87cf4e 100755
--- a/spec/unit/provider/network_device_spec.rb
+++ b/spec/unit/provider/network_device_spec.rb
@@ -3,10 +3,15 @@
require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/provider/network_device'
+require 'ostruct'
Puppet::Type.type(:vlan).provide :test, :parent => Puppet::Provider::NetworkDevice do
mk_resource_methods
- def self.lookup(device_url, name)
+ def self.lookup(device, name)
+ end
+
+ def self.device(url)
+ :device
end
end
@@ -34,7 +39,7 @@ describe provider_class do
end
it "should lookup an entry for each passed resource" do
- provider_class.expects(:lookup).with(nil, "200").returns nil
+ provider_class.expects(:lookup).with{ |device,value| value == "200" }.returns nil
provider_class.stubs(:new)
@resource.stubs(:provider=)
@@ -44,7 +49,7 @@ describe provider_class do
describe "resources that do not exist" do
it "should create a provider with :ensure => :absent" do
provider_class.stubs(:lookup).returns(nil)
- provider_class.expects(:new).with(:ensure => :absent).returns "myprovider"
+ provider_class.expects(:new).with(:device, :ensure => :absent).returns "myprovider"
@resource.expects(:provider=).with("myprovider")
provider_class.prefetch(@resources)
end
@@ -54,7 +59,7 @@ describe provider_class do
it "should create a provider with the results of the find and ensure at present" do
provider_class.stubs(:lookup).returns({ :name => "200", :description => "myvlan"})
- provider_class.expects(:new).with(:name => "200", :description => "myvlan", :ensure => :present).returns "myprovider"
+ provider_class.expects(:new).with(:device, :name => "200", :description => "myvlan", :ensure => :present).returns "myprovider"
@resource.expects(:provider=).with("myprovider")
provider_class.prefetch(@resources)
@@ -74,7 +79,7 @@ describe provider_class do
end
it "should store a copy of the hash as its vlan_properties" do
- instance = provider_class.new(:one => :two)
+ instance = provider_class.new(:device, :one => :two)
instance.former_properties.should == {:one => :two}
end
end
@@ -82,7 +87,7 @@ describe provider_class do
describe "when an instance" do
before do
- @instance = provider_class.new
+ @instance = provider_class.new(:device)
@property_class = stub 'property_class', :array_matching => :all, :superclass => Puppet::Property
@resource_class = stub 'resource_class', :attrclass => @property_class, :valid_parameter? => true, :validproperties => [:description]
@@ -98,12 +103,12 @@ describe provider_class do
end
it "should indicate when the instance already exists" do
- @instance = provider_class.new(:ensure => :present)
+ @instance = provider_class.new(:device, :ensure => :present)
@instance.exists?.should be_true
end
it "should indicate when the instance does not exist" do
- @instance = provider_class.new(:ensure => :absent)
+ @instance = provider_class.new(:device, :ensure => :absent)
@instance.exists?.should be_false
end
diff --git a/spec/unit/provider/vlan/cisco_spec.rb b/spec/unit/provider/vlan/cisco_spec.rb
index bb243a75e..a67290eb4 100755
--- a/spec/unit/provider/vlan/cisco_spec.rb
+++ b/spec/unit/provider/vlan/cisco_spec.rb
@@ -8,12 +8,13 @@ provider_class = Puppet::Type.type(:vlan).provider(:cisco)
describe provider_class do
before do
+ @device = stub_everything 'device'
@resource = stub("resource", :name => "200")
- @provider = provider_class.new(@resource)
+ @provider = provider_class.new(@device, @resource)
end
- it "should have a parent of Puppet::Provider::NetworkDevice" do
- provider_class.should < Puppet::Provider::NetworkDevice
+ it "should have a parent of Puppet::Provider::Cisco" do
+ provider_class.should < Puppet::Provider::Cisco
end
it "should have an instances method" do
@@ -22,31 +23,24 @@ describe provider_class do
describe "when looking up instances at prefetch" do
before do
- @device = stub_everything 'device'
- Puppet::Util::NetworkDevice::Cisco::Device.stubs(:new).returns(@device)
@device.stubs(:command).yields(@device)
end
- it "should initialize the network device with the given url" do
- Puppet::Util::NetworkDevice::Cisco::Device.expects(:new).with(:url).returns(@device)
- provider_class.lookup(:url, "200")
- end
-
it "should delegate to the device vlans" do
@device.expects(:parse_vlans)
- provider_class.lookup("", "200")
+ provider_class.lookup(@device, "200")
end
it "should return only the given vlan" do
@device.expects(:parse_vlans).returns({"200" => { :description => "thisone" }, "1" => { :description => "nothisone" }})
- provider_class.lookup("", "200").should == {:description => "thisone" }
+ provider_class.lookup(@device, "200").should == {:description => "thisone" }
end
end
describe "when an instance is being flushed" do
it "should call the device update_vlan method with its vlan id, current attributes, and desired attributes" do
- @instance = provider_class.new(:ensure => :present, :name => "200", :description => "myvlan")
+ @instance = provider_class.new(@device, :ensure => :present, :name => "200", :description => "myvlan")
@instance.description = "myvlan2"
@instance.resource = @resource
@resource.stubs(:[]).with(:name).returns("200")
diff --git a/spec/unit/resource/catalog_spec.rb b/spec/unit/resource/catalog_spec.rb
index ae65aa91a..ebf523eab 100755
--- a/spec/unit/resource/catalog_spec.rb
+++ b/spec/unit/resource/catalog_spec.rb
@@ -592,6 +592,7 @@ describe Puppet::Resource::Catalog, "when compiling" do
Puppet::Transaction.stubs(:new).returns(@transaction)
@transaction.stubs(:evaluate)
@transaction.stubs(:add_times)
+ @transaction.stubs(:for_network_device=)
Puppet.settings.stubs(:use)
end
diff --git a/spec/unit/transaction_spec.rb b/spec/unit/transaction_spec.rb
index 4157e58ac..d7788c06c 100755
--- a/spec/unit/transaction_spec.rb
+++ b/spec/unit/transaction_spec.rb
@@ -270,6 +270,24 @@ describe Puppet::Transaction do
@resource.stubs(:virtual?).returns true
@transaction.should be_skip(@resource)
end
+
+ it "should skip device only resouce on normal host" do
+ @resource.stubs(:appliable_to_device?).returns true
+ @transaction.for_network_device = false
+ @transaction.should be_skip(@resource)
+ end
+
+ it "should not skip device only resouce on remote device" do
+ @resource.stubs(:appliable_to_device?).returns true
+ @transaction.for_network_device = true
+ @transaction.should_not be_skip(@resource)
+ end
+
+ it "should skip host resouce on device" do
+ @resource.stubs(:appliable_to_device?).returns false
+ @transaction.for_network_device = true
+ @transaction.should be_skip(@resource)
+ end
end
describe "when determining if tags are missing" do
diff --git a/spec/unit/type/interface_spec.rb b/spec/unit/type/interface_spec.rb
index 68f4c765f..12ba225d9 100755
--- a/spec/unit/type/interface_spec.rb
+++ b/spec/unit/type/interface_spec.rb
@@ -3,6 +3,7 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Type.type(:interface) do
+
it "should have a 'name' parameter'" do
Puppet::Type.type(:interface).new(:name => "FastEthernet 0/1")[:name].should == "FastEthernet 0/1"
end
@@ -15,6 +16,10 @@ describe Puppet::Type.type(:interface) do
Puppet::Type.type(:interface).attrtype(:ensure).should == :property
end
+ it "should be applied on device" do
+ Puppet::Type.type(:interface).new(:name => "FastEthernet 0/1").should be_appliable_to_device
+ end
+
[:description, :speed, :duplex, :native_vlan, :encapsulation, :mode, :allowed_trunk_vlans, :etherchannel, :ipaddress].each do |p|
it "should have a #{p} property" do
Puppet::Type.type(:interface).attrtype(p).should == :property
diff --git a/spec/unit/type/schedule_spec.rb b/spec/unit/type/schedule_spec.rb
index 7599411e4..33064ca6f 100755
--- a/spec/unit/type/schedule_spec.rb
+++ b/spec/unit/type/schedule_spec.rb
@@ -36,6 +36,14 @@ describe Puppet::Type.type(:schedule) do
describe Puppet::Type.type(:schedule) do
include ScheduleTesting
+ it "should apply to device" do
+ @schedule.should be_appliable_to_device
+ end
+
+ it "should apply to host" do
+ @schedule.should be_appliable_to_host
+ end
+
it "should default to :distance for period-matching" do
@schedule[:periodmatch].should == :distance
end
diff --git a/spec/unit/type/vlan_spec.rb b/spec/unit/type/vlan_spec.rb
index 2983a58e9..3bee14bbd 100755
--- a/spec/unit/type/vlan_spec.rb
+++ b/spec/unit/type/vlan_spec.rb
@@ -3,6 +3,7 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Type.type(:vlan) do
+
it "should have a 'name' parameter'" do
Puppet::Type.type(:vlan).new(:name => "200")[:name].should == "200"
end
@@ -11,6 +12,10 @@ describe Puppet::Type.type(:vlan) do
Puppet::Type.type(:vlan).new(:name => "200", :device_url => :device)[:device_url].should == :device
end
+ it "should be applied on device" do
+ Puppet::Type.type(:vlan).new(:name => "200").should be_appliable_to_device
+ end
+
it "should have an ensure property" do
Puppet::Type.type(:vlan).attrtype(:ensure).should == :property
end
diff --git a/spec/unit/util/network_device/cisco/device_spec.rb b/spec/unit/util/network_device/cisco/device_spec.rb
index 82b0666e6..33242a1ab 100755
--- a/spec/unit/util/network_device/cisco/device_spec.rb
+++ b/spec/unit/util/network_device/cisco/device_spec.rb
@@ -392,130 +392,17 @@ eos
@cisco.parse_interface_config("Gi0/17").should == {:etherchannel=>"1"}
end
end
+
+ describe "when finding device facts" do
+ it "should delegate to the cisco facts entity" do
+ facts = stub 'facts'
+ Puppet::Util::NetworkDevice::Cisco::Facts.expects(:new).returns(facts)
+
+ facts.expects(:retrieve).returns(:facts)
+
+ @cisco.facts.should == :facts
+ end
+ end
+
end
-# static access
-# Switch#sh interfaces FastEthernet 0/1 switchport
-# Name: Fa0/1
-# Switchport: Enabled
-# Administrative mode: static access
-# Operational Mode: static access
-# Administrative Trunking Encapsulation: isl
-# Operational Trunking Encapsulation: isl
-# Negotiation of Trunking: Disabled
-# Access Mode VLAN: 100 (SHDSL)
-# Trunking Native Mode VLAN: 1 (default)
-# Trunking VLANs Enabled: NONE
-# Pruning VLANs Enabled: NONE
-#
-# Priority for untagged frames: 0
-# Override vlan tag priority: FALSE
-# Voice VLAN: none
-# Appliance trust: none
-# Self Loopback: No
-# Switch#
-
-# c2960#sh interfaces GigabitEthernet 0/1 switchport
-# Name: Gi0/1
-# Switchport: Enabled
-# Administrative Mode: trunk
-# Operational Mode: trunk
-# Administrative Trunking Encapsulation: dot1q
-# Operational Trunking Encapsulation: dot1q
-# Negotiation of Trunking: On
-# Access Mode VLAN: 1 (default)
-# Trunking Native Mode VLAN: 1 (default)
-# Administrative Native VLAN tagging: enabled
-# Voice VLAN: none
-# Administrative private-vlan host-association: none
-# Administrative private-vlan mapping: none
-# Administrative private-vlan trunk native VLAN: none
-# Administrative private-vlan trunk Native VLAN tagging: enabled
-# Administrative private-vlan trunk encapsulation: dot1q
-# Administrative private-vlan trunk normal VLANs: none
-# Administrative private-vlan trunk associations: none
-# Administrative private-vlan trunk mappings: none
-# Operational private-vlan: none
-# Trunking VLANs Enabled: 1,99
-# Pruning VLANs Enabled: 2-1001
-# Capture Mode Disabled
-# Capture VLANs Allowed: ALL
-#
-# Protected: false
-# Unknown unicast blocked: disabled
-# Unknown multicast blocked: disabled
-# Appliance trust: none
-# c2960#
-
-# c2960#sh interfaces GigabitEthernet 0/2 switchport
-# Name: Gi0/2
-# Switchport: Enabled
-# Administrative Mode: static access
-# Operational Mode: static access
-# Administrative Trunking Encapsulation: dot1q
-# Operational Trunking Encapsulation: native
-# Negotiation of Trunking: Off
-# Access Mode VLAN: 99 (MGMT)
-# Trunking Native Mode VLAN: 1 (default)
-# Administrative Native VLAN tagging: enabled
-# Voice VLAN: none
-# Administrative private-vlan host-association: none
-# Administrative private-vlan mapping: none
-# Administrative private-vlan trunk native VLAN: none
-# Administrative private-vlan trunk Native VLAN tagging: enabled
-# Administrative private-vlan trunk encapsulation: dot1q
-# Administrative private-vlan trunk normal VLANs: none
-# Administrative private-vlan trunk associations: none
-# Administrative private-vlan trunk mappings: none
-# Operational private-vlan: none
-# Trunking VLANs Enabled: ALL
-# Pruning VLANs Enabled: 2-1001
-# Capture Mode Disabled
-# Capture VLANs Allowed: ALL
-#
-# Protected: false
-# Unknown unicast blocked: disabled
-# Unknown multicast blocked: disabled
-# Appliance trust: none
-# c2960#
-
-# c877#sh interfaces FastEthernet 1 switchport
-# Name: Fa1
-# Switchport: Enabled
-# Administrative Mode: trunk
-# Operational Mode: trunk
-# Administrative Trunking Encapsulation: dot1q
-# Operational Trunking Encapsulation: dot1q
-# Negotiation of Trunking: Disabled
-# Access Mode VLAN: 0 ((Inactive))
-# Trunking Native Mode VLAN: 1 (default)
-# Trunking VLANs Enabled: ALL
-# Trunking VLANs Active: 1
-# Protected: false
-# Priority for untagged frames: 0
-# Override vlan tag priority: FALSE
-# Voice VLAN: none
-# Appliance trust: none
-
-
-# c2960#sh etherchannel summary
-# Flags: D - down P - bundled in port-channel
-# I - stand-alone s - suspended
-# H - Hot-standby (LACP only)
-# R - Layer3 S - Layer2
-# U - in use f - failed to allocate aggregator
-#
-# M - not in use, minimum links not met
-# u - unsuitable for bundling
-# w - waiting to be aggregated
-# d - default port
-#
-#
-# Number of channel-groups in use: 1
-# Number of aggregators: 1
-#
-# Group Port-channel Protocol Ports
-# ------+-------------+-----------+-----------------------------------------------
-# 1 Po1(SU) LACP Gi0/17(P) Gi0/18(P)
-#
-# c2960#
diff --git a/spec/unit/util/network_device/cisco/facts_spec.rb b/spec/unit/util/network_device/cisco/facts_spec.rb
new file mode 100644
index 000000000..bb29ac292
--- /dev/null
+++ b/spec/unit/util/network_device/cisco/facts_spec.rb
@@ -0,0 +1,63 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../../spec_helper'
+
+require 'puppet/util/network_device'
+require 'puppet/util/network_device/cisco/facts'
+
+describe Puppet::Util::NetworkDevice::Cisco::Facts do
+ before(:each) do
+ @transport = stub_everything 'transport'
+ @facts = Puppet::Util::NetworkDevice::Cisco::Facts.new(@transport)
+ end
+
+ {
+ "cisco WS-C2924C-XL (PowerPC403GA) processor (revision 0x11) with 8192K/1024K bytes of memory." => {:hardwaremodel => "WS-C2924C-XL", :memorysize => "8192K", :processor => "PowerPC403GA", :hardwarerevision => "0x11" },
+ "Cisco 1841 (revision 5.0) with 355328K/37888K bytes of memory." => {:hardwaremodel=>"1841", :memorysize => "355328K", :hardwarerevision => "5.0" },
+ "Cisco 877 (MPC8272) processor (revision 0x200) with 118784K/12288K bytes of memory." => {:hardwaremodel=>"877", :memorysize => "118784K", :processor => "MPC8272", :hardwarerevision => "0x200" },
+ "cisco WS-C2960G-48TC-L (PowerPC405) processor (revision C0) with 61440K/4088K bytes of memory." => {:hardwaremodel=>"WS-C2960G-48TC-L", :memorysize => "61440K", :processor => "PowerPC405", :hardwarerevision => "C0" },
+ "cisco WS-C2950T-24 (RC32300) processor (revision R0) with 19959K bytes of memory." => {:hardwaremodel=>"WS-C2950T-24", :memorysize => "19959K", :processor => "RC32300", :hardwarerevision => "R0" }
+ }.each do |ver, expected|
+ it "should parse show ver output for hardware device facts" do
+ @transport.stubs(:command).with("sh ver").returns(<<eos)
+Switch>sh ver
+#{ver}
+Switch>
+eos
+ @facts.parse_show_ver.should == expected
+ end
+ end
+
+ {
+"Switch uptime is 1 year, 12 weeks, 6 days, 22 hours, 32 minutes" => { :hostname => "Switch", :uptime => "1 year, 12 weeks, 6 days, 22 hours, 32 minutes", :uptime_seconds => 39393120, :uptime_days => 455 },
+"c2950 uptime is 3 weeks, 1 day, 23 hours, 36 minutes" => { :hostname => "c2950", :uptime => "3 weeks, 1 day, 23 hours, 36 minutes", :uptime_days => 22, :uptime_seconds => 1985760},
+"router uptime is 5 weeks, 1 day, 3 hours, 30 minutes" => { :hostname => "router", :uptime => "5 weeks, 1 day, 3 hours, 30 minutes", :uptime_days => 36, :uptime_seconds => 3123000 },
+"c2950 uptime is 1 minute" => { :hostname => "c2950", :uptime => "1 minute", :uptime_days => 0, :uptime_seconds => 60 }
+ }.each do |ver, expected|
+ it "should parse show ver output for device uptime facts" do
+ @transport.stubs(:command).with("sh ver").returns(<<eos)
+Switch>sh ver
+#{ver}
+Switch>
+eos
+ @facts.parse_show_ver.should == expected
+ end
+ end
+
+ {
+"IOS (tm) C2900XL Software (C2900XL-C3H2S-M), Version 12.0(5)WC10, RELEASE SOFTWARE (fc1)"=> { :operatingsystem => "IOS", :operatingsystemrelease => "12.0(5)WC10", :operatingsystemmajrelease => "12.0WC", :operatingsystemfeature => "C3H2S"},
+"IOS (tm) C2950 Software (C2950-I6K2L2Q4-M), Version 12.1(22)EA8a, RELEASE SOFTWARE (fc1)"=> { :operatingsystem => "IOS", :operatingsystemrelease => "12.1(22)EA8a", :operatingsystemmajrelease => "12.1EA", :operatingsystemfeature => "I6K2L2Q4"},
+"Cisco IOS Software, C2960 Software (C2960-LANBASEK9-M), Version 12.2(44)SE, RELEASE SOFTWARE (fc1)"=>{ :operatingsystem => "IOS", :operatingsystemrelease => "12.2(44)SE", :operatingsystemmajrelease => "12.2SE", :operatingsystemfeature => "LANBASEK9"},
+"Cisco IOS Software, C870 Software (C870-ADVIPSERVICESK9-M), Version 12.4(11)XJ4, RELEASE SOFTWARE (fc2)"=>{ :operatingsystem => "IOS", :operatingsystemrelease => "12.4(11)XJ4", :operatingsystemmajrelease => "12.4XJ", :operatingsystemfeature => "ADVIPSERVICESK9"},
+"Cisco IOS Software, 1841 Software (C1841-ADVSECURITYK9-M), Version 12.4(24)T4, RELEASE SOFTWARE (fc2)" =>{ :operatingsystem => "IOS", :operatingsystemrelease => "12.4(24)T4", :operatingsystemmajrelease => "12.4T", :operatingsystemfeature => "ADVSECURITYK9"},
+ }.each do |ver, expected|
+ it "should parse show ver output for device software version facts" do
+ @transport.stubs(:command).with("sh ver").returns(<<eos)
+Switch>sh ver
+#{ver}
+Switch>
+eos
+ @facts.parse_show_ver.should == expected
+ end
+ end
+end
diff --git a/spec/unit/util/network_device/config_spec.rb b/spec/unit/util/network_device/config_spec.rb
new file mode 100644
index 000000000..52796f30b
--- /dev/null
+++ b/spec/unit/util/network_device/config_spec.rb
@@ -0,0 +1,102 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/util/network_device/config'
+
+describe Puppet::Util::NetworkDevice::Config do
+ before(:each) do
+ Puppet[:deviceconfig] = "/dummy"
+ FileTest.stubs(:exists?).with("/dummy").returns(true)
+ end
+
+ describe "when initializing" do
+ before :each do
+ Puppet::Util::NetworkDevice::Config.any_instance.stubs(:read)
+ end
+
+ it "should use the deviceconfig setting as pathname" do
+ Puppet.expects(:[]).with(:deviceconfig).returns("/dummy")
+
+ Puppet::Util::NetworkDevice::Config.new
+ end
+
+ it "should raise an error if no file is defined finally" do
+ Puppet.expects(:[]).with(:deviceconfig).returns(nil)
+
+ lambda { Puppet::Util::NetworkDevice::Config.new }.should raise_error(Puppet::DevError)
+ end
+
+ it "should read and parse the file" do
+ Puppet::Util::NetworkDevice::Config.any_instance.expects(:read)
+
+ Puppet::Util::NetworkDevice::Config.new
+ end
+ end
+
+ describe "when parsing device" do
+ before :each do
+ @config = Puppet::Util::NetworkDevice::Config.new
+ @config.stubs(:changed?).returns(true)
+ @fd = stub 'fd'
+ File.stubs(:open).yields(@fd)
+ end
+
+ it "should skip comments" do
+ @fd.stubs(:each).yields(' # comment')
+
+ OpenStruct.expects(:new).never
+
+ @config.read
+ end
+
+ it "should increment line number even on commented lines" do
+ @fd.stubs(:each).multiple_yields(' # comment','[router.puppetlabs.com]')
+
+ @config.read
+ @config.devices.should be_include('router.puppetlabs.com')
+ end
+
+ it "should skip blank lines" do
+ @fd.stubs(:each).yields(' ')
+
+ @config.read
+ @config.devices.should be_empty
+ end
+
+ it "should produce the correct line number" do
+ @fd.stubs(:each).multiple_yields(' ', '[router.puppetlabs.com]')
+
+ @config.read
+ @config.devices['router.puppetlabs.com'].line.should == 2
+ end
+
+ it "should throw an error if the current device already exists" do
+ @fd.stubs(:each).multiple_yields('[router.puppetlabs.com]', '[router.puppetlabs.com]')
+
+ lambda { @config.read }.should raise_error
+ end
+
+ it "should create a new device for each found device line" do
+ @fd.stubs(:each).multiple_yields('[router.puppetlabs.com]', '[swith.puppetlabs.com]')
+
+ @config.read
+ @config.devices.size.should == 2
+ end
+
+ it "should parse the device type" do
+ @fd.stubs(:each).multiple_yields('[router.puppetlabs.com]', 'type cisco')
+
+ @config.read
+ @config.devices['router.puppetlabs.com'].provider.should == 'cisco'
+ end
+
+ it "should parse the device url" do
+ @fd.stubs(:each).multiple_yields('[router.puppetlabs.com]', 'type cisco', 'url ssh://test/')
+
+ @config.read
+ @config.devices['router.puppetlabs.com'].url.should == 'ssh://test/'
+ end
+ end
+
+end \ No newline at end of file
diff --git a/spec/unit/util/network_device/transport/ssh_spec.rb b/spec/unit/util/network_device/transport/ssh_spec.rb
index 0e91ed9f9..18d22a953 100755
--- a/spec/unit/util/network_device/transport/ssh_spec.rb
+++ b/spec/unit/util/network_device/transport/ssh_spec.rb
@@ -30,6 +30,14 @@ describe Puppet::Util::NetworkDevice::Transport::Ssh, :if => Puppet.features.ssh
@transport.connect
end
+ it "should raise a Puppet::Error when encountering an authentication failure" do
+ Net::SSH.expects(:start).raises Net::SSH::AuthenticationFailed
+ @transport.host = "localhost"
+ @transport.user = "user"
+
+ lambda { @transport.connect }.should raise_error Puppet::Error
+ end
+
describe "when connected" do
before(:each) do
@ssh = stub_everything 'ssh'
diff --git a/spec/unit/util/network_device_spec.rb b/spec/unit/util/network_device_spec.rb
new file mode 100644
index 000000000..70cb509b4
--- /dev/null
+++ b/spec/unit/util/network_device_spec.rb
@@ -0,0 +1,46 @@
+#!/usr/bin/env rspec
+require 'spec_helper'
+
+require 'ostruct'
+require 'puppet/util/network_device'
+
+describe Puppet::Util::NetworkDevice do
+
+ before(:each) do
+ @device = OpenStruct.new(:name => "name", :provider => "test")
+ end
+
+ class Puppet::Util::NetworkDevice::Test
+ class Device
+ def initialize(device)
+ end
+ end
+ end
+
+ describe "when initializing the remote network device singleton" do
+ it "should load the network device code" do
+ Puppet::Util::NetworkDevice.expects(:require)
+ Puppet::Util::NetworkDevice.init(@device)
+ end
+
+ it "should create a network device instance" do
+ Puppet::Util::NetworkDevice.stubs(:require)
+ Puppet::Util::NetworkDevice::Test::Device.expects(:new)
+ Puppet::Util::NetworkDevice.init(@device)
+ end
+
+ it "should raise an error if the remote device instance can't be created" do
+ Puppet::Util::NetworkDevice.stubs(:require).raises("error")
+ lambda { Puppet::Util::NetworkDevice.init(@device) }.should raise_error
+ end
+
+ it "should let caller to access the singleton device" do
+ device = stub 'device'
+ Puppet::Util::NetworkDevice.stubs(:require)
+ Puppet::Util::NetworkDevice::Test::Device.expects(:new).returns(device)
+ Puppet::Util::NetworkDevice.init(@device)
+
+ Puppet::Util::NetworkDevice.current.should == device
+ end
+ end
+end \ No newline at end of file