utilrb 1.6.6 → 2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+