From aab419b8c1ad84e51c6f58839290bbe5d1e7b28b Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Tue, 14 Aug 2007 00:09:49 -0500 Subject: An intermediate commit in the work towards adding multi-environment support. This has required splitting the interpreter up considerably, which is much cleaner but is a large project. There is now a 'nodes' handler, but it is currently non-functional, although all the support structure is there. It just needs to have the individual methods fleshed out, and it needs to be connected to the 'facts' handler. --- test/network/handler/node.rb | 341 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 341 insertions(+) create mode 100755 test/network/handler/node.rb (limited to 'test/network/handler') diff --git a/test/network/handler/node.rb b/test/network/handler/node.rb new file mode 100755 index 000000000..c682929d9 --- /dev/null +++ b/test/network/handler/node.rb @@ -0,0 +1,341 @@ +#!/usr/bin/env ruby + +$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/ + +require 'mocha' +require 'puppettest' +require 'puppettest/resourcetesting' +require 'puppettest/parsertesting' +require 'puppettest/servertest' +require 'puppet/network/handler/node' + +module NodeTesting + include PuppetTest + Node = Puppet::Network::Handler::Node + SimpleNode = Puppet::Network::Handler::Node::SimpleNode + + def mk_node_mapper + # First, make sure our nodesearch command works as we expect + # Make a nodemapper + mapper = tempfile() + ruby = %x{which ruby}.chomp + File.open(mapper, "w") { |f| + f.puts "#!#{ruby} + require 'yaml' + name = ARGV.last.chomp + result = {} + + if name =~ /a/ + result[:parameters] = {'one' => ARGV.last + '1', 'two' => ARGV.last + '2'} + end + + if name =~ /p/ + result['classes'] = [1,2,3].collect { |n| ARGV.last + n.to_s } + end + + puts YAML.dump(result) + " + } + File.chmod(0755, mapper) + mapper + end + + def mk_searcher(name) + searcher = Object.new + searcher.extend(Node.node_source(name)) + end +end + +class TestNodeInterface < Test::Unit::TestCase + def setup + super + end + + def teardown + end + + def test_node + raise "Failing, yo" + end + + def test_environment + raise "still failing" + end + + def test_parameters + raise "still failing" + end + + def test_classes + raise "still failing" + end +end + +# Test our configuration object. +class TestNodeSources < Test::Unit::TestCase + include NodeTesting + + def test_node_sources + mod = nil + assert_nothing_raised("Could not add new search type") do + mod = Node.newnode_source(:testing) do + def nodesearch(name) + end + end + end + assert_equal(mod, Node.node_source(:testing), "Did not get node_source back") + + cleanup do + Node.rm_node_source(:testing) + end + end + + def test_external_node_source + mapper = mk_node_mapper + searcher = mk_searcher(:external) + + # Make sure it gives the right response + assert_equal({'classes' => %w{apple1 apple2 apple3}, :parameters => {"one" => "apple1", "two" => "apple2"}}, + YAML.load(%x{#{mapper} apple})) + + # First make sure we get nil back by default + assert_nothing_raised { + assert_nil(searcher.nodesearch("apple"), + "Interp#nodesearch_external defaulted to a non-nil response") + } + assert_nothing_raised { Puppet[:external_nodes] = mapper } + + node = nil + # Both 'a' and 'p', so we get classes and parameters + assert_nothing_raised { node = searcher.nodesearch("apple") } + assert_equal("apple", node.name, "node name was not set correctly for apple") + assert_equal(%w{apple1 apple2 apple3}, node.classes, "node classes were not set correctly for apple") + assert_equal( {"one" => "apple1", "two" => "apple2"}, node.parameters, "node parameters were not set correctly for apple") + + # A 'p' but no 'a', so we only get classes + assert_nothing_raised { node = searcher.nodesearch("plum") } + assert_equal("plum", node.name, "node name was not set correctly for plum") + assert_equal(%w{plum1 plum2 plum3}, node.classes, "node classes were not set correctly for plum") + assert_equal({}, node.parameters, "node parameters were not set correctly for plum") + + # An 'a' but no 'p', so we only get parameters. + assert_nothing_raised { node = searcher.nodesearch("guava")} # no p's, thus no classes + assert_equal("guava", node.name, "node name was not set correctly for guava") + assert_equal([], node.classes, "node classes were not set correctly for guava") + assert_equal({"one" => "guava1", "two" => "guava2"}, node.parameters, "node parameters were not set correctly for guava") + + assert_nothing_raised { node = searcher.nodesearch("honeydew")} # neither, thus nil + assert_nil(node) + end + + # Make sure a nodesearch with arguments works + def test_nodesearch_external_arguments + mapper = mk_node_mapper + Puppet[:external_nodes] = "#{mapper} -s something -p somethingelse" + searcher = mk_searcher(:external) + node = nil + assert_nothing_raised do + node = searcher.nodesearch("apple") + end + assert_instance_of(SimpleNode, node, "did not create node") + end + + # A wrapper test, to make sure we're correctly calling the external search method. + def test_nodesearch_external_functional + mapper = mk_node_mapper + searcher = mk_searcher(:external) + + Puppet[:external_nodes] = mapper + + node = nil + assert_nothing_raised do + node = searcher.nodesearch("apple") + end + assert_instance_of(SimpleNode, node, "did not create node") + end + + # This can stay in the main test suite because it doesn't actually use ldapsearch, + # it just overrides the method so it behaves as though it were hitting ldap. + def test_ldap_nodesearch + searcher = mk_searcher(:ldap) + + nodetable = {} + + # Override the ldapsearch definition, so we don't have to actually set it up. + searcher.meta_def(:ldapsearch) do |name| + nodetable[name] + end + + # Make sure we get nothing for nonexistent hosts + node = nil + assert_nothing_raised do + node = searcher.nodesearch("nosuchhost") + end + + assert_nil(node, "Got a node for a non-existent host") + + # Now add a base node with some classes and parameters + nodetable["base"] = [nil, %w{one two}, {"base" => "true"}] + + assert_nothing_raised do + node = searcher.nodesearch("base") + end + + assert_instance_of(SimpleNode, node, "Did not get node from ldap nodesearch") + assert_equal("base", node.name, "node name was not set") + + assert_equal(%w{one two}, node.classes, "node classes were not set") + assert_equal({"base" => "true"}, node.parameters, "node parameters were not set") + + # Now use a different with this as the base + nodetable["middle"] = ["base", %w{three}, {"center" => "boo"}] + assert_nothing_raised do + node = searcher.nodesearch("middle") + end + + assert_instance_of(SimpleNode, node, "Did not get node from ldap nodesearch") + assert_equal("middle", node.name, "node name was not set") + + assert_equal(%w{one two three}.sort, node.classes.sort, "node classes were not set correctly with a parent node") + assert_equal({"base" => "true", "center" => "boo"}, node.parameters, "node parameters were not set correctly with a parent node") + + # And one further, to make sure we fully recurse + nodetable["top"] = ["middle", %w{four five}, {"master" => "far"}] + assert_nothing_raised do + node = searcher.nodesearch("top") + end + + assert_instance_of(SimpleNode, node, "Did not get node from ldap nodesearch") + assert_equal("top", node.name, "node name was not set") + + assert_equal(%w{one two three four five}.sort, node.classes.sort, "node classes were not set correctly with the top node") + assert_equal({"base" => "true", "center" => "boo", "master" => "far"}, node.parameters, "node parameters were not set correctly with the top node") + end +end + +class LdapNodeTest < PuppetTest::TestCase + include NodeTesting + include PuppetTest::ServerTest + include PuppetTest::ParserTesting + include PuppetTest::ResourceTesting + AST = Puppet::Parser::AST + confine "LDAP is not available" => Puppet.features.ldap? + confine "No LDAP test data for networks other than Luke's" => Facter.value(:domain) == "madstop.com" + + def ldapconnect + + @ldap = LDAP::Conn.new("ldap", 389) + @ldap.set_option( LDAP::LDAP_OPT_PROTOCOL_VERSION, 3 ) + @ldap.simple_bind("", "") + + return @ldap + end + + def ldaphost(name) + node = NodeDef.new(:name => name) + parent = nil + found = false + @ldap.search( "ou=hosts, dc=madstop, dc=com", 2, + "(&(objectclass=puppetclient)(cn=%s))" % name + ) do |entry| + node.classes = entry.vals("puppetclass") || [] + node.parameters = entry.to_hash.inject({}) do |hash, ary| + if ary[1].length == 1 + hash[ary[0]] = ary[1].shift + else + hash[ary[0]] = ary[1] + end + hash + end + parent = node.parameters["parentnode"] + found = true + end + raise "Could not find node %s" % name unless found + + return node, parent + end + + def test_ldapsearch + Puppet[:ldapbase] = "ou=hosts, dc=madstop, dc=com" + Puppet[:ldapnodes] = true + + searcher = Object.new + searcher.extend(Node.node_source(:ldap)) + + ldapconnect() + + # Make sure we get nil and nil back when we search for something missing + parent, classes, parameters = nil + assert_nothing_raised do + parent, classes, parameters = searcher.ldapsearch("nosuchhost") + end + + assert_nil(parent, "Got a parent for a non-existent host") + assert_nil(classes, "Got classes for a non-existent host") + + # Make sure we can find 'culain' in ldap + assert_nothing_raised do + parent, classes, parameters = searcher.ldapsearch("culain") + end + + node, realparent = ldaphost("culain") + assert_equal(realparent, parent, "did not get correct parent node from ldap") + assert_equal(node.classes, classes, "did not get correct ldap classes from ldap") + assert_equal(node.parameters, parameters, "did not get correct ldap parameters from ldap") + + # Now compare when we specify the attributes to get. + Puppet[:ldapattrs] = "cn" + assert_nothing_raised do + parent, classes, parameters = searcher.ldapsearch("culain") + end + assert_equal(realparent, parent, "did not get correct parent node from ldap") + assert_equal(node.classes, classes, "did not get correct ldap classes from ldap") + + list = %w{cn puppetclass parentnode dn} + should = node.parameters.inject({}) { |h, a| h[a[0]] = a[1] if list.include?(a[0]); h } + assert_equal(should, parameters, "did not get correct ldap parameters from ldap") + end +end + +class LdapReconnectTests < PuppetTest::TestCase + include NodeTesting + include PuppetTest::ServerTest + include PuppetTest::ParserTesting + include PuppetTest::ResourceTesting + AST = Puppet::Parser::AST + confine "Not running on culain as root" => (Puppet::Util::SUIDManager.uid == 0 and Facter.value("hostname") == "culain") + + def test_ldapreconnect + Puppet[:ldapbase] = "ou=hosts, dc=madstop, dc=com" + Puppet[:ldapnodes] = true + + searcher = Object.new + searcher.extend(Node.node_source(:ldap)) + hostname = "culain.madstop.com" + + # look for our host + assert_nothing_raised { + parent, classes = searcher.nodesearch(hostname) + } + + # Now restart ldap + system("/etc/init.d/slapd restart 2>/dev/null >/dev/null") + sleep(1) + + # and look again + assert_nothing_raised { + parent, classes = searcher.nodesearch(hostname) + } + + # Now stop ldap + system("/etc/init.d/slapd stop 2>/dev/null >/dev/null") + cleanup do + system("/etc/init.d/slapd start 2>/dev/null >/dev/null") + end + + # And make sure we actually fail here + assert_raise(Puppet::Error) { + parent, classes = searcher.nodesearch(hostname) + } + end +end -- cgit From 90a9d09cd08ec072530e2f000e9f7b65f1c41095 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Tue, 14 Aug 2007 18:25:08 -0500 Subject: Finalizing the node handler. It now correctly uses the different node sources and knows how to retrieve data from those sources. Now I just need to fix the language stuff to use this handler instead of the existing node stuff. --- test/network/handler/node.rb | 330 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 324 insertions(+), 6 deletions(-) (limited to 'test/network/handler') diff --git a/test/network/handler/node.rb b/test/network/handler/node.rb index c682929d9..02da9eef0 100755 --- a/test/network/handler/node.rb +++ b/test/network/handler/node.rb @@ -43,31 +43,342 @@ module NodeTesting def mk_searcher(name) searcher = Object.new searcher.extend(Node.node_source(name)) + searcher.meta_def(:newnode) do |name, *args| + SimpleNode.new(name, *args) + end + searcher + end + + def mk_node_source + @node_info = {} + @node_source = Node.newnode_source(:testing, :fact_merge => true) do + def nodesearch(key) + if info = @node_info[key] + SimpleNode.new(info) + else + nil + end + end + end + Puppet[:node_source] = "testing" + + cleanup { Node.rm_node_source(:testing) } end end class TestNodeInterface < Test::Unit::TestCase + include NodeTesting + def setup super + mk_node_source + end + + # Make sure that the handler includes the appropriate + # node source. + def test_initialize + # First try it when passing in the node source + handler = nil + assert_nothing_raised("Could not specify a node source") do + handler = Node.new(:Source => :testing) + end + assert(handler.metaclass.included_modules.include?(@node_source), "Handler did not include node source") + + # Now use the Puppet[:node_source] + Puppet[:node_source] = "testing" + assert_nothing_raised("Could not specify a node source") do + handler = Node.new() + end + assert(handler.metaclass.included_modules.include?(@node_source), "Handler did not include node source") + + # And make sure we throw an exception when an invalid node source is used + assert_raise(ArgumentError, "Accepted an invalid node source") do + handler = Node.new(:Source => "invalid") + end end - def teardown + # Make sure we can find and we cache a fact handler. + def test_fact_handler + handler = Node.new + fhandler = nil + assert_nothing_raised("Could not retrieve the fact handler") do + fhandler = handler.send(:fact_handler) + end + assert_instance_of(Puppet::Network::Handler::Facts, fhandler, "Did not get a fact handler back") + + # Now call it again, making sure we're caching the value. + fhandler2 = nil + assert_nothing_raised("Could not retrieve the fact handler") do + fhandler2 = handler.send(:fact_handler) + end + assert_instance_of(Puppet::Network::Handler::Facts, fhandler2, "Did not get a fact handler on the second run") + assert_equal(fhandler.object_id, fhandler2.object_id, "Did not cache fact handler") end - def test_node - raise "Failing, yo" + # Make sure we can get node facts from the fact handler. + def test_node_facts + # Check the case where we find the node. + handler = Node.new + fhandler = handler.send(:fact_handler) + fhandler.expects(:get).with("present").returns("a" => "b") + + result = nil + assert_nothing_raised("Could not get facts from fact handler") do + result = handler.send(:node_facts, "present") + end + assert_equal({"a" => "b"}, result, "Did not get correct facts back") + + # Now try the case where the fact handler knows nothing about our host + fhandler.expects(:get).with('missing').returns(nil) + result = nil + assert_nothing_raised("Could not get facts from fact handler when host is missing") do + result = handler.send(:node_facts, "missing") + end + assert_equal({}, result, "Did not get empty hash when no facts are known") end + # Test our simple shorthand + def test_newnode + SimpleNode.expects(:new).with("stuff") + handler = Node.new + handler.newnode("stuff") + end + + # Make sure we can build up the correct node names to search for + def test_node_names + handler = Node.new + + # Verify that the handler asks for the facts if we don't pass them in + handler.expects(:node_facts).with("testing").returns({}) + handler.send(:node_names, "testing") + + handler = Node.new + # Test it first with no parameters + assert_equal(%w{testing}, handler.send(:node_names, "testing"), "Node names did not default to an array including just the node name") + + # Now test it with a fully qualified name + assert_equal(%w{testing.domain.com testing}, handler.send(:node_names, "testing.domain.com"), + "Fully qualified names did not get turned into multiple names, longest first") + + # And try it with a short name + domain fact + assert_equal(%w{testing host.domain.com host}, handler.send(:node_names, "testing", "domain" => "domain.com", "hostname" => "host"), + "The domain fact was not used to build up an fqdn") + + # And with an fqdn + assert_equal(%w{testing host.domain.com host}, handler.send(:node_names, "testing", "fqdn" => "host.domain.com"), + "The fqdn was not used") + + # And make sure the fqdn beats the domain + assert_equal(%w{testing host.other.com host}, handler.send(:node_names, "testing", "domain" => "domain.com", "fqdn" => "host.other.com"), + "The domain was used in preference to the fqdn") + end + + # Make sure we can retrieve a whole node by name. + def test_details_when_we_find_nodes + handler = Node.new + + # Make sure we get the facts first + handler.expects(:node_facts).with("host").returns(:facts) + + # Find the node names + handler.expects(:node_names).with("host", :facts).returns(%w{a b c}) + + # Iterate across them + handler.expects(:nodesearch).with("a").returns(nil) + handler.expects(:nodesearch).with("b").returns(nil) + + # Create an example node to return + node = SimpleNode.new("host") + + # Make sure its source is set + node.expects(:source=).with(handler.source) + + # And make sure we actually get it back + handler.expects(:nodesearch).with("c").returns(node) + + handler.expects(:fact_merge?).returns(true) + + # Make sure we merge the facts with the node's parameters. + node.expects(:fact_merge).with(:facts) + + # Now call the method + result = nil + assert_nothing_raised("could not call 'details'") do + result = handler.details("host") + end + assert_equal(node, result, "Did not get correct node back") + end + + # But make sure we pass through to creating default nodes when appropriate. + def test_details_using_default_node + handler = Node.new + + # Make sure we get the facts first + handler.expects(:node_facts).with("host").returns(:facts) + + # Find the node names + handler.expects(:node_names).with("host", :facts).returns([]) + + # Create an example node to return + node = SimpleNode.new("host") + + # Make sure its source is set + node.expects(:source=).with(handler.source) + + # And make sure we actually get it back + handler.expects(:nodesearch).with("default").returns(node) + + # This time, have it return false + handler.expects(:fact_merge?).returns(false) + + # And because fact_merge was false, we don't merge them. + node.expects(:fact_merge).never + + # Now call the method + result = nil + assert_nothing_raised("could not call 'details'") do + result = handler.details("host") + end + assert_equal(node, result, "Did not get correct node back") + end + + # Make sure our handler behaves rationally when it comes to getting environment data. def test_environment - raise "still failing" + # What happens when we can't find the node + handler = Node.new + handler.expects(:details).with("fake").returns(nil) + + result = nil + assert_nothing_raised("Could not call 'Node.environment'") do + result = handler.environment("fake") + end + assert_nil(result, "Got an environment for a node we could not find") + + # Now for nodes we can find + handler = Node.new + node = SimpleNode.new("fake") + handler.expects(:details).with("fake").returns(node) + node.expects(:environment).returns("dev") + + result = nil + assert_nothing_raised("Could not call 'Node.environment'") do + result = handler.environment("fake") + end + assert_equal("dev", result, "Did not get environment back") end + # Make sure our handler behaves rationally when it comes to getting parameter data. def test_parameters - raise "still failing" + # What happens when we can't find the node + handler = Node.new + handler.expects(:details).with("fake").returns(nil) + + result = nil + assert_nothing_raised("Could not call 'Node.parameters'") do + result = handler.parameters("fake") + end + assert_nil(result, "Got parameters for a node we could not find") + + # Now for nodes we can find + handler = Node.new + node = SimpleNode.new("fake") + handler.expects(:details).with("fake").returns(node) + node.expects(:parameters).returns({"a" => "b"}) + + result = nil + assert_nothing_raised("Could not call 'Node.parameters'") do + result = handler.parameters("fake") + end + assert_equal({"a" => "b"}, result, "Did not get parameters back") end def test_classes - raise "still failing" + # What happens when we can't find the node + handler = Node.new + handler.expects(:details).with("fake").returns(nil) + + result = nil + assert_nothing_raised("Could not call 'Node.classes'") do + result = handler.classes("fake") + end + assert_nil(result, "Got classes for a node we could not find") + + # Now for nodes we can find + handler = Node.new + node = SimpleNode.new("fake") + handler.expects(:details).with("fake").returns(node) + node.expects(:classes).returns(%w{yay foo}) + + result = nil + assert_nothing_raised("Could not call 'Node.classes'") do + result = handler.classes("fake") + end + assert_equal(%w{yay foo}, result, "Did not get classes back") + end +end + +class TestSimpleNode < Test::Unit::TestCase + include NodeTesting + + # Make sure we get all the defaults correctly. + def test_simplenode_initialize + node = nil + assert_nothing_raised("could not create a node without classes or parameters") do + node = SimpleNode.new("testing") + end + assert_equal("testing", node.name, "Did not set name correctly") + assert_equal({}, node.parameters, "Node parameters did not default correctly") + assert_equal([], node.classes, "Node classes did not default correctly") + + # Now test it with values for both + params = {"a" => "b"} + classes = %w{one two} + assert_nothing_raised("could not create a node with classes and parameters") do + node = SimpleNode.new("testing", :parameters => params, :classes => classes) + end + assert_equal("testing", node.name, "Did not set name correctly") + assert_equal(params, node.parameters, "Node parameters did not get set correctly") + assert_equal(classes, node.classes, "Node classes did not get set correctly") + + # And make sure a single class gets turned into an array + assert_nothing_raised("could not create a node with a class as a string") do + node = SimpleNode.new("testing", :classes => "test") + end + assert_equal(%w{test}, node.classes, "A node class string was not converted to an array") + + # Make sure we get environments + assert_nothing_raised("could not create a node with an environment") do + node = SimpleNode.new("testing", :environment => "test") + end + assert_equal("test", node.environment, "Environment was not set") + + # Now make sure we get the default env + Puppet[:environment] = "prod" + assert_nothing_raised("could not create a node with no environment") do + node = SimpleNode.new("testing") + end + assert_equal("prod", node.environment, "Did not get default environment") + + # But that it stays nil if there's no default env set + Puppet[:environment] = "" + assert_nothing_raised("could not create a node with no environment and no default env") do + node = SimpleNode.new("testing") + end + assert_nil(node.environment, "Got a default env when none was set") + + end + + # Verify that the node source wins over facter. + def test_fact_merge + node = SimpleNode.new("yay", :parameters => {"a" => "one", "b" => "two"}) + + assert_nothing_raised("Could not merge parameters") do + node.fact_merge("b" => "three", "c" => "yay") + end + params = node.parameters + assert_equal("one", params["a"], "Lost nodesource parameters in parameter merge") + assert_equal("two", params["b"], "Overrode nodesource parameters in parameter merge") + assert_equal("yay", params["c"], "Did not get facts in parameter merge") end end @@ -87,12 +398,16 @@ class TestNodeSources < Test::Unit::TestCase cleanup do Node.rm_node_source(:testing) + assert(! Node.const_defined?("Testing"), "Did not remove constant") end end def test_external_node_source + source = Node.node_source(:external) + assert(source, "Could not find external node source") mapper = mk_node_mapper searcher = mk_searcher(:external) + assert(searcher.fact_merge?, "External node source does not merge facts") # Make sure it gives the right response assert_equal({'classes' => %w{apple1 apple2 apple3}, :parameters => {"one" => "apple1", "two" => "apple2"}}, @@ -157,7 +472,10 @@ class TestNodeSources < Test::Unit::TestCase # This can stay in the main test suite because it doesn't actually use ldapsearch, # it just overrides the method so it behaves as though it were hitting ldap. def test_ldap_nodesearch + source = Node.node_source(:ldap) + assert(source, "Could not find ldap node source") searcher = mk_searcher(:ldap) + assert(searcher.fact_merge?, "LDAP node source does not merge facts") nodetable = {} -- cgit From 65559af75e3da6522f4c3e952a73d80e0040609c Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Wed, 15 Aug 2007 13:55:55 -0500 Subject: Adding a "none" node source, which will be the default node source and will just return an empty node. --- test/network/handler/node.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'test/network/handler') diff --git a/test/network/handler/node.rb b/test/network/handler/node.rb index 02da9eef0..37b63db69 100755 --- a/test/network/handler/node.rb +++ b/test/network/handler/node.rb @@ -529,6 +529,24 @@ class TestNodeSources < Test::Unit::TestCase assert_equal(%w{one two three four five}.sort, node.classes.sort, "node classes were not set correctly with the top node") assert_equal({"base" => "true", "center" => "boo", "master" => "far"}, node.parameters, "node parameters were not set correctly with the top node") end + + # Make sure we always get a node back from the 'none' nodesource. + def test_nodesource_none + source = Node.node_source(:none) + assert(source, "Could not find 'none' node source") + searcher = mk_searcher(:none) + assert(searcher.fact_merge?, "'none' node source does not merge facts") + + # Run a couple of node names through it + node = nil + %w{192.168.0.1 0:0:0:3:a:f host host.domain.com}.each do |name| + assert_nothing_raised("Could not create an empty node with name '%s'" % name) do + node = searcher.nodesearch(name) + end + assert_instance_of(SimpleNode, node, "Did not get a simple node back for %s" % name) + assert_equal(name, node.name, "Name was not set correctly") + end + end end class LdapNodeTest < PuppetTest::TestCase -- cgit From aabad8e1e262fb2f63fa4eef0f0e6fc00cc4b01f Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Wed, 15 Aug 2007 14:21:59 -0500 Subject: Adding the necessary name/ip fields to the node methods --- test/network/handler/node.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/network/handler') diff --git a/test/network/handler/node.rb b/test/network/handler/node.rb index 37b63db69..9fad3f765 100755 --- a/test/network/handler/node.rb +++ b/test/network/handler/node.rb @@ -141,7 +141,7 @@ class TestNodeInterface < Test::Unit::TestCase def test_newnode SimpleNode.expects(:new).with("stuff") handler = Node.new - handler.newnode("stuff") + handler.send(:newnode, "stuff") end # Make sure we can build up the correct node names to search for -- cgit From 70dffdde70b60ae9e84b6ab2889f6b50fe6bed70 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Wed, 15 Aug 2007 16:31:44 -0500 Subject: The new configuration handler looks to be ready for usage. Now I just need to convert the interpreter to use SimpleNode objects, then continue with the Configuration object. --- test/network/handler/configuration.rb | 167 ++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100755 test/network/handler/configuration.rb (limited to 'test/network/handler') diff --git a/test/network/handler/configuration.rb b/test/network/handler/configuration.rb new file mode 100755 index 000000000..7a505f5eb --- /dev/null +++ b/test/network/handler/configuration.rb @@ -0,0 +1,167 @@ +#!/usr/bin/env ruby + +$:.unshift("../../lib") if __FILE__ =~ /\.rb$/ + +require 'puppettest' +require 'puppet/network/handler/configuration' + +class TestHandlerConfiguration < Test::Unit::TestCase + include PuppetTest + + Config = Puppet::Network::Handler.handler(:configuration) + + # Check all of the setup stuff. + def test_initialize + config = nil + assert_nothing_raised("Could not create local config") do + config = Config.new(:Local => true) + end + + assert(config.local?, "Config is not considered local after being started that way") + end + + # Make sure we create the node handler when necessary. + def test_node_handler + config = Config.new + handler = nil + assert_nothing_raised("Could not create node handler") do + handler = config.send(:node_handler) + end + assert_instance_of(Puppet::Network::Handler.handler(:node), handler, "Did not create node handler") + + # Now make sure we get the same object back again + assert_equal(handler.object_id, config.send(:node_handler).object_id, "Did not cache node handler") + end + + # Test creation/returning of the interpreter + def test_interpreter + config = Config.new + + # First test the defaults + args = {} + config.instance_variable_set("@options", args) + config.expects(:create_interpreter).with(args).returns(:interp) + assert_equal(:interp, config.send(:interpreter), "Did not return the interpreter") + + # Now run it again and make sure we get the same thing + assert_equal(:interp, config.send(:interpreter), "Did not cache the interpreter") + end + + def test_create_interpreter + config = Config.new(:Local => false) + args = {} + + # Try it first with defaults. + Puppet::Parser::Interpreter.expects(:new).with(:Local => config.local?, :Manifest => Puppet[:manifest]).returns(:interp) + assert_equal(:interp, config.send(:create_interpreter, args), "Did not return the interpreter") + + # Now reset it and make sure a specified manifest passes through + file = tempfile + args[:Manifest] = file + Puppet::Parser::Interpreter.expects(:new).with(:Local => config.local?, :Manifest => file).returns(:interp) + assert_equal(:interp, config.send(:create_interpreter, args), "Did not return the interpreter") + + # And make sure the code does, too + args.delete(:Manifest) + args[:Code] = "yay" + Puppet::Parser::Interpreter.expects(:new).with(:Local => config.local?, :Code => "yay").returns(:interp) + assert_equal(:interp, config.send(:create_interpreter, args), "Did not return the interpreter") + end + + # Make sure node objects get appropriate data added to them. + def test_add_node_data + # First with no classes + config = Config.new + + fakenode = Object.new + # Set the server facts to something + config.instance_variable_set("@server_facts", :facts) + fakenode.expects(:fact_merge).with(:facts) + config.send(:add_node_data, fakenode) + + # Now try it with classes. + config.instance_variable_set("@options", {:Classes => %w{a b}}) + list = [] + fakenode = Object.new + fakenode.expects(:fact_merge).with(:facts) + fakenode.expects(:classes).returns(list).times(2) + config.send(:add_node_data, fakenode) + assert_equal(%w{a b}, list, "Did not add classes to node") + end + + def test_compile + config = Config.new + + # First do a local + node = Object.new + node.expects(:name).returns(:mynode) + + interp = Object.new + interp.expects(:compile).with(node).returns(:config) + config.expects(:interpreter).returns(interp) + + Puppet.expects(:notice) # The log message from benchmarking + + assert_equal(:config, config.send(:compile, node), "Did not return config") + + # Now try it non-local + config = Config.new(:Local => true) + + node = Object.new + node.expects(:name).returns(:mynode) + + interp = Object.new + interp.expects(:compile).with(node).returns(:config) + config.expects(:interpreter).returns(interp) + + assert_equal(:config, config.send(:compile, node), "Did not return config") + end + + def test_set_server_facts + config = Config.new + assert_nothing_raised("Could not call :set_server_facts") do + config.send(:set_server_facts) + end + facts = config.instance_variable_get("@server_facts") + %w{servername serverversion serverip}.each do |fact| + assert(facts.include?(fact), "Config did not set %s fact" % fact) + end + end + + def test_translate + # First do a local config + config = Config.new(:Local => true) + assert_equal(:plain, config.send(:translate, :plain), "Attempted to translate local config") + + # Now a non-local + config = Config.new(:Local => false) + obj = Object.new + yamld = Object.new + obj.expects(:to_yaml).with(:UseBlock => true).returns(yamld) + CGI.expects(:escape).with(yamld).returns(:translated) + assert_equal(:translated, config.send(:translate, obj), "Did not return translated config") + end + + # Check that we're storing the node freshness into the rails db. Hackilicious. + def test_update_node_freshness + # This is stupid. + config = Config.new + node = Object.new + node.expects(:name).returns(:hostname) + now = Object.new + Time.expects(:now).returns(now) + host = Object.new + host.expects(:last_freshcheck=).with(now) + host.expects(:save) + + # Only test the case where rails is there + Puppet[:storeconfigs] = true + Puppet.features.expects(:rails?).returns(true) + Puppet::Rails.expects(:connect) + Puppet::Rails::Host.expects(:find_or_create_by_name).with(:hostname).returns(host) + + config.send(:update_node_freshness, node) + + + end +end -- cgit From 297dabb63744f8ad468ee4bf5caa54a75754ceee Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Wed, 15 Aug 2007 16:56:05 -0500 Subject: Refactoring a small part of the interface between the configuration handler and the interpreter. --- test/network/handler/configuration.rb | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'test/network/handler') diff --git a/test/network/handler/configuration.rb b/test/network/handler/configuration.rb index 7a505f5eb..525db5e6a 100755 --- a/test/network/handler/configuration.rb +++ b/test/network/handler/configuration.rb @@ -143,7 +143,7 @@ class TestHandlerConfiguration < Test::Unit::TestCase end # Check that we're storing the node freshness into the rails db. Hackilicious. - def test_update_node_freshness + def test_update_node_check # This is stupid. config = Config.new node = Object.new @@ -160,8 +160,30 @@ class TestHandlerConfiguration < Test::Unit::TestCase Puppet::Rails.expects(:connect) Puppet::Rails::Host.expects(:find_or_create_by_name).with(:hostname).returns(host) - config.send(:update_node_freshness, node) + config.send(:update_node_check, node) + end + def test_version + # First try the case where we can't look up the node + config = Config.new + handler = Object.new + handler.expects(:details).with(:client).returns(false) + config.expects(:node_handler).returns(handler) + interp = Object.new + interp.expects(:configuration_version).returns(:version) + config.expects(:interpreter).returns(interp) + assert_equal(:version, config.version(:client), "Did not return configuration version") + # And then when we find the node. + config = Config.new + node = Object.new + handler = Object.new + handler.expects(:details).with(:client).returns(node) + config.expects(:update_node_check).with(node) + config.expects(:node_handler).returns(handler) + interp = Object.new + interp.expects(:configuration_version).returns(:version) + config.expects(:interpreter).returns(interp) + assert_equal(:version, config.version(:client), "Did not return configuration version") end end -- cgit From a9539548d957304a03aa8bdc61c06793228f57c0 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Wed, 15 Aug 2007 17:05:49 -0500 Subject: Keeping the node names in the node object, so that they are available to the interpreter --- test/network/handler/node.rb | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/network/handler') diff --git a/test/network/handler/node.rb b/test/network/handler/node.rb index 9fad3f765..9902c2dd1 100755 --- a/test/network/handler/node.rb +++ b/test/network/handler/node.rb @@ -193,6 +193,9 @@ class TestNodeInterface < Test::Unit::TestCase # Make sure its source is set node.expects(:source=).with(handler.source) + # And that the names are retained + node.expects(:names=).with(%w{a b c}) + # And make sure we actually get it back handler.expects(:nodesearch).with("c").returns(node) -- cgit From 1527f4a615f9c429e90becd90f9ed1e8c1e83249 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Wed, 15 Aug 2007 17:18:43 -0500 Subject: Adding node caching, so that node sources are not spammed during file serving and such --- test/network/handler/node.rb | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'test/network/handler') diff --git a/test/network/handler/node.rb b/test/network/handler/node.rb index 9902c2dd1..745c7470e 100755 --- a/test/network/handler/node.rb +++ b/test/network/handler/node.rb @@ -66,7 +66,7 @@ module NodeTesting end end -class TestNodeInterface < Test::Unit::TestCase +class TestNodeHandler < Test::Unit::TestCase include NodeTesting def setup @@ -318,6 +318,28 @@ class TestNodeInterface < Test::Unit::TestCase end assert_equal(%w{yay foo}, result, "Did not get classes back") end + + # We reuse the filetimeout for the node caching timeout. + def test_node_caching + handler = Node.new + + node = Object.new + node.metaclass.instance_eval do + attr_accessor :time, :name + end + node.time = Time.now + node.name = "yay" + + # Make sure caching works normally + assert_nothing_raised("Could not cache node") do + handler.send(:cache, node) + end + assert_equal(node.object_id, handler.send(:cached?, "yay").object_id, "Did not get node back from the cache") + + # Now set the node's time to be a long time ago + node.time = Time.now - 50000 + assert(! handler.send(:cached?, "yay"), "Timed-out node was returned from cache") + end end class TestSimpleNode < Test::Unit::TestCase @@ -332,6 +354,7 @@ class TestSimpleNode < Test::Unit::TestCase assert_equal("testing", node.name, "Did not set name correctly") assert_equal({}, node.parameters, "Node parameters did not default correctly") assert_equal([], node.classes, "Node classes did not default correctly") + assert_instance_of(Time, node.time, "Did not set the creation time") # Now test it with values for both params = {"a" => "b"} -- cgit From 6467c21e15b8a28e627d1395f76fe8f42ee77d70 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Mon, 20 Aug 2007 13:28:40 -0500 Subject: The first pass where at least all of the snippet tests pass. I have unfortunately had to stop being so assiduous in my rewriting of tests, but I am in too much of a time crunch to do this "right". The basic structure is definitely in place, though, and from here it is a question of making the rest of the tests work and hopefully writing some sufficient new tests, rather than making the code itself work. --- test/network/handler/master.rb | 74 ------------------------------------------ 1 file changed, 74 deletions(-) (limited to 'test/network/handler') diff --git a/test/network/handler/master.rb b/test/network/handler/master.rb index 08e17373b..9cf52b1cd 100755 --- a/test/network/handler/master.rb +++ b/test/network/handler/master.rb @@ -8,56 +8,6 @@ require 'puppet/network/handler/master' class TestMaster < Test::Unit::TestCase include PuppetTest::ServerTest - # run through all of the existing test files and make sure everything - # works - def test_files - count = 0 - textfiles { |file| - Puppet.debug("parsing %s" % file) - client = nil - master = nil - - # create our master - assert_nothing_raised() { - # this is the default server setup - master = Puppet::Network::Handler.master.new( - :Manifest => file, - :UseNodes => false, - :Local => true - ) - } - - # and our client - assert_nothing_raised() { - client = Puppet::Network::Client.master.new( - :Master => master - ) - } - - # pull our configuration a few times - assert_nothing_raised() { - client.getconfig - stopservices - Puppet::Type.allclear - } - assert_nothing_raised() { - client.getconfig - stopservices - Puppet::Type.allclear - } - assert_nothing_raised() { - client.getconfig - stopservices - Puppet::Type.allclear - } - # only test three files; that's plenty - if count > 3 - break - end - count += 1 - } - end - def test_defaultmanifest textfiles { |file| Puppet[:manifest] = file @@ -166,30 +116,6 @@ class TestMaster < Test::Unit::TestCase assert(FileTest.exists?(file2), "Second file %s does not exist" % file2) end - def test_addfacts - master = nil - file = mktestmanifest() - # create our master - assert_nothing_raised() { - # this is the default server setup - master = Puppet::Network::Handler.master.new( - :Manifest => file, - :UseNodes => false, - :Local => true - ) - } - - facts = {} - - assert_nothing_raised { - master.addfacts(facts) - } - - %w{serverversion servername serverip}.each do |fact| - assert(facts.include?(fact), "Fact %s was not set" % fact) - end - end - # Make sure we're using the hostname as configured with :node_name def test_hostname_in_getconfig master = nil -- cgit From 4eb87ed7c8829a6fbc558595be9149e9b3cf5b36 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Mon, 20 Aug 2007 22:25:00 -0500 Subject: A round of bugfixing. Many more tests now pass -- I think we are largely down to tests that (yay!) fail in trunk. --- test/network/handler/configuration.rb | 4 +- test/network/handler/master.rb | 129 +++++++--------------------------- 2 files changed, 29 insertions(+), 104 deletions(-) (limited to 'test/network/handler') diff --git a/test/network/handler/configuration.rb b/test/network/handler/configuration.rb index 525db5e6a..98c3bdcde 100755 --- a/test/network/handler/configuration.rb +++ b/test/network/handler/configuration.rb @@ -170,7 +170,7 @@ class TestHandlerConfiguration < Test::Unit::TestCase handler.expects(:details).with(:client).returns(false) config.expects(:node_handler).returns(handler) interp = Object.new - interp.expects(:configuration_version).returns(:version) + interp.expects(:parsedate).returns(:version) config.expects(:interpreter).returns(interp) assert_equal(:version, config.version(:client), "Did not return configuration version") @@ -182,7 +182,7 @@ class TestHandlerConfiguration < Test::Unit::TestCase config.expects(:update_node_check).with(node) config.expects(:node_handler).returns(handler) interp = Object.new - interp.expects(:configuration_version).returns(:version) + interp.expects(:parsedate).returns(:version) config.expects(:interpreter).returns(interp) assert_equal(:version, config.version(:client), "Did not return configuration version") end diff --git a/test/network/handler/master.rb b/test/network/handler/master.rb index 9cf52b1cd..5ac8cbbbc 100755 --- a/test/network/handler/master.rb +++ b/test/network/handler/master.rb @@ -116,114 +116,39 @@ class TestMaster < Test::Unit::TestCase assert(FileTest.exists?(file2), "Second file %s does not exist" % file2) end - # Make sure we're using the hostname as configured with :node_name - def test_hostname_in_getconfig - master = nil - file = tempfile() - #@createdfile = File.join(tmpdir(), self.class.to_s + "manifesttesting" + - # "_" + @method_name) - file_cert = tempfile() - file_fact = tempfile() - - certname = "y4yn3ss" - factname = Facter.value("hostname") - - File.open(file, "w") { |f| - f.puts %{ - node #{certname} { file { "#{file_cert}": ensure => file, mode => 755 } } - node #{factname} { file { "#{file_fact}": ensure => file, mode => 755 } } -} - } - # create our master - assert_nothing_raised() { - # this is the default server setup - master = Puppet::Network::Handler.master.new( - :Manifest => file, - :UseNodes => true, - :Local => true - ) - } - - result = nil - - # Use the hostname from facter - Puppet[:node_name] = 'facter' - assert_nothing_raised { - result = master.getconfig({"hostname" => factname}, "yaml", certname, "127.0.0.1") - } - - result = result.flatten - - assert(result.find { |obj| obj.name == file_fact }, - "Could not find correct file") - assert(!result.find { |obj| obj.name == file_cert }, - "Found incorrect file") - - # Use the hostname from the cert - Puppet[:node_name] = 'cert' - assert_nothing_raised { - result = master.getconfig({"hostname" => factname}, "yaml", certname, "127.0.0.1") - } - - result = result.flatten - - assert(!result.find { |obj| obj.name == file_fact }, - "Could not find correct file") - assert(result.find { |obj| obj.name == file_cert }, - "Found incorrect file") - end - # Make sure we're correctly doing clientname manipulations. # Testing to make sure we always get a hostname and IP address. def test_clientname - master = nil - file = tempfile() - - File.open(file, "w") { |f| - f.puts %{ - node yay { file { "/something": ensure => file, mode => 755 } } -} - } # create our master - assert_nothing_raised() { - # this is the default server setup - master = Puppet::Network::Handler.master.new( - :Manifest => file, - :UseNodes => true, - :Local => true - ) - } + master = Puppet::Network::Handler.master.new( + :Manifest => tempfile, + :UseNodes => true, + :Local => true + ) + + # First check that 'cert' works Puppet[:node_name] = "cert" - # First act like we're local - fakename = nil - fakeip = nil - - name = ip = nil - facts = Facter.to_hash - assert_nothing_raised do - name, ip = master.clientname(fakename, fakeip, facts) - end - - assert(facts["hostname"], "Removed hostname fact") - assert(facts["ipaddress"], "Removed ipaddress fact") - - assert_equal(facts["hostname"], name) - assert_equal(facts["ipaddress"], ip) - - # Now set them to something real, and make sure we get them back - fakename = "yayness" - fakeip = "192.168.0.1" - facts = Facter.to_hash - assert_nothing_raised do - name, ip = master.clientname(fakename, fakeip, facts) - end - - assert(facts["hostname"], "Removed hostname fact") - assert(facts["ipaddress"], "Removed ipaddress fact") - - assert_equal(fakename, name) - assert_equal(fakeip, ip) + + # Make sure we get the fact data back when nothing is set + facts = {"hostname" => "fact_hostname", "ipaddress" => "fact_ip"} + certname = "cert_hostname" + certip = "cert_ip" + + resname, resip = master.send(:clientname, nil, nil, facts) + assert_equal(facts["hostname"], resname, "Did not use fact hostname when no certname was present") + assert_equal(facts["ipaddress"], resip, "Did not use fact ip when no certname was present") + + # Now try it with the cert stuff present + resname, resip = master.send(:clientname, certname, certip, facts) + assert_equal(certname, resname, "Did not use cert hostname when certname was present") + assert_equal(certip, resip, "Did not use cert ip when certname was present") + + # And reset the node_name stuff and make sure we use it. + Puppet[:node_name] = :facter + resname, resip = master.send(:clientname, certname, certip, facts) + assert_equal(facts["hostname"], resname, "Did not use fact hostname when nodename was set to facter") + assert_equal(facts["ipaddress"], resip, "Did not use fact ip when nodename was set to facter") end end -- cgit From f1727f18ab933df9ecbecc2da8fad72eb441e0d5 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Wed, 22 Aug 2007 16:14:39 -0500 Subject: Adding the topscope metadata to the configuration being returned to the client, just like it expects, and fixing how the resource handler calls the master type. --- test/network/handler/resource.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/network/handler') diff --git a/test/network/handler/resource.rb b/test/network/handler/resource.rb index 589d22d83..18f52dbd6 100755 --- a/test/network/handler/resource.rb +++ b/test/network/handler/resource.rb @@ -236,7 +236,7 @@ class TestResourceServer < Test::Unit::TestCase def test_apply server = nil assert_nothing_raised do - server = Puppet::Network::Handler.resource.new() + server = Puppet::Network::Handler.resource.new(:Local => false) end file = tempfile() -- cgit From 8b3361afae35cfb65754d7bd9aff5b820ed714f0 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Wed, 22 Aug 2007 17:57:28 -0500 Subject: The last commits before I actually start on the multi-environment support. There are still failing tests, but apparently only those that are also failing in trunk. --- test/network/handler/node.rb | 68 +------------------------------------------- 1 file changed, 1 insertion(+), 67 deletions(-) (limited to 'test/network/handler') diff --git a/test/network/handler/node.rb b/test/network/handler/node.rb index 745c7470e..d5c98fec6 100755 --- a/test/network/handler/node.rb +++ b/test/network/handler/node.rb @@ -12,7 +12,7 @@ require 'puppet/network/handler/node' module NodeTesting include PuppetTest Node = Puppet::Network::Handler::Node - SimpleNode = Puppet::Network::Handler::Node::SimpleNode + SimpleNode = Puppet::Node def mk_node_mapper # First, make sure our nodesearch command works as we expect @@ -342,72 +342,6 @@ class TestNodeHandler < Test::Unit::TestCase end end -class TestSimpleNode < Test::Unit::TestCase - include NodeTesting - - # Make sure we get all the defaults correctly. - def test_simplenode_initialize - node = nil - assert_nothing_raised("could not create a node without classes or parameters") do - node = SimpleNode.new("testing") - end - assert_equal("testing", node.name, "Did not set name correctly") - assert_equal({}, node.parameters, "Node parameters did not default correctly") - assert_equal([], node.classes, "Node classes did not default correctly") - assert_instance_of(Time, node.time, "Did not set the creation time") - - # Now test it with values for both - params = {"a" => "b"} - classes = %w{one two} - assert_nothing_raised("could not create a node with classes and parameters") do - node = SimpleNode.new("testing", :parameters => params, :classes => classes) - end - assert_equal("testing", node.name, "Did not set name correctly") - assert_equal(params, node.parameters, "Node parameters did not get set correctly") - assert_equal(classes, node.classes, "Node classes did not get set correctly") - - # And make sure a single class gets turned into an array - assert_nothing_raised("could not create a node with a class as a string") do - node = SimpleNode.new("testing", :classes => "test") - end - assert_equal(%w{test}, node.classes, "A node class string was not converted to an array") - - # Make sure we get environments - assert_nothing_raised("could not create a node with an environment") do - node = SimpleNode.new("testing", :environment => "test") - end - assert_equal("test", node.environment, "Environment was not set") - - # Now make sure we get the default env - Puppet[:environment] = "prod" - assert_nothing_raised("could not create a node with no environment") do - node = SimpleNode.new("testing") - end - assert_equal("prod", node.environment, "Did not get default environment") - - # But that it stays nil if there's no default env set - Puppet[:environment] = "" - assert_nothing_raised("could not create a node with no environment and no default env") do - node = SimpleNode.new("testing") - end - assert_nil(node.environment, "Got a default env when none was set") - - end - - # Verify that the node source wins over facter. - def test_fact_merge - node = SimpleNode.new("yay", :parameters => {"a" => "one", "b" => "two"}) - - assert_nothing_raised("Could not merge parameters") do - node.fact_merge("b" => "three", "c" => "yay") - end - params = node.parameters - assert_equal("one", params["a"], "Lost nodesource parameters in parameter merge") - assert_equal("two", params["b"], "Overrode nodesource parameters in parameter merge") - assert_equal("yay", params["c"], "Did not get facts in parameter merge") - end -end - # Test our configuration object. class TestNodeSources < Test::Unit::TestCase include NodeTesting -- cgit