chef 12.0.1 → 12.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +1 -1
- data/lib/chef/digester.rb +1 -0
- data/lib/chef/dsl/recipe.rb +2 -1
- data/lib/chef/exceptions.rb +5 -0
- data/lib/chef/knife.rb +7 -0
- data/lib/chef/knife/cookbook_site_install.rb +34 -10
- data/lib/chef/provider/link.rb +1 -1
- data/lib/chef/provider/package/apt.rb +2 -2
- data/lib/chef/provider/package/homebrew.rb +11 -2
- data/lib/chef/provider/package/windows/msi.rb +2 -0
- data/lib/chef/provider/subversion.rb +3 -3
- data/lib/chef/resource.rb +23 -91
- data/lib/chef/resource/homebrew_package.rb +2 -1
- data/lib/chef/resource/resource_notification.rb +109 -0
- data/lib/chef/resource_collection/resource_set.rb +8 -8
- data/lib/chef/run_context.rb +4 -4
- data/lib/chef/version.rb +1 -1
- data/lib/chef/whitelist.rb +3 -1
- data/lib/chef/win32/api/file.rb +17 -3
- data/spec/functional/notifications_spec.rb +169 -0
- data/spec/functional/resource/link_spec.rb +31 -32
- data/spec/support/platform_helpers.rb +5 -2
- data/spec/unit/knife/cookbook_site_install_spec.rb +157 -116
- data/spec/unit/knife_spec.rb +108 -78
- data/spec/unit/mixin/shell_out_spec.rb +39 -40
- data/spec/unit/node_spec.rb +34 -0
- data/spec/unit/provider/link_spec.rb +5 -5
- data/spec/unit/provider/package/apt_spec.rb +264 -257
- data/spec/unit/provider/package/homebrew_spec.rb +26 -0
- data/spec/unit/provider/package/windows/msi_spec.rb +18 -3
- data/spec/unit/provider/subversion_spec.rb +5 -5
- data/spec/unit/provider_resolver_spec.rb +2 -2
- data/spec/unit/recipe_spec.rb +1 -0
- data/spec/unit/resource/apt_package_spec.rb +3 -5
- data/spec/unit/resource/resource_notification_spec.rb +170 -0
- data/spec/unit/resource_spec.rb +0 -151
- data/spec/unit/run_context_spec.rb +94 -55
- metadata +5 -2
@@ -44,7 +44,7 @@ class Chef
|
|
44
44
|
is_chef_resource!(resource)
|
45
45
|
resource_type ||= resource.resource_name
|
46
46
|
instance_name ||= resource.name
|
47
|
-
key =
|
47
|
+
key = create_key(resource_type, instance_name)
|
48
48
|
@resources_by_key[key] = resource
|
49
49
|
end
|
50
50
|
|
@@ -53,7 +53,7 @@ class Chef
|
|
53
53
|
when key.kind_of?(String)
|
54
54
|
lookup_by = key
|
55
55
|
when key.kind_of?(Chef::Resource)
|
56
|
-
lookup_by =
|
56
|
+
lookup_by = create_key(key.resource_name, key.name)
|
57
57
|
else
|
58
58
|
raise ArgumentError, "Must pass a Chef::Resource or String to lookup"
|
59
59
|
end
|
@@ -128,18 +128,18 @@ class Chef
|
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
131
|
-
|
131
|
+
private
|
132
|
+
|
133
|
+
def create_key(resource_type, instance_name)
|
132
134
|
"#{resource_type}[#{instance_name}]"
|
133
135
|
end
|
134
136
|
|
135
|
-
private
|
136
|
-
|
137
137
|
def find_resource_by_hash(arg)
|
138
138
|
results = Array.new
|
139
139
|
arg.each do |resource_type, name_list|
|
140
140
|
instance_names = name_list.kind_of?(Array) ? name_list : [ name_list ]
|
141
141
|
instance_names.each do |instance_name|
|
142
|
-
results << lookup(
|
142
|
+
results << lookup(create_key(resource_type, instance_name))
|
143
143
|
end
|
144
144
|
end
|
145
145
|
return results
|
@@ -153,12 +153,12 @@ class Chef
|
|
153
153
|
arg =~ /^.+\[(.+)\]$/
|
154
154
|
resource_list = $1
|
155
155
|
resource_list.split(",").each do |instance_name|
|
156
|
-
results << lookup(
|
156
|
+
results << lookup(create_key(resource_type, instance_name))
|
157
157
|
end
|
158
158
|
when SINGLE_RESOURCE_MATCH
|
159
159
|
resource_type = $1
|
160
160
|
name = $2
|
161
|
-
results << lookup(
|
161
|
+
results << lookup(create_key(resource_type, name))
|
162
162
|
else
|
163
163
|
raise ArgumentError, "Bad string format #{arg}, you must have a string like resource_type[name]!"
|
164
164
|
end
|
data/lib/chef/run_context.rb
CHANGED
@@ -100,7 +100,7 @@ class Chef
|
|
100
100
|
if nr.instance_of?(Chef::Resource)
|
101
101
|
@immediate_notification_collection[nr.name] << notification
|
102
102
|
else
|
103
|
-
@immediate_notification_collection[nr.
|
103
|
+
@immediate_notification_collection[nr.declared_key] << notification
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
@@ -111,7 +111,7 @@ class Chef
|
|
111
111
|
if nr.instance_of?(Chef::Resource)
|
112
112
|
@delayed_notification_collection[nr.name] << notification
|
113
113
|
else
|
114
|
-
@delayed_notification_collection[nr.
|
114
|
+
@delayed_notification_collection[nr.declared_key] << notification
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
@@ -119,7 +119,7 @@ class Chef
|
|
119
119
|
if resource.instance_of?(Chef::Resource)
|
120
120
|
return @immediate_notification_collection[resource.name]
|
121
121
|
else
|
122
|
-
return @immediate_notification_collection[resource.
|
122
|
+
return @immediate_notification_collection[resource.declared_key]
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
@@ -127,7 +127,7 @@ class Chef
|
|
127
127
|
if resource.instance_of?(Chef::Resource)
|
128
128
|
return @delayed_notification_collection[resource.name]
|
129
129
|
else
|
130
|
-
return @delayed_notification_collection[resource.
|
130
|
+
return @delayed_notification_collection[resource.declared_key]
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
data/lib/chef/version.rb
CHANGED
data/lib/chef/whitelist.rb
CHANGED
@@ -57,7 +57,9 @@ class Chef
|
|
57
57
|
all_data = all_data[part]
|
58
58
|
end
|
59
59
|
|
60
|
-
|
60
|
+
# Note: You can't do all_data[parts[-1]] here because the value
|
61
|
+
# may be false-y
|
62
|
+
unless all_data.key?(parts[-1])
|
61
63
|
Chef::Log.warn("Could not find whitelist attribute #{item}.")
|
62
64
|
return nil
|
63
65
|
end
|
data/lib/chef/win32/api/file.rb
CHANGED
@@ -457,11 +457,25 @@ BOOL WINAPI DeviceIoControl(
|
|
457
457
|
# takes the given path pre-pends "\\?\" and
|
458
458
|
# UTF-16LE encodes it. Used to prepare paths
|
459
459
|
# to be passed to the *W vesion of WinAPI File
|
460
|
-
# functions
|
460
|
+
# functions.
|
461
|
+
# This function is used by the "Link" resources where we need
|
462
|
+
# preserve relative paths because symbolic links can actually
|
463
|
+
# point to a relative path (relative to the link itself).
|
461
464
|
def encode_path(path)
|
465
|
+
(path_prepender << path.gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR)).to_wstring
|
466
|
+
end
|
467
|
+
|
468
|
+
# Expands the path, prepends "\\?\" and UTF-16LE encodes it.
|
469
|
+
# This function is used by the "File" resources where we need
|
470
|
+
# convert relative paths to fully qualified paths.
|
471
|
+
def canonical_encode_path(path)
|
462
472
|
Chef::Util::PathHelper.canonical_path(path).to_wstring
|
463
473
|
end
|
464
474
|
|
475
|
+
def path_prepender
|
476
|
+
"\\\\?\\"
|
477
|
+
end
|
478
|
+
|
465
479
|
# retrieves a file search handle and passes it
|
466
480
|
# to +&block+ along with the find_data. also
|
467
481
|
# ensures the handle is closed on exit of the block
|
@@ -474,7 +488,7 @@ BOOL WINAPI DeviceIoControl(
|
|
474
488
|
# broader fix to map all the paths starting with "/" to
|
475
489
|
# SYSTEM_DRIVE on windows.
|
476
490
|
path = ::File.expand_path(path) if path.start_with? "/"
|
477
|
-
path =
|
491
|
+
path = canonical_encode_path(path)
|
478
492
|
find_data = WIN32_FIND_DATA.new
|
479
493
|
handle = FindFirstFileW(path, find_data)
|
480
494
|
if handle == INVALID_HANDLE_VALUE
|
@@ -491,7 +505,7 @@ BOOL WINAPI DeviceIoControl(
|
|
491
505
|
# ensures the handle is closed on exit of the block
|
492
506
|
def file_handle(path, &block)
|
493
507
|
begin
|
494
|
-
path =
|
508
|
+
path = canonical_encode_path(path)
|
495
509
|
handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ,
|
496
510
|
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, nil)
|
497
511
|
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'chef/recipe'
|
3
|
+
|
4
|
+
|
5
|
+
# The goal of these tests is to make sure that loading resources from a file creates the necessary notifications.
|
6
|
+
# Then once converge has started, both immediate and delayed notifications are called as the resources are converged.
|
7
|
+
# We want to do this WITHOUT actually converging any resources - we don't want to take time changing the system,
|
8
|
+
# we just want to make sure the run_context, the notification DSL and the converge hooks are working together
|
9
|
+
# to perform notifications.
|
10
|
+
|
11
|
+
# This test is extremely fragile since it mocks MANY different systems at once - any of them changes, this test
|
12
|
+
# breaks
|
13
|
+
describe "Notifications" do
|
14
|
+
|
15
|
+
# We always pretend we are on OSx because that has a specific provider (HomebrewProvider) so it
|
16
|
+
# tests the translation from Provider => HomebrewProvider
|
17
|
+
let(:node) {
|
18
|
+
n = Chef::Node.new
|
19
|
+
n.override[:os] = "darwin"
|
20
|
+
n
|
21
|
+
}
|
22
|
+
let(:cookbook_collection) { double("Chef::CookbookCollection").as_null_object }
|
23
|
+
let(:events) { double("Chef::EventDispatch::Dispatcher").as_null_object }
|
24
|
+
let(:run_context) { Chef::RunContext.new(node, cookbook_collection, events) }
|
25
|
+
let(:recipe) { Chef::Recipe.new("notif", "test", run_context) }
|
26
|
+
let(:runner) { Chef::Runner.new(run_context) }
|
27
|
+
|
28
|
+
before do
|
29
|
+
# By default, every provider will do nothing
|
30
|
+
p = Chef::Provider.new(nil, run_context)
|
31
|
+
allow_any_instance_of(Chef::Resource).to receive(:provider_for_action).and_return(p)
|
32
|
+
allow(p).to receive(:run_action)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should subscribe from one resource to another" do
|
36
|
+
log_resource = recipe.declare_resource(:log, "subscribed-log") do
|
37
|
+
message "This is a log message"
|
38
|
+
action :nothing
|
39
|
+
subscribes :write, "package[vim]", :immediately
|
40
|
+
end
|
41
|
+
|
42
|
+
package_resource = recipe.declare_resource(:package, "vim") do
|
43
|
+
action :install
|
44
|
+
end
|
45
|
+
|
46
|
+
expect(log_resource).to receive(:run_action).with(:nothing, nil, nil).and_call_original
|
47
|
+
|
48
|
+
expect(package_resource).to receive(:run_action).with(:install, nil, nil).and_call_original
|
49
|
+
update_action(package_resource)
|
50
|
+
|
51
|
+
expect(log_resource).to receive(:run_action).with(:write, :immediate, package_resource).and_call_original
|
52
|
+
|
53
|
+
runner.converge
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should notify from one resource to another immediately" do
|
57
|
+
log_resource = recipe.declare_resource(:log, "log") do
|
58
|
+
message "This is a log message"
|
59
|
+
action :write
|
60
|
+
notifies :install, "package[vim]", :immediately
|
61
|
+
end
|
62
|
+
|
63
|
+
package_resource = recipe.declare_resource(:package, "vim") do
|
64
|
+
action :nothing
|
65
|
+
end
|
66
|
+
|
67
|
+
expect(log_resource).to receive(:run_action).with(:write, nil, nil).and_call_original
|
68
|
+
update_action(log_resource)
|
69
|
+
|
70
|
+
expect(package_resource).to receive(:run_action).with(:install, :immediate, log_resource).ordered.and_call_original
|
71
|
+
|
72
|
+
expect(package_resource).to receive(:run_action).with(:nothing, nil, nil).ordered.and_call_original
|
73
|
+
|
74
|
+
runner.converge
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should notify from one resource to another delayed" do
|
78
|
+
log_resource = recipe.declare_resource(:log, "log") do
|
79
|
+
message "This is a log message"
|
80
|
+
action :write
|
81
|
+
notifies :install, "package[vim]", :delayed
|
82
|
+
end
|
83
|
+
|
84
|
+
package_resource = recipe.declare_resource(:package, "vim") do
|
85
|
+
action :nothing
|
86
|
+
end
|
87
|
+
|
88
|
+
expect(log_resource).to receive(:run_action).with(:write, nil, nil).and_call_original
|
89
|
+
update_action(log_resource)
|
90
|
+
|
91
|
+
expect(package_resource).to receive(:run_action).with(:nothing, nil, nil).ordered.and_call_original
|
92
|
+
|
93
|
+
expect(package_resource).to receive(:run_action).with(:install, :delayed, nil).ordered.and_call_original
|
94
|
+
|
95
|
+
runner.converge
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "when one resource is defined lazily" do
|
99
|
+
|
100
|
+
it "subscribes to a resource defined in a ruby block" do
|
101
|
+
r = recipe
|
102
|
+
t = self
|
103
|
+
ruby_block = recipe.declare_resource(:ruby_block, "rblock") do
|
104
|
+
block do
|
105
|
+
log_resource = r.declare_resource(:log, "log") do
|
106
|
+
message "This is a log message"
|
107
|
+
action :write
|
108
|
+
end
|
109
|
+
t.expect(log_resource).to t.receive(:run_action).with(:write, nil, nil).and_call_original
|
110
|
+
t.update_action(log_resource)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
package_resource = recipe.declare_resource(:package, "vim") do
|
115
|
+
action :nothing
|
116
|
+
subscribes :install, "log[log]", :delayed
|
117
|
+
end
|
118
|
+
|
119
|
+
# RubyBlock needs to be able to run for our lazy examples to work - and it alone cannot affect the system
|
120
|
+
expect(ruby_block).to receive(:provider_for_action).and_call_original
|
121
|
+
|
122
|
+
expect(package_resource).to receive(:run_action).with(:nothing, nil, nil).ordered.and_call_original
|
123
|
+
|
124
|
+
expect(package_resource).to receive(:run_action).with(:install, :delayed, nil).ordered.and_call_original
|
125
|
+
|
126
|
+
runner.converge
|
127
|
+
end
|
128
|
+
|
129
|
+
it "notifies from inside a ruby_block to a resource defined outside" do
|
130
|
+
r = recipe
|
131
|
+
t = self
|
132
|
+
ruby_block = recipe.declare_resource(:ruby_block, "rblock") do
|
133
|
+
block do
|
134
|
+
log_resource = r.declare_resource(:log, "log") do
|
135
|
+
message "This is a log message"
|
136
|
+
action :write
|
137
|
+
notifies :install, "package[vim]", :immediately
|
138
|
+
end
|
139
|
+
t.expect(log_resource).to t.receive(:run_action).with(:write, nil, nil).and_call_original
|
140
|
+
t.update_action(log_resource)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
package_resource = recipe.declare_resource(:package, "vim") do
|
145
|
+
action :nothing
|
146
|
+
end
|
147
|
+
|
148
|
+
# RubyBlock needs to be able to run for our lazy examples to work - and it alone cannot affect the system
|
149
|
+
expect(ruby_block).to receive(:provider_for_action).and_call_original
|
150
|
+
|
151
|
+
expect(package_resource).to receive(:run_action).with(:install, :immediate, instance_of(Chef::Resource::Log)).ordered.and_call_original
|
152
|
+
|
153
|
+
expect(package_resource).to receive(:run_action).with(:nothing, nil, nil).ordered.and_call_original
|
154
|
+
|
155
|
+
runner.converge
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
# Mocks having the provider run successfully and update the resource
|
161
|
+
def update_action(resource)
|
162
|
+
p = Chef::Provider.new(resource, run_context)
|
163
|
+
expect(resource).to receive(:provider_for_action).and_return(p)
|
164
|
+
expect(p).to receive(:run_action) {
|
165
|
+
resource.updated_by_last_action(true)
|
166
|
+
}
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
@@ -72,8 +72,8 @@ describe Chef::Resource::Link do
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
-
def
|
76
|
-
|
75
|
+
def canonicalize(path)
|
76
|
+
windows? ? path.gsub('/', '\\') : path
|
77
77
|
end
|
78
78
|
|
79
79
|
def symlink(a, b)
|
@@ -179,8 +179,8 @@ describe Chef::Resource::Link do
|
|
179
179
|
end
|
180
180
|
|
181
181
|
it 'links to the target file' do
|
182
|
-
symlink?(target_file).
|
183
|
-
|
182
|
+
expect(symlink?(target_file)).to be_true
|
183
|
+
expect(readlink(target_file)).to eq(canonicalize(to))
|
184
184
|
end
|
185
185
|
it 'marks the resource updated' do
|
186
186
|
resource.should be_updated
|
@@ -200,8 +200,8 @@ describe Chef::Resource::Link do
|
|
200
200
|
end
|
201
201
|
|
202
202
|
it 'leaves the file linked' do
|
203
|
-
symlink?(target_file).
|
204
|
-
|
203
|
+
expect(symlink?(target_file)).to be_true
|
204
|
+
expect(readlink(target_file)).to eq(canonicalize(to))
|
205
205
|
end
|
206
206
|
it 'does not mark the resource updated' do
|
207
207
|
resource.should_not be_updated
|
@@ -278,8 +278,8 @@ describe Chef::Resource::Link do
|
|
278
278
|
context 'pointing at the target' do
|
279
279
|
before(:each) do
|
280
280
|
symlink(to, target_file)
|
281
|
-
symlink?(target_file).
|
282
|
-
|
281
|
+
expect(symlink?(target_file)).to be_true
|
282
|
+
expect(readlink(target_file)).to eq(canonicalize(to))
|
283
283
|
end
|
284
284
|
include_context 'create symbolic link is noop'
|
285
285
|
include_context 'delete succeeds'
|
@@ -293,8 +293,8 @@ describe Chef::Resource::Link do
|
|
293
293
|
@other_target = File.join(test_file_dir, make_tmpname('other_spec'))
|
294
294
|
File.open(@other_target, 'w') { |file| file.write('eek') }
|
295
295
|
symlink(@other_target, target_file)
|
296
|
-
symlink?(target_file).
|
297
|
-
|
296
|
+
expect(symlink?(target_file)).to be_true
|
297
|
+
expect(readlink(target_file)).to eq(canonicalize(@other_target))
|
298
298
|
end
|
299
299
|
after(:each) do
|
300
300
|
File.delete(@other_target)
|
@@ -310,8 +310,8 @@ describe Chef::Resource::Link do
|
|
310
310
|
before(:each) do
|
311
311
|
nonexistent = File.join(test_file_dir, make_tmpname('nonexistent_spec'))
|
312
312
|
symlink(nonexistent, target_file)
|
313
|
-
symlink?(target_file).
|
314
|
-
|
313
|
+
expect(symlink?(target_file)).to be_true
|
314
|
+
expect(readlink(target_file)).to eq(canonicalize(nonexistent))
|
315
315
|
end
|
316
316
|
include_context 'create symbolic link succeeds'
|
317
317
|
include_context 'delete succeeds'
|
@@ -392,8 +392,8 @@ describe Chef::Resource::Link do
|
|
392
392
|
@other_target = File.join(test_file_dir, make_tmpname("other_spec"))
|
393
393
|
File.open(@other_target, "w") { |file| file.write("eek") }
|
394
394
|
symlink(@other_target, to)
|
395
|
-
symlink?(to).
|
396
|
-
|
395
|
+
expect(symlink?(to)).to be_true
|
396
|
+
expect(readlink(to)).to eq(canonicalize(@other_target))
|
397
397
|
end
|
398
398
|
after(:each) do
|
399
399
|
File.delete(@other_target)
|
@@ -407,8 +407,8 @@ describe Chef::Resource::Link do
|
|
407
407
|
before(:each) do
|
408
408
|
@other_target = File.join(test_file_dir, make_tmpname("other_spec"))
|
409
409
|
symlink(@other_target, to)
|
410
|
-
symlink?(to).
|
411
|
-
|
410
|
+
expect(symlink?(to)).to be_true
|
411
|
+
expect(readlink(to)).to eq(canonicalize(@other_target))
|
412
412
|
end
|
413
413
|
context 'and the link does not yet exist' do
|
414
414
|
include_context 'create symbolic link succeeds'
|
@@ -440,8 +440,8 @@ describe Chef::Resource::Link do
|
|
440
440
|
context 'when the link already exists and points at the target' do
|
441
441
|
before(:each) do
|
442
442
|
symlink(to, target_file)
|
443
|
-
symlink?(target_file).
|
444
|
-
|
443
|
+
expect(symlink?(target_file)).to be_true
|
444
|
+
expect(readlink(target_file)).to eq(canonicalize(to))
|
445
445
|
end
|
446
446
|
include_context 'create symbolic link is noop'
|
447
447
|
include_context 'delete succeeds'
|
@@ -449,8 +449,8 @@ describe Chef::Resource::Link do
|
|
449
449
|
context 'when the link already exists and points at the target with an absolute path' do
|
450
450
|
before(:each) do
|
451
451
|
symlink(absolute_to, target_file)
|
452
|
-
symlink?(target_file).
|
453
|
-
|
452
|
+
expect(symlink?(target_file)).to be_true
|
453
|
+
expect(readlink(target_file)).to eq(canonicalize(absolute_to))
|
454
454
|
end
|
455
455
|
include_context 'create symbolic link succeeds'
|
456
456
|
include_context 'delete succeeds'
|
@@ -477,8 +477,8 @@ describe Chef::Resource::Link do
|
|
477
477
|
context "and the link already exists and is a symbolic link pointing at the same file" do
|
478
478
|
before(:each) do
|
479
479
|
symlink(to, target_file)
|
480
|
-
symlink?(target_file).
|
481
|
-
|
480
|
+
expect(symlink?(target_file)).to be_true
|
481
|
+
expect(readlink(target_file)).to eq(canonicalize(to))
|
482
482
|
end
|
483
483
|
include_context 'create hard link succeeds'
|
484
484
|
it_behaves_like 'delete errors out'
|
@@ -551,8 +551,8 @@ describe Chef::Resource::Link do
|
|
551
551
|
@other_target = File.join(test_file_dir, make_tmpname("other_spec"))
|
552
552
|
File.open(@other_target, "w") { |file| file.write("eek") }
|
553
553
|
symlink(@other_target, to)
|
554
|
-
symlink?(to).
|
555
|
-
|
554
|
+
expect(symlink?(to)).to be_true
|
555
|
+
expect(readlink(to)).to eq(canonicalize(@other_target))
|
556
556
|
end
|
557
557
|
after(:each) do
|
558
558
|
File.delete(@other_target)
|
@@ -562,10 +562,9 @@ describe Chef::Resource::Link do
|
|
562
562
|
resource.run_action(:create)
|
563
563
|
File.exists?(target_file).should be_true
|
564
564
|
# OS X gets angry about this sort of link. Bug in OS X, IMO.
|
565
|
-
pending('OS X/FreeBSD/AIX symlink? and readlink working on hard links to symlinks'
|
566
|
-
|
567
|
-
|
568
|
-
end
|
565
|
+
pending('OS X/FreeBSD/AIX symlink? and readlink working on hard links to symlinks') if (os_x? or freebsd? or aix?)
|
566
|
+
expect(symlink?(target_file)).to be_true
|
567
|
+
expect(readlink(target_file)).to eq(canonicalize(@other_target))
|
569
568
|
end
|
570
569
|
include_context 'delete is noop'
|
571
570
|
end
|
@@ -574,8 +573,8 @@ describe Chef::Resource::Link do
|
|
574
573
|
before(:each) do
|
575
574
|
@other_target = File.join(test_file_dir, make_tmpname("other_spec"))
|
576
575
|
symlink(@other_target, to)
|
577
|
-
symlink?(to).
|
578
|
-
|
576
|
+
expect(symlink?(to)).to be_true
|
577
|
+
expect(readlink(to)).to eq(canonicalize(@other_target))
|
579
578
|
end
|
580
579
|
context 'and the link does not yet exist' do
|
581
580
|
it 'links to the target file' do
|
@@ -587,8 +586,8 @@ describe Chef::Resource::Link do
|
|
587
586
|
else
|
588
587
|
File.exists?(target_file).should be_false
|
589
588
|
end
|
590
|
-
symlink?(target_file).
|
591
|
-
|
589
|
+
expect(symlink?(target_file)).to be_true
|
590
|
+
expect(readlink(target_file)).to eq(canonicalize(@other_target))
|
592
591
|
end
|
593
592
|
end
|
594
593
|
include_context 'delete is noop'
|