scout-gear 6.0.0 → 7.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 6.0.0
1
+ 7.1.0
@@ -84,6 +84,14 @@ class DoneProcessing < Exception
84
84
  end
85
85
  end
86
86
 
87
+ class WorkerException < ScoutException
88
+ attr_accessor :exception, :pid
89
+ def initialize(exception, pid)
90
+ @exception = exception
91
+ @pid = pid
92
+ end
93
+ end
94
+
87
95
 
88
96
  #class OpenGzipError < StandardError; end
89
97
  #
@@ -143,13 +143,14 @@ module Log
143
143
  CONCEPT_COLORS = IndiferentHash.setup({
144
144
  :title => magenta,
145
145
  :path => blue,
146
- :input => blue,
146
+ :input => cyan,
147
147
  :value => green,
148
148
  :integer => green,
149
149
  :negative => red,
150
150
  :float => green,
151
151
  :waiting => yellow,
152
- :started => blue,
152
+ :started => cyan,
153
+ :start => cyan,
153
154
  :done => green,
154
155
  :error => red,
155
156
  })
@@ -166,10 +167,36 @@ module Log
166
167
  def self.color(color, str = nil, reset = false)
167
168
  return str.dup || "" if nocolor
168
169
 
170
+ if (color == :integer || color == :float) && Numeric === str
171
+ color = if str < 0
172
+ :red
173
+ elsif str > 1
174
+ :cyan
175
+ else
176
+ :green
177
+ end
178
+ end
179
+
180
+ if color == :status
181
+ color = case str.to_sym
182
+ when :done
183
+ :green
184
+ when :error, :aborted
185
+ :red
186
+ when :waiting, :queued
187
+ :yellow
188
+ when :started, :start, :streamming
189
+ :cyan
190
+ else
191
+ :cyan
192
+ end
193
+ end
194
+
169
195
  color = SEVERITY_COLOR[color] if Integer === color
170
196
  color = CONCEPT_COLORS[color] if CONCEPT_COLORS.include?(color)
171
197
  color = Term::ANSIColor.send(color) if Symbol === color and Term::ANSIColor.respond_to?(color)
172
198
 
199
+ str = str.to_s unless str.nil?
173
200
  return str if Symbol === color
174
201
  color_str = reset ? Term::ANSIColor.reset : ""
175
202
  color_str << color
@@ -28,6 +28,8 @@ module Log
28
28
  end
29
29
 
30
30
  def self.new_bar(max, options = {})
31
+ options, max = max, nil if Hash === max
32
+ max = options[:max] if max.nil?
31
33
  cleanup_bars
32
34
  BAR_MUTEX.synchronize do
33
35
  Log::LAST.replace "new_bar" if Log::LAST == "progress"
@@ -24,6 +24,8 @@ module Log
24
24
  IndiferentHash.process_options options, :depth, :desc, :file, :bytes, :frequency, :process, :callback,
25
25
  :depth => 0, :frequency => 2
26
26
 
27
+ max = nil if TrueClass === max
28
+
27
29
  @max = max
28
30
  @ticks = 0
29
31
  @frequency = frequency
data/lib/scout/log.rb CHANGED
@@ -206,7 +206,11 @@ module Log
206
206
  line = line.sub('`',"'")
207
207
  color = :green if line =~ /workflow/
208
208
  color = :blue if line =~ /scout-/
209
- Log.color color, line
209
+ if color
210
+ Log.color color, line
211
+ else
212
+ line
213
+ end
210
214
  end unless stack.nil?
211
215
  end
212
216
 
@@ -41,9 +41,7 @@ module Misc
41
41
 
42
42
  def self.digest(obj)
43
43
  str = Misc.digest_str(obj)
44
- hash = Digest::MD5.hexdigest(str)
45
- Log.debug "Digest #{hash} - #{str}"
46
- hash
44
+ Digest::MD5.hexdigest(str)
47
45
  end
48
46
 
49
47
  def self.file_md5(file)
@@ -31,13 +31,16 @@ module Open
31
31
  Thread.current.report_on_exception = false
32
32
  consume_stream(io, false, into, into_close)
33
33
  end
34
+
34
35
  io.threads.push(consumer_thread) if io.respond_to?(:threads)
36
+ Thread.pass until consumer_thread["name"]
37
+
35
38
  consumer_thread
36
39
  else
37
40
  if into
