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
|
#!/usr/bin/env ruby
#
# = Synopsis
#
# Run unit tests, usually with the goal of resolving some conflict
# between tests.
#
# = Usage
#
# test [-d|--debug] [-f|--files] [-h|--help] [-n method] [-v|--verbose] <file> [file] ...
#
# = Description
#
# This script is useful for running a specific subset of unit tests, especially
# when attempting to find a conflict between tests. By default, it will take
# the first argument you pass it and run that test or test directory with each
# test directory in turn, looking for a failure. If any tests fail, then
# the script will drill into that test directory, looking for the specific conflict.
#
# In this way, when you have deduced you have two conflicting unit tests (tests which
# pass in isolation but fail when run together), you can tell this script where
# the failure is and leave it alone to find the conflict.
#
# This script is different from the Rakefile because it will run all tests in
# a single process, whereas if you ask the Rakefile to run multiple tests, it will
# run them in separate processes thus making it impossible to find conflicts.
#
# = Examples
#
# Attempt to resolve a conflict between a single test suite that could be anywhere:
#
# ./test ral/providers/user.rb
#
# Determine whether two individual files conflict:
#
# ./test --files language/functions.rb ral/providers/provider.rb
#
# Run the same test, but only run a specific unit test:
#
# ./test -d -n test_search --files language/functions.rb ral/providers/provider.rb
#
# = Options
#
# debug::
# Enable full debugging.
#
# files::
# Specify exactly which files to test.
#
# help::
# Print this help message
#
# n::
# Specify a single unit test to run. You can still specify as many files
# as you want.
#
# verbose::
# Print extra information.
#
# = Example
#
# puppet -l /tmp/script.log script.pp
#
# = Author
#
# Luke Kanies
#
# = Copyright
#
# Copyright (c) 2005 Puppet Labs, LLC
# Licensed under the GNU Public License
require 'find'
require 'getoptlong'
include Find
result = GetoptLong.new(
[ "--debug", "-d", GetoptLong::NO_ARGUMENT ],
[ "--verbose", "-v", GetoptLong::NO_ARGUMENT ],
[ "-n", GetoptLong::REQUIRED_ARGUMENT ],
[ "--files", "-f", GetoptLong::NO_ARGUMENT ],
[ "--help", "-h", GetoptLong::NO_ARGUMENT ]
)
usage = "USAGE: %s [--help] suite" % $0
$options = {}
keep = []
result.each { |opt,arg|
case opt
when "--verbose"
$options[:verbose] = true
when "--files"
$options[:files] = true
when "--debug"
$options[:debug] = true
$options[:verbose] = true
when "--help"
puts usage
exit
else
keep << opt
keep << arg if arg
end
}
def dirs
Dir.glob("*").find_all { |d| FileTest.directory?(d) }.reject { |d|
["lib", "data"].include?(d)
}
end
def rake(*args)
print "trying %s..." % args.join(" ")
output = %x{rake %s} % args.join(" ")
if $?.exitstatus == 0
puts "succeeded"
return true
else
puts "failed"
return false
end
end
def resolve(dir)
dirs = dirs()
# If the passed dir is a subdir or file, put the basedir last
if dir.include?(File::SEPARATOR)
basedir = dir.split(File::SEPARATOR)[0]
if dirs.include?(basedir)
dirs.delete(basedir)
dirs << basedir
end
end
failed = nil
dirs.each do |d|
next if d == dir
unless run([d, dir])
failed = d
break
end
end
puts "%s failed" % failed
files = ruby_files(failed)
files.each do |file|
unless run([file, dir])
puts file
exit(0)
end
end
exit(1)
end
def ruby_files(dir)
files = []
# First collect the entire file list.
begin
find(dir) { |f| files << f if f =~ /\.rb$/ }
rescue => detail
puts "could not find on %s: %s" % [dir.inspect, detail]
end
files
end
def run(files, flags = nil)
args = %w{ruby}
args << "-Ilib:../lib"
args << "lib/rake/puppet_test_loader.rb"
if flags
args += flags
end
args += ARGV
print files.join(" ") + "... "
$stdout.flush
files.each do |file|
case File.stat(file).ftype
when "file"; args << file
when "directory"; args += ruby_files(file)
else
$stderr.puts "Skipping %s; can't handle %s" %
[file, File.stat(file).ftype]
end
end
args = args.join(" ")
if $options[:verbose]
p args
end
output = %x{#{args} 2>&1}
if $options[:debug]
print output
end
if $?.exitstatus == 0
puts "succeeded"
return true
else
puts "failed"
puts output
return false
end
end
if $options[:files]
run(ARGV, keep)
else
dir = ARGV.shift
unless dir
$stderr.puts usage
exit(1)
end
resolve(dir)
end
#
#
#files = []
#
#args.each do |test|
# if FileTest.directory?(test)
# files += ruby_files(test)
# end
#end
## Now load all of our files.
#files.each do |file|
# load file unless file =~ /^-/
#end
#
#runner = Test::Unit::AutoRunner.new(false)
#runner.process_args
#runner.run
|