diff --git a/acceptance/lib/helper.rb b/acceptance/lib/helper.rb new file mode 100644 index 000000000..c2b5df870 --- /dev/null +++ b/acceptance/lib/helper.rb @@ -0,0 +1 @@ +$LOAD_PATH << File.expand_path(File.dirname(__FILE__)) diff --git a/acceptance/lib/puppet/acceptance/temp_file_utils.rb b/acceptance/lib/puppet/acceptance/temp_file_utils.rb new file mode 100644 index 000000000..75c62eceb --- /dev/null +++ b/acceptance/lib/puppet/acceptance/temp_file_utils.rb @@ -0,0 +1,113 @@ +module Puppet + module Acceptance + module TempFileUtils + + # Create a file on the host. + # Parameters: + # [host] the host 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_test_file(host, file_rel_path, file_content, options) + + # set default options + options[:mkdirs] ||= false + options[:owner] ||= "root" + options[:group] ||= "puppet" + options[:mode] ||= "755" + + file_path = get_test_file_path(host, file_rel_path) + + mkdirs(host, File.dirname(file_path)) if (options[:mkdirs] == true) + create_remote_file(host, file_path, file_content) + + # + # NOTE: we need these chown/chmod calls because the acceptance framework connects to the nodes as "root", but + # puppet 'master' runs as user 'puppet'. Therefore, in order for puppet master to be able to read any files + # that we've created, we have to carefully set their permissions + # + + chown(host, options[:owner], options[:group], file_path) + chmod(host, options[:mode], file_path) + + end + + + # Given a relative path, returns an absolute path for a test file. Basically, this just prepends the + # a unique temp dir path (specific to the current test execution) to your relative path. + def get_test_file_path(host, file_rel_path) + File.join(@host_test_tmp_dirs[host.name], file_rel_path) + end + + + # Check for the existence of a temp file for the current test; basically, this just calls file_exists?(), + # but prepends the path to the current test's temp dir onto the file_rel_path parameter. This allows + # tests to be written using only a relative path to specify file locations, while still taking advantage + # of automatic temp file cleanup at test completion. + def test_file_exists?(host, file_rel_path) + file_exists?(host, get_test_file_path(host, file_rel_path)) + end + + def file_exists?(host, file_path) + host.execute("test -f \"#{file_path}\"", + :acceptable_exit_codes => [0, 1]) do |result| + return result.exit_code == 0 + end + end + + def file_contents(host, file_path) + host.execute("cat \"#{file_path}\"") do |result| + return result.stdout + end + end + + def tmpdir(host, basename) + host_tmpdir = host.tmpdir(basename) + # we need to make sure that the puppet user can traverse this directory... + chmod(host, "755", host_tmpdir) + host_tmpdir + end + + def mkdirs(host, dir_path) + on(host, "mkdir -p #{dir_path}") + end + + def chown(host, owner, group, path) + on(host, "chown #{owner}:#{group} #{path}") + end + + def chmod(host, mode, path) + on(host, "chmod #{mode} #{path}") + end + + + def initialize_temp_dirs() + # pluck this out of the test case environment; not sure if there is a better way + @cur_test_file = @path + @cur_test_file_shortname = File.basename(@cur_test_file, File.extname(@cur_test_file)) + + # we need one list of all of the hosts, to assist in managing temp dirs. It's possible + # that the master is also an agent, so this will consolidate them into a unique set + @all_hosts = Set[master, *agents] + + # now we can create a hash of temp dirs--one per host, and unique to this test--without worrying about + # doing it twice on any individual host + @host_test_tmp_dirs = Hash[@all_hosts.map do |host| [host.name, tmpdir(host, @cur_test_file_shortname)] end ] + end + + def remove_temp_dirs() + @all_hosts.each do |host| + on(host, "rm -rf #{@host_test_tmp_dirs[host.name]}") + end + end + + # a silly variable for keeping track of whether or not all of the tests passed... + @all_tests_passed = false + end + end +end \ No newline at end of file diff --git a/acceptance/pending/pluginsync/7316_faces_should_be_available_via_pluginsync.rb b/acceptance/pending/pluginsync/7316_faces_should_be_available_via_pluginsync.rb deleted file mode 100644 index 281c68fc4..000000000 --- a/acceptance/pending/pluginsync/7316_faces_should_be_available_via_pluginsync.rb +++ /dev/null @@ -1,242 +0,0 @@ -test_name "the pluginsync functionality should sync app definitions, and they should be runnable afterwards" - -# -# This test is intended to ensure that pluginsync syncs face definitions to the agents. -# Further, the face should be runnable on the agent after the sync has occurred. -# -# (NOTE: When this test is passing, it should resolve both #7316 re: verifying that apps/faces can -# be run on the agent node after a plugin sync, and #6753 re: being able to run a face without -# having a placeholder stub file in the "applications" directory.) -# - -############################################################################### -# BEGIN UTILITY METHODS - ideally this stuff would live somewhere besides in -# the actual test. -############################################################################### - -# Create a file on the host. -# Parameters: -# [host] the host 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_test_file(host, file_rel_path, file_content, options) - - # set default options - options[:mkdirs] ||= false - options[:owner] ||= "root" - options[:group] ||= "puppet" - options[:mode] ||= "755" - - file_path = get_test_file_path(host, file_rel_path) - - mkdirs(host, File.dirname(file_path)) if (options[:mkdirs] == true) - create_remote_file(host, file_path, file_content) - -# -# NOTE: we need these chown/chmod calls because the acceptance framework connects to the nodes as "root", but -# puppet 'master' runs as user 'puppet'. Therefore, in order for puppet master to be able to read any files -# that we've created, we have to carefully set their permissions -# - - chown(host, options[:owner], options[:group], file_path) - chmod(host, options[:mode], file_path) - -end - - -# Given a relative path, returns an absolute path for a test file. Basically, this just prepends the -# a unique temp dir path (specific to the current test execution) to your relative path. -def get_test_file_path(host, file_rel_path) - File.join(@host_test_tmp_dirs[host.name], file_rel_path) -end - - -# Check for the existence of a temp file for the current test; basically, this just calls file_exists?(), -# but prepends the path to the current test's temp dir onto the file_rel_path parameter. This allows -# tests to be written using only a relative path to specify file locations, while still taking advantage -# of automatic temp file cleanup at test completion. -def test_file_exists?(host, file_rel_path) - host.execute("test -f \"#{get_test_file_path(host, file_rel_path)}\"", - :acceptable_exit_codes => [0, 1]) do |result| - return result.exit_code == 0 - end -end - -def tmpdir(host, basename) - host_tmpdir = host.tmpdir(basename) - # we need to make sure that the puppet user can traverse this directory... - chmod(host, "755", host_tmpdir) - host_tmpdir -end - -def mkdirs(host, dir_path) - on(host, "mkdir -p #{dir_path}") -end - -def chown(host, owner, group, path) - on(host, "chown #{owner}:#{group} #{path}") -end - -def chmod(host, mode, path) - on(host, "chmod #{mode} #{path}") -end - - - - -# pluck this out of the test case environment; not sure if there is a better way -cur_test_file = @path -cur_test_file_shortname = File.basename(cur_test_file, File.extname(cur_test_file)) - -# we need one list of all of the hosts, to assist in managing temp dirs. It's possible -# that the master is also an agent, so this will consolidate them into a unique set -all_hosts = Set[master, *agents] - -# now we can create a hash of temp dirs--one per host, and unique to this test--without worrying about -# doing it twice on any individual host -@host_test_tmp_dirs = Hash[all_hosts.map do |host| [host.name, tmpdir(host, cur_test_file_shortname)] end ] - -# a silly variable for keeping track of whether or not all of the tests passed... -all_tests_passed = false - -############################################################################### -# END UTILITY METHODS -############################################################################### - - - -############################################################################### -# BEGIN TEST LOGIC -############################################################################### - -# create some vars to point to the directories that we're going to point the master/agents at -master_module_dir = "master_modules" -agent_lib_dir = "agent_lib" - -app_name = "superbogus" -app_desc = "a simple %1$s for testing %1$s delivery via plugin sync" -app_output = "Hello from the #{app_name} %s" - -master_module_file_content = {} - - -master_module_file_content["face"] = <<-HERE -Puppet::Face.define(:#{app_name}, '0.0.1') do - copyright "Puppet Labs", 2011 - license "Apache 2 license; see COPYING" - - summary "#{app_desc % "face"}" - - action(:foo) do - summary "a test action defined in the test face in the main puppet lib dir" - - default - when_invoked do |*args| - puts "#{app_output % "face"}" - end - end - -end -HERE - - - -# this begin block is here for handling temp file cleanup via an "ensure" block at the very end of the -# test. -begin - - modes = ["face"] - - modes.each do |mode| - - # here we create a custom app, which basically doesn't do anything except for print a hello-world message - agent_module_app_file = "#{agent_lib_dir}/puppet/#{mode}/#{app_name}.rb" - master_module_app_file = "#{master_module_dir}/#{app_name}/lib/puppet/#{mode}/#{app_name}.rb" - - - # copy all the files to the master - step "write our simple module out to the master" do - create_test_file(master, master_module_app_file, master_module_file_content[mode], :mkdirs => true) - end - - step "verify that the app file exists on the master" do - unless test_file_exists?(master, master_module_app_file) then - fail_test("Failed to create app file '#{get_test_file_path(master, master_module_app_file)}' on master") - end - end - - step "start the master" do - with_master_running_on(master, - "--modulepath=\"#{get_test_file_path(master, master_module_dir)}\"") do - - # the module files shouldn't exist on the agent yet because they haven't been synced - step "verify that the module files don't exist on the agent path" do - agents.each do |agent| - if test_file_exists?(agent, agent_module_app_file) then - fail_test("app file already exists on agent: '#{get_test_file_path(agent, agent_module_app_file)}'") - end - end - end - - step "run the agent" do - agents.each do |agent| - run_agent_on(agent, "--trace --libdir=\"#{get_test_file_path(agent, agent_lib_dir)}\" " + - "--no-daemonize --verbose --onetime --test --server #{master}") - end - end - - end - end - - step "verify that the module files were synced down to the agent" do - agents.each do |agent| - unless test_file_exists?(agent, agent_module_app_file) then - fail_test("Expected app file not synced to agent: '#{get_test_file_path(agent, agent_module_app_file)}'") - end - end - end - - step "verify that the application shows up in help" do - agents.each do |agent| - on(agent, PuppetCommand.new(:help, "--libdir=\"#{get_test_file_path(agent, agent_lib_dir)}\"")) do - assert_match(/^\s+#{app_name}\s+#{app_desc % mode}$/, result.stdout) - end - end - end - - step "verify that we can run the application" do - agents.each do |agent| - on(agent, PuppetCommand.new(:"#{app_name}", "--libdir=\"#{get_test_file_path(agent, agent_lib_dir)}\"")) do - assert_match(/^#{app_output % mode}$/, result.stdout) - end - end - end - - step "clear out the libdir on the agents in preparation for the next test" do - agents.each do |agent| - on(agent, "rm -rf #{get_test_file_path(agent, agent_module_app_file)}/*") - end - end - - end - - all_tests_passed = true - -ensure - ########################################################################################## - # Clean up all of the temp files created by this test. It would be nice if this logic - # could be handled outside of the test itself; I envision a stanza like this one appearing - # in a very large number of the tests going forward unless it is handled by the framework. - ########################################################################################## - if all_tests_passed then - all_hosts.each do |host| - on(host, "rm -rf #{@host_test_tmp_dirs[host.name]}") - end - end -end \ No newline at end of file diff --git a/acceptance/tests/agent/agent_disable_lockfile.rb b/acceptance/tests/agent/agent_disable_lockfile.rb index 6881f78bd..b7d57ed6a 100644 --- a/acceptance/tests/agent/agent_disable_lockfile.rb +++ b/acceptance/tests/agent/agent_disable_lockfile.rb @@ -1,209 +1,104 @@ test_name "the agent --disable/--enable functionality should manage the agent lockfile properly" # # This test is intended to ensure that puppet agent --enable/--disable # work properly, both in terms of complying with our public "API" around # lockfile semantics ( http://links.puppetlabs.com/agent_lockfiles ), and # in terms of actually restricting or allowing new agent runs to begin. # -############################################################################### -# BEGIN UTILITY METHODS - ideally this stuff would live somewhere besides in -# the actual test. -############################################################################### - -# Create a file on the host. -# Parameters: -# [host] the host 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_test_file(host, file_rel_path, file_content, options) - - # set default options - options[:mkdirs] ||= false - options[:owner] ||= "root" - options[:group] ||= "puppet" - options[:mode] ||= "755" - - file_path = get_test_file_path(host, file_rel_path) - - mkdirs(host, File.dirname(file_path)) if (options[:mkdirs] == true) - create_remote_file(host, file_path, file_content) - -# -# NOTE: we need these chown/chmod calls because the acceptance framework connects to the nodes as "root", but -# puppet 'master' runs as user 'puppet'. Therefore, in order for puppet master to be able to read any files -# that we've created, we have to carefully set their permissions -# - - chown(host, options[:owner], options[:group], file_path) - chmod(host, options[:mode], file_path) - -end +require 'puppet/acceptance/temp_file_utils' -# Given a relative path, returns an absolute path for a test file. Basically, this just prepends the -# a unique temp dir path (specific to the current test execution) to your relative path. -def get_test_file_path(host, file_rel_path) - File.join(@host_test_tmp_dirs[host.name], file_rel_path) -end - - -# Check for the existence of a temp file for the current test; basically, this just calls file_exists?(), -# but prepends the path to the current test's temp dir onto the file_rel_path parameter. This allows -# tests to be written using only a relative path to specify file locations, while still taking advantage -# of automatic temp file cleanup at test completion. -def test_file_exists?(host, file_rel_path) - file_exists?(host, get_test_file_path(host, file_rel_path)) -end - -def file_exists?(host, file_path) - host.execute("test -f \"#{file_path}\"", - :acceptable_exit_codes => [0, 1]) do |result| - return result.exit_code == 0 - end -end - -def file_contents(host, file_path) - host.execute("cat \"#{file_path}\"") do |result| - return result.stdout - end -end - -def tmpdir(host, basename) - host_tmpdir = host.tmpdir(basename) - # we need to make sure that the puppet user can traverse this directory... - chmod(host, "755", host_tmpdir) - host_tmpdir -end +extend Puppet::Acceptance::TempFileUtils -def mkdirs(host, dir_path) - on(host, "mkdir -p #{dir_path}") -end - -def chown(host, owner, group, path) - on(host, "chown #{owner}:#{group} #{path}") -end - -def chmod(host, mode, path) - on(host, "chmod #{mode} #{path}") -end - - - - -# pluck this out of the test case environment; not sure if there is a better way -cur_test_file = @path -cur_test_file_shortname = File.basename(cur_test_file, File.extname(cur_test_file)) - -# we need one list of all of the hosts, to assist in managing temp dirs. It's possible -# that the master is also an agent, so this will consolidate them into a unique set -all_hosts = Set[master, *agents] - -# now we can create a hash of temp dirs--one per host, and unique to this test--without worrying about -# doing it twice on any individual host -@host_test_tmp_dirs = Hash[all_hosts.map do |host| [host.name, tmpdir(host, cur_test_file_shortname)] end ] - -# a silly variable for keeping track of whether or not all of the tests passed... +initialize_temp_dirs() all_tests_passed = false -############################################################################### -# END UTILITY METHODS -############################################################################### - - ############################################################################### # BEGIN TEST LOGIC ############################################################################### # this begin block is here for handling temp file cleanup via an "ensure" block at the very end of the # test. begin tuples = [ ["reason not specified", false], ["I'm busy; go away.'", true] ] step "start the master" do with_master_running_on(master, "--autosign true") do tuples.each do |expected_message, explicitly_specify_message| step "disable the agent; specify message? '#{explicitly_specify_message}', message: '#{expected_message}'" do agents.each do |agent| if (explicitly_specify_message) run_agent_on(agent, "--disable \"#{expected_message}\"") else run_agent_on(agent, "--disable") end agent_disabled_lockfile = "#{agent['puppetvardir']}/state/agent_disabled.lock" unless file_exists?(agent, agent_disabled_lockfile) then fail_test("Failed to create disabled lock file '#{agent_disabled_lockfile}' on agent '#{agent}'") end lock_file_content = file_contents(agent, agent_disabled_lockfile) # This is a hack; we should parse the JSON into a hash, but I don't think I have a library available # from the acceptance test framework that I can use to do that. So I'm falling back to regex. lock_file_content_regex = /"disabled_message"\s*:\s*"#{expected_message}"/ unless lock_file_content =~ lock_file_content_regex fail_test("Disabled lock file contents invalid; expected to match '#{lock_file_content_regex}', got '#{lock_file_content}' on agent '#{agent}'") end end end step "attempt to run the agent (message: '#{expected_message}')" do agents.each do |agent| run_agent_on(agent, "--no-daemonize --verbose --onetime --test --server #{master}", :acceptable_exit_codes => [1]) do disabled_regex = /administratively disabled.*'#{expected_message}'/ unless result.stdout =~ disabled_regex fail_test("Unexpected output from attempt to run agent disabled; expecting to match '#{disabled_regex}', got '#{result.stdout}' on agent '#{agent}'") end end end end step "enable the agent (message: '#{expected_message}')" do agents.each do |agent| agent_disabled_lockfile = "#{agent['puppetvardir']}/state/agent_disabled.lock" run_agent_on(agent, "--enable") if file_exists?(agent, agent_disabled_lockfile) then fail_test("Failed to remove disabled lock file '#{agent_disabled_lockfile}' on agent '#{agent}'") end end step "verify that we can run the agent (message: '#{expected_message}')" do agents.each do |agent| run_agent_on(agent) end end end end end end all_tests_passed = true ensure ########################################################################################## # Clean up all of the temp files created by this test. It would be nice if this logic # could be handled outside of the test itself; I envision a stanza like this one appearing # in a very large number of the tests going forward unless it is handled by the framework. ########################################################################################## if all_tests_passed then - all_hosts.each do |host| - on(host, "rm -rf #{@host_test_tmp_dirs[host.name]}") - end + remove_temp_dirs() end end \ No newline at end of file diff --git a/acceptance/tests/pluginsync/7316_apps_should_be_available_via_pluginsync.rb b/acceptance/tests/pluginsync/7316_apps_should_be_available_via_pluginsync.rb index b3f393029..c24c68011 100644 --- a/acceptance/tests/pluginsync/7316_apps_should_be_available_via_pluginsync.rb +++ b/acceptance/tests/pluginsync/7316_apps_should_be_available_via_pluginsync.rb @@ -1,237 +1,141 @@ test_name "the pluginsync functionality should sync app definitions, and they should be runnable afterwards" # # This test is intended to ensure that pluginsync syncs app definitions to the agents. # Further, the apps should be runnable on the agent after the sync has occurred. # -############################################################################### -# BEGIN UTILITY METHODS - ideally this stuff would live somewhere besides in -# the actual test. -############################################################################### - -# Create a file on the host. -# Parameters: -# [host] the host 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_test_file(host, file_rel_path, file_content, options) - - # set default options - options[:mkdirs] ||= false - options[:owner] ||= "root" - options[:group] ||= "puppet" - options[:mode] ||= "755" - - file_path = get_test_file_path(host, file_rel_path) - - mkdirs(host, File.dirname(file_path)) if (options[:mkdirs] == true) - create_remote_file(host, file_path, file_content) - -# -# NOTE: we need these chown/chmod calls because the acceptance framework connects to the nodes as "root", but -# puppet 'master' runs as user 'puppet'. Therefore, in order for puppet master to be able to read any files -# that we've created, we have to carefully set their permissions -# - - chown(host, options[:owner], options[:group], file_path) - chmod(host, options[:mode], file_path) - -end - - -# Given a relative path, returns an absolute path for a test file. Basically, this just prepends the -# a unique temp dir path (specific to the current test execution) to your relative path. -def get_test_file_path(host, file_rel_path) - File.join(@host_test_tmp_dirs[host.name], file_rel_path) -end - - -# Check for the existence of a temp file for the current test; basically, this just calls file_exists?(), -# but prepends the path to the current test's temp dir onto the file_rel_path parameter. This allows -# tests to be written using only a relative path to specify file locations, while still taking advantage -# of automatic temp file cleanup at test completion. -def test_file_exists?(host, file_rel_path) - host.execute("test -f \"#{get_test_file_path(host, file_rel_path)}\"", - :acceptable_exit_codes => [0, 1]) do |result| - return result.exit_code == 0 - end -end - -def tmpdir(host, basename) - host_tmpdir = host.tmpdir(basename) - # we need to make sure that the puppet user can traverse this directory... - chmod(host, "755", host_tmpdir) - host_tmpdir -end - -def mkdirs(host, dir_path) - on(host, "mkdir -p #{dir_path}") -end - -def chown(host, owner, group, path) - on(host, "chown #{owner}:#{group} #{path}") -end - -def chmod(host, mode, path) - on(host, "chmod #{mode} #{path}") -end - - +require 'puppet/acceptance/temp_file_utils' +extend Puppet::Acceptance::TempFileUtils -# pluck this out of the test case environment; not sure if there is a better way -cur_test_file = @path -cur_test_file_shortname = File.basename(cur_test_file, File.extname(cur_test_file)) +initialize_temp_dirs() -# we need one list of all of the hosts, to assist in managing temp dirs. It's possible -# that the master is also an agent, so this will consolidate them into a unique set -all_hosts = Set[master, *agents] - -# now we can create a hash of temp dirs--one per host, and unique to this test--without worrying about -# doing it twice on any individual host -@host_test_tmp_dirs = Hash[all_hosts.map do |host| [host.name, tmpdir(host, cur_test_file_shortname)] end ] - -# a silly variable for keeping track of whether or not all of the tests passed... all_tests_passed = false -############################################################################### -# END UTILITY METHODS -############################################################################### - - - ############################################################################### # BEGIN TEST LOGIC ############################################################################### # create some vars to point to the directories that we're going to point the master/agents at master_module_dir = "master_modules" agent_lib_dir = "agent_lib" app_name = "superbogus" app_desc = "a simple %1$s for testing %1$s delivery via plugin sync" app_output = "Hello from the #{app_name} %s" master_module_file_content = {} master_module_file_content["application"] = <<-HERE require 'puppet/application' class Puppet::Application::#{app_name.capitalize} < Puppet::Application def help <<-HELP puppet-#{app_name}(8) -- #{app_desc % "application"} ======== HELP end def main() puts("#{app_output % "application"}") end end HERE # this begin block is here for handling temp file cleanup via an "ensure" block at the very end of the # test. begin modes = ["application"] modes.each do |mode| # here we create a custom app, which basically doesn't do anything except for print a hello-world message agent_module_app_file = "#{agent_lib_dir}/puppet/#{mode}/#{app_name}.rb" master_module_app_file = "#{master_module_dir}/#{app_name}/lib/puppet/#{mode}/#{app_name}.rb" # copy all the files to the master step "write our simple module out to the master" do create_test_file(master, master_module_app_file, master_module_file_content[mode], :mkdirs => true) end step "verify that the app file exists on the master" do unless test_file_exists?(master, master_module_app_file) then fail_test("Failed to create app file '#{get_test_file_path(master, master_module_app_file)}' on master") end end step "start the master" do with_master_running_on(master, "--modulepath=\"#{get_test_file_path(master, master_module_dir)}\" " + "--autosign true") do # the module files shouldn't exist on the agent yet because they haven't been synced step "verify that the module files don't exist on the agent path" do agents.each do |agent| if test_file_exists?(agent, agent_module_app_file) then fail_test("app file already exists on agent: '#{get_test_file_path(agent, agent_module_app_file)}'") end end end step "run the agent" do agents.each do |agent| run_agent_on(agent, "--trace --libdir=\"#{get_test_file_path(agent, agent_lib_dir)}\" " + "--no-daemonize --verbose --onetime --test --server #{master}") end end end end step "verify that the module files were synced down to the agent" do agents.each do |agent| unless test_file_exists?(agent, agent_module_app_file) then fail_test("Expected app file not synced to agent: '#{get_test_file_path(agent, agent_module_app_file)}'") end end end step "verify that the application shows up in help" do agents.each do |agent| on(agent, PuppetCommand.new(:help, "--libdir=\"#{get_test_file_path(agent, agent_lib_dir)}\"")) do assert_match(/^\s+#{app_name}\s+#{app_desc % mode}/, result.stdout) end end end step "verify that we can run the application" do agents.each do |agent| on(agent, PuppetCommand.new(:"#{app_name}", "--libdir=\"#{get_test_file_path(agent, agent_lib_dir)}\"")) do assert_match(/^#{app_output % mode}/, result.stdout) end end end step "clear out the libdir on the agents in preparation for the next test" do agents.each do |agent| on(agent, "rm -rf #{get_test_file_path(agent, agent_lib_dir)}/*") end end end all_tests_passed = true ensure ########################################################################################## # Clean up all of the temp files created by this test. It would be nice if this logic # could be handled outside of the test itself; I envision a stanza like this one appearing # in a very large number of the tests going forward unless it is handled by the framework. ########################################################################################## if all_tests_passed then - all_hosts.each do |host| - on(host, "rm -rf #{@host_test_tmp_dirs[host.name]}") - end + remove_temp_dirs() end end \ No newline at end of file diff --git a/acceptance/tests/pluginsync/7316_faces_with_app_stubs_should_be_available_via_pluginsync.rb b/acceptance/tests/pluginsync/7316_faces_with_app_stubs_should_be_available_via_pluginsync.rb index 1862736aa..3d7a70cba 100644 --- a/acceptance/tests/pluginsync/7316_faces_with_app_stubs_should_be_available_via_pluginsync.rb +++ b/acceptance/tests/pluginsync/7316_faces_with_app_stubs_should_be_available_via_pluginsync.rb @@ -1,258 +1,161 @@ test_name "the pluginsync functionality should sync app definitions, and they should be runnable afterwards" # # This test is intended to ensure that pluginsync syncs face definitions to the agents. # Further, the face should be runnable on the agent after the sync has occurred. # # (NOTE: When this test is passing, it should resolve both #7316 re: verifying that apps/faces can # be run on the agent node after a plugin sync, and #6753 re: being able to run a face without # having a placeholder stub file in the "applications" directory.) # -############################################################################### -# BEGIN UTILITY METHODS - ideally this stuff would live somewhere besides in -# the actual test. -############################################################################### - -# Create a file on the host. -# Parameters: -# [host] the host 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_test_file(host, file_rel_path, file_content, options) - - # set default options - options[:mkdirs] ||= false - options[:owner] ||= "root" - options[:group] ||= "puppet" - options[:mode] ||= "755" - - file_path = get_test_file_path(host, file_rel_path) - - mkdirs(host, File.dirname(file_path)) if (options[:mkdirs] == true) - create_remote_file(host, file_path, file_content) - -# -# NOTE: we need these chown/chmod calls because the acceptance framework connects to the nodes as "root", but -# puppet 'master' runs as user 'puppet'. Therefore, in order for puppet master to be able to read any files -# that we've created, we have to carefully set their permissions -# - - chown(host, options[:owner], options[:group], file_path) - chmod(host, options[:mode], file_path) - -end +require 'puppet/acceptance/temp_file_utils' +extend Puppet::Acceptance::TempFileUtils -# Given a relative path, returns an absolute path for a test file. Basically, this just prepends the -# a unique temp dir path (specific to the current test execution) to your relative path. -def get_test_file_path(host, file_rel_path) - File.join(@host_test_tmp_dirs[host.name], file_rel_path) -end - - -# Check for the existence of a temp file for the current test; basically, this just calls file_exists?(), -# but prepends the path to the current test's temp dir onto the file_rel_path parameter. This allows -# tests to be written using only a relative path to specify file locations, while still taking advantage -# of automatic temp file cleanup at test completion. -def test_file_exists?(host, file_rel_path) - host.execute("test -f \"#{get_test_file_path(host, file_rel_path)}\"", - :acceptable_exit_codes => [0, 1]) do |result| - return result.exit_code == 0 - end -end - -def tmpdir(host, basename) - host_tmpdir = host.tmpdir(basename) - # we need to make sure that the puppet user can traverse this directory... - chmod(host, "755", host_tmpdir) - host_tmpdir -end - -def mkdirs(host, dir_path) - on(host, "mkdir -p #{dir_path}") -end - -def chown(host, owner, group, path) - on(host, "chown #{owner}:#{group} #{path}") -end - -def chmod(host, mode, path) - on(host, "chmod #{mode} #{path}") -end - - - - -# pluck this out of the test case environment; not sure if there is a better way -cur_test_file = @path -cur_test_file_shortname = File.basename(cur_test_file, File.extname(cur_test_file)) - -# we need one list of all of the hosts, to assist in managing temp dirs. It's possible -# that the master is also an agent, so this will consolidate them into a unique set -all_hosts = Set[master, *agents] - -# now we can create a hash of temp dirs--one per host, and unique to this test--without worrying about -# doing it twice on any individual host -@host_test_tmp_dirs = Hash[all_hosts.map do |host| [host.name, tmpdir(host, cur_test_file_shortname)] end ] - -# a silly variable for keeping track of whether or not all of the tests passed... +initialize_temp_dirs() all_tests_passed = false -############################################################################### -# END UTILITY METHODS -############################################################################### - - - ############################################################################### # BEGIN TEST LOGIC ############################################################################### # create some vars to point to the directories that we're going to point the master/agents at master_module_dir = "master_modules" agent_lib_dir = "agent_lib" app_name = "superbogus" app_desc = "a simple %1$s for testing %1$s delivery via plugin sync" app_output = "Hello from the #{app_name} %s" master_module_file_content = {} master_module_face_content = <<-HERE Puppet::Face.define(:#{app_name}, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" summary "#{app_desc % "face"}" action(:foo) do summary "a test action defined in the test face in the main puppet lib dir" default when_invoked do |*args| puts "#{app_output % "face"}" end end end HERE master_module_app_content = <<-HERE require 'puppet/application/face_base' class Puppet::Application::#{app_name.capitalize} < Puppet::Application::FaceBase end HERE # this begin block is here for handling temp file cleanup via an "ensure" block at the very end of the # test. begin # here we create a custom app, which basically doesn't do anything except for print a hello-world message agent_module_face_file = "#{agent_lib_dir}/puppet/face/#{app_name}.rb" master_module_face_file = "#{master_module_dir}/#{app_name}/lib/puppet/face/#{app_name}.rb" agent_module_app_file = "#{agent_lib_dir}/puppet/application/#{app_name}.rb" master_module_app_file = "#{master_module_dir}/#{app_name}/lib/puppet/application/#{app_name}.rb" # copy all the files to the master step "write our simple module out to the master" do create_test_file(master, master_module_app_file, master_module_app_content, :mkdirs => true) create_test_file(master, master_module_face_file, master_module_face_content, :mkdirs => true) end step "verify that the app file exists on the master" do unless test_file_exists?(master, master_module_app_file) then fail_test("Failed to create app file '#{get_test_file_path(master, master_module_app_file)}' on master") end unless test_file_exists?(master, master_module_face_file) then fail_test("Failed to create face file '#{get_test_file_path(master, master_module_face_file)}' on master") end end step "start the master" do with_master_running_on(master, "--modulepath=\"#{get_test_file_path(master, master_module_dir)}\" " + "--autosign true") do # the module files shouldn't exist on the agent yet because they haven't been synced step "verify that the module files don't exist on the agent path" do agents.each do |agent| if test_file_exists?(agent, agent_module_app_file) then fail_test("app file already exists on agent: '#{get_test_file_path(agent, agent_module_app_file)}'") end if test_file_exists?(agent, agent_module_app_file) then fail_test("face file already exists on agent: '#{get_test_file_path(agent, agent_module_face_file)}'") end end end step "run the agent" do agents.each do |agent| run_agent_on(agent, "--trace --libdir=\"#{get_test_file_path(agent, agent_lib_dir)}\" " + "--no-daemonize --verbose --onetime --test --server #{master}") end end end end step "verify that the module files were synced down to the agent" do agents.each do |agent| unless test_file_exists?(agent, agent_module_app_file) then fail_test("Expected app file not synced to agent: '#{get_test_file_path(agent, agent_module_app_file)}'") end unless test_file_exists?(agent, agent_module_face_file) then fail_test("Expected face file not synced to agent: '#{get_test_file_path(agent, agent_module_face_file)}'") end end end step "verify that the application shows up in help" do agents.each do |agent| on(agent, PuppetCommand.new(:help, "--libdir=\"#{get_test_file_path(agent, agent_lib_dir)}\"")) do assert_match(/^\s+#{app_name}\s+#{app_desc % "face"}/, result.stdout) end end end step "verify that we can run the application" do agents.each do |agent| on(agent, PuppetCommand.new(:"#{app_name}", "--libdir=\"#{get_test_file_path(agent, agent_lib_dir)}\"")) do assert_match(/^#{app_output % "face"}/, result.stdout) end end end step "clear out the libdir on the agents in preparation for the next test" do agents.each do |agent| on(agent, "rm -rf #{get_test_file_path(agent, agent_lib_dir)}/*") end end all_tests_passed = true ensure ########################################################################################## # Clean up all of the temp files created by this test. It would be nice if this logic # could be handled outside of the test itself; I envision a stanza like this one appearing # in a very large number of the tests going forward unless it is handled by the framework. ########################################################################################## if all_tests_passed then - all_hosts.each do |host| - on(host, "rm -rf #{@host_test_tmp_dirs[host.name]}") - end + remove_temp_dirs() end end \ No newline at end of file diff --git a/acceptance/tests/pluginsync/apply_should_sync_plugins.rb b/acceptance/tests/pluginsync/apply_should_sync_plugins.rb index ca6122c64..d626aaaf6 100644 --- a/acceptance/tests/pluginsync/apply_should_sync_plugins.rb +++ b/acceptance/tests/pluginsync/apply_should_sync_plugins.rb @@ -1,147 +1,41 @@ test_name "puppet apply should pluginsync" -############################################################################### -# BEGIN UTILITY METHODS - ideally this stuff would live somewhere besides in -# the actual test. -############################################################################### -# Create a file on the host. -# Parameters: -# [host] the host 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_test_file(host, file_rel_path, file_content, options) +require 'puppet/acceptance/temp_file_utils' - # set default options - options[:mkdirs] ||= false - options[:owner] ||= "root" - options[:group] ||= "puppet" - options[:mode] ||= "755" +extend Puppet::Acceptance::TempFileUtils - file_path = get_test_file_path(host, file_rel_path) +initialize_temp_dirs() - mkdirs(host, File.dirname(file_path)) if (options[:mkdirs] == true) - create_remote_file(host, file_path, file_content) - -# -# NOTE: we need these chown/chmod calls because the acceptance framework connects to the nodes as "root", but -# puppet 'master' runs as user 'puppet'. Therefore, in order for puppet master to be able to read any files -# that we've created, we have to carefully set their permissions -# - - chown(host, options[:owner], options[:group], file_path) - chmod(host, options[:mode], file_path) - -end - - -# Given a relative path, returns an absolute path for a test file. Basically, this just prepends the -# a unique temp dir path (specific to the current test execution) to your relative path. -def get_test_file_path(host, file_rel_path) - File.join(@host_test_tmp_dirs[host.name], file_rel_path) -end - - -# Check for the existence of a temp file for the current test; basically, this just calls file_exists?(), -# but prepends the path to the current test's temp dir onto the file_rel_path parameter. This allows -# tests to be written using only a relative path to specify file locations, while still taking advantage -# of automatic temp file cleanup at test completion. -def test_file_exists?(host, file_rel_path) - file_exists?(host, get_test_file_path(host, file_rel_path)) -end - -def file_exists?(host, file_path) - host.execute("test -f \"#{file_path}\"", - :acceptable_exit_codes => [0, 1]) do |result| - return result.exit_code == 0 - end -end - -def file_contents(host, file_path) - host.execute("cat \"#{file_path}\"") do |result| - return result.stdout - end -end - -def tmpdir(host, basename) - host_tmpdir = host.tmpdir(basename) - # we need to make sure that the puppet user can traverse this directory... - chmod(host, "755", host_tmpdir) - host_tmpdir -end - -def mkdirs(host, dir_path) - on(host, "mkdir -p #{dir_path}") -end - -def chown(host, owner, group, path) - if host['platform'].include?('windows') - return; - end - on(host, "chown #{owner}:#{group} #{path}") -end - -def chmod(host, mode, path) - on(host, "chmod #{mode} #{path}") -end - - - - -# pluck this out of the test case environment; not sure if there is a better way -cur_test_file = @path -cur_test_file_shortname = File.basename(cur_test_file, File.extname(cur_test_file)) - -# we need one list of all of the hosts, to assist in managing temp dirs. It's possible -# that the master is also an agent, so this will consolidate them into a unique set -all_hosts = Set[master, *agents] - -# now we can create a hash of temp dirs--one per host, and unique to this test--without worrying about -# doing it twice on any individual host -@host_test_tmp_dirs = Hash[all_hosts.map do |host| [host.name, tmpdir(host, cur_test_file_shortname)] end ] - -# a silly variable for keeping track of whether or not all of the tests passed... all_tests_passed = false -############################################################################### -# END UTILITY METHODS -############################################################################### - - step "Create some modules in the modulepath" basedir = 'tmp_acceptance_pluginsync_modules' module1libdir = "#{basedir}/1/a/lib" module2libdir = "#{basedir}/2/a/lib" begin agents.each do |agent| create_test_file(agent, get_test_file_path(agent, "#{module1libdir}/foo.rb"), "#1a", :mkdirs => true) create_test_file(agent, get_test_file_path(agent, "#{module2libdir}//foo.rb"), "#2a", :mkdirs => true) on agent, puppet_apply("--modulepath=#{get_test_file_path(agent, "#{basedir}/1")}:#{get_test_file_path(agent, "#{basedir}/2")} --pluginsync -e 'notify { \"hello\": }'") agent.execute("cat #{agent['puppetvardir']}/lib/foo.rb", {}) do assert_match(/#1a/, stdout, "The synced plugin was not found or the wrong version was synced") end end + all_tests_passed = true ensure ########################################################################################## # Clean up all of the temp files created by this test. It would be nice if this logic # could be handled outside of the test itself; I envision a stanza like this one appearing # in a very large number of the tests going forward unless it is handled by the framework. ########################################################################################## if all_tests_passed then - all_hosts.each do |host| - on(host, "rm -rf #{@host_test_tmp_dirs[host.name]}") - end + remove_temp_dirs() end end diff --git a/acceptance/tests/pluginsync/feature/pluginsync_should_sync_features.rb b/acceptance/tests/pluginsync/feature/pluginsync_should_sync_features.rb index 80d1c381a..3cc48ec99 100644 --- a/acceptance/tests/pluginsync/feature/pluginsync_should_sync_features.rb +++ b/acceptance/tests/pluginsync/feature/pluginsync_should_sync_features.rb @@ -1,286 +1,189 @@ test_name "the pluginsync functionality should sync feature definitions" # # This test is intended to ensure that pluginsync syncs feature definitions to the agents. It checks the feature # twice; once to make sure that it gets loaded successfully during the run in which it was synced, and once to # ensure that it still gets loaded successfully during the subsequent run (in which it should not be synced because # the files haven't changed.) # +require 'puppet/acceptance/temp_file_utils' -############################################################################### -# BEGIN UTILITY METHODS - ideally this stuff would live somewhere besides in -# the actual test. -############################################################################### - -# Create a file on the host. -# Parameters: -# [host] the host 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_test_file(host, file_rel_path, file_content, options) - - # set default options - options[:mkdirs] ||= false - options[:owner] ||= "root" - options[:group] ||= "puppet" - options[:mode] ||= "755" - - file_path = get_test_file_path(host, file_rel_path) - - mkdirs(host, File.dirname(file_path)) if (options[:mkdirs] == true) - create_remote_file(host, file_path, file_content) - -# -# NOTE: we need these chown/chmod calls because the acceptance framework connects to the nodes as "root", but -# puppet 'master' runs as user 'puppet'. Therefore, in order for puppet master to be able to read any files -# that we've created, we have to carefully set their permissions -# - - chown(host, options[:owner], options[:group], file_path) - chmod(host, options[:mode], file_path) - -end +extend Puppet::Acceptance::TempFileUtils +initialize_temp_dirs() -# Given a relative path, returns an absolute path for a test file. Basically, this just prepends the -# a unique temp dir path (specific to the current test execution) to your relative path. -def get_test_file_path(host, file_rel_path) - File.join(@host_test_tmp_dirs[host.name], file_rel_path) -end - - -# Check for the existence of a temp file for the current test; basically, this just calls file_exists?(), -# but prepends the path to the current test's temp dir onto the file_rel_path parameter. This allows -# tests to be written using only a relative path to specify file locations, while still taking advantage -# of automatic temp file cleanup at test completion. -def test_file_exists?(host, file_rel_path) - host.execute("test -f \"#{get_test_file_path(host, file_rel_path)}\"", - :acceptable_exit_codes => [0, 1]) do |result| - return result.exit_code == 0 - end -end - -def tmpdir(host, basename) - host_tmpdir = host.tmpdir(basename) - # we need to make sure that the puppet user can traverse this directory... - chmod(host, "755", host_tmpdir) - host_tmpdir -end - -def mkdirs(host, dir_path) - on(host, "mkdir -p #{dir_path}") -end - -def chown(host, owner, group, path) - on(host, "chown #{owner}:#{group} #{path}") -end - -def chmod(host, mode, path) - on(host, "chmod #{mode} #{path}") -end - - - - - -# pluck this out of the test case environment; not sure if there is a better way -cur_test_file = @path -cur_test_file_shortname = File.basename(cur_test_file, File.extname(cur_test_file)) - -# we need one list of all of the hosts, to assist in managing temp dirs. It's possible -# that the master is also an agent, so this will consolidate them into a unique set -all_hosts = Set[master, *agents] - -# now we can create a hash of temp dirs--one per host, and unique to this test--without worrying about -# doing it twice on any individual host -@host_test_tmp_dirs = Hash[all_hosts.map do |host| [host.name, tmpdir(host, cur_test_file_shortname)] end ] - -# a silly variable for keeping track of whether or not all of the tests passed... all_tests_passed = false -############################################################################### -# END UTILITY METHODS -############################################################################### - - ############################################################################### # BEGIN TEST LOGIC ############################################################################### # create some vars to point to the directories that we're going to point the master/agents at test_identifier = "pluginsync_should_sync_features" master_module_dir = "master_modules" agent_lib_dir = "agent_lib" module_name = "superbogus" # here we create a custom type, which basically doesn't do anything except for test the value of # our custom feature and write the result to a file agent_module_type_file = "#{agent_lib_dir}/puppet/type/#{module_name}.rb" master_module_type_file = "#{master_module_dir}/#{module_name}/lib/puppet/type/#{module_name}.rb" master_module_type_content = < "Hi. I'm setting the testfeature property of #{module_name} here in site.pp", } HERE # for convenience we build up a list of all of the files we are expecting to deploy on the master all_master_files = [ [master_module_feature_file, 'feature'], [master_module_type_file, 'type'], [master_manifest_file, 'manifest'] ] # for convenience we build up a list of all of the files we are expecting to deploy on the agents all_agent_files = [ [agent_module_feature_file, 'feature'], [agent_module_type_file, 'type'] ] # the command line args we'll pass to the agent each time we call it agent_args = "--trace --libdir=\"%s\" --pluginsync --no-daemonize --verbose " + "--onetime --test --server #{master}" # legal exit codes whenever we run the agent # we need to allow exit code 2, which means "changes were applied" on the agent agent_exit_codes = [0, 2] # this begin block is here for handling temp file cleanup via an "ensure" block at the very end of the # test. begin # copy all the files to the master step "write our simple module out to the master" do create_test_file(master, master_module_type_file, master_module_type_content, :mkdirs => true) create_test_file(master, master_module_feature_file, master_module_feature_content, :mkdirs => true) create_test_file(master, master_manifest_file, master_manifest_content, :mkdirs => true) end step "verify that the module and manifest files exist on the master" do all_master_files.each do |file_path, desc| unless test_file_exists?(master, file_path) then fail_test("Failed to create #{desc} file '#{get_test_file_path(master, file_path)}' on master") end end end step "start the master" do with_master_running_on(master, "--manifest=\"#{get_test_file_path(master, master_manifest_file)}\" " + "--modulepath=\"#{get_test_file_path(master, master_module_dir)}\" " + "--autosign true --pluginsync") do # the module files shouldn't exist on the agent yet because they haven't been synced step "verify that the module files don't exist on the agent path" do agents.each do |agent| all_agent_files.each do |file_path, desc| if test_file_exists?(agent, file_path) then fail_test("#{desc} file already exists on agent: '#{get_test_file_path(agent, file_path)}'") end end end end step "run the agent and verify that it loaded the feature" do agents.each do |agent| run_agent_on(agent, agent_args % get_test_file_path(agent, agent_lib_dir), :acceptable_exit_codes => agent_exit_codes) do assert_match(/The value of the #{module_name} feature is: true/, result.stdout, "Expected agent stdout to include confirmation that the feature was 'true'") end end end step "verify that the module files were synced down to the agent" do agents.each do |agent| all_agent_files.each do |file_path, desc| unless test_file_exists?(agent, file_path) then fail_test("Expected #{desc} file not synced to agent: '#{get_test_file_path(agent, file_path)}'") end end end end step "run the agent again" do agents.each do |agent| run_agent_on(agent, agent_args % get_test_file_path(agent, agent_lib_dir), :acceptable_exit_codes => agent_exit_codes) do assert_match(/The value of the #{module_name} feature is: true/, result.stdout, "Expected agent stdout to include confirmation that the feature was 'true'") end end end #TODO: was thinking about putting in a check for the timestamps on the files (maybe add a method for that to # the framework?) to verify that they didn't get re-synced, but it seems like more trouble than it's worth # at the moment. #step "verify that the module files were not re-synced" do # fail_test("NOT YET IMPLEMENTED: verify that the module files were not re-synced") #end end all_tests_passed = true end ensure ########################################################################################## # Clean up all of the temp files created by this test. It would be nice if this logic # could be handled outside of the test itself; I envision a stanza like this one appearing # in a very large number of the tests going forward unless it is handled by the framework. ########################################################################################## if all_tests_passed then - all_hosts.each do |host| - on(host, "rm -rf #{@host_test_tmp_dirs[host.name]}") - end + remove_temp_dirs() end end diff --git a/acceptance/tests/ticket_13948_lib_dir_hook_should_be_called_on_initialization.rb b/acceptance/tests/ticket_13948_lib_dir_hook_should_be_called_on_initialization.rb index d20c5da61..f54f4d835 100644 --- a/acceptance/tests/ticket_13948_lib_dir_hook_should_be_called_on_initialization.rb +++ b/acceptance/tests/ticket_13948_lib_dir_hook_should_be_called_on_initialization.rb @@ -1,259 +1,155 @@ test_name "the $libdir setting hook is called on startup" -# -# This test is intended to ensure that pluginsync syncs face definitions to the agents. -# Further, the face should be runnable on the agent after the sync has occurred. -# -# (NOTE: When this test is passing, it should resolve both #7316 re: verifying that apps/faces can -# be run on the agent node after a plugin sync, and #6753 re: being able to run a face without -# having a placeholder stub file in the "applications" directory.) -# - -############################################################################### -# BEGIN UTILITY METHODS - ideally this stuff would live somewhere besides in -# the actual test. -############################################################################### - -# Create a file on the host. -# Parameters: -# [host] the host 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_test_file(host, file_rel_path, file_content, options) - - # set default options - options[:mkdirs] ||= false - options[:owner] ||= "root" - options[:group] ||= "puppet" - options[:mode] ||= "755" - - file_path = get_test_file_path(host, file_rel_path) - - mkdirs(host, File.dirname(file_path)) if (options[:mkdirs] == true) - create_remote_file(host, file_path, file_content) - -# -# NOTE: we need these chown/chmod calls because the acceptance framework connects to the nodes as "root", but -# puppet 'master' runs as user 'puppet'. Therefore, in order for puppet master to be able to read any files -# that we've created, we have to carefully set their permissions -# - - chown(host, options[:owner], options[:group], file_path) - chmod(host, options[:mode], file_path) - -end - - -# Given a relative path, returns an absolute path for a test file. Basically, this just prepends the -# a unique temp dir path (specific to the current test execution) to your relative path. -def get_test_file_path(host, file_rel_path) - File.join(@host_test_tmp_dirs[host.name], file_rel_path) -end - - -# Check for the existence of a temp file for the current test; basically, this just calls file_exists?(), -# but prepends the path to the current test's temp dir onto the file_rel_path parameter. This allows -# tests to be written using only a relative path to specify file locations, while still taking advantage -# of automatic temp file cleanup at test completion. -def test_file_exists?(host, file_rel_path) - host.execute("test -f \"#{get_test_file_path(host, file_rel_path)}\"", - :acceptable_exit_codes => [0, 1]) do |result| - return result.exit_code == 0 - end -end - -def tmpdir(host, basename) - host_tmpdir = host.tmpdir(basename) - # we need to make sure that the puppet user can traverse this directory... - chmod(host, "755", host_tmpdir) - host_tmpdir -end - -def mkdirs(host, dir_path) - on(host, "mkdir -p #{dir_path}") -end - -def chown(host, owner, group, path) - on(host, "chown #{owner}:#{group} #{path}") -end - -def chmod(host, mode, path) - on(host, "chmod #{mode} #{path}") -end - - -# pluck this out of the test case environment; not sure if there is a better way -cur_test_file = @path -cur_test_file_shortname = File.basename(cur_test_file, File.extname(cur_test_file)) +require 'puppet/acceptance/temp_file_utils' -# we need one list of all of the hosts, to assist in managing temp dirs. It's possible -# that the master is also an agent, so this will consolidate them into a unique set -all_hosts = Set[master, *agents] +extend Puppet::Acceptance::TempFileUtils -# now we can create a hash of temp dirs--one per host, and unique to this test--without worrying about -# doing it twice on any individual host -@host_test_tmp_dirs = Hash[all_hosts.map do |host| [host.name, tmpdir(host, cur_test_file_shortname)] end ] - -# a silly variable for keeping track of whether or not all of the tests passed... +initialize_temp_dirs() all_tests_passed = false -############################################################################### -# END UTILITY METHODS -############################################################################### - - - ############################################################################### # BEGIN TEST LOGIC ############################################################################### # create some vars to point to the directories that we're going to point the master/agents at master_module_dir = "master_modules" agent_var_dir = "agent_var" agent_lib_dir = "#{agent_var_dir}/lib" app_name = "superbogus" app_desc = "a simple %1$s for testing %1$s delivery via plugin sync" app_output = "Hello from the #{app_name} %s" master_module_file_content = {} master_module_face_content = <<-HERE Puppet::Face.define(:#{app_name}, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" summary "#{app_desc % "face"}" action(:foo) do summary "a test action defined in the test face in the main puppet lib dir" default when_invoked do |*args| puts "#{app_output % "face"}" end end end HERE master_module_app_content = <<-HERE require 'puppet/application/face_base' class Puppet::Application::#{app_name.capitalize} < Puppet::Application::FaceBase end HERE # this begin block is here for handling temp file cleanup via an "ensure" block at the very end of the # test. begin # here we create a custom app, which basically doesn't do anything except for print a hello-world message agent_module_face_file = "#{agent_lib_dir}/puppet/face/#{app_name}.rb" master_module_face_file = "#{master_module_dir}/#{app_name}/lib/puppet/face/#{app_name}.rb" agent_module_app_file = "#{agent_lib_dir}/puppet/application/#{app_name}.rb" master_module_app_file = "#{master_module_dir}/#{app_name}/lib/puppet/application/#{app_name}.rb" # copy all the files to the master step "write our simple module out to the master" do create_test_file(master, master_module_app_file, master_module_app_content, :mkdirs => true) create_test_file(master, master_module_face_file, master_module_face_content, :mkdirs => true) end step "verify that the app file exists on the master" do unless test_file_exists?(master, master_module_app_file) then fail_test("Failed to create app file '#{get_test_file_path(master, master_module_app_file)}' on master") end unless test_file_exists?(master, master_module_face_file) then fail_test("Failed to create face file '#{get_test_file_path(master, master_module_face_file)}' on master") end end step "start the master" do with_master_running_on(master, "--modulepath=\"#{get_test_file_path(master, master_module_dir)}\" " + "--autosign true") do # the module files shouldn't exist on the agent yet because they haven't been synced step "verify that the module files don't exist on the agent path" do agents.each do |agent| if test_file_exists?(agent, agent_module_app_file) then fail_test("app file already exists on agent: '#{get_test_file_path(agent, agent_module_app_file)}'") end if test_file_exists?(agent, agent_module_app_file) then fail_test("face file already exists on agent: '#{get_test_file_path(agent, agent_module_face_file)}'") end end end step "run the agent" do agents.each do |agent| run_agent_on(agent, "--trace --vardir=\"#{get_test_file_path(agent, agent_var_dir)}\" " + "--no-daemonize --verbose --onetime --test --server #{master}") end end end end step "verify that the module files were synced down to the agent" do agents.each do |agent| unless test_file_exists?(agent, agent_module_app_file) then fail_test("Expected app file not synced to agent: '#{get_test_file_path(agent, agent_module_app_file)}'") end unless test_file_exists?(agent, agent_module_face_file) then fail_test("Expected face file not synced to agent: '#{get_test_file_path(agent, agent_module_face_file)}'") end end end step "verify that the application shows up in help" do agents.each do |agent| on(agent, PuppetCommand.new(:help, "--vardir=\"#{get_test_file_path(agent, agent_var_dir)}\"")) do assert_match(/^\s+#{app_name}\s+#{app_desc % "face"}/, result.stdout) end end end step "verify that we can run the application" do agents.each do |agent| on(agent, PuppetCommand.new(:"#{app_name}", "--vardir=\"#{get_test_file_path(agent, agent_var_dir)}\"")) do assert_match(/^#{app_output % "face"}/, result.stdout) end end end step "clear out the libdir on the agents in preparation for the next test" do agents.each do |agent| on(agent, "rm -rf #{get_test_file_path(agent, agent_lib_dir)}/*") end end all_tests_passed = true ensure ########################################################################################## # Clean up all of the temp files created by this test. It would be nice if this logic # could be handled outside of the test itself; I envision a stanza like this one appearing # in a very large number of the tests going forward unless it is handled by the framework. ########################################################################################## if all_tests_passed then - all_hosts.each do |host| - on(host, "rm -rf #{@host_test_tmp_dirs[host.name]}") - end + remove_temp_dirs() end end \ No newline at end of file