utilrb 1.6.6 → 2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/Manifest.txt +10 -9
  2. data/README.rd +23 -0
  3. data/Rakefile +40 -37
  4. data/ext/utilrb/extconf.rb +36 -0
  5. data/ext/{proc.cc → utilrb/proc.c} +7 -6
  6. data/ext/utilrb/ruby_allocator.hh +76 -0
  7. data/ext/{ruby_internals-1.8.h → utilrb/ruby_internals-1.8.h} +0 -0
  8. data/ext/{ruby_internals-1.9.h → utilrb/ruby_internals-1.9.h} +0 -0
  9. data/ext/{swap.cc → utilrb/swap.cc} +0 -0
  10. data/ext/utilrb/utilrb.cc +79 -0
  11. data/ext/{value_set.cc → utilrb/value_set.cc} +5 -5
  12. data/ext/{weakref.cc → utilrb/weakref.cc} +0 -0
  13. data/lib/utilrb/common.rb +7 -2
  14. data/lib/utilrb/doc/rake.rb +46 -15
  15. data/lib/utilrb/kernel/load_dsl_file.rb +2 -2
  16. data/lib/utilrb/kernel/options.rb +6 -0
  17. data/lib/utilrb/logger/forward.rb +7 -0
  18. data/lib/utilrb/logger/hierarchy.rb +100 -42
  19. data/lib/utilrb/logger/indent.rb +38 -3
  20. data/lib/utilrb/logger/log_pp.rb +1 -1
  21. data/lib/utilrb/logger/root.rb +27 -12
  22. data/lib/utilrb/module/inherited_enumerable.rb +2 -196
  23. data/lib/utilrb/objectstats.rb +4 -1
  24. data/lib/utilrb/pkgconfig.rb +42 -6
  25. data/lib/utilrb/rake_common.rb +12 -0
  26. data/lib/utilrb/ruby_object_graph.rb +195 -46
  27. data/lib/utilrb/yard.rb +89 -89
  28. data/test/test_array.rb +1 -1
  29. data/test/test_dir.rb +1 -1
  30. data/test/test_enumerable.rb +7 -1
  31. data/test/test_event_loop.rb +407 -0
  32. data/test/test_exception.rb +1 -1
  33. data/test/test_gc.rb +1 -1
  34. data/test/test_hash.rb +57 -1
  35. data/test/test_kernel.rb +52 -21
  36. data/test/test_logger.rb +150 -1
  37. data/test/test_misc.rb +1 -1
  38. data/test/test_models.rb +212 -0
  39. data/test/test_module.rb +41 -71
  40. data/test/test_object.rb +1 -1
  41. data/test/test_objectstats.rb +1 -1
  42. data/test/test_pkgconfig.rb +7 -5
  43. data/test/test_proc.rb +1 -1
  44. data/test/test_set.rb +1 -1
  45. data/test/test_thread_pool.rb +409 -0
  46. data/test/test_time.rb +6 -6
  47. data/test/test_unbound_method.rb +1 -1
  48. metadata +157 -131
  49. data/README.txt +0 -45
  50. data/ext/extconf.rb +0 -29
  51. data/ext/utilrb_ext.cc +0 -144
data/test/test_module.rb CHANGED
@@ -1,6 +1,6 @@
1
- require 'test_config'
1
+ require 'test/test_config'
2
2
 
3
- require 'flexmock'
3
+ require 'flexmock/test_unit'
4
4
  require 'set'
5
5
  require 'enumerator'
6
6
  require 'utilrb/module'
@@ -70,75 +70,6 @@ class TC_Module < Test::Unit::TestCase
70
70
  assert_equal( [10, 20], obj.enum_for(:each_mapped, :a).to_a )
71
71
  end
72
72
 
