diff options
| author | Luke Kanies <luke@madstop.com> | 2007-09-22 17:22:07 -0500 |
|---|---|---|
| committer | Luke Kanies <luke@madstop.com> | 2007-09-22 17:22:07 -0500 |
| commit | e552c83b2875dab60a5508bfae352e7aa9235746 (patch) | |
| tree | 3b7555352428bb701bc072be86a0535ca7fb02d6 | |
| parent | d6e91ae78698bdbec818d383574f4c279735e172 (diff) | |
| download | puppet-e552c83b2875dab60a5508bfae352e7aa9235746.tar.gz puppet-e552c83b2875dab60a5508bfae352e7aa9235746.tar.xz puppet-e552c83b2875dab60a5508bfae352e7aa9235746.zip | |
Adding the base file terminus. This will, at the least,
be used as the back end for filebuckets and the
certificate authority.
| -rw-r--r-- | lib/puppet/indirector/file.rb | 40 | ||||
| -rwxr-xr-x | spec/unit/indirector/file.rb | 130 |
2 files changed, 170 insertions, 0 deletions
diff --git a/lib/puppet/indirector/file.rb b/lib/puppet/indirector/file.rb new file mode 100644 index 000000000..75fcf1ddf --- /dev/null +++ b/lib/puppet/indirector/file.rb @@ -0,0 +1,40 @@ +require 'puppet/indirector/terminus' + +# An empty terminus type, meant to just return empty objects. +class Puppet::Indirector::File < Puppet::Indirector::Terminus + def destroy(file) + raise Puppet::Error.new("File %s does not exist; cannot destroy" % [file.name]) unless File.exist?(file.path) + + begin + File.unlink(file.path) + rescue => detail + raise Puppet::Error, "Could not remove %s: %s" % [file.path, detail] + end + end + + def find(path) + return nil unless File.exist?(path) + + begin + content = File.read(path) + rescue => detail + raise Puppet::Error, "Could not retrieve path %s: %s" % [path, detail] + end + + file = model.new(path) + file.content = content + return file + end + + def save(file) + dir = File.dirname(file.path) + + raise Puppet::Error.new("Cannot save %s; parent directory %s does not exist" % [file.name, dir]) unless File.directory?(dir) + + begin + File.open(file.path, "w") { |f| f.print file.content } + rescue => detail + raise Puppet::Error, "Could not write %s: %s" % [file.path, detail] + end + end +end diff --git a/spec/unit/indirector/file.rb b/spec/unit/indirector/file.rb new file mode 100755 index 000000000..d08ff6455 --- /dev/null +++ b/spec/unit/indirector/file.rb @@ -0,0 +1,130 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../spec_helper' +require 'puppet/indirector/file' + +module FileTerminusTesting + def setup + Puppet::Indirector::Terminus.stubs(:register_terminus_class) + @model = mock 'model' + @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model + Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection) + + @file_class = Class.new(Puppet::Indirector::File) do + def self.to_s + "Testing" + end + end + + @searcher = @file_class.new + + @path = "/my/file" + @dir = "/my" + end +end + +describe Puppet::Indirector::File, " when finding files" do + include FileTerminusTesting + + it "should provide a method to return file contents at a specified path" do + end + + it "should return file contents as an instance of the model" do + content = "my content" + + file = mock 'file' + @model.expects(:new).with(@path).returns(file) + file.expects(:content=).with(content) + + File.expects(:exist?).with(@path).returns(true) + File.expects(:read).with(@path).returns(content) + @searcher.find(@path) + end + + it "should set the file contents as the 'content' attribute of the returned instance" do + content = "my content" + + file = mock 'file' + @model.expects(:new).with(@path).returns(file) + file.expects(:content=).with(content) + + File.expects(:exist?).with(@path).returns(true) + File.expects(:read).with(@path).returns(content) + @searcher.find(@path).should equal(file) + end + + it "should return nil if no file is found" do + File.expects(:exist?).with(@path).returns(false) + @searcher.find(@path).should be_nil + end + + it "should fail intelligently if a found file cannot be read" do + content = "my content" + File.expects(:exist?).with(@path).returns(true) + File.expects(:read).with(@path).raises(RuntimeError) + proc { @searcher.find(@path) }.should raise_error(Puppet::Error) + end +end + +describe Puppet::Indirector::File, " when saving files" do + include FileTerminusTesting + + it "should provide a method to save file contents at a specified path" do + filehandle = mock 'file' + content = "my content" + File.expects(:directory?).with(@dir).returns(true) + File.expects(:open).with(@path, "w").yields(filehandle) + filehandle.expects(:print).with(content) + + file = stub 'file', :content => content, :path => @path, :name => @path + + @searcher.save(file) + end + + it "should fail intelligently if the file's parent directory does not exist" do + File.expects(:directory?).with(@dir).returns(false) + + file = stub 'file', :path => @path, :name => @path + + proc { @searcher.save(file) }.should raise_error(Puppet::Error) + end + + it "should fail intelligently if a file cannot be written" do + filehandle = mock 'file' + content = "my content" + File.expects(:directory?).with(@dir).returns(true) + File.expects(:open).with(@path, "w").yields(filehandle) + filehandle.expects(:print).with(content).raises(ArgumentError) + + file = stub 'file', :content => content, :path => @path, :name => @path + + proc { @searcher.save(file) }.should raise_error(Puppet::Error) + end +end + +describe Puppet::Indirector::File, " when removing files" do + include FileTerminusTesting + + it "should provide a method to remove files at a specified path" do + file = stub 'file', :path => @path, :name => @path + File.expects(:exist?).with(@path).returns(true) + File.expects(:unlink).with(@path) + + @searcher.destroy(file) + end + + it "should throw an exception if the file is not found" do + file = stub 'file', :path => @path, :name => @path + File.expects(:exist?).with(@path).returns(false) + + proc { @searcher.destroy(file) }.should raise_error(Puppet::Error) + end + + it "should fail intelligently if the file cannot be removed" do + file = stub 'file', :path => @path, :name => @path + File.expects(:exist?).with(@path).returns(true) + File.expects(:unlink).with(@path).raises(ArgumentError) + + proc { @searcher.destroy(file) }.should raise_error(Puppet::Error) + end +end |
