passenger 5.0.0.beta3 → 5.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (218) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/.editorconfig +11 -5
  5. data/CHANGELOG +38 -0
  6. data/CONTRIBUTING.md +1 -4
  7. data/Gemfile +0 -1
  8. data/Gemfile.lock +0 -2
  9. data/Rakefile +33 -33
  10. data/bin/passenger +1 -1
  11. data/bin/passenger-config +1 -1
  12. data/bin/passenger-install-apache2-module +800 -800
  13. data/bin/passenger-install-nginx-module +592 -592
  14. data/bin/passenger-memory-stats +127 -127
  15. data/bin/passenger-status +216 -216
  16. data/build/agents.rb +127 -127
  17. data/build/apache2.rb +87 -87
  18. data/build/basics.rb +60 -60
  19. data/build/common_library.rb +165 -165
  20. data/build/cplusplus_support.rb +51 -51
  21. data/build/cxx_tests.rb +268 -268
  22. data/build/debian.rb +143 -143
  23. data/build/documentation.rb +58 -58
  24. data/build/integration_tests.rb +81 -81
  25. data/build/misc.rb +132 -132
  26. data/build/nginx.rb +20 -20
  27. data/build/node_tests.rb +7 -7
  28. data/build/oxt_tests.rb +14 -14
  29. data/build/packaging.rb +570 -570
  30. data/build/preprocessor.rb +260 -260
  31. data/build/rake_extensions.rb +71 -71
  32. data/build/ruby_extension.rb +29 -29
  33. data/build/ruby_tests.rb +6 -6
  34. data/build/test_basics.rb +37 -37
  35. data/debian.template/control.template +3 -5
  36. data/dev/copy_boost_headers +134 -134
  37. data/dev/install_scripts_bootstrap_code.rb +25 -25
  38. data/dev/list_tests +20 -20
  39. data/dev/ruby_server.rb +223 -223
  40. data/dev/runner +18 -18
  41. data/doc/ServerOptimizationGuide.txt.md +55 -2
  42. data/doc/Users guide Nginx.txt +0 -26
  43. data/doc/Users guide Standalone.txt +5 -1
  44. data/doc/users_guide_snippets/tips.txt +9 -0
  45. data/ext/common/ApplicationPool2/Group.h +23 -11
  46. data/ext/common/ApplicationPool2/Implementation.cpp +32 -7
  47. data/ext/common/ApplicationPool2/Pool.h +22 -17
  48. data/ext/common/ApplicationPool2/SmartSpawner.h +4 -1
  49. data/ext/common/ApplicationPool2/Spawner.h +1 -1
  50. data/ext/common/Constants.h +1 -1
  51. data/ext/common/agents/Base.cpp +35 -20
  52. data/ext/common/agents/HelperAgent/Main.cpp +8 -1
  53. data/ext/common/agents/HelperAgent/OptionParser.h +18 -4
  54. data/ext/common/agents/HelperAgent/RequestHandler.h +2 -83
  55. data/ext/common/agents/HelperAgent/RequestHandler/ForwardResponse.cpp +54 -1
  56. data/ext/common/agents/HelperAgent/RequestHandler/InitRequest.cpp +7 -4
  57. data/ext/common/agents/Main.cpp +1 -1
  58. data/ext/common/agents/Watchdog/Main.cpp +54 -19
  59. data/ext/nginx/Configuration.c +7 -0
  60. data/ext/nginx/ContentHandler.c +9 -1
  61. data/helper-scripts/backtrace-sanitizer.rb +106 -87
  62. data/helper-scripts/crash-watch.rb +32 -0
  63. data/helper-scripts/download_binaries/extconf.rb +38 -38
  64. data/helper-scripts/meteor-loader.rb +107 -107
  65. data/helper-scripts/prespawn +101 -101
  66. data/helper-scripts/rack-loader.rb +96 -96
  67. data/helper-scripts/rack-preloader.rb +137 -137
  68. data/lib/phusion_passenger.rb +292 -292
  69. data/lib/phusion_passenger/abstract_installer.rb +438 -438
  70. data/lib/phusion_passenger/active_support3_extensions/init.rb +168 -170
  71. data/lib/phusion_passenger/admin_tools.rb +20 -20
  72. data/lib/phusion_passenger/admin_tools/instance.rb +178 -178
  73. data/lib/phusion_passenger/admin_tools/instance_registry.rb +61 -61
  74. data/lib/phusion_passenger/admin_tools/memory_stats.rb +267 -267
  75. data/lib/phusion_passenger/apache2/config_options.rb +182 -182
  76. data/lib/phusion_passenger/common_library.rb +479 -485
  77. data/lib/phusion_passenger/config/about_command.rb +161 -161
  78. data/lib/phusion_passenger/config/admin_command_command.rb +129 -129
  79. data/lib/phusion_passenger/config/agent_compiler.rb +121 -121
  80. data/lib/phusion_passenger/config/build_native_support_command.rb +43 -43
  81. data/lib/phusion_passenger/config/command.rb +25 -25
  82. data/lib/phusion_passenger/config/compile_agent_command.rb +62 -62
  83. data/lib/phusion_passenger/config/compile_nginx_engine_command.rb +88 -73
  84. data/lib/phusion_passenger/config/detach_process_command.rb +72 -72
  85. data/lib/phusion_passenger/config/download_agent_command.rb +246 -227
  86. data/lib/phusion_passenger/config/download_nginx_engine_command.rb +245 -224
  87. data/lib/phusion_passenger/config/install_agent_command.rb +144 -132
  88. data/lib/phusion_passenger/config/install_standalone_runtime_command.rb +205 -185
  89. data/lib/phusion_passenger/config/installation_utils.rb +204 -204
  90. data/lib/phusion_passenger/config/list_instances_command.rb +64 -64
  91. data/lib/phusion_passenger/config/main.rb +152 -152
  92. data/lib/phusion_passenger/config/nginx_engine_compiler.rb +319 -300
  93. data/lib/phusion_passenger/config/reopen_logs_command.rb +67 -67
  94. data/lib/phusion_passenger/config/restart_app_command.rb +155 -155
  95. data/lib/phusion_passenger/config/system_metrics_command.rb +13 -13
  96. data/lib/phusion_passenger/config/utils.rb +95 -95
  97. data/lib/phusion_passenger/config/validate_install_command.rb +198 -198
  98. data/lib/phusion_passenger/console_text_template.rb +25 -25
  99. data/lib/phusion_passenger/constants.rb +90 -90
  100. data/lib/phusion_passenger/debug_logging.rb +106 -106
  101. data/lib/phusion_passenger/loader_shared_helpers.rb +447 -432
  102. data/lib/phusion_passenger/message_channel.rb +312 -312
  103. data/lib/phusion_passenger/message_client.rb +176 -176
  104. data/lib/phusion_passenger/native_support.rb +369 -369
  105. data/lib/phusion_passenger/nginx/config_options.rb +297 -297
  106. data/lib/phusion_passenger/packaging.rb +131 -131
  107. data/lib/phusion_passenger/platform_info.rb +360 -360
  108. data/lib/phusion_passenger/platform_info/apache.rb +767 -767
  109. data/lib/phusion_passenger/platform_info/apache_detector.rb +199 -199
  110. data/lib/phusion_passenger/platform_info/binary_compatibility.rb +107 -107
  111. data/lib/phusion_passenger/platform_info/compiler.rb +570 -570
  112. data/lib/phusion_passenger/platform_info/curl.rb +32 -32
  113. data/lib/phusion_passenger/platform_info/cxx_portability.rb +188 -188
  114. data/lib/phusion_passenger/platform_info/depcheck.rb +372 -372
  115. data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +109 -109
  116. data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +4 -4
  117. data/lib/phusion_passenger/platform_info/depcheck_specs/gems.rb +10 -34
  118. data/lib/phusion_passenger/platform_info/depcheck_specs/libs.rb +101 -101
  119. data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +5 -5
  120. data/lib/phusion_passenger/platform_info/depcheck_specs/utilities.rb +13 -13
  121. data/lib/phusion_passenger/platform_info/linux.rb +55 -55
  122. data/lib/phusion_passenger/platform_info/operating_system.rb +149 -149
  123. data/lib/phusion_passenger/platform_info/ruby.rb +468 -448
  124. data/lib/phusion_passenger/platform_info/zlib.rb +9 -9
  125. data/lib/phusion_passenger/plugin.rb +66 -66
  126. data/lib/phusion_passenger/preloader_shared_helpers.rb +126 -126
  127. data/lib/phusion_passenger/public_api.rb +191 -191
  128. data/lib/phusion_passenger/rack/out_of_band_gc.rb +93 -94
  129. data/lib/phusion_passenger/rack/thread_handler_extension.rb +231 -227
  130. data/lib/phusion_passenger/request_handler.rb +567 -577
  131. data/lib/phusion_passenger/request_handler/thread_handler.rb +379 -381
  132. data/lib/phusion_passenger/ruby_core_enhancements.rb +86 -86
  133. data/lib/phusion_passenger/ruby_core_io_enhancements.rb +74 -74
  134. data/lib/phusion_passenger/simple_benchmarking.rb +25 -25
  135. data/lib/phusion_passenger/standalone/app_finder.rb +153 -150
  136. data/lib/phusion_passenger/standalone/command.rb +44 -40
  137. data/lib/phusion_passenger/standalone/config_utils.rb +53 -53
  138. data/lib/phusion_passenger/standalone/control_utils.rb +38 -59
  139. data/lib/phusion_passenger/standalone/main.rb +73 -73
  140. data/lib/phusion_passenger/standalone/start_command.rb +697 -685
  141. data/lib/phusion_passenger/standalone/start_command/builtin_engine.rb +193 -155
  142. data/lib/phusion_passenger/standalone/start_command/nginx_engine.rb +162 -133
  143. data/lib/phusion_passenger/standalone/status_command.rb +64 -64
  144. data/lib/phusion_passenger/standalone/stop_command.rb +72 -72
  145. data/lib/phusion_passenger/standalone/version_command.rb +9 -9
  146. data/lib/phusion_passenger/union_station/connection.rb +32 -32
  147. data/lib/phusion_passenger/union_station/core.rb +251 -251
  148. data/lib/phusion_passenger/union_station/transaction.rb +126 -126
  149. data/lib/phusion_passenger/utils.rb +199 -167
  150. data/lib/phusion_passenger/utils/ansi_colors.rb +128 -128
  151. data/lib/phusion_passenger/utils/download.rb +196 -196
  152. data/lib/phusion_passenger/utils/file_system_watcher.rb +158 -158
  153. data/lib/phusion_passenger/utils/hosts_file_parser.rb +101 -101
  154. data/lib/phusion_passenger/utils/lock.rb +31 -31
  155. data/lib/phusion_passenger/utils/native_support_utils.rb +31 -31
  156. data/lib/phusion_passenger/utils/progress_bar.rb +26 -26
  157. data/lib/phusion_passenger/utils/shellwords.rb +20 -20
  158. data/lib/phusion_passenger/utils/terminal_choice_menu.rb +206 -206
  159. data/lib/phusion_passenger/utils/unseekable_socket.rb +272 -272
  160. data/lib/phusion_passenger/vendor/crash_watch/app.rb +129 -0
  161. data/lib/phusion_passenger/vendor/crash_watch/gdb_controller.rb +341 -0
  162. data/lib/phusion_passenger/vendor/crash_watch/version.rb +24 -0
  163. data/lib/phusion_passenger/vendor/daemon_controller.rb +877 -0
  164. data/lib/phusion_passenger/vendor/daemon_controller/lock_file.rb +127 -0
  165. data/lib/phusion_passenger/vendor/daemon_controller/spawn.rb +26 -0
  166. data/lib/phusion_passenger/vendor/daemon_controller/version.rb +29 -0
  167. data/packaging/rpm/passenger_spec/passenger.spec.template +0 -1
  168. data/passenger.gemspec +0 -1
  169. data/resources/templates/config/nginx_engine_compiler/possible_solutions_for_download_and_extraction_problems.txt.erb +27 -0
  170. data/resources/templates/standalone/config.erb +19 -15
  171. data/test/integration_tests/apache2_tests.rb +566 -566
  172. data/test/integration_tests/downloaded_binaries_tests.rb +126 -125
  173. data/test/integration_tests/native_packaging_spec.rb +296 -296
  174. data/test/integration_tests/nginx_tests.rb +393 -393
  175. data/test/integration_tests/shared/example_webapp_tests.rb +282 -280
  176. data/test/integration_tests/source_packaging_test.rb +138 -138
  177. data/test/integration_tests/spec_helper.rb +5 -5
  178. data/test/integration_tests/standalone_tests.rb +367 -367
  179. data/test/ruby/debug_logging_spec.rb +133 -133
  180. data/test/ruby/message_channel_spec.rb +186 -186
  181. data/test/ruby/rack/loader_spec.rb +28 -28
  182. data/test/ruby/rack/preloader_spec.rb +34 -34
  183. data/test/ruby/rails3.0/loader_spec.rb +12 -12
  184. data/test/ruby/rails3.0/preloader_spec.rb +18 -18
  185. data/test/ruby/rails3.1/loader_spec.rb +12 -12
  186. data/test/ruby/rails3.1/preloader_spec.rb +18 -18
  187. data/test/ruby/rails3.2/loader_spec.rb +12 -12
  188. data/test/ruby/rails3.2/preloader_spec.rb +18 -18
  189. data/test/ruby/rails4.0/loader_spec.rb +12 -12
  190. data/test/ruby/rails4.0/preloader_spec.rb +18 -18
  191. data/test/ruby/rails4.1/loader_spec.rb +12 -12
  192. data/test/ruby/rails4.1/preloader_spec.rb +18 -18
  193. data/test/ruby/request_handler_spec.rb +730 -730
  194. data/test/ruby/shared/loader_sharedspec.rb +224 -224
  195. data/test/ruby/shared/rails/union_station_extensions_sharedspec.rb +327 -327
  196. data/test/ruby/shared/ruby_loader_sharedspec.rb +47 -47
  197. data/test/ruby/spec_helper.rb +65 -65
  198. data/test/ruby/standalone/runtime_installer_spec.rb +384 -384
  199. data/test/ruby/union_station_spec.rb +276 -276
  200. data/test/ruby/utils/file_system_watcher_spec.rb +220 -220
  201. data/test/ruby/utils/hosts_file_parser.rb +248 -248
  202. data/test/ruby/utils/tee_input_spec.rb +215 -215
  203. data/test/ruby/utils/unseekable_socket_spec.rb +57 -57
  204. data/test/ruby/utils_spec.rb +21 -21
  205. data/test/stub/rack/config.ru +87 -87
  206. data/test/stub/rack/library.rb +8 -8
  207. data/test/stub/rack/start.rb +30 -30
  208. data/test/support/apache2_controller.rb +191 -191
  209. data/test/support/nginx_controller.rb +90 -99
  210. data/test/support/placebo-preloader.rb +57 -57
  211. data/test/support/test_helper.rb +435 -435
  212. metadata +11 -21
  213. metadata.gz.asc +7 -7
  214. data/lib/phusion_passenger/standalone/command2.rb +0 -292
  215. data/lib/phusion_passenger/standalone/start2_command.rb +0 -799
  216. data/resources/templates/standalone/download_tool_missing.txt.erb +0 -18
  217. data/resources/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -17
  218. data/resources/templates/standalone/run_installer_as_root.txt.erb +0 -8