73
- def test_inherited_enumerable_module
74
- m = Module.new do
75
- inherited_enumerable(:signature, :signatures) { Array.new }
76
- end
77
- k = Class.new do
78
- include m
79
- inherited_enumerable(:child_attribute) { Array.new }
80
- end
81
-
82
- # Add another attribute *after* k has been defined
83
- m.class_eval do
84
- inherited_enumerable(:mapped, :map, :map => true) { Hash.new }
85
- end
86
- check_inherited_enumerable(m, k)
87
- end
88
-
89
- def test_inherited_enumerable_class
90
- a = Class.new do
91
- inherited_enumerable(:signature, :signatures) { Array.new }
92
- inherited_enumerable(:mapped, :map, :map => true) { Hash.new }
93
- end
94
- b = Class.new(a) do
95
- include Module.new # include an empty module between a and b to check that the module
96
- # is skipped transparently
97
- inherited_enumerable(:child_attribute) { Array.new }
98
- end
99
- check_inherited_enumerable(a, b)
100
-
101
- # Test for singleton class support
102
- object = b.new
103
- assert(object.singleton_class.respond_to?(:signatures))
104
- object.singleton_class.signatures << :in_singleton
105
- assert_equal([:in_singleton], object.singleton_class.signatures)
106
- end
107
-
108
- def check_inherited_enumerable(base, derived)
109
- assert(base.respond_to?(:each_signature))
110
- assert(base.respond_to?(:signatures))
111
- assert(!base.respond_to?(:has_signature?))
112
- assert(!base.respond_to?(:find_signatures))
113
-
114
- assert(base.respond_to?(:each_mapped))
115
- assert(base.respond_to?(:map))
116
- assert(base.respond_to?(:has_mapped?))
117
-
118
- base.signatures << :in_base
119
- base.map[:base] = 10
120
- base.map[:overriden] = 20
121
- assert_equal([:in_base], base.enum_for(:each_signature).to_a)
122
- assert_equal([10].to_set, base.enum_for(:each_mapped, :base, false).to_set)
123
-
124
- assert(!base.respond_to?(:child_attribute))
125
- assert(!base.respond_to?(:each_child_attribute))
126
- assert(derived.respond_to?(:child_attribute))
127
- assert(derived.respond_to?(:each_child_attribute))
128
-
129
- derived.signatures << :in_derived
130
-
131
- derived.map[:overriden] = 15
132
- derived.map[:derived] = 25
133
-
134
- assert_equal([:in_derived, :in_base], derived.enum_for(:each_signature).to_a)
135
- assert_equal([20, 15].to_set, derived.enum_for(:each_mapped, :overriden, false).to_set)
136
- assert_equal([15].to_set, derived.enum_for(:each_mapped, :overriden, true).to_set)
137
- assert_equal([25].to_set, derived.enum_for(:each_mapped, :derived).to_set)
138
- assert_equal([[:base, 10], [:overriden, 20], [:overriden, 15], [:derived, 25]].to_set, derived.enum_for(:each_mapped, nil, false).to_set)
139
- assert_equal([[:base, 10], [:overriden, 15], [:derived, 25]].to_set, derived.enum_for(:each_mapped, nil, true).to_set)
140
- end
141
-
142
73
  def test_has_ancestor
143
74
  mod = Module.new
144
75
  parent = Class.new do
@@ -152,5 +83,44 @@ class TC_Module < Test::Unit::TestCase
152
83
 
153
84
  assert(!parent.has_ancestor?(child))
154
85
  end