38
- Log.medium "Consuming stream #{Log.fingerprint io} -> #{Log.fingerprint into}"
41
+ Log.low "Consuming stream #{Log.fingerprint io} -> #{Log.fingerprint into}"
39
42
  else
40
- Log.medium "Consuming stream #{Log.fingerprint io}"
43
+ Log.low "Consuming stream #{Log.fingerprint io}"
41
44
  end
42
45
 
43
46
  begin
@@ -53,7 +56,6 @@ module Open
53
56
  into_close = false unless into.respond_to? :close
54
57
  io.sync = true
55
58
 
56
- Log.high "started consuming stream #{Log.fingerprint io}"
57
59
  begin
58
60
  while c = io.readpartial(BLOCK_SIZE)
59
61
  into << c if into
@@ -67,15 +69,14 @@ module Open
67
69
  into.close if into and into_close and not into.closed?
68
70
  block.call if block_given?
69
71
 
70
- Log.high "Done consuming stream #{Log.fingerprint io} into #{into_path || into}"
71
72
  c
72
73
  rescue Aborted
73
- Log.high "Consume stream Aborted #{Log.fingerprint io} into #{into_path || into}"
74
+ Log.low "Consume stream Aborted #{Log.fingerprint io} into #{into_path || into}"
74
75
  io.abort $! if io.respond_to? :abort
75
76
  into.close if into.respond_to?(:closed?) && ! into.closed?
76
77
  FileUtils.rm into_path if into_path and File.exist?(into_path)
77
78
  rescue Exception
78
- Log.high "Consume stream Exception reading #{Log.fingerprint io} into #{into_path || into} - #{$!.message}"
79
+ Log.low "Consume stream Exception reading #{Log.fingerprint io} into #{into_path || into} - #{$!.message}"
79
80
  exception = io.stream_exception || $!
80
81
  io.abort exception if io.respond_to? :abort
81
82
  into.close if into.respond_to?(:closed?) && ! into.closed?
@@ -145,12 +146,12 @@ module Open
145
146
 
146
147
  Open.notify_write(path)
147
148
  rescue Aborted
148
- Log.medium "Aborted sensible_write -- #{ Log.reset << Log.color(:blue, path) }"
149
+ Log.low "Aborted sensible_write -- #{ Log.reset << Log.color(:blue, path) }"
149
150
  content.abort if content.respond_to? :abort
150
151
  Open.rm path if File.exist? path
151
152
  rescue Exception
152
153
  exception = (AbortedStream === content and content.exception) ? content.exception : $!
153
- Log.medium "Exception in sensible_write: [#{Process.pid}] #{exception.message} -- #{ Log.color :blue, path }"
154
+ Log.low "Exception in sensible_write: [#{Process.pid}] #{exception.message} -- #{ Log.color :blue, path }"
154
155
  content.abort if content.respond_to? :abort
155
156
  Open.rm path if File.exist? path
156
157
  raise exception
@@ -219,16 +220,15 @@ module Open
219
220
 
220
221
  #parent_pid = Process.pid
