chef 13.7.16 → 13.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/distro/common/man/man8/chef-solo.8 +1 -1
- data/lib/chef/chef_fs/data_handler/organization_invites_data_handler.rb +1 -1
- data/lib/chef/knife/bootstrap.rb +1 -1
- data/lib/chef/knife/search.rb +3 -1
- data/lib/chef/knife/ssh.rb +5 -7
- data/lib/chef/node/attribute.rb +70 -46
- data/lib/chef/node/attribute_collections.rb +5 -5
- data/lib/chef/node/common_api.rb +1 -1
- data/lib/chef/node/immutable_collections.rb +23 -180
- data/lib/chef/node/mixin/state_tracking.rb +6 -6
- data/lib/chef/node_map.rb +26 -0
- data/lib/chef/provider/remote_file/http.rb +8 -3
- data/lib/chef/resource/log.rb +1 -1
- data/lib/chef/resource/windows_task.rb +4 -4
- data/lib/chef/version.rb +1 -1
- data/spec/functional/mixin/powershell_out_spec.rb +5 -21
- data/spec/spec_helper.rb +19 -1
- data/spec/unit/daemon_spec.rb +21 -12
- data/spec/unit/mixin/powershell_type_coercions_spec.rb +6 -7
- data/spec/unit/node/attribute_spec.rb +24 -55
- data/spec/unit/node/immutable_collections_spec.rb +16 -30
- data/spec/unit/node/vivid_mash_spec.rb +10 -27
- data/spec/unit/node_map_spec.rb +29 -4
- data/spec/unit/provider/remote_file/http_spec.rb +6 -8
- data/spec/unit/resource/windows_task_spec.rb +9 -1
- metadata +4 -4
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright:: Copyright 2016
|
2
|
+
# Copyright:: Copyright 2016, Chef Software, Inc.
|
3
3
|
# License:: Apache License, Version 2.0
|
4
4
|
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -24,12 +24,11 @@ class Chef
|
|
24
24
|
attr_reader :__node__
|
25
25
|
attr_reader :__precedence__
|
26
26
|
|
27
|
-
def initialize(data = nil, root = self, node = nil, precedence = nil
|
27
|
+
def initialize(data = nil, root = self, node = nil, precedence = nil)
|
28
28
|
# __path__ and __root__ must be nil when we call super so it knows
|
29
29
|
# to avoid resetting the cache on construction
|
30
30
|
data.nil? ? super() : super(data)
|
31
|
-
@__path__ =
|
32
|
-
@__path__ ||= []
|
31
|
+
@__path__ = []
|
33
32
|
@__root__ = root
|
34
33
|
@__node__ = node
|
35
34
|
@__precedence__ = precedence
|
@@ -77,8 +76,9 @@ class Chef
|
|
77
76
|
end
|
78
77
|
end
|
79
78
|
|
80
|
-
def send_reset_cache(path)
|
81
|
-
|
79
|
+
def send_reset_cache(path = nil, key = nil)
|
80
|
+
next_path = [ path, key ].flatten.compact
|
81
|
+
__root__.reset_cache(next_path.first) if !__root__.nil? && __root__.respond_to?(:reset_cache) && !next_path.nil?
|
82
82
|
end
|
83
83
|
|
84
84
|
def copy_state_to(ret, next_path)
|
data/lib/chef/node_map.rb
CHANGED
@@ -118,6 +118,32 @@ class Chef
|
|
118
118
|
end.map { |matcher| matcher[:klass] }
|
119
119
|
end
|
120
120
|
|
121
|
+
# Remove a class from all its matchers in the node_map, will remove mappings completely if its the last matcher left
|
122
|
+
#
|
123
|
+
# Note that this leaks the internal structure out a bit, but the main consumer of this (poise/halite) cares only about
|
124
|
+
# the keys in the returned Hash.
|
125
|
+
#
|
126
|
+
# @param klass [Class] the class to seek and destroy
|
127
|
+
#
|
128
|
+
# @return [Hash] deleted entries in the same format as the @map
|
129
|
+
def delete_class(klass)
|
130
|
+
raise "please use a Class type for the klass argument" unless klass.is_a?(Class)
|
131
|
+
deleted = {}
|
132
|
+
map.each do |key, matchers|
|
133
|
+
deleted_matchers = []
|
134
|
+
matchers.delete_if do |matcher|
|
135
|
+
# because matcher[:klass] may be a string (which needs to die), coerce both to strings to compare somewhat canonically
|
136
|
+
if matcher[:klass].to_s == klass.to_s
|
137
|
+
deleted_matchers << matcher
|
138
|
+
true
|
139
|
+
end
|
140
|
+
end
|
141
|
+
deleted[key] = deleted_matchers unless deleted_matchers.empty?
|
142
|
+
map.delete(key) if matchers.empty?
|
143
|
+
end
|
144
|
+
deleted
|
145
|
+
end
|
146
|
+
|
121
147
|
# Seriously, don't use this, it's nearly certain to change on you
|
122
148
|
# @return remaining
|
123
149
|
# @api private
|
@@ -61,17 +61,22 @@ class Chef
|
|
61
61
|
|
62
62
|
def fetch
|
63
63
|
http = Chef::HTTP::Simple.new(uri, http_client_opts)
|
64
|
-
|
64
|
+
orig_tempfile = Chef::FileContentManagement::Tempfile.new(@new_resource).tempfile
|
65
65
|
if want_progress?
|
66
|
-
tempfile = http.streaming_request_with_progress(uri, headers,
|
66
|
+
tempfile = http.streaming_request_with_progress(uri, headers, orig_tempfile) do |size, total|
|
67
67
|
events.resource_update_progress(new_resource, size, total, progress_interval)
|
68
68
|
end
|
69
69
|
else
|
70
|
-
tempfile = http.streaming_request(uri, headers,
|
70
|
+
tempfile = http.streaming_request(uri, headers, orig_tempfile)
|
71
71
|
end
|
72
72
|
if tempfile
|
73
73
|
update_cache_control_data(tempfile, http.last_response)
|
74
74
|
tempfile.close
|
75
|
+
else
|
76
|
+
# cache_control shows the file is unchanged, so we got back nil from the streaming_request above, and it is
|
77
|
+
# now our responsibility to unlink the tempfile we created
|
78
|
+
orig_tempfile.close
|
79
|
+
orig_tempfile.unlink
|
75
80
|
end
|
76
81
|
tempfile
|
77
82
|
end
|
data/lib/chef/resource/log.rb
CHANGED
@@ -39,7 +39,7 @@ class Chef
|
|
39
39
|
class Log < Chef::Resource
|
40
40
|
resource_name :log
|
41
41
|
|
42
|
-
property :message, String, name_property: true
|
42
|
+
property :message, String, name_property: true, identity: true
|
43
43
|
property :level, Symbol, equal_to: [ :debug, :info, :warn, :error, :fatal ], default: :info
|
44
44
|
|
45
45
|
allowed_actions :write
|
@@ -82,7 +82,7 @@ class Chef
|
|
82
82
|
validate_create_frequency_modifier(frequency, frequency_modifier)
|
83
83
|
validate_create_day(day, frequency) if day
|
84
84
|
validate_create_months(months, frequency) if months
|
85
|
-
validate_idle_time(idle_time, frequency)
|
85
|
+
validate_idle_time(idle_time, frequency)
|
86
86
|
end
|
87
87
|
|
88
88
|
private
|
@@ -196,13 +196,13 @@ class Chef
|
|
196
196
|
end
|
197
197
|
|
198
198
|
def validate_idle_time(idle_time, frequency)
|
199
|
-
|
199
|
+
if !idle_time.nil? && frequency != :on_idle
|
200
200
|
raise ArgumentError, "idle_time property is only valid for tasks that run on_idle"
|
201
201
|
end
|
202
|
-
if idle_time.nil?
|
202
|
+
if idle_time.nil? && frequency == :on_idle
|
203
203
|
raise ArgumentError, "idle_time value should be set for :on_idle frequency."
|
204
204
|
end
|
205
|
-
unless idle_time > 0 && idle_time <= 999
|
205
|
+
unless idle_time.nil? || idle_time > 0 && idle_time <= 999
|
206
206
|
raise ArgumentError, "idle_time value #{idle_time} is invalid. Valid values for :on_idle frequency are 1 - 999."
|
207
207
|
end
|
208
208
|
end
|
data/lib/chef/version.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright:: Copyright 2014-
|
2
|
+
# Copyright:: Copyright 2014-2018, Chef Software Inc.
|
3
3
|
# License:: Apache License, Version 2.0
|
4
4
|
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -22,16 +22,8 @@ describe Chef::Mixin::PowershellOut, windows_only: true do
|
|
22
22
|
include Chef::Mixin::PowershellOut
|
23
23
|
|
24
24
|
describe "#powershell_out" do
|
25
|
-
|
26
|
-
|
27
|
-
expect(powershell_out("get-process").run_command.stdout).to match /Handles\s+NPM\(K\)\s+PM\(K\)\s+WS\(K\)\s+VM\(M\)\s+CPU\(s\)\s+Id\s+/
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
context "for windows version greater than 10", windows_gte_10: true do
|
32
|
-
it "runs a powershell command and collects stdout" do
|
33
|
-
expect(powershell_out("get-process").run_command.stdout).to match /Handles\s+NPM\(K\)\s+PM\(K\)\s+WS\(K\)\s+CPU\(s\)\s+Id\s+SI\s+ProcessName\s+/
|
34
|
-
end
|
25
|
+
it "runs a powershell command and collects stdout" do
|
26
|
+
expect(powershell_out("get-process").run_command.stdout).to match /Handles/
|
35
27
|
end
|
36
28
|
|
37
29
|
it "does not raise exceptions when the command is invalid" do
|
@@ -40,16 +32,8 @@ describe Chef::Mixin::PowershellOut, windows_only: true do
|
|
40
32
|
end
|
41
33
|
|
42
34
|
describe "#powershell_out!" do
|
43
|
-
|
44
|
-
|
45
|
-
expect(powershell_out!("get-process").run_command.stdout).to match /Handles\s+NPM\(K\)\s+PM\(K\)\s+WS\(K\)\s+VM\(M\)\s+CPU\(s\)\s+Id\s+/
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
context "for windows version less than 10", windows_gte_10: true do
|
50
|
-
it "runs a powershell command and collects stdout" do
|
51
|
-
expect(powershell_out("get-process").run_command.stdout).to match /Handles\s+NPM\(K\)\s+PM\(K\)\s+WS\(K\)\s+CPU\(s\)\s+Id\s+SI\s+ProcessName\s+/
|
52
|
-
end
|
35
|
+
it "runs a powershell command and collects stdout" do
|
36
|
+
expect(powershell_out!("get-process").run_command.stdout).to match /Handles/
|
53
37
|
end
|
54
38
|
|
55
39
|
it "raises exceptions when the command is invalid" do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Adam Jacob (<adam@chef.io>)
|
3
|
-
# Copyright:: Copyright 2008-
|
3
|
+
# Copyright:: Copyright 2008-2018, Chef Software Inc.
|
4
4
|
# License:: Apache License, Version 2.0
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -254,6 +254,24 @@ RSpec.configure do |config|
|
|
254
254
|
Chef.resource_priority_map.instance_variable_set(:@map, resource_priority_map.dup)
|
255
255
|
end
|
256
256
|
|
257
|
+
# This bit of jankiness guards against specs which accidentally drop privs when running as
|
258
|
+
# root -- which are nearly impossible to debug and so we bail out very hard if this
|
259
|
+
# condition ever happens. If a spec stubs Process.[e]uid this can throw a false positive
|
260
|
+
# which the spec must work around by unmocking Process.[e]uid to and_call_original in its
|
261
|
+
# after block.
|
262
|
+
if Process.euid == 0 && Process.uid == 0
|
263
|
+
config.after(:each) do
|
264
|
+
if Process.uid != 0
|
265
|
+
RSpec.configure { |c| c.fail_fast = true }
|
266
|
+
raise "rspec was invoked as root, but the last test dropped real uid to #{Process.uid}"
|
267
|
+
end
|
268
|
+
if Process.euid != 0
|
269
|
+
RSpec.configure { |c| c.fail_fast = true }
|
270
|
+
raise "rspec was invoked as root, but the last test dropped effective uid to #{Process.euid}"
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
257
275
|
# raise if anyone commits any test to CI with :focus set on it
|
258
276
|
if ENV["CI"]
|
259
277
|
config.before(:example, :focus) do
|
data/spec/unit/daemon_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# Author:: AJ Christensen (<aj@junglist.gen.nz>)
|
3
|
-
# Copyright:: Copyright 2008-
|
3
|
+
# Copyright:: Copyright 2008-2018, Chef Software Inc.
|
4
4
|
# License:: Apache License, Version 2.0
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -19,6 +19,9 @@ require "spec_helper"
|
|
19
19
|
require "ostruct"
|
20
20
|
|
21
21
|
describe Chef::Daemon do
|
22
|
+
let(:testuser) { "thisisausernamewhichshouldnotexist" }
|
23
|
+
let(:testgroup) { "thisisagroupnamewhichshouldnotexist" }
|
24
|
+
|
22
25
|
before do
|
23
26
|
if windows?
|
24
27
|
mock_struct = #Struct::Passwd.new(nil, nil, 111, 111)
|
@@ -73,8 +76,9 @@ describe Chef::Daemon do
|
|
73
76
|
describe ".change_privilege" do
|
74
77
|
|
75
78
|
before do
|
79
|
+
allow(Chef::Daemon).to receive(:_change_privilege)
|
76
80
|
allow(Chef::Application).to receive(:fatal!).and_return(true)
|
77
|
-
Chef::Config[:user] =
|
81
|
+
Chef::Config[:user] = testuser
|
78
82
|
allow(Dir).to receive(:chdir)
|
79
83
|
end
|
80
84
|
|
@@ -86,28 +90,28 @@ describe Chef::Daemon do
|
|
86
90
|
describe "when the user and group options are supplied" do
|
87
91
|
|
88
92
|
before do
|
89
|
-
Chef::Config[:group] =
|
93
|
+
Chef::Config[:group] = testgroup
|
90
94
|
end
|
91
95
|
|
92
96
|
it "should log an appropriate info message" do
|
93
|
-
expect(Chef::Log).to receive(:info).with("About to change privilege to
|
97
|
+
expect(Chef::Log).to receive(:info).with("About to change privilege to #{testuser}:#{testgroup}")
|
94
98
|
Chef::Daemon.change_privilege
|
95
99
|
end
|
96
100
|
|
97
101
|
it "should call _change_privilege with the user and group" do
|
98
|
-
expect(Chef::Daemon).to receive(:_change_privilege).with(
|
102
|
+
expect(Chef::Daemon).to receive(:_change_privilege).with(testuser, testgroup)
|
99
103
|
Chef::Daemon.change_privilege
|
100
104
|
end
|
101
105
|
end
|
102
106
|
|
103
107
|
describe "when just the user option is supplied" do
|
104
108
|
it "should log an appropriate info message" do
|
105
|
-
expect(Chef::Log).to receive(:info).with("About to change privilege to
|
109
|
+
expect(Chef::Log).to receive(:info).with("About to change privilege to #{testuser}")
|
106
110
|
Chef::Daemon.change_privilege
|
107
111
|
end
|
108
112
|
|
109
113
|
it "should call _change_privilege with just the user" do
|
110
|
-
expect(Chef::Daemon).to receive(:_change_privilege).with(
|
114
|
+
expect(Chef::Daemon).to receive(:_change_privilege).with(testuser)
|
111
115
|
Chef::Daemon.change_privilege
|
112
116
|
end
|
113
117
|
end
|
@@ -138,18 +142,18 @@ describe Chef::Daemon do
|
|
138
142
|
end
|
139
143
|
|
140
144
|
it "should initialize the supplemental group list" do
|
141
|
-
expect(Process).to receive(:initgroups).with(
|
142
|
-
Chef::Daemon._change_privilege(
|
145
|
+
expect(Process).to receive(:initgroups).with(testuser, 20)
|
146
|
+
Chef::Daemon._change_privilege(testuser)
|
143
147
|
end
|
144
148
|
|
145
149
|
it "should attempt to change the process GID" do
|
146
150
|
expect(Process::GID).to receive(:change_privilege).with(20).and_return(20)
|
147
|
-
Chef::Daemon._change_privilege(
|
151
|
+
Chef::Daemon._change_privilege(testuser)
|
148
152
|
end
|
149
153
|
|
150
154
|
it "should attempt to change the process UID" do
|
151
155
|
expect(Process::UID).to receive(:change_privilege).with(501).and_return(501)
|
152
|
-
Chef::Daemon._change_privilege(
|
156
|
+
Chef::Daemon._change_privilege(testuser)
|
153
157
|
end
|
154
158
|
end
|
155
159
|
|
@@ -159,6 +163,11 @@ describe Chef::Daemon do
|
|
159
163
|
allow(Process).to receive(:egid).and_return(999)
|
160
164
|
end
|
161
165
|
|
166
|
+
after do
|
167
|
+
allow(Process).to receive(:euid).and_call_original
|
168
|
+
allow(Process).to receive(:egid).and_call_original
|
169
|
+
end
|
170
|
+
|
162
171
|
it "should log an appropriate error message and fail miserably" do
|
163
172
|
allow(Process).to receive(:initgroups).and_raise(Errno::EPERM)
|
164
173
|
error = "Operation not permitted"
|
@@ -166,7 +175,7 @@ describe Chef::Daemon do
|
|
166
175
|
error = "Not owner"
|
167
176
|
end
|
168
177
|
expect(Chef::Application).to receive(:fatal!).with("Permission denied when trying to change 999:999 to 501:20. #{error}")
|
169
|
-
Chef::Daemon._change_privilege(
|
178
|
+
Chef::Daemon._change_privilege(testuser)
|
170
179
|
end
|
171
180
|
end
|
172
181
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Jay Mundrawala (<jdm@chef.io>)
|
3
|
-
# Copyright:: Copyright 2015-
|
3
|
+
# Copyright:: Copyright 2015-2016, Chef Software, Inc.
|
4
4
|
# License:: Apache License, Version 2.0
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -64,15 +64,14 @@ describe Chef::Mixin::PowershellTypeCoercions do
|
|
64
64
|
end
|
65
65
|
|
66
66
|
it "translates a Chef::Node::ImmutableMash like a hash" do
|
67
|
-
|
68
|
-
|
69
|
-
expect(test_class.translate_type(
|
67
|
+
test_mash = Chef::Node::ImmutableMash.new({ "a" => 1, "b" => 1.2,
|
68
|
+
"c" => false, "d" => true })
|
69
|
+
expect(test_class.translate_type(test_mash)).to eq("@{a=1;b=1.2;c=$false;d=$true}")
|
70
70
|
end
|
71
71
|
|
72
72
|
it "translates a Chef::Node::ImmutableArray like an array" do
|
73
|
-
|
74
|
-
|
75
|
-
expect(test_class.translate_type(node[:test])).to eq("@($true,$false)")
|
73
|
+
test_array = Chef::Node::ImmutableArray.new([true, false])
|
74
|
+
expect(test_class.translate_type(test_array)).to eq("@($true,$false)")
|
76
75
|
end
|
77
76
|
|
78
77
|
it "falls back :to_psobject if we have not defined at explicit rule" do
|
@@ -171,7 +171,6 @@ describe Chef::Node::Attribute do
|
|
171
171
|
}
|
172
172
|
@automatic_hash = { "week" => "friday" }
|
173
173
|
@attributes = Chef::Node::Attribute.new(@attribute_hash, @default_hash, @override_hash, @automatic_hash, node)
|
174
|
-
allow(node).to receive(:attributes).and_return(@attributes)
|
175
174
|
end
|
176
175
|
|
177
176
|
describe "initialize" do
|
@@ -180,14 +179,13 @@ describe Chef::Node::Attribute do
|
|
180
179
|
end
|
181
180
|
|
182
181
|
it "should take an Automatioc, Normal, Default and Override hash" do
|
183
|
-
expect { Chef::Node::Attribute.new({}, {}, {}, {}
|
182
|
+
expect { Chef::Node::Attribute.new({}, {}, {}, {}) }.not_to raise_error
|
184
183
|
end
|
185
184
|
|
186
185
|
[ :normal, :default, :override, :automatic ].each do |accessor|
|
187
186
|
it "should set #{accessor}" do
|
188
|
-
|
189
|
-
|
190
|
-
expect(@attributes.send(accessor)).to eq({ accessor.to_s => true })
|
187
|
+
na = Chef::Node::Attribute.new({ :normal => true }, { :default => true }, { :override => true }, { :automatic => true })
|
188
|
+
expect(na.send(accessor)).to eq({ accessor.to_s => true })
|
191
189
|
end
|
192
190
|
end
|
193
191
|
|
@@ -332,8 +330,7 @@ describe Chef::Node::Attribute do
|
|
332
330
|
end
|
333
331
|
|
334
332
|
it "merges nested hashes between precedence levels" do
|
335
|
-
@attributes = Chef::Node::Attribute.new({}, {}, {}, {}
|
336
|
-
allow(node).to receive(:attributes).and_return(@attributes)
|
333
|
+
@attributes = Chef::Node::Attribute.new({}, {}, {}, {})
|
337
334
|
@attributes.env_default = { "a" => { "b" => { "default" => "default" } } }
|
338
335
|
@attributes.normal = { "a" => { "b" => { "normal" => "normal" } } }
|
339
336
|
@attributes.override = { "a" => { "override" => "role" } }
|
@@ -587,10 +584,8 @@ describe Chef::Node::Attribute do
|
|
587
584
|
"one" => { "six" => "seven" },
|
588
585
|
"snack" => "cookies",
|
589
586
|
},
|
590
|
-
{}
|
591
|
-
node
|
587
|
+
{}
|
592
588
|
)
|
593
|
-
allow(node).to receive(:attributes).and_return(@attributes)
|
594
589
|
end
|
595
590
|
|
596
591
|
it "should yield each top level key" do
|
@@ -637,10 +632,8 @@ describe Chef::Node::Attribute do
|
|
637
632
|
"one" => "six",
|
638
633
|
"snack" => "cookies",
|
639
634
|
},
|
640
|
-
{}
|
641
|
-
node
|
635
|
+
{}
|
642
636
|
)
|
643
|
-
allow(node).to receive(:attributes).and_return(@attributes)
|
644
637
|
end
|
645
638
|
|
646
639
|
it "should yield each top level key and value, post merge rules" do
|
@@ -677,10 +670,8 @@ describe Chef::Node::Attribute do
|
|
677
670
|
"one" => "six",
|
678
671
|
"snack" => "cookies",
|
679
672
|
},
|
680
|
-
{}
|
681
|
-
node
|
673
|
+
{}
|
682
674
|
)
|
683
|
-
allow(node).to receive(:attributes).and_return(@attributes)
|
684
675
|
end
|
685
676
|
|
686
677
|
it "should respond to each_key" do
|
@@ -715,10 +706,8 @@ describe Chef::Node::Attribute do
|
|
715
706
|
"one" => "six",
|
716
707
|
"snack" => "cookies",
|
717
708
|
},
|
718
|
-
{}
|
719
|
-
node
|
709
|
+
{}
|
720
710
|
)
|
721
|
-
allow(node).to receive(:attributes).and_return(@attributes)
|
722
711
|
end
|
723
712
|
|
724
713
|
it "should respond to each_pair" do
|
@@ -753,10 +742,8 @@ describe Chef::Node::Attribute do
|
|
753
742
|
"one" => "six",
|
754
743
|
"snack" => "cookies",
|
755
744
|
},
|
756
|
-
{}
|
757
|
-
node
|
745
|
+
{}
|
758
746
|
)
|
759
|
-
allow(node).to receive(:attributes).and_return(@attributes)
|
760
747
|
end
|
761
748
|
|
762
749
|
it "should respond to each_value" do
|
@@ -799,10 +786,9 @@ describe Chef::Node::Attribute do
|
|
799
786
|
"one" => "six",
|
800
787
|
"snack" => "cookies",
|
801
788
|
},
|
802
|
-
{}
|
803
|
-
node
|
789
|
+
{}
|
804
790
|
)
|
805
|
-
|
791
|
+
@empty = Chef::Node::Attribute.new({}, {}, {}, {})
|
806
792
|
end
|
807
793
|
|
808
794
|
it "should respond to empty?" do
|
@@ -810,9 +796,7 @@ describe Chef::Node::Attribute do
|
|
810
796
|
end
|
811
797
|
|
812
798
|
it "should return true when there are no keys" do
|
813
|
-
@
|
814
|
-
allow(node).to receive(:attributes).and_return(@attributes)
|
815
|
-
expect(@attributes.empty?).to eq(true)
|
799
|
+
expect(@empty.empty?).to eq(true)
|
816
800
|
end
|
817
801
|
|
818
802
|
it "should return false when there are keys" do
|
@@ -836,10 +820,8 @@ describe Chef::Node::Attribute do
|
|
836
820
|
"one" => "six",
|
837
821
|
"snack" => "cookies",
|
838
822
|
},
|
839
|
-
{}
|
840
|
-
node
|
823
|
+
{}
|
841
824
|
)
|
842
|
-
allow(node).to receive(:attributes).and_return(@attributes)
|
843
825
|
end
|
844
826
|
|
845
827
|
it "should respond to fetch" do
|
@@ -895,10 +877,8 @@ describe Chef::Node::Attribute do
|
|
895
877
|
"one" => "six",
|
896
878
|
"snack" => "cookies",
|
897
879
|
},
|
898
|
-
{}
|
899
|
-
node
|
880
|
+
{}
|
900
881
|
)
|
901
|
-
allow(node).to receive(:attributes).and_return(@attributes)
|
902
882
|
end
|
903
883
|
|
904
884
|
it "should respond to has_value?" do
|
@@ -942,10 +922,8 @@ describe Chef::Node::Attribute do
|
|
942
922
|
"one" => "six",
|
943
923
|
"snack" => "cookies",
|
944
924
|
},
|
945
|
-
{}
|
946
|
-
node
|
925
|
+
{}
|
947
926
|
)
|
948
|
-
allow(node).to receive(:attributes).and_return(@attributes)
|
949
927
|
end
|
950
928
|
|
951
929
|
it "should respond to index" do
|
@@ -985,10 +963,8 @@ describe Chef::Node::Attribute do
|
|
985
963
|
"one" => "six",
|
986
964
|
"snack" => "cookies",
|
987
965
|
},
|
988
|
-
{}
|
989
|
-
node
|
966
|
+
{}
|
990
967
|
)
|
991
|
-
allow(node).to receive(:attributes).and_return(@attributes)
|
992
968
|
end
|
993
969
|
|
994
970
|
it "should respond to values" do
|
@@ -1023,10 +999,8 @@ describe Chef::Node::Attribute do
|
|
1023
999
|
"one" => "six",
|
1024
1000
|
"snack" => "cookies",
|
1025
1001
|
},
|
1026
|
-
{}
|
1027
|
-
node
|
1002
|
+
{}
|
1028
1003
|
)
|
1029
|
-
allow(node).to receive(:attributes).and_return(@attributes)
|
1030
1004
|
end
|
1031
1005
|
|
1032
1006
|
it "should respond to select" do
|
@@ -1075,11 +1049,10 @@ describe Chef::Node::Attribute do
|
|
1075
1049
|
"one" => "six",
|
1076
1050
|
"snack" => "cookies",
|
1077
1051
|
},
|
1078
|
-
{}
|
1079
|
-
node
|
1052
|
+
{}
|
1080
1053
|
)
|
1081
|
-
allow(node).to receive(:attributes).and_return(@attributes)
|
1082
1054
|
|
1055
|
+
@empty = Chef::Node::Attribute.new({}, {}, {}, {})
|
1083
1056
|
end
|
1084
1057
|
|
1085
1058
|
it "should respond to size" do
|
@@ -1091,9 +1064,7 @@ describe Chef::Node::Attribute do
|
|
1091
1064
|
end
|
1092
1065
|
|
1093
1066
|
it "should return 0 for an empty attribute" do
|
1094
|
-
@
|
1095
|
-
allow(node).to receive(:attributes).and_return(@attributes)
|
1096
|
-
expect(@attributes.size).to eq(0)
|
1067
|
+
expect(@empty.size).to eq(0)
|
1097
1068
|
end
|
1098
1069
|
|
1099
1070
|
it "should return the number of pairs" do
|
@@ -1121,9 +1092,8 @@ describe Chef::Node::Attribute do
|
|
1121
1092
|
|
1122
1093
|
describe "to_s" do
|
1123
1094
|
it "should output simple attributes" do
|
1124
|
-
|
1125
|
-
|
1126
|
-
expect(@attributes.to_s).to eq("{}")
|
1095
|
+
attributes = Chef::Node::Attribute.new(nil, nil, nil, nil)
|
1096
|
+
expect(attributes.to_s).to eq("{}")
|
1127
1097
|
end
|
1128
1098
|
|
1129
1099
|
it "should output merged attributes" do
|
@@ -1135,9 +1105,8 @@ describe Chef::Node::Attribute do
|
|
1135
1105
|
"b" => 3,
|
1136
1106
|
"c" => 4,
|
1137
1107
|
}
|
1138
|
-
|
1139
|
-
|
1140
|
-
expect(@attributes.to_s).to eq('{"b"=>3, "c"=>4, "a"=>1}')
|
1108
|
+
attributes = Chef::Node::Attribute.new(nil, default_hash, override_hash, nil)
|
1109
|
+
expect(attributes.to_s).to eq('{"a"=>1, "b"=>3, "c"=>4}')
|
1141
1110
|
end
|
1142
1111
|
end
|
1143
1112
|
|