csd 0.0.15 → 0.0.16

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 (256) hide show
  1. data/.gitignore +1 -0
  2. data/COPYING +367 -0
  3. data/Rakefile +10 -10
  4. data/VERSION +1 -1
  5. data/bin/ai +19 -0
  6. data/csd.gemspec +257 -35
  7. data/lib/active_support.rb +75 -0
  8. data/lib/active_support/all.rb +3 -0
  9. data/lib/active_support/backtrace_cleaner.rb +94 -0
  10. data/lib/active_support/base64.rb +42 -0
  11. data/lib/active_support/basic_object.rb +21 -0
  12. data/lib/active_support/benchmarkable.rb +60 -0
  13. data/lib/active_support/buffered_logger.rb +132 -0
  14. data/lib/active_support/builder.rb +6 -0
  15. data/lib/active_support/cache.rb +626 -0
  16. data/lib/active_support/cache/compressed_mem_cache_store.rb +13 -0
  17. data/lib/active_support/cache/file_store.rb +188 -0
  18. data/lib/active_support/cache/mem_cache_store.rb +191 -0
  19. data/lib/active_support/cache/memory_store.rb +159 -0
  20. data/lib/active_support/cache/strategy/local_cache.rb +164 -0
  21. data/lib/active_support/cache/synchronized_memory_store.rb +11 -0
  22. data/lib/active_support/callbacks.rb +600 -0
  23. data/lib/active_support/concern.rb +29 -0
  24. data/lib/active_support/configurable.rb +36 -0
  25. data/lib/active_support/core_ext.rb +3 -0
  26. data/lib/active_support/core_ext/array.rb +7 -0
  27. data/lib/active_support/core_ext/array/access.rb +46 -0
  28. data/lib/active_support/core_ext/array/conversions.rb +164 -0
  29. data/lib/active_support/core_ext/array/extract_options.rb +29 -0
  30. data/lib/active_support/core_ext/array/grouping.rb +100 -0
  31. data/lib/active_support/core_ext/array/random_access.rb +20 -0
  32. data/lib/active_support/core_ext/array/uniq_by.rb +17 -0
  33. data/lib/active_support/core_ext/array/wrap.rb +22 -0
  34. data/lib/active_support/core_ext/benchmark.rb +7 -0
  35. data/lib/active_support/core_ext/big_decimal.rb +1 -0
  36. data/lib/active_support/core_ext/big_decimal/conversions.rb +27 -0
  37. data/lib/active_support/core_ext/cgi.rb +1 -0
  38. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +19 -0
  39. data/lib/active_support/core_ext/class.rb +4 -0
  40. data/lib/active_support/core_ext/class/attribute.rb +67 -0
  41. data/lib/active_support/core_ext/class/attribute_accessors.rb +63 -0
  42. data/lib/active_support/core_ext/class/delegating_attributes.rb +44 -0
  43. data/lib/active_support/core_ext/class/inheritable_attributes.rb +232 -0
  44. data/lib/active_support/core_ext/class/subclasses.rb +55 -0
  45. data/lib/active_support/core_ext/date/acts_like.rb +8 -0
  46. data/lib/active_support/core_ext/date/calculations.rb +240 -0
  47. data/lib/active_support/core_ext/date/conversions.rb +99 -0
  48. data/lib/active_support/core_ext/date/freeze.rb +31 -0
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +13 -0
  50. data/lib/active_support/core_ext/date_time/calculations.rb +113 -0
  51. data/lib/active_support/core_ext/date_time/conversions.rb +102 -0
  52. data/lib/active_support/core_ext/date_time/zones.rb +17 -0
  53. data/lib/active_support/core_ext/enumerable.rb +119 -0
  54. data/lib/active_support/core_ext/exception.rb +3 -0
  55. data/lib/active_support/core_ext/file.rb +2 -0
  56. data/lib/active_support/core_ext/file/atomic.rb +41 -0
  57. data/lib/active_support/core_ext/file/path.rb +5 -0
  58. data/lib/active_support/core_ext/float.rb +1 -0
  59. data/lib/active_support/core_ext/float/rounding.rb +19 -0
  60. data/lib/active_support/core_ext/hash.rb +8 -0
  61. data/lib/active_support/core_ext/hash/conversions.rb +150 -0
  62. data/lib/active_support/core_ext/hash/deep_merge.rb +16 -0
  63. data/lib/active_support/core_ext/hash/diff.rb +13 -0
  64. data/lib/active_support/core_ext/hash/except.rb +24 -0
  65. data/lib/active_support/core_ext/hash/indifferent_access.rb +14 -0
  66. data/lib/active_support/core_ext/hash/keys.rb +45 -0
  67. data/lib/active_support/core_ext/hash/reverse_merge.rb +28 -0
  68. data/lib/active_support/core_ext/hash/slice.rb +38 -0
  69. data/lib/active_support/core_ext/integer.rb +3 -0
  70. data/lib/active_support/core_ext/integer/inflections.rb +14 -0
  71. data/lib/active_support/core_ext/integer/multiple.rb +6 -0
  72. data/lib/active_support/core_ext/integer/time.rb +39 -0
  73. data/lib/active_support/core_ext/kernel.rb +5 -0
  74. data/lib/active_support/core_ext/kernel/agnostics.rb +11 -0
  75. data/lib/active_support/core_ext/kernel/debugger.rb +16 -0
  76. data/lib/active_support/core_ext/kernel/reporting.rb +62 -0
  77. data/lib/active_support/core_ext/kernel/requires.rb +26 -0
  78. data/lib/active_support/core_ext/kernel/singleton_class.rb +13 -0
  79. data/lib/active_support/core_ext/load_error.rb +23 -0
  80. data/lib/active_support/core_ext/logger.rb +146 -0
  81. data/lib/active_support/core_ext/module.rb +12 -0
  82. data/lib/active_support/core_ext/module/aliasing.rb +70 -0
  83. data/lib/active_support/core_ext/module/anonymous.rb +24 -0
  84. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +31 -0
  85. data/lib/active_support/core_ext/module/attr_internal.rb +32 -0
  86. data/lib/active_support/core_ext/module/attribute_accessors.rb +66 -0
  87. data/lib/active_support/core_ext/module/delegation.rb +146 -0
  88. data/lib/active_support/core_ext/module/deprecation.rb +9 -0
  89. data/lib/active_support/core_ext/module/introspection.rb +88 -0
  90. data/lib/active_support/core_ext/module/method_names.rb +14 -0
  91. data/lib/active_support/core_ext/module/reachable.rb +10 -0
  92. data/lib/active_support/core_ext/module/remove_method.rb +6 -0
  93. data/lib/active_support/core_ext/module/synchronization.rb +42 -0
  94. data/lib/active_support/core_ext/name_error.rb +18 -0
  95. data/lib/active_support/core_ext/numeric.rb +2 -0
  96. data/lib/active_support/core_ext/numeric/bytes.rb +44 -0
  97. data/lib/active_support/core_ext/numeric/time.rb +77 -0
  98. data/lib/active_support/core_ext/object.rb +14 -0
  99. data/lib/active_support/core_ext/object/acts_like.rb +10 -0
  100. data/lib/active_support/core_ext/object/blank.rb +76 -0
  101. data/lib/active_support/core_ext/object/conversions.rb +4 -0
  102. data/lib/active_support/core_ext/object/duplicable.rb +65 -0
  103. data/lib/active_support/core_ext/object/extending.rb +11 -0
  104. data/lib/active_support/core_ext/object/instance_variables.rb +67 -0
  105. data/lib/active_support/core_ext/object/misc.rb +2 -0
  106. data/lib/active_support/core_ext/object/returning.rb +42 -0
  107. data/lib/active_support/core_ext/object/to_param.rb +49 -0
  108. data/lib/active_support/core_ext/object/to_query.rb +27 -0
  109. data/lib/active_support/core_ext/object/try.rb +36 -0
  110. data/lib/active_support/core_ext/object/with_options.rb +26 -0
  111. data/lib/active_support/core_ext/proc.rb +14 -0
  112. data/lib/active_support/core_ext/process.rb +1 -0
  113. data/lib/active_support/core_ext/process/daemon.rb +23 -0
  114. data/lib/active_support/core_ext/range.rb +4 -0
  115. data/lib/active_support/core_ext/range/blockless_step.rb +29 -0
  116. data/lib/active_support/core_ext/range/conversions.rb +21 -0
  117. data/lib/active_support/core_ext/range/include_range.rb +21 -0
  118. data/lib/active_support/core_ext/range/overlaps.rb +8 -0
  119. data/lib/active_support/core_ext/regexp.rb +5 -0
  120. data/lib/active_support/core_ext/rexml.rb +46 -0
  121. data/lib/active_support/core_ext/string.rb +12 -0
  122. data/lib/active_support/core_ext/string/access.rb +99 -0
  123. data/lib/active_support/core_ext/string/behavior.rb +7 -0
  124. data/lib/active_support/core_ext/string/conversions.rb +61 -0
  125. data/lib/active_support/core_ext/string/encoding.rb +11 -0
  126. data/lib/active_support/core_ext/string/exclude.rb +6 -0
  127. data/lib/active_support/core_ext/string/filters.rb +49 -0
  128. data/lib/active_support/core_ext/string/inflections.rb +149 -0
  129. data/lib/active_support/core_ext/string/interpolation.rb +2 -0
  130. data/lib/active_support/core_ext/string/multibyte.rb +72 -0
  131. data/lib/active_support/core_ext/string/output_safety.rb +109 -0
  132. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -0
  133. data/lib/active_support/core_ext/string/xchar.rb +18 -0
  134. data/lib/active_support/core_ext/time/acts_like.rb +8 -0
  135. data/lib/active_support/core_ext/time/calculations.rb +282 -0
  136. data/lib/active_support/core_ext/time/conversions.rb +85 -0
  137. data/lib/active_support/core_ext/time/marshal.rb +56 -0
  138. data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +10 -0
  139. data/lib/active_support/core_ext/time/zones.rb +78 -0
  140. data/lib/active_support/core_ext/uri.rb +22 -0
  141. data/lib/active_support/dependencies.rb +628 -0
  142. data/lib/active_support/dependencies/autoload.rb +50 -0
  143. data/lib/active_support/deprecation.rb +18 -0
  144. data/lib/active_support/deprecation/behaviors.rb +38 -0
  145. data/lib/active_support/deprecation/method_wrappers.rb +29 -0
  146. data/lib/active_support/deprecation/proxy_wrappers.rb +74 -0
  147. data/lib/active_support/deprecation/reporting.rb +56 -0
  148. data/lib/active_support/duration.rb +105 -0
  149. data/lib/active_support/gzip.rb +25 -0
  150. data/lib/active_support/hash_with_indifferent_access.rb +145 -0
  151. data/lib/active_support/i18n.rb +8 -0
  152. data/lib/active_support/inflections.rb +56 -0
  153. data/lib/active_support/inflector.rb +7 -0
  154. data/lib/active_support/inflector/inflections.rb +211 -0
  155. data/lib/active_support/inflector/methods.rb +141 -0
  156. data/lib/active_support/inflector/transliterate.rb +97 -0
  157. data/lib/active_support/json.rb +2 -0
  158. data/lib/active_support/json/backends/jsongem.rb +43 -0
  159. data/lib/active_support/json/backends/yajl.rb +40 -0
  160. data/lib/active_support/json/backends/yaml.rb +90 -0
  161. data/lib/active_support/json/decoding.rb +51 -0
  162. data/lib/active_support/json/encoding.rb +254 -0
  163. data/lib/active_support/json/variable.rb +11 -0
  164. data/lib/active_support/lazy_load_hooks.rb +27 -0
  165. data/lib/active_support/locale/en.yml +36 -0
  166. data/lib/active_support/memoizable.rb +103 -0
  167. data/lib/active_support/message_encryptor.rb +71 -0
  168. data/lib/active_support/message_verifier.rb +62 -0
  169. data/lib/active_support/multibyte.rb +44 -0
  170. data/lib/active_support/multibyte/chars.rb +480 -0
  171. data/lib/active_support/multibyte/exceptions.rb +8 -0
  172. data/lib/active_support/multibyte/unicode.rb +393 -0
  173. data/lib/active_support/multibyte/utils.rb +60 -0
  174. data/lib/active_support/notifications.rb +81 -0
  175. data/lib/active_support/notifications/fanout.rb +93 -0
  176. data/lib/active_support/notifications/instrumenter.rb +56 -0
  177. data/lib/active_support/option_merger.rb +25 -0
  178. data/lib/active_support/ordered_hash.rb +158 -0
  179. data/lib/active_support/ordered_options.rb +27 -0
  180. data/lib/active_support/railtie.rb +100 -0
  181. data/lib/active_support/rescuable.rb +114 -0
  182. data/lib/active_support/ruby/shim.rb +22 -0
  183. data/lib/active_support/secure_random.rb +199 -0
  184. data/lib/active_support/string_inquirer.rb +21 -0
  185. data/lib/active_support/test_case.rb +42 -0
  186. data/lib/active_support/testing/assertions.rb +82 -0
  187. data/lib/active_support/testing/declarative.rb +40 -0
  188. data/lib/active_support/testing/default.rb +9 -0
  189. data/lib/active_support/testing/deprecation.rb +55 -0
  190. data/lib/active_support/testing/isolation.rb +154 -0
  191. data/lib/active_support/testing/pending.rb +48 -0
  192. data/lib/active_support/testing/performance.rb +455 -0
  193. data/lib/active_support/testing/setup_and_teardown.rb +111 -0
  194. data/lib/active_support/time.rb +34 -0
  195. data/lib/active_support/time/autoload.rb +5 -0
  196. data/lib/active_support/time_with_zone.rb +341 -0
  197. data/lib/active_support/values/time_zone.rb +377 -0
  198. data/lib/active_support/values/unicode_tables.dat +0 -0
  199. data/lib/active_support/version.rb +10 -0
  200. data/lib/active_support/whiny_nil.rb +60 -0
  201. data/lib/active_support/xml_mini.rb +158 -0
  202. data/lib/active_support/xml_mini/jdom.rb +168 -0
  203. data/lib/active_support/xml_mini/libxml.rb +80 -0
  204. data/lib/active_support/xml_mini/libxmlsax.rb +85 -0
  205. data/lib/active_support/xml_mini/nokogiri.rb +78 -0
  206. data/lib/active_support/xml_mini/nokogirisax.rb +83 -0
  207. data/lib/active_support/xml_mini/rexml.rb +129 -0
  208. data/lib/csd.rb +82 -2
  209. data/lib/csd/application.rb +2 -0
  210. data/lib/csd/application/default.rb +51 -0
  211. data/lib/csd/application/default/base.rb +15 -0
  212. data/lib/csd/application/minisip.rb +25 -0
  213. data/lib/csd/application/minisip/about.yml +14 -0
  214. data/lib/csd/application/minisip/base.rb +161 -0
  215. data/lib/csd/application/minisip/error.rb +11 -0
  216. data/lib/csd/application/minisip/options/common.rb +0 -0
  217. data/lib/csd/application/minisip/options/compile.rb +59 -0
  218. data/lib/csd/{applications → application}/minisip/unix/base.rb +10 -11
  219. data/lib/csd/application/opensips/about.yml +2 -0
  220. data/lib/csd/applications.rb +55 -0
  221. data/lib/csd/commands.rb +88 -65
  222. data/lib/csd/error.rb +31 -0
  223. data/lib/csd/extensions.rb +1 -0
  224. data/lib/{extensions → csd/extensions}/core/array.rb +2 -2
  225. data/lib/csd/extensions/core/dir.rb +46 -0
  226. data/lib/{extensions → csd/extensions}/core/file.rb +2 -2
  227. data/lib/{extensions → csd/extensions}/core/object.rb +2 -2
  228. data/lib/csd/extensions/core/option_parser.rb +33 -0
  229. data/lib/{extensions → csd/extensions}/core/pathname.rb +12 -3
  230. data/lib/{extensions → csd/extensions}/core/string.rb +2 -2
  231. data/lib/{extensions → csd/extensions}/gem/platform.rb +6 -2
  232. data/lib/csd/global_open_struct.rb +18 -0
  233. data/lib/csd/options.rb +124 -95
  234. data/lib/csd/path.rb +31 -0
  235. data/lib/csd/ui.rb +1 -0
  236. data/lib/csd/ui/cli.rb +7 -0
  237. data/lib/csd/ui/ui.rb +46 -0
  238. data/lib/csd/version.rb +9 -0
  239. data/lib/term/ansicolor.rb +102 -0
  240. data/lib/term/ansicolor/.keep +0 -0
  241. data/lib/term/ansicolor/version.rb +10 -0
  242. data/test/functional/test_applications.rb +86 -0
  243. data/test/functional/test_commands.rb +42 -29
  244. data/test/functional/test_options.rb +98 -0
  245. data/test/helper.rb +14 -0
  246. data/test/unit/test_dir.rb +38 -0
  247. data/test/unit/test_pathname.rb +32 -0
  248. metadata +253 -40
  249. data/LICENSE +0 -20
  250. data/bin/csd +0 -8
  251. data/lib/csd/applications/base.rb +0 -33
  252. data/lib/csd/applications/minisip/base.rb +0 -125
  253. data/lib/csd/applications/minisip/init.rb +0 -20
  254. data/lib/csd/init.rb +0 -69
  255. data/lib/csd/path_container.rb +0 -15
  256. data/publish +0 -29
