Please review pull request #129: Minor tweaks and new utility methods in acceptance framework test-case opened by (cprice-puppet)
Description:
This commit includes the following:
- Minor cleanup for readability on failure error messages
- Documentation for with_master_running_on method
- New defaults for with_master_running_on: ** will automatically add "--daemonize" if you haven't specified either that or --no-daemonize ** will automatically add "--logdest=/log/puppetmaster.log" if you don't specify a logdest; sending acceptance framework log messages to syslog didn't seem very useful ** will automatically add "--dns_alt_names" if you don't specify it ** will automatically add "--autosign" if you don't specify it ** no longer deletes log dir between executions of master
- New "get_puppet_tmpdir_path()" method, to hopefully start quarantining acceptance test temp files in a common location
- Documentation for "create_remote_file" method
- New options for create_remote_file method to ensure files are visible to "puppet" user et al: ** "mkdirs": will attempt to create parent directory structure before creating file ** "owner": a username to chown the new file to ** "group": a groupname to chown the new file to ** "mode": file permissions to chmod the new file to
- new "mkdirs_on" method
- new "rmdirs_on" method
- new "file_exists_on?" method
- Opened: Thu Feb 02 17:11:48 UTC 2012
- Based on: puppetlabs:master (a2b32d29a0f45fcfdafc2390f16ed2d4eb350c39)
- Requested merge: cprice-puppet:file_utility_methods (ec9bdfa9d3f1c7be3250f7b12acbb146e5dead14)
Diff follows:
diff --git a/lib/test_case.rb b/lib/test_case.rb
index 83ce60f..dacbdc5 100644
--- a/lib/test_case.rb
+++ b/lib/test_case.rb
@@ -104,7 +104,7 @@ def on(host, command, options={}, &block)
if options[:acceptable_exit_codes].include?(exit_code)
# cool.
elsif options[:failing_exit_codes].include?(exit_code)
- assert( false, "Host '#{host} exited with #{exit_code} running: #{command.cmd_line('')}" )
+ fail_test( "Host '#{host} exited with #{exit_code} running: #{command.cmd_line('')}" )
else
raise "Host '#{host}' exited with #{exit_code} running: #{command.cmd_line('')}"
end
@@ -135,7 +135,7 @@ def skip_test(msg)
@test_status = :skip
end
def fail_test(msg)
- assert(false, msg)
+ flunk(msg + "\n" + pretty_call_stack_to_s + "\n")
end
#
# result access
@@ -269,11 +269,37 @@ def run_cron_on(host, action, user, entry="", &block)
end
end
+ # This method performs the following steps:
+ # 1. issues start command for puppet master on specified host
+ # 2. polls until it determines that the master has started successfully
+ # 3. yields to a block of code passed by the caller
+ # 4. runs a "kill" command on the master's pid (on the specified host)
+ # 5. polls until it determines that the master has shut down successfully.
+ #
+ # Parameters:
+ # [host] the master host
+ # [arg] a string containing all of the command line arguments that you would like for the puppet master to
+ # be started with. Defaults to '--daemonize'. NOTE: the following values will be added to the argument list
+ # if they are not explicitly set in your 'args' parameter:
+ # * --daemonize
+ # * --logdest="#{host['puppetvardir']}/log/puppetmaster.log"
+ # * --dns_alt_names="puppet, $(hostname -s), $(hostname -f)"
+ # * --autosign=true
def with_master_running_on(host, arg='--daemonize', &block)
+ # they probably want to run with daemonize. If they pass some other arg/args but forget to re-include
+ # daemonize, we'll check and make sure they didn't explicitly specify "no-daemonize", and, failing that,
+ # we'll add daemonize to the arg string
+ if (arg !~ /(?:--daemonize)|(?:--no-daemonize)/) then arg << " --daemonize" end
+
+ if (arg !~ /--logdest/) then arg << " --logdest=\"#{master['puppetvardir']}/log/puppetmaster.log\"" end
+ if (arg !~ /--dns_alt_names/) then arg << " --dns_alt_names=\"puppet, $(hostname -s), $(hostname -f)\"" end
+ if (arg !~ /--autosign/) then arg << " --autosign=true" end
+
on hosts, host_command('rm -rf #{host["puppetpath"]}/ssl')
agents.each do |agent|
- if vardir = agent['puppetvardir']
- on agent, "rm -rf #{vardir}/*"
+ if ((vardir = agent['puppetvardir']) && File.exists?(vardir))
+ # we want to remove everything except the log directory
+ on agent, "for f in #{vardir}/*; do if [ \"$f\" != \"#{vardir}/log\" ]; then rm -r \"$f\"; fi; done"
end
end
@@ -316,14 +342,85 @@ def poll_master_until(host, verb)
end
end
- def create_remote_file(hosts, file_path, file_content)
+ # Utility function to return a consistent place where we can/should store temp files on the nodes. Adhering to
+ # the convention of calling this method and then creating your temp dir somewhere underneath the location it returns
+ # will make it so that a developer / user can safely delete the entire "root" dir that this function describes when
+ # they want to clean temp files off of their nodes.
+ def get_puppet_tmpdir_path()
+ "/tmp/puppet-acceptance"
+ end
+
+ # Create a file on the remote host(s).
+ # Parameters:
+ # [hosts] the hosts to create the file on
+ # [file_path] the path to the file to be created
+ # [file_content] a string containing the contents to be written to the file
+ # [options] a hash containing additional behavior options. Currently supported:
+ # * :mkdirs (default false) if true, attempt to create the parent directories on the remote host before writing
+ # the file
+ # * :owner (default 'root') the username of the user that the file should be owned by
+ # * :group (default 'puppet') the name of the group that the file should be owned by
+ # * :mode (default '644') the mode (file permissions) that the file should be created with
+ def create_remote_file(hosts, file_path, file_content, options = {})
+
+ default_options = {
+ :mkdirs => false,
+ :owner => "root",
+ :group => "puppet",
+ :mode => "644"
+ }
+
+ options = default_options.merge(options)
+
+
+ if (options[:mkdirs] == true) then
+ mkdirs_on(hosts, File.dirname(file_path))
+ end
+
Tempfile.open 'puppet-acceptance' do |tempfile|
File.open(tempfile.path, 'w') { |file| file.puts file_content }
scp_to hosts, tempfile.path, file_path
+ on(hosts, "chown #{options[:owner]}:#{options[:group]} #{file_path}; chmod #{options[:mode]} #{file_path}")
end
end
+
+ # Create a directory structure on the remote hosts.
+ # Parameters:
+ # [hosts] the hosts to create the directories on
+ # [dir] the target directory to create; this method will attempt to create any missing parent directories as well
+ def mkdirs_on(hosts, dir)
+ on(hosts, "mkdir -p #{dir}")
+ end
+
+ # Remove (recursively) a directory structure on the remote hosts.
+ # Parameters:
+ # [hosts] the hosts to create the directories on
+ # [dir] the target directory to remove; this method will attempt to recursively delete all of the contents of the
+ # specified directory
+ def rmdirs_on!(hosts, dir)
+ on(hosts, "rm -rf #{dir}")
+ end
+
+
+ # Check to see if a file exists on a host
+ # Parameters:
+ # [host] the host to check
+ # [file_path] the absolute path of a file to look for
+ #
+ # returns true if the file exists, false otherwise
+ def file_exists_on?(host, file_path)
+ result = false
+ on(host, "ruby -e \"print File.exists?('#{file_path}')\"") do
+ result = (stdout.chomp() == "true")
+ end
+ result
+ end
+
+
+
+
def with_standard_output_to_logs
stdout = ''
old_stdout = $stdout
@@ -343,4 +440,42 @@ def with_standard_output_to_logs
return result
end
+
+
+ # utility method to get the current call stack and format it to a human-readable string (which some IDEs/editors
+ # will recognize as links to the line numbers in the trace)
+ def pretty_call_stack_to_s()
+
+ caller(1).collect do |line|
+ file_path, line_num = line.split(":")
+ file_path = expand_symlinks(File.expand_path(file_path))
+
+ file_path + ":" + line_num
+ end .join("\n")
+
+ end
+ private :pretty_call_stack_to_s
+
+ # utility method that takes a path as input, checks each component of the path to see if it is a symlink, and expands
+ # it if it is. returns the expanded path.
+ def expand_symlinks(file_path)
+ file_path.split("/").inject do |full_path, next_dir|
+ next_path = full_path + "/" + next_dir
+ if File.symlink?(next_path) then
+ link = File.readlink(next_path)
+ next_path =
+ case link
+ when /^\// then link
+ else
+ File.expand_path(full_path + "/" + link)
+ end
+ end
+ next_path
+ end
+ end
+ private :expand_symlinks
+
+
+
+
end
-- You received this message because you are subscribed to the Google Groups "Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to [email protected].
For more options, visit this group at http://groups.google.com/group/puppet-dev?hl=en.
