forked from puppetlabs/puppet
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgenerate_spec.rb
179 lines (149 loc) · 6.53 KB
/
generate_spec.rb
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
require 'spec_helper'
def with_executor
return yield unless Puppet::Util::Platform.jruby?
begin
Puppet::Util::ExecutionStub.set do |command, options, stdin, stdout, stderr|
require 'open3'
# simulate what puppetserver does
Dir.chdir(options[:cwd]) do
out, err, _status = Open3.capture3(*command)
stdout.write(out)
stderr.write(err)
# execution api expects stdout to be returned
out
end
end
yield
ensure
Puppet::Util::ExecutionStub.reset
end
end
describe "the generate function" do
include PuppetSpec::Files
let :node do Puppet::Node.new('localhost') end
let :compiler do Puppet::Parser::Compiler.new(node) end
let :scope do Puppet::Parser::Scope.new(compiler) end
let :cwd do tmpdir('generate') end
it "should exist" do
expect(Puppet::Parser::Functions.function("generate")).to eq("function_generate")
end
it "accept a fully-qualified path as a command" do
command = File.expand_path('/command/foo')
expect(Puppet::Util::Execution).to receive(:execute).with([command], anything).and_return("yay")
expect(scope.function_generate([command])).to eq("yay")
end
it "should not accept a relative path as a command" do
expect { scope.function_generate(["command"]) }.to raise_error(Puppet::ParseError)
end
it "should not accept a command containing illegal characters" do
expect { scope.function_generate([File.expand_path('/##/command')]) }.to raise_error(Puppet::ParseError)
end
it "should not accept a command containing spaces" do
expect { scope.function_generate([File.expand_path('/com mand')]) }.to raise_error(Puppet::ParseError)
end
it "should not accept a command containing '..'", :unless => RUBY_PLATFORM == 'java' do
command = File.expand_path("/command/../")
expect { scope.function_generate([command]) }.to raise_error(Puppet::ParseError)
end
it "should execute the generate script with the correct working directory" do
command = File.expand_path("/usr/local/command")
expect(Puppet::Util::Execution).to receive(:execute).with([command], hash_including(cwd: %r{/usr/local})).and_return("yay")
scope.function_generate([command])
end
it "should execute the generate script with failonfail" do
command = File.expand_path("/usr/local/command")
expect(Puppet::Util::Execution).to receive(:execute).with([command], hash_including(failonfail: true)).and_return("yay")
scope.function_generate([command])
end
it "should execute the generate script with combine" do
command = File.expand_path("/usr/local/command")
expect(Puppet::Util::Execution).to receive(:execute).with([command], hash_including(combine: true)).and_return("yay")
scope.function_generate([command])
end
it "executes a command in a working directory" do
if Puppet::Util::Platform.windows?
command = File.join(cwd, 'echo.bat')
File.write(command, <<~END)
@echo off
echo %CD%
END
expect(scope.function_generate([command]).chomp).to match(cwd.gsub('/', '\\'))
else
with_executor do
command = File.join(cwd, 'echo.sh')
File.write(command, <<~END)
#!/bin/sh
echo $PWD
END
Puppet::FileSystem.chmod(0755, command)
expect(scope.function_generate([command]).chomp).to eq(cwd)
end
end
end
describe "on Windows", :if => Puppet::Util::Platform.windows? do
it "should accept the tilde in the path" do
command = "C:/DOCUME~1/ADMINI~1/foo.bat"
expect(Puppet::Util::Execution).to receive(:execute).with([command], hash_including(cwd: "C:/DOCUME~1/ADMINI~1")).and_return("yay")
expect(scope.function_generate([command])).to eq('yay')
end
it "should accept lower-case drive letters" do
command = 'd:/command/foo'
expect(Puppet::Util::Execution).to receive(:execute).with([command], hash_including(cwd: "d:/command")).and_return("yay")
expect(scope.function_generate([command])).to eq('yay')
end
it "should accept upper-case drive letters" do
command = 'D:/command/foo'
expect(Puppet::Util::Execution).to receive(:execute).with([command], hash_including(cwd: "D:/command")).and_return("yay")
expect(scope.function_generate([command])).to eq('yay')
end
it "should accept forward and backslashes in the path" do
command = 'D:\command/foo\bar'
expect(Puppet::Util::Execution).to receive(:execute).with([command], hash_including(cwd: 'D:\command/foo')).and_return("yay")
expect(scope.function_generate([command])).to eq('yay')
end
it "should reject colons when not part of the drive letter" do
expect { scope.function_generate(['C:/com:mand']) }.to raise_error(Puppet::ParseError)
end
it "should reject root drives" do
expect { scope.function_generate(['C:/']) }.to raise_error(Puppet::ParseError)
end
end
describe "on POSIX", :if => Puppet.features.posix? do
it "should reject backslashes" do
expect { scope.function_generate(['/com\\mand']) }.to raise_error(Puppet::ParseError)
end
it "should accept plus and dash" do
command = "/var/folders/9z/9zXImgchH8CZJh6SgiqS2U+++TM/-Tmp-/foo"
expect(Puppet::Util::Execution).to receive(:execute).with([command], hash_including(cwd: '/var/folders/9z/9zXImgchH8CZJh6SgiqS2U+++TM/-Tmp-')).and_return("yay")
expect(scope.function_generate([command])).to eq('yay')
end
end
describe "function_generate", :unless => RUBY_PLATFORM == 'java' do
let :command do
script_containing('function_generate',
:windows => '@echo off' + "\n" + 'echo a-%1 b-%2',
:posix => '#!/bin/sh' + "\n" + 'echo a-$1 b-$2')
end
after :each do
File.delete(command) if Puppet::FileSystem.exist?(command)
end
it "returns the output as a String" do
expect(scope.function_generate([command]).class).to eq(String)
end
it "should call generator with no arguments" do
expect(scope.function_generate([command])).to eq("a- b-\n")
end
it "should call generator with one argument" do
expect(scope.function_generate([command, 'one'])).to eq("a-one b-\n")
end
it "should call generator with wo arguments" do
expect(scope.function_generate([command, 'one', 'two'])).to eq("a-one b-two\n")
end
it "should fail if generator is not absolute" do
expect { scope.function_generate(['boo']) }.to raise_error(Puppet::ParseError)
end
it "should fail if generator fails" do
expect { scope.function_generate(['/boo']) }.to raise_error(Puppet::ParseError)
end
end
end