diff --git a/spec/integration/parser/compiler_spec.rb b/spec/integration/parser/compiler_spec.rb index 51611f888..9f6aae907 100755 --- a/spec/integration/parser/compiler_spec.rb +++ b/spec/integration/parser/compiler_spec.rb @@ -1,133 +1,133 @@ #!/usr/bin/env rspec require 'spec_helper' describe Puppet::Parser::Compiler do before :each do @node = Puppet::Node.new "testnode" @scope_resource = stub 'scope_resource', :builtin? => true, :finish => nil, :ref => 'Class[main]' @scope = stub 'scope', :resource => @scope_resource, :source => mock("source") end after do Puppet.settings.clear end - it "should be able to determine the configuration version from a local version control repository", :fails_on_windows => true do + it "should be able to determine the configuration version from a local version control repository" do # This should always work, because we should always be # in the puppet repo when we run this. version = %x{git rev-parse HEAD}.chomp Puppet.settings[:config_version] = 'git rev-parse HEAD' @parser = Puppet::Parser::Parser.new "development" @compiler = Puppet::Parser::Compiler.new(@node) @compiler.catalog.version.should == version end it "should not create duplicate resources when a class is referenced both directly and indirectly by the node classifier (4792)" do Puppet[:code] = <<-PP class foo { notify { foo_notify: } include bar } class bar { notify { bar_notify: } } PP @node.stubs(:classes).returns(['foo', 'bar']) catalog = Puppet::Parser::Compiler.compile(@node) catalog.resource("Notify[foo_notify]").should_not be_nil catalog.resource("Notify[bar_notify]").should_not be_nil end describe "when resolving class references" do it "should favor local scope, even if there's an included class in topscope" do Puppet[:code] = <<-PP class experiment { class baz { } notify {"x" : require => Class[Baz] } } class baz { } include baz include experiment include experiment::baz PP catalog = Puppet::Parser::Compiler.compile(Puppet::Node.new("mynode")) notify_resource = catalog.resource( "Notify[x]" ) notify_resource[:require].title.should == "Experiment::Baz" end it "should favor local scope, even if there's an unincluded class in topscope" do Puppet[:code] = <<-PP class experiment { class baz { } notify {"x" : require => Class[Baz] } } class baz { } include experiment include experiment::baz PP catalog = Puppet::Parser::Compiler.compile(Puppet::Node.new("mynode")) notify_resource = catalog.resource( "Notify[x]" ) notify_resource[:require].title.should == "Experiment::Baz" end end it "should recompute the version after input files are re-parsed" do Puppet[:code] = 'class foo { }' Time.stubs(:now).returns(1) node = Puppet::Node.new('mynode') Puppet::Parser::Compiler.compile(node).version.should == 1 Time.stubs(:now).returns(2) Puppet::Parser::Compiler.compile(node).version.should == 1 # no change because files didn't change Puppet::Resource::TypeCollection.any_instance.stubs(:stale?).returns(true).then.returns(false) # pretend change Puppet::Parser::Compiler.compile(node).version.should == 2 end ['class', 'define', 'node'].each do |thing| it "should not allow #{thing} inside evaluated conditional constructs" do Puppet[:code] = <<-PP if true { #{thing} foo { } notify { decoy: } } PP begin Puppet::Parser::Compiler.compile(Puppet::Node.new("mynode")) raise "compilation should have raised Puppet::Error" rescue Puppet::Error => e e.message.should =~ /at line 2/ end end end it "should not allow classes inside unevaluated conditional constructs" do Puppet[:code] = <<-PP if false { class foo { } } PP lambda { Puppet::Parser::Compiler.compile(Puppet::Node.new("mynode")) }.should raise_error(Puppet::Error) end end diff --git a/spec/integration/provider/mount_spec.rb b/spec/integration/provider/mount_spec.rb index eb8cc134a..b2e9c4497 100755 --- a/spec/integration/provider/mount_spec.rb +++ b/spec/integration/provider/mount_spec.rb @@ -1,151 +1,151 @@ require 'spec_helper' require 'puppet/file_bucket/dipper' -describe "mount provider (integration)", :fails_on_windows => true do +describe "mount provider (integration)", :unless => Puppet.features.microsoft_windows? do include PuppetSpec::Files def create_fake_fstab(initially_contains_entry) File.open(@fake_fstab, 'w') do |f| if initially_contains_entry f.puts("/dev/disk1s1\t/Volumes/foo_disk\tmsdos\tlocal\t0\t0") end end end before :each do @fake_fstab = tmpfile('fstab') @current_options = "local" @current_device = "/dev/disk1s1" Puppet::Type.type(:mount).defaultprovider.stubs(:default_target).returns(@fake_fstab) Facter.stubs(:value).with(:operatingsystem).returns('Darwin') Puppet::Util::ExecutionStub.set do |command, options| case command[0] when %r{/s?bin/mount} if command.length == 1 if @mounted "#{@current_device} on /Volumes/foo_disk (msdos, #{@current_options})\n" else '' end else command.length.should == 4 command[1].should == '-o' command[3].should == '/Volumes/foo_disk' @mounted.should == false # verify that we don't try to call "mount" redundantly @current_options = command[2] @current_device = check_fstab(true) @mounted = true '' end when %r{/s?bin/umount} command.length.should == 2 command[1].should == '/Volumes/foo_disk' @mounted.should == true # "umount" doesn't work when device not mounted (see #6632) @mounted = false '' else fail "Unexpected command #{command.inspect} executed" end end end after :each do Puppet::Type::Mount::ProviderParsed.clear # Work around bug #6628 end def check_fstab(expected_to_be_present) # Verify that the fake fstab has the expected data in it fstab_contents = File.read(@fake_fstab).split("\n").reject { |x| x =~ /^#|^$/ } if expected_to_be_present fstab_contents.length().should == 1 device, rest_of_line = fstab_contents[0].split(/\t/,2) rest_of_line.should == "/Volumes/foo_disk\tmsdos\t#{@desired_options}\t0\t0" device else fstab_contents.length().should == 0 nil end end def run_in_catalog(settings) resource = Puppet::Type.type(:mount).new(settings.merge(:name => "/Volumes/foo_disk", :device => "/dev/disk1s1", :fstype => "msdos")) Puppet::FileBucket::Dipper.any_instance.stubs(:backup) # Don't backup to the filebucket resource.expects(:err).never catalog = Puppet::Resource::Catalog.new catalog.host_config = false # Stop Puppet from doing a bunch of magic catalog.add_resource resource catalog.apply end [false, true].each do |initial_state| describe "When initially #{initial_state ? 'mounted' : 'unmounted'}" do before :each do @mounted = initial_state end [false, true].each do |initial_fstab_entry| describe "When there is #{initial_fstab_entry ? 'an' : 'no'} initial fstab entry" do before :each do create_fake_fstab(initial_fstab_entry) end [:defined, :present, :mounted, :unmounted, :absent].each do |ensure_setting| expected_final_state = case ensure_setting when :mounted true when :unmounted, :absent false when :defined, :present initial_state else fail "Unknown ensure_setting #{ensure_setting}" end expected_fstab_data = (ensure_setting != :absent) describe "When setting ensure => #{ensure_setting}" do ["local", "journaled"].each do |options_setting| describe "When setting options => #{options_setting}" do it "should leave the system in the #{expected_final_state ? 'mounted' : 'unmounted'} state, #{expected_fstab_data ? 'with' : 'without'} data in /etc/fstab" do @desired_options = options_setting run_in_catalog(:ensure=>ensure_setting, :options => options_setting) @mounted.should == expected_final_state if expected_fstab_data check_fstab(expected_fstab_data).should == "/dev/disk1s1" else check_fstab(expected_fstab_data).should == nil end if @mounted if ![:defined, :present].include?(ensure_setting) @current_options.should == @desired_options elsif initial_fstab_entry @current_options.should == @desired_options else @current_options.should == 'local' #Workaround for #6645 end end end end end end end end end end end describe "When the wrong device is mounted" do it "should remount the correct device" do pending "Due to bug 6309" @mounted = true @current_device = "/dev/disk2s2" create_fake_fstab(true) @desired_options = "local" run_in_catalog(:ensure=>:mounted, :options=>'local') @current_device.should=="/dev/disk1s1" @mounted.should==true @current_options.should=='local' check_fstab(true).should == "/dev/disk1s1" end end end diff --git a/spec/integration/provider/ssh_authorized_key_spec.rb b/spec/integration/provider/ssh_authorized_key_spec.rb index f7f61ab25..252f7bf78 100755 --- a/spec/integration/provider/ssh_authorized_key_spec.rb +++ b/spec/integration/provider/ssh_authorized_key_spec.rb @@ -1,207 +1,207 @@ #!/usr/bin/env ruby require 'spec_helper' require 'puppet/file_bucket/dipper' -describe "ssh_authorized_key provider (integration)", :fails_on_windows => true do +describe "ssh_authorized_key provider (integration)", :unless => Puppet.features.microsoft_windows? do include PuppetSpec::Files before :each do @fake_userfile = tmpfile('authorized_keys.user') @fake_rootfile = tmpfile('authorized_keys.root') # few testkeys generated with ssh-keygen @sample_rsa_keys = [ 'AAAAB3NzaC1yc2EAAAADAQABAAAAgQCi18JBZOq10X3w4f67nVhO0O3s5Y1vHH4UgMSM3ZnQwbC5hjGyYSi9UULOoQQoQynI/a0I9NL423/Xk/XJVIKCHcS8q6V2Wmjd+fLNelOjxxoW6mbIytEt9rDvwgq3Mof3/m21L3t2byvegR00a+ikKbmInPmKwjeWZpexCIsHzQ==', # 1024 bit 'AAAAB3NzaC1yc2EAAAADAQABAAAAgQDLClyvi3CsJw5Id6khZs2/+s11qOH4Gdp6iDioDsrIp0m8kSiPr71VGyQYAfPzzvHemHS7Xg0NkG1Kc8u9tRqBQfTvz7ubq0AT/g01+4P2hQ/soFkuwlUG/HVnnaYb6N0Qp5SHWvD5vBE2nFFQVpP5GrSctPtHSjzJq/i+6LYhmQ==', # 1024 bit 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDLygAO6txXkh9FNV8xSsBkATeqLbHzS7sFjGI3gt0Dx6q3LjyKwbhQ1RLf28kd5G6VWiXmClU/RtiPdUz8nrGuun++2mrxzrXrvpR9dq1lygLQ2wn2cI35dN5bjRMtXy3decs6HUhFo9MoNwX250rUWfdCyNPhGIp6OOfmjdy+UeLGNxq9wDx6i4bT5tVVSqVRtsEfw9+ICXchzl85QudjneVVpP+thriPZXfXA5eaGwAo/dmoKOIhUwF96gpdLqzNtrGQuxPbV80PTbGv9ZtAtTictxaDz8muXO7he9pXmchUpxUKtMFjHkL0FAZ9tRPmv3RA30sEr2fZ8+LKvnE50w0' #2048 Bit ] @sample_dsa_keys = [ 'AAAAB3NzaC1kc3MAAACBAOPck2O8MIDSqxPSnvENt6tzRrKJ5oOhB6Nc6oEcWm+VEH1gvuxdiRqwoMgRwyEf1yUd+UAcLw3a6Jn+EtFyEBN/5WF+4Tt4xTxZ0Pfik2Wc5uqHbQ2dkmOoXiAOYPiD3JUQ1Xwm/J0CgetjitoLfzAGdCNhMqguqAuHcVJ78ZZbAAAAFQCIBKFYZ+I18I+dtgteirXh+VVEEwAAAIEAs1yvQ/wnLLrRCM660pF4kBiw3D6dJfMdCXWQpn0hZmkBQSIzZv4Wuk3giei5luxscDxNc+y3CTXtnyG4Kt1Yi2sOdvhRI3rX8tD+ejn8GHazM05l5VIo9uu4AQPIE32iV63IqgApSBbJ6vDJW91oDH0J492WdLCar4BS/KE3cRwAAACBAN0uSDyJqYLRsfYcFn4HyVf6TJxQm1IcwEt6GcJVzgjri9VtW7FqY5iBqa9B9Zdh5XXAYJ0XLsWQCcrmMHM2XGHGpA4gL9VlCJ/0QvOcXxD2uK7IXwAVUA7g4V4bw8EVnFv2Flufozhsp+4soo1xiYc5jiFVHwVlk21sMhAtKAeF' # 1024 Bit ] @sample_lines = [ "ssh-rsa #{@sample_rsa_keys[1]} root@someotherhost", "ssh-dss #{@sample_dsa_keys[0]} root@anywhere", "ssh-rsa #{@sample_rsa_keys[2]} paul" ] end after :each do Puppet::Type::Ssh_authorized_key::ProviderParsed.clear # Work around bug #6628 end def create_fake_key(username, content) filename = (username == :root ? @fake_rootfile : @fake_userfile ) File.open(filename, 'w') do |f| content.each do |line| f.puts line end end end def check_fake_key(username, expected_content) filename = (username == :root ? @fake_rootfile : @fake_userfile ) content = File.readlines(filename).map(&:chomp).sort.reject{ |x| x =~ /^#|^$/ } content.join("\n").should == expected_content.sort.join("\n") end def run_in_catalog(*resources) Puppet::FileBucket::Dipper.any_instance.stubs(:backup) # Don't backup to the filebucket catalog = Puppet::Resource::Catalog.new catalog.host_config = false resources.each do |resource| resource.expects(:err).never catalog.add_resource(resource) end catalog.apply end describe "when managing one resource" do before :each do # We are not running as root so chown/chmod is not possible File.stubs(:chown) File.stubs(:chmod) Puppet::Util::SUIDManager.stubs(:asuser).yields end describe "with ensure set to absent" do before :each do @example = Puppet::Type.type(:ssh_authorized_key).new( :name => 'root@hostname', :type => :rsa, :key => @sample_rsa_keys[0], :target => @fake_rootfile, :user => 'root', :ensure => :absent ) end it "should not modify root's keyfile if resource is currently not present" do create_fake_key(:root, @sample_lines) run_in_catalog(@example) check_fake_key(:root, @sample_lines) end it "remove the key from root's keyfile if resource is currently present" do create_fake_key(:root, @sample_lines + ["ssh-rsa #{@sample_rsa_keys[0]} root@hostname"]) run_in_catalog(@example) check_fake_key(:root, @sample_lines) end end describe "when ensure is present" do before :each do @example = Puppet::Type.type(:ssh_authorized_key).new( :name => 'root@hostname', :type => :rsa, :key => @sample_rsa_keys[0], :target => @fake_rootfile, :user => 'root', :ensure => :present ) # just a dummy so the parsedfile provider is aware # of the user's authorized_keys file @dummy = Puppet::Type.type(:ssh_authorized_key).new( :name => 'dummy', :target => @fake_userfile, :user => 'nobody', :ensure => :absent ) end it "should add the key if it is not present" do create_fake_key(:root, @sample_lines) run_in_catalog(@example) check_fake_key(:root, @sample_lines + ["ssh-rsa #{@sample_rsa_keys[0]} root@hostname" ]) end it "should modify the type if type is out of sync" do create_fake_key(:root,@sample_lines + [ "ssh-dss #{@sample_rsa_keys[0]} root@hostname" ]) run_in_catalog(@example) check_fake_key(:root, @sample_lines + [ "ssh-rsa #{@sample_rsa_keys[0]} root@hostname" ]) end it "should modify the key if key is out of sync" do create_fake_key(:root,@sample_lines + [ "ssh-rsa #{@sample_rsa_keys[1]} root@hostname" ]) run_in_catalog(@example) check_fake_key(:root, @sample_lines + [ "ssh-rsa #{@sample_rsa_keys[0]} root@hostname" ]) end it "should remove the key from old file if target is out of sync" do create_fake_key(:user, [ @sample_lines[0], "ssh-rsa #{@sample_rsa_keys[0]} root@hostname" ]) create_fake_key(:root, [ @sample_lines[1], @sample_lines[2] ]) run_in_catalog(@example, @dummy) check_fake_key(:user, [ @sample_lines[0] ]) #check_fake_key(:root, [ @sample_lines[1], @sample_lines[2], "ssh-rsa #{@sample_rsa_keys[0]} root@hostname" ]) end it "should add the key to new file if target is out of sync" do create_fake_key(:user, [ @sample_lines[0], "ssh-rsa #{@sample_rsa_keys[0]} root@hostname" ]) create_fake_key(:root, [ @sample_lines[1], @sample_lines[2] ]) run_in_catalog(@example, @dummy) #check_fake_key(:user, [ @sample_lines[0] ]) check_fake_key(:root, [ @sample_lines[1], @sample_lines[2], "ssh-rsa #{@sample_rsa_keys[0]} root@hostname" ]) end it "should modify options if options are out of sync" do @example[:options]=[ 'from="correct.domain.com"', 'no-port-forwarding', 'no-pty' ] create_fake_key(:root, @sample_lines + [ "from=\"incorrect.domain.com\",no-port-forwarding,no-pty ssh-rsa #{@sample_rsa_keys[0]} root@hostname"]) run_in_catalog(@example) check_fake_key(:root, @sample_lines + [ "from=\"correct.domain.com\",no-port-forwarding,no-pty ssh-rsa #{@sample_rsa_keys[0]} root@hostname"] ) end end end describe "when managing two resource" do before :each do # We are not running as root so chown/chmod is not possible File.stubs(:chown) File.stubs(:chmod) Puppet::Util::SUIDManager.stubs(:asuser).yields @example_one = Puppet::Type.type(:ssh_authorized_key).new( :name => 'root@hostname', :type => :rsa, :key => @sample_rsa_keys[0], :target => @fake_rootfile, :user => 'root', :ensure => :present ) @example_two = Puppet::Type.type(:ssh_authorized_key).new( :name => 'user@hostname', :key => @sample_rsa_keys[1], :type => :rsa, :target => @fake_userfile, :user => 'nobody', :ensure => :present ) end describe "and both keys are absent" do before :each do create_fake_key(:root, @sample_lines) create_fake_key(:user, @sample_lines) end it "should add both keys" do run_in_catalog(@example_one, @example_two) check_fake_key(:root, @sample_lines + [ "ssh-rsa #{@sample_rsa_keys[0]} root@hostname" ]) check_fake_key(:user, @sample_lines + [ "ssh-rsa #{@sample_rsa_keys[1]} user@hostname" ]) end end end end diff --git a/spec/unit/provider/exec/shell_spec.rb b/spec/unit/provider/exec/shell_spec.rb index 4e1f00281..62036a79c 100755 --- a/spec/unit/provider/exec/shell_spec.rb +++ b/spec/unit/provider/exec/shell_spec.rb @@ -1,50 +1,50 @@ #!/usr/bin/env rspec require 'spec_helper' provider_class = Puppet::Type.type(:exec).provider(:shell) -describe provider_class, :fails_on_windows => true do +describe provider_class, :unless => Puppet.features.microsoft_windows? do before :each do @resource = Puppet::Resource.new(:exec, 'foo') @provider = provider_class.new(@resource) end describe "#run" do it "should be able to run builtin shell commands" do output, status = @provider.run("if [ 1 = 1 ]; then echo 'blah'; fi") status.exitstatus.should == 0 output.should == "blah\n" end it "should be able to run commands with single quotes in them" do output, status = @provider.run("echo 'foo bar'") status.exitstatus.should == 0 output.should == "foo bar\n" end it "should be able to run commands with double quotes in them" do output, status = @provider.run('echo "foo bar"') status.exitstatus.should == 0 output.should == "foo bar\n" end it "should be able to run multiple commands separated by a semicolon" do output, status = @provider.run("echo 'foo' ; echo 'bar'") status.exitstatus.should == 0 output.should == "foo\nbar\n" end it "should be able to read values from the environment parameter" do @resource[:environment] = "FOO=bar" output, status = @provider.run("echo $FOO") status.exitstatus.should == 0 output.should == "bar\n" end end describe "#validatecmd" do it "should always return true because builtins don't need path or to be fully qualified" do @provider.validatecmd('whateverdoesntmatter').should == true end end end diff --git a/spec/unit/provider/ssh_authorized_key/parsed_spec.rb b/spec/unit/provider/ssh_authorized_key/parsed_spec.rb index 8a7fe755c..a7798be54 100755 --- a/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +++ b/spec/unit/provider/ssh_authorized_key/parsed_spec.rb @@ -1,200 +1,200 @@ #!/usr/bin/env rspec require 'spec_helper' require 'shared_behaviours/all_parsedfile_providers' require 'puppet_spec/files' provider_class = Puppet::Type.type(:ssh_authorized_key).provider(:parsed) -describe provider_class do +describe provider_class, :unless => Puppet.features.microsoft_windows? do include PuppetSpec::Files before :each do @keyfile = tmpfile('authorized_keys') @provider_class = provider_class @provider_class.initvars @provider_class.any_instance.stubs(:target).returns @keyfile @user = 'random_bob' Puppet::Util.stubs(:uid).with(@user).returns 12345 end def mkkey(args) args[:target] = @keyfile args[:user] = @user resource = Puppet::Type.type(:ssh_authorized_key).new(args) key = @provider_class.new(resource) args.each do |p,v| key.send(p.to_s + "=", v) end key end def genkey(key) @provider_class.stubs(:filetype).returns(Puppet::Util::FileType::FileTypeRam) File.stubs(:chown) File.stubs(:chmod) Puppet::Util::SUIDManager.stubs(:asuser).yields key.flush @provider_class.target_object(@keyfile).read end it_should_behave_like "all parsedfile providers", provider_class it "should be able to generate a basic authorized_keys file" do key = mkkey(:name => "Just_Testing", :key => "AAAAfsfddsjldjgksdflgkjsfdlgkj", :type => "ssh-dss", :ensure => :present, :options => [:absent] ) genkey(key).should == "ssh-dss AAAAfsfddsjldjgksdflgkjsfdlgkj Just_Testing\n" end it "should be able to generate a authorized_keys file with options" do key = mkkey(:name => "root@localhost", :key => "AAAAfsfddsjldjgksdflgkjsfdlgkj", :type => "ssh-rsa", :ensure => :present, :options => ['from="192.168.1.1"', "no-pty", "no-X11-forwarding"] ) genkey(key).should == "from=\"192.168.1.1\",no-pty,no-X11-forwarding ssh-rsa AAAAfsfddsjldjgksdflgkjsfdlgkj root@localhost\n" end it "should be able to parse options containing commas via its parse_options method" do options = %w{from="host1.reductlivelabs.com,host.reductivelabs.com" command="/usr/local/bin/run" ssh-pty} optionstr = options.join(", ") @provider_class.parse_options(optionstr).should == options end it "should use '' as name for entries that lack a comment" do line = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAut8aOSxenjOqF527dlsdHWV4MNoAsX14l9M297+SQXaQ5Z3BedIxZaoQthkDALlV/25A1COELrg9J2MqJNQc8Xe9XQOIkBQWWinUlD/BXwoOTWEy8C8zSZPHZ3getMMNhGTBO+q/O+qiJx3y5cA4MTbw2zSxukfWC87qWwcZ64UUlegIM056vPsdZWFclS9hsROVEa57YUMrehQ1EGxT4Z5j6zIopufGFiAPjZigq/vqgcAqhAKP6yu4/gwO6S9tatBeEjZ8fafvj1pmvvIplZeMr96gHE7xS3pEEQqnB3nd4RY7AF6j9kFixnsytAUO7STPh/M3pLiVQBN89TvWPQ==" @provider_class.parse(line)[0][:name].should == "" end end -describe provider_class do +describe provider_class, :unless => Puppet.features.microsoft_windows? do before :each do @resource = Puppet::Type.type(:ssh_authorized_key).new(:name => "foo", :user => "random_bob") @provider = provider_class.new(@resource) provider_class.stubs(:filetype).returns(Puppet::Util::FileType::FileTypeRam) Puppet::Util::SUIDManager.stubs(:asuser).yields provider_class.initvars end describe "when flushing" do before :each do # Stub file and directory operations Dir.stubs(:mkdir) File.stubs(:chmod) File.stubs(:chown) end describe "and both a user and a target have been specified" do before :each do Puppet::Util.stubs(:uid).with("random_bob").returns 12345 @resource[:user] = "random_bob" target = "/tmp/.ssh_dir/place_to_put_authorized_keys" @resource[:target] = target end it "should create the directory" do File.stubs(:exist?).with("/tmp/.ssh_dir").returns false Dir.expects(:mkdir).with("/tmp/.ssh_dir", 0700) @provider.flush end it "should chown the directory to the user" do uid = Puppet::Util.uid("random_bob") File.expects(:chown).with(uid, nil, "/tmp/.ssh_dir") @provider.flush end it "should chown the key file to the user" do uid = Puppet::Util.uid("random_bob") File.expects(:chown).with(uid, nil, "/tmp/.ssh_dir/place_to_put_authorized_keys") @provider.flush end it "should chmod the key file to 0600" do File.expects(:chmod).with(0600, "/tmp/.ssh_dir/place_to_put_authorized_keys") @provider.flush end end - describe "and a user has been specified with no target", :fails_on_windows => true do + describe "and a user has been specified with no target" do before :each do @resource[:user] = "nobody" # # I'd like to use random_bob here and something like # # File.stubs(:expand_path).with("~random_bob/.ssh").returns "/users/r/random_bob/.ssh" # # but mocha objects strenuously to stubbing File.expand_path # so I'm left with using nobody. @dir = File.expand_path("~nobody/.ssh") end it "should create the directory if it doesn't exist" do File.stubs(:exist?).with(@dir).returns false Dir.expects(:mkdir).with(@dir,0700) @provider.flush end it "should not create or chown the directory if it already exist" do File.stubs(:exist?).with(@dir).returns false Dir.expects(:mkdir).never @provider.flush end it "should chown the directory to the user if it creates it" do File.stubs(:exist?).with(@dir).returns false Dir.stubs(:mkdir).with(@dir,0700) uid = Puppet::Util.uid("nobody") File.expects(:chown).with(uid, nil, @dir) @provider.flush end it "should not create or chown the directory if it already exist" do File.stubs(:exist?).with(@dir).returns false Dir.expects(:mkdir).never File.expects(:chown).never @provider.flush end it "should chown the key file to the user" do uid = Puppet::Util.uid("nobody") File.expects(:chown).with(uid, nil, File.expand_path("~nobody/.ssh/authorized_keys")) @provider.flush end it "should chmod the key file to 0600" do File.expects(:chmod).with(0600, File.expand_path("~nobody/.ssh/authorized_keys")) @provider.flush end end describe "and a target has been specified with no user" do it "should raise an error" do @resource = Puppet::Type.type(:ssh_authorized_key).new(:name => "foo", :target => "/tmp/.ssh_dir/place_to_put_authorized_keys") @provider = provider_class.new(@resource) proc { @provider.flush }.should raise_error end end - describe "and a invalid user has been specified with no target", :fails_on_windows => true do + describe "and a invalid user has been specified with no target" do it "should catch an exception and raise a Puppet error" do @resource[:user] = "thisusershouldnotexist" lambda { @provider.flush }.should raise_error(Puppet::Error) end end end end diff --git a/spec/unit/type/ssh_authorized_key_spec.rb b/spec/unit/type/ssh_authorized_key_spec.rb index 41413763c..db58dc9f3 100755 --- a/spec/unit/type/ssh_authorized_key_spec.rb +++ b/spec/unit/type/ssh_authorized_key_spec.rb @@ -1,263 +1,263 @@ #!/usr/bin/env rspec require 'spec_helper' ssh_authorized_key = Puppet::Type.type(:ssh_authorized_key) -describe ssh_authorized_key do +describe ssh_authorized_key, :unless => Puppet.features.microsoft_windows? do include PuppetSpec::Files before do @class = Puppet::Type.type(:ssh_authorized_key) @provider_class = stub 'provider_class', :name => "fake", :suitable? => true, :supports_parameter? => true @class.stubs(:defaultprovider).returns(@provider_class) @class.stubs(:provider).returns(@provider_class) @provider = stub 'provider', :class => @provider_class, :file_path => make_absolute("/tmp/whatever"), :clear => nil @provider_class.stubs(:new).returns(@provider) @catalog = Puppet::Resource::Catalog.new end it "should have :name be its namevar" do @class.key_attributes.should == [:name] end describe "when validating attributes" do [:name, :provider].each do |param| it "should have a #{param} parameter" do @class.attrtype(param).should == :param end end [:type, :key, :user, :target, :options, :ensure].each do |property| it "should have a #{property} property" do @class.attrtype(property).should == :property end end end describe "when validating values" do describe "for name" do it "should support valid names" do proc { @class.new(:name => "username", :ensure => :present, :user => "nobody") }.should_not raise_error proc { @class.new(:name => "username@hostname", :ensure => :present, :user => "nobody") }.should_not raise_error end it "should not support whitespaces" do proc { @class.new(:name => "my test", :ensure => :present, :user => "nobody") }.should raise_error(Puppet::Error,/Resourcename must not contain whitespace/) proc { @class.new(:name => "my\ttest", :ensure => :present, :user => "nobody") }.should raise_error(Puppet::Error,/Resourcename must not contain whitespace/) end end describe "for ensure" do it "should support :present" do proc { @class.new(:name => "whev", :ensure => :present, :user => "nobody") }.should_not raise_error end it "should support :absent" do proc { @class.new(:name => "whev", :ensure => :absent, :user => "nobody") }.should_not raise_error end it "should not support other values" do proc { @class.new(:name => "whev", :ensure => :foo, :user => "nobody") }.should raise_error(Puppet::Error, /Invalid value/) end end describe "for type" do it "should support ssh-dss" do proc { @class.new(:name => "whev", :type => "ssh-dss", :user => "nobody") }.should_not raise_error end it "should support ssh-rsa" do proc { @class.new(:name => "whev", :type => "ssh-rsa", :user => "nobody") }.should_not raise_error end it "should support :dsa" do proc { @class.new(:name => "whev", :type => :dsa, :user => "nobody") }.should_not raise_error end it "should support :rsa" do proc { @class.new(:name => "whev", :type => :rsa, :user => "nobody") }.should_not raise_error end it "should alias :rsa to :ssh-rsa" do key = @class.new(:name => "whev", :type => :rsa, :user => "nobody") key.should(:type).should == :'ssh-rsa' end it "should alias :dsa to :ssh-dss" do key = @class.new(:name => "whev", :type => :dsa, :user => "nobody") key.should(:type).should == :'ssh-dss' end it "should not support values other than ssh-dss, ssh-rsa, dsa, rsa" do proc { @class.new(:name => "whev", :type => :something) }.should raise_error(Puppet::Error,/Invalid value/) end end describe "for key" do it "should support a valid key like a 1024 bit rsa key" do proc { @class.new(:name => "whev", :type => :rsa, :user => "nobody", :key => 'AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCPfzW2ry7XvMc6E5Kj2e5fF/YofhKEvsNMUogR3PGL/HCIcBlsEjKisrY0aYgD8Ikp7ZidpXLbz5dBsmPy8hJiBWs5px9ZQrB/EOQAwXljvj69EyhEoGawmxQMtYw+OAIKHLJYRuk1QiHAMHLp5piqem8ZCV2mLb9AsJ6f7zUVw==')}.should_not raise_error end it "should support a valid key like a 4096 bit rsa key" do proc { @class.new(:name => "whev", :type => :rsa, :user => "nobody", :key => 'AAAAB3NzaC1yc2EAAAADAQABAAACAQDEY4pZFyzSfRc9wVWI3DfkgT/EL033UZm/7x1M+d+lBD00qcpkZ6CPT7lD3Z+vylQlJ5S8Wcw6C5Smt6okZWY2WXA9RCjNJMIHQbJAzwuQwgnwU/1VMy9YPp0tNVslg0sUUgpXb13WW4mYhwxyGmIVLJnUrjrQmIFhtfHsJAH8ZVqCWaxKgzUoC/YIu1u1ScH93lEdoBPLlwm6J0aiM7KWXRb7Oq1nEDZtug1zpX5lhgkQWrs0BwceqpUbY+n9sqeHU5e7DCyX/yEIzoPRW2fe2Gx1Iq6JKM/5NNlFfaW8rGxh3Z3S1NpzPHTRjw8js3IeGiV+OPFoaTtM1LsWgPDSBlzIdyTbSQR7gKh0qWYCNV/7qILEfa0yIFB5wIo4667iSPZw2pNgESVtenm8uXyoJdk8iWQ4mecdoposV/znknNb2GPgH+n/2vme4btZ0Sl1A6rev22GQjVgbWOn8zaDglJ2vgCN1UAwmq41RXprPxENGeLnWQppTnibhsngu0VFllZR5kvSIMlekLRSOFLFt92vfd+tk9hZIiKm9exxcbVCGGQPsf6dZ27rTOmg0xM2Sm4J6RRKuz79HQgA4Eg18+bqRP7j/itb89DmtXEtoZFAsEJw8IgIfeGGDtHTkfAlAC92mtK8byeaxGq57XCTKbO/r5gcOMElZHy1AcB8kw==')}.should_not raise_error end it "should support a valid key like a 1024 bit dsa key" do proc { @class.new(:name => "whev", :type => :dsa, :user => "nobody", :key => 'AAAAB3NzaC1kc3MAAACBAI80iR78QCgpO4WabVqHHdEDigOjUEHwIjYHIubR/7u7DYrXY+e+TUmZ0CVGkiwB/0yLHK5dix3Y/bpj8ZiWCIhFeunnXccOdE4rq5sT2V3l1p6WP33RpyVYbLmeuHHl5VQ1CecMlca24nHhKpfh6TO/FIwkMjghHBfJIhXK+0w/AAAAFQDYzLupuMY5uz+GVrcP+Kgd8YqMmwAAAIB3SVN71whLWjFPNTqGyyIlMy50624UfNOaH4REwO+Of3wm/cE6eP8n75vzTwQGBpJX3BPaBGW1S1Zp/DpTOxhCSAwZzAwyf4WgW7YyAOdxN3EwTDJZeyiyjWMAOjW9/AOWt9gtKg0kqaylbMHD4kfiIhBzo31ZY81twUzAfN7angAAAIBfva8sTSDUGKsWWIXkdbVdvM4X14K4gFdy0ZJVzaVOtZ6alysW6UQypnsl6jfnbKvsZ0tFgvcX/CPyqNY/gMR9lyh/TCZ4XQcbqeqYPuceGehz+jL5vArfqsW2fJYFzgCcklmr/VxtP5h6J/T0c9YcDgc/xIfWdZAlznOnphI/FA==')}.should_not raise_error end it "should not support whitespaces" do proc { @class.new(:name => "whev", :type => :rsa, :user => "nobody", :key => 'AAA FA==')}.should raise_error(Puppet::Error,/Key must not contain whitespace/) end end describe "for options" do it "should support flags as options" do proc { @class.new(:name => "whev", :type => :rsa, :user => "nobody", :options => 'cert-authority')}.should_not raise_error proc { @class.new(:name => "whev", :type => :rsa, :user => "nobody", :options => 'no-port-forwarding')}.should_not raise_error end it "should support key-value pairs as options" do proc { @class.new(:name => "whev", :type => :rsa, :user => "nobody", :options => 'command="command"')}.should_not raise_error end it "should support environments as options" do proc { @class.new(:name => "whev", :type => :rsa, :user => "nobody", :options => 'environment="NAME=value"')}.should_not raise_error end it "should support multiple options as an array" do proc { @class.new(:name => "whev", :type => :rsa, :user => "nobody", :options => ['cert-authority','environment="NAME=value"'])}.should_not raise_error end it "should not support a comma separated lists" do proc { @class.new(:name => "whev", :type => :rsa, :user => "nobody", :options => 'cert-authority,no-port-forwarding')}.should raise_error(Puppet::Error, /must be provided as an array/) end it "should use :absent as a default value" do @class.new(:name => "whev", :type => :rsa, :user => "nobody").should(:options).should == [:absent] end it "property should return well formed string of arrays from is_to_s" do resource = @class.new(:name => "whev", :type => :rsa, :user => "nobody", :options => ["a","b","c"]) resource.property(:options).is_to_s(["a","b","c"]).should == "a,b,c" end it "property should return well formed string of arrays from is_to_s" do resource = @class.new(:name => "whev", :type => :rsa, :user => "nobody", :options => ["a","b","c"]) resource.property(:options).should_to_s(["a","b","c"]).should == "a,b,c" end end describe "for user" do it "should support present users" do proc { @class.new(:name => "whev", :type => :rsa, :user => "root") }.should_not raise_error end it "should support absent users" do proc { @class.new(:name => "whev", :type => :rsa, :user => "ihopeimabsent") }.should_not raise_error end end describe "for target" do it "should support absolute paths" do proc { @class.new(:name => "whev", :type => :rsa, :target => "/tmp/here") }.should_not raise_error end - it "should use the user's path if not explicitly specified", :fails_on_windows => true do + it "should use the user's path if not explicitly specified" do @class.new(:name => "whev", :user => 'root').should(:target).should == File.expand_path("~root/.ssh/authorized_keys") end it "should not consider the user's path if explicitly specified" do @class.new(:name => "whev", :user => 'root', :target => '/tmp/here').should(:target).should == '/tmp/here' end it "should inform about an absent user" do Puppet::Log.level = :debug @class.new(:name => "whev", :user => 'idontexist').should(:target) @logs.map(&:message).should include("The required user is not yet present on the system") end end end describe "when neither user nor target is specified" do it "should raise an error" do proc do @class.new( :name => "Test", :key => "AAA", :type => "ssh-rsa", :ensure => :present) end.should raise_error(Puppet::Error,/user.*or.*target.*mandatory/) end end describe "when both target and user are specified" do it "should use target" do resource = @class.new( :name => "Test", :user => "root", :target => "/tmp/blah" ) resource.should(:target).should == "/tmp/blah" end end - describe "when user is specified", :unless => Puppet.features.microsoft_windows? do + describe "when user is specified" do it "should determine target" do resource = @class.create( :name => "Test", :user => "root" ) target = File.expand_path("~root/.ssh/authorized_keys") resource.should(:target).should == target end # Bug #2124 - ssh_authorized_key always changes target if target is not defined it "should not raise spurious change events" do resource = @class.new(:name => "Test", :user => "root") target = File.expand_path("~root/.ssh/authorized_keys") resource.property(:target).safe_insync?(target).should == true end end describe "when calling validate" do it "should not crash on a non-existant user" do resource = @class.create( :name => "Test", :user => "ihopesuchuserdoesnotexist" ) proc { resource.validate }.should_not raise_error end end end