@@ -7,139 +7,139 @@ require 'fileutils'
7
7
  module PhusionPassenger
8
8
 
9
9
  describe DebugLogging do
10
- after :each do
11
- DebugLogging.log_level = DEFAULT_LOG_LEVEL
12
- DebugLogging.log_file = nil
13
- DebugLogging.stderr_evaluator = nil
14
- FileUtils.rm_rf(@tmpdir) if @tmpdir
15
- end
16
-
17
- class MyClass
18
- include DebugLogging
19
- end
20
-
21
- def use_log_file!
22
- @tmpdir = Dir.mktmpdir
23
- @log_file = "#{@tmpdir}/debug.log"
24
- DebugLogging.log_file = @log_file
25
- end
26
-
27
- describe "#debug" do
28
- it "doesn't print the message if log level is LVL_INFO" do
29
- use_log_file!
30
- DebugLogging.log_level = LVL_INFO
31
- DebugLogging.debug("hello")
32
- File.exist?(@log_file).should be_false
33
- end
34
-
35
- it "prints the message if log level is LVL_DEBUG" do
36
- use_log_file!
37
- DebugLogging.log_level = LVL_DEBUG
38
- DebugLogging.debug("hello")
39
- File.exist?(@log_file).should be_true
40
- end
41
-
42
- it "prints the message if log level is greater than LVL_DEBUG" do
43
- use_log_file!
44
- DebugLogging.log_level = LVL_DEBUG2
45
- DebugLogging.debug("hello")
46
- File.exist?(@log_file).should be_true
47
- end
48
-
49
- it "prints the location of the calling function" do
50
- use_log_file!
51
- DebugLogging.log_level = LVL_DEBUG
52
- DebugLogging.debug("hello")
53
- File.read(@log_file).should include("debug_logging_spec.rb")
54
- end
55
-
56
- it "prints to STDERR by default" do
57
- io = StringIO.new
58
- DebugLogging.log_level = LVL_DEBUG
59
- DebugLogging.stderr_evaluator = lambda { io }
60
- DebugLogging.debug("hello")
61
- io.string.should include("hello")
62
- end
63
-
64
- it "reopens the log file handle if it has been closed" do
65
- use_log_file!
66
- DebugLogging.log_level = LVL_DEBUG
67
- DebugLogging.debug("hello")
68
- DebugLogging._log_device.close
69
- DebugLogging.debug("world")
70
- File.read(@log_file).should include("world")
71
- end
72
-
73
- it "also works as included method" do
74
- use_log_file!
75
- DebugLogging.log_level = LVL_DEBUG
76
- MyClass.new.send(:debug, "hello")
77
- File.read(@log_file).should include("hello")
78
- end
79
-
80
- it "is private when included" do
81
- MyClass.private_method_defined?(:debug)
82
- end
83
- end
84
-
85
- describe "#trace" do
86
- specify "#trace(x, ...) doesn't print the message if the log level is lower than LVL_INFO + x" do
87
- use_log_file!
88
- DebugLogging.log_level = LVL_INFO + 1
89
- DebugLogging.trace(2, "hello")
90
- File.exist?(@log_file).should be_false
91
- end
92
-
93
- specify "#trace(x, ...) prints the message if the log level equals LVL_INFO + 2" do
94
- use_log_file!
95
- DebugLogging.log_level = LVL_INFO + 2
96
- DebugLogging.trace(2, "hello")
97
- File.exist?(@log_file).should be_true
98
- end
99
-
100
- specify "#trace(x, ...) prints the message if the log level is greater than LVL_INFO + 3" do
101
- use_log_file!
102
- DebugLogging.log_level = LVL_INFO + 3
103
- DebugLogging.trace(2, "hello")
104
- File.exist?(@log_file).should be_true
105
- end
106
-
107
- specify "#trace prints the location of the calling function" do
108
- io = StringIO.new
109
- DebugLogging.log_level = LVL_DEBUG
110
- DebugLogging.stderr_evaluator = lambda { io }
111
- DebugLogging.trace(1, "hello")
112
- io.string.should include("hello")
113
- end
114
-
115
- it "prints to STDERR by default" do
116
- io = StringIO.new
117
- DebugLogging.log_level = LVL_DEBUG
118
- DebugLogging.stderr_evaluator = lambda { io }
119
- DebugLogging.trace(1, "hello")
120
- io.string.should include("hello")
121
- end
122
-
123
- it "reopens the log file handle if it has been closed" do
124
- use_log_file!
125
- DebugLogging.log_level = LVL_DEBUG
126
- DebugLogging.trace(1, "hello")
127
- DebugLogging._log_device.close
128
- DebugLogging.trace(1, "world")
129
- File.read(@log_file).should include("world")
130
- end
131
-
132
- it "also works as included method" do
133
- use_log_file!
134
- DebugLogging.log_level = LVL_DEBUG
135
- MyClass.new.send(:trace, 1, "hello")
136
- File.read(@log_file).should include("hello")
137
- end
138
-
139
- it "is private when included" do
140
- MyClass.private_method_defined?(:trace)
141
- end
142
- end
10
+ after :each do
11
+ DebugLogging.log_level = DEFAULT_LOG_LEVEL
12
+ DebugLogging.log_file = nil
13
+ DebugLogging.stderr_evaluator = nil
14
+ FileUtils.rm_rf(@tmpdir) if @tmpdir
15
+ end
16
+
17
+ class MyClass
18
+ include DebugLogging
19
+ end
20
+
21
+ def use_log_file!
22
+ @tmpdir = Dir.mktmpdir
23
+ @log_file = "#{@tmpdir}/debug.log"
24
+ DebugLogging.log_file = @log_file
25
+ end
26
+
27
+ describe "#debug" do
28
+ it "doesn't print the message if log level is LVL_INFO" do
29
+ use_log_file!
30
+ DebugLogging.log_level = LVL_INFO
31
+ DebugLogging.debug("hello")
32
+ File.exist?(@log_file).should be_false
33
+ end
34
+
35
+ it "prints the message if log level is LVL_DEBUG" do
36
+ use_log_file!
37
+ DebugLogging.log_level = LVL_DEBUG
38
+ DebugLogging.debug("hello")
39
+ File.exist?(@log_file).should be_true
40
+ end
41
+
42
+ it "prints the message if log level is greater than LVL_DEBUG" do
43
+ use_log_file!
44
+ DebugLogging.log_level = LVL_DEBUG2
45
+ DebugLogging.debug("hello")
46
+ File.exist?(@log_file).should be_true
47
+ end
48
+
49
+ it "prints the location of the calling function" do
50
+ use_log_file!
51
+ DebugLogging.log_level = LVL_DEBUG
52
+ DebugLogging.debug("hello")
53
+ File.read(@log_file).should include("debug_logging_spec.rb")
54
+ end
55
+
56
+ it "prints to STDERR by default" do
57
+ io = StringIO.new
58
+ DebugLogging.log_level = LVL_DEBUG
59
+ DebugLogging.stderr_evaluator = lambda { io }
60
+ DebugLogging.debug("hello")
61
+ io.string.should include("hello")
62
+ end
63
+
64
+ it "reopens the log file handle if it has been closed" do
65
+ use_log_file!
66
+ DebugLogging.log_level = LVL_DEBUG
67
+ DebugLogging.debug("hello")
68
+ DebugLogging._log_device.close
69
+ DebugLogging.debug("world")
70
+ File.read(@log_file).should include("world")
71
+ end
72
+
73
+ it "also works as included method" do
74
+ use_log_file!
75
+ DebugLogging.log_level = LVL_DEBUG
76
+ MyClass.new.send(:debug, "hello")
77
+ File.read(@log_file).should include("hello")
78
+ end
79
+
80
+ it "is private when included" do
81
+ MyClass.private_method_defined?(:debug)
82
+ end
83
+ end
84
+
85
+ describe "#trace" do
86
+ specify "#trace(x, ...) doesn't print the message if the log level is lower than LVL_INFO + x" do
87
+ use_log_file!
88
+ DebugLogging.log_level = LVL_INFO + 1
89
+ DebugLogging.trace(2, "hello")
90
+ File.exist?(@log_file).should be_false
91
+ end
92
+
93
+ specify "#trace(x, ...) prints the message if the log level equals LVL_INFO + 2" do
94
+ use_log_file!
95
+ DebugLogging.log_level = LVL_INFO + 2
96
+ DebugLogging.trace(2, "hello")
97
+ File.exist?(@log_file).should be_true
98
+ end
99
+
100
+ specify "#trace(x, ...) prints the message if the log level is greater than LVL_INFO + 3" do
101
+ use_log_file!
102
+ DebugLogging.log_level = LVL_INFO + 3
103
+ DebugLogging.trace(2, "hello")
104
+ File.exist?(@log_file).should be_true
105
+ end
106
+
107
+ specify "#trace prints the location of the calling function" do
108
+ io = StringIO.new
109
+ DebugLogging.log_level = LVL_DEBUG
110
+ DebugLogging.stderr_evaluator = lambda { io }
111
+ DebugLogging.trace(1, "hello")
112
+ io.string.should include("hello")
113
+ end
114
+
115
+ it "prints to STDERR by default" do
116
+ io = StringIO.new
117
+ DebugLogging.log_level = LVL_DEBUG
118
+ DebugLogging.stderr_evaluator = lambda { io }
119
+ DebugLogging.trace(1, "hello")
120
+ io.string.should include("hello")
121
+ end
122
+
123
+ it "reopens the log file handle if it has been closed" do
124
+ use_log_file!
125
+ DebugLogging.log_level = LVL_DEBUG
126
+ DebugLogging.trace(1, "hello")
127
+ DebugLogging._log_device.close
128
+ DebugLogging.trace(1, "world")
129
+ File.read(@log_file).should include("world")
130
+ end
131
+
132
+ it "also works as included method" do
133
+ use_log_file!
134
+ DebugLogging.log_level = LVL_DEBUG
135
+ MyClass.new.send(:trace, 1, "hello")
136
+ File.read(@log_file).should include("hello")
137
+ end
138
+
139
+ it "is private when included" do
140
+ MyClass.private_method_defined?(:trace)
141
+ end
142
+ end
143
143
  end
