summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2007-09-22 17:22:07 -0500
committerLuke Kanies <luke@madstop.com>2007-09-22 17:22:07 -0500
commite552c83b2875dab60a5508bfae352e7aa9235746 (patch)
tree3b7555352428bb701bc072be86a0535ca7fb02d6
parentd6e91ae78698bdbec818d383574f4c279735e172 (diff)
downloadpuppet-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.rb40
-rwxr-xr-xspec/unit/indirector/file.rb130
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