summaryrefslogtreecommitdiff
path: root/spec/unit/util
diff options
context:
space:
mode:
Diffstat (limited to 'spec/unit/util')
-rwxr-xr-xspec/unit/util/colors_spec.rb22
-rwxr-xr-xspec/unit/util/command_line_spec.rb18
-rwxr-xr-xspec/unit/util/execution_spec.rb77
-rwxr-xr-xspec/unit/util/feature_spec.rb12
-rw-r--r--spec/unit/util/http_proxy_spec.rb44
-rwxr-xr-xspec/unit/util/log/destinations_spec.rb46
-rwxr-xr-xspec/unit/util/logging_spec.rb44
-rw-r--r--spec/unit/util/pidlock_spec.rb38
-rw-r--r--spec/unit/util/profiler/aggregate_spec.rb59
-rw-r--r--spec/unit/util/profiler/around_profiler_spec.rb61
-rw-r--r--spec/unit/util/profiler/logging_spec.rb47
-rw-r--r--spec/unit/util/profiler/none_spec.rb12
-rw-r--r--spec/unit/util/profiler/wall_clock_spec.rb2
-rw-r--r--spec/unit/util/profiler_spec.rb55
-rwxr-xr-xspec/unit/util/queue_spec.rb1
-rwxr-xr-xspec/unit/util/rdoc/parser_spec.rb20
-rwxr-xr-xspec/unit/util/tagging_spec.rb33
-rw-r--r--spec/unit/util/windows/access_control_entry_spec.rb2
-rwxr-xr-xspec/unit/util/windows/adsi_spec.rb (renamed from spec/unit/util/adsi_spec.rb)219
-rw-r--r--spec/unit/util/windows/api_types_spec.rb28
-rwxr-xr-xspec/unit/util/windows/registry_spec.rb13
-rwxr-xr-xspec/unit/util/windows/sid_spec.rb9
-rw-r--r--spec/unit/util/windows/string_spec.rb4
-rwxr-xr-xspec/unit/util/zaml_spec.rb6
24 files changed, 640 insertions, 232 deletions
diff --git a/spec/unit/util/colors_spec.rb b/spec/unit/util/colors_spec.rb
index 7407b628b..b0f791f82 100755
--- a/spec/unit/util/colors_spec.rb
+++ b/spec/unit/util/colors_spec.rb
@@ -67,17 +67,23 @@ describe Puppet::Util::Colors do
end
end
- describe "on Windows", :if => Puppet.features.microsoft_windows? do
- it "expects a trailing embedded NULL character in the wide string" do
- message = "hello"
+ context "on Windows in Ruby 1.x", :if => Puppet.features.microsoft_windows? && RUBY_VERSION =~ /^1./ do
+ it "should define WideConsole" do
+ expect(defined?(Puppet::Util::Colors::WideConsole)).to be_true
+ end
- console = Puppet::Util::Colors::WideConsole.new
- wstr, nchars = console.string_encode(message)
+ it "should define WideIO" do
+ expect(defined?(Puppet::Util::Colors::WideIO)).to be_true
+ end
+ end
- expect(nchars).to eq(message.length)
+ context "on Windows in Ruby 2.x", :if => Puppet.features.microsoft_windows? && RUBY_VERSION =~ /^2./ do
+ it "should not define WideConsole" do
+ expect(defined?(Puppet::Util::Colors::WideConsole)).to be_false
+ end
- expect(wstr.length).to eq(nchars + 1)
- expect(wstr[-1].ord).to be_zero
+ it "should not define WideIO" do
+ expect(defined?(Puppet::Util::Colors::WideIO)).to be_false
end
end
end
diff --git a/spec/unit/util/command_line_spec.rb b/spec/unit/util/command_line_spec.rb
index 6ba8077c2..9eb61b077 100755
--- a/spec/unit/util/command_line_spec.rb
+++ b/spec/unit/util/command_line_spec.rb
@@ -70,7 +70,7 @@ describe Puppet::Util::CommandLine do
it "should print the version and exit if #{arg} is given" do
expect do
described_class.new("puppet", [arg]).execute
- end.to have_printed(/^#{Puppet.version}$/)
+ end.to have_printed(/^#{Regexp.escape(Puppet.version)}$/)
end
end
end
@@ -93,35 +93,39 @@ describe Puppet::Util::CommandLine do
end
describe "and an external implementation cannot be found" do
+ before :each do
+ Puppet::Util::CommandLine::UnknownSubcommand.any_instance.stubs(:console_has_color?).returns false
+ end
+
it "should abort and show the usage message" do
- commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'])
Puppet::Util.expects(:which).with('puppet-whatever').returns(nil)
+ commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'])
commandline.expects(:exec).never
expect {
commandline.execute
- }.to have_printed(/Unknown Puppet subcommand 'whatever'/)
+ }.to have_printed(/Unknown Puppet subcommand 'whatever'/).and_exit_with(1)
end
it "should abort and show the help message" do
- commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'])
Puppet::Util.expects(:which).with('puppet-whatever').returns(nil)
+ commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'])
commandline.expects(:exec).never
expect {
commandline.execute
- }.to have_printed(/See 'puppet help' for help on available puppet subcommands/)
+ }.to have_printed(/See 'puppet help' for help on available puppet subcommands/).and_exit_with(1)
end
%w{--version -V}.each do |arg|
it "should abort and display #{arg} information" do
- commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', arg])
Puppet::Util.expects(:which).with('puppet-whatever').returns(nil)
+ commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', arg])
commandline.expects(:exec).never
expect {
commandline.execute
- }.to have_printed(/^#{Puppet.version}$/)
+ }.to have_printed(%r[^#{Regexp.escape(Puppet.version)}$]).and_exit_with(1)
end
end
end
diff --git a/spec/unit/util/execution_spec.rb b/spec/unit/util/execution_spec.rb
index 7c6238f9f..6a4bee490 100755
--- a/spec/unit/util/execution_spec.rb
+++ b/spec/unit/util/execution_spec.rb
@@ -1,15 +1,9 @@
#! /usr/bin/env ruby
require 'spec_helper'
+require 'puppet/file_system/uniquefile'
describe Puppet::Util::Execution do
include Puppet::Util::Execution
- # utility method to help deal with some windows vs. unix differences
- def process_status(exitstatus)
- return exitstatus if Puppet.features.microsoft_windows?
-
- stub('child_status', :exitstatus => exitstatus)
- end
-
# utility methods to help us test some private methods without being quite so verbose
def call_exec_posix(command, arguments, stdin, stdout, stderr)
Puppet::Util::Execution.send(:execute_posix, command, arguments, stdin, stdout, stderr)
@@ -28,8 +22,8 @@ describe Puppet::Util::Execution do
def stub_process_wait(exitstatus)
if Puppet.features.microsoft_windows?
Puppet::Util::Windows::Process.stubs(:wait_process).with(process_handle).returns(exitstatus)
- Process.stubs(:CloseHandle).with(process_handle)
- Process.stubs(:CloseHandle).with(thread_handle)
+ FFI::WIN32.stubs(:CloseHandle).with(process_handle)
+ FFI::WIN32.stubs(:CloseHandle).with(thread_handle)
else
Process.stubs(:waitpid2).with(pid).returns([pid, stub('child_status', :exitstatus => exitstatus)])
end
@@ -52,7 +46,7 @@ describe Puppet::Util::Execution do
$stderr.stubs(:reopen)
@stdin = File.open(null_file, 'r')
- @stdout = Tempfile.new('stdout')
+ @stdout = Puppet::FileSystem::Uniquefile.new('stdout')
@stderr = File.open(null_file, 'w')
# there is a danger here that ENV will be modified by exec_posix. Normally it would only affect the ENV
@@ -132,7 +126,7 @@ describe Puppet::Util::Execution do
stub_process_wait(0)
@stdin = File.open(null_file, 'r')
- @stdout = Tempfile.new('stdout')
+ @stdout = Puppet::FileSystem::Uniquefile.new('stdout')
@stderr = File.open(null_file, 'w')
end
@@ -223,8 +217,8 @@ describe Puppet::Util::Execution do
describe "when squelch is not set" do
it "should set stdout to a temporary output file" do
- outfile = Tempfile.new('stdout')
- Tempfile.stubs(:new).returns(outfile)
+ outfile = Puppet::FileSystem::Uniquefile.new('stdout')
+ Puppet::FileSystem::Uniquefile.stubs(:new).returns(outfile)
Puppet::Util::Execution.expects(executor).with do |_,_,_,stdout,_|
stdout.path == outfile.path
@@ -234,8 +228,8 @@ describe Puppet::Util::Execution do
end
it "should set stderr to the same file as stdout if combine is true" do
- outfile = Tempfile.new('stdout')
- Tempfile.stubs(:new).returns(outfile)
+ outfile = Puppet::FileSystem::Uniquefile.new('stdout')
+ Puppet::FileSystem::Uniquefile.stubs(:new).returns(outfile)
Puppet::Util::Execution.expects(executor).with do |_,_,_,stdout,stderr|
stdout.path == outfile.path and stderr.path == outfile.path
@@ -245,8 +239,8 @@ describe Puppet::Util::Execution do
end
it "should set stderr to the null device if combine is false" do
- outfile = Tempfile.new('stdout')
- Tempfile.stubs(:new).returns(outfile)
+ outfile = Puppet::FileSystem::Uniquefile.new('stdout')
+ Puppet::FileSystem::Uniquefile.stubs(:new).returns(outfile)
Puppet::Util::Execution.expects(executor).with do |_,_,_,stdout,stderr|
stdout.path == outfile.path and stderr.path == null_file
@@ -256,8 +250,8 @@ describe Puppet::Util::Execution do
end
it "should combine stdout and stderr if combine is true" do
- outfile = Tempfile.new('stdout')
- Tempfile.stubs(:new).returns(outfile)
+ outfile = Puppet::FileSystem::Uniquefile.new('stdout')
+ Puppet::FileSystem::Uniquefile.stubs(:new).returns(outfile)
Puppet::Util::Execution.expects(executor).with do |_,_,_,stdout,stderr|
stdout.path == outfile.path and stderr.path == outfile.path
@@ -267,8 +261,8 @@ describe Puppet::Util::Execution do
end
it "should default combine to true when no options are specified" do
- outfile = Tempfile.new('stdout')
- Tempfile.stubs(:new).returns(outfile)
+ outfile = Puppet::FileSystem::Uniquefile.new('stdout')
+ Puppet::FileSystem::Uniquefile.stubs(:new).returns(outfile)
Puppet::Util::Execution.expects(executor).with do |_,_,_,stdout,stderr|
stdout.path == outfile.path and stderr.path == outfile.path
@@ -278,8 +272,8 @@ describe Puppet::Util::Execution do
end
it "should default combine to false when options are specified, but combine is not" do
- outfile = Tempfile.new('stdout')
- Tempfile.stubs(:new).returns(outfile)
+ outfile = Puppet::FileSystem::Uniquefile.new('stdout')
+ Puppet::FileSystem::Uniquefile.stubs(:new).returns(outfile)
Puppet::Util::Execution.expects(executor).with do |_,_,_,stdout,stderr|
stdout.path == outfile.path and stderr.path == null_file
@@ -289,8 +283,8 @@ describe Puppet::Util::Execution do
end
it "should default combine to false when an empty hash of options is specified" do
- outfile = Tempfile.new('stdout')
- Tempfile.stubs(:new).returns(outfile)
+ outfile = Puppet::FileSystem::Uniquefile.new('stdout')
+ Puppet::FileSystem::Uniquefile.stubs(:new).returns(outfile)
Puppet::Util::Execution.expects(executor).with do |_,_,_,stdout,stderr|
stdout.path == outfile.path and stderr.path == null_file
@@ -306,8 +300,8 @@ describe Puppet::Util::Execution do
Puppet::Util::Execution.stubs(:execute_windows).returns(proc_info_stub)
Puppet::Util::Windows::Process.expects(:wait_process).with(process_handle).raises('whatever')
- Puppet::Util::Windows::Process.expects(:CloseHandle).with(thread_handle)
- Puppet::Util::Windows::Process.expects(:CloseHandle).with(process_handle)
+ FFI::WIN32.expects(:CloseHandle).with(thread_handle)
+ FFI::WIN32.expects(:CloseHandle).with(process_handle)
expect { Puppet::Util::Execution.execute('test command') }.to raise_error(RuntimeError)
end
@@ -507,25 +501,25 @@ describe Puppet::Util::Execution do
end
it "should read and return the output if squelch is false" do
- stdout = Tempfile.new('test')
- Tempfile.stubs(:new).returns(stdout)
+ stdout = Puppet::FileSystem::Uniquefile.new('test')
+ Puppet::FileSystem::Uniquefile.stubs(:new).returns(stdout)
stdout.write("My expected command output")
Puppet::Util::Execution.execute('test command').should == "My expected command output"
end
it "should not read the output if squelch is true" do
- stdout = Tempfile.new('test')
- Tempfile.stubs(:new).returns(stdout)
+ stdout = Puppet::FileSystem::Uniquefile.new('test')
+ Puppet::FileSystem::Uniquefile.stubs(:new).returns(stdout)
stdout.write("My expected command output")
Puppet::Util::Execution.execute('test command', :squelch => true).should == ''
end
it "should delete the file used for output if squelch is false" do
- stdout = Tempfile.new('test')
+ stdout = Puppet::FileSystem::Uniquefile.new('test')
path = stdout.path
- Tempfile.stubs(:new).returns(stdout)
+ Puppet::FileSystem::Uniquefile.stubs(:new).returns(stdout)
Puppet::Util::Execution.execute('test command')
@@ -533,8 +527,8 @@ describe Puppet::Util::Execution do
end
it "should not raise an error if the file is open" do
- stdout = Tempfile.new('test')
- Tempfile.stubs(:new).returns(stdout)
+ stdout = Puppet::FileSystem::Uniquefile.new('test')
+ Puppet::FileSystem::Uniquefile.stubs(:new).returns(stdout)
file = File.new(stdout.path, 'r')
Puppet::Util.execute('test command')
@@ -597,40 +591,39 @@ describe Puppet::Util::Execution do
describe "#execpipe" do
it "should execute a string as a string" do
Puppet::Util::Execution.expects(:open).with('| echo hello 2>&1').returns('hello')
- $CHILD_STATUS.expects(:==).with(0).returns(true)
+ Puppet::Util::Execution.expects(:exitstatus).returns(0)
Puppet::Util::Execution.execpipe('echo hello').should == 'hello'
end
it "should print meaningful debug message for string argument" do
Puppet::Util::Execution.expects(:debug).with("Executing 'echo hello'")
Puppet::Util::Execution.expects(:open).with('| echo hello 2>&1').returns('hello')
- $CHILD_STATUS.expects(:==).with(0).returns(true)
+ Puppet::Util::Execution.expects(:exitstatus).returns(0)
Puppet::Util::Execution.execpipe('echo hello')
end
it "should print meaningful debug message for array argument" do
Puppet::Util::Execution.expects(:debug).with("Executing 'echo hello'")
Puppet::Util::Execution.expects(:open).with('| echo hello 2>&1').returns('hello')
- $CHILD_STATUS.expects(:==).with(0).returns(true)
+ Puppet::Util::Execution.expects(:exitstatus).returns(0)
Puppet::Util::Execution.execpipe(['echo','hello'])
end
it "should execute an array by pasting together with spaces" do
Puppet::Util::Execution.expects(:open).with('| echo hello 2>&1').returns('hello')
- $CHILD_STATUS.expects(:==).with(0).returns(true)
+ Puppet::Util::Execution.expects(:exitstatus).returns(0)
Puppet::Util::Execution.execpipe(['echo', 'hello']).should == 'hello'
end
it "should fail if asked to fail, and the child does" do
- Puppet::Util::Execution.stubs(:open).returns('error message')
- $CHILD_STATUS.expects(:==).with(0).returns(false)
+ Puppet::Util::Execution.stubs(:open).with('| echo hello 2>&1').returns('error message')
+ Puppet::Util::Execution.expects(:exitstatus).returns(1)
expect { Puppet::Util::Execution.execpipe('echo hello') }.
to raise_error Puppet::ExecutionFailure, /error message/
end
it "should not fail if asked not to fail, and the child does" do
Puppet::Util::Execution.stubs(:open).returns('error message')
- $CHILD_STATUS.stubs(:==).with(0).returns(false)
Puppet::Util::Execution.execpipe('echo hello', false).should == 'error message'
end
end
diff --git a/spec/unit/util/feature_spec.rb b/spec/unit/util/feature_spec.rb
index aa8afbba6..e6d844533 100755
--- a/spec/unit/util/feature_spec.rb
+++ b/spec/unit/util/feature_spec.rb
@@ -91,4 +91,16 @@ describe Puppet::Util::Feature do
@features.should_not be_myfeature
@features.should be_myfeature
end
+
+ it "should cache load failures when configured to do so" do
+ Puppet[:always_cache_features] = true
+
+ @features.add(:myfeature, :libs => %w{foo bar})
+ @features.expects(:require).with("foo").raises(LoadError)
+
+ @features.should_not be_myfeature
+ # second call would cause an expectation exception if 'require' was
+ # called a second time
+ @features.should_not be_myfeature
+ end
end
diff --git a/spec/unit/util/http_proxy_spec.rb b/spec/unit/util/http_proxy_spec.rb
index bc6b4d2b7..59f39c511 100644
--- a/spec/unit/util/http_proxy_spec.rb
+++ b/spec/unit/util/http_proxy_spec.rb
@@ -4,7 +4,7 @@ require 'puppet/util/http_proxy'
describe Puppet::Util::HttpProxy do
- host, port = 'some.host', 1234
+ host, port, user, password = 'some.host', 1234, 'user1', 'pAssw0rd'
describe ".http_proxy_env" do
it "should return nil if no environment variables" do
@@ -80,4 +80,46 @@ describe Puppet::Util::HttpProxy do
end
+ describe ".http_proxy_user" do
+ it "should return a proxy user if set in environment" do
+ Puppet::Util.withenv('HTTP_PROXY' => "http://#{user}:#{password}@#{host}:#{port}") do
+ subject.http_proxy_user.should == user
+ end
+ end
+
+ it "should return a proxy user if set in config" do
+ Puppet.settings[:http_proxy_user] = user
+ subject.http_proxy_user.should == user
+ end
+
+ it "should use environment variable before puppet settings" do
+ Puppet::Util.withenv('HTTP_PROXY' => "http://#{user}:#{password}@#{host}:#{port}") do
+ Puppet.settings[:http_proxy_user] = 'clownpants'
+ subject.http_proxy_user.should == user
+ end
+ end
+
+ end
+
+ describe ".http_proxy_password" do
+ it "should return a proxy password if set in environment" do
+ Puppet::Util.withenv('HTTP_PROXY' => "http://#{user}:#{password}@#{host}:#{port}") do
+ subject.http_proxy_password.should == password
+ end
+ end
+
+ it "should return a proxy password if set in config" do
+ Puppet.settings[:http_proxy_user] = user
+ Puppet.settings[:http_proxy_password] = password
+ subject.http_proxy_password.should == password
+ end
+
+ it "should use environment variable before puppet settings" do
+ Puppet::Util.withenv('HTTP_PROXY' => "http://#{user}:#{password}@#{host}:#{port}") do
+ Puppet.settings[:http_proxy_password] = 'clownpants'
+ subject.http_proxy_password.should == password
+ end
+ end
+
+ end
end
diff --git a/spec/unit/util/log/destinations_spec.rb b/spec/unit/util/log/destinations_spec.rb
index a91236dba..a81eac631 100755
--- a/spec/unit/util/log/destinations_spec.rb
+++ b/spec/unit/util/log/destinations_spec.rb
@@ -29,7 +29,7 @@ describe Puppet::Util::Log.desttypes[:file] do
before do
File.stubs(:open) # prevent actually creating the file
- File.stubs(:chown) # prevent chown on non existing file from failing
+ File.stubs(:chown) # prevent chown on non existing file from failing
@class = Puppet::Util::Log.desttypes[:file]
end
@@ -181,3 +181,47 @@ describe Puppet::Util::Log.desttypes[:console] do
end
end
end
+
+
+describe ":eventlog", :if => Puppet::Util::Platform.windows? do
+ before do
+ if Facter.value(:kernelmajversion).to_f < 6.0
+ pending("requires win32-eventlog gem upgrade to 0.6.2 on Windows 2003")
+ end
+ end
+
+ let(:klass) { Puppet::Util::Log.desttypes[:eventlog] }
+
+ def expects_message_with_type(klass, level, eventlog_type, eventlog_id)
+ eventlog = stub('eventlog')
+ eventlog.expects(:report_event).with(has_entries(:source => "Puppet", :event_type => eventlog_type, :event_id => eventlog_id, :data => "a hitchhiker: don't panic"))
+ Win32::EventLog.stubs(:open).returns(eventlog)
+
+ msg = Puppet::Util::Log.new(:level => level, :message => "don't panic", :source => "a hitchhiker")
+ dest = klass.new
+ dest.handle(msg)
+ end
+
+ it "supports the eventlog feature" do
+ expect(Puppet.features.eventlog?).to be_true
+ end
+
+ it "logs to the Application event log" do
+ eventlog = stub('eventlog')
+ Win32::EventLog.expects(:open).with('Application').returns(stub('eventlog'))
+
+ klass.new
+ end
+
+ it "logs :debug level as an information type event" do
+ expects_message_with_type(klass, :debug, klass::EVENTLOG_INFORMATION_TYPE, 0x1)
+ end
+
+ it "logs :warning level as an warning type event" do
+ expects_message_with_type(klass, :warning, klass::EVENTLOG_WARNING_TYPE, 0x2)
+ end
+
+ it "logs :err level as an error type event" do
+ expects_message_with_type(klass, :err, klass::EVENTLOG_ERROR_TYPE, 0x3)
+ end
+end
diff --git a/spec/unit/util/logging_spec.rb b/spec/unit/util/logging_spec.rb
index 0858f7857..abdae9189 100755
--- a/spec/unit/util/logging_spec.rb
+++ b/spec/unit/util/logging_spec.rb
@@ -93,6 +93,12 @@ describe Puppet::Util::Logging do
end
describe "when sending a deprecation warning" do
+ it "does not log a message when deprecation warnings are disabled" do
+ Puppet.expects(:[]).with(:disable_warnings).returns %w[deprecations]
+ @logger.expects(:warning).never
+ @logger.deprecation_warning 'foo'
+ end
+
it "logs the message with warn" do
@logger.expects(:warning).with do |msg|
msg =~ /^foo\n/
@@ -133,6 +139,44 @@ describe Puppet::Util::Logging do
end
end
+ describe "when sending a puppet_deprecation_warning" do
+ it "requires file and line or key options" do
+ expect do
+ @logger.puppet_deprecation_warning("foo")
+ end.to raise_error(Puppet::DevError, /Need either :file and :line, or :key/)
+ expect do
+ @logger.puppet_deprecation_warning("foo", :file => 'bar')
+ end.to raise_error(Puppet::DevError, /Need either :file and :line, or :key/)
+ expect do
+ @logger.puppet_deprecation_warning("foo", :key => 'akey')
+ @logger.puppet_deprecation_warning("foo", :file => 'afile', :line => 1)
+ end.to_not raise_error
+ end
+
+ it "warns with file and line" do
+ @logger.expects(:warning).with(regexp_matches(/deprecated foo.*afile:5/m))
+ @logger.puppet_deprecation_warning("deprecated foo", :file => 'afile', :line => 5)
+ end
+
+ it "warns keyed from file and line" do
+ @logger.expects(:warning).with(regexp_matches(/deprecated foo.*afile:5/m)).once
+ 5.times do
+ @logger.puppet_deprecation_warning("deprecated foo", :file => 'afile', :line => 5)
+ end
+ end
+
+ it "warns with separate key only once regardless of file and line" do
+ @logger.expects(:warning).with(regexp_matches(/deprecated foo.*afile:5/m)).once
+ @logger.puppet_deprecation_warning("deprecated foo", :key => 'some_key', :file => 'afile', :line => 5)
+ @logger.puppet_deprecation_warning("deprecated foo", :key => 'some_key', :file => 'bfile', :line => 3)
+ end
+
+ it "warns with key but no file and line" do
+ @logger.expects(:warning).with(regexp_matches(/deprecated foo.*unknown:unknown/m))
+ @logger.puppet_deprecation_warning("deprecated foo", :key => 'some_key')
+ end
+ end
+
describe "when formatting exceptions" do
it "should be able to format a chain of exceptions" do
exc3 = Puppet::Error.new("original")
diff --git a/spec/unit/util/pidlock_spec.rb b/spec/unit/util/pidlock_spec.rb
index 2ebe7dec8..fcef7aa31 100644
--- a/spec/unit/util/pidlock_spec.rb
+++ b/spec/unit/util/pidlock_spec.rb
@@ -50,6 +50,26 @@ describe Puppet::Util::Pidlock do
Puppet::FileSystem.exist?(@lockfile).should be_true
end
+ it 'should create an empty lock file even when pid is missing' do
+ Process.stubs(:pid).returns('')
+ @lock.lock
+ Puppet::FileSystem.exist?(@lock.file_path).should be_true
+ Puppet::FileSystem.read(@lock.file_path).should be_empty
+ end
+
+ it 'should replace an existing empty lockfile with a pid, given a subsequent lock call made against a valid pid' do
+ # empty pid results in empty lockfile
+ Process.stubs(:pid).returns('')
+ @lock.lock
+ Puppet::FileSystem.exist?(@lock.file_path).should be_true
+
+ # next lock call with valid pid kills existing empty lockfile
+ Process.stubs(:pid).returns(1234)
+ @lock.lock
+ Puppet::FileSystem.exist?(@lock.file_path).should be_true
+ Puppet::FileSystem.read(@lock.file_path).should == '1234'
+ end
+
it "should expose the lock file_path" do
@lock.file_path.should == @lockfile
end
@@ -83,6 +103,22 @@ describe Puppet::Util::Pidlock do
@lock.lock
@lock.should be_locked
end
+
+ it "should remove the lockfile when pid is missing" do
+ Process.stubs(:pid).returns('')
+ @lock.lock
+ @lock.locked?.should be_false
+ Puppet::FileSystem.exist?(@lock.file_path).should be_false
+ end
+ end
+
+ describe '#lock_pid' do
+ it 'should return nil if the pid is empty' do
+ # fake pid to get empty lockfile
+ Process.stubs(:pid).returns('')
+ @lock.lock
+ @lock.lock_pid.should == nil
+ end
end
describe "with a stale lock" do
@@ -105,7 +141,7 @@ describe Puppet::Util::Pidlock do
describe "#lock" do
it "should clear stale locks" do
- @lock.locked?
+ @lock.locked?.should be_false
Puppet::FileSystem.exist?(@lockfile).should be_false
end
diff --git a/spec/unit/util/profiler/aggregate_spec.rb b/spec/unit/util/profiler/aggregate_spec.rb
new file mode 100644
index 000000000..8d38d4673
--- /dev/null
+++ b/spec/unit/util/profiler/aggregate_spec.rb
@@ -0,0 +1,59 @@
+require 'spec_helper'
+require 'puppet/util/profiler'
+require 'puppet/util/profiler/around_profiler'
+require 'puppet/util/profiler/aggregate'
+
+describe Puppet::Util::Profiler::Aggregate do
+ let(:logger) { AggregateSimpleLog.new }
+ let(:profiler) { Puppet::Util::Profiler::Aggregate.new(logger, nil) }
+ let(:profiler_mgr) do
+ p = Puppet::Util::Profiler::AroundProfiler.new
+ p.add_profiler(profiler)
+ p
+ end
+
+ it "tracks the aggregate counts and time for the hierarchy of metrics" do
+ profiler_mgr.profile("Looking up hiera data in production environment", ["function", "hiera_lookup", "production"]) { sleep 0.01 }
+ profiler_mgr.profile("Looking up hiera data in test environment", ["function", "hiera_lookup", "test"]) {}
+ profiler_mgr.profile("looking up stuff for compilation", ["compiler", "lookup"]) { sleep 0.01 }
+ profiler_mgr.profile("COMPILING ALL OF THE THINGS!", ["compiler", "compiling"]) {}
+
+ profiler.values["function"].count.should == 2
+ profiler.values["function"].time.should be > 0
+ profiler.values["function"]["hiera_lookup"].count.should == 2
+ profiler.values["function"]["hiera_lookup"]["production"].count.should == 1
+ profiler.values["function"]["hiera_lookup"]["test"].count.should == 1
+ profiler.values["function"].time.should be >= profiler.values["function"]["hiera_lookup"]["test"].time
+
+ profiler.values["compiler"].count.should == 2
+ profiler.values["compiler"].time.should be > 0
+ profiler.values["compiler"]["lookup"].count.should == 1
+ profiler.values["compiler"]["compiling"].count.should == 1
+ profiler.values["compiler"].time.should be >= profiler.values["compiler"]["lookup"].time
+
+ profiler.shutdown
+
+ logger.output.should =~ /function -> hiera_lookup: .*\(2 calls\)\nfunction -> hiera_lookup ->.*\(1 calls\)/
+ logger.output.should =~ /compiler: .*\(2 calls\)\ncompiler ->.*\(1 calls\)/
+ end
+
+ it "tolerates calls to `profile` that don't include a metric id" do
+ profiler_mgr.profile("yo") {}
+ end
+
+ it "supports both symbols and strings as components of a metric id" do
+ profiler_mgr.profile("yo", [:foo, "bar"]) {}
+ end
+
+ class AggregateSimpleLog
+ attr_reader :output
+
+ def initialize
+ @output = ""
+ end
+
+ def call(msg)
+ @output << msg << "\n"
+ end
+ end
+end
diff --git a/spec/unit/util/profiler/around_profiler_spec.rb b/spec/unit/util/profiler/around_profiler_spec.rb
new file mode 100644
index 000000000..0837395b5
--- /dev/null
+++ b/spec/unit/util/profiler/around_profiler_spec.rb
@@ -0,0 +1,61 @@
+require 'spec_helper'
+require 'puppet/util/profiler'
+
+describe Puppet::Util::Profiler::AroundProfiler do
+ let(:child) { TestAroundProfiler.new() }
+ let(:profiler) { Puppet::Util::Profiler::AroundProfiler.new }
+
+ before :each do
+ profiler.add_profiler(child)
+ end
+
+ it "returns the value of the profiled segment" do
+ retval = profiler.profile("Testing", ["testing"]) { "the return value" }
+
+ retval.should == "the return value"
+ end
+
+ it "propagates any errors raised in the profiled segment" do
+ expect do
+ profiler.profile("Testing", ["testing"]) { raise "a problem" }
+ end.to raise_error("a problem")
+ end
+
+ it "makes the description and the context available to the `start` and `finish` methods" do
+ profiler.profile("Testing", ["testing"]) { }
+
+ child.context.should == "Testing"
+ child.description.should == "Testing"
+ end
+
+ it "calls finish even when an error is raised" do
+ begin
+ profiler.profile("Testing", ["testing"]) { raise "a problem" }
+ rescue
+ child.context.should == "Testing"
+ end
+ end
+
+ it "supports multiple profilers" do
+ profiler2 = TestAroundProfiler.new
+ profiler.add_profiler(profiler2)
+ profiler.profile("Testing", ["testing"]) {}
+
+ child.context.should == "Testing"
+ profiler2.context.should == "Testing"
+ end
+
+ class TestAroundProfiler
+ attr_accessor :context, :description
+
+ def start(description, metric_id)
+ description
+ end
+
+ def finish(context, description, metric_id)
+ @context = context
+ @description = description
+ end
+ end
+end
+
diff --git a/spec/unit/util/profiler/logging_spec.rb b/spec/unit/util/profiler/logging_spec.rb
index 5316e5ae9..3f6a728dd 100644
--- a/spec/unit/util/profiler/logging_spec.rb
+++ b/spec/unit/util/profiler/logging_spec.rb
@@ -4,51 +4,40 @@ require 'puppet/util/profiler'
describe Puppet::Util::Profiler::Logging do
let(:logger) { SimpleLog.new }
let(:identifier) { "Profiling ID" }
- let(:profiler) { TestLoggingProfiler.new(logger, identifier) }
-
- it "returns the value of the profiled segment" do
- retval = profiler.profile("Testing") { "the return value" }
-
- retval.should == "the return value"
- end
-
- it "propogates any errors raised in the profiled segment" do
- expect do
- profiler.profile("Testing") { raise "a problem" }
- end.to raise_error("a problem")
+ let(:logging_profiler) { TestLoggingProfiler.new(logger, identifier) }
+ let(:profiler) do
+ p = Puppet::Util::Profiler::AroundProfiler.new
+ p.add_profiler(logging_profiler)
+ p
end
it "logs the explanation of the profile results" do
- profiler.profile("Testing") { }
+ profiler.profile("Testing", ["test"]) { }
logger.messages.first.should =~ /the explanation/
end
- it "logs results even when an error is raised" do
- begin
- profiler.profile("Testing") { raise "a problem" }
- rescue
- logger.messages.first.should =~ /the explanation/
- end
- end
-
it "describes the profiled segment" do
- profiler.profile("Tested measurement") { }
+ profiler.profile("Tested measurement", ["test"]) { }
logger.messages.first.should =~ /PROFILE \[#{identifier}\] \d Tested measurement/
end
it "indicates the order in which segments are profiled" do
- profiler.profile("Measurement") { }
- profiler.profile("Another measurement") { }
+ profiler.profile("Measurement", ["measurement"]) { }
+ profiler.profile("Another measurement", ["measurement"]) { }
logger.messages[0].should =~ /1 Measurement/
logger.messages[1].should =~ /2 Another measurement/
end
it "indicates the nesting of profiled segments" do
- profiler.profile("Measurement") { profiler.profile("Nested measurement") { } }
- profiler.profile("Another measurement") { profiler.profile("Another nested measurement") { } }
+ profiler.profile("Measurement", ["measurement1"]) do
+ profiler.profile("Nested measurement", ["measurement2"]) { }
+ end
+ profiler.profile("Another measurement", ["measurement1"]) do
+ profiler.profile("Another nested measurement", ["measurement2"]) { }
+ end
logger.messages[0].should =~ /1.1 Nested measurement/
logger.messages[1].should =~ /1 Measurement/
@@ -57,12 +46,12 @@ describe Puppet::Util::Profiler::Logging do
end
class TestLoggingProfiler < Puppet::Util::Profiler::Logging
- def start
+ def do_start(metric, description)
"the start"
end
- def finish(context)
- "the explanation of #{context}"
+ def do_finish(context, metric, description)
+ {:msg => "the explanation of #{context}"}
end
end
diff --git a/spec/unit/util/profiler/none_spec.rb b/spec/unit/util/profiler/none_spec.rb
deleted file mode 100644
index 0cabfef6f..000000000
--- a/spec/unit/util/profiler/none_spec.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-require 'spec_helper'
-require 'puppet/util/profiler'
-
-describe Puppet::Util::Profiler::None do
- let(:profiler) { Puppet::Util::Profiler::None.new }
-
- it "returns the value of the profiled block" do
- retval = profiler.profile("Testing") { "the return value" }
-
- retval.should == "the return value"
- end
-end
diff --git a/spec/unit/util/profiler/wall_clock_spec.rb b/spec/unit/util/profiler/wall_clock_spec.rb
index 668f63221..1adcf0d61 100644
--- a/spec/unit/util/profiler/wall_clock_spec.rb
+++ b/spec/unit/util/profiler/wall_clock_spec.rb
@@ -6,7 +6,7 @@ describe Puppet::Util::Profiler::WallClock do
it "logs the number of seconds it took to execute the segment" do
profiler = Puppet::Util::Profiler::WallClock.new(nil, nil)
- message = profiler.finish(profiler.start)
+ message = profiler.do_finish(profiler.start(["foo", "bar"], "Testing"), ["foo", "bar"], "Testing")[:msg]
message.should =~ /took \d\.\d{4} seconds/
end
diff --git a/spec/unit/util/profiler_spec.rb b/spec/unit/util/profiler_spec.rb
new file mode 100644
index 000000000..c7fc48cb9
--- /dev/null
+++ b/spec/unit/util/profiler_spec.rb
@@ -0,0 +1,55 @@
+require 'spec_helper'
+require 'puppet/util/profiler'
+
+describe Puppet::Util::Profiler do
+ let(:profiler) { TestProfiler.new() }
+
+ it "supports adding profilers" do
+ subject.add_profiler(profiler)
+ subject.current[0].should == profiler
+ end
+
+ it "supports removing profilers" do
+ subject.add_profiler(profiler)
+ subject.remove_profiler(profiler)
+ subject.current.length.should == 0
+ end
+
+ it "supports clearing profiler list" do
+ subject.add_profiler(profiler)
+ subject.clear
+ subject.current.length.should == 0
+ end
+
+ it "supports profiling" do
+ subject.add_profiler(profiler)
+ subject.profile("hi", ["mymetric"]) {}
+ profiler.context[:metric_id].should == ["mymetric"]
+ profiler.context[:description].should == "hi"
+ profiler.description.should == "hi"
+ end
+
+ it "supports profiling without a metric id" do
+ subject.add_profiler(profiler)
+ subject.profile("hi") {}
+ profiler.context[:metric_id].should == nil
+ profiler.context[:description].should == "hi"
+ profiler.description.should == "hi"
+ end
+
+ class TestProfiler
+ attr_accessor :context, :metric, :description
+
+ def start(description, metric_id)
+ {:metric_id => metric_id,
+ :description => description}
+ end
+
+ def finish(context, description, metric_id)
+ @context = context
+ @metric_id = metric_id
+ @description = description
+ end
+ end
+end
+
diff --git a/spec/unit/util/queue_spec.rb b/spec/unit/util/queue_spec.rb
index d7ba57f85..48b98e8e3 100755
--- a/spec/unit/util/queue_spec.rb
+++ b/spec/unit/util/queue_spec.rb
@@ -1,7 +1,6 @@
#! /usr/bin/env ruby
require 'spec_helper'
require 'puppet/util/queue'
-require 'spec/mocks'
def make_test_client_class(n)
c = Class.new do
diff --git a/spec/unit/util/rdoc/parser_spec.rb b/spec/unit/util/rdoc/parser_spec.rb
index acc606b76..7ed2cffcc 100755
--- a/spec/unit/util/rdoc/parser_spec.rb
+++ b/spec/unit/util/rdoc/parser_spec.rb
@@ -21,6 +21,17 @@ describe "RDoc::Parser", :if => Puppet.features.rdoc1? do
end
describe "when scanning files" do
+ around(:each) do |example|
+ Puppet.override({
+ :current_environment => Puppet::Node::Environment.create(:doc, [], '/somewhere/etc/manifests/site.pp')
+ },
+ "A fake current environment that the application would have established by now"
+ ) do
+
+ example.run
+ end
+ end
+
it "should parse puppet files with the puppet parser" do
@parser.stubs(:scan_top_level)
parser = stub 'parser'
@@ -56,15 +67,12 @@ describe "RDoc::Parser", :if => Puppet.features.rdoc1? do
it "should scan the top level even if the file has already parsed" do
known_type = stub 'known_types'
- env = Puppet::Node::Environment.create(Puppet[:environment].to_sym, [])
+ env = Puppet.lookup(:current_environment)
env.stubs(:known_resource_types).returns(known_type)
known_type.expects(:watching_file?).with("module/manifests/init.pp").returns(true)
- Puppet.override(:environments => Puppet::Environments::Static.new(env)) do
-
- @parser.expects(:scan_top_level)
+ @parser.expects(:scan_top_level)
- @parser.scan
- end
+ @parser.scan
end
end
diff --git a/spec/unit/util/tagging_spec.rb b/spec/unit/util/tagging_spec.rb
index 248e915e9..53bb39d7a 100755
--- a/spec/unit/util/tagging_spec.rb
+++ b/spec/unit/util/tagging_spec.rb
@@ -41,7 +41,7 @@ describe Puppet::Util::Tagging do
end
it "should allow tags containing '.' characters" do
- expect { tagger.tag("good.tag") }.to_not raise_error(Puppet::ParseError)
+ expect { tagger.tag("good.tag") }.to_not raise_error
end
it "should add qualified classes as tags" do
@@ -127,5 +127,36 @@ describe Puppet::Util::Tagging do
expect(tagger).to be_tagged("two")
expect(tagger).to be_tagged("three")
end
+
+ it "protects against empty tags" do
+ expect { tagger.tags = "one,,two"}.to raise_error(/Invalid tag ''/)
+ end
+
+ it "takes an array of tags" do
+ tagger.tags = ["one", "two"]
+
+ expect(tagger).to be_tagged("one")
+ expect(tagger).to be_tagged("two")
+ end
+
+ it "removes any existing tags when reassigning" do
+ tagger.tags = "one, two"
+
+ tagger.tags = "three, four"
+
+ expect(tagger).to_not be_tagged("one")
+ expect(tagger).to_not be_tagged("two")
+ expect(tagger).to be_tagged("three")
+ expect(tagger).to be_tagged("four")
+ end
+
+ it "allows empty tags that are generated from :: separated tags" do
+ tagger.tags = "one::::two::three"
+
+ expect(tagger).to be_tagged("one")
+ expect(tagger).to be_tagged("")
+ expect(tagger).to be_tagged("two")
+ expect(tagger).to be_tagged("three")
+ end
end
end
diff --git a/spec/unit/util/windows/access_control_entry_spec.rb b/spec/unit/util/windows/access_control_entry_spec.rb
index b139b0d42..8d3f51c8a 100644
--- a/spec/unit/util/windows/access_control_entry_spec.rb
+++ b/spec/unit/util/windows/access_control_entry_spec.rb
@@ -5,7 +5,7 @@ require 'puppet/util/windows'
describe "Puppet::Util::Windows::AccessControlEntry", :if => Puppet.features.microsoft_windows? do
let(:klass) { Puppet::Util::Windows::AccessControlEntry }
let(:sid) { 'S-1-5-18' }
- let(:mask) { Windows::File::FILE_ALL_ACCESS }
+ let(:mask) { Puppet::Util::Windows::File::FILE_ALL_ACCESS }
it "creates an access allowed ace" do
ace = klass.new(sid, mask)
diff --git a/spec/unit/util/adsi_spec.rb b/spec/unit/util/windows/adsi_spec.rb
index 491c4374b..f569d91e9 100755
--- a/spec/unit/util/adsi_spec.rb
+++ b/spec/unit/util/windows/adsi_spec.rb
@@ -2,97 +2,104 @@
require 'spec_helper'
-require 'puppet/util/adsi'
+require 'puppet/util/windows'
-describe Puppet::Util::ADSI do
+describe Puppet::Util::Windows::ADSI, :if => Puppet.features.microsoft_windows? do
let(:connection) { stub 'connection' }
before(:each) do
- Puppet::Util::ADSI.instance_variable_set(:@computer_name, 'testcomputername')
- Puppet::Util::ADSI.stubs(:connect).returns connection
+ Puppet::Util::Windows::ADSI.instance_variable_set(:@computer_name, 'testcomputername')
+ Puppet::Util::Windows::ADSI.stubs(:connect).returns connection
end
after(:each) do
- Puppet::Util::ADSI.instance_variable_set(:@computer_name, nil)
+ Puppet::Util::Windows::ADSI.instance_variable_set(:@computer_name, nil)
end
it "should generate the correct URI for a resource" do
- Puppet::Util::ADSI.uri('test', 'user').should == "WinNT://./test,user"
+ Puppet::Util::Windows::ADSI.uri('test', 'user').should == "WinNT://./test,user"
end
it "should be able to get the name of the computer" do
- Puppet::Util::ADSI.computer_name.should == 'testcomputername'
+ Puppet::Util::Windows::ADSI.computer_name.should == 'testcomputername'
end
it "should be able to provide the correct WinNT base URI for the computer" do
- Puppet::Util::ADSI.computer_uri.should == "WinNT://."
+ Puppet::Util::Windows::ADSI.computer_uri.should == "WinNT://."
end
it "should generate a fully qualified WinNT URI" do
- Puppet::Util::ADSI.computer_uri('testcomputername').should == "WinNT://testcomputername"
+ Puppet::Util::Windows::ADSI.computer_uri('testcomputername').should == "WinNT://testcomputername"
end
- describe ".sid_for_account", :if => Puppet.features.microsoft_windows? do
+ describe ".sid_for_account" do
it "should return nil if the account does not exist" do
- Puppet::Util::Windows::Security.expects(:name_to_sid).with('foobar').returns nil
+ Puppet::Util::Windows::SID.expects(:name_to_sid).with('foobar').returns nil
- Puppet::Util::ADSI.sid_for_account('foobar').should be_nil
+ Puppet::Util::Windows::ADSI.sid_for_account('foobar').should be_nil
end
it "should return a SID for a passed user or group name" do
- Puppet::Util::Windows::Security.expects(:name_to_sid).with('testers').returns 'S-1-5-32-547'
+ Puppet::Util::Windows::SID.expects(:name_to_sid).with('testers').returns 'S-1-5-32-547'
- Puppet::Util::ADSI.sid_for_account('testers').should == 'S-1-5-32-547'
+ Puppet::Util::Windows::ADSI.sid_for_account('testers').should == 'S-1-5-32-547'
end
it "should return a SID for a passed fully-qualified user or group name" do
- Puppet::Util::Windows::Security.expects(:name_to_sid).with('MACHINE\testers').returns 'S-1-5-32-547'
+ Puppet::Util::Windows::SID.expects(:name_to_sid).with('MACHINE\testers').returns 'S-1-5-32-547'
- Puppet::Util::ADSI.sid_for_account('MACHINE\testers').should == 'S-1-5-32-547'
+ Puppet::Util::Windows::ADSI.sid_for_account('MACHINE\testers').should == 'S-1-5-32-547'
end
end
- describe ".sid_uri", :if => Puppet.features.microsoft_windows? do
+ describe ".computer_name" do
+ it "should return a non-empty ComputerName string" do
+ Puppet::Util::Windows::ADSI.instance_variable_set(:@computer_name, nil)
+ Puppet::Util::Windows::ADSI.computer_name.should_not be_empty
+ end
+ end
+
+ describe ".sid_uri" do
it "should raise an error when the input is not a SID object" do
[Object.new, {}, 1, :symbol, '', nil].each do |input|
expect {
- Puppet::Util::ADSI.sid_uri(input)
+ Puppet::Util::Windows::ADSI.sid_uri(input)
}.to raise_error(Puppet::Error, /Must use a valid SID object/)
end
end
it "should return a SID uri for a well-known SID (SYSTEM)" do
sid = Win32::Security::SID.new('SYSTEM')
- Puppet::Util::ADSI.sid_uri(sid).should == 'WinNT://S-1-5-18'
+ Puppet::Util::Windows::ADSI.sid_uri(sid).should == 'WinNT://S-1-5-18'
end
end
- describe Puppet::Util::ADSI::User do
+ describe Puppet::Util::Windows::ADSI::User do
let(:username) { 'testuser' }
let(:domain) { 'DOMAIN' }
let(:domain_username) { "#{domain}\\#{username}"}
it "should generate the correct URI" do
- Puppet::Util::ADSI.stubs(:sid_uri_safe).returns(nil)
- Puppet::Util::ADSI::User.uri(username).should == "WinNT://./#{username},user"
+ Puppet::Util::Windows::ADSI.stubs(:sid_uri_safe).returns(nil)
+ Puppet::Util::Windows::ADSI::User.uri(username).should == "WinNT://./#{username},user"
end
it "should generate the correct URI for a user with a domain" do
- Puppet::Util::ADSI.stubs(:sid_uri_safe).returns(nil)
- Puppet::Util::ADSI::User.uri(username, domain).should == "WinNT://#{domain}/#{username},user"
+ Puppet::Util::Windows::ADSI.stubs(:sid_uri_safe).returns(nil)
+ Puppet::Util::Windows::ADSI::User.uri(username, domain).should == "WinNT://#{domain}/#{username},user"
end
it "should be able to parse a username without a domain" do
- Puppet::Util::ADSI::User.parse_name(username).should == [username, '.']
+ Puppet::Util::Windows::ADSI::User.parse_name(username).should == [username, '.']
end
it "should be able to parse a username with a domain" do
- Puppet::Util::ADSI::User.parse_name(domain_username).should == [username, domain]
+ Puppet::Util::Windows::ADSI::User.parse_name(domain_username).should == [username, domain]
end
it "should raise an error with a username that contains a /" do
expect {
- Puppet::Util::ADSI::User.parse_name("#{domain}/#{username}")
+ Puppet::Util::Windows::ADSI::User.parse_name("#{domain}/#{username}")
}.to raise_error(Puppet::Error, /Value must be in DOMAIN\\user style syntax/)
end
@@ -100,63 +107,61 @@ describe Puppet::Util::ADSI do
adsi_user = stub('adsi')
connection.expects(:Create).with('user', username).returns(adsi_user)
- Puppet::Util::ADSI::Group.expects(:exists?).with(username).returns(false)
+ Puppet::Util::Windows::ADSI::Group.expects(:exists?).with(username).returns(false)
- user = Puppet::Util::ADSI::User.create(username)
+ user = Puppet::Util::Windows::ADSI::User.create(username)
- user.should be_a(Puppet::Util::ADSI::User)
+ user.should be_a(Puppet::Util::Windows::ADSI::User)
user.native_user.should == adsi_user
end
it "should be able to check the existence of a user" do
- Puppet::Util::ADSI.stubs(:sid_uri_safe).returns(nil)
- Puppet::Util::ADSI.expects(:connect).with("WinNT://./#{username},user").returns connection
- Puppet::Util::ADSI::User.exists?(username).should be_true
+ Puppet::Util::Windows::ADSI.stubs(:sid_uri_safe).returns(nil)
+ Puppet::Util::Windows::ADSI.expects(:connect).with("WinNT://./#{username},user").returns connection
+ Puppet::Util::Windows::ADSI::User.exists?(username).should be_true
end
it "should be able to check the existence of a domain user" do
- Puppet::Util::ADSI.stubs(:sid_uri_safe).returns(nil)
- Puppet::Util::ADSI.expects(:connect).with("WinNT://#{domain}/#{username},user").returns connection
- Puppet::Util::ADSI::User.exists?(domain_username).should be_true
+ Puppet::Util::Windows::ADSI.stubs(:sid_uri_safe).returns(nil)
+ Puppet::Util::Windows::ADSI.expects(:connect).with("WinNT://#{domain}/#{username},user").returns connection
+ Puppet::Util::Windows::ADSI::User.exists?(domain_username).should be_true
end
- it "should be able to confirm the existence of a user with a well-known SID",
- :if => Puppet.features.microsoft_windows? do
+ it "should be able to confirm the existence of a user with a well-known SID" do
system_user = Win32::Security::SID::LocalSystem
# ensure that the underlying OS is queried here
- Puppet::Util::ADSI.unstub(:connect)
- Puppet::Util::ADSI::User.exists?(system_user).should be_true
+ Puppet::Util::Windows::ADSI.unstub(:connect)
+ Puppet::Util::Windows::ADSI::User.exists?(system_user).should be_true
end
- it "should return nil with an unknown SID",
- :if => Puppet.features.microsoft_windows? do
+ it "should return nil with an unknown SID" do
bogus_sid = 'S-1-2-3-4'
# ensure that the underlying OS is queried here
- Puppet::Util::ADSI.unstub(:connect)
- Puppet::Util::ADSI::User.exists?(bogus_sid).should be_false
+ Puppet::Util::Windows::ADSI.unstub(:connect)
+ Puppet::Util::Windows::ADSI::User.exists?(bogus_sid).should be_false
end
it "should be able to delete a user" do
connection.expects(:Delete).with('user', username)
- Puppet::Util::ADSI::User.delete(username)
+ Puppet::Util::Windows::ADSI::User.delete(username)
end
it "should return an enumeration of IADsUser wrapped objects" do
- Puppet::Util::ADSI.stubs(:sid_uri_safe).returns(nil)
+ Puppet::Util::Windows::ADSI.stubs(:sid_uri_safe).returns(nil)
name = 'Administrator'
wmi_users = [stub('WMI', :name => name)]
- Puppet::Util::ADSI.expects(:execquery).with('select name from win32_useraccount where localaccount = "TRUE"').returns(wmi_users)
+ Puppet::Util::Windows::ADSI.expects(:execquery).with('select name from win32_useraccount where localaccount = "TRUE"').returns(wmi_users)
native_user = stub('IADsUser')
homedir = "C:\\Users\\#{name}"
native_user.expects(:Get).with('HomeDirectory').returns(homedir)
- Puppet::Util::ADSI.expects(:connect).with("WinNT://./#{name},user").returns(native_user)
+ Puppet::Util::Windows::ADSI.expects(:connect).with("WinNT://./#{name},user").returns(native_user)
- users = Puppet::Util::ADSI::User.to_a
+ users = Puppet::Util::Windows::ADSI::User.to_a
users.length.should == 1
users[0].name.should == name
users[0]['HomeDirectory'].should == homedir
@@ -165,7 +170,7 @@ describe Puppet::Util::ADSI do
describe "an instance" do
let(:adsi_user) { stub('user', :objectSID => []) }
let(:sid) { stub(:account => username, :domain => 'testcomputername') }
- let(:user) { Puppet::Util::ADSI::User.new(username, adsi_user) }
+ let(:user) { Puppet::Util::Windows::ADSI::User.new(username, adsi_user) }
it "should provide its groups as a list of names" do
names = ["group1", "group2"]
@@ -178,8 +183,8 @@ describe Puppet::Util::ADSI do
end
it "should be able to test whether a given password is correct" do
- Puppet::Util::ADSI::User.expects(:logon).with(username, 'pwdwrong').returns(false)
- Puppet::Util::ADSI::User.expects(:logon).with(username, 'pwdright').returns(true)
+ Puppet::Util::Windows::ADSI::User.expects(:logon).with(username, 'pwdwrong').returns(false)
+ Puppet::Util::Windows::ADSI::User.expects(:logon).with(username, 'pwdright').returns(true)
user.password_is?('pwdwrong').should be_false
user.password_is?('pwdright').should be_true
@@ -198,16 +203,16 @@ describe Puppet::Util::ADSI do
user.password = 'pwd'
end
- it "should generate the correct URI", :if => Puppet.features.microsoft_windows? do
- Puppet::Util::Windows::Security.stubs(:octet_string_to_sid_object).returns(sid)
+ it "should generate the correct URI" do
+ Puppet::Util::Windows::SID.stubs(:octet_string_to_sid_object).returns(sid)
user.uri.should == "WinNT://testcomputername/#{username},user"
end
- describe "when given a set of groups to which to add the user", :if => Puppet.features.microsoft_windows? do
+ describe "when given a set of groups to which to add the user" do
let(:groups_to_set) { 'group1,group2' }
before(:each) do
- Puppet::Util::Windows::Security.stubs(:octet_string_to_sid_object).returns(sid)
+ Puppet::Util::Windows::SID.stubs(:octet_string_to_sid_object).returns(sid)
user.expects(:groups).returns ['group2', 'group3']
end
@@ -219,9 +224,9 @@ describe Puppet::Util::ADSI do
group3 = stub 'group1'
group3.expects(:Remove).with("WinNT://testcomputername/#{username},user")
- Puppet::Util::ADSI.expects(:sid_uri).with(sid).returns("WinNT://testcomputername/#{username},user").twice
- Puppet::Util::ADSI.expects(:connect).with('WinNT://./group1,group').returns group1
- Puppet::Util::ADSI.expects(:connect).with('WinNT://./group3,group').returns group3
+ Puppet::Util::Windows::ADSI.expects(:sid_uri).with(sid).returns("WinNT://testcomputername/#{username},user").twice
+ Puppet::Util::Windows::ADSI.expects(:connect).with('WinNT://./group1,group').returns group1
+ Puppet::Util::Windows::ADSI.expects(:connect).with('WinNT://./group3,group').returns group3
user.set_groups(groups_to_set, false)
end
@@ -232,8 +237,8 @@ describe Puppet::Util::ADSI do
group1 = stub 'group1'
group1.expects(:Add).with("WinNT://testcomputername/#{username},user")
- Puppet::Util::ADSI.expects(:sid_uri).with(sid).returns("WinNT://testcomputername/#{username},user")
- Puppet::Util::ADSI.expects(:connect).with('WinNT://./group1,group').returns group1
+ Puppet::Util::Windows::ADSI.expects(:sid_uri).with(sid).returns("WinNT://testcomputername/#{username},user")
+ Puppet::Util::Windows::ADSI.expects(:connect).with('WinNT://./group1,group').returns group1
user.set_groups(groups_to_set, true)
end
@@ -242,50 +247,50 @@ describe Puppet::Util::ADSI do
end
end
- describe Puppet::Util::ADSI::Group do
+ describe Puppet::Util::Windows::ADSI::Group do
let(:groupname) { 'testgroup' }
describe "an instance" do
let(:adsi_group) { stub 'group' }
- let(:group) { Puppet::Util::ADSI::Group.new(groupname, adsi_group) }
+ let(:group) { Puppet::Util::Windows::ADSI::Group.new(groupname, adsi_group) }
let(:someone_sid){ stub(:account => 'someone', :domain => 'testcomputername')}
- it "should be able to add a member (deprecated)", :if => Puppet.features.microsoft_windows? do
- Puppet.expects(:deprecation_warning).with('Puppet::Util::ADSI::Group#add_members is deprecated; please use Puppet::Util::ADSI::Group#add_member_sids')
+ it "should be able to add a member (deprecated)" do
+ Puppet.expects(:deprecation_warning).with('Puppet::Util::Windows::ADSI::Group#add_members is deprecated; please use Puppet::Util::Windows::ADSI::Group#add_member_sids')
- Puppet::Util::Windows::Security.expects(:name_to_sid_object).with('someone').returns(someone_sid)
- Puppet::Util::ADSI.expects(:sid_uri).with(someone_sid).returns("WinNT://testcomputername/someone,user")
+ Puppet::Util::Windows::SID.expects(:name_to_sid_object).with('someone').returns(someone_sid)
+ Puppet::Util::Windows::ADSI.expects(:sid_uri).with(someone_sid).returns("WinNT://testcomputername/someone,user")
adsi_group.expects(:Add).with("WinNT://testcomputername/someone,user")
group.add_member('someone')
end
- it "should raise when adding a member that can't resolve to a SID (deprecated)", :if => Puppet.features.microsoft_windows? do
+ it "should raise when adding a member that can't resolve to a SID (deprecated)" do
expect {
group.add_member('foobar')
}.to raise_error(Puppet::Error, /Could not resolve username: foobar/)
end
- it "should be able to remove a member (deprecated)", :if => Puppet.features.microsoft_windows? do
- Puppet.expects(:deprecation_warning).with('Puppet::Util::ADSI::Group#remove_members is deprecated; please use Puppet::Util::ADSI::Group#remove_member_sids')
+ it "should be able to remove a member (deprecated)" do
+ Puppet.expects(:deprecation_warning).with('Puppet::Util::Windows::ADSI::Group#remove_members is deprecated; please use Puppet::Util::Windows::ADSI::Group#remove_member_sids')
- Puppet::Util::Windows::Security.expects(:name_to_sid_object).with('someone').returns(someone_sid)
- Puppet::Util::ADSI.expects(:sid_uri).with(someone_sid).returns("WinNT://testcomputername/someone,user")
+ Puppet::Util::Windows::SID.expects(:name_to_sid_object).with('someone').returns(someone_sid)
+ Puppet::Util::Windows::ADSI.expects(:sid_uri).with(someone_sid).returns("WinNT://testcomputername/someone,user")
adsi_group.expects(:Remove).with("WinNT://testcomputername/someone,user")
group.remove_member('someone')
end
- it "should raise when removing a member that can't resolve to a SID (deprecated)", :if => Puppet.features.microsoft_windows? do
+ it "should raise when removing a member that can't resolve to a SID (deprecated)" do
expect {
group.remove_member('foobar')
}.to raise_error(Puppet::Error, /Could not resolve username: foobar/)
end
- describe "should be able to use SID objects", :if => Puppet.features.microsoft_windows? do
- let(:system) { Puppet::Util::Windows::Security.name_to_sid_object('SYSTEM') }
+ describe "should be able to use SID objects" do
+ let(:system) { Puppet::Util::Windows::SID.name_to_sid_object('SYSTEM') }
it "to add a member" do
adsi_group.expects(:Add).with("WinNT://S-1-5-18")
@@ -310,7 +315,7 @@ describe Puppet::Util::ADSI do
group.members.should =~ names
end
- it "should be able to add a list of users to a group", :if => Puppet.features.microsoft_windows? do
+ it "should be able to add a list of users to a group" do
names = ['DOMAIN\user1', 'user2']
sids = [
stub(:account => 'user1', :domain => 'DOMAIN'),
@@ -319,14 +324,14 @@ describe Puppet::Util::ADSI do
]
# use stubbed objectSid on member to return stubbed SID
- Puppet::Util::Windows::Security.expects(:octet_string_to_sid_object).with([0]).returns(sids[0])
- Puppet::Util::Windows::Security.expects(:octet_string_to_sid_object).with([1]).returns(sids[1])
+ Puppet::Util::Windows::SID.expects(:octet_string_to_sid_object).with([0]).returns(sids[0])
+ Puppet::Util::Windows::SID.expects(:octet_string_to_sid_object).with([1]).returns(sids[1])
- Puppet::Util::Windows::Security.expects(:name_to_sid_object).with('user2').returns(sids[1])
- Puppet::Util::Windows::Security.expects(:name_to_sid_object).with('DOMAIN2\user3').returns(sids[2])
+ Puppet::Util::Windows::SID.expects(:name_to_sid_object).with('user2').returns(sids[1])
+ Puppet::Util::Windows::SID.expects(:name_to_sid_object).with('DOMAIN2\user3').returns(sids[2])
- Puppet::Util::ADSI.expects(:sid_uri).with(sids[0]).returns("WinNT://DOMAIN/user1,user")
- Puppet::Util::ADSI.expects(:sid_uri).with(sids[2]).returns("WinNT://DOMAIN2/user3,user")
+ Puppet::Util::Windows::ADSI.expects(:sid_uri).with(sids[0]).returns("WinNT://DOMAIN/user1,user")
+ Puppet::Util::Windows::ADSI.expects(:sid_uri).with(sids[2]).returns("WinNT://DOMAIN2/user3,user")
members = names.each_with_index.map{|n,i| stub(:Name => n, :objectSID => [i])}
adsi_group.expects(:Members).returns members
@@ -337,7 +342,7 @@ describe Puppet::Util::ADSI do
group.set_members(['user2', 'DOMAIN2\user3'])
end
- it "should raise an error when a username does not resolve to a SID", :if => Puppet.features.microsoft_windows? do
+ it "should raise an error when a username does not resolve to a SID" do
expect {
adsi_group.expects(:Members).returns []
group.set_members(['foobar'])
@@ -345,81 +350,79 @@ describe Puppet::Util::ADSI do
end
it "should generate the correct URI" do
- Puppet::Util::ADSI.stubs(:sid_uri_safe).returns(nil)
+ Puppet::Util::Windows::ADSI.stubs(:sid_uri_safe).returns(nil)
group.uri.should == "WinNT://./#{groupname},group"
end
end
it "should generate the correct URI" do
- Puppet::Util::ADSI.stubs(:sid_uri_safe).returns(nil)
- Puppet::Util::ADSI::Group.uri("people").should == "WinNT://./people,group"
+ Puppet::Util::Windows::ADSI.stubs(:sid_uri_safe).returns(nil)
+ Puppet::Util::Windows::ADSI::Group.uri("people").should == "WinNT://./people,group"
end
it "should be able to create a group" do
adsi_group = stub("adsi")
connection.expects(:Create).with('group', groupname).returns(adsi_group)
- Puppet::Util::ADSI::User.expects(:exists?).with(groupname).returns(false)
+ Puppet::Util::Windows::ADSI::User.expects(:exists?).with(groupname).returns(false)
- group = Puppet::Util::ADSI::Group.create(groupname)
+ group = Puppet::Util::Windows::ADSI::Group.create(groupname)
- group.should be_a(Puppet::Util::ADSI::Group)
+ group.should be_a(Puppet::Util::Windows::ADSI::Group)
group.native_group.should == adsi_group
end
it "should be able to confirm the existence of a group" do
- Puppet::Util::ADSI.stubs(:sid_uri_safe).returns(nil)
- Puppet::Util::ADSI.expects(:connect).with("WinNT://./#{groupname},group").returns connection
+ Puppet::Util::Windows::ADSI.stubs(:sid_uri_safe).returns(nil)
+ Puppet::Util::Windows::ADSI.expects(:connect).with("WinNT://./#{groupname},group").returns connection
- Puppet::Util::ADSI::Group.exists?(groupname).should be_true
+ Puppet::Util::Windows::ADSI::Group.exists?(groupname).should be_true
end
- it "should be able to confirm the existence of a group with a well-known SID",
- :if => Puppet.features.microsoft_windows? do
+ it "should be able to confirm the existence of a group with a well-known SID" do
service_group = Win32::Security::SID::Service
# ensure that the underlying OS is queried here
- Puppet::Util::ADSI.unstub(:connect)
- Puppet::Util::ADSI::Group.exists?(service_group).should be_true
+ Puppet::Util::Windows::ADSI.unstub(:connect)
+ Puppet::Util::Windows::ADSI::Group.exists?(service_group).should be_true
end
- it "should return nil with an unknown SID",
- :if => Puppet.features.microsoft_windows? do
+ it "should return nil with an unknown SID" do
bogus_sid = 'S-1-2-3-4'
# ensure that the underlying OS is queried here
- Puppet::Util::ADSI.unstub(:connect)
- Puppet::Util::ADSI::Group.exists?(bogus_sid).should be_false
+ Puppet::Util::Windows::ADSI.unstub(:connect)
+ Puppet::Util::Windows::ADSI::Group.exists?(bogus_sid).should be_false
end
it "should be able to delete a group" do
connection.expects(:Delete).with('group', groupname)
- Puppet::Util::ADSI::Group.delete(groupname)
+ Puppet::Util::Windows::ADSI::Group.delete(groupname)
end
it "should return an enumeration of IADsGroup wrapped objects" do
- Puppet::Util::ADSI.stubs(:sid_uri_safe).returns(nil)
+ Puppet::Util::Windows::ADSI.stubs(:sid_uri_safe).returns(nil)
name = 'Administrators'
wmi_groups = [stub('WMI', :name => name)]
- Puppet::Util::ADSI.expects(:execquery).with('select name from win32_group where localaccount = "TRUE"').returns(wmi_groups)
+ Puppet::Util::Windows::ADSI.expects(:execquery).with('select name from win32_group where localaccount = "TRUE"').returns(wmi_groups)
native_group = stub('IADsGroup')
native_group.expects(:Members).returns([stub(:Name => 'Administrator')])
- Puppet::Util::ADSI.expects(:connect).with("WinNT://./#{name},group").returns(native_group)
+ Puppet::Util::Windows::ADSI.expects(:connect).with("WinNT://./#{name},group").returns(native_group)
- groups = Puppet::Util::ADSI::Group.to_a
+ groups = Puppet::Util::Windows::ADSI::Group.to_a
groups.length.should == 1
groups[0].name.should == name
groups[0].members.should == ['Administrator']
end
end
- describe Puppet::Util::ADSI::UserProfile do
+ describe Puppet::Util::Windows::ADSI::UserProfile do
it "should be able to delete a user profile" do
connection.expects(:Delete).with("Win32_UserProfile.SID='S-A-B-C'")
- Puppet::Util::ADSI::UserProfile.delete('S-A-B-C')
+ Puppet::Util::Windows::ADSI::UserProfile.delete('S-A-B-C')
end
it "should warn on 2003" do
@@ -431,7 +434,7 @@ describe Puppet::Util::ADSI do
Exception occurred.")
Puppet.expects(:warning).with("Cannot delete user profile for 'S-A-B-C' prior to Vista SP1")
- Puppet::Util::ADSI::UserProfile.delete('S-A-B-C')
+ Puppet::Util::Windows::ADSI::UserProfile.delete('S-A-B-C')
end
end
end
diff --git a/spec/unit/util/windows/api_types_spec.rb b/spec/unit/util/windows/api_types_spec.rb
new file mode 100644
index 000000000..a1e1c76c9
--- /dev/null
+++ b/spec/unit/util/windows/api_types_spec.rb
@@ -0,0 +1,28 @@
+# encoding: UTF-8
+#!/usr/bin/env ruby
+
+require 'spec_helper'
+
+describe "FFI::MemoryPointer", :if => Puppet.features.microsoft_windows? do
+ context "read_wide_string" do
+ let (:string) { "foo_bar" }
+
+ it "should properly roundtrip a given string" do
+ read_string = nil
+ FFI::MemoryPointer.from_string_to_wide_string(string) do |ptr|
+ read_string = ptr.read_wide_string(string.length)
+ end
+
+ read_string.should == string
+ end
+
+ it "should return a given string in the default encoding" do
+ read_string = nil
+ FFI::MemoryPointer.from_string_to_wide_string(string) do |ptr|
+ read_string = ptr.read_wide_string(string.length)
+ end
+
+ read_string.encoding.should == Encoding.default_external
+ end
+ end
+end
diff --git a/spec/unit/util/windows/registry_spec.rb b/spec/unit/util/windows/registry_spec.rb
index 636ba0c93..ed52539a5 100755
--- a/spec/unit/util/windows/registry_spec.rb
+++ b/spec/unit/util/windows/registry_spec.rb
@@ -1,7 +1,6 @@
#! /usr/bin/env ruby
require 'spec_helper'
require 'puppet/util/windows'
-require 'puppet/util/windows/registry'
describe Puppet::Util::Windows::Registry, :if => Puppet::Util::Platform.windows? do
subject do
@@ -43,12 +42,14 @@ describe Puppet::Util::Windows::Registry, :if => Puppet::Util::Platform.windows?
yielded.should == subkey
end
- [described_class::KEY64, described_class::KEY32].each do |access|
- it "should open the key for read access 0x#{access.to_s(16)}" do
- mode = described_class::KEY_READ | access
- hkey.expects(:open).with(path, mode)
+ if Puppet::Util::Platform.windows?
+ [described_class::KEY64, described_class::KEY32].each do |access|
+ it "should open the key for read access 0x#{access.to_s(16)}" do
+ mode = described_class::KEY_READ | access
+ hkey.expects(:open).with(path, mode)
- subject.open(name, path, mode) {|reg| }
+ subject.open(name, path, mode) {|reg| }
+ end
end
end
diff --git a/spec/unit/util/windows/sid_spec.rb b/spec/unit/util/windows/sid_spec.rb
index 770512188..2748f13c6 100755
--- a/spec/unit/util/windows/sid_spec.rb
+++ b/spec/unit/util/windows/sid_spec.rb
@@ -4,12 +4,9 @@ require 'spec_helper'
describe "Puppet::Util::Windows::SID", :if => Puppet.features.microsoft_windows? do
if Puppet.features.microsoft_windows?
require 'puppet/util/windows'
- class SIDTester
- include Puppet::Util::Windows::SID
- end
end
- let(:subject) { SIDTester.new }
+ let(:subject) { Puppet::Util::Windows::SID }
let(:sid) { Win32::Security::SID::LocalSystem }
let(:invalid_sid) { 'bogus' }
let(:unknown_sid) { 'S-0-0-0' }
@@ -50,7 +47,7 @@ describe "Puppet::Util::Windows::SID", :if => Puppet.features.microsoft_windows?
expect {
invalid_octet = [1]
subject.octet_string_to_sid_object(invalid_octet)
- }.to raise_error(Win32::Security::SID::Error, /No mapping between account names and security IDs was done./)
+ }.to raise_error(SystemCallError, /No mapping between account names and security IDs was done./)
end
end
@@ -159,7 +156,7 @@ describe "Puppet::Util::Windows::SID", :if => Puppet.features.microsoft_windows?
it "should raise if the conversion fails" do
subject.expects(:string_to_sid_ptr).with(sid).
- raises(Puppet::Util::Windows::Error.new("Failed to convert string SID: #{sid}", Windows::Error::ERROR_ACCESS_DENIED))
+ raises(Puppet::Util::Windows::Error.new("Failed to convert string SID: #{sid}", Puppet::Util::Windows::Error::ERROR_ACCESS_DENIED))
expect {
subject.string_to_sid_ptr(sid) {|ptr| }
diff --git a/spec/unit/util/windows/string_spec.rb b/spec/unit/util/windows/string_spec.rb
index 60f7e6449..5c6473e70 100644
--- a/spec/unit/util/windows/string_spec.rb
+++ b/spec/unit/util/windows/string_spec.rb
@@ -50,5 +50,9 @@ describe "Puppet::Util::Windows::String", :if => Puppet.features.microsoft_windo
it "should convert an UTF-32BE string" do
converts_to_wide_string("bob\u00E8".encode(Encoding::UTF_32BE))
end
+
+ it "should return a nil when given a nil" do
+ wide_string(nil).should == nil
+ end
end
end
diff --git a/spec/unit/util/zaml_spec.rb b/spec/unit/util/zaml_spec.rb
index 56c5cb719..b239b4a84 100755
--- a/spec/unit/util/zaml_spec.rb
+++ b/spec/unit/util/zaml_spec.rb
@@ -69,7 +69,11 @@ describe "Pure ruby yaml implementation" do
end
it "serializes a time in UTC" do
- pending("not supported on Windows", :if => Puppet.features.microsoft_windows? && RUBY_VERSION[0,3] == '1.8') do
+ bad_rubies =
+ RUBY_VERSION[0,3] == '1.8' ||
+ RUBY_VERSION[0,3] == '2.0' && RUBY_PLATFORM == 'i386-mingw32'
+
+ pending("not supported on Windows", :if => Puppet.features.microsoft_windows? && bad_rubies) do
the_time_in("Europe/London").should be_equivalent_to(the_time_in_yaml_offset_by("+00:00"))
end
end