passenger 2.2.2 → 2.2.3

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 (254) hide show
  1. data/DEVELOPERS.TXT +13 -3
  2. data/Rakefile +42 -33
  3. data/bin/passenger-install-apache2-module +1 -2
  4. data/bin/passenger-install-nginx-module +7 -19
  5. data/bin/passenger-status +64 -15
  6. data/bin/passenger-stress-test +2 -2
  7. data/doc/ApplicationPool algorithm.txt +26 -22
  8. data/doc/Users guide Apache.html +374 -149
  9. data/doc/Users guide Apache.txt +318 -51
  10. data/doc/Users guide Nginx.html +13 -13
  11. data/doc/Users guide Nginx.txt +7 -2
  12. data/doc/cxxapi/Bucket_8h-source.html +62 -25
  13. data/doc/cxxapi/Configuration_8h-source.html +343 -326
  14. data/doc/cxxapi/DirectoryMapper_8h-source.html +12 -12
  15. data/doc/cxxapi/Hooks_8h-source.html +1 -1
  16. data/doc/cxxapi/annotated.html +1 -1
  17. data/doc/cxxapi/classHooks-members.html +1 -1
  18. data/doc/cxxapi/classHooks.html +1 -1
  19. data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +2 -2
  20. data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +9 -9
  21. data/doc/cxxapi/classes.html +1 -1
  22. data/doc/cxxapi/definitions_8h-source.html +1 -1
  23. data/doc/cxxapi/files.html +1 -1
  24. data/doc/cxxapi/functions.html +2 -2
  25. data/doc/cxxapi/functions_func.html +2 -2
  26. data/doc/cxxapi/graph_legend.html +1 -1
  27. data/doc/cxxapi/group__Configuration.html +1 -1
  28. data/doc/cxxapi/group__Core.html +1 -1
  29. data/doc/cxxapi/group__Hooks.html +1 -1
  30. data/doc/cxxapi/group__Support.html +1 -1
  31. data/doc/cxxapi/main.html +1 -1
  32. data/doc/cxxapi/modules.html +1 -1
  33. data/doc/rdoc/classes/ConditionVariable.html +194 -0
  34. data/doc/rdoc/classes/Exception.html +120 -0
  35. data/doc/rdoc/classes/GC.html +113 -0
  36. data/doc/rdoc/classes/IO.html +169 -0
  37. data/doc/rdoc/classes/PhusionPassenger.html +238 -0
  38. data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +153 -0
  39. data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +517 -0
  40. data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +719 -0
  41. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerAlreadyStarted.html +97 -0
  42. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerError.html +96 -0
  43. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerNotStarted.html +97 -0
  44. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/UnknownMessage.html +96 -0
  45. data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +598 -0
  46. data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +140 -0
  47. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +317 -0
  48. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +138 -0
  49. data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +154 -0
  50. data/doc/rdoc/classes/PhusionPassenger/Application.html +283 -0
  51. data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +172 -0
  52. data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +145 -0
  53. data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +175 -0
  54. data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +141 -0
  55. data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +92 -0
  56. data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +489 -0
  57. data/doc/rdoc/classes/PhusionPassenger/NativeSupport.html +350 -0
  58. data/doc/rdoc/classes/PhusionPassenger/Rack.html +91 -0
  59. data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +188 -0
  60. data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +194 -0
  61. data/doc/rdoc/classes/PhusionPassenger/Railz.html +95 -0
  62. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +442 -0
  63. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +98 -0
  64. data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +200 -0
  65. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +436 -0
  66. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +98 -0
  67. data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +155 -0
  68. data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +402 -0
  69. data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +125 -0
  70. data/doc/rdoc/classes/PhusionPassenger/Utils.html +805 -0
  71. data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +140 -0
  72. data/doc/rdoc/classes/PhusionPassenger/WSGI.html +89 -0
  73. data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +188 -0
  74. data/doc/rdoc/classes/PlatformInfo.html +831 -0
  75. data/doc/rdoc/classes/RakeExtensions.html +197 -0
  76. data/doc/rdoc/classes/Signal.html +131 -0
  77. data/doc/rdoc/created.rid +1 -0
  78. data/doc/rdoc/files/DEVELOPERS_TXT.html +255 -0
  79. data/doc/rdoc/files/README.html +157 -0
  80. data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +92 -0
  81. data/doc/rdoc/files/lib/phusion_passenger/abstract_installer_rb.html +129 -0
  82. data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +131 -0
  83. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +126 -0
  84. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +130 -0
  85. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +130 -0
  86. data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +122 -0
  87. data/doc/rdoc/files/lib/phusion_passenger/application_rb.html +127 -0
  88. data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +126 -0
  89. data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +122 -0
  90. data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +134 -0
  91. data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +122 -0
  92. data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +122 -0
  93. data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +126 -0
  94. data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +122 -0
  95. data/doc/rdoc/files/lib/phusion_passenger/packaging_rb.html +122 -0
  96. data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +127 -0
  97. data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +133 -0
  98. data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +127 -0
  99. data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +143 -0
  100. data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +126 -0
  101. data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +145 -0
  102. data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +127 -0
  103. data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +122 -0
  104. data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +161 -0
  105. data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +175 -0
  106. data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +129 -0
  107. data/doc/rdoc/files/misc/rake/extensions_rb.html +130 -0
  108. data/doc/rdoc/fr_class_index.html +90 -0
  109. data/doc/rdoc/fr_file_index.html +76 -0
  110. data/doc/rdoc/fr_method_index.html +200 -0
  111. data/doc/rdoc/index.html +26 -0
  112. data/doc/rdoc/rdoc-style.css +187 -0
  113. data/doc/users_guide_snippets/rackup_specifications.txt +2 -8
  114. data/ext/apache2/Bucket.cpp +71 -38
  115. data/ext/apache2/Bucket.h +53 -16
  116. data/ext/apache2/Configuration.cpp +15 -0
  117. data/ext/apache2/Configuration.h +19 -2
  118. data/ext/apache2/DirectoryMapper.h +10 -10
  119. data/ext/apache2/Hooks.cpp +334 -74
  120. data/ext/boost/mpl/apply.hpp +5 -1
  121. data/ext/boost/mpl/apply_wrap.hpp +5 -2
  122. data/ext/boost/mpl/aux_/full_lambda.hpp +5 -1
  123. data/ext/boost/mpl/bind.hpp +5 -1
  124. data/ext/common/Application.h +11 -31
  125. data/ext/common/ApplicationPool.h +2 -1
  126. data/ext/common/ApplicationPoolServer.h +61 -20
  127. data/ext/common/ApplicationPoolServerExecutable.cpp +132 -4
  128. data/ext/common/ApplicationPoolStatusReporter.h +189 -65
  129. data/ext/common/Base64.cpp +143 -0
  130. data/ext/common/Base64.h +57 -0
  131. data/ext/common/CachedFileStat.cpp +25 -82
  132. data/ext/common/CachedFileStat.h +11 -125
  133. data/ext/common/CachedFileStat.hpp +243 -0
  134. data/ext/common/Exceptions.h +13 -0
  135. data/ext/common/FileChangeChecker.h +209 -0
  136. data/ext/common/Logging.h +3 -2
  137. data/ext/common/MessageChannel.h +10 -10
  138. data/ext/common/PoolOptions.h +72 -5
  139. data/ext/common/SpawnManager.h +11 -8
  140. data/ext/common/StandardApplicationPool.h +38 -39
  141. data/ext/common/StaticString.h +1 -0
  142. data/ext/common/StringListCreator.h +83 -0
  143. data/ext/common/SystemTime.h +3 -2
  144. data/ext/common/Timer.h +88 -0
  145. data/ext/common/Utils.cpp +161 -42
  146. data/ext/common/Utils.h +62 -31
  147. data/ext/common/Version.h +1 -1
  148. data/ext/nginx/Configuration.c +0 -4
  149. data/ext/nginx/ContentHandler.c +8 -6
  150. data/ext/nginx/HelperServer.cpp +45 -55
  151. data/ext/nginx/HttpStatusExtractor.h +4 -0
  152. data/ext/nginx/StaticContentHandler.c +25 -5
  153. data/ext/nginx/config +3 -0
  154. data/ext/nginx/ngx_http_passenger_module.c +72 -17
  155. data/ext/nginx/ngx_http_passenger_module.h +2 -2
  156. data/lib/phusion_passenger/abstract_request_handler.rb +15 -7
  157. data/lib/phusion_passenger/abstract_server.rb +16 -2
  158. data/lib/phusion_passenger/admin_tools/control_process.rb +36 -25
  159. data/lib/phusion_passenger/constants.rb +1 -1
  160. data/lib/phusion_passenger/dependencies.rb +10 -0
  161. data/lib/phusion_passenger/platform_info.rb +1 -1
  162. data/lib/phusion_passenger/rack/application_spawner.rb +21 -2
  163. data/lib/phusion_passenger/rack/request_handler.rb +10 -0
  164. data/lib/phusion_passenger/railz/application_spawner.rb +38 -2
  165. data/lib/phusion_passenger/railz/framework_spawner.rb +26 -28
  166. data/lib/phusion_passenger/railz/request_handler.rb +5 -1
  167. data/lib/phusion_passenger/spawn_manager.rb +6 -2
  168. data/lib/phusion_passenger/utils.rb +79 -27
  169. data/misc/rake/cplusplus.rb +5 -5
  170. data/test/ApplicationPoolServerTest.cpp +42 -0
  171. data/test/ApplicationPoolTest.cpp +255 -267
  172. data/test/Base64Test.cpp +48 -0
  173. data/test/CachedFileStatTest.cpp +243 -103
  174. data/test/FileChangeCheckerTest.cpp +331 -0
  175. data/test/PoolOptionsTest.cpp +80 -0
  176. data/test/UtilsTest.cpp +5 -17
  177. data/test/integration_tests/apache2_tests.rb +15 -4
  178. data/test/integration_tests/mycook_spec.rb +3 -4
  179. data/test/oxt/syscall_interruption_test.cpp +2 -14
  180. data/test/ruby/abstract_server_collection_spec.rb +1 -1
  181. data/test/ruby/abstract_server_spec.rb +35 -1
  182. data/test/ruby/rack/application_spawner_spec.rb +23 -6
  183. data/test/ruby/rails/application_spawner_spec.rb +6 -6
  184. data/test/ruby/rails/framework_spawner_spec.rb +6 -5
  185. data/test/ruby/rails/minimal_spawner_spec.rb +19 -0
  186. data/test/ruby/rails/spawner_error_handling_spec.rb +62 -7
  187. data/test/ruby/spawn_manager_spec.rb +10 -7
  188. data/test/ruby/spawn_server_spec.rb +1 -1
  189. data/test/ruby/utils_spec.rb +193 -20
  190. data/test/ruby/wsgi/application_spawner_spec.rb +3 -1
  191. data/test/stub/apache2/httpd.conf.erb +3 -0
  192. data/test/stub/rack/config.ru +1 -1
  193. data/test/stub/rails_apps/mycook/app/controllers/welcome_controller.rb +8 -0
  194. data/test/support/Support.cpp +84 -0
  195. data/test/support/Support.h +66 -8
  196. data/test/support/config.rb +14 -2
  197. data/test/support/test_helper.rb +5 -0
  198. data/vendor/rack-1.0.0-git/lib/rack/auth/openid.rb +123 -116
  199. data/vendor/rack-1.0.0-git/lib/rack/cascade.rb +17 -12
  200. data/vendor/rack-1.0.0-git/lib/rack/commonlogger.rb +34 -43
  201. data/vendor/rack-1.0.0-git/lib/rack/handler/cgi.rb +1 -1
  202. data/vendor/rack-1.0.0-git/lib/rack/handler/fastcgi.rb +1 -1
  203. data/vendor/rack-1.0.0-git/lib/rack/handler/lsws.rb +1 -1
  204. data/vendor/rack-1.0.0-git/lib/rack/handler/mongrel.rb +1 -1
  205. data/vendor/rack-1.0.0-git/lib/rack/handler/scgi.rb +1 -1
  206. data/vendor/rack-1.0.0-git/lib/rack/handler/webrick.rb +1 -1
  207. data/vendor/rack-1.0.0-git/lib/rack/mock.rb +4 -17
  208. data/vendor/rack-1.0.0-git/lib/rack/request.rb +3 -9
  209. data/vendor/rack-1.0.0-git/lib/rack/rewindable_input.rb +2 -0
  210. data/vendor/rack-1.0.0-git/lib/rack/utils.rb +38 -12
  211. metadata +231 -186
  212. data/ext/common/FileChecker.h +0 -112
  213. data/test/FileCheckerTest.cpp +0 -79
  214. data/test/stub/minimal-railsapp/README +0 -3
  215. data/test/stub/minimal-railsapp/config/application.rb +0 -0
  216. data/test/stub/minimal-railsapp/config/environment.rb +0 -3
  217. data/test/stub/minimal-railsapp/vendor/rails/actionmailer/lib/action_mailer.rb +0 -0
  218. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_controller.rb +0 -10
  219. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_pack.rb +0 -0
  220. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_view.rb +0 -0
  221. data/test/stub/minimal-railsapp/vendor/rails/activerecord/lib/active_record.rb +0 -7
  222. data/test/stub/minimal-railsapp/vendor/rails/activeresource/lib/active_resource.rb +0 -0
  223. data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support.rb +0 -17
  224. data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support/whiny_nil.rb +0 -0
  225. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/dispatcher.rb +0 -0
  226. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/initializer.rb +0 -8
  227. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/ruby_version_check.rb +0 -1
  228. data/test/stub/railsapp/app/controllers/application.rb +0 -12
  229. data/test/stub/railsapp/app/controllers/bar_controller.rb +0 -5
  230. data/test/stub/railsapp/app/controllers/bar_controller_1.txt +0 -5
  231. data/test/stub/railsapp/app/controllers/bar_controller_2.txt +0 -5
  232. data/test/stub/railsapp/app/controllers/foo_controller.rb +0 -9
  233. data/test/stub/railsapp/app/helpers/application_helper.rb +0 -3
  234. data/test/stub/railsapp/config/boot.rb +0 -108
  235. data/test/stub/railsapp/config/database.yml +0 -19
  236. data/test/stub/railsapp/config/environment.rb +0 -59
  237. data/test/stub/railsapp/config/environments/development.rb +0 -18
  238. data/test/stub/railsapp/config/environments/production.rb +0 -19
  239. data/test/stub/railsapp/config/initializers/inflections.rb +0 -10
  240. data/test/stub/railsapp/config/initializers/mime_types.rb +0 -5
  241. data/test/stub/railsapp/config/routes.rb +0 -35
  242. data/test/stub/railsapp/public/useless.txt +0 -1
  243. data/test/stub/railsapp2/app/controllers/application.rb +0 -12
  244. data/test/stub/railsapp2/app/controllers/foo_controller.rb +0 -5
  245. data/test/stub/railsapp2/app/helpers/application_helper.rb +0 -3
  246. data/test/stub/railsapp2/config/boot.rb +0 -108
  247. data/test/stub/railsapp2/config/database.yml +0 -19
  248. data/test/stub/railsapp2/config/environment.rb +0 -59
  249. data/test/stub/railsapp2/config/environments/development.rb +0 -18
  250. data/test/stub/railsapp2/config/environments/production.rb +0 -19
  251. data/test/stub/railsapp2/config/initializers/inflections.rb +0 -10
  252. data/test/stub/railsapp2/config/initializers/mime_types.rb +0 -5
  253. data/test/stub/railsapp2/config/routes.rb +0 -35
  254. data/test/stub/railsapp2/public/useless.txt +0 -1