86
+
87
+ def test_dsl_attribute_without_filter
88
+ obj = Class.new do
89
+ dsl_attribute :value
90
+ end.new
91
+ assert_same nil, obj.value
92
+ assert_same obj, obj.value(10)
93
+ assert_equal 10, obj.value
94
+ end
95
+
96
+ def test_dsl_attribute_with_filter
97
+ obj = Class.new do
98
+ dsl_attribute :value do |v|
99
+ v * 2
100
+ end
101
+ end.new
102
+ assert_same nil, obj.value
103
+ assert_same obj, obj.value(10)
104
+ assert_equal 20, obj.value
105
+ end
106
+
107
+ def test_define_inherited_enumerable_usable_on_extended_modules
108
+ obj = Array.new
109
+ defmod = Module.new do
110
+ define_inherited_enumerable(:object, :objects) { obj }
111
+ end
112
+ mod = Module.new { extend defmod }
113
+ assert_same obj, mod.objects
114
+ end
115
+
116
+ def test_define_inherited_enumerable_usable_through_inclusion
117
+ obj = Array.new
118
+ defmod = Module.new do
119
+ define_inherited_enumerable(:object, :objects) { obj }
120
+ end
121
+ intermediate = Module.new { include defmod }
122
+ mod = Module.new { extend intermediate }
123
+ assert_same obj, mod.objects
124
+ end
155
125
  end
156
126
 
data/test/test_object.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'test_config'
1
+ require 'test/test_config'
2
2
 
3
3
  require 'utilrb/object'
4
4
  require 'utilrb/module/attr_predicate'
@@ -1,4 +1,4 @@
1
- require 'test_config'
1
+ require 'test/test_config'
2
2
 
3
3
  require 'utilrb/objectstats'
4
4
  require 'utilrb/hash/to_s'
@@ -63,13 +63,15 @@ class TC_PkgConfig < Test::Unit::TestCase
63
63
  PkgConfig::ACTIONS.each do |action_name|
64
64
  method_name = action_name.gsub(/-/, '_')
65
65
 
