456020e9d480f3d329281f9fe7c48494d213340a
[packages/precise/mcollective.git] / spec / unit / rpc / actionrunner_spec.rb
1 #!/usr/bin/env rspec
2
3 require 'spec_helper'
4
5 module MCollective
6   module RPC
7     describe ActionRunner do
8       before(:each) do
9         @req = mock
10         @req.stubs(:agent).returns("spectester")
11         @req.stubs(:action).returns("tester")
12
13         command = "/bin/echo 1"
14
15         @runner = ActionRunner.new(command, @req, :json)
16       end
17
18       describe "#initialize" do
19         it "should set command" do
20           @runner.command.should == "/bin/echo 1"
21         end
22
23         it "should set agent" do
24           @runner.agent.should == "spectester"
25         end
26
27         it "should set action" do
28           @runner.action.should == "tester"
29         end
30
31         it "should set format" do
32           @runner.format.should == :json
33         end
34
35         it "should set request" do
36           @runner.request.should == @req
37         end
38
39         it "should set stdout" do
40           @runner.stdout.should == ""
41         end
42
43         it "should set stderr" do
44           @runner.stderr.should == ""
45         end
46
47         it "should set the command via path_to_command" do
48           ActionRunner.any_instance.expects(:path_to_command).with("rspec").once
49           ActionRunner.new("rspec", @req, :json)
50         end
51       end
52
53       describe "#shell" do
54         it "should create a shell instance with correct settings" do
55           s = @runner.shell("test", "infile", "outfile")
56
57           s.command.should == "test infile outfile"
58           s.cwd.should == Dir.tmpdir
59           s.stdout.should == ""
60           s.stderr.should == ""
61           s.environment["MCOLLECTIVE_REQUEST_FILE"].should == "infile"
62           s.environment["MCOLLECTIVE_REPLY_FILE"].should == "outfile"
63         end
64       end
65
66       describe "#load_results" do
67         it "should call the correct format loader" do
68           req = mock
69           req.expects(:agent).returns("spectester")
70           req.expects(:action).returns("tester")
71
72           runner = ActionRunner.new("/bin/echo 1", req, :foo)
73           runner.expects("load_foo_results").returns({:foo => :bar})
74           runner.load_results("/dev/null").should == {:foo => :bar}
75         end
76
77         it "should set all keys to Symbol" do
78           data = {"foo" => "bar", "bar" => "baz"}
79           Tempfile.open("mcollective_test", Dir.tmpdir) do |f|
80             f.puts data.to_json
81             f.close
82
83             results = @runner.load_results(f.path)
84             results.should == {:foo => "bar", :bar => "baz"}
85           end
86         end
87       end
88
89       describe "#load_json_results" do
90         it "should load data from a file" do
91           Tempfile.open("mcollective_test", Dir.tmpdir) do |f|
92             f.puts '{"foo":"bar","bar":"baz"}'
93             f.close
94
95             @runner.load_json_results(f.path).should == {"foo" => "bar", "bar" => "baz"}
96           end
97
98         end
99
100         it "should return empty data on JSON parse error" do
101           @runner.load_json_results("/dev/null").should == {}
102         end
103
104         it "should return empty data for missing files" do
105           @runner.load_json_results("/nonexisting").should == {}
106         end
107
108         it "should load complex data correctly" do
109           data = {"foo" => "bar", "bar" => {"one" => "two"}}
110           Tempfile.open("mcollective_test", Dir.tmpdir) do |f|
111             f.puts data.to_json
112             f.close
113
114             @runner.load_json_results(f.path).should == data
115           end
116         end
117
118       end
119
120       describe "#saverequest" do
121         it "should call the correct format serializer" do
122           req = mock
123           req.expects(:agent).returns("spectester")
124           req.expects(:action).returns("tester")
125
126           runner = ActionRunner.new("/bin/echo 1", req, :foo)
127
128           runner.expects("save_foo_request").with(req).returns('{"foo":"bar"}')
129
130           runner.saverequest(req)
131         end
132
133         it "should save to a temp file" do
134           @req.expects(:to_json).returns({:foo => "bar"}.to_json)
135           fname = @runner.saverequest(@req).path
136
137           JSON.load(File.read(fname)).should == {"foo" => "bar"}
138           File.dirname(fname).should == Dir.tmpdir
139         end
140       end
141
142       describe "#save_json_request" do
143         it "should return correct json data" do
144           @req.expects(:to_json).returns({:foo => "bar"}.to_json)
145           @runner.save_json_request(@req).should == '{"foo":"bar"}'
146         end
147       end
148
149       describe "#canrun?" do
150         it "should correctly report executables" do
151           if Util.windows?
152             @runner.canrun?(File.join(ENV['SystemRoot'], "explorer.exe")).should == true
153           else
154             @runner.canrun?("/bin/true").should == true
155           end
156         end
157
158         it "should detect missing files" do
159           @runner.canrun?("/nonexisting").should == false
160         end
161       end
162
163       describe "#to_s" do
164         it "should return correct data" do
165           @runner.to_s.should == "spectester#tester command: /bin/echo 1"
166         end
167       end
168
169       describe "#tempfile" do
170         it "should return a TempFile" do
171           @runner.tempfile("foo").class.should == Tempfile
172         end
173
174         it "should contain the prefix in its name" do
175           @runner.tempfile("foo").path.should match(/foo/)
176         end
177       end
178
179       describe "#path_to_command" do
180         it "should return the command if it starts with separator" do
181           command = "#{File::SEPARATOR}rspec"
182
183           runner = ActionRunner.new(command , @req, :json)
184           runner.path_to_command(command).should == command
185         end
186
187         it "should find the first match in the libdir" do
188           Config.instance.expects(:libdir).returns(["#{File::SEPARATOR}libdir1", "#{File::SEPARATOR}libdir2"])
189
190           action_in_first_dir = File.join(File::SEPARATOR, "libdir1", "agent", "spectester", "action.sh")
191           action_in_last_dir = File.join(File::SEPARATOR, "libdir2", "agent", "spectester", "action.sh")
192
193           File.expects("exist?").with(action_in_first_dir).returns(true)
194           File.expects("exist?").with(action_in_last_dir).never
195
196           ActionRunner.new("action.sh", @req, :json).command.should == action_in_first_dir
197         end
198
199         it "should find the match even in the last libdir" do
200           Config.instance.expects(:libdir).returns(["#{File::SEPARATOR}libdir1", "#{File::SEPARATOR}libdir2"])
201
202           action_in_first_dir = File.join(File::SEPARATOR, "libdir1", "agent", "spectester", "action.sh")
203           action_in_last_dir = File.join(File::SEPARATOR, "libdir2", "agent", "spectester", "action.sh")
204
205           File.expects("exist?").with(action_in_first_dir).returns(false)
206           File.expects("exist?").with(action_in_last_dir).returns(true)
207
208           ActionRunner.new("action.sh", @req, :json).command.should == action_in_last_dir
209         end
210       end
211     end
212   end
213 end