summaryrefslogtreecommitdiffstats
path: root/test/test
blob: 98c504a8da7f4942795e1682fb16b350b6bef2fa (plain)
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 Reductive 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