activesupport 3.2.22.5 → 4.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +325 -136
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -2
- data/lib/active_support.rb +8 -21
- 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.rb +203 -171
- data/lib/active_support/cache/file_store.rb +12 -12
- 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/callbacks.rb +195 -247
- 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.rb +1 -0
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/array/access.rb +17 -9
- data/lib/active_support/core_ext/array/conversions.rb +113 -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 +11 -14
- data/lib/active_support/core_ext/big_decimal/conversions.rb +7 -24
- data/lib/active_support/core_ext/class/attribute.rb +12 -8
- 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.rb +6 -0
- data/lib/active_support/core_ext/date/calculations.rb +34 -188
- data/lib/active_support/core_ext/date/conversions.rb +16 -38
- data/lib/active_support/core_ext/date/infinite_comparable.rb +5 -0
- data/lib/active_support/core_ext/date/zones.rb +25 -2
- data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
- data/lib/active_support/core_ext/date_time.rb +5 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +73 -65
- data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
- data/lib/active_support/core_ext/date_time/infinite_comparable.rb +5 -0
- data/lib/active_support/core_ext/date_time/zones.rb +11 -8
- data/lib/active_support/core_ext/enumerable.rb +26 -73
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/file/atomic.rb +27 -11
- data/lib/active_support/core_ext/hash.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/infinite_comparable.rb +35 -0
- 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 +19 -0
- data/lib/active_support/core_ext/module.rb +1 -3
- 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 +57 -40
- 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/numeric.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
- data/lib/active_support/core_ext/numeric/infinite_comparable.rb +9 -0
- data/lib/active_support/core_ext/numeric/time.rb +6 -6
- data/lib/active_support/core_ext/object.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 +6 -6
- 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/proc.rb +3 -0
- data/lib/active_support/core_ext/range.rb +0 -2
- data/lib/active_support/core_ext/range/conversions.rb +0 -2
- data/lib/active_support/core_ext/range/include_range.rb +1 -1
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/string.rb +2 -2
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/conversions.rb +29 -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/struct.rb +6 -0
- data/lib/active_support/core_ext/thread.rb +74 -0
- data/lib/active_support/core_ext/time.rb +6 -0
- data/lib/active_support/core_ext/time/calculations.rb +105 -193
- data/lib/active_support/core_ext/time/conversions.rb +27 -51
- data/lib/active_support/core_ext/time/infinite_comparable.rb +5 -0
- 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/uri.rb +13 -17
- data/lib/active_support/dependencies.rb +160 -141
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/deprecation.rb +39 -14
- 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/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 +112 -37
- 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.rb +56 -36
- data/lib/active_support/log_subscriber/test_helper.rb +18 -15
- data/lib/active_support/logger.rb +57 -0
- data/lib/active_support/logger_silence.rb +24 -0
- data/lib/active_support/message_encryptor.rb +32 -29
- data/lib/active_support/message_verifier.rb +8 -14
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/multibyte/chars.rb +80 -333
- data/lib/active_support/multibyte/unicode.rb +74 -64
- data/lib/active_support/notifications.rb +57 -25
- data/lib/active_support/notifications/fanout.rb +105 -18
- data/lib/active_support/notifications/instrumenter.rb +32 -13
- data/lib/active_support/number_helper.rb +636 -0
- data/lib/active_support/ordered_hash.rb +8 -190
- data/lib/active_support/ordered_options.rb +21 -23
- 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/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 +52 -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 +25 -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 +78 -43
- data/lib/active_support/values/time_zone.rb +77 -58
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +4 -4
- data/lib/active_support/xml_mini.rb +35 -17
- data/lib/active_support/xml_mini/jdom.rb +9 -17
- data/lib/active_support/xml_mini/libxml.rb +1 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -2
- data/lib/active_support/xml_mini/nokogiri.rb +1 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -2
- data/lib/active_support/xml_mini/rexml.rb +6 -8
- metadata +107 -77
- 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.rb +0 -1
- data/lib/active_support/core_ext/float/rounding.rb +0 -19
- 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.rb +0 -1
- data/lib/active_support/core_ext/process/daemon.rb +0 -23
- 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/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.rb +0 -317
- 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.rb +0 -152
- 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/time/autoload.rb +0 -5
- data/lib/active_support/whiny_nil.rb +0 -24
@@ -1,60 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module ActiveSupport #:nodoc:
|
4
|
-
module Multibyte #:nodoc:
|
5
|
-
if Kernel.const_defined?(:Encoding)
|
6
|
-
# Returns a regular expression that matches valid characters in the current encoding
|
7
|
-
def self.valid_character
|
8
|
-
VALID_CHARACTER[Encoding.default_external.to_s]
|
9
|
-
end
|
10
|
-
else
|
11
|
-
def self.valid_character
|
12
|
-
case $KCODE
|
13
|
-
when 'UTF8'
|
14
|
-
VALID_CHARACTER['UTF-8']
|
15
|
-
when 'SJIS'
|
16
|
-
VALID_CHARACTER['Shift_JIS']
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
if 'string'.respond_to?(:valid_encoding?)
|
22
|
-
# Verifies the encoding of a string
|
23
|
-
def self.verify(string)
|
24
|
-
string.valid_encoding?
|
25
|
-
end
|
26
|
-
else
|
27
|
-
def self.verify(string)
|
28
|
-
if expression = valid_character
|
29
|
-
# Splits the string on character boundaries, which are determined based on $KCODE.
|
30
|
-
string.split(//).all? { |c| expression =~ c }
|
31
|
-
else
|
32
|
-
true
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# Verifies the encoding of the string and raises an exception when it's not valid
|
38
|
-
def self.verify!(string)
|
39
|
-
raise EncodingError.new("Found characters with invalid encoding") unless verify(string)
|
40
|
-
end
|
41
|
-
|
42
|
-
if 'string'.respond_to?(:force_encoding)
|
43
|
-
# Removes all invalid characters from the string.
|
44
|
-
#
|
45
|
-
# Note: this method is a no-op in Ruby 1.9
|
46
|
-
def self.clean(string)
|
47
|
-
string
|
48
|
-
end
|
49
|
-
else
|
50
|
-
def self.clean(string)
|
51
|
-
if expression = valid_character
|
52
|
-
# Splits the string on character boundaries, which are determined based on $KCODE.
|
53
|
-
string.split(//).grep(expression).join
|
54
|
-
else
|
55
|
-
string
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
# Backported Ruby builtins so you can code with the latest & greatest
|
2
|
-
# but still run on any Ruby 1.8.x.
|
3
|
-
#
|
4
|
-
# Date next_year, next_month
|
5
|
-
# DateTime to_date, to_datetime, xmlschema
|
6
|
-
# Enumerable group_by, each_with_object, none?
|
7
|
-
# Process Process.daemon
|
8
|
-
# REXML security fix
|
9
|
-
# String ord
|
10
|
-
# Time to_date, to_time, to_datetime
|
11
|
-
require 'active_support'
|
12
|
-
require 'active_support/core_ext/date/calculations'
|
13
|
-
require 'active_support/core_ext/date_time/conversions'
|
14
|
-
require 'active_support/core_ext/enumerable'
|
15
|
-
require 'active_support/core_ext/process/daemon'
|
16
|
-
require 'active_support/core_ext/string/conversions'
|
17
|
-
require 'active_support/core_ext/string/interpolation'
|
18
|
-
require 'active_support/core_ext/string/encoding'
|
19
|
-
require 'active_support/core_ext/rexml'
|
20
|
-
require 'active_support/core_ext/time/conversions'
|
21
|
-
require 'active_support/core_ext/file/path'
|
22
|
-
require 'active_support/core_ext/module/method_names'
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'digest'
|
2
|
-
|
3
|
-
module ActiveSupport
|
4
|
-
module SecurityUtils
|
5
|
-
# Constant time string comparison.
|
6
|
-
#
|
7
|
-
# The values compared should be of fixed length, such as strings
|
8
|
-
# that have already been processed by HMAC. This should not be used
|
9
|
-
# on variable length plaintext strings because it could leak length info
|
10
|
-
# via timing attacks.
|
11
|
-
def secure_compare(a, b)
|
12
|
-
return false unless a.bytesize == b.bytesize
|
13
|
-
|
14
|
-
l = a.unpack "C#{a.bytesize}"
|
15
|
-
|
16
|
-
res = 0
|
17
|
-
b.each_byte { |byte| res |= byte ^ l.shift }
|
18
|
-
res == 0
|
19
|
-
end
|
20
|
-
module_function :secure_compare
|
21
|
-
|
22
|
-
def variable_size_secure_compare(a, b) # :nodoc:
|
23
|
-
secure_compare(::Digest::SHA256.hexdigest(a), ::Digest::SHA256.hexdigest(b))
|
24
|
-
end
|
25
|
-
module_function :variable_size_secure_compare
|
26
|
-
end
|
27
|
-
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,115 +0,0 @@
|
|
1
|
-
require 'jruby/profiler'
|
2
|
-
require 'java'
|
3
|
-
java_import java.lang.management.ManagementFactory
|
4
|
-
|
5
|
-
module ActiveSupport
|
6
|
-
module Testing
|
7
|
-
module Performance
|
8
|
-
DEFAULTS.merge!(
|
9
|
-
if ENV["BENCHMARK_TESTS"]
|
10
|
-
{:metrics => [:wall_time, :user_time, :memory, :gc_runs, :gc_time]}
|
11
|
-
else
|
12
|
-
{ :metrics => [:wall_time],
|
13
|
-
:formats => [:flat, :graph] }
|
14
|
-
end).freeze
|
15
|
-
|
16
|
-
protected
|
17
|
-
def run_gc
|
18
|
-
ManagementFactory.memory_mx_bean.gc
|
19
|
-
end
|
20
|
-
|
21
|
-
class Profiler < Performer
|
22
|
-
def initialize(*args)
|
23
|
-
super
|
24
|
-
@supported = @metric.is_a?(Metrics::WallTime)
|
25
|
-
end
|
26
|
-
|
27
|
-
def run
|
28
|
-
return unless @supported
|
29
|
-
|
30
|
-
@total = time_with_block do
|
31
|
-
@data = JRuby::Profiler.profile do
|
32
|
-
full_profile_options[:runs].to_i.times { run_test(@metric, :profile) }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def record
|
38
|
-
return unless @supported
|
39
|
-
|
40
|
-
klasses = full_profile_options[:formats].map { |f| JRuby::Profiler.const_get("#{f.to_s.camelize}ProfilePrinter") }.compact
|
41
|
-
|
42
|
-
klasses.each do |klass|
|
43
|
-
fname = output_filename(klass)
|
44
|
-
FileUtils.mkdir_p(File.dirname(fname))
|
45
|
-
file = File.open(fname, 'wb') do |file|
|
46
|
-
klass.new(@data).printProfile(file)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
protected
|
52
|
-
def output_filename(printer_class)
|
53
|
-
suffix =
|
54
|
-
case printer_class.name.demodulize
|
55
|
-
when 'FlatProfilePrinter'; 'flat.txt'
|
56
|
-
when 'GraphProfilePrinter'; 'graph.txt'
|
57
|
-
else printer_class.name.sub(/ProfilePrinter$/, '').underscore
|
58
|
-
end
|
59
|
-
|
60
|
-
"#{super()}_#{suffix}"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
module Metrics
|
65
|
-
class Base
|
66
|
-
def profile
|
67
|
-
yield
|
68
|
-
end
|
69
|
-
|
70
|
-
protected
|
71
|
-
def with_gc_stats
|
72
|
-
ManagementFactory.memory_mx_bean.gc
|
73
|
-
yield
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
class WallTime < Time
|
78
|
-
def measure
|
79
|
-
super
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
class CpuTime < Time
|
84
|
-
def measure
|
85
|
-
ManagementFactory.thread_mx_bean.get_current_thread_cpu_time / 1000 / 1000 / 1000.0 # seconds
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
class UserTime < Time
|
90
|
-
def measure
|
91
|
-
ManagementFactory.thread_mx_bean.get_current_thread_user_time / 1000 / 1000 / 1000.0 # seconds
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
class Memory < DigitalInformationUnit
|
96
|
-
def measure
|
97
|
-
ManagementFactory.memory_mx_bean.non_heap_memory_usage.used + ManagementFactory.memory_mx_bean.heap_memory_usage.used
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
class GcRuns < Amount
|
102
|
-
def measure
|
103
|
-
ManagementFactory.garbage_collector_mx_beans.inject(0) { |total_runs, current_gc| total_runs += current_gc.collection_count }
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
class GcTime < Time
|
108
|
-
def measure
|
109
|
-
ManagementFactory.garbage_collector_mx_beans.inject(0) { |total_time, current_gc| total_time += current_gc.collection_time } / 1000.0 # seconds
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|