summaryrefslogtreecommitdiff
path: root/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb
blob: a5ec146fc1e37162bfd41b516aecba85777d9564 (plain)
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@chef.io>)
# Copyright:: Copyright (c) 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"] = {}
    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(:guard_interpreter) { Chef::GuardInterpreter::ResourceGuardInterpreter.new(parent_resource, "exit 0", {}) }
      let(:resource) { guard_interpreter.instance_variable_get(:@resource) }

      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) do
            instance_double(Mixlib::ShellOut, live_stream: true, run_command: true, error!: nil)
          end

          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 "assigns the comand to the resource's code property" do
            guard_interpreter.evaluate
            expect(resource.code).to eq("exit 0")
          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 "assigns the comand to the resource's command property" do
            guard_interpreter.evaluate
            expect(resource.command).to eq("exit 0")
          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 "assigns the comand to the resource's command property" do
          guard_interpreter.evaluate
          expect(resource.command).to eq("exit 0")
        end
      end

    end
  end
end