@@ -93,6 +93,18 @@ describe "mod_passenger running in Apache 2" do
93
93
  end
94
94
  end
95
95
  end
96
+
97
+ it "supports environment variable passing through mod_env" do
98
+ begin
99
+ File.open("#{@stub.app_root}/public/.htaccess", 'w') do |f|
100
+ f.puts 'SetEnv FOO "Foo Bar!"'
101
+ end
102
+ File.touch("#{@stub.app_root}/tmp/restart.txt")
103
+ get('/welcome/environment').should =~ /FOO = Foo Bar\!/
104
+ ensure
105
+ File.unlink("#{@stub.app_root}/public/.htaccess") rescue nil
106
+ end
107
+ end
96
108
  end
97
109
 
98
110
  describe ": MyCook(tm) beta running in a sub-URI" do
@@ -199,7 +211,8 @@ describe "mod_passenger running in Apache 2" do
199
211
  })
200
212
  end
201
213
 
202
- File.open(restart_file, 'w').close
214
+ now = Time.now
215
+ File.touch(restart_file, now - 5)
203
216
  get('/bar').should == "hello world"
204
217
 
205
218
  File.open(controller, 'w') do |f|
@@ -212,9 +225,7 @@ describe "mod_passenger running in Apache 2" do
212
225
  })
