mcollective-client 1.3.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of mcollective-client might be problematic. Click here for more details.
- data/bin/mc-call-agent +54 -0
- data/bin/mco +27 -0
- data/lib/mcollective.rb +70 -0
- data/lib/mcollective/agents.rb +160 -0
- data/lib/mcollective/application.rb +354 -0
- data/lib/mcollective/applications.rb +145 -0
- data/lib/mcollective/client.rb +292 -0
- data/lib/mcollective/config.rb +202 -0
- data/lib/mcollective/connector.rb +18 -0
- data/lib/mcollective/connector/base.rb +24 -0
- data/lib/mcollective/facts.rb +39 -0
- data/lib/mcollective/facts/base.rb +86 -0
- data/lib/mcollective/log.rb +103 -0
- data/lib/mcollective/logger.rb +5 -0
- data/lib/mcollective/logger/base.rb +73 -0
- data/lib/mcollective/logger/console_logger.rb +61 -0
- data/lib/mcollective/logger/file_logger.rb +46 -0
- data/lib/mcollective/logger/syslog_logger.rb +53 -0
- data/lib/mcollective/matcher.rb +16 -0
- data/lib/mcollective/matcher/parser.rb +93 -0
- data/lib/mcollective/matcher/scanner.rb +123 -0
- data/lib/mcollective/message.rb +201 -0
- data/lib/mcollective/monkey_patches.rb +104 -0
- data/lib/mcollective/optionparser.rb +164 -0
- data/lib/mcollective/pluginmanager.rb +180 -0
- data/lib/mcollective/pluginpackager.rb +26 -0
- data/lib/mcollective/pluginpackager/agent_definition.rb +79 -0
- data/lib/mcollective/pluginpackager/standard_definition.rb +59 -0
- data/lib/mcollective/registration.rb +16 -0
- data/lib/mcollective/registration/base.rb +75 -0
- data/lib/mcollective/rpc.rb +188 -0
- data/lib/mcollective/rpc/actionrunner.rb +142 -0
- data/lib/mcollective/rpc/agent.rb +441 -0
- data/lib/mcollective/rpc/audit.rb +38 -0
- data/lib/mcollective/rpc/client.rb +793 -0
- data/lib/mcollective/rpc/ddl.rb +258 -0
- data/lib/mcollective/rpc/helpers.rb +339 -0
- data/lib/mcollective/rpc/progress.rb +63 -0
- data/lib/mcollective/rpc/reply.rb +61 -0
- data/lib/mcollective/rpc/request.rb +51 -0
- data/lib/mcollective/rpc/result.rb +41 -0
- data/lib/mcollective/rpc/stats.rb +185 -0
- data/lib/mcollective/runnerstats.rb +90 -0
- data/lib/mcollective/security.rb +26 -0
- data/lib/mcollective/security/base.rb +237 -0
- data/lib/mcollective/shell.rb +87 -0
- data/lib/mcollective/ssl.rb +246 -0
- data/lib/mcollective/unix_daemon.rb +37 -0
- data/lib/mcollective/util.rb +274 -0
- data/lib/mcollective/vendor.rb +41 -0
- data/lib/mcollective/vendor/require_vendored.rb +2 -0
- data/lib/mcollective/windows_daemon.rb +25 -0
- data/spec/Rakefile +16 -0
- data/spec/fixtures/application/test.rb +7 -0
- data/spec/fixtures/test-cert.pem +15 -0
- data/spec/fixtures/test-private.pem +15 -0
- data/spec/fixtures/test-public.pem +6 -0
- data/spec/monkey_patches/instance_variable_defined.rb +7 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/unit/agents_spec.rb +280 -0
- data/spec/unit/application_spec.rb +636 -0
- data/spec/unit/applications_spec.rb +155 -0
- data/spec/unit/array.rb +30 -0
- data/spec/unit/config_spec.rb +148 -0
- data/spec/unit/facts/base_spec.rb +118 -0
- data/spec/unit/facts_spec.rb +39 -0
- data/spec/unit/log_spec.rb +71 -0
- data/spec/unit/logger/base_spec.rb +110 -0
- data/spec/unit/logger/syslog_logger_spec.rb +86 -0
- data/spec/unit/matcher/parser_spec.rb +106 -0
- data/spec/unit/matcher/scanner_spec.rb +71 -0
- data/spec/unit/message_spec.rb +401 -0
- data/spec/unit/optionparser_spec.rb +113 -0
- data/spec/unit/pluginmanager_spec.rb +173 -0
- data/spec/unit/pluginpackager/agent_definition_spec.rb +130 -0
- data/spec/unit/pluginpackager/standard_definition_spec.rb +75 -0
- data/spec/unit/plugins/mcollective/connector/activemq_spec.rb +533 -0
- data/spec/unit/plugins/mcollective/connector/stomp/eventlogger_spec.rb +34 -0
- data/spec/unit/plugins/mcollective/connector/stomp_spec.rb +417 -0
- data/spec/unit/plugins/mcollective/packagers/ospackage_spec.rb +229 -0
- data/spec/unit/plugins/mcollective/security/psk_spec.rb +156 -0
- data/spec/unit/registration/base_spec.rb +77 -0
- data/spec/unit/rpc/actionrunner_spec.rb +213 -0
- data/spec/unit/rpc/agent_spec.rb +155 -0
- data/spec/unit/rpc/client_spec.rb +523 -0
- data/spec/unit/rpc/ddl_spec.rb +388 -0
- data/spec/unit/rpc/helpers_spec.rb +55 -0
- data/spec/unit/rpc/reply_spec.rb +143 -0
- data/spec/unit/rpc/request_spec.rb +115 -0
- data/spec/unit/rpc/result_spec.rb +66 -0
- data/spec/unit/rpc/stats_spec.rb +288 -0
- data/spec/unit/runnerstats_spec.rb +40 -0
- data/spec/unit/security/base_spec.rb +279 -0
- data/spec/unit/shell_spec.rb +144 -0
- data/spec/unit/ssl_spec.rb +244 -0
- data/spec/unit/symbol.rb +11 -0
- data/spec/unit/unix_daemon.rb +41 -0
- data/spec/unit/util_spec.rb +342 -0
- data/spec/unit/vendor_spec.rb +34 -0
- data/spec/unit/windows_daemon.rb +43 -0
- data/spec/windows_spec.opts +1 -0
- metadata +242 -0
@@ -0,0 +1,155 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
module MCollective
|
6
|
+
describe Applications do
|
7
|
+
before do
|
8
|
+
tmpfile = Tempfile.new("mc_applications_spec")
|
9
|
+
path = tmpfile.path
|
10
|
+
tmpfile.close!
|
11
|
+
|
12
|
+
@tmpdir = FileUtils.mkdir_p(path)
|
13
|
+
@tmpdir = @tmpdir[0] if @tmpdir.is_a?(Array) # ruby 1.9.2
|
14
|
+
$LOAD_PATH << @tmpdir
|
15
|
+
|
16
|
+
@appsdir = File.join([@tmpdir, "mcollective", "application"])
|
17
|
+
FileUtils.mkdir_p(@appsdir)
|
18
|
+
|
19
|
+
FileUtils.cp(File.join([File.dirname(__FILE__), "..", "fixtures", "application", "test.rb"]), @appsdir)
|
20
|
+
end
|
21
|
+
|
22
|
+
after do
|
23
|
+
FileUtils.rm_r(@tmpdir)
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "[]" do
|
27
|
+
it "should load the config" do
|
28
|
+
Applications.expects(:load_config).once
|
29
|
+
PluginManager.expects("[]").once
|
30
|
+
Applications["test"]
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should return the correct stored application" do
|
34
|
+
app = mock("app")
|
35
|
+
app.stubs(:run)
|
36
|
+
|
37
|
+
Applications.expects(:load_config).once
|
38
|
+
PluginManager.expects("[]").with("test_application").once.returns(app)
|
39
|
+
Applications["test"].should == app
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#run" do
|
44
|
+
it "should load the configuration" do
|
45
|
+
app = mock("app")
|
46
|
+
app.stubs(:run)
|
47
|
+
|
48
|
+
Applications.expects(:load_config).once
|
49
|
+
Applications.expects(:load_application).once
|
50
|
+
PluginManager.expects("[]").once.returns(app)
|
51
|
+
|
52
|
+
Applications.run("test")
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should load the application" do
|
56
|
+
app = mock("app")
|
57
|
+
app.stubs(:run)
|
58
|
+
|
59
|
+
Applications.expects(:load_config).once
|
60
|
+
Applications.expects(:load_application).with("test").once
|
61
|
+
PluginManager.expects("[]").once.returns(app)
|
62
|
+
|
63
|
+
Applications.run("test")
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should invoke the application run method" do
|
67
|
+
app = mock("app")
|
68
|
+
app.stubs(:run).returns("hello world")
|
69
|
+
|
70
|
+
Applications.expects(:load_config).once
|
71
|
+
Applications.expects(:load_application)
|
72
|
+
PluginManager.expects("[]").once.returns(app)
|
73
|
+
|
74
|
+
Applications.run("test").should == "hello world"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "#load_application" do
|
79
|
+
it "should return the existing application if already loaded" do
|
80
|
+
app = mock("app")
|
81
|
+
app.stubs(:run)
|
82
|
+
|
83
|
+
PluginManager << {:type => "test_application", :class => app}
|
84
|
+
|
85
|
+
Applications.expects("load_config").never
|
86
|
+
|
87
|
+
Applications.load_application("test")
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should load the config" do
|
91
|
+
Applications.expects("load_config").returns(true).once
|
92
|
+
Applications.load_application("test")
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should load the correct class from disk" do
|
96
|
+
PluginManager.expects("loadclass").with("MCollective::Application::Test")
|
97
|
+
Applications.expects("load_config").returns(true).once
|
98
|
+
|
99
|
+
Applications.load_application("test")
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should add the class to the plugin manager" do
|
103
|
+
Applications.expects("load_config").returns(true).once
|
104
|
+
|
105
|
+
PluginManager.expects("<<").with({:type => "test_application", :class => "MCollective::Application::Test"})
|
106
|
+
|
107
|
+
Applications.load_application("test")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "#list" do
|
112
|
+
it "should load the configuration" do
|
113
|
+
Applications.expects("load_config").returns(true).once
|
114
|
+
Config.any_instance.expects("libdir").returns([@tmpdir])
|
115
|
+
Applications.list
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should add found applications to the list" do
|
119
|
+
Applications.expects("load_config").returns(true).once
|
120
|
+
Config.any_instance.expects("libdir").returns([@tmpdir])
|
121
|
+
|
122
|
+
Applications.list.should == ["test"]
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should print a friendly error and exit on failure" do
|
126
|
+
Applications.expects("load_config").raises(Exception)
|
127
|
+
IO.any_instance.expects(:puts).with(regexp_matches(/Failed to generate application list/)).once
|
128
|
+
|
129
|
+
expect {
|
130
|
+
Applications.list.should
|
131
|
+
}.to raise_error(SystemExit)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "#filter_extra_options" do
|
136
|
+
it "should parse --config=x" do
|
137
|
+
["--config=x --foo=bar -f -f bar", "--foo=bar --config=x -f -f bar"].each do |t|
|
138
|
+
Applications.filter_extra_options(t).should == "--config=x"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should parse --config x" do
|
143
|
+
["--config x --foo=bar -f -f bar", "--foo=bar --config x -f -f bar"].each do |t|
|
144
|
+
Applications.filter_extra_options(t).should == "--config=x"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should parse -c x" do
|
149
|
+
["-c x --foo=bar -f -f bar", "--foo=bar -c x -f -f bar"].each do |t|
|
150
|
+
Applications.filter_extra_options(t).should == "--config=x"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
data/spec/unit/array.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
class Array
|
6
|
+
describe "#in_groups_of" do
|
7
|
+
it "should correctly group array members" do
|
8
|
+
[1,2,3,4,5,6,7,8,9,10].in_groups_of(5).should == [[1,2,3,4,5], [6,7,8,9,10]]
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should padd missing data with correctly" do
|
12
|
+
arr = [1,2,3,4,5,6,7,8,9,10]
|
13
|
+
|
14
|
+
arr.in_groups_of(3).should == [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, nil, nil]]
|
15
|
+
arr.in_groups_of(3, 0).should == [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 0, 0]]
|
16
|
+
arr.in_groups_of(11).should == [[1,2,3,4,5, 6,7,8,9,10, nil]]
|
17
|
+
arr.in_groups_of(11, 0).should == [[1,2,3,4,5, 6,7,8,9,10, 0]]
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should indicate when the last abtched was reached" do
|
21
|
+
arr = [1,2,3,4,5,6,7,8,9,10]
|
22
|
+
|
23
|
+
ctr = 0
|
24
|
+
|
25
|
+
[1,2,3,4,5,6,7,8,9,10].in_groups_of(3) {|a, last_batch| ctr += 1 unless last_batch}
|
26
|
+
|
27
|
+
ctr.should == 3
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
module MCollective
|
6
|
+
describe Config do
|
7
|
+
describe "#loadconfig" do
|
8
|
+
it "should not allow any path like construct for identities" do
|
9
|
+
# Taken from puppet test cases
|
10
|
+
['../foo', '..\\foo', './../foo', '.\\..\\foo',
|
11
|
+
'/foo', '//foo', '\\foo', '\\\\goo',
|
12
|
+
"test\0/../bar", "test\0\\..\\bar",
|
13
|
+
"..\\/bar", "/tmp/bar", "/tmp\\bar", "tmp\\bar",
|
14
|
+
" / bar", " /../ bar", " \\..\\ bar",
|
15
|
+
"c:\\foo", "c:/foo", "\\\\?\\UNC\\bar", "\\\\foo\\bar",
|
16
|
+
"\\\\?\\c:\\foo", "//?/UNC/bar", "//foo/bar",
|
17
|
+
"//?/c:/foo"
|
18
|
+
].each do |input|
|
19
|
+
File.expects(:open).with("/nonexisting", "r").returns(StringIO.new("identity = #{input}"))
|
20
|
+
File.expects(:exists?).with("/nonexisting").returns(true)
|
21
|
+
File.expects(:exists?).with(File.join(File.dirname("/nonexisting"), "rpc-help.erb")).returns(true)
|
22
|
+
|
23
|
+
expect {
|
24
|
+
Config.instance.loadconfig("/nonexisting")
|
25
|
+
}.to raise_error('Identities can only match /\w\.\-/')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should allow valid identities" do
|
30
|
+
["foo", "foo_bar", "foo-bar", "foo-bar-123", "foo.bar", "foo_bar_123"].each do |input|
|
31
|
+
File.expects(:open).with("/nonexisting", "r").returns(StringIO.new("identity = #{input}"))
|
32
|
+
File.expects(:exists?).with("/nonexisting").returns(true)
|
33
|
+
File.expects(:exists?).with(File.join(File.dirname("/nonexisting"), "rpc-help.erb")).returns(true)
|
34
|
+
PluginManager.stubs(:loadclass)
|
35
|
+
PluginManager.stubs("<<")
|
36
|
+
|
37
|
+
Config.instance.loadconfig("/nonexisting")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should not allow the syslog logger type on windows" do
|
42
|
+
Util.expects("windows?").returns(true).twice
|
43
|
+
File.expects(:open).with("/nonexisting", "r").returns(StringIO.new("logger_type = syslog"))
|
44
|
+
File.expects(:exists?).with("/nonexisting").returns(true)
|
45
|
+
File.expects(:exists?).with(File.join(File.dirname("/nonexisting"), "rpc-help.erb")).returns(true)
|
46
|
+
PluginManager.stubs(:loadclass)
|
47
|
+
PluginManager.stubs("<<")
|
48
|
+
|
49
|
+
expect { Config.instance.loadconfig("/nonexisting") }.to raise_error("The sylog logger is not usable on the Windows platform")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should default to finding the help template in the same dir as the config file" do
|
53
|
+
path = File.join(File.dirname("/nonexisting"), "rpc-help.erb")
|
54
|
+
|
55
|
+
File.expects(:open).with("/nonexisting", "r").returns(StringIO.new(""))
|
56
|
+
File.expects(:exists?).with("/nonexisting").returns(true)
|
57
|
+
PluginManager.stubs(:loadclass)
|
58
|
+
PluginManager.stubs("<<")
|
59
|
+
|
60
|
+
File.expects(:exists?).with(path).returns(true)
|
61
|
+
|
62
|
+
Config.instance.loadconfig("/nonexisting")
|
63
|
+
Config.instance.rpchelptemplate.should == path
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should fall back to old behavior if the help template file does not exist in the config dir" do
|
67
|
+
path = File.join(File.dirname("/nonexisting"), "rpc-help.erb")
|
68
|
+
|
69
|
+
File.expects(:open).with("/nonexisting", "r").returns(StringIO.new(""))
|
70
|
+
File.expects(:exists?).with("/nonexisting").returns(true)
|
71
|
+
File.expects(:exists?).with(path).returns(false)
|
72
|
+
PluginManager.stubs(:loadclass)
|
73
|
+
PluginManager.stubs("<<")
|
74
|
+
|
75
|
+
Config.instance.loadconfig("/nonexisting")
|
76
|
+
Config.instance.rpchelptemplate.should == "/etc/mcollective/rpc-help.erb"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "#read_plugin_config_dir" do
|
81
|
+
before do
|
82
|
+
tmpfile = Tempfile.new("mc_config_spec")
|
83
|
+
path = tmpfile.path
|
84
|
+
tmpfile.close!
|
85
|
+
|
86
|
+
@tmpdir = FileUtils.mkdir_p(path)
|
87
|
+
@tmpdir = @tmpdir[0] if @tmpdir.is_a?(Array) # ruby 1.9.2
|
88
|
+
|
89
|
+
@plugindir = File.join([@tmpdir, "plugin.d"])
|
90
|
+
FileUtils.mkdir(@plugindir)
|
91
|
+
|
92
|
+
Config.instance.set_config_defaults("")
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should not fail if the supplied directory is missing" do
|
96
|
+
Config.instance.read_plugin_config_dir("/nonexisting")
|
97
|
+
Config.instance.pluginconf.should == {}
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should skip files that do not match the expected filename pattern" do
|
101
|
+
File.open(File.join([@tmpdir, "plugin.d", "foo.txt"]), "w") { }
|
102
|
+
IO.expects(:open).with(File.join([@tmpdir, "plugin.d", "foo.txt"])).never
|
103
|
+
|
104
|
+
Config.instance.read_plugin_config_dir(@plugindir)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should load the config files" do
|
108
|
+
configfile = File.join([@tmpdir, "plugin.d", "foo.cfg"])
|
109
|
+
File.open(configfile, "w") { }
|
110
|
+
|
111
|
+
File.expects(:open).with(configfile, "r").returns([]).once
|
112
|
+
Config.instance.read_plugin_config_dir(@plugindir)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should set config parameters correctly" do
|
116
|
+
configfile = File.join([@tmpdir, "plugin.d", "foo.cfg"])
|
117
|
+
|
118
|
+
File.open(configfile, "w") do |f|
|
119
|
+
f.puts "bar = baz"
|
120
|
+
end
|
121
|
+
|
122
|
+
Config.instance.set_config_defaults(@tmpdir)
|
123
|
+
Config.instance.read_plugin_config_dir(@plugindir)
|
124
|
+
Config.instance.pluginconf.should == {"foo.bar" => "baz"}
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should override main config file" do
|
128
|
+
configfile = File.join([@tmpdir, "plugin.d", "foo.cfg"])
|
129
|
+
servercfg = File.join(@tmpdir, "server.cfg")
|
130
|
+
|
131
|
+
File.open(servercfg, "w") {|f| f.puts "plugin.foo.bar = foo"}
|
132
|
+
|
133
|
+
PluginManager.stubs(:loadclass)
|
134
|
+
|
135
|
+
Config.instance.loadconfig(servercfg)
|
136
|
+
Config.instance.pluginconf.should == {"foo.bar" => "foo"}
|
137
|
+
|
138
|
+
File.open(configfile, "w") do |f|
|
139
|
+
f.puts "bar = baz"
|
140
|
+
end
|
141
|
+
|
142
|
+
PluginManager.delete("global_stats")
|
143
|
+
Config.instance.loadconfig(servercfg)
|
144
|
+
Config.instance.pluginconf.should == {"foo.bar" => "baz"}
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
module MCollective::Facts
|
6
|
+
describe Base do
|
7
|
+
before do
|
8
|
+
class Testfacts<Base; end
|
9
|
+
|
10
|
+
MCollective::PluginManager.delete("facts_plugin")
|
11
|
+
MCollective::PluginManager << {:type => "facts_plugin", :class => "MCollective::Facts::Testfacts"}
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#inherited" do
|
15
|
+
it "should add classes to the plugin manager" do
|
16
|
+
MCollective::PluginManager.stubs("<<").with({:type => "facts_plugin", :class => "MCollective::Facts::Bar"})
|
17
|
+
|
18
|
+
class Bar<Base; end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should be available in the PluginManager" do
|
22
|
+
MCollective::PluginManager["facts_plugin"].class.should == MCollective::Facts::Testfacts
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#get_fact" do
|
27
|
+
it "should call the fact provider #load_facts_from_source" do
|
28
|
+
Testfacts.any_instance.stubs("load_facts_from_source").returns({"foo" => "bar"}).once
|
29
|
+
|
30
|
+
f = Testfacts.new
|
31
|
+
f.get_fact("foo")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should honor the cache timeout" do
|
35
|
+
Testfacts.any_instance.stubs("load_facts_from_source").returns({"foo" => "bar"}).once
|
36
|
+
|
37
|
+
f = Testfacts.new
|
38
|
+
f.get_fact("foo")
|
39
|
+
f.get_fact("foo")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should detect empty facts" do
|
43
|
+
Testfacts.any_instance.stubs("load_facts_from_source").returns({})
|
44
|
+
MCollective::Log.expects("error").with("Failed to load facts: RuntimeError: Got empty facts").once
|
45
|
+
|
46
|
+
f = Testfacts.new
|
47
|
+
f.get_fact("foo")
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should convert non string facts to strings" do
|
51
|
+
Testfacts.any_instance.stubs("load_facts_from_source").returns({:foo => "bar"})
|
52
|
+
|
53
|
+
f = Testfacts.new
|
54
|
+
f.get_fact("foo").should == "bar"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should not create duplicate facts while converting to strings" do
|
58
|
+
Testfacts.any_instance.stubs("load_facts_from_source").returns({:foo => "bar"})
|
59
|
+
|
60
|
+
f = Testfacts.new
|
61
|
+
f.get_fact(nil).include?(:foo).should == false
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should update last_facts_load on success" do
|
65
|
+
Testfacts.any_instance.stubs("load_facts_from_source").returns({"foo" => "bar"}).once
|
66
|
+
|
67
|
+
f = Testfacts.new
|
68
|
+
f.get_fact("foo")
|
69
|
+
|
70
|
+
f.instance_variable_get("@last_facts_load").should_not == 0
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should restore last known good facts on failure" do
|
74
|
+
Testfacts.any_instance.stubs("load_facts_from_source").returns({}).once
|
75
|
+
MCollective::Log.expects("error").with("Failed to load facts: RuntimeError: Got empty facts").once
|
76
|
+
|
77
|
+
f = Testfacts.new
|
78
|
+
f.instance_variable_set("@last_good_facts", {"foo" => "bar"})
|
79
|
+
|
80
|
+
f.get_fact("foo").should == "bar"
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should return all facts for nil parameter" do
|
84
|
+
Testfacts.any_instance.stubs("load_facts_from_source").returns({"foo" => "bar", "bar" => "baz"})
|
85
|
+
|
86
|
+
f = Testfacts.new
|
87
|
+
f.get_fact(nil).keys.size.should == 2
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should return a specific fact when specified" do
|
91
|
+
Testfacts.any_instance.stubs("load_facts_from_source").returns({"foo" => "bar", "bar" => "baz"})
|
92
|
+
|
93
|
+
f = Testfacts.new
|
94
|
+
f.get_fact("bar").should == "baz"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "#get_facts" do
|
99
|
+
it "should load and return all facts" do
|
100
|
+
Testfacts.any_instance.stubs("load_facts_from_source").returns({"foo" => "bar", "bar" => "baz"})
|
101
|
+
|
102
|
+
f = Testfacts.new
|
103
|
+
f.get_facts.should == {"foo" => "bar", "bar" => "baz"}
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "#has_fact?" do
|
108
|
+
it "should correctly report fact presense" do
|
109
|
+
Testfacts.any_instance.stubs("load_facts_from_source").returns({"foo" => "bar"})
|
110
|
+
|
111
|
+
f = Testfacts.new
|
112
|
+
f.has_fact?("foo").should == true
|
113
|
+
f.has_fact?("bar").should == false
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|