diff --git a/lib/puppet/reports/rrdgraph.rb b/lib/puppet/reports/rrdgraph.rb
index 2357e233e..517fa8f03 100644
--- a/lib/puppet/reports/rrdgraph.rb
+++ b/lib/puppet/reports/rrdgraph.rb
@@ -1,128 +1,128 @@
Puppet::Reports.register_report(:rrdgraph) do
desc "Graph all available data about hosts using the RRD library. You
must have the Ruby RRDtool library installed to use this report, which
you can get from
[the RubyRRDTool RubyForge page](http://rubyforge.org/projects/rubyrrdtool/).
This package may also be available as `ruby-rrd` or `rrdtool-ruby` in your
distribution's package management system. The library and/or package will both
require the binary `rrdtool` package from your distribution to be installed.
This report will create, manage, and graph RRD database files for each
of the metrics generated during transactions, and it will create a
few simple html files to display the reporting host's graphs. At this
point, it will not create a common index file to display links to
all hosts.
All RRD files and graphs get created in the `rrddir` directory. If
you want to serve these publicly, you should be able to just alias that
directory in a web server.
If you really know what you're doing, you can tune the `rrdinterval`,
which defaults to the `runinterval`."
def hostdir
@hostdir ||= File.join(Puppet[:rrddir], self.host)
end
def htmlfile(type, graphs, field)
file = File.join(hostdir, "#{type}.html")
File.open(file, "w") do |of|
of.puts "
#{type.capitalize} graphs for #{host}"
graphs.each do |graph|
if field == :first
name = graph.sub(/-\w+.png/, '').capitalize
else
name = graph.sub(/\w+-/, '').sub(".png", '').capitalize
end
of.puts "
"
end
of.puts ""
end
file
end
def mkhtml
images = Dir.entries(hostdir).find_all { |d| d =~ /\.png/ }
periodorder = %w{daily weekly monthly yearly}
periods = {}
types = {}
images.each do |n|
type, period = n.sub(".png", '').split("-")
periods[period] ||= []
types[type] ||= []
periods[period] << n
types[type] << n
end
files = []
# Make the period html files
periodorder.each do |period|
unless ary = periods[period]
raise Puppet::Error, "Could not find graphs for #{period}"
end
files << htmlfile(period, ary, :first)
end
# make the type html files
types.sort { |a,b| a[0] <=> b[0] }.each do |type, ary|
newary = []
periodorder.each do |period|
if graph = ary.find { |g| g.include?("-#{period}.png") }
newary << graph
else
raise "Could not find #{type}-#{period} graph"
end
end
files << htmlfile(type, newary, :second)
end
File.open(File.join(hostdir, "index.html"), "w") do |of|
of.puts "Report graphs for #{host}"
files.each do |file|
of.puts "#{File.basename(file).sub(".html",'').capitalize}
"
end
of.puts ""
end
end
def process(time = nil)
time ||= Time.now.to_i
unless File.directory?(hostdir) and FileTest.writable?(hostdir)
# Some hackishness to create the dir with all of the right modes and ownership
config = Puppet::Util::Settings.new
config.setdefaults(:reports, :hostdir => {:default => hostdir, :owner => 'service', :mode => 0755, :group => 'service', :desc => "eh"})
# This creates the dir.
config.use(:reports)
end
self.metrics.each do |name, metric|
metric.basedir = hostdir
if name == "time"
timeclean(metric)
end
metric.store(time)
metric.graph
end
mkhtml unless FileTest.exists?(File.join(hostdir, "index.html"))
end
# Unfortunately, RRD does not deal well with changing lists of values,
# so we have to pick a list of values and stick with it. In this case,
# that means we record the total time, the config time, and that's about
# it. We should probably send each type's time as a separate metric.
def timeclean(metric)
- metric.values = metric.values.find_all { |name, label, value| [:total, :config_retrieval].include?(name) }
+ metric.values = metric.values.find_all { |name, label, value| ['total', 'config_retrieval'].include?(name.to_s) }
end
end
diff --git a/spec/fixtures/yaml/report0.25.x.yaml b/spec/fixtures/yaml/report0.25.x.yaml
new file mode 100644
index 000000000..ce6a64286
--- /dev/null
+++ b/spec/fixtures/yaml/report0.25.x.yaml
@@ -0,0 +1,64 @@
+--- !ruby/object:Puppet::Transaction::Report
+ host: mattmac.local
+ logs:
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym info
+ message: Applying configuration version '1285283846'
+ source: Puppet
+ tags:
+ - info
+ time: 2010-09-23 16:17:26.977750 -07:00
+ metrics:
+ time: !ruby/object:Puppet::Util::Metric
+ label: Time
+ name: time
+ values:
+ - - !ruby/sym config_retrieval
+ - Config retrieval
+ - 0.955046892166138
+ - - !ruby/sym schedule
+ - Schedule
+ - 0.00123691558837891
+ - - !ruby/sym total
+ - Total
+ - 0.956486701965332
+ - - !ruby/sym filebucket
+ - Filebucket
+ - 0.00020289421081543
+ resources: !ruby/object:Puppet::Util::Metric
+ label: Resources
+ name: resources
+ values:
+ - - !ruby/sym skipped
+ - Skipped
+ - 0
+ - - !ruby/sym scheduled
+ - Scheduled
+ - 7
+ - - !ruby/sym applied
+ - Applied
+ - 0
+ - - !ruby/sym restarted
+ - Restarted
+ - 0
+ - - !ruby/sym total
+ - Total
+ - 10
+ - - !ruby/sym failed_restarts
+ - Failed restarts
+ - 0
+ - - !ruby/sym out_of_sync
+ - Out of sync
+ - 0
+ - - !ruby/sym failed
+ - Failed
+ - 0
+ changes: !ruby/object:Puppet::Util::Metric
+ label: Changes
+ name: changes
+ values:
+ - - !ruby/sym total
+ - Total
+ - 0
+ records: {}
+ time: 2010-09-23 16:17:26.987789 -07:00
\ No newline at end of file
diff --git a/spec/fixtures/yaml/report2.6.x.yaml b/spec/fixtures/yaml/report2.6.x.yaml
new file mode 100644
index 000000000..dd4c3814e
--- /dev/null
+++ b/spec/fixtures/yaml/report2.6.x.yaml
@@ -0,0 +1,190 @@
+--- !ruby/object:Puppet::Transaction::Report
+ external_times:
+ !ruby/sym config_retrieval: 0.170313835144043
+ host: ubuntu1004desktop.localdomain
+ logs:
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym debug
+ message: Using cached certificate for ca
+ source: Puppet
+ tags:
+ - debug
+ time: 2010-09-23 15:44:06.244173 -07:00
+ version: &id001 2.6.1
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym debug
+ message: Using cached certificate for ubuntu1004desktop.localdomain
+ source: Puppet
+ tags:
+ - debug
+ time: 2010-09-23 15:44:06.244764 -07:00
+ version: *id001
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym debug
+ message: Using cached certificate_revocation_list for ca
+ source: Puppet
+ tags:
+ - debug
+ time: 2010-09-23 15:44:06.245677 -07:00
+ version: *id001
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym debug
+ message: "catalog supports formats: b64_zlib_yaml dot marshal pson raw yaml; using pson"
+ source: Puppet
+ tags:
+ - debug
+ time: 2010-09-23 15:44:06.247069 -07:00
+ version: *id001
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym info
+ message: Caching catalog for ubuntu1004desktop.localdomain
+ source: Puppet
+ tags:
+ - info
+ time: 2010-09-23 15:44:06.409109 -07:00
+ version: *id001
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym debug
+ message: Creating default schedules
+ source: Puppet
+ tags:
+ - debug
+ time: 2010-09-23 15:44:06.418755 -07:00
+ version: *id001
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym debug
+ message: Loaded state in 0.00 seconds
+ source: Puppet
+ tags:
+ - debug
+ time: 2010-09-23 15:44:06.427441 -07:00
+ version: *id001
+ - !ruby/object:Puppet::Util::Log
+ level: !ruby/sym info
+ message: Applying configuration version '1285281846'
+ source: Puppet
+ tags:
+ - info
+ time: 2010-09-23 15:44:06.429532 -07:00
+ version: *id001
+ metrics:
+ time: !ruby/object:Puppet::Util::Metric
+ label: Time
+ name: time
+ values:
+ - - config_retrieval
+ - Config retrieval
+ - 0.170313835144043
+ - - schedule
+ - Schedule
+ - 0.00077
+ - - filebucket
+ - Filebucket
+ - 0.000166
+ resources: !ruby/object:Puppet::Util::Metric
+ label: Resources
+ name: resources
+ values:
+ - - !ruby/sym total
+ - Total
+ - 7
+ events: !ruby/object:Puppet::Util::Metric
+ label: Events
+ name: events
+ values:
+ - - !ruby/sym total
+ - Total
+ - 0
+ changes: !ruby/object:Puppet::Util::Metric
+ label: Changes
+ name: changes
+ values:
+ - - !ruby/sym total
+ - Total
+ - 0
+ resource_statuses:
+ "Schedule[monthly]": !ruby/object:Puppet::Resource::Status
+ evaluation_time: 0.000121
+ events: []
+ file:
+ line:
+ resource: "Schedule[monthly]"
+ source_description: "/Schedule[monthly]"
+ tags:
+ - schedule
+ - monthly
+ time: 2010-09-23 15:44:06.430577 -07:00
+ version: 1285281846
+ "Filebucket[puppet]": !ruby/object:Puppet::Resource::Status
+ evaluation_time: 0.000166
+ events: []
+ file:
+ line:
+ resource: "Filebucket[puppet]"
+ source_description: "/Filebucket[puppet]"
+ tags:
+ - filebucket
+ - puppet
+ time: 2010-09-23 15:44:06.430998 -07:00
+ version: 1285281846
+ "Schedule[never]": !ruby/object:Puppet::Resource::Status
+ evaluation_time: 0.000119
+ events: []
+ file:
+ line:
+ resource: "Schedule[never]"
+ source_description: "/Schedule[never]"
+ tags:
+ - schedule
+ - never
+ time: 2010-09-23 15:44:06.433034 -07:00
+ version: 1285281846
+ "Schedule[weekly]": !ruby/object:Puppet::Resource::Status
+ evaluation_time: 0.000118
+ events: []
+ file:
+ line:
+ resource: "Schedule[weekly]"
+ source_description: "/Schedule[weekly]"
+ tags:
+ - schedule
+ - weekly
+ time: 2010-09-23 15:44:06.431443 -07:00
+ version: 1285281846
+ "Schedule[puppet]": !ruby/object:Puppet::Resource::Status
+ evaluation_time: 0.000129
+ events: []
+ file:
+ line:
+ resource: "Schedule[puppet]"
+ source_description: "/Schedule[puppet]"
+ tags:
+ - schedule
+ - puppet
+ time: 2010-09-23 15:44:06.432626 -07:00
+ version: 1285281846
+ "Schedule[daily]": !ruby/object:Puppet::Resource::Status
+ evaluation_time: 0.000154
+ events: []
+ file:
+ line:
+ resource: "Schedule[daily]"
+ source_description: "/Schedule[daily]"
+ tags:
+ - schedule
+ - daily
+ time: 2010-09-23 15:44:06.430130 -07:00
+ version: 1285281846
+ "Schedule[hourly]": !ruby/object:Puppet::Resource::Status
+ evaluation_time: 0.000129
+ events: []
+ file:
+ line:
+ resource: "Schedule[hourly]"
+ source_description: "/Schedule[hourly]"
+ tags:
+ - schedule
+ - hourly
+ time: 2010-09-23 15:44:06.432185 -07:00
+ version: 1285281846
+ time: 2010-09-23 15:44:05.894401 -07:00
\ No newline at end of file
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 2fe0c36a3..b5b273857 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,78 +1,79 @@
unless defined?(SPEC_HELPER_IS_LOADED)
SPEC_HELPER_IS_LOADED = 1
dir = File.expand_path(File.dirname(__FILE__))
$LOAD_PATH.unshift("#{dir}/")
$LOAD_PATH.unshift("#{dir}/lib") # a spec-specific test lib dir
$LOAD_PATH.unshift("#{dir}/../lib")
# Don't want puppet getting the command line arguments for rake or autotest
ARGV.clear
require 'puppet'
require 'mocha'
gem 'rspec', '>=1.2.9'
require 'spec/autorun'
# So everyone else doesn't have to include this base constant.
module PuppetSpec
FIXTURE_DIR = File.join(dir = File.expand_path(File.dirname(__FILE__)), "fixtures") unless defined?(FIXTURE_DIR)
end
+require 'spec/lib/puppet_spec/files'
require 'monkey_patches/alias_should_to_must'
require 'monkey_patches/add_confine_and_runnable_to_rspec_dsl'
require 'monkey_patches/publicize_methods'
Spec::Runner.configure do |config|
config.mock_with :mocha
config.prepend_after :each do
Puppet.settings.clear
Puppet::Node::Environment.clear
Puppet::Util::Storage.clear
if defined?($tmpfiles)
$tmpfiles.each do |file|
file = File.expand_path(file)
if Puppet.features.posix? and file !~ /^\/tmp/ and file !~ /^\/var\/folders/
puts "Not deleting tmpfile #{file} outside of /tmp or /var/folders"
next
elsif Puppet.features.microsoft_windows?
tempdir = File.expand_path(File.join(Dir::LOCAL_APPDATA, "Temp"))
if file !~ /^#{tempdir}/
puts "Not deleting tmpfile #{file} outside of #{tempdir}"
next
end
end
if FileTest.exist?(file)
system("chmod -R 755 '#{file}'")
system("rm -rf '#{file}'")
end
end
$tmpfiles.clear
end
@logs.clear
Puppet::Util::Log.close_all
end
config.prepend_before :each do
# these globals are set by Application
$puppet_application_mode = nil
$puppet_application_name = nil
# Set the confdir and vardir to gibberish so that tests
# have to be correctly mocked.
Puppet[:confdir] = "/dev/null"
Puppet[:vardir] = "/dev/null"
# Avoid opening ports to the outside world
Puppet.settings[:bindaddress] = "127.0.0.1"
@logs = []
Puppet::Util::Log.newdestination(@logs)
end
end
end
diff --git a/spec/unit/indirector/node/active_record_spec.rb b/spec/unit/indirector/node/active_record_spec.rb
index 6cc3f5132..3540ef738 100755
--- a/spec/unit/indirector/node/active_record_spec.rb
+++ b/spec/unit/indirector/node/active_record_spec.rb
@@ -1,41 +1,40 @@
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/node'
-require 'spec/lib/puppet_spec/files.rb'
describe "Puppet::Node::ActiveRecord" do
include PuppetSpec::Files
confine "Missing Rails" => Puppet.features.rails?
confine "Missing sqlite" => Puppet.features.sqlite?
before do
require 'puppet/indirector/node/active_record'
end
it "should be a subclass of the ActiveRecord terminus class" do
Puppet::Node::ActiveRecord.ancestors.should be_include(Puppet::Indirector::ActiveRecord)
end
it "should use Puppet::Rails::Host as its ActiveRecord model" do
Puppet::Node::ActiveRecord.ar_model.should equal(Puppet::Rails::Host)
end
it "should call fact_merge when a node is found" do
db_instance = stub 'db_instance'
Puppet::Node::ActiveRecord.ar_model.expects(:find_by_name).returns db_instance
node = Puppet::Node.new("foo")
db_instance.expects(:to_puppet).returns node
Puppet[:statedir] = tmpdir('active_record_tmp')
Puppet[:railslog] = '$statedir/rails.log'
ar = Puppet::Node::ActiveRecord.new
node.expects(:fact_merge)
request = Puppet::Indirector::Request.new(:node, :find, "what.ever")
ar.find(request)
end
end
diff --git a/spec/unit/reports/rrdgraph_spec.rb b/spec/unit/reports/rrdgraph_spec.rb
new file mode 100644
index 000000000..ce2cf7905
--- /dev/null
+++ b/spec/unit/reports/rrdgraph_spec.rb
@@ -0,0 +1,31 @@
+#!/usr/bin/env ruby
+
+Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
+
+require 'puppet/reports'
+
+processor = Puppet::Reports.report(:rrdgraph)
+
+describe processor do
+ include PuppetSpec::Files
+ before do
+ Puppet[:rrddir] = tmpdir('rrdgraph')
+ Puppet.settings.use :master
+ end
+
+ after do
+ FileUtils.rm_rf(Puppet[:rrddir])
+ end
+
+ it "should not error on 0.25.x report format" do
+ report = YAML.load_file(File.join(PuppetSpec::FIXTURE_DIR, 'yaml/report0.25.x.yaml')).extend processor
+ report.expects(:mkhtml)
+ lambda{ report.process }.should_not raise_error
+ end
+
+ it "should not error on 2.6.x report format" do
+ report = YAML.load_file(File.join(PuppetSpec::FIXTURE_DIR, 'yaml/report2.6.x.yaml')).extend processor
+ report.expects(:mkhtml)
+ lambda{ report.process }.should_not raise_error
+ end
+end