221
222
  pid = Process.fork {
222
- purge_pipes(sin)
223
- sout.close
224
223
  begin
224
+ purge_pipes(sin)
225
+ sout.close
225
226
 
226
227
  yield sin
227
228
  sin.close if close and not sin.closed?
228
229
 
229
230
  rescue Exception
230
231
  Log.exception $!
231
- #Process.kill :INT, parent_pid
232
232
  Kernel.exit!(-1)
233
233
  end
234
234
  Kernel.exit! 0
@@ -242,18 +242,18 @@ module Open
242
242
  ConcurrentStream.setup sout, :pair => sin
243
243
 
244
244
  thread = Thread.new do
245
- Thread.current["name"] = "Pipe input #{Log.fingerprint sin} => #{Log.fingerprint sout}"
246
- Thread.current.report_on_exception = false
247
245
  begin
246
+ Thread.current.report_on_exception = false
247
+ Thread.current["name"] = "Pipe input #{Log.fingerprint sin} => #{Log.fingerprint sout}"
248
248
 
249
249
  yield sin
250
250
 
251
251
  sin.close if close and not sin.closed? and not sin.aborted?
252
252
  rescue Aborted
253
- Log.medium "Aborted open_pipe: #{$!.message}"
253
+ Log.low "Aborted open_pipe: #{$!.message}"
254
254
  raise $!
255
255
  rescue Exception
256
- Log.medium "Exception in open_pipe: #{$!.message}"
256
+ Log.low "Exception in open_pipe: #{$!.message}"
257
257
  begin
258
258
  sout.threads.delete(Thread.current)
259
259
  sout.pair = []
@@ -269,6 +269,7 @@ module Open
269
269
 
270
270
  sin.threads = [thread]
271
271
  sout.threads = [thread]
272
+ Thread.pass until thread["name"]
272
273
  end
273
274
 
274
275
  sout
@@ -287,8 +288,8 @@ module Open
287
288
 
288
289
  splitter_thread = Thread.new(Thread.current) do |parent|
289
290
  begin
290
- Thread.current["name"] = "Splitter #{Log.fingerprint stream}"
291
291
  Thread.current.report_on_exception = false
292
+ Thread.current["name"] = "Splitter #{Log.fingerprint stream}"
292
293
 
293
294
  skip = [false] * num
294
295
  begin
@@ -317,7 +318,7 @@ module Open
317
318
  out_pipes.each do |sout|
318
319
  sout.abort if sout.respond_to? :abort
319
320
  end
320
- Log.medium "Tee aborting #{Log.fingerprint stream}"
321
+ Log.low "Tee aborting #{Log.fingerprint stream}"
321
322
  raise $!
322
323
  rescue Exception
323
324
  begin
@@ -332,7 +333,7 @@ module Open
332
333
  in_pipes.each do |sin|
333
334
  sin.close unless sin.closed?
334
335
  end
335
- Log.medium "Tee exception #{Log.fingerprint stream}"
336
+ Log.low "Tee exception #{Log.fingerprint stream}"
336
337
  rescue
337
338
  Log.exception $!
338
339
  ensure
@@ -348,7 +349,7 @@ module Open
348
349
  out_pipes.each do |sout|
349
350
  ConcurrentStream.setup sout, :threads => splitter_thread, :filename => filename, :pair => stream
350
351
  end
351
- splitter_thread.wakeup until splitter_thread["name"]
352
+ Thread.pass until splitter_thread["name"]
352
353
 
353
354
  main_pipe = out_pipes.first
354
355
  main_pipe.autojoin = true
@@ -0,0 +1,144 @@
1
+ module TSV
2
+ def self.cast_value(value, cast)
3
+ if Array === value
4
+ value.collect{|e| cast_value(e, cast) }
5
+ else
6
+ value.send(cast)
7
+ end
8
+ end
9
+
10
+ def self.parse_line(line, type: :list, key: 0, positions: nil, sep: "\t", sep2: "|", cast: nil)
11
+ items = line.split(sep, -1)
12
+
13
+ if positions.nil? && key == 0
14
+ key = items.shift
15
+ elsif positions.nil?
16
+ key = items.delete(key)
17
+ else
18
+ key, items = items[key], items.values_at(*positions)
19
+ end
20
+
21
+ items = case type
22
+ when :list
23
+ items
24
+ when :single
25
+ items.first
26
+ when :flat
27
+ [items]
28
+ when :double
29
+ items.collect{|i| i.split(sep2, -1) }
30
+ end
31
+
32
+ key = key.partition(sep2).first if type == :double
33
+
34
+ if cast
35
+ items = cast_value(items, cast)
36
+ end
37
+
38
+ [key, items]
39
+ end
40
+
41
+ def self.parse_stream(stream, data: nil, merge: true, type: :list, fix: true, bar: false, first_line: nil, **kargs, &block)
42
+ begin
43
+ bar = Log::ProgressBar.new_bar(bar) if bar
44
+
45
+ data = {} if data.nil?
46
+ merge = false if type != :double
47
+ line = first_line || stream.gets
48
+ while line
49
+ begin
50
+ line.strip!
51
+ line = Misc.fixutf8(line) if fix
52
+ bar.tick if bar
53
+ key, items = parse_line(line, type: type, **kargs)
54
+
55
+ if block_given?
56
+ res = block.call(key, items)
57
+ data[key] = res unless res.nil?
58
+ next
59
+ end
60
+
61
+ if ! merge || ! data.include?(key)
62
+ data[key] = items
63
+ else
64
+ current = data[key]
65
+ if merge == :concat
66
+ items.each_with_index do |new,i|
67
+ next if new.empty?
68
+ current[i].concat(new)
69
+ end
70
+ else
71
+ merged = []
72
+ items.each_with_index do |new,i|
73
+ next if new.empty?
74
+ merged[i] = current[i] + new
75
+ end
76
+ data[key] = merged
77
+ end
78
+ end
79
+ ensure
80
+ line = stream.gets
81
+ end
82
+ end
83
+ data
84
+ ensure
85
+ Log::ProgressBar.remove_bar(bar) if bar
86
+ end
87
+ end
88
+
89
+ def self.parse_header(stream, fix: true, header_hash: '#', sep: "\n")
90
+ raise "Closed stream" if IO === stream && stream.closed?
91
+
92
+ options = {}
93
+ preamble = []
94
+
95
+ # Get line
96
+
97
+ #Thread.pass while IO.select([stream], nil, nil, 1).nil? if IO === stream
98
+ line = stream.gets
99
+ return {} if line.nil?
100
+ line = Misc.fixutf8 line.chomp if fix
101
+
102
+ # Process options line
103
+ if line and (String === header_hash && m = line.match(/^#{header_hash}: (.*)/))
104
+ options = IndiferentHash.string2hash m.captures.first.chomp
105
+ line = stream.gets
106
+ line = Misc.fixutf8 line.chomp if line && fix
107
+ end
108
+
109
+ # Determine separator
110
+ sep = options[:sep] if options[:sep]
111
+
112
+ # Process fields line
113
+ preamble << line if line
114
+ while line && (TrueClass === header_hash || (String === header_hash && line.start_with?(header_hash)))
115
+ fields = line.split(sep, -1)
116
+ key_field = fields.shift
117
+ key_field = key_field.sub(header_hash, '') if String === header_hash && ! header_hash.empty?
118
+
119
+ line = (header_hash != "" ? stream.gets : nil)
120
+ line = Misc.fixutf8 line.chomp if line
121
+ preamble << line if line
122
+ break if TrueClass === header_hash || header_hash == ""
123
+ end
124
+
125
+ preamble = preamble[0..-3] * "\n"
126
+
127
+ line ||= stream.gets
128
+
129
+ first_line = line
130
+
131
+ [options, key_field, fields, first_line, preamble]
132
+ end
133
+
134
+ def self.parse(stream, **kwargs)
135
+ options, key_field, fields, first_line, preamble = parse_header(stream)
136
+
137
+ options.each do |option,value|
138
+ option = option.to_sym
139
+ kwargs[option] = value unless kwargs.include?(option)
140
+ end
141
+ data = parse_stream(stream, first_line: first_line, **kwargs)
142
+ TSV.setup data, :key_field => key_field, :fields => fields
143
+ end
144
+ end
data/lib/scout/tsv.rb ADDED
@@ -0,0 +1,14 @@
1
+ require_relative 'meta_extension'
2
+ require_relative 'tsv/parser'
3
+
4
+ module TSV
5
+ extend MetaExtension
6
+ extension_attr :key_field, :fields
7
+
8
+ def self.open(file, options = {})
9
+ Open.open(file) do |f|
10
+ TSV.parse(f,**options)
11
+ end
12
+ end
13
+ end
14
+
@@ -1,16 +1,18 @@
1
1
  class WorkQueue
2
2
  class Worker
3
3
  attr_accessor :pid, :ignore_ouput
4
- def initialize
4
+ def initialize(ignore_ouput = false)
5
+ @ignore_output = ignore_ouput
5
6
  end
6
7
 
7
8
  def run
8
9
  @pid = Process.fork do
10
+ Log.debug "Worker start with #{Process.pid}"
9
11
  yield
10
12
  end
11
13
  end
12
14
 
13
- def process(input, output, &block)
15
+ def process(input, output = nil, &block)
14
16
  run do
15
17
  begin
16
18
  while obj = input.read
@@ -19,33 +21,36 @@ class WorkQueue
19
21
  raise obj
20
22
  end
21
23
  res = block.call obj
22
- output.write res unless ignore_ouput || res == :ignore
24
+ output.write res unless output.nil? || ignore_ouput || res == :ignore
23
25
  end
24
26
  rescue DoneProcessing
25
- Log.log "Worker #{Process.pid} done"
27
+ rescue Interrupt
26
28
  rescue Exception
27
- Log.exception $!
29
+ output.write WorkerException.new($!, Process.pid)
28
30
  exit -1
29
31
  end
30
32
  end
31
33
  end
32
34
 
35
+ def abort
36
+ begin
37
+ Log.log "Aborting worker #{@pid}"
38
+ Process.kill "INT", @pid
39
+ rescue Errno::ECHILD
40
+ end
41
+ end
42
+
33
43
  def join
34
44
  Log.log "Joining worker #{@pid}"
35
45
  Process.waitpid @pid
36
46
  end
37
47
 
38
- def exit(status)
39
- Log.log "Worker #{@pid} exited with status #{Log.color(:green, status)}"
40
- end
41
-
42
48
  def self.join(workers)
43
49
  workers = [workers] unless Array === workers
44
50
  begin
45
51
  while pid = Process.wait
46
52
  status = $?
47
- worker = workers.select{|w| w.pid == pid }.first
48
- worker.exit status.exitstatus if worker
53
+ worker = workers.select{|w| w.pid == pid }.first
49
54
  end
50
55
  rescue Errno::ECHILD
51
56
  end
@@ -35,52 +35,79 @@ class WorkQueue
35
35
  end
36
36
 
37
37
  def remove_worker(pid)
38
- worker = @worker_mutex.synchronize do
39
- Log.debug "Remove #{pid}"
40
- @removed_workers.concat(@workers.delete_if{|w| w.pid == pid })
38
+ @worker_mutex.synchronize do
39
+ @workers.delete_if{|w| w.pid == pid }
40
+ @removed_workers << pid
41
41
  end
42
42
  end
43
43
 
44
44
  def process(&callback)
45
- @workers.each do |w|
46
- w.process @input, @output, &@worker_proc
47
- end
48
- @reader = Thread.new do
45
+ @reader = Thread.new do |parent|
49
46
  begin
47
+ Thread.current.report_on_exception = false
48
+ Thread.current["name"] = "Output reader #{Process.pid}"
49
+ @done_workers ||= []
50
50
  while true
51
51
  obj = @output.read
52
52
  if DoneProcessing === obj
53
- remove_worker obj.pid if obj.pid
53
+ done = @worker_mutex.synchronize do
54
+ Log.low "Worker #{obj.pid} done"
55
+ @done_workers << obj.pid
56
+ @done_workers.length == @removed_workers.length + @workers.length
57
+ end
58
+ break if done
59
+ elsif Exception === obj
60
+ raise obj
54
61
  else
55
62
  callback.call obj if callback
56
63
  end
57
64
  end
65
+ rescue DoneProcessing
58
66
  rescue Aborted
67
+ rescue WorkerException
68
+ Log.error "Exception in worker #{obj.pid} #{Log.fingerprint obj.exception}"
69
+ self.abort
70
+ raise obj.exception
59
71
  end
60
- end if @output
72
+ end
73
+
74
+ @workers.each do |w|
75
+ w.process @input, @output, &@worker_proc
76
+ end
77
+
78
+ Thread.pass until @reader["name"]
79
+
80
+ @waiter = Thread.new do
81
+ begin
82
+ Thread.current.report_on_exception = false
83
+ Thread.current["name"] = "Worker waiter #{Process.pid}"
84
+ while true
85
+ pid = Process.wait
86
+ remove_worker(pid)
87
+ break if workers.empty?
88
+ end
89
+ end
90
+ end
91
+
92
+ Thread.pass until @waiter["name"]
61
93
  end
62
94
 
63
95
  def write(obj)
64
96
  @input.write obj
65
97
  end
66
98
 
99
+ def abort
100
+ workers.each{|w| w.abort }
101
+ end
102
+
67
103
  def close
68
- while @worker_mutex.synchronize{ @workers.length } > 0
69
- begin
70
- @input.write DoneProcessing.new
71
- pid = Process.wait
72
- status = $?
73
- worker = @worker_mutex.synchronize{ @removed_workers.delete_if{|w| w.pid == pid }.first }
74
- worker.exit $?.exitstatus if worker
75
- rescue Errno::ECHILD
76
- Thread.pass until @workers.length == 0
77
- break
78
- end
104
+ @worker_mutex.synchronize{ @workers.length }.times do
105
+ @input.write DoneProcessing.new()
79
106
  end
80
- @reader.raise Aborted if @reader
81
107
  end
82
108
 
83
109
  def join
110
+ @waiter.join if @waiter
84
111
  @reader.join if @reader
85
112
  end
86
113
  end
@@ -55,9 +55,9 @@ class Step
55
55
 
56
56
  def report_status(status, message = nil)
57
57
  if message.nil?
58
- Log.info Log.color(status, status.to_s) + " " + Log.color(:path, path)
58
+ Log.info Log.color(:status, status, true) + " " + Log.color(:path, path)
59
59
  else
60
- Log.info Log.color(status, status.to_s) + " " + Log.color(:path, path) + " " + message
60
+ Log.info Log.color(:status, status, true) + " " + Log.color(:path, path) + " " + message
61
61
  end
62
62
  end
63
63
 
@@ -109,7 +109,8 @@ class Step
109
109
  end
110
110
 
111
111
  def clean
112
- FileUtils.rm path.find if path.exist?
112
+ Open.rm path if Open.exist?(path)
113
+ Open.rm info_file if Open.exist?(info_file)
113
114
  end
114
115
 
115
116
  def recursive_clean
@@ -143,8 +143,8 @@ module Task
143
143
  non_default_inputs.concat provided_inputs.keys.select{|k| String === k && k.include?("#") } if Hash === provided_inputs
144
144
 
145
145
  if non_default_inputs.any?
146
- hash = Misc.digest(:inputs => input_hash, :non_default_inputs => non_default_inputs, :dependencies => dependencies)
147
- Log.debug "Hash #{name} - #{hash}: #{Misc.digest_str(:inputs => inputs, :dependencies => dependencies)}"
146
+ hash = Misc.digest(:inputs => input_hash, :dependencies => dependencies)
147
+ Log.debug "Hash #{name} - #{hash}: #{Misc.digest_str(:inputs => inputs, :non_default_inputs => non_default_inputs, :dependencies => dependencies)}"
148
148
  id = [id, hash] * "_"
149
149
  end
150
150
 
data/scout-gear.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: scout-gear 6.0.0 ruby lib
5
+ # stub: scout-gear 7.1.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "scout-gear".freeze
9
- s.version = "6.0.0"
9
+ s.version = "7.1.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Miguel Vazquez".freeze]
14
- s.date = "2023-04-29"
14
+ s.date = "2023-05-01"
15
15
  s.description = "Temporary files, logs, etc.".freeze
16
16
  s.email = "mikisvaz@gmail.com".freeze
17
17
  s.executables = ["scout".freeze]
@@ -77,6 +77,8 @@ Gem::Specification.new do |s|
77
77
  "lib/scout/simple_opt/parse.rb",
78
78
  "lib/scout/simple_opt/setup.rb",
79
79
  "lib/scout/tmpfile.rb",
80
+ "lib/scout/tsv.rb",
81
+ "lib/scout/tsv/parser.rb",
80
82
  "lib/scout/work_queue.rb",
81
83
  "lib/scout/work_queue/socket.rb",
82
84
  "lib/scout/work_queue/worker.rb",
@@ -137,8 +139,10 @@ Gem::Specification.new do |s|
137
139
  "test/scout/test_resource.rb",
138
140
  "test/scout/test_semaphore.rb",
139
141
  "test/scout/test_tmpfile.rb",
142
+ "test/scout/test_tsv.rb",
140
143
  "test/scout/test_work_queue.rb",
141
144
  "test/scout/test_workflow.rb",
145
+ "test/scout/tsv/test_parser.rb",
142
146
  "test/scout/work_queue/test_socket.rb",
143
147
  "test/scout/work_queue/test_worker.rb",
144
148
  "test/scout/workflow/step/test_info.rb",
@@ -139,7 +139,7 @@ class TestOpenStream < Test::Unit::TestCase
139
139
 
140
140
  def test_tee_stream_save_error
141
141
  Log.with_severity 6 do
142
- 5.times do |i|
142
+ 50.times do |i|
143
143
  TmpFile.with_file do |tmp|
144
144
  Path.setup tmp
145
145
  assert_raise ScoutException do
@@ -4,7 +4,7 @@ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1
4
4
  require 'scout/work_queue/worker'
5
5
  class TestSemaphore < Test::Unit::TestCase
6
6
 
7
- def _test_simple
7
+ def test_simple
8
8
  ScoutSemaphore.with_semaphore 1 do |sem|
9
9
  10.times do
10
10
  ScoutSemaphore.synchronize(sem) do