@@ -0,0 +1,40 @@
1
+ module ActiveSupport
2
+ module Testing
3
+ module Declarative
4
+
5
+ def self.extended(klass)
6
+ klass.class_eval do
7
+
8
+ unless method_defined?(:describe)
9
+ def self.describe(text)
10
+ class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
11
+ def self.name
12
+ "#{text}"
13
+ end
14
+ RUBY_EVAL
15
+ end
16
+ end
17
+
18
+ end
19
+ end
20
+
21
+ unless defined?(Spec)
22
+ # test "verify something" do
23
+ # ...
24
+ # end
25
+ def test(name, &block)
26
+ test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
27
+ defined = instance_method(test_name) rescue false
28
+ raise "#{test_name} is already defined in #{self}" if defined
29
+ if block_given?
30
+ define_method(test_name, &block)
31
+ else
32
+ define_method(test_name) do
33
+ flunk "No implementation provided for #{name}"
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveSupport
2
+ module Testing
3
+ module Default #:nodoc:
4
+ # Placeholder so test/unit ignores test cases without any tests.
5
+ def default_test
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,55 @@
1
+ require 'active_support/deprecation'
2
+
3
+ module ActiveSupport
4
+ module Testing
5
+ module Deprecation #:nodoc:
6
+ def assert_deprecated(match = nil, &block)
7
+ result, warnings = collect_deprecations(&block)
8
+ assert !warnings.empty?, "Expected a deprecation warning within the block but received none"
9
+ if match
10
+ match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp)
11
+ assert warnings.any? { |w| w =~ match }, "No deprecation warning matched #{match}: #{warnings.join(', ')}"
12
+ end
13
+ result
14
+ end
15
+
16
+ def assert_not_deprecated(&block)
17
+ result, deprecations = collect_deprecations(&block)
18
+ assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}"
19
+ result
20
+ end
21
+
22
+ private
23
+ def collect_deprecations
24
+ old_behavior = ActiveSupport::Deprecation.behavior
25
+ deprecations = []
26
+ ActiveSupport::Deprecation.behavior = Proc.new do |message, callstack|
27
+ deprecations << message
28
+ end
29
+ result = yield
30
+ [result, deprecations]
31
+ ensure
32
+ ActiveSupport::Deprecation.behavior = old_behavior
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ begin
39
+ require 'test/unit/error'
40
+ rescue LoadError
41
+ # Using miniunit, ignore.
42
+ else
43
+ module Test
44
+ module Unit
45
+ class Error #:nodoc:
46
+ # Silence warnings when reporting test errors.
47
+ def message_with_silenced_deprecation
48
+ ActiveSupport::Deprecation.silence { message_without_silenced_deprecation }
49
+ end
50
+ alias_method :message_without_silenced_deprecation, :message
51
+ alias_method :message, :message_with_silenced_deprecation
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,154 @@
1
+ require 'rbconfig'
2
+ module ActiveSupport
3
+ module Testing
4
+ class RemoteError < StandardError
5
+
6
+ attr_reader :message, :backtrace
7
+
8
+ def initialize(exception)
9
+ @message = "caught #{exception.class.name}: #{exception.message}"
10
+ @backtrace = exception.backtrace
11
+ end
12
+ end
13
+
14
+ class ProxyTestResult
15
+ def initialize
16
+ @calls = []
17
+ end
18
+
19
+ def add_error(e)
20
+ e = Test::Unit::Error.new(e.test_name, RemoteError.new(e.exception))
21
+ @calls << [:add_error, e]
22
+ end
23
+
24
+ def __replay__(result)
25
+ @calls.each do |name, args|
26
+ result.send(name, *args)
27
+ end
28
+ end
29
+
30
+ def method_missing(name, *args)
31
+ @calls << [name, args]
32
+ end
33
+ end
34
+
35
+ module Isolation
36
+ def self.forking_env?
37
+ !ENV["NO_FORK"] && ((Config::CONFIG['host_os'] !~ /mswin|mingw/) && (RUBY_PLATFORM !~ /java/))
38
+ end
39
+
40
+ def self.included(base)
41
+ if defined?(::MiniTest) && base < ::MiniTest::Unit::TestCase
42
+ base.send :include, MiniTest
43
+ elsif defined?(Test::Unit)
44
+ base.send :include, TestUnit
45
+ end
46
+ end
47
+
48
+ module TestUnit
49
+ def run(result)
50
+ unless defined?(@@ran_class_setup)
51
+ self.class.setup if self.class.respond_to?(:setup)
52
+ @@ran_class_setup = true
53
+ end
54
+
55
+ yield(Test::Unit::TestCase::STARTED, name)
56
+
57
+ @_result = result
58
+
59
+ serialized = run_in_isolation do |proxy|
60
+ begin
61
+ super(proxy) { }
62
+ rescue Exception => e
63
+ proxy.add_error(Test::Unit::Error.new(name, e))
64
+ end
65
+ end
66
+
67
+ retval, proxy = Marshal.load(serialized)
68
+ proxy.__replay__(@_result)
69
+
70
+ yield(Test::Unit::TestCase::FINISHED, name)
71
+ retval
72
+ end
73
+ end
74
+
75
+ module MiniTest
76
+ def run(runner)
77
+ unless defined?(@@ran_class_setup)
78
+ self.class.setup if self.class.respond_to?(:setup)
79
+ @@ran_class_setup = true
80
+ end
81
+
82
+ serialized = run_in_isolation do |isolated_runner|
83
+ super(isolated_runner)
84
+ end
85
+
86
+ retval, proxy = Marshal.load(serialized)
87
+ proxy.__replay__(runner)
88
+ retval
89
+ end
90
+ end
91
+
92
+ module Forking
93
+ def run_in_isolation(&blk)
94
+ read, write = IO.pipe
95
+
96
+ pid = fork do
97
+ read.close
98
+ proxy = ProxyTestResult.new
99
+ retval = yield proxy
100
+ write.puts [Marshal.dump([retval, proxy])].pack("m")
101
+ exit!
102
+ end
103
+
104
+ write.close
105
+ result = read.read
106
+ Process.wait2(pid)
107
+ return result.unpack("m")[0]
108
+ end
109
+ end
110
+
111
+ module Subprocess
112
+ # Crazy H4X to get this working in windows / jruby with
113
+ # no forking.
114
+ def run_in_isolation(&blk)
115
+ require "tempfile"
116
+
117
+ if ENV["ISOLATION_TEST"]
118
+ proxy = ProxyTestResult.new
119
+ retval = yield proxy
120
+ File.open(ENV["ISOLATION_OUTPUT"], "w") do |file|
121
+ file.puts [Marshal.dump([retval, proxy])].pack("m")
122
+ end
123
+ exit!
124
+ else
125
+ Tempfile.open("isolation") do |tmpfile|
126
+ ENV["ISOLATION_TEST"] = @method_name
127
+ ENV["ISOLATION_OUTPUT"] = tmpfile.path
128
+
129
+ load_paths = $-I.map {|p| "-I\"#{File.expand_path(p)}\"" }.join(" ")
130
+ `#{Gem.ruby} #{load_paths} #{$0} #{ORIG_ARGV.join(" ")} -t\"#{self.class}\"`
131
+
132
+ ENV.delete("ISOLATION_TEST")
133
+ ENV.delete("ISOLATION_OUTPUT")
134
+
135
+ return tmpfile.read.unpack("m")[0]
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ include forking_env? ? Forking : Subprocess
142
+ end
143
+ end
144
+ end
145
+
146
+ # Only in subprocess for windows / jruby.
147
+ if ENV['ISOLATION_TEST']
148
+ require "test/unit/collector/objectspace"
149
+ class Test::Unit::Collector::ObjectSpace
150
+ def include?(test)
151
+ super && test.method_name == ENV['ISOLATION_TEST']
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,48 @@
1
+ # Some code from jeremymcanally's "pending"
2
+ # http://github.com/jeremymcanally/pending/tree/master
3
+
4
+ module ActiveSupport
5
+ module Testing
6
+ module Pending
7
+
8
+ unless defined?(Spec)
9
+
10
+ @@pending_cases = []
11
+ @@at_exit = false
12
+
13
+ def pending(description = "", &block)
14
+ if description.is_a?(Symbol)
15
+ is_pending = $tags[description]
16
+ return block.call unless is_pending
17
+ end
18
+
19
+ if block_given?
20
+ failed = false
21
+
22
+ begin
23
+ block.call
24
+ rescue Exception
25
+ failed = true
26
+ end
27
+
28
+ flunk("<#{description}> did not fail.") unless failed
29
+ end
30
+
31
+ caller[0] =~ (/(.*):(.*):in `(.*)'/)
32
+ @@pending_cases << "#{$3} at #{$1}, line #{$2}"
33
+ print "P"
34
+
35
+ @@at_exit ||= begin
36
+ at_exit do
37
+ puts "\nPending Cases:"
38
+ @@pending_cases.each do |test_case|
39
+ puts test_case
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,455 @@
1
+ begin
2
+ require 'ruby-prof'
3
+
4
+ require 'fileutils'
5
+ require 'rails/version'
6
+ require 'active_support/core_ext/class/delegating_attributes'
7
+ require 'active_support/core_ext/string/inflections'
8
+
9
+ module ActiveSupport
10
+ module Testing
11
+ module Performance
12
+ DEFAULTS =
13
+ if benchmark = ARGV.include?('--benchmark') # HAX for rake test
14
+ { :benchmark => true,
15
+ :runs => 4,
16
+ :metrics => [:wall_time, :memory, :objects, :gc_runs, :gc_time],
17
+ :output => 'tmp/performance' }
18
+ else
19
+ { :benchmark => false,
20
+ :runs => 1,
21
+ :min_percent => 0.01,
22
+ :metrics => [:process_time, :memory, :objects],
23
+ :formats => [:flat, :graph_html, :call_tree],
24
+ :output => 'tmp/performance' }
25
+ end.freeze
26
+
27
+ def self.included(base)
28
+ base.superclass_delegating_accessor :profile_options
29
+ base.profile_options = DEFAULTS
30
+ end
31
+
32
+ def full_test_name
33
+ "#{self.class.name}##{method_name}"
34
+ end
35
+
36
+ def run(result)
37
+ return if method_name =~ /^default_test$/
38
+
39
+ yield(self.class::STARTED, name)
40
+ @_result = result
41
+
42
+ run_warmup
43
+ if profile_options && metrics = profile_options[:metrics]
44
+ metrics.each do |metric_name|
45
+ if klass = Metrics[metric_name.to_sym]
46
+ run_profile(klass.new)
47
+ result.add_run
48
+ end
49
+ end
50
+ end
51
+
52
+ yield(self.class::FINISHED, name)
53
+ end
54
+
55
+ def run_test(metric, mode)
56
+ run_callbacks :setup
57
+ setup
58
+ metric.send(mode) { __send__ @method_name }
59
+ rescue ::Test::Unit::AssertionFailedError => e
60
+ add_failure(e.message, e.backtrace)
61
+ rescue StandardError, ScriptError
62
+ add_error($!)
63
+ ensure
64
+ begin
65
+ teardown
66
+ run_callbacks :teardown, :enumerator => :reverse_each
67
+ rescue ::Test::Unit::AssertionFailedError => e
68
+ add_failure(e.message, e.backtrace)
69
+ rescue StandardError, ScriptError
70
+ add_error($!)
71
+ end
72
+ end
73
+
74
+ protected
75
+ def run_warmup
76
+ GC.start
77
+
78
+ time = Metrics::Time.new
79
+ run_test(time, :benchmark)
80
+ puts "%s (%s warmup)" % [full_test_name, time.format(time.total)]
81
+
82
+ GC.start
83
+ end
84
+
85
+ def run_profile(metric)
86
+ klass = profile_options[:benchmark] ? Benchmarker : Profiler
87
+ performer = klass.new(self, metric)
88
+
89
+ performer.run
90
+ puts performer.report
91
+ performer.record
92
+ end
93
+
94
+ class Performer
95
+ delegate :run_test, :profile_options, :full_test_name, :to => :@harness
96
+
97
+ def initialize(harness, metric)
98
+ @harness, @metric = harness, metric
99
+ end
100
+
101
+ def report
102
+ rate = @total / profile_options[:runs]
103
+ '%20s: %s' % [@metric.name, @metric.format(rate)]
104
+ end
105
+
106
+ protected
107
+ def output_filename
108
+ "#{profile_options[:output]}/#{full_test_name}_#{@metric.name}"
109
+ end
110
+ end
111
+
112
+ class Benchmarker < Performer
113
+ def run
114
+ profile_options[:runs].to_i.times { run_test(@metric, :benchmark) }
115
+ @total = @metric.total
116
+ end
117
+
118
+ def record
119
+ avg = @metric.total / profile_options[:runs].to_i
120
+ now = Time.now.utc.xmlschema
121
+ with_output_file do |file|
122
+ file.puts "#{avg},#{now},#{environment}"
123
+ end
124
+ end
125
+
126
+ def environment
127
+ unless defined? @env
128
+ app = "#{$1}.#{$2}" if File.directory?('.git') && `git branch -v` =~ /^\* (\S+)\s+(\S+)/
129
+
130
+ rails = Rails::VERSION::STRING
131
+ if File.directory?('vendor/rails/.git')
132
+ Dir.chdir('vendor/rails') do
133
+ rails += ".#{$1}.#{$2}" if `git branch -v` =~ /^\* (\S+)\s+(\S+)/
134
+ end
135
+ end
136
+
137
+ ruby = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
138
+ ruby += "-#{RUBY_VERSION}.#{RUBY_PATCHLEVEL}"
139
+
140
+ @env = [app, rails, ruby, RUBY_PLATFORM] * ','
141
+ end
142
+
143
+ @env
144
+ end
145
+
146
+ protected
147
+ HEADER = 'measurement,created_at,app,rails,ruby,platform'
148
+
149
+ def with_output_file
150
+ fname = output_filename
151
+
152
+ if new = !File.exist?(fname)
153
+ FileUtils.mkdir_p(File.dirname(fname))
154
+ end
155
+
156
+ File.open(fname, 'ab') do |file|
157
+ file.puts(HEADER) if new
158
+ yield file
159
+ end
160
+ end
161
+
162
+ def output_filename
163
+ "#{super}.csv"
164
+ end
165
+ end
166
+
167
+ class Profiler < Performer
168
+ def initialize(*args)
169
+ super
170
+ @supported = @metric.measure_mode rescue false
171
+ end
172
+
173
+ def run
174
+ return unless @supported
175
+
176
+ RubyProf.measure_mode = @metric.measure_mode
177
+ RubyProf.start
178
+ RubyProf.pause
179
+ profile_options[:runs].to_i.times { run_test(@metric, :profile) }
180
+ @data = RubyProf.stop
181
+ @total = @data.threads.values.sum(0) { |method_infos| method_infos.sort.last.total_time }
182
+ end
183
+
184
+ def report
185
+ if @supported
186
+ super
187
+ else
188
+ '%20s: unsupported' % @metric.name
189
+ end
190
+ end
191
+
192
+ def record
193
+ return unless @supported
194
+
195
+ klasses = profile_options[:formats].map { |f| RubyProf.const_get("#{f.to_s.camelize}Printer") }.compact
196
+
197
+ klasses.each do |klass|
198
+ fname = output_filename(klass)
199
+ FileUtils.mkdir_p(File.dirname(fname))
200
+ File.open(fname, 'wb') do |file|
201
+ klass.new(@data).print(file, profile_options.slice(:min_percent))
202
+ end
203
+ end
204
+ end
205
+
206
+ protected
207
+ def output_filename(printer_class)
208
+ suffix =
209
+ case printer_class.name.demodulize
210
+ when 'FlatPrinter'; 'flat.txt'
211
+ when 'GraphPrinter'; 'graph.txt'
212
+ when 'GraphHtmlPrinter'; 'graph.html'
213
+ when 'CallTreePrinter'; 'tree.txt'
214
+ else printer_class.name.sub(/Printer$/, '').underscore
215
+ end
216
+
217
+ "#{super()}_#{suffix}"
218
+ end
219
+ end
220
+
221
+ module Metrics
222
+ def self.[](name)
223
+ const_get(name.to_s.camelize)
224
+ rescue NameError
225
+ nil
226
+ end
227
+
228
+ class Base
229
+ attr_reader :total
230
+
231
+ def initialize
232
+ @total = 0
233
+ end
234
+
235
+ def name
236
+ @name ||= self.class.name.demodulize.underscore
237
+ end
238
+
239
+ def measure_mode
240
+ self.class::Mode
241
+ end
242
+
243
+ def measure
244
+ 0
245
+ end
246
+
247
+ def benchmark
248
+ with_gc_stats do
249
+ before = measure
250
+ yield
251
+ @total += (measure - before)
252
+ end
253
+ end
254
+
255
+ def profile
256
+ RubyProf.resume
257
+ yield
258
+ ensure
259
+ RubyProf.pause
260
+ end
261
+
262
+ protected
263
+ if GC.respond_to?(:enable_stats)
264
+ def with_gc_stats
265
+ GC.enable_stats
266
+ yield
267
+ ensure
268
+ GC.disable_stats
269
+ end
270
+ elsif defined?(GC::Profiler)
271
+ def with_gc_stats
272
+ GC.start
273
+ GC.disable
274
+ GC::Profiler.enable
275
+ yield
276
+ ensure
277
+ GC::Profiler.disable
278
+ GC.enable
279
+ end
280
+ else
281
+ def with_gc_stats
282
+ yield
283
+ end
284
+ end
285
+ end
286
+
287
+ class Time < Base
288
+ def measure
289
+ ::Time.now.to_f
290
+ end
291
+
292
+ def format(measurement)
293
+ if measurement < 2
294
+ '%d ms' % (measurement * 1000)
295
+ else
296
+ '%.2f sec' % measurement
297
+ end
298
+ end
299
+ end
300
+
301
+ class ProcessTime < Time
302
+ Mode = RubyProf::PROCESS_TIME
303
+
304
+ def measure
305
+ RubyProf.measure_process_time
306
+ end
307
+ end
308
+
309
+ class WallTime < Time
310
+ Mode = RubyProf::WALL_TIME
311
+
312
+ def measure
313
+ RubyProf.measure_wall_time
314
+ end
315
+ end
316
+
317
+ class CpuTime < Time
318
+ Mode = RubyProf::CPU_TIME if RubyProf.const_defined?(:CPU_TIME)
319
+
320
+ def initialize(*args)
321
+ # FIXME: yeah my CPU is 2.33 GHz
322
+ RubyProf.cpu_frequency = 2.33e9
323
+ super
324
+ end
325
+
326
+ def measure
327
+ RubyProf.measure_cpu_time
328
+ end
329
+ end
330
+
331
+ class Memory < Base
332
+ Mode = RubyProf::MEMORY if RubyProf.const_defined?(:MEMORY)
333
+
334
+ # ruby-prof wrapper
335
+ if RubyProf.respond_to?(:measure_memory)
336
+ def measure
337
+ RubyProf.measure_memory / 1024.0
338
+ end
339
+
340
+ # Ruby 1.8 + railsbench patch
341
+ elsif GC.respond_to?(:allocated_size)
342
+ def measure
343
+ GC.allocated_size / 1024.0
344
+ end
345
+
346
+ # Ruby 1.8 + lloyd patch
347
+ elsif GC.respond_to?(:heap_info)
348
+ def measure
349
+ GC.heap_info['heap_current_memory'] / 1024.0
350
+ end
351
+
352
+ # Ruby 1.9 with total_malloc_allocated_size patch
353
+ elsif GC.respond_to?(:malloc_total_allocated_size)
354
+ def measure
355
+ GC.total_malloc_allocated_size / 1024.0
356
+ end
357
+
358
+ # Ruby 1.9 unpatched
359
+ elsif GC.respond_to?(:malloc_allocated_size)
360
+ def measure
361
+ GC.malloc_allocated_size / 1024.0
362
+ end
363
+
364
+ # Ruby 1.9 + GC profiler patch
365
+ elsif defined?(GC::Profiler)
366
+ def measure
367
+ GC.enable
368
+ GC.start
369
+ kb = GC::Profiler.data.last[:HEAP_USE_SIZE] / 1024.0
370
+ GC.disable
371
+ kb
372
+ end
373
+ end
374
+
375
+ def format(measurement)
376
+ '%.2f KB' % measurement
377
+ end
378
+ end
379
+
380
+ class Objects < Base
381
+ Mode = RubyProf::ALLOCATIONS if RubyProf.const_defined?(:ALLOCATIONS)
382
+
383
+ if RubyProf.respond_to?(:measure_allocations)
384
+ def measure
385
+ RubyProf.measure_allocations
386
+ end
387
+
388
+ # Ruby 1.8 + railsbench patch
389
+ elsif ObjectSpace.respond_to?(:allocated_objects)
390
+ def measure
391
+ ObjectSpace.allocated_objects
392
+ end
393
+
394
+ # Ruby 1.9 + GC profiler patch
395
+ elsif defined?(GC::Profiler)
396
+ def measure
397
+ GC.enable
398
+ GC.start
399
+ last = GC::Profiler.data.last
400
+ count = last[:HEAP_LIVE_OBJECTS] + last[:HEAP_FREE_OBJECTS]
401
+ GC.disable
402
+ count
403
+ end
404
+ end
405
+
406
+ def format(measurement)
407
+ measurement.to_i.to_s
408
+ end
409
+ end
410
+
411
+ class GcRuns < Base
412
+ Mode = RubyProf::GC_RUNS if RubyProf.const_defined?(:GC_RUNS)
413
+
414
+ if RubyProf.respond_to?(:measure_gc_runs)
415
+ def measure
416
+ RubyProf.measure_gc_runs
417
+ end
418
+ elsif GC.respond_to?(:collections)
419
+ def measure
420
+ GC.collections
421
+ end
422
+ elsif GC.respond_to?(:heap_info)
423
+ def measure
424
+ GC.heap_info['num_gc_passes']
425
+ end
426
+ end
427
+
428
+ def format(measurement)
429
+ measurement.to_i.to_s
430
+ end
431
+ end
432
+
433
+ class GcTime < Base
434
+ Mode = RubyProf::GC_TIME if RubyProf.const_defined?(:GC_TIME)
435
+
436
+ if RubyProf.respond_to?(:measure_gc_time)
437
+ def measure
438
+ RubyProf.measure_gc_time
439
+ end
440
+ elsif GC.respond_to?(:time)
441
+ def measure
442
+ GC.time
443
+ end
444
+ end
445
+
446
+ def format(measurement)
447
+ '%d ms' % (measurement / 1000)
448
+ end
449
+ end
450
+ end
451
+ end
452
+ end
453
+ end
454
+ rescue LoadError
455
+ end