summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2007-10-18 20:47:56 -0500
committerLuke Kanies <luke@madstop.com>2007-10-18 20:47:56 -0500
commitfc607513faa54d64186a674a36d81ea010745569 (patch)
treed409b20c752cdb50e2fe72e8f6ef815951c360b4
parent64c6700bc7530f1213e124d248cc176a7cfe6180 (diff)
downloadpuppet-fc607513faa54d64186a674a36d81ea010745569.tar.gz
puppet-fc607513faa54d64186a674a36d81ea010745569.tar.xz
puppet-fc607513faa54d64186a674a36d81ea010745569.zip
I've now split the file-serving termini into two separate types (in
addition to Rest): A local terminus that just uses direct file paths, and a mounts terminus that uses the file server to figure out what the path should be. It looks like it also makes sense to split the 'mounts' terminus further, so there is a 'modules' terminus used to look files up in the terminus. I've added some integration tests to verify that everything is hooked together correctly. Lastly, I added a directory for shared behaviours. There's a ton of duplication in this setup, because the Content and Metadata classes behave almost but not quite identically across the board.
-rw-r--r--lib/puppet/file_serving/configuration.rb34
-rw-r--r--lib/puppet/file_serving/metadata.rb19
-rw-r--r--lib/puppet/file_serving/terminus_helper.rb22
-rw-r--r--lib/puppet/file_serving/terminus_selector.rb20
-rw-r--r--lib/puppet/indirector/file_content/local.rb9
-rw-r--r--lib/puppet/indirector/file_content/mounts.rb28
-rw-r--r--lib/puppet/indirector/file_content/rest.rb12
-rw-r--r--lib/puppet/indirector/file_metadata/local.rb16
-rw-r--r--lib/puppet/indirector/file_metadata/mounts.rb28
-rw-r--r--lib/puppet/indirector/file_metadata/rest.rb12
-rwxr-xr-xspec/integration/file_serving/content.rb18
-rwxr-xr-xspec/integration/file_serving/metadata.rb19
-rwxr-xr-xspec/integration/indirector/file_content/mounts.rb18
-rwxr-xr-xspec/integration/indirector/file_metadata/mounts.rb18
-rw-r--r--spec/lib/shared_behaviours/file_server_mounts.rb37
-rw-r--r--spec/lib/shared_behaviours/file_serving.rb49
-rwxr-xr-xspec/unit/file_serving/configuration.rb32
-rwxr-xr-xspec/unit/file_serving/content.rb12
-rwxr-xr-xspec/unit/file_serving/metadata.rb23
-rwxr-xr-xspec/unit/file_serving/terminus_helper.rb50
-rwxr-xr-xspec/unit/file_serving/terminus_selector.rb29
-rwxr-xr-xspec/unit/indirector/file_content/local.rb18
-rwxr-xr-xspec/unit/indirector/file_content/mounts.rb53
-rwxr-xr-xspec/unit/indirector/file_metadata/local.rb29
-rwxr-xr-xspec/unit/indirector/file_metadata/mounts.rb54
25 files changed, 594 insertions, 65 deletions
diff --git a/lib/puppet/file_serving/configuration.rb b/lib/puppet/file_serving/configuration.rb
index b1512e14e..6cd99b267 100644
--- a/lib/puppet/file_serving/configuration.rb
+++ b/lib/puppet/file_serving/configuration.rb
@@ -30,13 +30,22 @@ class Puppet::FileServing::Configuration
# Return a content instance.
def content(path, options = {})
- mount, file_path = splitpath(path, options[:node])
+ mount, file_path = split_path(path, options[:node])
return nil unless mount
mount.file_instance :content, file_path, options
end
+ # Search for a file.
+ def file_path(key, options = {})
+ mount, file_path = split_path(key, options[:node])
+
+ return nil unless mount
+
+ return mount.file(file_path, options)
+ end
+
def initialize
@mounts = {}
@config_file = nil
@@ -48,32 +57,13 @@ class Puppet::FileServing::Configuration
# Return a metadata instance.
def metadata(path, options = {})
- mount, file_path = splitpath(path, options[:node])
+ mount, file_path = split_path(path, options[:node])
return nil unless mount
mount.file_instance :metadata, file_path, options
end
- # Mount a new directory with a name.
- def mount(path, name)
- if @mounts.include?(name)
- if @mounts[name] != path
- raise FileServerError, "%s is already mounted at %s" %
- [@mounts[name].path, name]
- else
- # it's already mounted; no problem
- return
- end
- end
-
- # Let the mounts do their own error-checking.
- @mounts[name] = Mount.new(name, path)
- @mounts[name].info "Mounted %s" % path
-
- return @mounts[name]
- end
-
# Is a given mount available?
def mounted?(name)
@mounts.include?(name)
@@ -137,7 +127,7 @@ class Puppet::FileServing::Configuration
end
# Split the path into the separate mount point and path.
- def splitpath(uri, node)
+ def split_path(uri, node)
# Reparse the configuration if necessary.
readconfig
diff --git a/lib/puppet/file_serving/metadata.rb b/lib/puppet/file_serving/metadata.rb
index 73e1f53d4..7adb66981 100644
--- a/lib/puppet/file_serving/metadata.rb
+++ b/lib/puppet/file_serving/metadata.rb
@@ -23,12 +23,7 @@ class Puppet::FileServing::Metadata
@checksum_type = type
end
- def initialize(path, checksum_type = "md5")
- raise ArgumentError.new("Files must be fully qualified") unless path =~ /^#{::File::SEPARATOR}/
- raise ArgumentError.new("Files must exist") unless FileTest.exists?(path)
-
- @path = path
-
+ def get_attributes
stat = File.stat(path)
@owner = stat.uid
@group = stat.gid
@@ -36,10 +31,20 @@ class Puppet::FileServing::Metadata
# Set the octal mode, but as a string.
@mode = "%o" % (stat.mode & 007777)
- @checksum_type = checksum_type
@checksum = get_checksum
end
+ def initialize(path = nil)
+ if path
+ raise ArgumentError.new("Files must be fully qualified") unless path =~ /^#{::File::SEPARATOR}/
+ raise ArgumentError.new("Files must exist") unless FileTest.exists?(path)
+
+ @path = path
+ end
+
+ @checksum_type = "md5"
+ end
+
private
# Retrieve our checksum.
diff --git a/lib/puppet/file_serving/terminus_helper.rb b/lib/puppet/file_serving/terminus_helper.rb
new file mode 100644
index 000000000..b7f560c57
--- /dev/null
+++ b/lib/puppet/file_serving/terminus_helper.rb
@@ -0,0 +1,22 @@
+#
+# Created by Luke Kanies on 2007-10-16.
+# Copyright (c) 2007. All rights reserved.
+
+require 'uri'
+require 'puppet/file_serving'
+require 'puppet/file_serving/configuration'
+
+module Puppet::FileServing::TerminusHelper
+ def key2uri(key)
+ # Return it directly if it's fully qualified.
+ if key =~ /^#{::File::SEPARATOR}/
+ key = "file://" + key
+ end
+
+ begin
+ uri = URI.parse(URI.escape(key))
+ rescue => detail
+ raise ArgumentError, "Could not understand URI %s: %s" % [key, detail.to_s]
+ end
+ end
+end
diff --git a/lib/puppet/file_serving/terminus_selector.rb b/lib/puppet/file_serving/terminus_selector.rb
index 0cec4bf98..4525a8570 100644
--- a/lib/puppet/file_serving/terminus_selector.rb
+++ b/lib/puppet/file_serving/terminus_selector.rb
@@ -9,18 +9,26 @@ require 'puppet/file_serving'
# in file-serving indirections. This is necessary because
# the terminus varies based on the URI asked for.
module Puppet::FileServing::TerminusSelector
- PROTOCOL_MAP = {"puppet" => :rest, "file" => :local}
+ PROTOCOL_MAP = {"puppet" => :rest, "file" => :local, "puppetmounts" => :mounts}
# Pick an appropriate terminus based on the protocol.
- def select_terminus(uri)
+ def select_terminus(full_uri)
# Short-circuit to :local if it's a fully-qualified path.
- return PROTOCOL_MAP["file"] if uri =~ /^#{::File::SEPARATOR}/
+ return PROTOCOL_MAP["file"] if full_uri =~ /^#{::File::SEPARATOR}/
begin
- uri = URI.parse(URI.escape(uri))
+ uri = URI.parse(URI.escape(full_uri))
rescue => detail
- raise ArgumentError, "Could not understand URI %s: %s" % [uri, detail.to_s]
+ raise ArgumentError, "Could not understand URI %s: %s" % [full_uri, detail.to_s]
end
- return PROTOCOL_MAP[uri.scheme] || raise(ArgumentError, "URI protocol '%s' is not supported for file serving" % uri.scheme)
+ terminus = PROTOCOL_MAP[uri.scheme] || raise(ArgumentError, "URI protocol '%s' is not supported for file serving" % uri.scheme)
+
+ # This provides a convenient mechanism for people to write configurations work
+ # well in both a networked and local setting.
+ if uri.host.nil? and uri.scheme == "puppet" and Puppet.settings[:name] == "puppet"
+ terminus = :mounts
+ end
+
+ return terminus
end
end
diff --git a/lib/puppet/indirector/file_content/local.rb b/lib/puppet/indirector/file_content/local.rb
index 34d1c7794..a597fea55 100644
--- a/lib/puppet/indirector/file_content/local.rb
+++ b/lib/puppet/indirector/file_content/local.rb
@@ -3,12 +3,19 @@
# Copyright (c) 2007. All rights reserved.
require 'puppet/file_serving/content'
+require 'puppet/file_serving/terminus_helper'
require 'puppet/indirector/file_content'
require 'puppet/indirector/file'
class Puppet::Indirector::FileContent::Local < Puppet::Indirector::File
desc "Retrieve file contents from disk."
- def find(path)
+ include Puppet::FileServing::TerminusHelper
+
+ def find(key)
+ uri = key2uri(key)
+
+ return nil unless FileTest.exists?(uri.path)
+ Puppet::FileServing::Content.new uri.path
end
end
diff --git a/lib/puppet/indirector/file_content/mounts.rb b/lib/puppet/indirector/file_content/mounts.rb
new file mode 100644
index 000000000..3d147d65a
--- /dev/null
+++ b/lib/puppet/indirector/file_content/mounts.rb
@@ -0,0 +1,28 @@
+#
+# Created by Luke Kanies on 2007-10-18.
+# Copyright (c) 2007. All rights reserved.
+
+require 'puppet/file_serving/content'
+require 'puppet/file_serving/terminus_helper'
+require 'puppet/indirector/file_content'
+require 'puppet/indirector/code'
+
+class Puppet::Indirector::FileContent::Mounts < Puppet::Indirector::Code
+ desc "Retrieve file contents using Puppet's fileserver."
+
+ include Puppet::FileServing::TerminusHelper
+
+ # This way it can be cleared or whatever and we aren't retaining
+ # a reference to the old one.
+ def configuration
+ Puppet::FileServing::Configuration.create
+ end
+
+ def find(key)
+ uri = key2uri(key)
+
+ return nil unless path = configuration.file_path(uri.path) and FileTest.exists?(path)
+
+ Puppet::FileServing::Content.new path
+ end
+end
diff --git a/lib/puppet/indirector/file_content/rest.rb b/lib/puppet/indirector/file_content/rest.rb
new file mode 100644
index 000000000..9e2de360c
--- /dev/null
+++ b/lib/puppet/indirector/file_content/rest.rb
@@ -0,0 +1,12 @@
+#
+# Created by Luke Kanies on 2007-10-18.
+# Copyright (c) 2007. All rights reserved.
+
+require 'puppet/file_serving/content'
+require 'puppet/file_serving/terminus_helper'
+require 'puppet/indirector/file_content'
+require 'puppet/indirector/rest'
+
+class Puppet::Indirector::FileContent::Rest < Puppet::Indirector::REST
+ desc "Retrieve file contents via a REST HTTP interface."
+end
diff --git a/lib/puppet/indirector/file_metadata/local.rb b/lib/puppet/indirector/file_metadata/local.rb
index f6cfa1f1c..e1d774cc8 100644
--- a/lib/puppet/indirector/file_metadata/local.rb
+++ b/lib/puppet/indirector/file_metadata/local.rb
@@ -4,13 +4,21 @@
require 'puppet/file_serving/metadata'
require 'puppet/indirector/file_metadata'
+require 'puppet/file_serving/terminus_helper'
require 'puppet/indirector/code'
class Puppet::Indirector::FileMetadata::Local < Puppet::Indirector::Code
- desc "Retrieve file metadata using Puppet's Resource Abstraction Layer.
- Returns everything about the file except its content."
+ desc "Retrieve file metadata directly from the local filesystem."
- def find(file)
- Puppet::Node::Facts.new(key, Facter.to_hash)
+ include Puppet::FileServing::TerminusHelper
+
+ def find(key)
+ uri = key2uri(key)
+
+ return nil unless FileTest.exists?(uri.path)
+ data = Puppet::FileServing::Metadata.new uri.path
+ data.get_attributes
+
+ return data
end
end
diff --git a/lib/puppet/indirector/file_metadata/mounts.rb b/lib/puppet/indirector/file_metadata/mounts.rb
new file mode 100644
index 000000000..6d7fe15c6
--- /dev/null
+++ b/lib/puppet/indirector/file_metadata/mounts.rb
@@ -0,0 +1,28 @@
+#
+# Created by Luke Kanies on 2007-10-18.
+# Copyright (c) 2007. All rights reserved.
+
+require 'puppet/file_serving/metadata'
+require 'puppet/file_serving/terminus_helper'
+require 'puppet/indirector/file_metadata'
+require 'puppet/indirector/code'
+
+class Puppet::Indirector::FileMetadata::Mounts < Puppet::Indirector::Code
+ desc "Retrieve file metadata using Puppet's fileserver."
+
+ include Puppet::FileServing::TerminusHelper
+
+ # This way it can be cleared or whatever and we aren't retaining
+ # a reference to the old one.
+ def configuration
+ Puppet::FileServing::Configuration.create
+ end
+
+ def find(key)
+ uri = key2uri(key)
+
+ return nil unless path = configuration.file_path(uri.path) and FileTest.exists?(path)
+
+ Puppet::FileServing::Metadata.new path
+ end
+end
diff --git a/lib/puppet/indirector/file_metadata/rest.rb b/lib/puppet/indirector/file_metadata/rest.rb
new file mode 100644
index 000000000..dcf875b25
--- /dev/null
+++ b/lib/puppet/indirector/file_metadata/rest.rb
@@ -0,0 +1,12 @@
+#
+# Created by Luke Kanies on 2007-10-18.
+# Copyright (c) 2007. All rights reserved.
+
+require 'puppet/file_serving/metadata'
+require 'puppet/file_serving/terminus_helper'
+require 'puppet/indirector/file_metadata'
+require 'puppet/indirector/rest'
+
+class Puppet::Indirector::FileMetadata::Rest < Puppet::Indirector::REST
+ desc "Retrieve file metadata via a REST HTTP interface."
+end
diff --git a/spec/integration/file_serving/content.rb b/spec/integration/file_serving/content.rb
new file mode 100755
index 000000000..aee2a9f2d
--- /dev/null
+++ b/spec/integration/file_serving/content.rb
@@ -0,0 +1,18 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2007-10-18.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/file_serving/content'
+require 'shared_behaviours/file_serving'
+
+describe Puppet::FileServing::Content, " when finding files" do
+ it_should_behave_like "Puppet::FileServing::Files"
+
+ before do
+ @test_class = Puppet::FileServing::Content
+ @indirection = Puppet::FileServing::Content.indirection
+ end
+end
diff --git a/spec/integration/file_serving/metadata.rb b/spec/integration/file_serving/metadata.rb
new file mode 100755
index 000000000..5600365f1
--- /dev/null
+++ b/spec/integration/file_serving/metadata.rb
@@ -0,0 +1,19 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2007-10-18.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/file_serving/metadata'
+require 'shared_behaviours/file_serving'
+
+describe Puppet::FileServing::Metadata, " when finding files" do
+ it_should_behave_like "Puppet::FileServing::Files"
+
+ before do
+ @test_class = Puppet::FileServing::Metadata
+ @indirection = Puppet::FileServing::Metadata.indirection
+ end
+end
+
diff --git a/spec/integration/indirector/file_content/mounts.rb b/spec/integration/indirector/file_content/mounts.rb
new file mode 100755
index 000000000..cd80825c7
--- /dev/null
+++ b/spec/integration/indirector/file_content/mounts.rb
@@ -0,0 +1,18 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2007-10-18.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/file_content/mounts'
+require 'shared_behaviours/file_server_mounts'
+
+describe Puppet::Indirector::FileContent::Mounts, " when finding files" do
+ it_should_behave_like "Puppet::Indirector::FileServerMounts"
+
+ before do
+ @terminus = Puppet::Indirector::FileContent::Mounts.new
+ @test_class = Puppet::FileServing::Content
+ end
+end
diff --git a/spec/integration/indirector/file_metadata/mounts.rb b/spec/integration/indirector/file_metadata/mounts.rb
new file mode 100755
index 000000000..5899a9dbd
--- /dev/null
+++ b/spec/integration/indirector/file_metadata/mounts.rb
@@ -0,0 +1,18 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2007-10-18.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/file_metadata/mounts'
+require 'shared_behaviours/file_server_mounts'
+
+describe Puppet::Indirector::FileMetadata::Mounts, " when finding files" do
+ it_should_behave_like "Puppet::Indirector::FileServerMounts"
+
+ before do
+ @terminus = Puppet::Indirector::FileMetadata::Mounts.new
+ @test_class = Puppet::FileServing::Metadata
+ end
+end
diff --git a/spec/lib/shared_behaviours/file_server_mounts.rb b/spec/lib/shared_behaviours/file_server_mounts.rb
new file mode 100644
index 000000000..955f88b44
--- /dev/null
+++ b/spec/lib/shared_behaviours/file_server_mounts.rb
@@ -0,0 +1,37 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2007-10-18.
+# Copyright (c) 2007. All rights reserved.
+
+describe "Puppet::Indirector::FileServerMounts", :shared => true do
+ # This only works if the shared behaviour is included before
+ # the 'before' block in the including context.
+ before do
+ Puppet::FileServing::Configuration.clear_cache
+ FileTest.stubs(:exists?).with(Puppet[:fileserverconfig]).returns(true)
+ FileTest.stubs(:exists?).with("/my/mount/path").returns(true)
+ FileTest.stubs(:directory?).with("/my/mount/path").returns(true)
+ FileTest.stubs(:readable?).with("/my/mount/path").returns(true)
+
+ # Use a real mount, so the integration is a bit deeper.
+ @mount1 = Puppet::FileServing::Configuration::Mount.new("one")
+ @mount1.path = "/my/mount/path"
+
+ @parser = stub 'parser', :changed? => false
+ @parser.stubs(:parse).returns("one" => @mount1)
+
+ Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
+
+ Puppet::FileServing::Configuration.create.stubs(:modules_mount)
+ end
+
+ it "should use the file server configuration to find files" do
+ path = "/my/mount/path/my/file"
+ FileTest.stubs(:exists?).with(path).returns(true)
+ @test_class.expects(:new).with(path).returns(:myinstance)
+ FileTest.stubs(:exists?).with("/my/mount/path").returns(true)
+ @mount1.expects(:file).with("my/file", {}).returns(path)
+
+ @terminus.find("puppetmounts://myhost/one/my/file").should == :myinstance
+ end
+end
diff --git a/spec/lib/shared_behaviours/file_serving.rb b/spec/lib/shared_behaviours/file_serving.rb
new file mode 100644
index 000000000..ffc96ee78
--- /dev/null
+++ b/spec/lib/shared_behaviours/file_serving.rb
@@ -0,0 +1,49 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2007-10-18.
+# Copyright (c) 2007. All rights reserved.
+
+describe "Puppet::FileServing::Files", :shared => true do
+ it "should use the rest terminus when the 'puppet' URI scheme is used and a host name is present" do
+ uri = "puppet://myhost/mymod/my/file"
+ @indirection.terminus(:rest).expects(:find).with(uri)
+ @test_class.find(uri)
+ end
+
+ it "should use the rest terminus when the 'puppet' URI scheme is used, no host name is present, and the process name is not 'puppet'" do
+ uri = "puppet:///mymod/my/file"
+ Puppet.settings.stubs(:value).with(:name).returns("puppetd")
+ Puppet.settings.stubs(:value).with(:modulepath).returns("")
+ @indirection.terminus(:rest).expects(:find).with(uri)
+ @test_class.find(uri)
+ end
+
+ it "should use the mounts terminus when the 'puppet' URI scheme is used, no host name is present, and the process name is 'puppet'" do
+ uri = "puppet:///mymod/my/file"
+ Puppet.settings.stubs(:value).with(:name).returns("puppet")
+ Puppet.settings.stubs(:value).with(:modulepath).returns("")
+ Puppet.settings.stubs(:value).with(:libdir).returns("")
+ Puppet.settings.stubs(:value).with(:fileserverconfig).returns("/whatever")
+ @indirection.terminus(:mounts).expects(:find).with(uri)
+ @test_class.find(uri)
+ end
+
+ it "should use the mounts terminus when the 'puppetmounts' URI scheme is used" do
+ uri = "puppetmounts:///mymod/my/file"
+ @indirection.terminus(:mounts).expects(:find).with(uri)
+ @test_class.find(uri)
+ end
+
+ it "should use the local terminus when the 'file' URI scheme is used" do
+ uri = "file:///mymod/my/file"
+ @indirection.terminus(:local).expects(:find).with(uri)
+ @test_class.find(uri)
+ end
+
+ it "should use the local terminus when a fully qualified path is provided" do
+ uri = "/mymod/my/file"
+ @indirection.terminus(:local).expects(:find).with(uri)
+ @test_class.find(uri)
+ end
+end
+
diff --git a/spec/unit/file_serving/configuration.rb b/spec/unit/file_serving/configuration.rb
index eabad0838..b0b3527e7 100755
--- a/spec/unit/file_serving/configuration.rb
+++ b/spec/unit/file_serving/configuration.rb
@@ -117,9 +117,7 @@ describe Puppet::FileServing::Configuration, " when using a module mount" do
it "should prefer module mounts to static mounts"
end
-# We're kind of testing the implementation here, because we know that both
-# content and metadata use the same internal method. Oh well.
-describe Puppet::FileServing::Configuration, " when using File URIs to pick the correct mount and file" do
+describe Puppet::FileServing::Configuration, " when finding files" do
include FSConfigurationTesting
before do
@@ -139,48 +137,50 @@ describe Puppet::FileServing::Configuration, " when using File URIs to pick the
it "should fail if the uri does not match a leading slash followed by a valid mount name" do
@parser.expects(:parse).returns(@mounts)
- proc { @config.metadata("something") }.should raise_error(ArgumentError)
+ proc { @config.file_path("something") }.should raise_error(ArgumentError)
end
it "should use the first term after the first slash for the mount name" do
@parser.expects(:parse).returns(@mounts)
- @mount1.expects(:file_instance)
- @config.metadata("/one")
+ @mount1.expects(:file)
+ @config.file_path("/one")
end
it "should use the remainder of the URI after the mount name as the file name" do
@parser.expects(:parse).returns(@mounts)
- @mount1.expects(:file_instance).with(:metadata, "something/else", {})
- @config.metadata("/one/something/else")
+ @mount1.expects(:file).with("something/else", {})
+ @config.file_path("/one/something/else")
end
it "should treat a bare name as a mount and no relative file" do
@parser.expects(:parse).returns(@mounts)
- @mount1.expects(:file_instance).with(:metadata, nil, {})
- @config.metadata("/one")
+ @mount1.expects(:file).with(nil, {})
+ @config.file_path("/one")
end
it "should treat a name with a trailing slash equivalently to a name with no trailing slash" do
@parser.expects(:parse).returns(@mounts)
- @mount1.expects(:file_instance).with(:metadata, nil, {})
- @config.metadata("/one/")
+ @mount1.expects(:file).with(nil, {})
+ @config.file_path("/one/")
end
it "should return nil if the mount cannot be found" do
@parser.expects(:changed?).returns(true)
@parser.expects(:parse).returns({})
- @config.metadata("/one/something").should be_nil
+ @config.file_path("/one/something").should be_nil
end
+ it "should return nil if the mount does not contain the file"
+
it "should reparse the configuration file when it has changed" do
- @mount1.stubs(:file_instance).returns("whatever")
+ @mount1.stubs(:file).returns("whatever")
@parser.expects(:changed?).returns(true)
@parser.expects(:parse).returns(@mounts)
- @config.metadata("/one/something")
+ @config.file_path("/one/something")
@parser.expects(:changed?).returns(true)
@parser.expects(:parse).returns({})
- @config.metadata("/one/something").should be_nil
+ @config.file_path("/one/something").should be_nil
end
end
diff --git a/spec/unit/file_serving/content.rb b/spec/unit/file_serving/content.rb
index 6d8e2d0ba..593278bf4 100755
--- a/spec/unit/file_serving/content.rb
+++ b/spec/unit/file_serving/content.rb
@@ -33,7 +33,7 @@ describe Puppet::FileServing::Content, " when initializing" do
proc { Puppet::FileServing::Content.new(@path) }.should raise_error(ArgumentError)
end
- it "should not read the file" do
+ it "should not stat the file" do
FileTest.expects(:exists?).with(@path).returns(true)
File.expects(:read).with(@path).never
Puppet::FileServing::Content.new(@path)
@@ -52,3 +52,13 @@ describe Puppet::FileServing::Content, " when converting to yaml" do
@content.to_yaml.should == "mycontent"
end
end
+
+describe Puppet::FileServing::Content, " when converting from yaml" do
+ # LAK:FIXME This isn't in the right place, but we need some kind of
+ # control somewhere that requires that all REST connections only pull
+ # from the file-server, thus guaranteeing they go through our authorization
+ # hook.
+ it "should set the URI scheme to 'puppetmounts'" do
+ pending "We need to figure out where this should be"
+ end
+end
diff --git a/spec/unit/file_serving/metadata.rb b/spec/unit/file_serving/metadata.rb
index f54a6feb6..1237c3184 100755
--- a/spec/unit/file_serving/metadata.rb
+++ b/spec/unit/file_serving/metadata.rb
@@ -15,11 +15,19 @@ describe Puppet::FileServing::Metadata do
end
describe Puppet::FileServing::Metadata, " when initializing" do
- it "should require a fully qualified file path" do
+ it "should allow initialization without a path" do
+ proc { Puppet::FileServing::Metadata.new() }.should_not raise_error
+ end
+
+ it "should allow initialization with a path" do
+ proc { Puppet::FileServing::Metadata.new("unqualified") }.should raise_error(ArgumentError)
+ end
+
+ it "should the path to be fully qualified if it is provied" do
proc { Puppet::FileServing::Metadata.new("unqualified") }.should raise_error(ArgumentError)
end
- it "should require the path to exist" do
+ it "should require the path to exist if it is provided" do
FileTest.expects(:exists?).with("/no/such/path").returns(false)
proc { Puppet::FileServing::Metadata.new("/no/such/path") }.should raise_error(ArgumentError)
end
@@ -36,6 +44,7 @@ describe Puppet::FileServing::Metadata do
@checksum = Digest::MD5.hexdigest("some content\n")
FileTest.expects(:exists?).with(@path).returns(true)
@metadata = Puppet::FileServing::Metadata.new(@path)
+ @metadata.get_attributes
end
it "should accept a file path" do
@@ -76,3 +85,13 @@ describe Puppet::FileServing::Metadata do
@metadata.checksum.should == "{md5}" + @checksum
end
end
+
+describe Puppet::FileServing::Metadata, " when converting from yaml" do
+ # LAK:FIXME This isn't in the right place, but we need some kind of
+ # control somewhere that requires that all REST connections only pull
+ # from the file-server, thus guaranteeing they go through our authorization
+ # hook.
+ it "should set the URI scheme to 'puppetmounts'" do
+ pending "We need to figure out where this should be"
+ end
+end
diff --git a/spec/unit/file_serving/terminus_helper.rb b/spec/unit/file_serving/terminus_helper.rb
new file mode 100755
index 000000000..f136da553
--- /dev/null
+++ b/spec/unit/file_serving/terminus_helper.rb
@@ -0,0 +1,50 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2007-10-18.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/file_serving/terminus_helper'
+
+module TerminusHelperTesting
+ def setup
+ @helper = Object.new
+ @config = mock 'fs configuration'
+ Puppet::FileServing::Configuration.stubs(:create).returns(@config)
+ @helper.extend(Puppet::FileServing::TerminusHelper)
+ end
+end
+
+describe Puppet::FileServing::TerminusHelper, " when converting a key to a URI" do
+ include TerminusHelperTesting
+
+ it "should escape the key before parsing" do
+ URI.expects(:escape).with("mykey").returns("http://myhost/blah")
+ URI.expects(:parse).with("http://myhost/blah").returns(:myuri)
+ @helper.key2uri("mykey").should == :myuri
+ end
+
+ it "should use the URI class to parse the key" do
+ URI.expects(:parse).with("http://myhost/blah").returns(:myuri)
+ @helper.key2uri("http://myhost/blah").should == :myuri
+ end
+
+ it "should set the scheme to 'file' if the key is a fully qualified path" do
+ URI.expects(:parse).with("file:///myhost/blah").returns(:myuri)
+ @helper.key2uri("/myhost/blah").should == :myuri
+ end
+
+ it "should set the host to 'nil' if the key is a fully qualified path" do
+ URI.expects(:parse).with("file:///myhost/blah").returns(:myuri)
+ @helper.key2uri("/myhost/blah").should == :myuri
+ end
+end
+
+describe Puppet::FileServing::TerminusHelper, " when returning file paths" do
+ include TerminusHelperTesting
+
+ it "should follow links if the links option is set to :follow"
+
+ it "should ignore links if the links option is not set to follow"
+end
diff --git a/spec/unit/file_serving/terminus_selector.rb b/spec/unit/file_serving/terminus_selector.rb
index 4a5683e88..d21e42839 100755
--- a/spec/unit/file_serving/terminus_selector.rb
+++ b/spec/unit/file_serving/terminus_selector.rb
@@ -13,10 +13,37 @@ describe Puppet::FileServing::TerminusSelector, " when being used to select term
@object.extend(Puppet::FileServing::TerminusSelector)
end
+ it "should escape the key before parsing" do
+ uri = stub 'uri', :scheme => "puppet", :host => "blah", :path => "/something"
+ URI.expects(:escape).with("mykey").returns("http://myhost/blah")
+ URI.expects(:parse).with("http://myhost/blah").returns(uri)
+ @object.select_terminus("mykey")
+ end
+
+ it "should use the URI class to parse the key" do
+ uri = stub 'uri', :scheme => "puppet", :host => "blah", :path => "/something"
+ URI.expects(:parse).with("http://myhost/blah").returns(uri)
+ @object.select_terminus("http://myhost/blah")
+ end
+
it "should choose :rest when the protocol is 'puppet'" do
@object.select_terminus("puppet://host/module/file").should == :rest
end
+ it "should choose :mounts when the protocol is 'puppetmounts'" do
+ @object.select_terminus("puppetmounts://host/module/file").should == :mounts
+ end
+
+ it "should choose :mounts when no server name is provided and the process name is 'puppet'" do
+ Puppet.settings.expects(:value).with(:name).returns("puppet")
+ @object.select_terminus("puppet:///module/file").should == :mounts
+ end
+
+ it "should choose :rest when no server name is provided and the process name is not 'puppet'" do
+ Puppet.settings.expects(:value).with(:name).returns("puppetd")
+ @object.select_terminus("puppet:///module/file").should == :rest
+ end
+
it "should choose :local when the protocol is 'file'" do
@object.select_terminus("file://host/module/file").should == :local
end
@@ -25,7 +52,7 @@ describe Puppet::FileServing::TerminusSelector, " when being used to select term
@object.select_terminus("/module/file").should == :local
end
- it "should fail when a protocol other than :puppet or :file is used" do
+ it "should fail when a protocol other than :puppet, :file, or :puppetmounts is used" do
proc { @object.select_terminus("http:///module/file") }.should raise_error(ArgumentError)
end
end
diff --git a/spec/unit/indirector/file_content/local.rb b/spec/unit/indirector/file_content/local.rb
index 81ebd8ed0..361628767 100755
--- a/spec/unit/indirector/file_content/local.rb
+++ b/spec/unit/indirector/file_content/local.rb
@@ -17,13 +17,21 @@ describe Puppet::Indirector::FileContent::Local do
end
end
-describe Puppet::Indirector::FileContent::Local, "when finding a single local" do
- before do
+describe Puppet::Indirector::FileContent::Local, "when finding a single file" do
+ it "should return a Content instance created with the full path to the file if the file exists" do
@content = Puppet::Indirector::FileContent::Local.new
- @path = "/my/local"
+ @uri = "file:///my/local"
+
+ FileTest.expects(:exists?).with("/my/local").returns true
+ Puppet::FileServing::Content.expects(:new).with("/my/local").returns(:mycontent)
+ @content.find(@uri).should == :mycontent
end
- it "should return nil if the local does not exist"
+ it "should return nil if the file does not exist" do
+ @content = Puppet::Indirector::FileContent::Local.new
+ @uri = "file:///my/local"
- it "should return a Content instance with the path set to the local if the local exists"
+ FileTest.expects(:exists?).with("/my/local").returns false
+ @content.find(@uri).should be_nil
+ end
end
diff --git a/spec/unit/indirector/file_content/mounts.rb b/spec/unit/indirector/file_content/mounts.rb
new file mode 100755
index 000000000..0a137d57e
--- /dev/null
+++ b/spec/unit/indirector/file_content/mounts.rb
@@ -0,0 +1,53 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2007-10-18.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/file_content/mounts'
+
+describe Puppet::Indirector::FileContent::Mounts do
+ it "should be registered with the file_content indirection" do
+ Puppet::Indirector::Terminus.terminus_class(:file_content, :mounts).should equal(Puppet::Indirector::FileContent::Mounts)
+ end
+
+ it "should be a subclass of the Code terminus" do
+ Puppet::Indirector::FileContent::Mounts.superclass.should equal(Puppet::Indirector::Code)
+ end
+end
+
+describe Puppet::Indirector::FileContent::Mounts, "when finding a single file" do
+ before do
+ @content = Puppet::Indirector::FileContent::Mounts.new
+ @uri = "puppetmounts://host/my/local"
+ end
+
+ it "should use the path portion of the URI as the file name" do
+ Puppet::FileServing::Configuration.create.expects(:file_path).with("/my/local")
+ @content.find(@uri)
+ end
+
+ it "should use the FileServing configuration to convert the file name to a fully qualified path" do
+ Puppet::FileServing::Configuration.create.expects(:file_path).with("/my/local")
+ @content.find(@uri)
+ end
+
+ it "should return nil if no fully qualified path is found" do
+ Puppet::FileServing::Configuration.create.expects(:file_path).with("/my/local").returns(nil)
+ @content.find(@uri).should be_nil
+ end
+
+ it "should return nil if the configuration returns a file path that does not exist" do
+ Puppet::FileServing::Configuration.create.expects(:file_path).with("/my/local").returns("/some/file")
+ FileTest.expects(:exists?).with("/some/file").returns(false)
+ @content.find(@uri).should be_nil
+ end
+
+ it "should return a Content instance if a file is found and it exists" do
+ Puppet::FileServing::Configuration.create.expects(:file_path).with("/my/local").returns("/some/file")
+ FileTest.expects(:exists?).with("/some/file").returns(true)
+ Puppet::FileServing::Content.expects(:new).with("/some/file").returns(:mycontent)
+ @content.find(@uri).should == :mycontent
+ end
+end
diff --git a/spec/unit/indirector/file_metadata/local.rb b/spec/unit/indirector/file_metadata/local.rb
index 26837b911..604cdf6af 100755
--- a/spec/unit/indirector/file_metadata/local.rb
+++ b/spec/unit/indirector/file_metadata/local.rb
@@ -12,3 +12,32 @@ describe Puppet::Indirector::FileMetadata::Local do
Puppet::Indirector::Terminus.terminus_class(:file_metadata, :local).should equal(Puppet::Indirector::FileMetadata::Local)
end
end
+
+describe Puppet::Indirector::FileMetadata::Local, "when finding a single file" do
+ before do
+ @content = Puppet::Indirector::FileMetadata::Local.new
+ @uri = "file:///my/local"
+
+ @data = mock 'metadata'
+ end
+ it "should return a Metadata instance created with the full path to the file if the file exists" do
+ @data.stubs(:get_attributes)
+
+ FileTest.expects(:exists?).with("/my/local").returns true
+ Puppet::FileServing::Metadata.expects(:new).with("/my/local").returns(@data)
+ @content.find(@uri).should == @data
+ end
+
+ it "should collect its attributes when a file is found" do
+ @data.expects(:get_attributes)
+
+ FileTest.expects(:exists?).with("/my/local").returns true
+ Puppet::FileServing::Metadata.expects(:new).with("/my/local").returns(@data)
+ @content.find(@uri).should == @data
+ end
+
+ it "should return nil if the file does not exist" do
+ FileTest.expects(:exists?).with("/my/local").returns false
+ @content.find(@uri).should be_nil
+ end
+end
diff --git a/spec/unit/indirector/file_metadata/mounts.rb b/spec/unit/indirector/file_metadata/mounts.rb
new file mode 100755
index 000000000..558e920ee
--- /dev/null
+++ b/spec/unit/indirector/file_metadata/mounts.rb
@@ -0,0 +1,54 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2007-10-18.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/file_metadata/mounts'
+
+describe Puppet::Indirector::FileMetadata::Mounts do
+ it "should be registered with the file_metadata indirection" do
+ Puppet::Indirector::Terminus.terminus_class(:file_metadata, :mounts).should equal(Puppet::Indirector::FileMetadata::Mounts)
+ end
+
+ it "should be a subclass of the Code terminus" do
+ Puppet::Indirector::FileMetadata::Mounts.superclass.should equal(Puppet::Indirector::Code)
+ end
+end
+
+describe Puppet::Indirector::FileMetadata::Mounts, "when finding a single file" do
+ before do
+ @metadata = Puppet::Indirector::FileMetadata::Mounts.new
+ @uri = "puppetmounts://host/my/local"
+ end
+
+ it "should use the path portion of the URI as the file name" do
+ Puppet::FileServing::Configuration.create.expects(:file_path).with("/my/local")
+ @metadata.find(@uri)
+ end
+
+ it "should use the FileServing configuration to convert the file name to a fully qualified path" do
+ Puppet::FileServing::Configuration.create.expects(:file_path).with("/my/local")
+ @metadata.find(@uri)
+ end
+
+ it "should return nil if no fully qualified path is found" do
+ Puppet::FileServing::Configuration.create.expects(:file_path).with("/my/local").returns(nil)
+ @metadata.find(@uri).should be_nil
+ end
+
+ it "should return nil if the configuration returns a file path that does not exist" do
+ Puppet::FileServing::Configuration.create.expects(:file_path).with("/my/local").returns("/some/file")
+ FileTest.expects(:exists?).with("/some/file").returns(false)
+ @metadata.find(@uri).should be_nil
+ end
+
+ it "should return a Metadata instance if a file is found and it exists" do
+ Puppet::FileServing::Configuration.create.expects(:file_path).with("/my/local").returns("/some/file")
+ FileTest.expects(:exists?).with("/some/file").returns(true)
+ Puppet::FileServing::Metadata.expects(:new).with("/some/file").returns(:mymetadata)
+ @metadata.find(@uri).should == :mymetadata
+ end
+end
+