144
144
 
145
145
  end # module PhusionPassenger
@@ -5,192 +5,192 @@ PhusionPassenger.require_passenger_lib 'message_channel'
5
5
  module PhusionPassenger
6
6
 
7
7
  describe MessageChannel do
8
- describe "scenarios with a single channel" do
9
- before :each do
10
- @reader_pipe, @writer_pipe = IO.pipe
11
- @reader = MessageChannel.new(@reader_pipe)
12
- @writer = MessageChannel.new(@writer_pipe)
13
- end
14
-
15
- after :each do
16
- @reader_pipe.close unless @reader_pipe.closed?
17
- @writer_pipe.close unless @writer_pipe.closed?
18
- end
19
-
20
- it "can read a single written array message" do
21
- @writer.write("hello")
22
- @reader.read.should == ["hello"]
23
- end
24
-
25
- it "can handle array messages that contain spaces" do
26
- @writer.write("hello world", "! ")
27
- @reader.read.should == ["hello world", "! "]
28
- end
29
-
30
- it "can handle array messages that have only a single empty string" do
31
- @writer.write("")
32
- @reader.read.should == [""]
33
- end
34
-
35
- it "can handle array messages with empty arguments" do
36
- @writer.write("hello", "", "world")
37
- @reader.read.should == ["hello", "", "world"]
38
-
39
- @writer.write("")
40
- @reader.read.should == [""]
41
-
42
- @writer.write(nil, "foo")
43
- @reader.read.should == ["", "foo"]
44
- end
45
-
46
- it "properly detects end-of-file when reading an array message" do
47
- @writer.close
48
- @reader.read.should be_nil
49
- end
50
-
51
- specify "#read_hash works" do
52
- @writer.write("hello", "world")
53
- @reader.read_hash.should == { "hello" => "world" }
54
-
55
- @writer.write("hello", "world", "foo", "bar", "", "...")
56
- @reader.read_hash.should == { "hello" => "world", "foo" => "bar", "" => "..." }
57
- end
58
-
59
- specify "#read_hash throws an exception if the array message doesn't have an even number of items" do
60
- @writer.write("foo")
61
- lambda { @reader.read_hash }.should raise_error(MessageChannel::InvalidHashError)
62
-
63
- @writer.write("foo", "bar", "baz")
64
- lambda { @reader.read_hash }.should raise_error(MessageChannel::InvalidHashError)
65
- end
66
-
67
- it "can read a single written scalar message" do
68
- @writer.write_scalar("hello world")
69
- @reader.read_scalar.should == "hello world"
70
- end
71
-
72
- it "can handle empty scalar messages" do
73
- @writer.write_scalar("")
74
- @reader.read_scalar.should == ""
75
- end
76
-
77
- it "properly detects end-of-file when reading a scalar message" do
78
- @writer.close
79
- @reader.read_scalar.should be_nil
80
- end
81
-
82
- it "puts the data into the given buffer" do
83
- buffer = ''
84
- @writer.write_scalar("x" * 100)
85
- result = @reader.read_scalar(buffer)
86
- result.object_id.should == buffer.object_id
87
- buffer.should == "x" * 100
88
- end
89
-
90
- it "raises SecurityError when a received scalar message's size is larger than a specified maximum" do
91
- @writer.write_scalar(" " * 100)
92
- lambda { @reader.read_scalar('', 99) }.should raise_error(SecurityError)
93
- end
94
- end
95
-
96
- describe "scenarios with 2 channels and 2 concurrent processes" do
97
- after :each do
98
- @parent_socket.close
99
- Process.waitpid(@pid) rescue nil
100
- end
101
-
102
- def spawn_process
103
- @parent_socket, @child_socket = UNIXSocket.pair
104
- @pid = fork do
105
- @parent_socket.close
106
- @channel = MessageChannel.new(@child_socket)
107
- begin
108
- yield
109
- rescue Exception => e
110
- print_exception("child", e)
111
- ensure
112
- @child_socket.close
113
- exit!
114
- end
115
- end
116
- @child_socket.close
117
- @channel = MessageChannel.new(@parent_socket)
118
- end
119
-
120
- it "both processes can read and write a single array message" do
121
- spawn_process do
122
- x = @channel.read
123
- @channel.write("#{x[0]}!")
124
- end
125
- @channel.write("hello")
126
- @channel.read.should == ["hello!"]
127
- end
128
-
129
- it "can handle scalar messages with arbitrary binary data" do
130
- garbage_files = ["garbage1.dat", "garbage2.dat", "garbage3.dat"]
131
- spawn_process do
132
- garbage_files.each do |name|
133
- data = File.binread("stub/#{name}")
134
- @channel.write_scalar(data)
135
- end
136
- end
137
-
138
- garbage_files.each do |name|
139
- data = File.binread("stub/#{name}")
140
- @channel.read_scalar.should == data
141
- end
142
- end
143
-
144
- it "supports IO object (file descriptor) passing" do
145
- spawn_process do
146
- writer = @channel.recv_io
147
- writer.write("it works")
148
- writer.close
149
- end
150
- reader, writer = IO.pipe
151
- @channel.send_io(writer)
152
- writer.close
153
- reader.read.should == "it works"
154
- reader.close
155
- end
156
-
157
- it "supports large amounts of data" do
158
- iterations = 1000
159
- blob = "123" * 1024
160
- spawn_process do
161
- iterations.times do |i|
162
- @channel.write(blob)
163
- end
164
- end
165
- iterations.times do
166
- @channel.read.should == [blob]
167
- end
168
- end
169
-
170
- it "has stream properties" do
171
- garbage = File.binread("stub/garbage1.dat")
172
- spawn_process do
173
- @channel.write("hello", "world")
174
- @channel.write_scalar(garbage)
175
- @channel.send_io(STDIN)
176
- @channel.write_scalar(":-)")
177
-
178
- a = @channel.read_scalar
179
- b = @channel.read
180
- b << a
181
- @channel.write(*b)
182
- end
183
- @channel.read.should == ["hello", "world"]
184
- @channel.read_scalar.should == garbage
185
- @channel.recv_io.close
186
- @channel.read_scalar.should == ":-)"
187
-
188
- @channel.write_scalar("TASTE MY WRATH! ULTIMATE SWORD TECHNIQUE!! DRAGON'S BREATH SL--")
189
- @channel.write("Uhm, watch your step.", "WAAHH?!", "Calm down, Motoko!!")
190
- @channel.read.should == ["Uhm, watch your step.", "WAAHH?!", "Calm down, Motoko!!",
191
- "TASTE MY WRATH! ULTIMATE SWORD TECHNIQUE!! DRAGON'S BREATH SL--"]
192
- end
193
- end
8
+ describe "scenarios with a single channel" do
9
+ before :each do
10
+ @reader_pipe, @writer_pipe = IO.pipe
11
+ @reader = MessageChannel.new(@reader_pipe)
12
+ @writer = MessageChannel.new(@writer_pipe)
13
+ end
14
+
15
+ after :each do
16
+ @reader_pipe.close unless @reader_pipe.closed?
17
+ @writer_pipe.close unless @writer_pipe.closed?
18
+ end
19
+
20
+ it "can read a single written array message" do
21
+ @writer.write("hello")
22
+ @reader.read.should == ["hello"]
23
+ end
24
+
25
+ it "can handle array messages that contain spaces" do
26
+ @writer.write("hello world", "! ")
27
+ @reader.read.should == ["hello world", "! "]
28
+ end
29
+
30
+ it "can handle array messages that have only a single empty string" do
31
+ @writer.write("")
32
+ @reader.read.should == [""]
33
+ end
34
+
35
+ it "can handle array messages with empty arguments" do
36
+ @writer.write("hello", "", "world")
37
+ @reader.read.should == ["hello", "", "world"]
38
+
39
+ @writer.write("")
40
+ @reader.read.should == [""]
41
+
42
+ @writer.write(nil, "foo")
43
+ @reader.read.should == ["", "foo"]
44
+ end
45
+
46
+ it "properly detects end-of-file when reading an array message" do
47
+ @writer.close
48
+ @reader.read.should be_nil
49
+ end
50
+
51
+ specify "#read_hash works" do
52
+ @writer.write("hello", "world")
53
+ @reader.read_hash.should == { "hello" => "world" }
54
+
55
+ @writer.write("hello", "world", "foo", "bar", "", "...")
56
+ @reader.read_hash.should == { "hello" => "world", "foo" => "bar", "" => "..." }
57
+ end
58
+
59
+ specify "#read_hash throws an exception if the array message doesn't have an even number of items" do
60
+ @writer.write("foo")
61
+ lambda { @reader.read_hash }.should raise_error(MessageChannel::InvalidHashError)
62
+
63
+ @writer.write("foo", "bar", "baz")
64
+ lambda { @reader.read_hash }.should raise_error(MessageChannel::InvalidHashError)
65
+ end
66
+
67
+ it "can read a single written scalar message" do
68
+ @writer.write_scalar("hello world")
69
+ @reader.read_scalar.should == "hello world"
70
+ end
71
+
72
+ it "can handle empty scalar messages" do
73
+ @writer.write_scalar("")
74
+ @reader.read_scalar.should == ""
75
+ end
76
+
77
+ it "properly detects end-of-file when reading a scalar message" do
78
+ @writer.close
79
+ @reader.read_scalar.should be_nil
80
+ end
81
+
82
+ it "puts the data into the given buffer" do
83
+ buffer = ''
84
+ @writer.write_scalar("x" * 100)
85
+ result = @reader.read_scalar(buffer)
86
+ result.object_id.should == buffer.object_id
87
+ buffer.should == "x" * 100
88
+ end
89
+
90
+ it "raises SecurityError when a received scalar message's size is larger than a specified maximum" do
91
+ @writer.write_scalar(" " * 100)
92
+ lambda { @reader.read_scalar('', 99) }.should raise_error(SecurityError)
93
+ end
94
+ end
95
+
96
+ describe "scenarios with 2 channels and 2 concurrent processes" do
97
+ after :each do
98
+ @parent_socket.close
99
+ Process.waitpid(@pid) rescue nil
100
+ end
101
+
102
+ def spawn_process
103
+ @parent_socket, @child_socket = UNIXSocket.pair
104
+ @pid = fork do
105
+ @parent_socket.close
106
+ @channel = MessageChannel.new(@child_socket)
107
+ begin
108
+ yield
109
+ rescue Exception => e
110
+ print_exception("child", e)
111
+ ensure
112
+ @child_socket.close
113
+ exit!
114
+ end
115
+ end
116
+ @child_socket.close
117
+ @channel = MessageChannel.new(@parent_socket)
118
+ end
119
+
120
+ it "both processes can read and write a single array message" do
121
+ spawn_process do
122
+ x = @channel.read
123
+ @channel.write("#{x[0]}!")
124
+ end
125
+ @channel.write("hello")
126
+ @channel.read.should == ["hello!"]
127
+ end
128
+
129
+ it "can handle scalar messages with arbitrary binary data" do
130
+ garbage_files = ["garbage1.dat", "garbage2.dat", "garbage3.dat"]
131
+ spawn_process do
132
+ garbage_files.each do |name|
133
+ data = File.binread("stub/#{name}")
134
+ @channel.write_scalar(data)
135
+ end
136
+ end
137
+
138
+ garbage_files.each do |name|
139
+ data = File.binread("stub/#{name}")
140
+ @channel.read_scalar.should == data
141
+ end
142
+ end
143
+
144
+ it "supports IO object (file descriptor) passing" do
145
+ spawn_process do
146
+ writer = @channel.recv_io
147
+ writer.write("it works")
148
+ writer.close
149
+ end
150
+ reader, writer = IO.pipe
151
+ @channel.send_io(writer)
152
+ writer.close
153
+ reader.read.should == "it works"
154
+ reader.close
155
+ end
156
+
157
+ it "supports large amounts of data" do
158
+ iterations = 1000
159
+ blob = "123" * 1024
160
+ spawn_process do
161
+ iterations.times do |i|
162
+ @channel.write(blob)
163
+ end
164
+ end
165
+ iterations.times do
166
+ @channel.read.should == [blob]
167
+ end
168
+ end
169
+
170
+ it "has stream properties" do
171
+ garbage = File.binread("stub/garbage1.dat")
172
+ spawn_process do
173
+ @channel.write("hello", "world")
174
+ @channel.write_scalar(garbage)
175
+ @channel.send_io(STDIN)
176
+ @channel.write_scalar(":-)")
177
+
178
+ a = @channel.read_scalar
179
+ b = @channel.read
180
+ b << a
181
+ @channel.write(*b)
182
+ end
183
+ @channel.read.should == ["hello", "world"]
184
+ @channel.read_scalar.should == garbage
185
+ @channel.recv_io.close
186
+ @channel.read_scalar.should == ":-)"
187
+
188
+ @channel.write_scalar("TASTE MY WRATH! ULTIMATE SWORD TECHNIQUE!! DRAGON'S BREATH SL--")
189
+ @channel.write("Uhm, watch your step.", "WAAHH?!", "Calm down, Motoko!!")
190
+ @channel.read.should == ["Uhm, watch your step.", "WAAHH?!", "Calm down, Motoko!!",
191
+ "TASTE MY WRATH! ULTIMATE SWORD TECHNIQUE!! DRAGON'S BREATH SL--"]
192
+ end
193
+ end
194
194
  end
195
195
 
196
196
  end # module PhusionPassenger