213
226
  end
214
227
 
215
- now = Time.now
216
- File.open(restart_file, 'w').close
217
- File.utime(now - 10, now - 10, restart_file)
228
+ File.touch(restart_file, now - 10)
218
229
  get('/bar').should == "oh hai"
219
230
  ensure
220
231
  File.unlink(controller) rescue nil
@@ -124,8 +124,7 @@ shared_examples_for "MyCook(tm) beta" do
124
124
  end
125
125
  }
126
126
  end
127
- File.open(restart_file, 'w').close
128
- File.utime(now - 10, now - 10, restart_file)
127
+ File.touch(restart_file, now - 10)
129
128
  get('/test').should == "foo"
130
129
 
131
130
  File.open(controller, 'w') do |f|
@@ -139,7 +138,7 @@ shared_examples_for "MyCook(tm) beta" do
139
138
  }
140
139
  end
141
140
 
142
- File.utime(now - 5, now - 5, restart_file)
141
+ File.touch(restart_file, now - 5)
143
142
  get('/test').should == 'bar'
144
143
  ensure
145
144
  File.unlink(controller) rescue nil
@@ -165,7 +164,7 @@ shared_examples_for "MyCook(tm) beta" do
165
164
  })
166
165
  end
167
166
  begin
168
- system "touch '#{@stub.app_root}/tmp/restart.txt'"
167
+ File.touch("#{@stub.app_root}/tmp/restart.txt")
169
168
  get('/welcome/passenger_name').should == 'Gourry Gabriev'
