rake 10.0.0.beta.2 → 10.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rake might be problematic. Click here for more details.
- data/Rakefile +1 -0
- data/doc/release_notes/rake-10.0.0.rdoc +2 -2
- data/lib/rake/application.rb +24 -15
- data/lib/rake/backtrace.rb +2 -1
- data/lib/rake/ext/string.rb +2 -1
- data/lib/rake/ext/time.rb +2 -1
- data/lib/rake/private_reader.rb +20 -0
- data/lib/rake/promise.rb +99 -0
- data/lib/rake/task.rb +1 -1
- data/lib/rake/thread_history_display.rb +6 -3
- data/lib/rake/thread_pool.rb +42 -76
- data/lib/rake/version.rb +0 -2
- data/test/test_private_reader.rb +42 -0
- data/test/test_rake_application_options.rb +2 -1
- data/test/test_rake_backtrace.rb +22 -8
- data/test/test_rake_functional.rb +1 -1
- data/test/test_rake_thread_pool.rb +1 -24
- data/test/test_thread_history_display.rb +14 -14
- metadata +6 -3
data/Rakefile
CHANGED
@@ -152,8 +152,8 @@ GitHub:: git://github.com/jimweirich/rake.git
|
|
152
152
|
|
153
153
|
== Thanks
|
154
154
|
|
155
|
-
As usual, it was input from users that drove a
|
156
|
-
following people
|
155
|
+
As usual, it was input from users that drove a lot of these changes. The
|
156
|
+
following people contributed patches, made suggestions or made
|
157
157
|
otherwise helpful comments. Thanks to ...
|
158
158
|
|
159
159
|
* Aaron Patterson
|
data/lib/rake/application.rb
CHANGED
@@ -58,7 +58,7 @@ module Rake
|
|
58
58
|
#
|
59
59
|
# * Initialize the command line options (+init+).
|
60
60
|
# * Define the tasks (+load_rakefile+).
|
61
|
-
# * Run the top level tasks (+
|
61
|
+
# * Run the top level tasks (+top_level+).
|
62
62
|
#
|
63
63
|
# If you wish to build a custom rake command, you should call
|
64
64
|
# +init+ on your application. Then define any tasks. Finally,
|
@@ -67,15 +67,7 @@ module Rake
|
|
67
67
|
standard_exception_handling do
|
68
68
|
init
|
69
69
|
load_rakefile
|
70
|
-
thread_pool.gather_history if options.job_stats == :history
|
71
70
|
top_level
|
72
|
-
thread_pool.join
|
73
|
-
if options.job_stats
|
74
|
-
stats = thread_pool.statistics
|
75
|
-
puts "Maximum active threads: #{stats[:max_active_threads]}"
|
76
|
-
puts "Total threads in play: #{stats[:total_threads_in_play]}"
|
77
|
-
end
|
78
|
-
ThreadHistoryDisplay.new(thread_pool.history).show if options.job_stats == :history
|
79
71
|
end
|
80
72
|
end
|
81
73
|
|
@@ -97,13 +89,30 @@ module Rake
|
|
97
89
|
|
98
90
|
# Run the top level tasks of a Rake application.
|
99
91
|
def top_level
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
92
|
+
run_with_threads do
|
93
|
+
if options.show_tasks
|
94
|
+
display_tasks_and_comments
|
95
|
+
elsif options.show_prereqs
|
96
|
+
display_prerequisites
|
97
|
+
else
|
98
|
+
top_level_tasks.each { |task_name| invoke_task(task_name) }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Run the given block with the thread startup and shutdown.
|
104
|
+
def run_with_threads
|
105
|
+
thread_pool.gather_history if options.job_stats == :history
|
106
|
+
|
107
|
+
yield
|
108
|
+
|
109
|
+
thread_pool.join
|
110
|
+
if options.job_stats
|
111
|
+
stats = thread_pool.statistics
|
112
|
+
puts "Maximum active threads: #{stats[:max_active_threads]}"
|
113
|
+
puts "Total threads in play: #{stats[:total_threads_in_play]}"
|
106
114
|
end
|
115
|
+
ThreadHistoryDisplay.new(thread_pool.history).show if options.job_stats == :history
|
107
116
|
end
|
108
117
|
|
109
118
|
# Add a loader to handle imported files ending in the extension
|
data/lib/rake/backtrace.rb
CHANGED
@@ -5,8 +5,9 @@ module Rake
|
|
5
5
|
keys.grep(/(prefix|libdir)/)) + [
|
6
6
|
File.join(File.dirname(__FILE__), ".."),
|
7
7
|
].map { |f| Regexp.quote(File.expand_path(f)) }
|
8
|
+
SUPPRESSED_PATHS.reject! { |s| s.nil? || s =~ /^ *$/ }
|
8
9
|
|
9
|
-
SUPPRESS_PATTERN = %r!(\A#{SUPPRESSED_PATHS.join('|')}|bin/rake:\d+)!
|
10
|
+
SUPPRESS_PATTERN = %r!(\A#{SUPPRESSED_PATHS.join('|')}|bin/rake:\d+)!i
|
10
11
|
|
11
12
|
def self.collapse(backtrace)
|
12
13
|
pattern = Rake.application.options.suppress_backtrace_pattern ||
|
data/lib/rake/ext/string.rb
CHANGED
@@ -4,6 +4,7 @@ require 'rake/ext/core'
|
|
4
4
|
# Rake extension methods for String.
|
5
5
|
#
|
6
6
|
class String
|
7
|
+
|
7
8
|
rake_extension("ext") do
|
8
9
|
# Replace the file extension with +newext+. If there is no extension on
|
9
10
|
# the string, append the new extension to the end. If the new extension
|
@@ -163,5 +164,5 @@ class String
|
|
163
164
|
result
|
164
165
|
end
|
165
166
|
end
|
166
|
-
end # class String
|
167
167
|
|
168
|
+
end
|
data/lib/rake/ext/time.rb
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Rake
|
2
|
+
|
3
|
+
# Include PrivateReader to use +private_reader+.
|
4
|
+
module PrivateReader # :nodoc: all
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
|
12
|
+
# Declare a list of private accessors
|
13
|
+
def private_reader(*names)
|
14
|
+
attr_reader(*names)
|
15
|
+
private(*names)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
data/lib/rake/promise.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
module Rake
|
2
|
+
|
3
|
+
# A Promise object represents a promise to do work (a chore) in the
|
4
|
+
# future. The promise is created with a block and a list of
|
5
|
+
# arguments for the block. Calling value will return the value of
|
6
|
+
# the promised chore.
|
7
|
+
#
|
8
|
+
# Used by ThreadPool.
|
9
|
+
#
|
10
|
+
class Promise # :nodoc: all
|
11
|
+
NOT_SET = Object.new.freeze # :nodoc:
|
12
|
+
|
13
|
+
attr_accessor :recorder
|
14
|
+
|
15
|
+
# Create a promise to do the chore specified by the block.
|
16
|
+
def initialize(args, &block)
|
17
|
+
@mutex = Mutex.new
|
18
|
+
@result = NOT_SET
|
19
|
+
@error = NOT_SET
|
20
|
+
@args = args.collect { |a| begin; a.dup; rescue; a; end }
|
21
|
+
@block = block
|
22
|
+
end
|
23
|
+
|
24
|
+
# Return the value of this promise.
|
25
|
+
#
|
26
|
+
# If the promised chore is not yet complete, then do the work
|
27
|
+
# synchronously. We will wait.
|
28
|
+
def value
|
29
|
+
unless complete?
|
30
|
+
stat :sleeping_on, :item_id => object_id
|
31
|
+
@mutex.synchronize do
|
32
|
+
stat :has_lock_on, :item_id => object_id
|
33
|
+
chore
|
34
|
+
stat :releasing_lock_on, :item_id => object_id
|
35
|
+
end
|
36
|
+
end
|
37
|
+
error? ? raise(@error) : @result
|
38
|
+
end
|
39
|
+
|
40
|
+
# If no one else is working this promise, go ahead and do the chore.
|
41
|
+
def work
|
42
|
+
stat :attempting_lock_on, :item_id => object_id
|
43
|
+
if @mutex.try_lock
|
44
|
+
stat :has_lock_on, :item_id => object_id
|
45
|
+
chore
|
46
|
+
stat :releasing_lock_on, :item_id => object_id
|
47
|
+
@mutex.unlock
|
48
|
+
else
|
49
|
+
stat :bailed_on, :item_id => object_id
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# Perform the chore promised
|
56
|
+
def chore
|
57
|
+
if complete?
|
58
|
+
stat :found_completed, :item_id => object_id
|
59
|
+
return
|
60
|
+
end
|
61
|
+
stat :will_execute, :item_id => object_id
|
62
|
+
begin
|
63
|
+
@result = @block.call(*@args)
|
64
|
+
rescue Exception => e
|
65
|
+
@error = e
|
66
|
+
end
|
67
|
+
stat :did_execute, :item_id => object_id
|
68
|
+
discard
|
69
|
+
end
|
70
|
+
|
71
|
+
# Do we have a result for the promise
|
72
|
+
def result?
|
73
|
+
! @result.equal?(NOT_SET)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Did the promise throw an error
|
77
|
+
def error?
|
78
|
+
! @error.equal?(NOT_SET)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Are we done with the promise
|
82
|
+
def complete?
|
83
|
+
result? || error?
|
84
|
+
end
|
85
|
+
|
86
|
+
# free up these items for the GC
|
87
|
+
def discard
|
88
|
+
@args = nil
|
89
|
+
@block = nil
|
90
|
+
end
|
91
|
+
|
92
|
+
# Record execution statistics if there is a recorder
|
93
|
+
def stat(*args)
|
94
|
+
@recorder.call(*args) if @recorder
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
data/lib/rake/task.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
+
require 'rake/private_reader'
|
2
|
+
|
1
3
|
module Rake
|
2
4
|
|
3
5
|
class ThreadHistoryDisplay # :nodoc: all
|
4
|
-
|
5
|
-
|
6
|
+
include Rake::PrivateReader
|
7
|
+
|
8
|
+
private_reader :stats, :items, :threads
|
6
9
|
|
7
10
|
def initialize(stats)
|
8
11
|
@stats = stats
|
@@ -13,7 +16,7 @@ module Rake
|
|
13
16
|
def show
|
14
17
|
puts "Job History:"
|
15
18
|
stats.each do |stat|
|
16
|
-
stat[:data] ||=
|
19
|
+
stat[:data] ||= {}
|
17
20
|
rename(stat, :thread, threads)
|
18
21
|
rename(stat[:data], :item_id, items)
|
19
22
|
rename(stat[:data], :new_thread, threads)
|
data/lib/rake/thread_pool.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'thread'
|
2
2
|
require 'set'
|
3
3
|
|
4
|
+
require 'rake/promise'
|
5
|
+
|
4
6
|
module Rake
|
5
7
|
|
6
8
|
class ThreadPool # :nodoc: all
|
@@ -28,63 +30,12 @@ module Rake
|
|
28
30
|
# pool. Sending <tt>#value</tt> to the object will sleep the
|
29
31
|
# current thread until the future is finished and will return the
|
30
32
|
# result (or raise an exception thrown from the future)
|
31
|
-
def future(*args
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
promise_mutex = Mutex.new
|
36
|
-
promise_result = promise_error = NOT_SET
|
37
|
-
|
38
|
-
# (promise code builds on Ben Lavender's public-domain 'promise' gem)
|
39
|
-
promise = lambda do
|
40
|
-
# return immediately if the future has been executed
|
41
|
-
unless promise_result.equal?(NOT_SET) && promise_error.equal?(NOT_SET)
|
42
|
-
return promise_error.equal?(NOT_SET) ? promise_result : raise(promise_error)
|
43
|
-
end
|
44
|
-
|
45
|
-
# try to get the lock and execute the promise, otherwise, sleep.
|
46
|
-
if promise_mutex.try_lock
|
47
|
-
if promise_result.equal?(NOT_SET) && promise_error.equal?(NOT_SET)
|
48
|
-
#execute the promise
|
49
|
-
begin
|
50
|
-
promise_result = block.call(*local_args)
|
51
|
-
rescue Exception => e
|
52
|
-
promise_error = e
|
53
|
-
end
|
54
|
-
block = local_args = nil # GC can now clean these up
|
55
|
-
end
|
56
|
-
promise_mutex.unlock
|
57
|
-
else
|
58
|
-
# Even if we didn't get the lock, we need to sleep until the
|
59
|
-
# promise has finished executing. If, however, the current
|
60
|
-
# thread is part of the thread pool, we need to free up a
|
61
|
-
# new thread in the pool so there will always be a thread
|
62
|
-
# doing work.
|
63
|
-
|
64
|
-
wait_for_promise = lambda {
|
65
|
-
stat :waiting, item_id: promise.object_id
|
66
|
-
promise_mutex.synchronize {}
|
67
|
-
stat :continue, item_id: promise.object_id
|
68
|
-
}
|
69
|
-
|
70
|
-
unless @threads_mon.synchronize { @threads.include? Thread.current }
|
71
|
-
wait_for_promise.call
|
72
|
-
else
|
73
|
-
@threads_mon.synchronize { @max_active_threads += 1 }
|
74
|
-
start_thread
|
75
|
-
wait_for_promise.call
|
76
|
-
@threads_mon.synchronize { @max_active_threads -= 1 }
|
77
|
-
end
|
78
|
-
end
|
79
|
-
promise_error.equal?(NOT_SET) ? promise_result : raise(promise_error)
|
80
|
-
end
|
81
|
-
|
82
|
-
def promise.value
|
83
|
-
call
|
84
|
-
end
|
33
|
+
def future(*args, &block)
|
34
|
+
promise = Promise.new(args, &block)
|
35
|
+
promise.recorder = lambda { |*stats| stat(*stats) }
|
85
36
|
|
86
37
|
@queue.enq promise
|
87
|
-
stat :
|
38
|
+
stat :queued, :item_id => promise.object_id
|
88
39
|
start_thread
|
89
40
|
promise
|
90
41
|
end
|
@@ -93,14 +44,18 @@ module Rake
|
|
93
44
|
def join
|
94
45
|
@threads_mon.synchronize do
|
95
46
|
begin
|
96
|
-
|
47
|
+
stat :joining
|
48
|
+
@join_cond.wait unless @threads.empty?
|
49
|
+
stat :joined
|
97
50
|
rescue Exception => e
|
51
|
+
stat :joined
|
98
52
|
$stderr.puts e
|
99
53
|
$stderr.print "Queue contains #{@queue.size} items. Thread pool contains #{@threads.count} threads\n"
|
100
54
|
$stderr.print "Current Thread #{Thread.current} status = #{Thread.current.status}\n"
|
101
55
|
$stderr.puts e.backtrace.join("\n")
|
102
56
|
@threads.each do |t|
|
103
57
|
$stderr.print "Thread #{t} status = #{t.status}\n"
|
58
|
+
# 1.8 doesn't support Thread#backtrace
|
104
59
|
$stderr.puts t.backtrace.join("\n") if t.respond_to? :backtrace
|
105
60
|
end
|
106
61
|
raise e
|
@@ -119,45 +74,58 @@ module Rake
|
|
119
74
|
# (see #gather_history). Best to call this when the job is
|
120
75
|
# complete (i.e. after ThreadPool#join is called).
|
121
76
|
def history # :nodoc:
|
122
|
-
@history_mon.synchronize { @history.dup }
|
77
|
+
@history_mon.synchronize { @history.dup }.
|
78
|
+
sort_by { |i| i[:time] }.
|
79
|
+
each { |i| i[:time] -= @history_start_time }
|
123
80
|
end
|
124
81
|
|
125
82
|
# Return a hash of always collected statistics for the thread pool.
|
126
83
|
def statistics # :nodoc:
|
127
84
|
{
|
128
|
-
total_threads_in_play
|
129
|
-
max_active_threads
|
85
|
+
:total_threads_in_play => @total_threads_in_play,
|
86
|
+
:max_active_threads => @max_active_threads,
|
130
87
|
}
|
131
88
|
end
|
132
89
|
|
133
90
|
private
|
134
91
|
|
92
|
+
# processes one item on the queue. Returns true if there was an
|
93
|
+
# item to process, false if there was no item
|
94
|
+
def process_queue_item #:nodoc:
|
95
|
+
return false if @queue.empty?
|
96
|
+
|
97
|
+
# Even though we just asked if the queue was empty, it
|
98
|
+
# still could have had an item which by this statement
|
99
|
+
# is now gone. For this reason we pass true to Queue#deq
|
100
|
+
# because we will sleep indefinitely if it is empty.
|
101
|
+
promise = @queue.deq(true)
|
102
|
+
stat :dequeued, :item_id => promise.object_id
|
103
|
+
promise.work
|
104
|
+
return true
|
105
|
+
|
106
|
+
rescue ThreadError # this means the queue is empty
|
107
|
+
false
|
108
|
+
end
|
109
|
+
|
135
110
|
def start_thread # :nodoc:
|
136
111
|
@threads_mon.synchronize do
|
137
112
|
next unless @threads.count < @max_active_threads
|
138
113
|
|
139
114
|
t = Thread.new do
|
140
115
|
begin
|
141
|
-
while @threads.count <= @max_active_threads
|
142
|
-
|
143
|
-
# still could have had an item which by this statement
|
144
|
-
# is now gone. For this reason we pass true to Queue#deq
|
145
|
-
# because we will sleep indefinitely if it is empty.
|
146
|
-
block = @queue.deq(true)
|
147
|
-
stat :item_dequeued, item_id: block.object_id
|
148
|
-
block.call
|
116
|
+
while @threads.count <= @max_active_threads
|
117
|
+
break unless process_queue_item
|
149
118
|
end
|
150
|
-
rescue ThreadError # this means the queue is empty
|
151
119
|
ensure
|
152
120
|
@threads_mon.synchronize do
|
153
121
|
@threads.delete Thread.current
|
154
|
-
stat :
|
122
|
+
stat :ended, :thread_count => @threads.count
|
155
123
|
@join_cond.broadcast if @threads.empty?
|
156
124
|
end
|
157
125
|
end
|
158
126
|
end
|
159
127
|
@threads << t
|
160
|
-
stat :
|
128
|
+
stat :spawned, :new_thread => t.object_id, :thread_count => @threads.count
|
161
129
|
@total_threads_in_play = @threads.count if @threads.count > @total_threads_in_play
|
162
130
|
end
|
163
131
|
end
|
@@ -165,10 +133,10 @@ module Rake
|
|
165
133
|
def stat(event, data=nil) # :nodoc:
|
166
134
|
return if @history_start_time.nil?
|
167
135
|
info = {
|
168
|
-
event
|
169
|
-
data
|
170
|
-
time
|
171
|
-
thread
|
136
|
+
:event => event,
|
137
|
+
:data => data,
|
138
|
+
:time => Time.now,
|
139
|
+
:thread => Thread.current.object_id,
|
172
140
|
}
|
173
141
|
@history_mon.synchronize { @history << info }
|
174
142
|
end
|
@@ -182,8 +150,6 @@ module Rake
|
|
182
150
|
def __threads__ # :nodoc:
|
183
151
|
@threads.dup
|
184
152
|
end
|
185
|
-
|
186
|
-
NOT_SET = Object.new.freeze # :nodoc:
|
187
153
|
end
|
188
154
|
|
189
155
|
end
|
data/lib/rake/version.rb
CHANGED
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.expand_path('../helper', __FILE__)
|
2
|
+
require 'rake/private_reader'
|
3
|
+
|
4
|
+
class TestPrivateAttrs < Rake::TestCase
|
5
|
+
|
6
|
+
class Sample
|
7
|
+
include Rake::PrivateReader
|
8
|
+
|
9
|
+
private_reader :reader, :a
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@reader = :RVALUE
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_reader
|
16
|
+
reader
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def setup
|
22
|
+
super
|
23
|
+
@sample = Sample.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_private_reader_is_private
|
27
|
+
assert_private do @sample.reader end
|
28
|
+
assert_private do @sample.a end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_private_reader_returns_data
|
32
|
+
assert_equal :RVALUE, @sample.get_reader
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def assert_private
|
38
|
+
ex = assert_raises(NoMethodError) do yield end
|
39
|
+
assert_match(/private/, ex.message)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -145,7 +145,8 @@ class TestRakeApplicationOptions < Rake::TestCase
|
|
145
145
|
end
|
146
146
|
|
147
147
|
def test_rakelib
|
148
|
-
|
148
|
+
dirs = %w(A B C).join(File::PATH_SEPARATOR)
|
149
|
+
flags(['--rakelibdir', dirs], ["--rakelibdir=#{dirs}"], ['-R', dirs], ["-R#{dirs}"]) do |opts|
|
149
150
|
assert_equal ['A', 'B', 'C'], opts.rakelib
|
150
151
|
end
|
151
152
|
end
|
data/test/test_rake_backtrace.rb
CHANGED
@@ -24,8 +24,8 @@ class TestRakeBacktrace < Rake::TestCase
|
|
24
24
|
|
25
25
|
assert_equal "rake aborted!", lines[0]
|
26
26
|
assert_equal "foooo!", lines[1]
|
27
|
-
|
28
|
-
|
27
|
+
assert_something_matches %r!\A#{Regexp.quote Dir.pwd}/Rakefile:3!i, lines
|
28
|
+
assert_something_matches %r!\ATasks:!, lines
|
29
29
|
end
|
30
30
|
|
31
31
|
def test_multi_collapse
|
@@ -42,9 +42,9 @@ class TestRakeBacktrace < Rake::TestCase
|
|
42
42
|
|
43
43
|
assert_equal "rake aborted!", lines[0]
|
44
44
|
assert_equal "barrr!", lines[1]
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
assert_something_matches %r!\A#{Regexp.quote Dir.pwd}/Rakefile:6!i, lines
|
46
|
+
assert_something_matches %r!\A#{Regexp.quote Dir.pwd}/Rakefile:3!i, lines
|
47
|
+
assert_something_matches %r!\ATasks:!, lines
|
48
48
|
end
|
49
49
|
|
50
50
|
def test_suppress_option
|
@@ -57,11 +57,25 @@ class TestRakeBacktrace < Rake::TestCase
|
|
57
57
|
lines = rake("baz").split("\n")
|
58
58
|
assert_equal "rake aborted!", lines[0]
|
59
59
|
assert_equal "bazzz!", lines[1]
|
60
|
-
|
60
|
+
assert_something_matches %r!Rakefile!i, lines
|
61
61
|
|
62
|
-
lines = rake("--suppress-backtrace", "
|
62
|
+
lines = rake("--suppress-backtrace", ".ak.file", "baz").split("\n")
|
63
63
|
assert_equal "rake aborted!", lines[0]
|
64
64
|
assert_equal "bazzz!", lines[1]
|
65
|
-
refute_match %r!Rakefile
|
65
|
+
refute_match %r!Rakefile!i, lines[2]
|
66
66
|
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
# Assert that the pattern matches at least one line in +lines+.
|
71
|
+
def assert_something_matches(pattern, lines)
|
72
|
+
lines.each do |ln|
|
73
|
+
if pattern =~ ln
|
74
|
+
assert_match pattern, ln
|
75
|
+
return
|
76
|
+
end
|
77
|
+
end
|
78
|
+
flunk "expected #{pattern.inspect} to match something in:\n #{lines.join("\n ")}"
|
79
|
+
end
|
80
|
+
|
67
81
|
end
|
@@ -435,7 +435,7 @@ class TestRakeFunctional < Rake::TestCase
|
|
435
435
|
assert_match(/ATEST/, @out)
|
436
436
|
refute_match(/BTEST/, @out)
|
437
437
|
else
|
438
|
-
|
438
|
+
skip "Signal detect seems broken on this system"
|
439
439
|
end
|
440
440
|
end
|
441
441
|
|
@@ -69,7 +69,7 @@ class TestRakeTestThreadPool < Rake::TestCase
|
|
69
69
|
}
|
70
70
|
|
71
71
|
pool.join
|
72
|
-
assert_equal true, pool.__send__(:__queue__).empty
|
72
|
+
assert_equal true, pool.__send__(:__queue__).empty?, "queue should be empty"
|
73
73
|
end
|
74
74
|
|
75
75
|
# test that throwing an exception way down in the blocks propagates
|
@@ -88,29 +88,6 @@ class TestRakeTestThreadPool < Rake::TestCase
|
|
88
88
|
|
89
89
|
end
|
90
90
|
|
91
|
-
def test_pool_always_has_max_threads_doing_work
|
92
|
-
# here we need to test that even if some threads are halted, there
|
93
|
-
# are always at least max_threads that are not sleeping.
|
94
|
-
pool = ThreadPool.new(2)
|
95
|
-
initial_sleep_time = 0.2
|
96
|
-
future1 = pool.future { sleep initial_sleep_time }
|
97
|
-
dependent_futures = 5.times.collect { pool.future{ future1.value } }
|
98
|
-
future2 = pool.future { sleep initial_sleep_time }
|
99
|
-
future3 = pool.future { sleep 0.01 }
|
100
|
-
|
101
|
-
sleep initial_sleep_time / 2.0 # wait for everything to queue up
|
102
|
-
|
103
|
-
# at this point, we should have 5 threads sleeping depending on future1, and
|
104
|
-
# two threads doing work on future1 and future 2.
|
105
|
-
assert_equal pool.__send__(:__threads__).count, 7
|
106
|
-
|
107
|
-
# future 3 is in the queue because there aren't enough active threads to work on it.
|
108
|
-
assert_equal pool.__send__(:__queue__).size, 1
|
109
|
-
|
110
|
-
[future1, dependent_futures, future2, future3].flatten.each { |f| f.value }
|
111
|
-
pool.join
|
112
|
-
end
|
113
|
-
|
114
91
|
def test_pool_prevents_deadlock
|
115
92
|
pool = ThreadPool.new(5)
|
116
93
|
|
@@ -18,7 +18,7 @@ class TestThreadHistoryDisplay < Rake::TestCase
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def test_item_queued
|
21
|
-
@stats << event(:item_queued, item_id
|
21
|
+
@stats << event(:item_queued, :item_id => 123)
|
22
22
|
out, _ = capture_io do
|
23
23
|
@display.show
|
24
24
|
end
|
@@ -26,7 +26,7 @@ class TestThreadHistoryDisplay < Rake::TestCase
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def test_item_dequeued
|
29
|
-
@stats << event(:item_dequeued, item_id
|
29
|
+
@stats << event(:item_dequeued, :item_id => 123)
|
30
30
|
out, _ = capture_io do
|
31
31
|
@display.show
|
32
32
|
end
|
@@ -34,8 +34,8 @@ class TestThreadHistoryDisplay < Rake::TestCase
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def test_multiple_items
|
37
|
-
@stats << event(:item_queued, item_id
|
38
|
-
@stats << event(:item_queued, item_id
|
37
|
+
@stats << event(:item_queued, :item_id => 123)
|
38
|
+
@stats << event(:item_queued, :item_id => 124)
|
39
39
|
out, _ = capture_io do
|
40
40
|
@display.show
|
41
41
|
end
|
@@ -44,7 +44,7 @@ class TestThreadHistoryDisplay < Rake::TestCase
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def test_waiting
|
47
|
-
@stats << event(:waiting, item_id
|
47
|
+
@stats << event(:waiting, :item_id => 123)
|
48
48
|
out, _ = capture_io do
|
49
49
|
@display.show
|
50
50
|
end
|
@@ -52,7 +52,7 @@ class TestThreadHistoryDisplay < Rake::TestCase
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def test_continue
|
55
|
-
@stats << event(:continue, item_id
|
55
|
+
@stats << event(:continue, :item_id => 123)
|
56
56
|
out, _ = capture_io do
|
57
57
|
@display.show
|
58
58
|
end
|
@@ -60,29 +60,29 @@ class TestThreadHistoryDisplay < Rake::TestCase
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def test_thread_deleted
|
63
|
-
@stats << event(:thread_deleted, deleted_thread
|
63
|
+
@stats << event(:thread_deleted, :deleted_thread => 123456, :thread_count => 12)
|
64
64
|
out, _ = capture_io do
|
65
65
|
@display.show
|
66
66
|
end
|
67
|
-
assert_match(/^ *1000000 +A +thread_deleted +deleted_thread:B +thread_count:12$/, out)
|
67
|
+
assert_match(/^ *1000000 +A +thread_deleted( +deleted_thread:B| +thread_count:12){2}$/, out)
|
68
68
|
end
|
69
69
|
|
70
70
|
def test_thread_created
|
71
|
-
@stats << event(:thread_created, new_thread
|
71
|
+
@stats << event(:thread_created, :new_thread => 123456, :thread_count => 13)
|
72
72
|
out, _ = capture_io do
|
73
73
|
@display.show
|
74
74
|
end
|
75
|
-
assert_match(/^ *1000000 +A +thread_created +new_thread:B +thread_count:13$/, out)
|
75
|
+
assert_match(/^ *1000000 +A +thread_created( +new_thread:B| +thread_count:13){2}$/, out)
|
76
76
|
end
|
77
77
|
|
78
78
|
private
|
79
79
|
|
80
80
|
def event(type, data={})
|
81
81
|
result = {
|
82
|
-
event
|
83
|
-
time
|
84
|
-
data
|
85
|
-
thread
|
82
|
+
:event => type,
|
83
|
+
:time => @time / 1_000_000.0,
|
84
|
+
:data => data,
|
85
|
+
:thread => Thread.current.object_id
|
86
86
|
}
|
87
87
|
@time += 1
|
88
88
|
result
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rake
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 10.0.0
|
5
|
-
prerelease:
|
4
|
+
version: 10.0.0
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Jim Weirich
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
@@ -106,6 +106,8 @@ files:
|
|
106
106
|
- lib/rake/packagetask.rb
|
107
107
|
- lib/rake/pathmap.rb
|
108
108
|
- lib/rake/phony.rb
|
109
|
+
- lib/rake/private_reader.rb
|
110
|
+
- lib/rake/promise.rb
|
109
111
|
- lib/rake/pseudo_status.rb
|
110
112
|
- lib/rake/rake_module.rb
|
111
113
|
- lib/rake/rake_test_loader.rb
|
@@ -124,6 +126,7 @@ files:
|
|
124
126
|
- lib/rake/win32.rb
|
125
127
|
- test/file_creation.rb
|
126
128
|
- test/helper.rb
|
129
|
+
- test/test_private_reader.rb
|
127
130
|
- test/test_rake.rb
|
128
131
|
- test/test_rake_application.rb
|
129
132
|
- test/test_rake_application_options.rb
|