Splitting the Agent class into Agent and Configurer
Once I went to add runinterval support to the Agent class, I realized it's really two classes: One that handles starting, stopping, running, et al (still called Agent), and one that handles downloading the catalog, running it, etc. (now called Configurer). This commit includes some additional code, but 95% of it is just moving code around. Signed-off-by: Luke Kanies <luke@madstop.com>
This commit is contained in:
Родитель
e8be6dcad2
Коммит
fc14b81f99
26
bin/puppetd
26
bin/puppetd
|
@ -162,7 +162,8 @@ trap(:INT) do
|
|||
end
|
||||
|
||||
require 'puppet'
|
||||
require 'puppet/network/client'
|
||||
require 'puppet/agent'
|
||||
require 'puppet/configurer'
|
||||
require 'getoptlong'
|
||||
|
||||
options = [
|
||||
|
@ -329,13 +330,19 @@ Puppet::SSL::Host.ca_location = :remote
|
|||
|
||||
Puppet::Transaction::Report.terminus_class = :rest
|
||||
|
||||
Puppet::Resource::Catalog.terminus_class = :rest
|
||||
Puppet::Resource::Catalog.cache_class = :yaml
|
||||
|
||||
Puppet::Node::Facts.terminus_class = :facter
|
||||
Puppet::Node::Facts.cache_class = :rest
|
||||
|
||||
# We need tomake the client either way, we just don't start it
|
||||
# if --no-client is set.
|
||||
client = Puppet::Network::Client.master.new(args)
|
||||
agent = Puppet::Agent.new(Puppet::Configurer)
|
||||
if options[:enable]
|
||||
client.enable
|
||||
agent.enable
|
||||
elsif options[:disable]
|
||||
client.disable
|
||||
agent.disable
|
||||
end
|
||||
|
||||
if options[:enable] or options[:disable]
|
||||
|
@ -347,12 +354,11 @@ server = nil
|
|||
# It'd be nice to daemonize later, but we have to daemonize before the
|
||||
# waitforcert happens.
|
||||
if Puppet[:daemonize]
|
||||
client.daemonize
|
||||
agent.daemonize
|
||||
end
|
||||
|
||||
host = Puppet::SSL::Host.new
|
||||
cert = host.wait_for_cert(options[:waitforcert])
|
||||
client.recycle_connection
|
||||
|
||||
objects = []
|
||||
|
||||
|
@ -402,7 +408,7 @@ elsif options[:onetime] and Puppet[:listen]
|
|||
end
|
||||
|
||||
if options[:client]
|
||||
objects << client
|
||||
objects << agent
|
||||
end
|
||||
|
||||
# Set traps for INT and TERM
|
||||
|
@ -417,10 +423,10 @@ if options[:onetime]
|
|||
end
|
||||
|
||||
# Add the service, so the traps work correctly.
|
||||
Puppet.newservice(client)
|
||||
Puppet.newservice(agent)
|
||||
|
||||
begin
|
||||
client.run
|
||||
agent.run
|
||||
rescue => detail
|
||||
if Puppet[:trace]
|
||||
puts detail.backtrace
|
||||
|
@ -435,7 +441,7 @@ else
|
|||
|
||||
if options[:client]
|
||||
Puppet.notice "Starting Puppet client version %s" % [Puppet.version]
|
||||
Puppet.newservice(client)
|
||||
Puppet.newservice(agent)
|
||||
end
|
||||
|
||||
Puppet.settraps
|
||||
|
|
|
@ -1,201 +1,74 @@
|
|||
# The client for interacting with the puppetmaster config server.
|
||||
require 'sync'
|
||||
require 'timeout'
|
||||
require 'puppet/network/http_pool'
|
||||
require 'puppet/util'
|
||||
require 'puppet/daemon'
|
||||
|
||||
# A general class for triggering a run of another
|
||||
# class.
|
||||
class Puppet::Agent
|
||||
require 'puppet/agent/fact_handler'
|
||||
require 'puppet/agent/plugin_handler'
|
||||
require 'puppet/agent/locker'
|
||||
include Puppet::Daemon
|
||||
|
||||
include Puppet::Agent::FactHandler
|
||||
include Puppet::Agent::PluginHandler
|
||||
require 'puppet/agent/locker'
|
||||
include Puppet::Agent::Locker
|
||||
|
||||
# For benchmarking
|
||||
include Puppet::Util
|
||||
attr_reader :client_class, :client
|
||||
attr_accessor :stopping
|
||||
|
||||
unless defined? @@sync
|
||||
@@sync = Sync.new
|
||||
end
|
||||
|
||||
attr_accessor :catalog
|
||||
attr_reader :compile_time
|
||||
|
||||
class << self
|
||||
# Puppetd should only have one instance running, and we need a way
|
||||
# to retrieve it.
|
||||
attr_accessor :instance
|
||||
include Puppet::Util
|
||||
end
|
||||
|
||||
def clear
|
||||
@catalog.clear(true) if @catalog
|
||||
@catalog = nil
|
||||
end
|
||||
|
||||
# Initialize and load storage
|
||||
def dostorage
|
||||
begin
|
||||
Puppet::Util::Storage.load
|
||||
@compile_time ||= Puppet::Util::Storage.cache(:configuration)[:compile_time]
|
||||
rescue => detail
|
||||
if Puppet[:trace]
|
||||
puts detail.backtrace
|
||||
end
|
||||
Puppet.err "Corrupt state file %s: %s" % [Puppet[:statefile], detail]
|
||||
begin
|
||||
::File.unlink(Puppet[:statefile])
|
||||
retry
|
||||
rescue => detail
|
||||
raise Puppet::Error.new("Cannot remove %s: %s" %
|
||||
[Puppet[:statefile], detail])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Just so we can specify that we are "the" instance.
|
||||
def initialize
|
||||
Puppet.settings.use(:main, :ssl, :puppetd)
|
||||
|
||||
self.class.instance = self
|
||||
@running = false
|
||||
def initialize(client_class)
|
||||
@splayed = false
|
||||
|
||||
@client_class = client_class
|
||||
end
|
||||
|
||||
# Prepare for catalog retrieval. Downloads everything necessary, etc.
|
||||
def prepare
|
||||
dostorage()
|
||||
|
||||
download_plugins()
|
||||
|
||||
download_fact_plugins()
|
||||
|
||||
upload_facts()
|
||||
def lockfile_path
|
||||
client_class.lockfile_path
|
||||
end
|
||||
|
||||
# Mark that we should restart. The Puppet module checks whether we're running,
|
||||
# so this only gets called if we're in the middle of a run.
|
||||
def restart
|
||||
# If we're currently running, then just mark for later
|
||||
Puppet.notice "Received signal to restart; waiting until run is complete"
|
||||
@restart = true
|
||||
end
|
||||
|
||||
# Should we restart?
|
||||
def restart?
|
||||
if defined? @restart
|
||||
@restart
|
||||
else
|
||||
false
|
||||
# Perform a run with our client.
|
||||
def run
|
||||
if client
|
||||
Puppet.notice "Run of %s already in progress; skipping" % client_class
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# Get the remote catalog, yo. Returns nil if no catalog can be found.
|
||||
def retrieve_catalog
|
||||
name = Facter.value("hostname")
|
||||
catalog_class = Puppet::Resource::Catalog
|
||||
|
||||
# First try it with no cache, then with the cache.
|
||||
result = nil
|
||||
begin
|
||||
duration = thinmark do
|
||||
result = catalog_class.find(name, :use_cache => false)
|
||||
end
|
||||
rescue => detail
|
||||
puts detail.backtrace if Puppet[:trace]
|
||||
Puppet.err "Could not retrieve catalog from remote server: %s" % detail
|
||||
if stopping?
|
||||
Puppet.notice "In shutdown progress; skipping run"
|
||||
return
|
||||
end
|
||||
|
||||
unless result
|
||||
splay
|
||||
with_client do |client|
|
||||
begin
|
||||
duration = thinmark do
|
||||
result = catalog_class.find(name, :use_cache => true)
|
||||
end
|
||||
sync.synchronize { lock { client.run } }
|
||||
rescue => detail
|
||||
puts detail.backtrace if Puppet[:trace]
|
||||
Puppet.err "Could not retrieve catalog from cache: %s" % detail
|
||||
Puppet.err "Could not run %s: %s" % [client_class, detail]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def shutdown
|
||||
if self.stopping?
|
||||
Puppet.notice "Already in shutdown"
|
||||
return
|
||||
end
|
||||
self.stopping = true
|
||||
if client and client.respond_to?(:stop)
|
||||
begin
|
||||
client.stop
|
||||
rescue
|
||||
puts detail.backtrace if Puppet[:trace]
|
||||
Puppet.err "Could not stop %s: %s" % [client_class, detail]
|
||||
end
|
||||
end
|
||||
|
||||
return nil unless result
|
||||
|
||||
convert_catalog(result, duration)
|
||||
super
|
||||
ensure
|
||||
self.stopping = false
|
||||
end
|
||||
|
||||
# Convert a plain resource catalog into our full host catalog.
|
||||
def convert_catalog(result, duration)
|
||||
catalog = result.to_ral
|
||||
catalog.retrieval_duration = duration
|
||||
catalog.host_config = true
|
||||
catalog.write_class_file
|
||||
return catalog
|
||||
end
|
||||
|
||||
# The code that actually runs the catalog.
|
||||
# This just passes any options on to the catalog,
|
||||
# which accepts :tags and :ignoreschedules.
|
||||
def run(options = {})
|
||||
got_lock = false
|
||||
splay
|
||||
Puppet::Util.sync(:puppetrun).synchronize(Sync::EX) do
|
||||
got_lock = lock do
|
||||
unless catalog = retrieve_catalog
|
||||
Puppet.err "Could not retrieve catalog; skipping run"
|
||||
return
|
||||
end
|
||||
|
||||
begin
|
||||
benchmark(:notice, "Finished catalog run") do
|
||||
catalog.apply(options)
|
||||
end
|
||||
rescue => detail
|
||||
puts detail.backtrace if Puppet[:trace]
|
||||
Puppet.err "Failed to apply catalog: %s" % detail
|
||||
end
|
||||
end
|
||||
|
||||
unless got_lock
|
||||
Puppet.notice "Lock file %s exists; skipping catalog run" % lockfile.lockfile
|
||||
return
|
||||
end
|
||||
|
||||
# Now close all of our existing http connections, since there's no
|
||||
# reason to leave them lying open.
|
||||
Puppet::Network::HttpPool.clear_http_instances
|
||||
|
||||
lockfile.unlock
|
||||
|
||||
# Did we get HUPped during the run? If so, then restart now that we're
|
||||
# done with the run.
|
||||
Process.kill(:HUP, $$) if self.restart?
|
||||
end
|
||||
end
|
||||
|
||||
def running?
|
||||
lockfile.locked?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.timeout
|
||||
timeout = Puppet[:configtimeout]
|
||||
case timeout
|
||||
when String:
|
||||
if timeout =~ /^\d+$/
|
||||
timeout = Integer(timeout)
|
||||
else
|
||||
raise ArgumentError, "Configuration timeout must be an integer"
|
||||
end
|
||||
when Integer: # nothing
|
||||
else
|
||||
raise ArgumentError, "Configuration timeout must be an integer"
|
||||
end
|
||||
|
||||
return timeout
|
||||
def stopping?
|
||||
stopping
|
||||
end
|
||||
|
||||
# Have we splayed already?
|
||||
def splayed?
|
||||
@splayed
|
||||
end
|
||||
|
@ -210,4 +83,44 @@ class Puppet::Agent
|
|||
sleep(time)
|
||||
@splayed = true
|
||||
end
|
||||
|
||||
# Start listening for events. We're pretty much just listening for
|
||||
# timer events here.
|
||||
def start
|
||||
# Create our timer. Puppet will handle observing it and such.
|
||||
Puppet.newtimer(
|
||||
:interval => Puppet[:runinterval],
|
||||
:tolerance => 1,
|
||||
:start? => true
|
||||
) do
|
||||
run()
|
||||
end
|
||||
|
||||
# Run once before we start following the timer
|
||||
run()
|
||||
end
|
||||
|
||||
def sync
|
||||
unless defined?(@sync) and @sync
|
||||
@sync = Sync.new
|
||||
end
|
||||
@sync
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Create and yield a client instance, keeping a reference
|
||||
# to it during the yield.
|
||||
def with_client
|
||||
begin
|
||||
@client = client_class.new
|
||||
rescue => details
|
||||
puts detail.backtrace if Puppet[:trace]
|
||||
Puppet.err "Could not create instance of %s: %s" % [client_class, details]
|
||||
return
|
||||
end
|
||||
yield @client
|
||||
ensure
|
||||
@client = nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,9 +30,14 @@ module Puppet::Agent::Locker
|
|||
|
||||
def lockfile
|
||||
unless defined?(@lockfile)
|
||||
@lockfile = Puppet::Util::Pidlock.new(Puppet[:puppetdlockfile])
|
||||
#@lockfile = Puppet::Util::Pidlock.new(Puppet[:puppetdlockfile])
|
||||
@lockfile = Puppet::Util::Pidlock.new(lockfile_path)
|
||||
end
|
||||
|
||||
@lockfile
|
||||
end
|
||||
|
||||
def running?
|
||||
lockfile.locked?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,185 @@
|
|||
# The client for interacting with the puppetmaster config server.
|
||||
require 'sync'
|
||||
require 'timeout'
|
||||
require 'puppet/network/http_pool'
|
||||
require 'puppet/util'
|
||||
|
||||
class Puppet::Configurer
|
||||
require 'puppet/configurer/fact_handler'
|
||||
require 'puppet/configurer/plugin_handler'
|
||||
|
||||
include Puppet::Configurer::FactHandler
|
||||
include Puppet::Configurer::PluginHandler
|
||||
|
||||
# For benchmarking
|
||||
include Puppet::Util
|
||||
|
||||
attr_accessor :catalog
|
||||
attr_reader :compile_time
|
||||
|
||||
# Provide more helpful strings to the logging that the Agent does
|
||||
def self.to_s
|
||||
"Puppet configuration client"
|
||||
end
|
||||
|
||||
class << self
|
||||
# Puppetd should only have one instance running, and we need a way
|
||||
# to retrieve it.
|
||||
attr_accessor :instance
|
||||
include Puppet::Util
|
||||
end
|
||||
|
||||
# How to lock instances of this class.
|
||||
def self.lockfile_path
|
||||
Puppet[:puppetdlockfile]
|
||||
end
|
||||
|
||||
def clear
|
||||
@catalog.clear(true) if @catalog
|
||||
@catalog = nil
|
||||
end
|
||||
|
||||
# Initialize and load storage
|
||||
def dostorage
|
||||
begin
|
||||
Puppet::Util::Storage.load
|
||||
@compile_time ||= Puppet::Util::Storage.cache(:configuration)[:compile_time]
|
||||
rescue => detail
|
||||
if Puppet[:trace]
|
||||
puts detail.backtrace
|
||||
end
|
||||
Puppet.err "Corrupt state file %s: %s" % [Puppet[:statefile], detail]
|
||||
begin
|
||||
::File.unlink(Puppet[:statefile])
|
||||
retry
|
||||
rescue => detail
|
||||
raise Puppet::Error.new("Cannot remove %s: %s" %
|
||||
[Puppet[:statefile], detail])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Just so we can specify that we are "the" instance.
|
||||
def initialize
|
||||
Puppet.settings.use(:main, :ssl, :puppetd)
|
||||
|
||||
self.class.instance = self
|
||||
@running = false
|
||||
@splayed = false
|
||||
end
|
||||
|
||||
# Prepare for catalog retrieval. Downloads everything necessary, etc.
|
||||
def prepare
|
||||
dostorage()
|
||||
|
||||
download_plugins()
|
||||
|
||||
download_fact_plugins()
|
||||
|
||||
upload_facts()
|
||||
end
|
||||
|
||||
# Mark that we should restart. The Puppet module checks whether we're running,
|
||||
# so this only gets called if we're in the middle of a run.
|
||||
def restart
|
||||
# If we're currently running, then just mark for later
|
||||
Puppet.notice "Received signal to restart; waiting until run is complete"
|
||||
@restart = true
|
||||
end
|
||||
|
||||
# Should we restart?
|
||||
def restart?
|
||||
if defined? @restart
|
||||
@restart
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
# Get the remote catalog, yo. Returns nil if no catalog can be found.
|
||||
def retrieve_catalog
|
||||
name = Facter.value("hostname")
|
||||
catalog_class = Puppet::Resource::Catalog
|
||||
|
||||
# First try it with no cache, then with the cache.
|
||||
result = nil
|
||||
begin
|
||||
duration = thinmark do
|
||||
result = catalog_class.find(name, :use_cache => false)
|
||||
end
|
||||
rescue => detail
|
||||
puts detail.backtrace if Puppet[:trace]
|
||||
Puppet.err "Could not retrieve catalog from remote server: %s" % detail
|
||||
end
|
||||
|
||||
unless result
|
||||
begin
|
||||
duration = thinmark do
|
||||
result = catalog_class.find(name, :use_cache => true)
|
||||
end
|
||||
rescue => detail
|
||||
puts detail.backtrace if Puppet[:trace]
|
||||
Puppet.err "Could not retrieve catalog from cache: %s" % detail
|
||||
end
|
||||
end
|
||||
|
||||
return nil unless result
|
||||
|
||||
convert_catalog(result, duration)
|
||||
end
|
||||
|
||||
# Convert a plain resource catalog into our full host catalog.
|
||||
def convert_catalog(result, duration)
|
||||
catalog = result.to_ral
|
||||
catalog.retrieval_duration = duration
|
||||
catalog.host_config = true
|
||||
catalog.write_class_file
|
||||
return catalog
|
||||
end
|
||||
|
||||
# The code that actually runs the catalog.
|
||||
# This just passes any options on to the catalog,
|
||||
# which accepts :tags and :ignoreschedules.
|
||||
def run(options = {})
|
||||
unless catalog = retrieve_catalog
|
||||
Puppet.err "Could not retrieve catalog; skipping run"
|
||||
return
|
||||
end
|
||||
|
||||
begin
|
||||
benchmark(:notice, "Finished catalog run") do
|
||||
catalog.apply(options)
|
||||
end
|
||||
rescue => detail
|
||||
puts detail.backtrace if Puppet[:trace]
|
||||
Puppet.err "Failed to apply catalog: %s" % detail
|
||||
end
|
||||
|
||||
# Now close all of our existing http connections, since there's no
|
||||
# reason to leave them lying open.
|
||||
Puppet::Network::HttpPool.clear_http_instances
|
||||
|
||||
# Did we get HUPped during the run? If so, then restart now that we're
|
||||
# done with the run.
|
||||
Process.kill(:HUP, $$) if self.restart?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.timeout
|
||||
timeout = Puppet[:configtimeout]
|
||||
case timeout
|
||||
when String:
|
||||
if timeout =~ /^\d+$/
|
||||
timeout = Integer(timeout)
|
||||
else
|
||||
raise ArgumentError, "Configuration timeout must be an integer"
|
||||
end
|
||||
when Integer: # nothing
|
||||
else
|
||||
raise ArgumentError, "Configuration timeout must be an integer"
|
||||
end
|
||||
|
||||
return timeout
|
||||
end
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
require 'puppet/agent'
|
||||
require 'puppet/resource/catalog'
|
||||
|
||||
class Puppet::Agent::Downloader
|
||||
class Puppet::Configurer::Downloader
|
||||
attr_reader :name, :path, :source, :ignore
|
||||
|
||||
# Determine the timeout value to use.
|
|
@ -3,7 +3,7 @@ require 'puppet/indirector/facts/facter'
|
|||
# Break out the code related to facts. This module is
|
||||
# just included into the agent, but having it here makes it
|
||||
# easier to test.
|
||||
module Puppet::Agent::FactHandler
|
||||
module Puppet::Configurer::FactHandler
|
||||
def download_fact_plugins?
|
||||
Puppet[:factsync]
|
||||
end
|
||||
|
@ -23,7 +23,7 @@ module Puppet::Agent::FactHandler
|
|||
def download_fact_plugins
|
||||
return unless download_fact_plugins?
|
||||
|
||||
Puppet::Agent::Downloader.new("fact", Puppet[:factsource], Puppet[:factdest], Puppet[:factsignore]).evaluate
|
||||
Puppet::Configurer::Downloader.new("fact", Puppet[:factsource], Puppet[:factdest], Puppet[:factsignore]).evaluate
|
||||
end
|
||||
|
||||
# Clear out all of the loaded facts and reload them from disk.
|
|
@ -1,7 +1,7 @@
|
|||
# Break out the code related to plugins. This module is
|
||||
# just included into the agent, but having it here makes it
|
||||
# easier to test.
|
||||
module Puppet::Agent::PluginHandler
|
||||
module Puppet::Configurer::PluginHandler
|
||||
def download_plugins?
|
||||
Puppet[:pluginsync]
|
||||
end
|
||||
|
@ -9,7 +9,7 @@ module Puppet::Agent::PluginHandler
|
|||
# Retrieve facts from the central server.
|
||||
def download_plugins
|
||||
return nil unless download_plugins?
|
||||
Puppet::Agent::Downloader.new("plugin", Puppet[:pluginsource], Puppet[:plugindest], Puppet[:pluginsignore]).evaluate.each { |file| load_plugin(file) }
|
||||
Puppet::Configurer::Downloader.new("plugin", Puppet[:pluginsource], Puppet[:plugindest], Puppet[:pluginsignore]).evaluate.each { |file| load_plugin(file) }
|
||||
end
|
||||
|
||||
def load_plugin(file)
|
|
@ -76,8 +76,6 @@ module Puppet::Daemon
|
|||
Puppet::Util::Log.destinations.reject { |d| d == :console }.each do |dest|
|
||||
Puppet::Util::Log.close(dest)
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -6,255 +6,200 @@
|
|||
require File.dirname(__FILE__) + '/../spec_helper'
|
||||
require 'puppet/agent'
|
||||
|
||||
class AgentTestClient
|
||||
def run
|
||||
# no-op
|
||||
end
|
||||
def stop
|
||||
# no-op
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Agent do
|
||||
it "should include the Plugin Handler module" do
|
||||
Puppet::Agent.ancestors.should be_include(Puppet::Agent::PluginHandler)
|
||||
before do
|
||||
@agent = Puppet::Agent.new(AgentTestClient)
|
||||
|
||||
# So we don't actually try to hit the filesystem.
|
||||
@agent.stubs(:lock).yields
|
||||
end
|
||||
|
||||
it "should include the Fact Handler module" do
|
||||
Puppet::Agent.ancestors.should be_include(Puppet::Agent::FactHandler)
|
||||
it "should set its client class at initialization" do
|
||||
Puppet::Agent.new("foo").client_class.should == "foo"
|
||||
end
|
||||
|
||||
it "should include the Locker module" do
|
||||
Puppet::Agent.ancestors.should be_include(Puppet::Agent::Locker)
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Agent, "when executing a catalog run" do
|
||||
before do
|
||||
Puppet.settings.stubs(:use).returns(true)
|
||||
@agent = Puppet::Agent.new
|
||||
@agent.stubs(:splay)
|
||||
@agent.stubs(:lock).yields.then.returns true
|
||||
end
|
||||
it "should create an instance of its client class and run it when asked to run" do
|
||||
client = mock 'client'
|
||||
AgentTestClient.expects(:new).returns client
|
||||
|
||||
it "should splay" do
|
||||
Puppet::Util.sync(:puppetrun).stubs(:synchronize)
|
||||
@agent.expects(:splay)
|
||||
@agent.run
|
||||
end
|
||||
|
||||
it "should use a global mutex to make sure no other thread is executing the catalog" do
|
||||
sync = mock 'sync'
|
||||
Puppet::Util.expects(:sync).with(:puppetrun).returns sync
|
||||
|
||||
sync.expects(:synchronize)
|
||||
|
||||
@agent.expects(:retrieve_config).never # i.e., if we don't yield, we don't retrieve the config
|
||||
@agent.run
|
||||
end
|
||||
|
||||
it "should retrieve the catalog if a lock is attained" do
|
||||
@agent.expects(:lock).yields.then.returns true
|
||||
|
||||
@agent.expects(:retrieve_catalog)
|
||||
client.expects(:run)
|
||||
|
||||
@agent.run
|
||||
end
|
||||
|
||||
it "should log and do nothing if the lock cannot be acquired" do
|
||||
@agent.expects(:lock).returns false
|
||||
|
||||
@agent.expects(:retrieve_catalog).never
|
||||
|
||||
Puppet.expects(:notice)
|
||||
|
||||
@agent.run
|
||||
it "should determine its lock file path by asking the client class" do
|
||||
AgentTestClient.expects(:lockfile_path).returns "/my/lock"
|
||||
@agent.lockfile_path.should == "/my/lock"
|
||||
end
|
||||
|
||||
it "should retrieve the catalog" do
|
||||
@agent.expects(:retrieve_catalog)
|
||||
describe "when running" do
|
||||
it "should splay" do
|
||||
@agent.expects(:splay)
|
||||
|
||||
@agent.run
|
||||
@agent.run
|
||||
end
|
||||
|
||||
it "should do nothing if a client instance exists" do
|
||||
@agent.expects(:client).returns "eh"
|
||||
AgentTestClient.expects(:new).never
|
||||
@agent.run
|
||||
end
|
||||
|
||||
it "should do nothing if it is in the process of stopping" do
|
||||
@agent.expects(:stopping?).returns true
|
||||
AgentTestClient.expects(:new).never
|
||||
@agent.run
|
||||
end
|
||||
|
||||
it "should not fail if a client class instance cannot be created" do
|
||||
AgentTestClient.expects(:new).raises "eh"
|
||||
Puppet.expects(:err)
|
||||
@agent.run
|
||||
end
|
||||
|
||||
it "should not fail if there is an exception while running its client" do
|
||||
client = AgentTestClient.new
|
||||
AgentTestClient.expects(:new).returns client
|
||||
client.expects(:run).raises "eh"
|
||||
Puppet.expects(:err)
|
||||
@agent.run
|
||||
end
|
||||
|
||||
it "should use a mutex to restrict multi-threading" do
|
||||
client = AgentTestClient.new
|
||||
AgentTestClient.expects(:new).returns client
|
||||
|
||||
mutex = mock 'mutex'
|
||||
@agent.expects(:sync).returns mutex
|
||||
|
||||
mutex.expects(:synchronize)
|
||||
client.expects(:run).never # if it doesn't run, then we know our yield is what triggers it
|
||||
@agent.run
|
||||
end
|
||||
|
||||
it "should use a filesystem lock to restrict multiple processes running the agent" do
|
||||
client = AgentTestClient.new
|
||||
AgentTestClient.expects(:new).returns client
|
||||
|
||||
@agent.expects(:lock)
|
||||
|
||||
client.expects(:run).never # if it doesn't run, then we know our yield is what triggers it
|
||||
@agent.run
|
||||
end
|
||||
|
||||
it "should make its client instance available while running" do
|
||||
client = AgentTestClient.new
|
||||
AgentTestClient.expects(:new).returns client
|
||||
|
||||
client.expects(:run).with { @agent.client.should equal(client); true }
|
||||
@agent.run
|
||||
end
|
||||
end
|
||||
|
||||
it "should log a failure and do nothing if no catalog can be retrieved" do
|
||||
@agent.expects(:retrieve_catalog).returns nil
|
||||
describe "when splaying" do
|
||||
before do
|
||||
Puppet.settings.stubs(:value).with(:splay).returns true
|
||||
Puppet.settings.stubs(:value).with(:splaylimit).returns "10"
|
||||
end
|
||||
|
||||
Puppet.expects(:err)
|
||||
it "should do nothing if splay is disabled" do
|
||||
Puppet.settings.expects(:value).returns false
|
||||
@agent.expects(:sleep).never
|
||||
@agent.splay
|
||||
end
|
||||
|
||||
@agent.run
|
||||
end
|
||||
it "should do nothing if it has already splayed" do
|
||||
@agent.expects(:splayed?).returns true
|
||||
@agent.expects(:sleep).never
|
||||
@agent.splay
|
||||
end
|
||||
|
||||
it "should apply the catalog with all options to :run" do
|
||||
catalog = stub 'catalog', :retrieval_duration= => nil
|
||||
@agent.expects(:retrieve_catalog).returns catalog
|
||||
it "should log that it is splaying" do
|
||||
@agent.stubs :sleep
|
||||
Puppet.expects :info
|
||||
@agent.splay
|
||||
end
|
||||
|
||||
catalog.expects(:apply).with(:one => true)
|
||||
@agent.run :one => true
|
||||
it "should sleep for a random portion of the splaylimit plus 1" do
|
||||
Puppet.settings.expects(:value).with(:splaylimit).returns "50"
|
||||
@agent.expects(:rand).with(51).returns 10
|
||||
@agent.expects(:sleep).with(10)
|
||||
@agent.splay
|
||||
end
|
||||
|
||||
it "should mark that it has splayed" do
|
||||
@agent.stubs(:sleep)
|
||||
@agent.splay
|
||||
@agent.should be_splayed
|
||||
end
|
||||
end
|
||||
|
||||
it "should benchmark how long it takes to apply the catalog" do
|
||||
@agent.expects(:benchmark).with(:notice, "Finished catalog run")
|
||||
describe "when shutting down" do
|
||||
it "should do nothing if already stopping" do
|
||||
@agent.expects(:stopping?).returns true
|
||||
@agent.shutdown
|
||||
end
|
||||
|
||||
catalog = stub 'catalog', :retrieval_duration= => nil
|
||||
@agent.expects(:retrieve_catalog).returns catalog
|
||||
it "should stop the client if one is available and it responds to 'stop'" do
|
||||
client = AgentTestClient.new
|
||||
|
||||
catalog.expects(:apply).never # because we're not yielding
|
||||
@agent.run
|
||||
@agent.stubs(:client).returns client
|
||||
client.expects(:stop)
|
||||
@agent.shutdown
|
||||
end
|
||||
|
||||
it "should remove its pid file" do
|
||||
@agent.expects(:rmpidfile)
|
||||
@agent.shutdown
|
||||
end
|
||||
|
||||
it "should mark itself as stopping while waiting for the client to stop" do
|
||||
client = AgentTestClient.new
|
||||
|
||||
@agent.stubs(:client).returns client
|
||||
client.expects(:stop).with { @agent.should be_stopping; true }
|
||||
|
||||
@agent.shutdown
|
||||
end
|
||||
end
|
||||
|
||||
it "should HUP itself if it should be restarted" do
|
||||
catalog = stub 'catalog', :retrieval_duration= => nil, :apply => nil
|
||||
@agent.expects(:retrieve_catalog).returns catalog
|
||||
describe "when starting" do
|
||||
it "should create a timer with the runinterval, a tolerance of 1, and :start? set to true" do
|
||||
Puppet.settings.expects(:value).with(:runinterval).returns 5
|
||||
Puppet.expects(:newtimer).with(:interval => 5, :start? => true, :tolerance => 1)
|
||||
@agent.stubs(:run)
|
||||
@agent.start
|
||||
end
|
||||
|
||||
Process.expects(:kill).with(:HUP, $$)
|
||||
it "should run once immediately" do
|
||||
Puppet.stubs(:newtimer)
|
||||
@agent.expects(:run)
|
||||
@agent.start
|
||||
end
|
||||
|
||||
@agent.expects(:restart?).returns true
|
||||
it "should run within the block passed to the timer" do
|
||||
Puppet.stubs(:newtimer).yields
|
||||
@agent.expects(:run).times(2)
|
||||
@agent.start
|
||||
end
|
||||
|
||||
@agent.run
|
||||
end
|
||||
|
||||
it "should not HUP itself if it should not be restarted" do
|
||||
catalog = stub 'catalog', :retrieval_duration= => nil, :apply => nil
|
||||
@agent.expects(:retrieve_catalog).returns catalog
|
||||
|
||||
Process.expects(:kill).never
|
||||
|
||||
@agent.expects(:restart?).returns false
|
||||
|
||||
@agent.run
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Agent, "when retrieving a catalog" do
|
||||
before do
|
||||
Puppet.settings.stubs(:use).returns(true)
|
||||
@agent = Puppet::Agent.new
|
||||
|
||||
@catalog = Puppet::Resource::Catalog.new
|
||||
|
||||
@agent.stubs(:convert_catalog).returns @catalog
|
||||
end
|
||||
|
||||
it "should use the Catalog class to get its catalog" do
|
||||
Puppet::Resource::Catalog.expects(:find).returns @catalog
|
||||
|
||||
@agent.retrieve_catalog
|
||||
end
|
||||
|
||||
it "should use its Facter name to retrieve the catalog" do
|
||||
Facter.stubs(:value).returns "eh"
|
||||
Facter.expects(:value).with("hostname").returns "myhost"
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| name == "myhost" }.returns @catalog
|
||||
|
||||
@agent.retrieve_catalog
|
||||
end
|
||||
|
||||
it "should default to returning a catalog retrieved directly from the server, skipping the cache" do
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == false }.returns @catalog
|
||||
|
||||
@agent.retrieve_catalog.should == @catalog
|
||||
end
|
||||
|
||||
it "should return the cached catalog when no catalog can be retrieved from the server" do
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == false }.returns nil
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == true }.returns @catalog
|
||||
|
||||
@agent.retrieve_catalog.should == @catalog
|
||||
end
|
||||
|
||||
it "should not look in the cache for a catalog if one is returned from the server" do
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == false }.returns @catalog
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == true }.never
|
||||
|
||||
@agent.retrieve_catalog.should == @catalog
|
||||
end
|
||||
|
||||
it "should return the cached catalog when retrieving the remote catalog throws an exception" do
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == false }.raises "eh"
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == true }.returns @catalog
|
||||
|
||||
@agent.retrieve_catalog.should == @catalog
|
||||
end
|
||||
|
||||
it "should return nil if no cached catalog is available and no catalog can be retrieved from the server" do
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == false }.returns nil
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == true }.returns nil
|
||||
|
||||
@agent.retrieve_catalog.should be_nil
|
||||
end
|
||||
|
||||
it "should convert the catalog before returning" do
|
||||
Puppet::Resource::Catalog.stubs(:find).returns @catalog
|
||||
|
||||
@agent.expects(:convert_catalog).with { |cat, dur| cat == @catalog }.returns "converted catalog"
|
||||
@agent.retrieve_catalog.should == "converted catalog"
|
||||
end
|
||||
|
||||
it "should return nil if there is an error while retrieving the catalog" do
|
||||
Puppet::Resource::Catalog.expects(:find).raises "eh"
|
||||
|
||||
@agent.retrieve_catalog.should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Agent, "when converting the catalog" do
|
||||
before do
|
||||
Puppet.settings.stubs(:use).returns(true)
|
||||
@agent = Puppet::Agent.new
|
||||
|
||||
@catalog = Puppet::Resource::Catalog.new
|
||||
@oldcatalog = stub 'old_catalog', :to_ral => @catalog
|
||||
end
|
||||
|
||||
it "should convert the catalog to a RAL-formed catalog" do
|
||||
@oldcatalog.expects(:to_ral).returns @catalog
|
||||
|
||||
@agent.convert_catalog(@oldcatalog, 10).should equal(@catalog)
|
||||
end
|
||||
|
||||
it "should record the passed retrieval time with the RAL catalog" do
|
||||
@catalog.expects(:retrieval_duration=).with 10
|
||||
|
||||
@agent.convert_catalog(@oldcatalog, 10)
|
||||
end
|
||||
|
||||
it "should write the RAL catalog's class file" do
|
||||
@catalog.expects(:write_class_file)
|
||||
|
||||
@agent.convert_catalog(@oldcatalog, 10)
|
||||
end
|
||||
|
||||
it "should mark the RAL catalog as a host catalog" do
|
||||
@catalog.expects(:host_config=).with true
|
||||
|
||||
@agent.convert_catalog(@oldcatalog, 10)
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Agent, "when preparing for a run" do
|
||||
before do
|
||||
Puppet.settings.stubs(:use).returns(true)
|
||||
@agent = Puppet::Agent.new
|
||||
@agent.stubs(:dostorage)
|
||||
@agent.stubs(:upload_facts)
|
||||
@facts = {"one" => "two", "three" => "four"}
|
||||
end
|
||||
|
||||
it "should initialize the metadata store" do
|
||||
@agent.class.stubs(:facts).returns(@facts)
|
||||
@agent.expects(:dostorage)
|
||||
@agent.prepare
|
||||
end
|
||||
|
||||
it "should download fact plugins" do
|
||||
@agent.stubs(:dostorage)
|
||||
@agent.expects(:download_fact_plugins)
|
||||
|
||||
@agent.prepare
|
||||
end
|
||||
|
||||
it "should download plugins" do
|
||||
@agent.stubs(:dostorage)
|
||||
@agent.expects(:download_plugins)
|
||||
|
||||
@agent.prepare
|
||||
end
|
||||
|
||||
it "should upload facts to use for catalog retrieval" do
|
||||
@agent.stubs(:dostorage)
|
||||
@agent.expects(:upload_facts)
|
||||
@agent.prepare
|
||||
it "should run within the block passed to the timer" do
|
||||
Puppet.stubs(:newtimer).yields
|
||||
@agent.expects(:run).times(2)
|
||||
@agent.start
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,12 +11,21 @@ end
|
|||
describe Puppet::Agent::Locker do
|
||||
before do
|
||||
@locker = LockerTester.new
|
||||
@locker.stubs(:lockfile_path).returns "/my/lock"
|
||||
end
|
||||
|
||||
it "should use a Pidlock instance as its lockfile" do
|
||||
@locker.lockfile.should be_instance_of(Puppet::Util::Pidlock)
|
||||
end
|
||||
|
||||
it "should use 'lockfile_path' to determine its lockfile path" do
|
||||
@locker.expects(:lockfile_path).returns "/my/lock"
|
||||
lock = Puppet::Util::Pidlock.new("/my/lock")
|
||||
Puppet::Util::Pidlock.expects(:new).with("/my/lock").returns lock
|
||||
|
||||
@locker.lockfile
|
||||
end
|
||||
|
||||
it "should reuse the same lock file each time" do
|
||||
@locker.lockfile.should equal(@locker.lockfile)
|
||||
end
|
||||
|
@ -83,4 +92,9 @@ describe Puppet::Agent::Locker do
|
|||
|
||||
lambda { @locker.lock { raise "foo" } }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "should be considered running if the lockfile is locked" do
|
||||
@locker.lockfile.expects(:locked?).returns true
|
||||
@locker.should be_running
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,225 @@
|
|||
#!/usr/bin/env ruby
|
||||
#
|
||||
# Created by Luke Kanies on 2007-11-12.
|
||||
# Copyright (c) 2007. All rights reserved.
|
||||
|
||||
require File.dirname(__FILE__) + '/../spec_helper'
|
||||
require 'puppet/configurer'
|
||||
|
||||
describe Puppet::Configurer do
|
||||
it "should include the Plugin Handler module" do
|
||||
Puppet::Configurer.ancestors.should be_include(Puppet::Configurer::PluginHandler)
|
||||
end
|
||||
|
||||
it "should include the Fact Handler module" do
|
||||
Puppet::Configurer.ancestors.should be_include(Puppet::Configurer::FactHandler)
|
||||
end
|
||||
|
||||
it "should use the puppetdlockfile as its lockfile path" do
|
||||
Puppet.settings.expects(:value).with(:puppetdlockfile).returns("/my/lock")
|
||||
Puppet::Configurer.lockfile_path.should == "/my/lock"
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Configurer, "when executing a catalog run" do
|
||||
before do
|
||||
Puppet.settings.stubs(:use).returns(true)
|
||||
@agent = Puppet::Configurer.new
|
||||
end
|
||||
|
||||
it "should retrieve the catalog" do
|
||||
@agent.expects(:retrieve_catalog)
|
||||
|
||||
@agent.run
|
||||
end
|
||||
|
||||
it "should log a failure and do nothing if no catalog can be retrieved" do
|
||||
@agent.expects(:retrieve_catalog).returns nil
|
||||
|
||||
Puppet.expects(:err)
|
||||
|
||||
@agent.run
|
||||
end
|
||||
|
||||
it "should apply the catalog with all options to :run" do
|
||||
catalog = stub 'catalog', :retrieval_duration= => nil
|
||||
@agent.expects(:retrieve_catalog).returns catalog
|
||||
|
||||
catalog.expects(:apply).with(:one => true)
|
||||
@agent.run :one => true
|
||||
end
|
||||
|
||||
it "should benchmark how long it takes to apply the catalog" do
|
||||
@agent.expects(:benchmark).with(:notice, "Finished catalog run")
|
||||
|
||||
catalog = stub 'catalog', :retrieval_duration= => nil
|
||||
@agent.expects(:retrieve_catalog).returns catalog
|
||||
|
||||
catalog.expects(:apply).never # because we're not yielding
|
||||
@agent.run
|
||||
end
|
||||
|
||||
it "should HUP itself if it should be restarted" do
|
||||
catalog = stub 'catalog', :retrieval_duration= => nil, :apply => nil
|
||||
@agent.expects(:retrieve_catalog).returns catalog
|
||||
|
||||
Process.expects(:kill).with(:HUP, $$)
|
||||
|
||||
@agent.expects(:restart?).returns true
|
||||
|
||||
@agent.run
|
||||
end
|
||||
|
||||
it "should not HUP itself if it should not be restarted" do
|
||||
catalog = stub 'catalog', :retrieval_duration= => nil, :apply => nil
|
||||
@agent.expects(:retrieve_catalog).returns catalog
|
||||
|
||||
Process.expects(:kill).never
|
||||
|
||||
@agent.expects(:restart?).returns false
|
||||
|
||||
@agent.run
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Configurer, "when retrieving a catalog" do
|
||||
before do
|
||||
Puppet.settings.stubs(:use).returns(true)
|
||||
@agent = Puppet::Configurer.new
|
||||
|
||||
@catalog = Puppet::Resource::Catalog.new
|
||||
|
||||
@agent.stubs(:convert_catalog).returns @catalog
|
||||
end
|
||||
|
||||
it "should use the Catalog class to get its catalog" do
|
||||
Puppet::Resource::Catalog.expects(:find).returns @catalog
|
||||
|
||||
@agent.retrieve_catalog
|
||||
end
|
||||
|
||||
it "should use its Facter name to retrieve the catalog" do
|
||||
Facter.stubs(:value).returns "eh"
|
||||
Facter.expects(:value).with("hostname").returns "myhost"
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| name == "myhost" }.returns @catalog
|
||||
|
||||
@agent.retrieve_catalog
|
||||
end
|
||||
|
||||
it "should default to returning a catalog retrieved directly from the server, skipping the cache" do
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == false }.returns @catalog
|
||||
|
||||
@agent.retrieve_catalog.should == @catalog
|
||||
end
|
||||
|
||||
it "should return the cached catalog when no catalog can be retrieved from the server" do
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == false }.returns nil
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == true }.returns @catalog
|
||||
|
||||
@agent.retrieve_catalog.should == @catalog
|
||||
end
|
||||
|
||||
it "should not look in the cache for a catalog if one is returned from the server" do
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == false }.returns @catalog
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == true }.never
|
||||
|
||||
@agent.retrieve_catalog.should == @catalog
|
||||
end
|
||||
|
||||
it "should return the cached catalog when retrieving the remote catalog throws an exception" do
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == false }.raises "eh"
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == true }.returns @catalog
|
||||
|
||||
@agent.retrieve_catalog.should == @catalog
|
||||
end
|
||||
|
||||
it "should return nil if no cached catalog is available and no catalog can be retrieved from the server" do
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == false }.returns nil
|
||||
Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:use_cache] == true }.returns nil
|
||||
|
||||
@agent.retrieve_catalog.should be_nil
|
||||
end
|
||||
|
||||
it "should convert the catalog before returning" do
|
||||
Puppet::Resource::Catalog.stubs(:find).returns @catalog
|
||||
|
||||
@agent.expects(:convert_catalog).with { |cat, dur| cat == @catalog }.returns "converted catalog"
|
||||
@agent.retrieve_catalog.should == "converted catalog"
|
||||
end
|
||||
|
||||
it "should return nil if there is an error while retrieving the catalog" do
|
||||
Puppet::Resource::Catalog.expects(:find).raises "eh"
|
||||
|
||||
@agent.retrieve_catalog.should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Configurer, "when converting the catalog" do
|
||||
before do
|
||||
Puppet.settings.stubs(:use).returns(true)
|
||||
@agent = Puppet::Configurer.new
|
||||
|
||||
@catalog = Puppet::Resource::Catalog.new
|
||||
@oldcatalog = stub 'old_catalog', :to_ral => @catalog
|
||||
end
|
||||
|
||||
it "should convert the catalog to a RAL-formed catalog" do
|
||||
@oldcatalog.expects(:to_ral).returns @catalog
|
||||
|
||||
@agent.convert_catalog(@oldcatalog, 10).should equal(@catalog)
|
||||
end
|
||||
|
||||
it "should record the passed retrieval time with the RAL catalog" do
|
||||
@catalog.expects(:retrieval_duration=).with 10
|
||||
|
||||
@agent.convert_catalog(@oldcatalog, 10)
|
||||
end
|
||||
|
||||
it "should write the RAL catalog's class file" do
|
||||
@catalog.expects(:write_class_file)
|
||||
|
||||
@agent.convert_catalog(@oldcatalog, 10)
|
||||
end
|
||||
|
||||
it "should mark the RAL catalog as a host catalog" do
|
||||
@catalog.expects(:host_config=).with true
|
||||
|
||||
@agent.convert_catalog(@oldcatalog, 10)
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Configurer, "when preparing for a run" do
|
||||
before do
|
||||
Puppet.settings.stubs(:use).returns(true)
|
||||
@agent = Puppet::Configurer.new
|
||||
@agent.stubs(:dostorage)
|
||||
@agent.stubs(:upload_facts)
|
||||
@facts = {"one" => "two", "three" => "four"}
|
||||
end
|
||||
|
||||
it "should initialize the metadata store" do
|
||||
@agent.class.stubs(:facts).returns(@facts)
|
||||
@agent.expects(:dostorage)
|
||||
@agent.prepare
|
||||
end
|
||||
|
||||
it "should download fact plugins" do
|
||||
@agent.stubs(:dostorage)
|
||||
@agent.expects(:download_fact_plugins)
|
||||
|
||||
@agent.prepare
|
||||
end
|
||||
|
||||
it "should download plugins" do
|
||||
@agent.stubs(:dostorage)
|
||||
@agent.expects(:download_plugins)
|
||||
|
||||
@agent.prepare
|
||||
end
|
||||
|
||||
it "should upload facts to use for catalog retrieval" do
|
||||
@agent.stubs(:dostorage)
|
||||
@agent.expects(:upload_facts)
|
||||
@agent.prepare
|
||||
end
|
||||
end
|
|
@ -2,36 +2,36 @@
|
|||
|
||||
require File.dirname(__FILE__) + '/../../spec_helper'
|
||||
|
||||
require 'puppet/agent/downloader'
|
||||
require 'puppet/configurer/downloader'
|
||||
|
||||
describe Puppet::Agent::Downloader do
|
||||
describe Puppet::Configurer::Downloader do
|
||||
it "should require a name" do
|
||||
lambda { Puppet::Agent::Downloader.new }.should raise_error(ArgumentError)
|
||||
lambda { Puppet::Configurer::Downloader.new }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "should require a path and a source at initialization" do
|
||||
lambda { Puppet::Agent::Downloader.new("name") }.should raise_error(ArgumentError)
|
||||
lambda { Puppet::Configurer::Downloader.new("name") }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "should set the name, path and source appropriately" do
|
||||
dler = Puppet::Agent::Downloader.new("facts", "path", "source")
|
||||
dler = Puppet::Configurer::Downloader.new("facts", "path", "source")
|
||||
dler.name.should == "facts"
|
||||
dler.path.should == "path"
|
||||
dler.source.should == "source"
|
||||
end
|
||||
|
||||
it "should be able to provide a timeout value" do
|
||||
Puppet::Agent::Downloader.should respond_to(:timeout)
|
||||
Puppet::Configurer::Downloader.should respond_to(:timeout)
|
||||
end
|
||||
|
||||
it "should use the configtimeout, converted to an integer, as its timeout" do
|
||||
Puppet.settings.expects(:value).with(:configtimeout).returns "50"
|
||||
Puppet::Agent::Downloader.timeout.should == 50
|
||||
Puppet::Configurer::Downloader.timeout.should == 50
|
||||
end
|
||||
|
||||
describe "when creating the file that does the downloading" do
|
||||
before do
|
||||
@dler = Puppet::Agent::Downloader.new("foo", "path", "source")
|
||||
@dler = Puppet::Configurer::Downloader.new("foo", "path", "source")
|
||||
end
|
||||
|
||||
it "should create a file instance with the right path and source" do
|
||||
|
@ -83,14 +83,14 @@ describe Puppet::Agent::Downloader do
|
|||
|
||||
it "should support providing an 'ignore' parameter" do
|
||||
Puppet::Type.type(:file).expects(:create).with { |opts| opts[:ignore] == ".svn" }
|
||||
@dler = Puppet::Agent::Downloader.new("foo", "path", "source", ".svn")
|
||||
@dler = Puppet::Configurer::Downloader.new("foo", "path", "source", ".svn")
|
||||
@dler.file
|
||||
end
|
||||
end
|
||||
|
||||
describe "when creating the catalog to do the downloading" do
|
||||
before do
|
||||
@dler = Puppet::Agent::Downloader.new("foo", "path", "source")
|
||||
@dler = Puppet::Configurer::Downloader.new("foo", "path", "source")
|
||||
end
|
||||
|
||||
it "should create a catalog and add the file to it" do
|
||||
|
@ -108,7 +108,7 @@ describe Puppet::Agent::Downloader do
|
|||
|
||||
describe "when downloading" do
|
||||
before do
|
||||
@dler = Puppet::Agent::Downloader.new("foo", "path", "source")
|
||||
@dler = Puppet::Configurer::Downloader.new("foo", "path", "source")
|
||||
end
|
||||
|
||||
it "should log that it is downloading" do
|
||||
|
@ -119,7 +119,7 @@ describe Puppet::Agent::Downloader do
|
|||
end
|
||||
|
||||
it "should set a timeout for the download" do
|
||||
Puppet::Agent::Downloader.expects(:timeout).returns 50
|
||||
Puppet::Configurer::Downloader.expects(:timeout).returns 50
|
||||
Timeout.expects(:timeout).with(50)
|
||||
|
||||
@dler.evaluate
|
|
@ -1,14 +1,14 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require File.dirname(__FILE__) + '/../../spec_helper'
|
||||
require 'puppet/agent'
|
||||
require 'puppet/agent/fact_handler'
|
||||
require 'puppet/configurer'
|
||||
require 'puppet/configurer/fact_handler'
|
||||
|
||||
class FactHandlerTester
|
||||
include Puppet::Agent::FactHandler
|
||||
include Puppet::Configurer::FactHandler
|
||||
end
|
||||
|
||||
describe Puppet::Agent::FactHandler do
|
||||
describe Puppet::Configurer::FactHandler do
|
||||
before do
|
||||
@facthandler = FactHandlerTester.new
|
||||
end
|
||||
|
@ -32,7 +32,7 @@ describe Puppet::Agent::FactHandler do
|
|||
end
|
||||
|
||||
it "should not download fact plugins when downloading is disabled" do
|
||||
Puppet::Agent::Downloader.expects(:new).never
|
||||
Puppet::Configurer::Downloader.expects(:new).never
|
||||
@facthandler.expects(:download_fact_plugins?).returns false
|
||||
@facthandler.download_fact_plugins
|
||||
end
|
||||
|
@ -44,7 +44,7 @@ describe Puppet::Agent::FactHandler do
|
|||
Puppet.settings.expects(:value).with(:factdest).returns "fdest"
|
||||
Puppet.settings.expects(:value).with(:factsignore).returns "fignore"
|
||||
|
||||
Puppet::Agent::Downloader.expects(:new).with("fact", "fsource", "fdest", "fignore").returns downloader
|
||||
Puppet::Configurer::Downloader.expects(:new).with("fact", "fsource", "fdest", "fignore").returns downloader
|
||||
|
||||
downloader.expects(:evaluate)
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require File.dirname(__FILE__) + '/../../spec_helper'
|
||||
require 'puppet/agent'
|
||||
require 'puppet/agent/plugin_handler'
|
||||
require 'puppet/configurer'
|
||||
require 'puppet/configurer/plugin_handler'
|
||||
|
||||
class PluginHandlerTester
|
||||
include Puppet::Agent::PluginHandler
|
||||
include Puppet::Configurer::PluginHandler
|
||||
end
|
||||
|
||||
describe Puppet::Agent::PluginHandler do
|
||||
describe Puppet::Configurer::PluginHandler do
|
||||
before do
|
||||
@pluginhandler = PluginHandlerTester.new
|
||||
end
|
||||
|
@ -32,7 +32,7 @@ describe Puppet::Agent::PluginHandler do
|
|||
end
|
||||
|
||||
it "should not download plugins when downloading is disabled" do
|
||||
Puppet::Agent::Downloader.expects(:new).never
|
||||
Puppet::Configurer::Downloader.expects(:new).never
|
||||
@pluginhandler.expects(:download_plugins?).returns false
|
||||
@pluginhandler.download_plugins
|
||||
end
|
||||
|
@ -44,7 +44,7 @@ describe Puppet::Agent::PluginHandler do
|
|||
Puppet.settings.expects(:value).with(:plugindest).returns "pdest"
|
||||
Puppet.settings.expects(:value).with(:pluginsignore).returns "pignore"
|
||||
|
||||
Puppet::Agent::Downloader.expects(:new).with("plugin", "psource", "pdest", "pignore").returns downloader
|
||||
Puppet::Configurer::Downloader.expects(:new).with("plugin", "psource", "pdest", "pignore").returns downloader
|
||||
|
||||
downloader.expects(:evaluate).returns []
|
||||
|
||||
|
@ -59,7 +59,7 @@ describe Puppet::Agent::PluginHandler do
|
|||
it "should load each downloaded file" do
|
||||
downloader = mock 'downloader'
|
||||
|
||||
Puppet::Agent::Downloader.expects(:new).returns downloader
|
||||
Puppet::Configurer::Downloader.expects(:new).returns downloader
|
||||
|
||||
downloader.expects(:evaluate).returns %w{one two}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require File.dirname(__FILE__) + '/lib/puppettest'
|
||||
|
||||
require 'puppettest'
|
||||
require 'puppet/agent'
|
||||
require 'mocha'
|
||||
|
||||
class TestAgent < Test::Unit::TestCase
|
||||
include PuppetTest::ServerTest
|
||||
|
||||
def setup
|
||||
super
|
||||
@agent_class = Puppet::Agent
|
||||
end
|
||||
|
||||
# Make sure we get a value for timeout
|
||||
def test_config_timeout
|
||||
master = Puppet::Agent
|
||||
time = Integer(Puppet[:configtimeout])
|
||||
assert_equal(time, master.timeout, "Did not get default value for timeout")
|
||||
assert_equal(time, master.timeout, "Did not get default value for timeout on second run")
|
||||
|
||||
# Reset it
|
||||
Puppet[:configtimeout] = "50"
|
||||
assert_equal(50, master.timeout, "Did not get changed default value for timeout")
|
||||
assert_equal(50, master.timeout, "Did not get changed default value for timeout on second run")
|
||||
|
||||
# Now try an integer
|
||||
Puppet[:configtimeout] = 100
|
||||
assert_equal(100, master.timeout, "Did not get changed integer default value for timeout")
|
||||
assert_equal(100, master.timeout, "Did not get changed integer default value for timeout on second run")
|
||||
end
|
||||
|
||||
def test_splay
|
||||
client = Puppet::Agent.new
|
||||
|
||||
# Make sure we default to no splay
|
||||
client.expects(:sleep).never
|
||||
|
||||
assert_nothing_raised("Failed to call splay") do
|
||||
client.send(:splay)
|
||||
end
|
||||
|
||||
# Now set it to true and make sure we get the right value
|
||||
client = Puppet::Agent.new
|
||||
client.expects(:sleep)
|
||||
|
||||
Puppet[:splay] = true
|
||||
assert_nothing_raised("Failed to call sleep when splay is true") do
|
||||
client.send(:splay)
|
||||
end
|
||||
|
||||
# Now try it again
|
||||
client = Puppet::Agent.new
|
||||
client.expects(:sleep)
|
||||
|
||||
assert_nothing_raised("Failed to call sleep when splay is true with a cached value") do
|
||||
client.send(:splay)
|
||||
end
|
||||
end
|
||||
end
|
Загрузка…
Ссылка в новой задаче