File: keyvalue_spec.rb

package info (click to toggle)
puppet 5.5.10-4
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 21,116 kB
  • sloc: ruby: 250,669; sh: 1,620; xml: 218; makefile: 151; sql: 103
file content (261 lines) | stat: -rw-r--r-- 9,229 bytes parent folder | download
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#! /usr/bin/env ruby
require 'spec_helper'

require 'puppet/property/keyvalue'


describe 'Puppet::Property::KeyValue' do 
  let(:klass) { Puppet::Property::KeyValue }

  it "should be a subclass of Property" do
    expect(klass.superclass).to eq(Puppet::Property)
  end

  describe "as an instance" do
    before do
      # Wow that's a messy interface to the resource.
      klass.initvars
      @resource = stub 'resource', :[]= => nil, :property => nil
      @property = klass.new(:resource => @resource)
      klass.log_only_changed_or_new_keys = false
    end

    it "should have a , as default delimiter" do
      expect(@property.delimiter).to eq(";")
    end

    it "should have a = as default separator" do
      expect(@property.separator).to eq("=")
    end

    it "should have a :membership as default membership" do
      expect(@property.membership).to eq(:key_value_membership)
    end

    it "should return the same value passed into should_to_s" do
      @property.should_to_s({:foo => "baz", :bar => "boo"}) == "foo=baz;bar=boo"
    end

    it "should return the passed in hash values joined with the delimiter from is_to_s" do
      s = @property.is_to_s({"foo" => "baz" , "bar" => "boo"})

      # We can't predict the order the hash is processed in...
      expect(["foo=baz;bar=boo", "bar=boo;foo=baz"]).to be_include s
    end

    describe "when calling hash_to_key_value_s" do
      let(:input) do
        {
          :key1 => "value1",
          :key2 => "value2",
          :key3 => "value3"
        }
      end

      before(:each) do
        @property.instance_variable_set(:@changed_or_new_keys, [:key1, :key2])
      end

      it "returns only the changed or new keys if log_only_changed_or_new_keys is set" do
        klass.log_only_changed_or_new_keys = true

        expect(@property.hash_to_key_value_s(input)).to eql("key1=value1;key2=value2")
      end
    end

    describe "when calling inclusive?" do
      it "should use the membership method to look up on the @resource" do
        @property.expects(:membership).returns(:key_value_membership)
        @resource.expects(:[]).with(:key_value_membership)
        @property.inclusive?
      end

      it "should return true when @resource[membership] == inclusive" do
        @property.stubs(:membership).returns(:key_value_membership)
        @resource.stubs(:[]).with(:key_value_membership).returns(:inclusive)
        expect(@property.inclusive?).to eq(true)
      end

      it "should return false when @resource[membership] != inclusive" do
        @property.stubs(:membership).returns(:key_value_membership)
        @resource.stubs(:[]).with(:key_value_membership).returns(:minimum)
        expect(@property.inclusive?).to eq(false)
      end
    end

    describe "when calling process_current_hash" do
      it "should return {} if hash is :absent" do
        expect(@property.process_current_hash(:absent)).to eq({})
      end

      it "should set every key to nil if inclusive?" do
        @property.stubs(:inclusive?).returns(true)
        expect(@property.process_current_hash({:foo => "bar", :do => "re"})).to eq({ :foo => nil, :do => nil })
      end

      it "should return the hash if !inclusive?" do
        @property.stubs(:inclusive?).returns(false)
        expect(@property.process_current_hash({:foo => "bar", :do => "re"})).to eq({:foo => "bar", :do => "re"})
      end
    end

    describe "when calling should" do
      it "should return nil if @should is nil" do
        expect(@property.should).to eq(nil)
      end

      it "should call process_current_hash" do
        @property.should = ["foo=baz", "bar=boo"]
        @property.stubs(:retrieve).returns({:do => "re", :mi => "fa" })
        @property.expects(:process_current_hash).returns({})
        @property.should
      end

      it "should return the hashed values of @should and the nilled values of retrieve if inclusive" do
        @property.should = ["foo=baz", "bar=boo"]
        @property.expects(:retrieve).returns({:do => "re", :mi => "fa" })
        @property.expects(:inclusive?).returns(true)
        expect(@property.should).to eq({ :foo => "baz", :bar => "boo", :do => nil, :mi => nil })
      end

      it "should return the hashed @should + the unique values of retrieve if !inclusive" do
        @property.should = ["foo=baz", "bar=boo"]
        @property.expects(:retrieve).returns({:foo => "diff", :do => "re", :mi => "fa"})
        @property.expects(:inclusive?).returns(false)
        expect(@property.should).to eq({ :foo => "baz", :bar => "boo", :do => "re", :mi => "fa" })
      end

      it "should mark the keys that will change or be added as a result of our Puppet run" do
        @property.should = {
          :key1 => "new_value1",
          :key2 => "value2",
          :key3 => "new_value3",
          :key4 => "value4"
        }
        @property.stubs(:retrieve).returns(
          {
            :key1 => "value1",
            :key2 => "value2",
            :key3 => "value3"
          }
        )
        @property.stubs(:inclusive?).returns(false)

        @property.should
        expect(@property.instance_variable_get(:@changed_or_new_keys)).to eql([:key1, :key3, :key4])
      end
    end

    describe "when calling retrieve" do
      before do
        @provider = mock("provider")
        @property.stubs(:provider).returns(@provider)
      end

      it "should send 'name' to the provider" do
        @provider.expects(:send).with(:keys)
        @property.expects(:name).returns(:keys)
        @property.retrieve
      end

      it "should return a hash with the provider returned info" do
        @provider.stubs(:send).with(:keys).returns({"do" => "re", "mi" => "fa" })
        @property.stubs(:name).returns(:keys)
        @property.retrieve == {"do" => "re", "mi" => "fa" }
      end

      it "should return :absent when the provider returns :absent" do
        @provider.stubs(:send).with(:keys).returns(:absent)
        @property.stubs(:name).returns(:keys)
        @property.retrieve == :absent
      end
    end

    describe "when calling hashify_should" do
      it "should return the underlying hash if the user passed in a hash" do
        @property.should = { "foo" => "bar" }
        expect(@property.hashify_should).to eql({ :foo => "bar" })
      end

      it "should hashify the array of key/value pairs if that is what our user passed in" do
        @property.should = [ "foo=baz", "bar=boo" ]
        expect(@property.hashify_should).to eq({ :foo => "baz", :bar => "boo" })
      end
    end

    describe "when calling safe_insync?" do
      before do
        @provider = mock("provider")
        @property.stubs(:provider).returns(@provider)
        @property.stubs(:name).returns(:prop_name)
      end

      it "should return true unless @should is defined and not nil" do
        @property.safe_insync?("foo") == true
      end

      it "should return true if the passed in values is nil" do
        @property.safe_insync?(nil) == true
      end

      it "should return true if hashified should value == (retrieved) value passed in" do
        @provider.stubs(:prop_name).returns({ :foo => "baz", :bar => "boo" })
        @property.should = ["foo=baz", "bar=boo"]
        @property.expects(:inclusive?).returns(true)
        expect(@property.safe_insync?({ :foo => "baz", :bar => "boo" })).to eq(true)
      end

      it "should return false if prepared value != should value" do
        @provider.stubs(:prop_name).returns({ "foo" => "bee", "bar" => "boo" })
        @property.should = ["foo=baz", "bar=boo"]
        @property.expects(:inclusive?).returns(true)
        expect(@property.safe_insync?({ "foo" => "bee", "bar" => "boo" })).to eq(false)
      end
    end

    describe 'when validating a passed-in property value' do
      it 'should raise a Puppet::Error if the property value is anything but a Hash or a String' do
        expect { @property.validate(5) }.to raise_error do |error|
          expect(error).to be_a(Puppet::Error)
          expect(error.message).to match("specified as a hash or an array")
        end
      end

      it 'should accept a Hash property value' do
        @property.validate({ 'foo' => 'bar' })
      end

      it "should raise a Puppet::Error if the property value isn't a key/value pair" do
        expect { @property.validate('foo') }.to raise_error do |error|
          expect(error).to be_a(Puppet::Error)
          expect(error.message).to match("separated by '='")
        end
      end

      it 'should accept a valid key/value pair property value' do
        @property.validate('foo=bar')
      end
    end

    describe 'when munging a passed-in property value' do
      it 'should return the value as-is if it is a string' do
        expect(@property.munge('foo=bar')).to eql('foo=bar')
      end

      it 'should stringify + symbolize the keys and stringify the values if it is a hash' do
        input = {
          1     => 2,
          true  => false,
          '   foo   ' => 'bar'
        }
        expected_output = {
          :'1'    => '2',
          :true => 'false',
          :foo  => 'bar'
        }

        expect(@property.munge(input)).to eql(expected_output)
      end
    end
  end
end