activesupport 3.2.22.5 → 4.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +364 -135
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -4
- data/lib/active_support/backtrace_cleaner.rb +33 -25
- data/lib/active_support/basic_object.rb +7 -17
- data/lib/active_support/benchmarkable.rb +19 -15
- data/lib/active_support/buffered_logger.rb +9 -113
- data/lib/active_support/cache/file_store.rb +14 -14
- data/lib/active_support/cache/mem_cache_store.rb +24 -30
- data/lib/active_support/cache/memory_store.rb +2 -0
- data/lib/active_support/cache/strategy/local_cache.rb +48 -37
- data/lib/active_support/cache.rb +228 -183
- data/lib/active_support/callbacks.rb +201 -253
- data/lib/active_support/concern.rb +16 -23
- data/lib/active_support/concurrency/latch.rb +27 -0
- data/lib/active_support/configurable.rb +69 -12
- data/lib/active_support/core_ext/array/access.rb +17 -9
- data/lib/active_support/core_ext/array/conversions.rb +115 -55
- data/lib/active_support/core_ext/array/extract_options.rb +2 -2
- data/lib/active_support/core_ext/array/grouping.rb +21 -22
- data/lib/active_support/core_ext/array/uniq_by.rb +12 -9
- data/lib/active_support/core_ext/array/wrap.rb +13 -16
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/benchmark.rb +7 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -24
- data/lib/active_support/core_ext/class/attribute.rb +40 -32
- data/lib/active_support/core_ext/class/attribute_accessors.rb +14 -12
- data/lib/active_support/core_ext/class/delegating_attributes.rb +15 -19
- data/lib/active_support/core_ext/class/subclasses.rb +11 -5
- data/lib/active_support/core_ext/date/calculations.rb +44 -187
- data/lib/active_support/core_ext/date/conversions.rb +16 -38
- data/lib/active_support/core_ext/date/zones.rb +25 -2
- data/lib/active_support/core_ext/date.rb +5 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +77 -62
- data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
- data/lib/active_support/core_ext/date_time/zones.rb +11 -8
- data/lib/active_support/core_ext/date_time.rb +4 -0
- data/lib/active_support/core_ext/enumerable.rb +26 -73
- data/lib/active_support/core_ext/file/atomic.rb +27 -11
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/hash/conversions.rb +145 -79
- data/lib/active_support/core_ext/hash/deep_merge.rb +14 -8
- data/lib/active_support/core_ext/hash/diff.rb +5 -4
- data/lib/active_support/core_ext/hash/except.rb +1 -9
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -5
- data/lib/active_support/core_ext/hash/keys.rb +108 -24
- data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
- data/lib/active_support/core_ext/hash/slice.rb +12 -12
- data/lib/active_support/core_ext/hash.rb +0 -1
- data/lib/active_support/core_ext/integer/inflections.rb +13 -1
- data/lib/active_support/core_ext/integer/time.rb +17 -12
- data/lib/active_support/core_ext/kernel/debugger.rb +2 -2
- data/lib/active_support/core_ext/kernel/reporting.rb +36 -22
- data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
- data/lib/active_support/core_ext/load_error.rb +7 -5
- data/lib/active_support/core_ext/logger.rb +7 -23
- data/lib/active_support/core_ext/marshal.rb +21 -0
- data/lib/active_support/core_ext/module/aliasing.rb +8 -9
- data/lib/active_support/core_ext/module/anonymous.rb +2 -7
- data/lib/active_support/core_ext/module/attr_internal.rb +0 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +12 -10
- data/lib/active_support/core_ext/module/delegation.rb +92 -49
- data/lib/active_support/core_ext/module/deprecation.rb +19 -3
- data/lib/active_support/core_ext/module/introspection.rb +17 -27
- data/lib/active_support/core_ext/module/qualified_const.rb +8 -20
- data/lib/active_support/core_ext/module/remove_method.rb +1 -5
- data/lib/active_support/core_ext/module.rb +1 -3
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
- data/lib/active_support/core_ext/numeric/time.rb +6 -6
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/acts_like.rb +4 -4
- data/lib/active_support/core_ext/object/blank.rb +7 -23
- data/lib/active_support/core_ext/object/deep_dup.rb +46 -0
- data/lib/active_support/core_ext/object/duplicable.rb +1 -30
- data/lib/active_support/core_ext/object/inclusion.rb +8 -7
- data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
- data/lib/active_support/core_ext/object/to_json.rb +8 -0
- data/lib/active_support/core_ext/object/to_param.rb +5 -2
- data/lib/active_support/core_ext/object/try.rb +46 -25
- data/lib/active_support/core_ext/object/with_options.rb +7 -8
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/proc.rb +3 -0
- data/lib/active_support/core_ext/range/conversions.rb +0 -2
- data/lib/active_support/core_ext/range/include_range.rb +3 -1
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +0 -2
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/conversions.rb +27 -38
- data/lib/active_support/core_ext/string/encoding.rb +6 -9
- data/lib/active_support/core_ext/string/filters.rb +24 -18
- data/lib/active_support/core_ext/string/indent.rb +43 -0
- data/lib/active_support/core_ext/string/inflections.rb +70 -60
- data/lib/active_support/core_ext/string/inquiry.rb +2 -2
- data/lib/active_support/core_ext/string/multibyte.rb +41 -64
- data/lib/active_support/core_ext/string/output_safety.rb +59 -51
- data/lib/active_support/core_ext/string/zones.rb +13 -0
- data/lib/active_support/core_ext/string.rb +2 -3
- data/lib/active_support/core_ext/struct.rb +6 -0
- data/lib/active_support/core_ext/thread.rb +74 -0
- data/lib/active_support/core_ext/time/calculations.rb +108 -184
- data/lib/active_support/core_ext/time/conversions.rb +27 -51
- data/lib/active_support/core_ext/time/marshal.rb +0 -27
- data/lib/active_support/core_ext/time/zones.rb +27 -17
- data/lib/active_support/core_ext/time.rb +5 -0
- data/lib/active_support/core_ext/uri.rb +13 -17
- data/lib/active_support/core_ext.rb +3 -2
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/dependencies.rb +160 -141
- data/lib/active_support/deprecation/behaviors.rb +44 -30
- data/lib/active_support/deprecation/instance_delegator.rb +24 -0
- data/lib/active_support/deprecation/method_wrappers.rb +33 -18
- data/lib/active_support/deprecation/proxy_wrappers.rb +58 -13
- data/lib/active_support/deprecation/reporting.rb +40 -11
- data/lib/active_support/deprecation.rb +39 -14
- data/lib/active_support/descendants_tracker.rb +34 -19
- data/lib/active_support/duration.rb +6 -8
- data/lib/active_support/file_update_checker.rb +63 -47
- data/lib/active_support/gzip.rb +11 -5
- data/lib/active_support/hash_with_indifferent_access.rb +127 -42
- data/lib/active_support/i18n.rb +4 -0
- data/lib/active_support/i18n_railtie.rb +5 -22
- data/lib/active_support/inflections.rb +14 -12
- data/lib/active_support/inflector/inflections.rb +108 -71
- data/lib/active_support/inflector/methods.rb +181 -160
- data/lib/active_support/inflector/transliterate.rb +16 -17
- data/lib/active_support/json/decoding.rb +18 -17
- data/lib/active_support/json/encoding.rb +93 -39
- data/lib/active_support/json/variable.rb +10 -1
- data/lib/active_support/key_generator.rb +75 -0
- data/lib/active_support/lazy_load_hooks.rb +21 -19
- data/lib/active_support/locale/en.yml +100 -3
- data/lib/active_support/log_subscriber/test_helper.rb +18 -15
- data/lib/active_support/log_subscriber.rb +35 -52
- data/lib/active_support/logger.rb +57 -0
- data/lib/active_support/logger_silence.rb +24 -0
- data/lib/active_support/message_encryptor.rb +38 -35
- data/lib/active_support/message_verifier.rb +9 -15
- data/lib/active_support/multibyte/chars.rb +80 -333
- data/lib/active_support/multibyte/unicode.rb +74 -64
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/notifications/fanout.rb +112 -18
- data/lib/active_support/notifications/instrumenter.rb +33 -14
- data/lib/active_support/notifications.rb +79 -26
- data/lib/active_support/number_helper.rb +637 -0
- data/lib/active_support/ordered_hash.rb +8 -190
- data/lib/active_support/ordered_options.rb +21 -23
- data/lib/active_support/per_thread_registry.rb +52 -0
- data/lib/active_support/proxy_object.rb +13 -0
- data/lib/active_support/rails.rb +27 -0
- data/lib/active_support/railtie.rb +12 -32
- data/lib/active_support/rescuable.rb +9 -4
- data/lib/active_support/string_inquirer.rb +13 -8
- data/lib/active_support/subscriber.rb +93 -0
- data/lib/active_support/tagged_logging.rb +51 -73
- data/lib/active_support/test_case.rb +46 -17
- data/lib/active_support/testing/assertions.rb +56 -26
- data/lib/active_support/testing/autorun.rb +5 -0
- data/lib/active_support/testing/constant_lookup.rb +54 -0
- data/lib/active_support/testing/declarative.rb +1 -1
- data/lib/active_support/testing/deprecation.rb +0 -19
- data/lib/active_support/testing/isolation.rb +29 -58
- data/lib/active_support/testing/pending.rb +5 -43
- data/lib/active_support/testing/setup_and_teardown.rb +6 -92
- data/lib/active_support/testing/tagged_logging.rb +25 -0
- data/lib/active_support/time.rb +6 -21
- data/lib/active_support/time_with_zone.rb +80 -43
- data/lib/active_support/values/time_zone.rb +81 -60
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +7 -6
- data/lib/active_support/xml_mini/jdom.rb +9 -11
- data/lib/active_support/xml_mini/libxml.rb +1 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
- data/lib/active_support/xml_mini/nokogiri.rb +1 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
- data/lib/active_support/xml_mini/rexml.rb +6 -8
- data/lib/active_support/xml_mini.rb +35 -17
- data/lib/active_support.rb +8 -21
- metadata +104 -72
- data/lib/active_support/base64.rb +0 -54
- data/lib/active_support/core_ext/array/random_access.rb +0 -30
- data/lib/active_support/core_ext/date/freeze.rb +0 -33
- data/lib/active_support/core_ext/exception.rb +0 -3
- data/lib/active_support/core_ext/file/path.rb +0 -5
- data/lib/active_support/core_ext/float/rounding.rb +0 -19
- data/lib/active_support/core_ext/float.rb +0 -1
- data/lib/active_support/core_ext/hash/deep_dup.rb +0 -18
- data/lib/active_support/core_ext/io.rb +0 -15
- data/lib/active_support/core_ext/module/method_names.rb +0 -14
- data/lib/active_support/core_ext/module/synchronization.rb +0 -45
- data/lib/active_support/core_ext/process/daemon.rb +0 -23
- data/lib/active_support/core_ext/process.rb +0 -1
- data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
- data/lib/active_support/core_ext/range/cover.rb +0 -3
- data/lib/active_support/core_ext/rexml.rb +0 -46
- data/lib/active_support/core_ext/string/interpolation.rb +0 -2
- data/lib/active_support/core_ext/string/xchar.rb +0 -18
- data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
- data/lib/active_support/memoizable.rb +0 -116
- data/lib/active_support/multibyte/exceptions.rb +0 -8
- data/lib/active_support/multibyte/utils.rb +0 -60
- data/lib/active_support/ruby/shim.rb +0 -22
- data/lib/active_support/security_utils.rb +0 -27
- data/lib/active_support/testing/mochaing.rb +0 -7
- data/lib/active_support/testing/performance/jruby.rb +0 -115
- data/lib/active_support/testing/performance/rubinius.rb +0 -113
- data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
- data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
- data/lib/active_support/testing/performance/ruby.rb +0 -152
- data/lib/active_support/testing/performance.rb +0 -317
- data/lib/active_support/time/autoload.rb +0 -5
- data/lib/active_support/whiny_nil.rb +0 -24
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
module ActiveSupport
|
|
2
|
-
module Testing
|
|
3
|
-
module Performance
|
|
4
|
-
module Metrics
|
|
5
|
-
class Base
|
|
6
|
-
protected
|
|
7
|
-
# Ruby 1.9 with GC::Profiler
|
|
8
|
-
if defined?(GC::Profiler)
|
|
9
|
-
def with_gc_stats
|
|
10
|
-
GC::Profiler.enable
|
|
11
|
-
GC.start
|
|
12
|
-
yield
|
|
13
|
-
ensure
|
|
14
|
-
GC::Profiler.disable
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
class Memory < DigitalInformationUnit
|
|
20
|
-
# Ruby 1.9 + GCdata patch
|
|
21
|
-
if GC.respond_to?(:malloc_allocated_size)
|
|
22
|
-
def measure
|
|
23
|
-
GC.malloc_allocated_size
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
class Objects < Amount
|
|
29
|
-
# Ruby 1.9 + GCdata patch
|
|
30
|
-
if GC.respond_to?(:malloc_allocations)
|
|
31
|
-
def measure
|
|
32
|
-
GC.malloc_allocations
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
class GcRuns < Amount
|
|
38
|
-
# Ruby 1.9
|
|
39
|
-
if GC.respond_to?(:count)
|
|
40
|
-
def measure
|
|
41
|
-
GC.count
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
class GcTime < Time
|
|
47
|
-
# Ruby 1.9 with GC::Profiler
|
|
48
|
-
if defined?(GC::Profiler) && GC::Profiler.respond_to?(:total_time)
|
|
49
|
-
def measure
|
|
50
|
-
GC::Profiler.total_time
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
begin
|
|
2
|
-
require 'ruby-prof'
|
|
3
|
-
rescue LoadError
|
|
4
|
-
$stderr.puts 'Specify ruby-prof as application\'s dependency in Gemfile to run benchmarks.'
|
|
5
|
-
exit
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
module ActiveSupport
|
|
9
|
-
module Testing
|
|
10
|
-
module Performance
|
|
11
|
-
DEFAULTS.merge!(
|
|
12
|
-
if ENV["BENCHMARK_TESTS"]
|
|
13
|
-
{ :metrics => [:wall_time, :memory, :objects, :gc_runs, :gc_time] }
|
|
14
|
-
else
|
|
15
|
-
{ :min_percent => 0.01,
|
|
16
|
-
:metrics => [:process_time, :memory, :objects],
|
|
17
|
-
:formats => [:flat, :graph_html, :call_tree, :call_stack] }
|
|
18
|
-
end).freeze
|
|
19
|
-
|
|
20
|
-
protected
|
|
21
|
-
def run_gc
|
|
22
|
-
GC.start
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
class Profiler < Performer
|
|
26
|
-
def initialize(*args)
|
|
27
|
-
super
|
|
28
|
-
@supported = @metric.measure_mode rescue false
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def run
|
|
32
|
-
return unless @supported
|
|
33
|
-
|
|
34
|
-
RubyProf.measure_mode = @metric.measure_mode
|
|
35
|
-
RubyProf.start
|
|
36
|
-
RubyProf.pause
|
|
37
|
-
full_profile_options[:runs].to_i.times { run_test(@metric, :profile) }
|
|
38
|
-
@data = RubyProf.stop
|
|
39
|
-
@total = @data.threads.sum(0) { |thread| thread.methods.max.total_time }
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def record
|
|
43
|
-
return unless @supported
|
|
44
|
-
|
|
45
|
-
klasses = full_profile_options[:formats].map { |f| RubyProf.const_get("#{f.to_s.camelize}Printer") }.compact
|
|
46
|
-
|
|
47
|
-
klasses.each do |klass|
|
|
48
|
-
fname = output_filename(klass)
|
|
49
|
-
FileUtils.mkdir_p(File.dirname(fname))
|
|
50
|
-
File.open(fname, 'wb') do |file|
|
|
51
|
-
klass.new(@data).print(file, full_profile_options.slice(:min_percent))
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
protected
|
|
57
|
-
def output_filename(printer_class)
|
|
58
|
-
suffix =
|
|
59
|
-
case printer_class.name.demodulize
|
|
60
|
-
when 'FlatPrinter'; 'flat.txt'
|
|
61
|
-
when 'FlatPrinterWithLineNumbers'; 'flat_line_numbers.txt'
|
|
62
|
-
when 'GraphPrinter'; 'graph.txt'
|
|
63
|
-
when 'GraphHtmlPrinter'; 'graph.html'
|
|
64
|
-
when 'GraphYamlPrinter'; 'graph.yml'
|
|
65
|
-
when 'CallTreePrinter'; 'tree.txt'
|
|
66
|
-
when 'CallStackPrinter'; 'stack.html'
|
|
67
|
-
when 'DotPrinter'; 'graph.dot'
|
|
68
|
-
else printer_class.name.sub(/Printer$/, '').underscore
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
"#{super()}_#{suffix}"
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
module Metrics
|
|
76
|
-
class Base
|
|
77
|
-
def measure_mode
|
|
78
|
-
self.class::Mode
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def profile
|
|
82
|
-
RubyProf.resume
|
|
83
|
-
yield
|
|
84
|
-
ensure
|
|
85
|
-
RubyProf.pause
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
protected
|
|
89
|
-
# overridden by each implementation
|
|
90
|
-
def with_gc_stats
|
|
91
|
-
yield
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
class ProcessTime < Time
|
|
96
|
-
Mode = RubyProf::PROCESS_TIME if RubyProf.const_defined?(:PROCESS_TIME)
|
|
97
|
-
|
|
98
|
-
def measure
|
|
99
|
-
RubyProf.measure_process_time
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
class WallTime < Time
|
|
104
|
-
Mode = RubyProf::WALL_TIME if RubyProf.const_defined?(:WALL_TIME)
|
|
105
|
-
|
|
106
|
-
def measure
|
|
107
|
-
RubyProf.measure_wall_time
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
class CpuTime < Time
|
|
112
|
-
Mode = RubyProf::CPU_TIME if RubyProf.const_defined?(:CPU_TIME)
|
|
113
|
-
|
|
114
|
-
def initialize(*args)
|
|
115
|
-
# FIXME: yeah my CPU is 2.33 GHz
|
|
116
|
-
RubyProf.cpu_frequency = 2.33e9 unless RubyProf.cpu_frequency > 0
|
|
117
|
-
super
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def measure
|
|
121
|
-
RubyProf.measure_cpu_time
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
class Memory < DigitalInformationUnit
|
|
126
|
-
Mode = RubyProf::MEMORY if RubyProf.const_defined?(:MEMORY)
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
class Objects < Amount
|
|
130
|
-
Mode = RubyProf::ALLOCATIONS if RubyProf.const_defined?(:ALLOCATIONS)
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
class GcRuns < Amount
|
|
134
|
-
Mode = RubyProf::GC_RUNS if RubyProf.const_defined?(:GC_RUNS)
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
class GcTime < Time
|
|
138
|
-
Mode = RubyProf::GC_TIME if RubyProf.const_defined?(:GC_TIME)
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
if RUBY_VERSION.between?('1.9.2', '2.0.0')
|
|
146
|
-
require 'active_support/testing/performance/ruby/yarv'
|
|
147
|
-
elsif RUBY_VERSION.between?('1.8.6', '1.9')
|
|
148
|
-
require 'active_support/testing/performance/ruby/mri'
|
|
149
|
-
else
|
|
150
|
-
$stderr.puts 'Update your ruby interpreter to be able to run benchmarks.'
|
|
151
|
-
exit
|
|
152
|
-
end
|
|
@@ -1,317 +0,0 @@
|
|
|
1
|
-
require 'fileutils'
|
|
2
|
-
require 'rails/version'
|
|
3
|
-
require 'active_support/concern'
|
|
4
|
-
require 'active_support/core_ext/class/delegating_attributes'
|
|
5
|
-
require 'active_support/core_ext/string/inflections'
|
|
6
|
-
require 'action_view/helpers/number_helper'
|
|
7
|
-
|
|
8
|
-
module ActiveSupport
|
|
9
|
-
module Testing
|
|
10
|
-
module Performance
|
|
11
|
-
extend ActiveSupport::Concern
|
|
12
|
-
|
|
13
|
-
included do
|
|
14
|
-
superclass_delegating_accessor :profile_options
|
|
15
|
-
self.profile_options = {}
|
|
16
|
-
|
|
17
|
-
if defined?(MiniTest::Assertions) && TestCase < MiniTest::Assertions
|
|
18
|
-
include ForMiniTest
|
|
19
|
-
else
|
|
20
|
-
include ForClassicTestUnit
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# each implementation should define metrics and freeze the defaults
|
|
25
|
-
DEFAULTS =
|
|
26
|
-
if ENV["BENCHMARK_TESTS"]
|
|
27
|
-
{ :runs => 4,
|
|
28
|
-
:output => 'tmp/performance',
|
|
29
|
-
:benchmark => true }
|
|
30
|
-
else
|
|
31
|
-
{ :runs => 1,
|
|
32
|
-
:output => 'tmp/performance',
|
|
33
|
-
:benchmark => false }
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def full_profile_options
|
|
37
|
-
DEFAULTS.merge(profile_options)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def full_test_name
|
|
41
|
-
"#{self.class.name}##{method_name}"
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
module ForMiniTest
|
|
45
|
-
def run(runner)
|
|
46
|
-
@runner = runner
|
|
47
|
-
|
|
48
|
-
run_warmup
|
|
49
|
-
if full_profile_options && metrics = full_profile_options[:metrics]
|
|
50
|
-
metrics.each do |metric_name|
|
|
51
|
-
if klass = Metrics[metric_name.to_sym]
|
|
52
|
-
run_profile(klass.new)
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
return
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def run_test(metric, mode)
|
|
61
|
-
result = '.'
|
|
62
|
-
begin
|
|
63
|
-
run_callbacks :setup
|
|
64
|
-
setup
|
|
65
|
-
metric.send(mode) { __send__ method_name }
|
|
66
|
-
rescue Exception => e
|
|
67
|
-
result = @runner.puke(self.class, method_name, e)
|
|
68
|
-
ensure
|
|
69
|
-
begin
|
|
70
|
-
teardown
|
|
71
|
-
run_callbacks :teardown, :enumerator => :reverse_each
|
|
72
|
-
rescue Exception => e
|
|
73
|
-
result = @runner.puke(self.class, method_name, e)
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
result
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
module ForClassicTestUnit
|
|
81
|
-
def run(result)
|
|
82
|
-
return if method_name =~ /^default_test$/
|
|
83
|
-
|
|
84
|
-
yield(self.class::STARTED, name)
|
|
85
|
-
@_result = result
|
|
86
|
-
|
|
87
|
-
run_warmup
|
|
88
|
-
if full_profile_options && metrics = full_profile_options[:metrics]
|
|
89
|
-
metrics.each do |metric_name|
|
|
90
|
-
if klass = Metrics[metric_name.to_sym]
|
|
91
|
-
run_profile(klass.new)
|
|
92
|
-
result.add_run
|
|
93
|
-
else
|
|
94
|
-
puts '%20s: unsupported' % metric_name
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
yield(self.class::FINISHED, name)
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def run_test(metric, mode)
|
|
103
|
-
run_callbacks :setup
|
|
104
|
-
setup
|
|
105
|
-
metric.send(mode) { __send__ @method_name }
|
|
106
|
-
rescue ::Test::Unit::AssertionFailedError => e
|
|
107
|
-
add_failure(e.message, e.backtrace)
|
|
108
|
-
rescue StandardError, ScriptError => e
|
|
109
|
-
add_error(e)
|
|
110
|
-
ensure
|
|
111
|
-
begin
|
|
112
|
-
teardown
|
|
113
|
-
run_callbacks :teardown, :enumerator => :reverse_each
|
|
114
|
-
rescue ::Test::Unit::AssertionFailedError => e
|
|
115
|
-
add_failure(e.message, e.backtrace)
|
|
116
|
-
rescue StandardError, ScriptError => e
|
|
117
|
-
add_error(e)
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
protected
|
|
123
|
-
# overridden by each implementation
|
|
124
|
-
def run_gc; end
|
|
125
|
-
|
|
126
|
-
def run_warmup
|
|
127
|
-
run_gc
|
|
128
|
-
|
|
129
|
-
time = Metrics::Time.new
|
|
130
|
-
run_test(time, :benchmark)
|
|
131
|
-
puts "%s (%s warmup)" % [full_test_name, time.format(time.total)]
|
|
132
|
-
|
|
133
|
-
run_gc
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
def run_profile(metric)
|
|
137
|
-
klass = full_profile_options[:benchmark] ? Benchmarker : Profiler
|
|
138
|
-
performer = klass.new(self, metric)
|
|
139
|
-
|
|
140
|
-
performer.run
|
|
141
|
-
puts performer.report
|
|
142
|
-
performer.record
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
class Performer
|
|
146
|
-
delegate :run_test, :full_profile_options, :full_test_name, :to => :@harness
|
|
147
|
-
|
|
148
|
-
def initialize(harness, metric)
|
|
149
|
-
@harness, @metric, @supported = harness, metric, false
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def report
|
|
153
|
-
if @supported
|
|
154
|
-
rate = @total / full_profile_options[:runs]
|
|
155
|
-
'%20s: %s' % [@metric.name, @metric.format(rate)]
|
|
156
|
-
else
|
|
157
|
-
'%20s: unsupported' % @metric.name
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
protected
|
|
162
|
-
def output_filename
|
|
163
|
-
"#{full_profile_options[:output]}/#{full_test_name}_#{@metric.name}"
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
# overridden by each implementation
|
|
168
|
-
class Profiler < Performer
|
|
169
|
-
def time_with_block
|
|
170
|
-
before = Time.now
|
|
171
|
-
yield
|
|
172
|
-
Time.now - before
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def run; end
|
|
176
|
-
def record; end
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
class Benchmarker < Performer
|
|
180
|
-
def initialize(*args)
|
|
181
|
-
super
|
|
182
|
-
@supported = @metric.respond_to?('measure')
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
def run
|
|
186
|
-
return unless @supported
|
|
187
|
-
|
|
188
|
-
full_profile_options[:runs].to_i.times { run_test(@metric, :benchmark) }
|
|
189
|
-
@total = @metric.total
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
def record
|
|
193
|
-
avg = @metric.total / full_profile_options[:runs].to_i
|
|
194
|
-
now = Time.now.utc.xmlschema
|
|
195
|
-
with_output_file do |file|
|
|
196
|
-
file.puts "#{avg},#{now},#{environment}"
|
|
197
|
-
end
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
def environment
|
|
201
|
-
unless defined? @env
|
|
202
|
-
app = "#{$1}.#{$2}" if File.directory?('.git') && `git branch -v` =~ /^\* (\S+)\s+(\S+)/
|
|
203
|
-
|
|
204
|
-
rails = Rails::VERSION::STRING
|
|
205
|
-
if File.directory?('vendor/rails/.git')
|
|
206
|
-
Dir.chdir('vendor/rails') do
|
|
207
|
-
rails += ".#{$1}.#{$2}" if `git branch -v` =~ /^\* (\S+)\s+(\S+)/
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
ruby = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
|
212
|
-
ruby += "-#{RUBY_VERSION}.#{RUBY_PATCHLEVEL}"
|
|
213
|
-
|
|
214
|
-
@env = [app, rails, ruby, RUBY_PLATFORM] * ','
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
@env
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
protected
|
|
221
|
-
HEADER = 'measurement,created_at,app,rails,ruby,platform'
|
|
222
|
-
|
|
223
|
-
def with_output_file
|
|
224
|
-
fname = output_filename
|
|
225
|
-
|
|
226
|
-
if new = !File.exist?(fname)
|
|
227
|
-
FileUtils.mkdir_p(File.dirname(fname))
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
File.open(fname, 'ab') do |file|
|
|
231
|
-
file.puts(HEADER) if new
|
|
232
|
-
yield file
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
def output_filename
|
|
237
|
-
"#{super}.csv"
|
|
238
|
-
end
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
module Metrics
|
|
242
|
-
def self.[](name)
|
|
243
|
-
const_get(name.to_s.camelize)
|
|
244
|
-
rescue NameError
|
|
245
|
-
nil
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
class Base
|
|
249
|
-
include ActionView::Helpers::NumberHelper
|
|
250
|
-
|
|
251
|
-
attr_reader :total
|
|
252
|
-
|
|
253
|
-
def initialize
|
|
254
|
-
@total = 0
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
def name
|
|
258
|
-
@name ||= self.class.name.demodulize.underscore
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
def benchmark
|
|
262
|
-
with_gc_stats do
|
|
263
|
-
before = measure
|
|
264
|
-
yield
|
|
265
|
-
@total += (measure - before)
|
|
266
|
-
end
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
# overridden by each implementation
|
|
270
|
-
def profile; end
|
|
271
|
-
|
|
272
|
-
protected
|
|
273
|
-
# overridden by each implementation
|
|
274
|
-
def with_gc_stats; end
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
class Time < Base
|
|
278
|
-
def measure
|
|
279
|
-
::Time.now.to_f
|
|
280
|
-
end
|
|
281
|
-
|
|
282
|
-
def format(measurement)
|
|
283
|
-
if measurement < 1
|
|
284
|
-
'%d ms' % (measurement * 1000)
|
|
285
|
-
else
|
|
286
|
-
'%.2f sec' % measurement
|
|
287
|
-
end
|
|
288
|
-
end
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
class Amount < Base
|
|
292
|
-
def format(measurement)
|
|
293
|
-
number_with_delimiter(measurement.floor)
|
|
294
|
-
end
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
class DigitalInformationUnit < Base
|
|
298
|
-
def format(measurement)
|
|
299
|
-
number_to_human_size(measurement, :precision => 2)
|
|
300
|
-
end
|
|
301
|
-
end
|
|
302
|
-
|
|
303
|
-
# each implementation provides its own metrics like ProcessTime, Memory or GcRuns
|
|
304
|
-
end
|
|
305
|
-
end
|
|
306
|
-
end
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
RUBY_ENGINE = 'ruby' unless defined?(RUBY_ENGINE) # mri 1.8
|
|
310
|
-
case RUBY_ENGINE
|
|
311
|
-
when 'ruby' then require 'active_support/testing/performance/ruby'
|
|
312
|
-
when 'rbx' then require 'active_support/testing/performance/rubinius'
|
|
313
|
-
when 'jruby' then require 'active_support/testing/performance/jruby'
|
|
314
|
-
else
|
|
315
|
-
$stderr.puts 'Your ruby interpreter is not supported for benchmarking.'
|
|
316
|
-
exit
|
|
317
|
-
end
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
require 'active_support/deprecation'
|
|
2
|
-
|
|
3
|
-
# Extensions to +nil+ which allow for more helpful error messages for people who
|
|
4
|
-
# are new to Rails.
|
|
5
|
-
#
|
|
6
|
-
# NilClass#id exists in Ruby 1.8 (though it is deprecated). Since +id+ is a fundamental
|
|
7
|
-
# method of Active Record models NilClass#id is redefined as well to raise a RuntimeError
|
|
8
|
-
# and warn the user. She probably wanted a model database identifier and the 4
|
|
9
|
-
# returned by the original method could result in obscure bugs.
|
|
10
|
-
#
|
|
11
|
-
# The flag <tt>config.whiny_nils</tt> determines whether this feature is enabled.
|
|
12
|
-
# By default it is on in development and test modes, and it is off in production
|
|
13
|
-
# mode.
|
|
14
|
-
class NilClass
|
|
15
|
-
def self.add_whiner(klass)
|
|
16
|
-
ActiveSupport::Deprecation.warn "NilClass.add_whiner is deprecated and this functionality is " \
|
|
17
|
-
"removed from Rails versions as it affects Ruby 1.9 performance.", caller
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# Raises a RuntimeError when you attempt to call +id+ on +nil+.
|
|
21
|
-
def id
|
|
22
|
-
raise RuntimeError, "Called id for nil, which would mistakenly be #{object_id} -- if you really wanted the id of nil, use object_id", caller
|
|
23
|
-
end
|
|
24
|
-
end
|