summaryrefslogtreecommitdiffstats
path: root/spec
diff options
context:
space:
mode:
authorPaul Berry <paul@puppetlabs.com>2011-02-17 14:59:59 -0800
committerPaul Berry <paul@puppetlabs.com>2011-02-17 14:59:59 -0800
commit23fc4db954c22bce2c6cc8996d5fafb175e2b747 (patch)
treefef367b2b6a94148b0207ad13acd53e42d49bea1 /spec
parentab27da7967e1e145d5fbc130e5fbcec6795ca775 (diff)
downloadpuppet-23fc4db954c22bce2c6cc8996d5fafb175e2b747.tar.gz
puppet-23fc4db954c22bce2c6cc8996d5fafb175e2b747.tar.xz
puppet-23fc4db954c22bce2c6cc8996d5fafb175e2b747.zip
(#5132) Provide a query REST interface for inventory
This REST interface returns a list of nodes that match a fact query. Fact queries can use (in)equality testing as a string comparison, and >, <, >=, <= numerical comparisons. Multiple tests can be done as AND comparisons, not OR. The fact queries need to be prefixed by facts, and the comparisons other than equality are specified with a .comparison_type after the fact name. This will be better explained in the REST documentation on the website. Searches that don't match anything now return empty array instead of a 404 error. Conflicts: spec/spec_helper.rb
Diffstat (limited to 'spec')
-rwxr-xr-xspec/unit/indirector/facts/yaml_spec.rb4
-rw-r--r--spec/unit/indirector/inventory/yaml_spec.rb130
-rw-r--r--spec/unit/network/http/api/v1_spec.rb12
-rwxr-xr-xspec/unit/network/http/handler_spec.rb11
4 files changed, 151 insertions, 6 deletions
diff --git a/spec/unit/indirector/facts/yaml_spec.rb b/spec/unit/indirector/facts/yaml_spec.rb
index e7bac3471..37a1bcae0 100755
--- a/spec/unit/indirector/facts/yaml_spec.rb
+++ b/spec/unit/indirector/facts/yaml_spec.rb
@@ -10,9 +10,9 @@ describe Puppet::Node::Facts::Yaml do
Puppet::Node::Facts::Yaml.superclass.should equal(Puppet::Indirector::Yaml)
end
-
it "should have documentation" do
Puppet::Node::Facts::Yaml.doc.should_not be_nil
+ Puppet::Node::Facts::Yaml.doc.should_not be_empty
end
it "should be registered with the facts indirection" do
@@ -20,7 +20,7 @@ describe Puppet::Node::Facts::Yaml do
Puppet::Node::Facts::Yaml.indirection.should equal(indirection)
end
- it "should have its name set to :facts" do
+ it "should have its name set to :yaml" do
Puppet::Node::Facts::Yaml.name.should == :yaml
end
end
diff --git a/spec/unit/indirector/inventory/yaml_spec.rb b/spec/unit/indirector/inventory/yaml_spec.rb
new file mode 100644
index 000000000..3a7035a9e
--- /dev/null
+++ b/spec/unit/indirector/inventory/yaml_spec.rb
@@ -0,0 +1,130 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/node/inventory'
+require 'puppet/indirector/inventory/yaml'
+require 'puppet/indirector/request'
+
+describe Puppet::Node::Inventory::Yaml do
+ def setup_search_matching(matching, nonmatching, query)
+ request = Puppet::Indirector::Request.new(:inventory, :search, nil, query)
+
+ Dir.stubs(:glob).returns(matching.keys + nonmatching.keys)
+ [matching, nonmatching].each do |examples|
+ examples.each do |key, value|
+ YAML.stubs(:load_file).with(key).returns value
+ end
+ end
+ return matching, request
+ end
+
+ it "should return node names that match the search query options" do
+ matching, request = setup_search_matching({
+ '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '4'),
+ '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "i386", 'processor_count' => '4', 'randomfact' => 'foo')
+ },
+ {
+ "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '4'),
+ "/path/to/nonmatching1.yaml" => Puppet::Node::Facts.new("nonmatchingnode1", "architecture" => "powerpc", 'processor_count' => '5'),
+ "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '5'),
+ "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3", 'processor_count' => '4'),
+ },
+ {'facts.architecture' => 'i386', 'facts.processor_count' => '4'}
+ )
+ Puppet::Node::Inventory::Yaml.new.search(request).should =~ matching.values.map {|facts| facts.name}
+ end
+
+ it "should return empty array when no nodes match the search query options" do
+ matching, request = setup_search_matching({}, {
+ "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '10'),
+ "/path/to/nonmatching1.yaml" => Puppet::Node::Facts.new("nonmatchingnode1", "architecture" => "powerpc", 'processor_count' => '5'),
+ "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '5'),
+ "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3", 'processor_count' => '4'),
+ },
+ {'facts.processor_count.lt' => '4', 'facts.processor_count.gt' => '4'}
+ )
+ Puppet::Node::Inventory::Yaml.new.search(request).should =~ matching.values.map {|facts| facts.name}
+ end
+
+
+ it "should return node names that match the search query options with the greater than operator" do
+ matching, request = setup_search_matching({
+ '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '5'),
+ '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "powerpc", 'processor_count' => '10', 'randomfact' => 'foo')
+ },
+ {
+ "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '4'),
+ "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '3'),
+ "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ),
+ },
+ {'facts.processor_count.gt' => '4'}
+ )
+
+ Puppet::Node::Inventory::Yaml.new.search(request).should =~ matching.values.map {|facts| facts.name}
+ end
+
+ it "should return node names that match the search query options with the less than operator" do
+ matching, request = setup_search_matching({
+ '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '5'),
+ '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "powerpc", 'processor_count' => '30', 'randomfact' => 'foo')
+ },
+ {
+ "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '50' ),
+ "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '100'),
+ "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ),
+ },
+ {'facts.processor_count.lt' => '50'}
+ )
+
+ Puppet::Node::Inventory::Yaml.new.search(request).should =~ matching.values.map {|facts| facts.name}
+ end
+
+ it "should return node names that match the search query options with the less than or equal to operator" do
+ matching, request = setup_search_matching({
+ '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '5'),
+ '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "powerpc", 'processor_count' => '50', 'randomfact' => 'foo')
+ },
+ {
+ "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '100' ),
+ "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '5000'),
+ "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ),
+ },
+ {'facts.processor_count.le' => '50'}
+ )
+
+ Puppet::Node::Inventory::Yaml.new.search(request).should =~ matching.values.map {|facts| facts.name}
+ end
+
+ it "should return node names that match the search query options with the greater than or equal to operator" do
+ matching, request = setup_search_matching({
+ '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '100'),
+ '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "powerpc", 'processor_count' => '50', 'randomfact' => 'foo')
+ },
+ {
+ "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '40'),
+ "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '9' ),
+ "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ),
+ },
+ {'facts.processor_count.ge' => '50'}
+ )
+
+ Puppet::Node::Inventory::Yaml.new.search(request).should =~ matching.values.map {|facts| facts.name}
+ end
+
+ it "should return node names that match the search query options with the not equal operator" do
+ matching, request = setup_search_matching({
+ '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => 'arm' ),
+ '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => 'powerpc', 'randomfact' => 'foo')
+ },
+ {
+ "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "i386" ),
+ "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '9' ),
+ "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ),
+ },
+ {'facts.architecture.ne' => 'i386'}
+ )
+
+ Puppet::Node::Inventory::Yaml.new.search(request).should =~ matching.values.map {|facts| facts.name}
+ end
+end
diff --git a/spec/unit/network/http/api/v1_spec.rb b/spec/unit/network/http/api/v1_spec.rb
index 23a291cf3..d47fc8d81 100644
--- a/spec/unit/network/http/api/v1_spec.rb
+++ b/spec/unit/network/http/api/v1_spec.rb
@@ -76,6 +76,18 @@ describe Puppet::Network::HTTP::API::V1 do
@tester.uri2indirection("GET", "/env/foos/bar", {}).method.should == :search
end
+ it "should choose 'find' as the indirection method if the http method is a GET and the indirection name is facts" do
+ @tester.uri2indirection("GET", "/env/facts/bar", {}).method.should == :find
+ end
+
+ it "should choose 'save' as the indirection method if the http method is a PUT and the indirection name is facts" do
+ @tester.uri2indirection("PUT", "/env/facts/bar", {}).method.should == :save
+ end
+
+ it "should choose 'search' as the indirection method if the http method is a GET and the indirection name is inventory" do
+ @tester.uri2indirection("GET", "/env/inventory/search", {}).method.should == :search
+ end
+
it "should choose 'delete' as the indirection method if the http method is a DELETE and the indirection name is singular" do
@tester.uri2indirection("DELETE", "/env/foo/bar", {}).method.should == :destroy
end
diff --git a/spec/unit/network/http/handler_spec.rb b/spec/unit/network/http/handler_spec.rb
index 8464ae68e..68c7b9aa3 100755
--- a/spec/unit/network/http/handler_spec.rb
+++ b/spec/unit/network/http/handler_spec.rb
@@ -344,17 +344,20 @@ describe Puppet::Network::HTTP::Handler do
@handler.do_search(@irequest, @request, @response)
end
- it "should return a 404 when searching returns an empty array" do
- @model_class.stubs(:name).returns "my name"
- @handler.expects(:set_response).with { |response, body, status| status == 404 }
+ it "should return [] when searching returns an empty array" do
+ @handler.expects(:accept_header).with(@request).returns "one,two"
@model_class.stubs(:search).returns([])
+ @model_class.expects(:render_multiple).with(@oneformat, []).returns "[]"
+
+
+ @handler.expects(:set_response).with { |response, data| data == "[]" }
@handler.do_search(@irequest, @request, @response)
end
it "should return a 404 when searching returns nil" do
@model_class.stubs(:name).returns "my name"
@handler.expects(:set_response).with { |response, body, status| status == 404 }
- @model_class.stubs(:search).returns([])
+ @model_class.stubs(:search).returns(nil)
@handler.do_search(@irequest, @request, @response)
end
end