170
169
  ensure
171
170
  File.unlink("#{@stub.app_root}/app/models/passenger.rb") rescue nil
@@ -9,22 +9,10 @@ using namespace oxt;
9
9
  using namespace std;
10
10
 
11
11
  namespace tut {
12
- struct SyscallInterruptionTest {
13
- SyscallInterruptionTest() {
14
- setup_syscall_interruption_support();
15
- }
16
-
17
- ~SyscallInterruptionTest() {
18
- struct sigaction action;
19
-
20
- action.sa_handler = SIG_DFL;
21
- action.sa_flags = 0;
22
- sigemptyset(&action.sa_mask);
23
- sigaction(INTERRUPTION_SIGNAL, &action, NULL);
24
- }
12
+ struct syscall_interruption_test {
25
13
  };
26
14
 
27
- DEFINE_TEST_GROUP(SyscallInterruptionTest);
15
+ DEFINE_TEST_GROUP(syscall_interruption_test);
28
16
 
29
17
  struct SleepFunction {
30
18
  void operator()() {
@@ -63,7 +63,7 @@ describe AbstractServerCollection do
63
63
  end
64
64
  end
65
65
 
66
- specify "#delete stop the server if it's started" do
66
+ specify "#delete stops the server if it's started" do
67
67
  @collection.synchronize do
68
68
  server = AbstractServer.new
69
69
  @collection.lookup_or_add('foo') do
@@ -1,4 +1,10 @@
1
- shared_examples_for "AbstractServer" do
1
+ require 'support/config'
2
+
3
+ require 'phusion_passenger/abstract_server'
4
+
5
+ include PhusionPassenger
6
+
7
+ shared_examples_for "an AbstractServer" do
2
8
  it "doesn't crash if it's started and stopped multiple times" do
3
9
  3.times do
4
10
  # Give the server some time to install the
@@ -15,3 +21,31 @@ shared_examples_for "AbstractServer" do
15
21
  lambda { @server.start }.should raise_error(AbstractServer::ServerAlreadyStarted)
16
22
  end
17
23
  end
24
+
25
+ describe AbstractServer do
26
+ before :each do
27
+ @server = AbstractServer.new
28
+ end
29
+
30
+ after :each do
31
+ @server.stop if @server.started?
32
+ end
33
+
34
+ it "reseeds the pseudo-random number generator after forking off a process" do
35
+ @server.send(:define_message_handler, :random_number, :handle_random_number)
36
+ @server.stub!(:handle_random_number).and_return do
37
+ @server.send(:client).write(rand.to_s)
38
+ end
39
+
40
+ @server.start
41
+ @server.send(:server).write("random_number")
42
+ first_num = @server.send(:server).read
43
+
44
+ @server.stop
45
+ @server.start
46
+ @server.send(:server).write("random_number")
47
+ second_num = @server.send(:server).read
48
+
49
+ first_num.should_not == second_num
50
+ end
51
+ end
@@ -19,7 +19,7 @@ describe PhusionPassenger::Rack::ApplicationSpawner do
19
19
 
20
20
  it "propagates exceptions in application startup" do
21
21
  File.prepend("#{@stub.app_root}/config.ru", "raise StandardError, 'foo'\n")
22
- spawn = lambda { spawn(@stub.app_root) }
22
+ spawn = lambda { spawn(@stub.app_root, "print_exceptions" => false) }
23
23
  spawn.should raise_error(StandardError)
24
24
  end
25
25
 
@@ -34,8 +34,25 @@ describe PhusionPassenger::Rack::ApplicationSpawner do
34
34
  config_ru_owner.should == touch_txt_owner
35
35
  end if Process.euid == 0
36
36
 
37
+ it "sets the environment variables passed in the environment_variables option" do
38
+ File.append("#{@stub.app_root}/config.ru", %q{
39
+ File.open("env.txt", "w") do |f|
40
+ ENV.each_pair do |key, value|
41
+ f.puts("#{key} = #{value}")
42
+ end
43
+ end
44
+ })
45
+ env_vars_string = "PATH\0/usr/bin:/opt/sw/bin\0FOO\0foo bar!\0"
46
+ options = { "environment_variables" => [env_vars_string].pack("m") }
47
+ spawn(@stub.app_root, options).close
48
+
49
+ contents = File.read("#{@stub.app_root}/env.txt")
50
+ contents.should =~ %r(PATH = /usr/bin:/opt/sw/bin\n)
51
+ contents.should =~ %r(FOO = foo bar\!\n)
52
+ end
53
+
37
54
  it "calls the starting_worker_process event after config.ru has been loaded" do
38
- File.append("#{@stub.app_root}/config.ru", %q{
55
+ File.append("#{@stub.app_root}/config.ru", %q{
39
56
  PhusionPassenger.on_event(:starting_worker_process) do
40
57
  File.append("rackresult.txt", "worker_process_started\n")
41
58
  end
@@ -55,7 +72,7 @@ describe PhusionPassenger::Rack::ApplicationSpawner do
55
72
  end
56
73
 
57
74
  it "calls the stopping_worker_process event" do
58
- File.append("#{@stub.app_root}/config.ru", %q{
75
+ File.append("#{@stub.app_root}/config.ru", %q{
59
76
  PhusionPassenger.on_event(:stopping_worker_process) do
60
77
  File.append("rackresult.txt", "worker_process_stopped\n")
61
78
  end
@@ -74,9 +91,9 @@ describe PhusionPassenger::Rack::ApplicationSpawner do
74
91
  "worker_process_stopped\n"
75
92
  end
76
93
 
77
- def spawn(app_root)
78
- PhusionPassenger::Rack::ApplicationSpawner.spawn_application(app_root,
79
- "lowest_user" => CONFIG['lowest_user'])
94
+ def spawn(app_root, extra_options = {})
95
+ options = { "lowest_user" => CONFIG['lowest_user'] }.merge(extra_options)
96
+ PhusionPassenger::Rack::ApplicationSpawner.spawn_application(app_root, options)
80
97
  end
81
98
  end
82
99
 
@@ -69,9 +69,9 @@ describe ApplicationSpawner do
69
69
  end
70
70
  end
71
71
 
72
- def spawn_stub_application(stub)
73
- @spawner = ApplicationSpawner.new(stub.app_root,
74
- "lowest_user" => CONFIG['lowest_user'])
72
+ def spawn_stub_application(stub, extra_options = {})
73
+ options = { "lowest_user" => CONFIG['lowest_user'] }.merge(extra_options)
74
+ @spawner = ApplicationSpawner.new(stub.app_root, options)
75
75
  begin
76
76
  @spawner.start
77
77
  return @spawner.spawn_application
@@ -107,9 +107,9 @@ describe ApplicationSpawner do
107
107
  end
108
108
  end
109
109
 
110
- def spawn_stub_application(stub)
111
- @spawner = ApplicationSpawner.new(stub.app_root,
112
- "lowest_user" => CONFIG['lowest_user'])
110
+ def spawn_stub_application(stub, extra_options = {})
111
+ options = { "lowest_user" => CONFIG['lowest_user'] }.merge(extra_options)
112
+ @spawner = ApplicationSpawner.new(stub.app_root, options)
113
113
  return @spawner.spawn_application!
114
114
  end
115
115
  end
@@ -76,7 +76,7 @@ describe FrameworkSpawner do
76
76
  it_should_behave_like "handling errors in framework initialization"
77
77
  end
78
78
 
79
- def spawn_stub_application(stub)
79
+ def spawn_stub_application(stub, extra_options = {})
80
80
  if use_vendor_rails?
81
81
  stub.use_vendor_rails('minimal')
82
82
  end
@@ -86,18 +86,19 @@ describe FrameworkSpawner do
86
86
  else
87
87
  options = { :version => version }
88
88
  end
89
+ options["lowest_user"] = CONFIG['lowest_user']
90
+ options = options.merge(extra_options)
89
91
  spawner = FrameworkSpawner.new(options)
90
92
  spawner.start
91
93
  begin
92
- return spawner.spawn_application(stub.app_root,
93
- "lowest_user" => CONFIG['lowest_user'])
94
+ return spawner.spawn_application(stub.app_root, options)
94
95
  ensure
95
96
  spawner.stop
96
97
  end
97
98
  end
98
99
 
99
- def load_nonexistant_framework
100
- spawner = FrameworkSpawner.new(:version => "1.9.827")
100
+ def load_nonexistant_framework(options = {})
101
+ spawner = FrameworkSpawner.new(options.merge(:version => "1.9.827"))
101
102
  begin
102
103
  spawner.start
103
104
  ensure
@@ -71,4 +71,23 @@ shared_examples_for "a minimal spawner" do
71
71
  lambda { spawn_stub_application(stub).close }.should_not raise_error
72
72
  end
73
73
  end
74
+
75
+ it "sets the environment variables passed in the environment_variables option" do
76
+ use_rails_stub('foobar') do |stub|
77
+ File.append(stub.environment_rb, %q{
78
+ File.open("env.txt", "w") do |f|
79
+ ENV.each_pair do |key, value|
80
+ f.puts("#{key} = #{value}")
81
+ end
82
+ end
83
+ })
84
+ env_vars_string = "PATH\0/usr/bin:/opt/sw/bin\0FOO\0foo bar!\0"
85
+ options = { "environment_variables" => [env_vars_string].pack("m") }
86
+ spawn_stub_application(stub, options).close
87
+
88
+ contents = File.read("#{stub.app_root}/env.txt")
89
+ contents.should =~ %r(PATH = /usr/bin:/opt/sw/bin\n)
90
+ contents.should =~ %r(FOO = foo bar\!\n)
91
+ end
92
+ end
74
93
  end
@@ -1,3 +1,5 @@
1
+ require 'stringio'
2
+
1
3
  shared_examples_for "handling errors in application initialization" do
2
4
  before :each do
3
5
  @stub = setup_rails_stub('foobar')
@@ -11,8 +13,8 @@ shared_examples_for "handling errors in application initialization" do
11
13
  it "raises an AppInitError if the spawned app raises a standard exception during startup" do
12
14
  File.prepend(@stub.environment_rb, "raise 'This is a dummy exception.'\n")
13
15
  begin
14
- spawn_stub_application(@stub).close
15
- violated "Spawning the application should have raised an InitializationError."
16
+ spawn_stub_application(@stub, "print_exceptions" => false).close
17
+ violated "Spawning the application should have raised an AppInitError."
16
18
  rescue AppInitError => e
17
19
  e.child_exception.message.should == "This is a dummy exception."
18
20
  end
@@ -26,8 +28,8 @@ shared_examples_for "handling errors in application initialization" do
26
28
  raise MyError, "This is a custom exception."
27
29
  })
28
30
  begin
29
- spawn_stub_application(@stub).close
30
- violated "Spawning the application should have raised an InitializationError."
31
+ spawn_stub_application(@stub, "print_exceptions" => false).close
32
+ violated "Spawning the application should have raised an AppInitError."
31
33
  rescue AppInitError => e
32
34
  e.child_exception.message.should == "This is a custom exception. (MyError)"
33
35
  end
@@ -36,17 +38,70 @@ shared_examples_for "handling errors in application initialization" do
36
38
  it "raises an AppInitError if the spawned app calls exit() during startup" do
37
39
  File.prepend(@stub.environment_rb, "exit\n")
38
40
  begin
39
- spawn_stub_application(@stub).close
40
- violated "Spawning the application should have raised an InitializationError."
41
+ spawn_stub_application(@stub, "print_exceptions" => false).close
42
+ violated "Spawning the application should have raised an AppInitError."
41
43
  rescue AppInitError => e
42
44
  e.child_exception.class.should == SystemExit
43
45
  end
44
46
  end
47
+
48
+ it "prints the exception to STDERR if the spawned app raised an error" do
49
+ old_stderr = STDERR
50
+ file = File.new('output.tmp', 'w+')
51
+ begin
52
+ Object.send(:remove_const, "STDERR") rescue nil
53
+ Object.const_set("STDERR", file)
54
+
55
+ File.prepend(@stub.environment_rb, "raise 'This is a dummy exception.'\n")
56
+ block = lambda do
57
+ spawn_stub_application(@stub).close
58
+ end
59
+ block.should raise_error(AppInitError)
60
+
61
+ file.rewind
62
+ data = file.read
63
+ data.should =~ /spawn_stub_application/
64
+ data.should =~ /spawner_error_handling_spec\.rb/
65
+ ensure
66
+ Object.send(:remove_const, "STDERR") rescue nil
67
+ Object.const_set("STDERR", old_stderr)
68
+ file.close rescue nil
69
+ File.unlink('output.tmp') rescue nil
70
+ end
71
+ end
45
72
  end
46
73
 
47
74
  shared_examples_for "handling errors in framework initialization" do
48
75
  include Utils
76
+
49
77
  it "raises FrameworkInitError if the framework could not be loaded" do
50
- lambda { load_nonexistant_framework.close }.should raise_error(FrameworkInitError)
78
+ block = lambda do
79
+ load_nonexistant_framework(:print_framework_loading_exceptions => false).close
80
+ end
81
+ block.should raise_error(FrameworkInitError)
82
+ end
83
+
84
+ it "prints the exception to STDERR if the framework could not be loaded" do
85
+ old_stderr = STDERR
86
+ file = File.new('output.tmp', 'w+')
87
+ begin
88
+ Object.send(:remove_const, "STDERR") rescue nil
89
+ Object.const_set("STDERR", file)
90
+
91
+ block = lambda do
92
+ load_nonexistant_framework.close
93
+ end
94
+ block.should raise_error(FrameworkInitError)
95
+
96
+ file.rewind
97
+ data = file.read
98
+ data.should =~ /load_nonexistant_framework/
99
+ data.should =~ /spawner_error_handling_spec\.rb/
100
+ ensure
101
+ Object.send(:remove_const, "STDERR") rescue nil
102
+ Object.const_set("STDERR", old_stderr)
103
+ file.close rescue nil
104
+ File.unlink('output.tmp') rescue nil
105
+ end
51
106
  end
52
107
  end
@@ -1,5 +1,6 @@
1
1
  require 'support/config'
2
2
  require 'support/test_helper'
3
+ require 'phusion_passenger/application'
3
4
  require 'phusion_passenger/spawn_manager'
4
5
 
5
6
  require 'ruby/abstract_server_spec'
@@ -32,7 +33,7 @@ describe SpawnManager do
32
33
  @spawn_method = "smart"
33
34
  end
34
35
 
35
- it_should_behave_like "AbstractServer"
36
+ it_should_behave_like "an AbstractServer"
36
37
  end
37
38
 
38
39
  describe "conservative spawning" do
@@ -40,7 +41,7 @@ describe SpawnManager do
40
41
  @spawn_method = "conservative"
41
42
  end
42
43
 
43
- it_should_behave_like "AbstractServer"
44
+ it_should_behave_like "an AbstractServer"
44
45
  end
45
46
 
46
47
  def spawn_arbitrary_application
@@ -169,19 +170,21 @@ describe SpawnManager do
169
170
  it_should_behave_like "handling errors in application initialization"
170
171
  it_should_behave_like "handling errors in framework initialization"
171
172
 
172
- def spawn_stub_application(stub)
173
+ def spawn_stub_application(stub, extra_options = {})
173
174
  spawner = SpawnManager.new
174
175
  begin
175
- return spawner.spawn_application(
176
+ options = {
176
177
  "app_root" => stub.app_root,
177
178
  "spawn_method" => @spawn_method,
178
- "lowest_user" => CONFIG['lowest_user'])
179
+ "lowest_user" => CONFIG['lowest_user']
180
+ }.merge(extra_options)
181
+ return spawner.spawn_application(options)
179
182
  ensure
180
183
  spawner.cleanup
181
184
  end
182
185
  end
183
186
 
184
- def load_nonexistant_framework
187
+ def load_nonexistant_framework(extra_options = {})
185
188
  # Prevent detect_framework_version from raising VersionNotFound
186
189
  Application.instance_eval do
187
190
  alias orig_detect_framework_version detect_framework_version
@@ -192,7 +195,7 @@ describe SpawnManager do
192
195
  begin
193
196
  File.write(@stub.environment_rb, "RAILS_GEM_VERSION = '1.9.827'")
194
197
  @stub.dont_use_vendor_rails
195
- return spawn_stub_application(@stub)
198
+ return spawn_stub_application(@stub, extra_options)
196
199
  ensure
197
200
  Application.instance_eval do
198
201
  alias detect_framework_version orig_detect_framework_version