chef 13.7.16 → 13.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright:: Copyright 2016-2017, Chef Software Inc.
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, path = 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__ = 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
- __root__.reset_cache(*path) if !__root__.nil? && __root__.respond_to?(:reset_cache) && !path.nil?
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)
@@ -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
- tempfile = Chef::FileContentManagement::Tempfile.new(@new_resource).tempfile
64
+ orig_tempfile = Chef::FileContentManagement::Tempfile.new(@new_resource).tempfile
65
65
  if want_progress?
66
- tempfile = http.streaming_request_with_progress(uri, headers, tempfile) do |size, total|
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, tempfile)
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
@@ -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) if ( !idle_time.nil? && ([:minute, :hourly, :daily, :weekly, :monthly].include? frequency)) || (idle_time.nil? || !(idle_time > 0 && idle_time <= 999)) && !([:minute, :hourly, :daily, :weekly, :monthly].include? 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
- unless [:on_idle].include?(frequency)
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
@@ -23,7 +23,7 @@ require "chef/version_string"
23
23
 
24
24
  class Chef
25
25
  CHEF_ROOT = File.expand_path("../..", __FILE__)
26
- VERSION = Chef::VersionString.new("13.7.16")
26
+ VERSION = Chef::VersionString.new("13.8.0")
27
27
  end
28
28
 
29
29
  #
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright:: Copyright 2014-2016, Chef Software, Inc.
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
- context "for windows version less than 10", windows_lt_10: true do
26
- it "runs a powershell command and collects stdout" do
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
- context "for windows version less than 10", windows_lt_10: true do
44
- it "runs a powershell command and collects stdout" do
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
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Adam Jacob (<adam@chef.io>)
3
- # Copyright:: Copyright 2008-2017, Chef Software Inc.
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
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: AJ Christensen (<aj@junglist.gen.nz>)
3
- # Copyright:: Copyright 2008-2016, Chef Software Inc.
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] = "aj"
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] = "staff"
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 aj:staff")
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("aj", "staff")
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 aj")
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("aj")
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("aj", 20)
142
- Chef::Daemon._change_privilege("aj")
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("aj")
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("aj")
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("aj")
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-2017, Chef Software Inc.
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
- node = Chef::Node.new
68
- node.default[:test] = { "a" => 1, "b" => 1.2, "c" => false, "d" => true }
69
- expect(test_class.translate_type(node[:test])).to eq("@{a=1;b=1.2;c=$false;d=$true}")
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
- node = Chef::Node.new
74
- node.default[:test] = [ true, false ]
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({}, {}, {}, {}, node) }.not_to raise_error
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
- @attributes = Chef::Node::Attribute.new({ :normal => true }, { :default => true }, { :override => true }, { :automatic => true }, node)
189
- allow(node).to receive(:attributes).and_return(@attributes)
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({}, {}, {}, {}, node)
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
- allow(node).to receive(:attributes).and_return(@attributes)
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
- @attributes = Chef::Node::Attribute.new({}, {}, {}, {}, node)
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
- @attributes = Chef::Node::Attribute.new({}, {}, {}, {}, node)
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
- @attributes = Chef::Node::Attribute.new(nil, nil, nil, nil, node)
1125
- allow(node).to receive(:attributes).and_return(@attributes)
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
- @attributes = Chef::Node::Attribute.new(nil, default_hash, override_hash, nil, node)
1139
- allow(node).to receive(:attributes).and_return(@attributes)
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