66
- pure_ruby = pkg.send(method_name)
67
- cpkgconfig = pkg.send("pkgconfig_#{method_name}")
68
- if Shellwords.shellsplit(pure_ruby).to_set != Shellwords.shellsplit(cpkgconfig).to_set
66
+ pure_ruby = Shellwords.shellsplit(pkg.send(method_name)).to_set
67
+ cpkgconfig = Shellwords.shellsplit(pkg.send("pkgconfig_#{method_name}")).to_set
68
+ default_paths = Utilrb::PkgConfig.default_search_path.map { |p| Regexp.quote(p.gsub(/\/pkgconfig/, '')) }.join("|")
69
+ pure_ruby.delete_if { |f| f=~/-[IL](#{default_paths}|\/lib)$/ }
70
+ if pure_ruby != cpkgconfig
69
71
  failed = true
70
72
  puts "#{name} #{action_name}"
71
- puts " pure ruby: #{pure_ruby}"
72
- puts " cpkgconfig: #{cpkgconfig}"
73
+ puts " pure ruby: #{pure_ruby.inspect}"
74
+ puts " cpkgconfig: #{cpkgconfig.inspect}"
73
75
  end
74
76
  end
75
77
  if failed
data/test/test_proc.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'test_config'
1
+ require 'test/test_config'
2
2
 
3
3
  require 'utilrb'
4
4
 
data/test/test_set.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'test_config'
1
+ require 'test/test_config'
2
2
  require 'utilrb/set'
3
3
 
4
4
  class TC_Set < Test::Unit::TestCase
@@ -0,0 +1,409 @@
1
+ require 'test/test_config'
2
+ require 'utilrb/thread_pool'
3
+ require 'minitest/spec'
4
+
5
+ MiniTest::Unit.autorun
6
+
7
+ describe Utilrb::ThreadPool do
8
+ describe "when created" do
9
+ it "must create min number of threads." do
10
+ pool = Utilrb::ThreadPool.new(5)
11
+ sleep 0.1
12
+ assert_equal 5,pool.waiting
13
+ assert_equal 5,pool.spawned
14
+ assert_equal 5,(pool.instance_variable_get(:@workers)).size
15
+ pool.shutdown
16
+ pool.join
17
+ end
18
+
19
+ it "must create min number of threads." do
20
+ pool = Utilrb::ThreadPool.new(5)
21
+ sleep 0.1
22
+ assert_equal 5,pool.waiting
23
+ assert_equal 5,pool.spawned
24
+ assert_equal 5,(pool.instance_variable_get(:@workers)).size
25
+ pool.shutdown
26
+ pool.join
27
+ end
28
+ end
29
+
30
+ describe "when under heavy load" do
31
+ it "must spawn upto max threads." do
32
+ pool = Utilrb::ThreadPool.new(5,20)
33
+ 0.upto 19 do
34
+ pool.process do
35
+ sleep 0.12
36
+ end
37
+ end
38
+ assert_equal 20,pool.backlog
39
+ assert_equal 20,pool.tasks.size
40
+ sleep 0.1
41
+ assert_equal 0,pool.backlog
42
+ assert_equal 0,pool.waiting
43
+ assert_equal 20,pool.spawned
44
+ sleep 0.1
45
+ assert_equal 20,pool.waiting
46
+ assert_equal 20,pool.spawned
47
+ pool.shutdown
48
+ pool.join
49
+ end
50
+
51
+ it "must be possible to resize its limit" do
52
+ pool = Utilrb::ThreadPool.new(5,5)
53
+ 0.upto 19 do
54
+ pool.process do
55
+ sleep 0.32
56
+ end
57
+ end
58
+ sleep 0.1
59
+ assert_equal 0,pool.waiting
60
+ assert_equal 5,pool.spawned
61
+ pool.resize(5,20)
62
+ sleep 0.1
63
+ assert_equal 0,pool.waiting
64
+ assert_equal 20,pool.spawned
65
+ sleep 0.4
66
+ assert_equal 20,pool.spawned
67
+ assert_equal 20,pool.waiting
68
+ pool.shutdown
69
+ pool.join
70
+ end
71
+
72
+ it "must reduce its number of threads after the work is done if auto_trim == true." do
73
+ pool = Utilrb::ThreadPool.new(5,20)
74
+ pool.auto_trim = true
75
+ 0.upto 19 do
76
+ pool.process do
77
+ sleep 0.15
78
+ end
79
+ end
80
+ sleep 0.13
81
+ assert_equal 0,pool.waiting
82
+ assert_equal 20,pool.spawned
83
+ sleep 0.4
84
+ assert_equal 5,pool.waiting
85
+ assert_equal 5,pool.spawned
86
+ pool.shutdown
87
+ pool.join
88
+ end
89
+
90
+ it "must not execute tasks with the same sync key in parallel" do
91
+ pool = Utilrb::ThreadPool.new(5,10)
92
+ pool.auto_trim = true
93
+ time = Time.now
94
+ 0.upto 10 do
95
+ t = pool.process_with_options :sync_key => time do
96
+ sleep 0.1
97
+ end
98
+ assert_equal time, t.sync_key
99
+ end
100
+ while pool.backlog > 0
101
+ sleep 0.1
102
+ end
103
+ pool.shutdown
104
+ pool.join
105
+ assert Time.now - time >= 1.0
106
+ end
107
+
108
+ it "must not execute a task and a sync call in parallel if they have the same sync key" do
109
+ pool = Utilrb::ThreadPool.new(5,5)
110
+ time = Time.now
111
+ t = pool.process_with_options :sync_key => 1 do
112
+ sleep 0.2
113
+ end
114
+ pool.sync 1 do
115
+ sleep 0.2
116
+ end
117
+ while pool.backlog > 0
118
+ sleep 0.1
119
+ end
120
+ pool.shutdown
121
+ pool.join
122
+ assert Time.now - time >= 0.4
123
+ end
124
+
125
+ it "must execute a task and a sync call in parallel if they have different sync keys" do
126
+ pool = Utilrb::ThreadPool.new(5,5)
127
+ time = Time.now
128
+ t = pool.process_with_options :sync_key => 1 do
129
+ sleep 0.2
130
+ end
131
+ pool.sync 2 do
132
+ sleep 0.2
133
+ end
134
+ while pool.backlog > 0
135
+ sleep 0.1
136
+ end
137
+ pool.shutdown
138
+ pool.join
139
+ assert Time.now - time < 0.4
140
+ end
141
+ end
142
+
143
+ describe "when running" do
144
+ it "must call on_task_finished for each finised task." do
145
+ pool = Utilrb::ThreadPool.new(5)
146
+ count = 0
147
+ pool.on_task_finished do |task|
148
+ count += 1
149
+ end
150
+ task = pool.process do
151
+ sleep 0.05
152
+ end
153
+ task = pool.process do
154
+ raise
155
+ end
156
+ sleep 0.1
157
+ assert_equal 2,count
158
+ pool.shutdown
159
+ pool.join
160
+ end
161
+
162
+ it "must be able to reque a task" do
163
+ pool = Utilrb::ThreadPool.new(5)
164
+ count = 0
165
+ task = pool.process do
166
+ count += 1
167
+ end
168
+ while !task.finished?
169
+ sleep 0.001
170
+ end
171
+ pool << task
172
+ while !task.finished?
173
+ sleep 0.001
174
+ end
175
+ assert_equal 2, count
176
+ end
177
+
178
+ it "must process the next task if thread gets available" do
179
+ pool = Utilrb::ThreadPool.new(1)
180
+ count = 0
181
+ pool.process do
182
+ sleep 0.1
183
+ count +=1
184
+ end
185
+ pool.process do
186
+ sleep 0.1
187
+ count +=1
188
+ end
189
+ sleep 0.25
190
+ assert_equal 2, count
191
+
192
+ task3 = Utilrb::ThreadPool::Task.new do
193
+ count +=1
194
+ sleep 0.1
195
+ end
196
+ task4 = Utilrb::ThreadPool::Task.new do
197
+ count +=1
198
+ sleep 0.1
199
+ end
200
+ pool << task3
201
+ pool << task4
202
+ sleep 0.15
203
+ pool.shutdown
204
+ pool.join
205
+ assert_equal 4, count
206
+ end
207
+ end
208
+
209
+ describe "when shutting down" do
210
+ it "must terminate all threads" do
211
+ pool = Utilrb::ThreadPool.new(5)
212
+ task = pool.process do
213
+ sleep 0.2
214
+ end
215
+ pool.shutdown()
216
+ pool.join
217
+ end
218
+ end
219
+ end
220
+
221
+
222
+ describe Utilrb::ThreadPool::Task do
223
+ describe "when created" do
224
+ it "must raise if no block is given." do
225
+ assert_raises(ArgumentError) do
226
+ Utilrb::ThreadPool::Task.new
227
+ end
228
+ end
229
+ it "must be in waiting state." do
230
+ task = Utilrb::ThreadPool::Task.new do
231
+ end
232
+ assert !task.running?
233
+ assert !task.finished?
234
+ assert !task.exception?
235
+ assert !task.terminated?
236
+ assert !task.successfull?
237
+ assert !task.started?
238
+ assert_equal :waiting, task.state
239
+ end
240
+ it "must raise if wrong option is given." do
241
+ assert_raises ArgumentError do
242
+ task = Utilrb::ThreadPool::Task.new :bla => 123 do
243
+ end
244
+ end
245
+ end
246
+ it "must set its options." do
247
+ task = Utilrb::ThreadPool::Task.new :sync_key => 2 do
248
+ 123
249
+ end
250
+ assert_equal 2,task.sync_key
251
+ end
252
+ end
253
+
254
+ describe "when executed" do
255
+ it "must be in finished state if task successfully executed." do
256
+ task = Utilrb::ThreadPool::Task.new do
257
+ 123
258
+ end
259
+ task.pre_execute
260
+ task.execute
261
+ task.finalize
262
+ assert !task.running?
263
+ assert task.finished?
264
+ assert !task.exception?
265
+ assert !task.terminated?
266
+ assert task.successfull?
267
+ assert task.started?
268
+ end
269
+
270
+ it "must call the callback after it is finished." do
271
+ task = Utilrb::ThreadPool::Task.new do
272
+ 123
273
+ end
274
+ result = nil
275
+ task.callback do |val,e|
276
+ result = val
277
+ end
278
+ task.pre_execute
279
+ task.execute
280
+ task.finalize
281
+
282
+ assert_equal 123,result
283
+ assert !task.running?
284
+ assert task.finished?
285
+ assert !task.exception?
286
+ assert !task.terminated?
287
+ assert task.successfull?
288
+ assert task.started?
289
+ end
290
+
291
+ it "must be in exception state if exception was raised." do
292
+ task = Utilrb::ThreadPool::Task.new do
293
+ raise
294
+ end
295
+ task.pre_execute
296
+ task.execute
297
+ task.finalize
298
+ assert !task.running?
299
+ assert task.finished?
300
+ assert task.exception?
301
+ assert !task.terminated?
302
+ assert !task.successfull?
303
+ assert task.started?
304
+
305
+ task = Utilrb::ThreadPool::Task.new do
306
+ raise
307
+ end
308
+ result = nil
309
+ task.callback do |val,e|
310
+ result = val ? val : e
311
+ end
312
+ task.pre_execute
313
+ task.execute
314
+ task.finalize
315
+ assert !task.running?
316
+ assert task.finished?
317
+ assert task.exception?
318
+ assert !task.terminated?
319
+ assert !task.successfull?
320
+ assert task.started?
321
+ assert_equal RuntimeError, result.class
322
+ end
323
+
324
+ it "must return the default value if an error was raised." do
325
+ task = Utilrb::ThreadPool::Task.new :default => 123 do
326
+ raise
327
+ end
328
+ result = nil
329
+ task.callback do |val,e|
330
+ result = val
331
+ end
332
+ task.pre_execute
333
+ task.execute
334
+ task.finalize
335
+ assert !task.running?
336
+ assert task.finished?
337
+ assert task.exception?
338
+ assert !task.terminated?
339
+ assert !task.successfull?
340
+ assert task.started?
341
+ assert_equal 123,result
342
+ end
343
+
344
+ it "must calculate its elapsed time." do
345
+ task = Utilrb::ThreadPool::Task.new do
346
+ sleep 0.2
347
+ end
348
+ assert_in_delta 0.0,task.time_elapsed,0.0001
349
+ thread = Thread.new do
350
+ task.pre_execute
351
+ task.execute
352
+ task.finalize
353
+ end
354
+ sleep 0.1
355
+ assert_in_delta 0.1,task.time_elapsed,0.01
356
+ thread.join
357
+ assert_in_delta 0.2,task.time_elapsed,0.001
358
+ sleep 0.1
359
+ assert_in_delta 0.2,task.time_elapsed,0.001
360
+ end
361
+ end
362
+
363
+ describe "when terminated" do
364
+ it "it must be in terminated state." do
365
+ task = Utilrb::ThreadPool::Task.new do
366
+ sleep 10
367
+ end
368
+ thread = Thread.new do
369
+ task.pre_execute
370
+ task.execute
371
+ task.finalize
372
+ end
373
+ sleep 0.1
374
+ task.terminate!
375
+ thread.join
376
+
377
+ assert !task.running?
378
+ assert task.finished?
379
+ assert !task.exception?
380
+ assert task.terminated?
381
+ assert !task.successfull?
382
+ assert task.started?
383
+ end
384
+ end
385
+
386
+ describe "when terminated" do
387
+ it "must be in state terminated." do
388
+ task = Utilrb::ThreadPool::Task.new do
389
+ sleep 10
390
+ end
391
+ thread = Thread.new do
392
+ task.pre_execute
393
+ task.execute
394
+ task.finalize
395
+ end
396
+ sleep 0.1
397
+ task.terminate!()
398
+ thread.join
399
+
400
+ assert !task.running?
401
+ assert task.finished?
402
+ assert !task.exception?
403
+ assert task.terminated?
404
+ assert !task.successfull?
405
+ assert task.started?
406
+ end
407
+ end
408
+ end
409
+