1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
#
# Author:: Adam Edwards (<adamed@getchef.com>)
# Copyright:: Copyright (c) 2014 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require "spec_helper"
describe Chef::GuardInterpreter::ResourceGuardInterpreter do
let(:node) do
node = Chef::Node.new
node.default["kernel"] = Hash.new
node.default["kernel"][:machine] = :x86_64.to_s
node.automatic[:os] = "windows"
node
end
let(:run_context) { Chef::RunContext.new(node, nil, nil) }
let(:parent_resource) do
parent_resource = Chef::Resource.new("powershell_unit_test", run_context)
allow(parent_resource).to receive(:run_action)
allow(parent_resource).to receive(:updated).and_return(true)
parent_resource
end
let(:guard_interpreter) { Chef::GuardInterpreter::ResourceGuardInterpreter.new(parent_resource, "echo hi", nil) }
describe "get_interpreter_resource" do
it "allows the guard interpreter to be set to Chef::Resource::Script" do
parent_resource.guard_interpreter(:script)
expect { guard_interpreter }.not_to raise_error
end
it "allows the guard interpreter to be set to Chef::Resource::PowershellScript derived indirectly from Chef::Resource::Script" do
parent_resource.guard_interpreter(:powershell_script)
expect { guard_interpreter }.not_to raise_error
end
it "raises an exception if guard_interpreter is set to a resource not derived from Chef::Resource::Script" do
parent_resource.guard_interpreter(:file)
expect { guard_interpreter }.to raise_error(ArgumentError, "Specified guard interpreter class Chef::Resource::File must be a kind of Chef::Resource::Execute resource")
end
context "when the resource cannot be found for the platform" do
before do
expect(Chef::Resource).to receive(:resource_for_node).with(:foobar, node).and_return(nil)
end
it "raises an exception" do
parent_resource.guard_interpreter(:foobar)
expect { guard_interpreter }.to raise_error(ArgumentError, "Specified guard_interpreter resource foobar unknown for this platform")
end
end
it "fails when parent_resource is nil" do
expect { Chef::GuardInterpreter::ResourceGuardInterpreter.new(nil, "echo hi", nil) }.to raise_error(ArgumentError, /Node for guard resource parent must not be nil/)
end
end
describe "#evaluate" do
let(:guard_interpreter) { Chef::GuardInterpreter::ResourceGuardInterpreter.new(parent_resource, "echo hi", {}) }
let(:parent_resource) do
parent_resource = Chef::Resource.new("execute resource", run_context)
parent_resource.guard_interpreter(:execute)
parent_resource
end
it "successfully evaluates the resource" do
expect(guard_interpreter.evaluate).to eq(true)
end
it "does not corrupt the run_context of the node" do
node_run_context_before_guard_execution = parent_resource.run_context
expect(node_run_context_before_guard_execution.object_id).to eq(parent_resource.node.run_context.object_id)
guard_interpreter.evaluate
node_run_context_after_guard_execution = parent_resource.run_context
expect(node_run_context_after_guard_execution.object_id).to eq(parent_resource.node.run_context.object_id)
end
describe "script command opts switch" do
let(:command_opts) { {} }
let(:guard_interpreter) { Chef::GuardInterpreter::ResourceGuardInterpreter.new(parent_resource, "exit 0", command_opts) }
context "resource is a Script" do
context "and guard_interpreter is a :script" do
let(:parent_resource) do
parent_resource = Chef::Resource::Script.new("resource", run_context)
# Ruby scripts are cross platform to both Linux and Windows
parent_resource.guard_interpreter(:ruby)
parent_resource
end
let(:shell_out) {
instance_double(Mixlib::ShellOut, :live_stream => true, :run_command => true, :error! => nil)
}
before do
# TODO for some reason Windows is failing on executing a ruby script
expect(Mixlib::ShellOut).to receive(:new) do |*args|
expect(args[0]).to match(/^"ruby"/)
shell_out
end
end
it "merges to :code" do
expect(command_opts).to receive(:merge).with({:code => "exit 0"}).and_call_original
expect(guard_interpreter.evaluate).to eq(true)
end
end
context "and guard_interpreter is :execute" do
let(:parent_resource) do
parent_resource = Chef::Resource::Script.new("resource", run_context)
parent_resource.guard_interpreter(:execute)
parent_resource
end
it "merges to :code" do
expect(command_opts).to receive(:merge).with({:command => "exit 0"}).and_call_original
expect(guard_interpreter.evaluate).to eq(true)
end
end
end
context "resource is not a Script" do
let(:parent_resource) do
parent_resource = Chef::Resource::Execute.new("resource", run_context)
parent_resource.guard_interpreter(:execute)
parent_resource
end
it "merges to :command" do
expect(command_opts).to receive(:merge).with({:command => "exit 0"}).and_call_original
expect(guard_interpreter.evaluate).to eq(true)
end
end
end
end
end
|