passenger 4.0.10 → 4.0.13

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 (224) hide show
  1. data.tar.gz.asc +7 -7
  2. data/.gitignore +66 -0
  3. data/.travis.yml +2 -5
  4. data/CONTRIBUTORS +2 -1
  5. data/NEWS +24 -0
  6. data/README.md +5 -10
  7. data/bin/passenger +1 -0
  8. data/bin/passenger-config +29 -3
  9. data/bin/passenger-install-nginx-module +1 -1
  10. data/build/basics.rb +8 -2
  11. data/build/debian.rb +22 -0
  12. data/build/integration_tests.rb +16 -2
  13. data/build/misc.rb +3 -0
  14. data/build/packaging.rb +77 -29
  15. data/build/preprocessor.rb +13 -10
  16. data/build/test_basics.rb +6 -0
  17. data/debian.template/locations.ini.template +13 -0
  18. data/debian.template/ruby-passenger-dev.install.template +3 -0
  19. data/debian.template/ruby-passenger-doc.install.template +2 -0
  20. data/debian.template/ruby-passenger.install.template +12 -0
  21. data/debian.template/rules.template +1 -0
  22. data/dev/run_travis.sh +46 -14
  23. data/doc/Architectural overview.html +25 -34
  24. data/doc/Packaging.html +31 -23
  25. data/doc/Packaging.txt.md +32 -23
  26. data/doc/Security of user switching support.html +16 -18
  27. data/doc/Users guide Apache.html +231 -239
  28. data/doc/Users guide Nginx.html +219 -227
  29. data/doc/Users guide Standalone.html +12 -15
  30. data/doc/users_guide_snippets/installation.txt +3 -2
  31. data/ext/common/ApplicationPool2/Implementation.cpp +6 -16
  32. data/ext/common/Constants.h +1 -1
  33. data/ext/common/ResourceLocator.h +6 -6
  34. data/ext/common/UnionStation.h +11 -15
  35. data/ext/common/Utils/ProcessMetricsCollector.h +7 -4
  36. data/ext/common/agents/HelperAgent/AgentOptions.h +6 -0
  37. data/ext/common/agents/HelperAgent/Main.cpp +5 -0
  38. data/ext/common/agents/HelperAgent/RequestHandler.h +9 -1
  39. data/ext/common/agents/LoggingAgent/Main.cpp +4 -0
  40. data/ext/common/agents/Watchdog/Main.cpp +7 -0
  41. data/ext/nginx/config +1 -1
  42. data/ext/oxt/Readme.txt +15 -0
  43. data/helper-scripts/download_binaries/extconf.rb +83 -0
  44. data/lib/phusion_passenger.rb +78 -80
  45. data/lib/phusion_passenger/abstract_installer.rb +22 -8
  46. data/lib/phusion_passenger/console_text_template.rb +1 -1
  47. data/lib/phusion_passenger/loader_shared_helpers.rb +2 -1
  48. data/lib/phusion_passenger/native_support.rb +22 -9
  49. data/lib/phusion_passenger/packaging.rb +7 -2
  50. data/lib/phusion_passenger/platform_info.rb +28 -1
  51. data/lib/phusion_passenger/platform_info/apache.rb +246 -26
  52. data/lib/phusion_passenger/platform_info/apache_detector.rb +232 -0
  53. data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +4 -0
  54. data/lib/phusion_passenger/platform_info/linux.rb +7 -0
  55. data/lib/phusion_passenger/public_api.rb +11 -2
  56. data/lib/phusion_passenger/standalone/command.rb +11 -14
  57. data/lib/phusion_passenger/standalone/runtime_installer.rb +313 -275
  58. data/lib/phusion_passenger/standalone/runtime_locator.rb +163 -0
  59. data/lib/phusion_passenger/standalone/start_command.rb +38 -46
  60. data/lib/phusion_passenger/utils/json.rb +329 -0
  61. data/lib/phusion_passenger/utils/tmpio.rb +1 -0
  62. data/passenger.gemspec +4 -0
  63. data/resources/mime.types +1 -0
  64. data/resources/oss-binaries.phusionpassenger.com.crt +84 -0
  65. data/resources/release.txt +0 -0
  66. data/resources/templates/standalone/download_tool_missing.txt.erb +18 -0
  67. data/rpm/README.rdoc +117 -0
  68. data/rpm/config/apache-passenger.conf.in +19 -0
  69. data/rpm/config/nginx-passenger.conf.in +10 -0
  70. data/rpm/config/rubygem-passenger.te +10 -0
  71. data/rpm/doc/README.nginx-alternatives +5 -0
  72. data/rpm/doc/example_yum_repository_htaccess +5 -0
  73. data/rpm/doc/footer.shtml +12 -0
  74. data/rpm/doc/header.shtml +156 -0
  75. data/rpm/nginx-alternatives.spec +97 -0
  76. data/rpm/passenger-release.spec +91 -0
  77. data/rpm/passenger.spec +667 -0
  78. data/rpm/patches/passenger-force-native.patch +63 -0
  79. data/rpm/release/RPM-GPG-KEY-stealthymonkeys +33 -0
  80. data/rpm/release/build-release.sh +35 -0
  81. data/rpm/release/build.rb +301 -0
  82. data/rpm/release/create-mirrors.sh +16 -0
  83. data/rpm/release/mirrors +1 -0
  84. data/rpm/release/mock-repo/comps.xml +21 -0
  85. data/rpm/release/mock-repo/rubygem-daemon_controller-0.2.5-1.noarch.rpm +0 -0
  86. data/rpm/release/mock-repo/rubygem-file-tail-1.0.5-1.noarch.rpm +0 -0
  87. data/rpm/release/mock-repo/rubygem-spruz-0.2.2-1.noarch.rpm +0 -0
  88. data/rpm/release/mocksetup-first.sh +102 -0
  89. data/rpm/release/mocksetup.sh +67 -0
  90. data/test/integration_tests/apache2_tests.rb +1 -1
  91. data/test/integration_tests/downloaded_binaries_tests.rb +76 -0
  92. data/test/integration_tests/native_packaging_spec.rb +38 -6
  93. data/test/integration_tests/source_packaging_test.rb +198 -0
  94. data/test/integration_tests/standalone_tests.rb +275 -0
  95. data/test/ruby/admin_tools_spec.rb +1 -1
  96. data/test/ruby/rails4.0/loader_spec.rb +28 -0
  97. data/test/ruby/rails4.0/preloader_spec.rb +34 -0
  98. data/test/ruby/spec_helper.rb +5 -1
  99. data/test/ruby/standalone/runtime_installer_spec.rb +399 -0
  100. data/test/ruby/standalone/runtime_locator_spec.rb +214 -0
  101. data/test/stub/apache2/httpd.conf.erb +18 -1
  102. data/test/stub/rack/tmp/.gitignore +0 -0
  103. data/test/stub/rails2.3/log/.gitignore +1 -0
  104. data/test/stub/rails2.3/public/.gitignore +1 -0
  105. data/test/stub/rails2.3/tmp/cache/.gitignore +1 -0
  106. data/test/stub/rails2.3/tmp/pids/.gitignore +1 -0
  107. data/test/stub/rails2.3/tmp/sessions/.gitignore +1 -0
  108. data/test/stub/rails2.3/tmp/sockets/.gitignore +1 -0
  109. data/test/stub/rails3.0/.gitignore +4 -0
  110. data/test/stub/rails3.0/Gemfile +1 -1
  111. data/test/stub/rails3.0/Gemfile.lock +1 -1
  112. data/test/stub/rails3.0/lib/tasks/.gitkeep +0 -0
  113. data/test/stub/rails3.0/log/.gitignore +0 -0
  114. data/test/stub/rails3.0/public/stylesheets/.gitkeep +0 -0
  115. data/test/stub/rails3.0/vendor/plugins/.gitkeep +0 -0
  116. data/test/stub/rails3.1/.gitignore +15 -0
  117. data/test/stub/rails3.1/Gemfile +1 -1
  118. data/test/stub/rails3.1/Gemfile.lock +1 -1
  119. data/test/stub/rails3.1/app/mailers/.gitkeep +0 -0
  120. data/test/stub/rails3.1/app/models/.gitkeep +0 -0
  121. data/test/stub/rails3.1/lib/assets/.gitkeep +0 -0
  122. data/test/stub/rails3.1/lib/tasks/.gitkeep +0 -0
  123. data/test/stub/rails3.1/log/.gitkeep +0 -0
  124. data/test/stub/rails3.1/test/fixtures/.gitkeep +0 -0
  125. data/test/stub/rails3.1/test/functional/.gitkeep +0 -0
  126. data/test/stub/rails3.1/test/integration/.gitkeep +0 -0
  127. data/test/stub/rails3.1/test/unit/.gitkeep +0 -0
  128. data/test/stub/rails3.1/vendor/assets/stylesheets/.gitkeep +0 -0
  129. data/test/stub/rails3.1/vendor/plugins/.gitkeep +0 -0
  130. data/test/stub/rails3.2/.gitignore +15 -0
  131. data/test/stub/rails3.2/app/mailers/.gitkeep +0 -0
  132. data/test/stub/rails3.2/app/models/.gitkeep +0 -0
  133. data/test/stub/rails3.2/lib/assets/.gitkeep +0 -0
  134. data/test/stub/rails3.2/lib/tasks/.gitkeep +0 -0
  135. data/test/stub/rails3.2/log/.gitkeep +0 -0
  136. data/test/stub/rails3.2/test/fixtures/.gitkeep +0 -0
  137. data/test/stub/rails3.2/test/functional/.gitkeep +0 -0
  138. data/test/stub/rails3.2/test/integration/.gitkeep +0 -0
  139. data/test/stub/rails3.2/test/unit/.gitkeep +0 -0
  140. data/test/stub/rails3.2/vendor/assets/stylesheets/.gitkeep +0 -0
  141. data/test/stub/rails3.2/vendor/plugins/.gitkeep +0 -0
  142. data/test/stub/rails4.0/.gitignore +16 -0
  143. data/test/stub/rails4.0/Gemfile +45 -0
  144. data/test/stub/rails4.0/Gemfile.lock +126 -0
  145. data/test/stub/rails4.0/README.rdoc +28 -0
  146. data/test/stub/rails4.0/Rakefile +6 -0
  147. data/test/stub/rails4.0/app/assets/images/.keep +0 -0
  148. data/test/stub/rails4.0/app/assets/javascripts/application.js +16 -0
  149. data/test/stub/rails4.0/app/assets/stylesheets/application.css +13 -0
  150. data/test/stub/rails4.0/app/controllers/application_controller.rb +5 -0
  151. data/test/stub/rails4.0/app/controllers/concerns/.keep +0 -0
  152. data/test/stub/rails4.0/app/helpers/application_helper.rb +2 -0
  153. data/test/stub/rails4.0/app/mailers/.keep +0 -0
  154. data/test/stub/rails4.0/app/models/.keep +0 -0
  155. data/test/stub/rails4.0/app/models/concerns/.keep +0 -0
  156. data/test/stub/rails4.0/app/views/layouts/application.html.erb +14 -0
  157. data/test/stub/rails4.0/bin/bundle +3 -0
  158. data/test/stub/rails4.0/bin/rails +4 -0
  159. data/test/stub/rails4.0/bin/rake +4 -0
  160. data/test/stub/rails4.0/config.ru +4 -0
  161. data/test/stub/rails4.0/config/application.rb +23 -0
  162. data/test/stub/rails4.0/config/boot.rb +4 -0
  163. data/test/stub/rails4.0/config/database.yml +25 -0
  164. data/test/stub/rails4.0/config/environment.rb +5 -0
  165. data/test/stub/rails4.0/config/environments/development.rb +29 -0
  166. data/test/stub/rails4.0/config/environments/production.rb +80 -0
  167. data/test/stub/rails4.0/config/environments/test.rb +36 -0
  168. data/test/stub/rails4.0/config/initializers/backtrace_silencers.rb +7 -0
  169. data/test/stub/rails4.0/config/initializers/filter_parameter_logging.rb +4 -0
  170. data/test/stub/rails4.0/config/initializers/inflections.rb +16 -0
  171. data/test/stub/rails4.0/config/initializers/mime_types.rb +5 -0
  172. data/test/stub/rails4.0/config/initializers/passenger.rb +1 -0
  173. data/test/stub/rails4.0/config/initializers/secret_token.rb +12 -0
  174. data/test/stub/rails4.0/config/initializers/session_store.rb +3 -0
  175. data/test/stub/rails4.0/config/initializers/wrap_parameters.rb +14 -0
  176. data/test/stub/rails4.0/config/locales/en.yml +23 -0
  177. data/test/stub/rails4.0/config/routes.rb +57 -0
  178. data/test/stub/rails4.0/db/seeds.rb +7 -0
  179. data/test/stub/rails4.0/lib/assets/.keep +0 -0
  180. data/test/stub/rails4.0/lib/tasks/.keep +0 -0
  181. data/test/stub/rails4.0/log/.keep +0 -0
  182. data/test/stub/rails4.0/public/404.html +58 -0
  183. data/test/stub/rails4.0/public/422.html +58 -0
  184. data/test/stub/rails4.0/public/500.html +57 -0
  185. data/test/stub/rails4.0/public/favicon.ico +0 -0
  186. data/test/stub/rails4.0/public/robots.txt +5 -0
  187. data/test/stub/rails4.0/test/controllers/.keep +0 -0
  188. data/test/stub/rails4.0/test/fixtures/.keep +0 -0
  189. data/test/stub/rails4.0/test/helpers/.keep +0 -0
  190. data/test/stub/rails4.0/test/integration/.keep +0 -0
  191. data/test/stub/rails4.0/test/mailers/.keep +0 -0
  192. data/test/stub/rails4.0/test/models/.keep +0 -0
  193. data/test/stub/rails4.0/test/test_helper.rb +15 -0
  194. data/test/stub/rails4.0/vendor/assets/javascripts/.keep +0 -0
  195. data/test/stub/rails4.0/vendor/assets/stylesheets/.keep +0 -0
  196. data/test/stub/rails_apps/1.2/empty/.gitignore +3 -0
  197. data/test/stub/rails_apps/1.2/empty/app/models/.gitignore +0 -0
  198. data/test/stub/rails_apps/1.2/empty/db/.gitignore +0 -0
  199. data/test/stub/rails_apps/1.2/empty/public/.htaccess +40 -0
  200. data/test/stub/rails_apps/1.2/empty/public/stylesheets/.gitignore +0 -0
  201. data/test/stub/rails_apps/2.0/empty/.gitignore +3 -0
  202. data/test/stub/rails_apps/2.0/empty/app/models/.gitignore +0 -0
  203. data/test/stub/rails_apps/2.0/empty/db/.gitignore +0 -0
  204. data/test/stub/rails_apps/2.0/empty/public/.htaccess +40 -0
  205. data/test/stub/rails_apps/2.0/empty/public/stylesheets/.gitignore +0 -0
  206. data/test/stub/rails_apps/2.2/empty/.gitignore +3 -0
  207. data/test/stub/rails_apps/2.2/empty/app/models/.gitignore +0 -0
  208. data/test/stub/rails_apps/2.2/empty/db/.gitignore +0 -0
  209. data/test/stub/rails_apps/2.2/empty/public/stylesheets/.gitignore +0 -0
  210. data/test/stub/rails_apps/2.3/empty/.gitignore +3 -0
  211. data/test/stub/rails_apps/2.3/empty/app/models/.gitignore +0 -0
  212. data/test/stub/rails_apps/2.3/empty/db/.gitignore +0 -0
  213. data/test/stub/rails_apps/2.3/empty/public/stylesheets/.gitignore +0 -0
  214. data/test/stub/rails_apps/2.3/mycook/public/.htaccess +42 -0
  215. data/test/stub/rails_apps/2.3/mycook/public/uploads/.gitignore +0 -0
  216. data/test/stub/wsgi/tmp/.gitignore +0 -0
  217. data/test/valgrind-osx.supp +7 -0
  218. metadata +162 -8
  219. metadata.gz.asc +7 -7
  220. data/debian.template/locations.ini +0 -12
  221. data/debian.template/ruby-passenger-dev.install +0 -3
  222. data/debian.template/ruby-passenger-doc.install +0 -2
  223. data/debian.template/ruby-passenger.install +0 -11
  224. data/resources/templates/installer_common/freebsd9_broken_cxx_runtime.txt.erb +0 -19
@@ -0,0 +1,275 @@
1
+ source_root = File.expand_path("../..", File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift("#{source_root}/lib")
3
+ require 'phusion_passenger'
4
+ PhusionPassenger.locate_directories
5
+ require 'phusion_passenger/platform_info/binary_compatibility'
6
+ require 'tmpdir'
7
+ require 'fileutils'
8
+ require 'webrick'
9
+ require 'thread'
10
+ require 'open-uri'
11
+
12
+ ENV['PATH'] = "#{PhusionPassenger.bin_dir}:#{ENV['PATH']}"
13
+ # This environment variable changes Passenger Standalone's behavior,
14
+ # so ensure that it's not set.
15
+ ENV.delete('PASSENGER_DEBUG')
16
+
17
+ describe "Passenger Standalone" do
18
+ after :each do
19
+ ENV.delete('PASSENGER_DEBUG')
20
+ end
21
+
22
+ let(:version) { PhusionPassenger::VERSION_STRING }
23
+ let(:nginx_version) { PhusionPassenger::PREFERRED_NGINX_VERSION }
24
+ let(:compat_id) { PhusionPassenger::PlatformInfo.cxx_binary_compatibility_id }
25
+
26
+ def use_binaries_from_source_root!
27
+ ENV['PASSENGER_DEBUG'] = '1'
28
+ end
29
+
30
+ def sh(*command)
31
+ if !system(*command)
32
+ abort "Command failed: #{command.join(' ')}"
33
+ end
34
+ end
35
+
36
+ def capture_output(command)
37
+ output = `#{command} 2>&1`.strip
38
+ if $?.exitstatus == 0
39
+ return output
40
+ else
41
+ abort "Command #{command} exited with status #{$?.exitstatus}; output:\n#{output}"
42
+ end
43
+ end
44
+
45
+ def start_server(document_root)
46
+ server = WEBrick::HTTPServer.new(:BindAddress => '127.0.0.1',
47
+ :Port => 0,
48
+ :DocumentRoot => document_root,
49
+ :Logger => WEBrick::Log.new("/dev/null"),
50
+ :AccessLog => [])
51
+ Thread.new do
52
+ Thread.current.abort_on_exception = true
53
+ server.start
54
+ end
55
+ [server, "http://127.0.0.1:#{server.config[:Port]}"]
56
+ end
57
+
58
+ def create_tarball(filename, contents = nil)
59
+ filename = File.expand_path(filename)
60
+ Dir.mktmpdir("tarball-") do |tarball_dir|
61
+ Dir.chdir(tarball_dir) do
62
+ if block_given?
63
+ yield
64
+ else
65
+ contents.each do |content_name|
66
+ create_file(content_name)
67
+ end
68
+ end
69
+ sh "tar", "-czf", filename, "."
70
+ end
71
+ end
72
+ end
73
+
74
+ def create_dummy_support_binaries
75
+ Dir.mkdir("agents") if !File.exist?("agents")
76
+ ["PassengerWatchdog", "PassengerHelperAgent", "PassengerLoggingAgent"].each do |exe|
77
+ File.open("agents/#{exe}", "w") do |f|
78
+ f.puts "#!/bin/bash"
79
+ f.puts "echo PASS"
80
+ end
81
+ File.chmod(0755, "agents/#{exe}")
82
+ end
83
+ end
84
+
85
+ def create_dummy_nginx_binary
86
+ File.open("nginx", "w") do |f|
87
+ f.puts "#!/bin/bash"
88
+ f.puts "echo nginx version: 1.0.0"
89
+ end
90
+ File.chmod(0755, "nginx")
91
+ end
92
+
93
+ def create_file(filename, contents = nil)
94
+ File.open(filename, "wb") do |f|
95
+ f.write(contents) if contents
96
+ end
97
+ end
98
+
99
+ specify "invoking 'passenger' without an argument is equivalent to 'passenger help'" do
100
+ output = capture_output("passenger")
101
+ output.should == capture_output("passenger help")
102
+ end
103
+
104
+ specify "'passenger --help' is equivalent to 'passenger help'" do
105
+ output = capture_output("passenger")
106
+ output.should == capture_output("passenger help")
107
+ end
108
+
109
+ specify "'passenger --version' displays the version number" do
110
+ output = capture_output("passenger --version")
111
+ output.should include("version #{PhusionPassenger::VERSION_STRING}\n")
112
+ end
113
+
114
+ describe "start command" do
115
+ SUPPORT_BINARIES_DOWNLOAD_MESSAGE = "Downloading Passenger support binaries for your platform, if available"
116
+ NGINX_BINARY_DOWNLOAD_MESSAGE = "Downloading Nginx binary for your platform, if available"
117
+ NGINX_SOURCE_DOWNLOAD_MESSAGE = "Downloading Nginx..."
118
+ COMPILING_MESSAGE = "Installing Phusion Passenger Standalone"
119
+
120
+ def test_serving_application(passenger_command)
121
+ Dir.chdir(@runtime_dir) do
122
+ File.open("config.ru", "w") do |f|
123
+ f.write(%Q{
124
+ app = lambda do |env|
125
+ [200, { "Content-Type" => "text/plain" }, ["ok"]]
126
+ end
127
+ run app
128
+ })
129
+ end
130
+ Dir.mkdir("public")
131
+ Dir.mkdir("tmp")
132
+ sh("#{passenger_command} -p 4000 -d >/dev/null")
133
+ begin
134
+ open("http://127.0.0.1:4000/") do |f|
135
+ f.read.should == "ok"
136
+ end
137
+ ensure
138
+ sh("passenger stop -p 4000")
139
+ end
140
+ end
141
+ end
142
+
143
+ context "if the runtime is not installed" do
144
+ before :each do
145
+ @runtime_dir = Dir.mktmpdir
146
+ @webroot = Dir.mktmpdir
147
+ @server, @base_url = start_server(@webroot)
148
+
149
+ Dir.mkdir("#{@webroot}/#{version}")
150
+ Dir.chdir("#{@webroot}/#{version}") do
151
+ create_tarball("nginx-#{nginx_version}-#{compat_id}.tar.gz") do
152
+ create_dummy_nginx_binary
153
+ end
154
+ create_tarball("support-#{compat_id}.tar.gz") do
155
+ FileUtils.mkdir_p("agents")
156
+ FileUtils.mkdir_p("common/libpassenger_common/ApplicationPool2")
157
+ create_file("common/libboost_oxt.a")
158
+ create_file("common/libpassenger_common/ApplicationPool2/Implementation.o")
159
+ create_dummy_support_binaries
160
+ end
161
+ end
162
+
163
+ create_file("#{PhusionPassenger.resources_dir}/release.txt")
164
+ end
165
+
166
+ after :each do
167
+ @server.stop
168
+ File.unlink("#{PhusionPassenger.resources_dir}/release.txt")
169
+ FileUtils.remove_entry_secure(@webroot)
170
+ FileUtils.remove_entry_secure(@runtime_dir)
171
+ end
172
+
173
+ context "when originally packaged" do
174
+ it "downloads binaries from the Internet" do
175
+ @output = capture_output("passenger start " +
176
+ "--runtime-dir '#{@runtime_dir}' " +
177
+ "--runtime-check-only " +
178
+ "--binaries-url-root '#{@base_url}'")
179
+ @output.should include(SUPPORT_BINARIES_DOWNLOAD_MESSAGE)
180
+ @output.should include(NGINX_BINARY_DOWNLOAD_MESSAGE)
181
+ @output.should_not include(NGINX_SOURCE_DOWNLOAD_MESSAGE)
182
+ @output.should_not include(COMPILING_MESSAGE)
183
+ end
184
+
185
+ it "builds the runtime if downloading fails" do
186
+ # Yes, we're testing the entire build system here.
187
+ command = "passenger start " +
188
+ "--runtime-dir '#{@runtime_dir}' " +
189
+ "--binaries-url-root '#{@base_url}/wrong'"
190
+ @output = capture_output("#{command} --runtime-check-only")
191
+ @output.should include(SUPPORT_BINARIES_DOWNLOAD_MESSAGE)
192
+ @output.should include(NGINX_BINARY_DOWNLOAD_MESSAGE)
193
+ @output.should include(NGINX_SOURCE_DOWNLOAD_MESSAGE)
194
+ @output.should include(COMPILING_MESSAGE)
195
+
196
+ test_serving_application(command)
197
+ end
198
+
199
+ it "starts a server which serves the application" do
200
+ # The last test already tests this. This empty test here
201
+ # is merely to show the intent of the tests, and to
202
+ # speed up the test suite by preventing an unnecessary
203
+ # compilation.
204
+ end
205
+ end
206
+
207
+ context "when natively packaged" do
208
+ before :each do
209
+ sh "passenger-config --make-locations-ini > '#{@runtime_dir}/locations.ini'"
210
+ ENV['PASSENGER_LOCATION_CONFIGURATION_FILE'] = "#{@runtime_dir}/locations.ini"
211
+ create_file("#{PhusionPassenger.lib_dir}/nginx")
212
+ end
213
+
214
+ after :each do
215
+ ENV.delete('PASSENGER_LOCATION_CONFIGURATION_FILE')
216
+ File.unlink("#{PhusionPassenger.lib_dir}/nginx")
217
+ end
218
+
219
+ it "downloads only the Nginx binary from the Internet" do
220
+ File.rename("#{@webroot}/#{version}/nginx-#{nginx_version}-#{compat_id}.tar.gz",
221
+ "#{@webroot}/#{version}/nginx-0.0.1-#{compat_id}.tar.gz")
222
+ @output = capture_output("passenger start " +
223
+ "--runtime-dir '#{@runtime_dir}' " +
224
+ "--runtime-check-only " +
225
+ "--binaries-url-root '#{@base_url}' " +
226
+ "--nginx-version 0.0.1")
227
+ @output.should_not include(SUPPORT_BINARIES_DOWNLOAD_MESSAGE)
228
+ @output.should include(NGINX_BINARY_DOWNLOAD_MESSAGE)
229
+ @output.should_not include(NGINX_SOURCE_DOWNLOAD_MESSAGE)
230
+ @output.should_not include(COMPILING_MESSAGE)
231
+ end
232
+
233
+ it "only builds Nginx if downloading fails" do
234
+ # Yes, we're testing the build system here.
235
+ command = "passenger start " +
236
+ "--runtime-dir '#{@runtime_dir}' " +
237
+ "--binaries-url-root '#{@base_url}' " +
238
+ "--nginx-version 1.4.1"
239
+ @output = capture_output("#{command} --runtime-check-only")
240
+ @output.should_not include(SUPPORT_BINARIES_DOWNLOAD_MESSAGE)
241
+ @output.should include(NGINX_BINARY_DOWNLOAD_MESSAGE)
242
+ @output.should include(NGINX_SOURCE_DOWNLOAD_MESSAGE)
243
+ @output.should include(COMPILING_MESSAGE)
244
+
245
+ test_serving_application(command)
246
+ end
247
+
248
+ it "starts a server which serves the application" do
249
+ # The last test already tests this. This empty test here
250
+ # is merely to show the intent of the tests, and to
251
+ # speed up the test suite by preventing an unnecessary
252
+ # compilation.
253
+ end
254
+ end
255
+ end
256
+
257
+ context "if the runtime is installed" do
258
+ it "doesn't download the runtime from the Internet"
259
+ it "doesn't build the runtime"
260
+ end
261
+
262
+ it "daemonizes if -d is given" do
263
+ # Earlier tests already test this. This empty test here
264
+ # is merely to show the intent of the tests, and to
265
+ # speed up the test suite by preventing an unnecessary
266
+ # compilation.
267
+ end
268
+ end
269
+
270
+ describe "help command" do
271
+ it "displays the available commands" do
272
+ capture_output("passenger help").should include("Available commands:")
273
+ end
274
+ end
275
+ end
@@ -57,7 +57,7 @@ describe AdminTools::ServerInstance do
57
57
  describe ".list" do
58
58
  before :each do
59
59
  AdminTools.should_receive(:tmpdir).and_return(passenger_tmpdir)
60
- AdminTools::ServerInstance.stub!(:current_time).
60
+ AdminTools::ServerInstance.stub(:current_time).
61
61
  and_return(Time.now + AdminTools::ServerInstance::STALE_TIME_THRESHOLD + 1)
62
62
  end
63
63
 
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'ruby/shared/loader_sharedspec'
3
+ require 'ruby/shared/rails/analytics_logging_extensions_sharedspec'
4
+
5
+ if RUBY_VERSION_INT >= 190
6
+ module PhusionPassenger
7
+
8
+ describe "Rack loader with Rails 4.0" do
9
+ include LoaderSpecHelper
10
+
11
+ before :each do
12
+ @stub = register_stub(RackStub.new("rails4.0"))
13
+ end
14
+
15
+ def start(options = {})
16
+ @loader = Loader.new(["ruby", "#{PhusionPassenger.helper_scripts_dir}/rack-loader.rb"], @stub.app_root)
17
+ return @loader.start(options)
18
+ end
19
+
20
+ def rails_version
21
+ return "4.0"
22
+ end
23
+
24
+ include_examples "analytics logging extensions for Rails"
25
+ end
26
+
27
+ end # module PhusionPassenger
28
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'ruby/shared/loader_sharedspec'
3
+ require 'ruby/shared/rails/analytics_logging_extensions_sharedspec'
4
+
5
+ if RUBY_VERSION_INT >= 190
6
+ module PhusionPassenger
7
+
8
+ describe "Rack loader with Rails 4.0" do
9
+ include LoaderSpecHelper
10
+
11
+ before :each do
12
+ @stub = register_stub(RackStub.new("rails4.0"))
13
+ end
14
+
15
+ def start(options = {})
16
+ @preloader = Preloader.new(["ruby", "#{PhusionPassenger.helper_scripts_dir}/rack-preloader.rb"], @stub.app_root)
17
+ result = @preloader.start(options)
18
+ if result[:status] == "Ready"
19
+ @loader = @preloader.spawn(options)
20
+ return @loader.start(options)
21
+ else
22
+ return result
23
+ end
24
+ end
25
+
26
+ def rails_version
27
+ return "4.0"
28
+ end
29
+
30
+ include_examples "analytics logging extensions for Rails"
31
+ end
32
+
33
+ end # module PhusionPassenger
34
+ end
@@ -2,6 +2,8 @@ if GC.respond_to?(:copy_on_write_friendly?) && !GC.copy_on_write_friendly?
2
2
  GC.copy_on_write_friendly = true
3
3
  end
4
4
 
5
+ RUBY_VERSION_INT = RUBY_VERSION.split('.')[0..2].join.to_i
6
+
5
7
  source_root = File.expand_path(File.dirname(__FILE__) + "/../..")
6
8
  Dir.chdir("#{source_root}/test")
7
9
 
@@ -26,7 +28,9 @@ def boolean_option(name, default_value = false)
26
28
  end
27
29
 
28
30
  DEBUG = boolean_option('DEBUG')
29
- TEST_CLASSIC_RAILS = boolean_option('TEST_CLASSIC_RAILS', true)
31
+ TEST_CLASSIC_RAILS = boolean_option('TEST_CLASSIC_RAILS', Gem::VERSION <= '1.9')
32
+
33
+ ENV.delete('PASSENGER_DEBUG')
30
34
 
31
35
  $LOAD_PATH.unshift("#{source_root}/lib")
32
36
  $LOAD_PATH.unshift("#{source_root}/test")
@@ -0,0 +1,399 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'phusion_passenger/standalone/runtime_installer'
3
+ require 'tmpdir'
4
+ require 'fileutils'
5
+ require 'stringio'
6
+
7
+ module PhusionPassenger
8
+ module Standalone
9
+
10
+ describe RuntimeInstaller do
11
+ before :each do
12
+ @temp_dir = Dir.mktmpdir
13
+ Dir.mkdir("#{@temp_dir}/support")
14
+ Dir.mkdir("#{@temp_dir}/nginx")
15
+ @logs = StringIO.new
16
+ PhusionPassenger.stub(:installed_from_release_package?).and_return(true)
17
+ end
18
+
19
+ after :each do
20
+ FileUtils.remove_entry_secure(@temp_dir)
21
+ end
22
+
23
+ let(:binaries_url_root) { "http://somewhere" }
24
+ let(:version) { PhusionPassenger::VERSION_STRING }
25
+ let(:nginx_version) { PhusionPassenger::PREFERRED_NGINX_VERSION }
26
+ let(:cxx_compat_id) { PlatformInfo.cxx_binary_compatibility_id }
27
+ let(:support_binaries_url) { "#{binaries_url_root}/#{version}/support-#{cxx_compat_id}.tar.gz" }
28
+ let(:nginx_binary_url) { "#{binaries_url_root}/#{version}/nginx-#{nginx_version}-#{cxx_compat_id}.tar.gz" }
29
+ let(:nginx_source_url) { "http://nginx.org/download/nginx-#{nginx_version}.tar.gz" }
30
+
31
+ def create_installer(options = {})
32
+ options = {
33
+ :binaries_url_root => binaries_url_root,
34
+ :stdout => @logs,
35
+ :stderr => @logs
36
+ }.merge(options)
37
+ @installer = RuntimeInstaller.new(options)
38
+ end
39
+
40
+ def create_tarball(filename, contents = nil)
41
+ Dir.mktmpdir("tarball-", @temp_dir) do |tarball_dir|
42
+ Dir.chdir(tarball_dir) do
43
+ if block_given?
44
+ yield
45
+ else
46
+ contents.each do |content_name|
47
+ File.open(content_name, "w").close
48
+ end
49
+ end
50
+ sh "tar", "-czf", filename, "."
51
+ end
52
+ end
53
+ end
54
+
55
+ def create_dummy_support_binaries
56
+ Dir.mkdir("agents")
57
+ ["PassengerWatchdog", "PassengerHelperAgent", "PassengerLoggingAgent"].each do |exe|
58
+ File.open("agents/#{exe}", "w") do |f|
59
+ f.puts "#!/bin/bash"
60
+ f.puts "echo PASS"
61
+ end
62
+ File.chmod(0755, "agents/#{exe}")
63
+ end
64
+ end
65
+
66
+ def create_dummy_nginx_binary
67
+ File.open("nginx", "w") do |f|
68
+ f.puts "#!/bin/bash"
69
+ f.puts "echo nginx version: 1.0.0"
70
+ end
71
+ File.chmod(0755, "nginx")
72
+ end
73
+
74
+ def create_dummy_nginx_source
75
+ Dir.mkdir("nginx-#{nginx_version}")
76
+ File.open("nginx-#{nginx_version}/configure", "w") do |f|
77
+ f.puts %Q{echo "$@" > '#{@temp_dir}/configure.txt'}
78
+ end
79
+ File.chmod(0700, "nginx-#{nginx_version}/configure")
80
+ File.open("nginx-#{nginx_version}/Makefile", "w") do |f|
81
+ f.puts("all:")
82
+ f.puts(" mkdir objs")
83
+ f.puts(" echo ok > objs/nginx")
84
+ end
85
+ end
86
+
87
+ def create_file(filename)
88
+ File.open(filename, "w").close
89
+ end
90
+
91
+ def sh(*command)
92
+ if !system(*command)
93
+ raise "Command failed: #{command.join(' ')}"
94
+ end
95
+ end
96
+
97
+ def test_download_nginx_binary
98
+ create_installer(:targets => [:nginx],
99
+ :nginx_dir => "#{@temp_dir}/nginx",
100
+ :lib_dir => PhusionPassenger.lib_dir)
101
+
102
+ @installer.should_receive(:download).
103
+ and_return do |url, output, options|
104
+ url.should == nginx_binary_url
105
+ options[:use_cache].should be_true
106
+ create_tarball(output) do
107
+ create_dummy_nginx_binary
108
+ end
109
+ true
110
+ end
111
+
112
+ @installer.should_receive(:check_for_download_tool)
113
+ @installer.should_not_receive(:check_depdendencies)
114
+ @installer.should_not_receive(:compile_support_binaries)
115
+ @installer.should_not_receive(:download_and_extract_nginx_sources)
116
+ @installer.should_not_receive(:compile_nginx)
117
+ @installer.run
118
+
119
+ File.exist?("#{@temp_dir}/nginx/nginx").should be_true
120
+ end
121
+
122
+ def test_building_nginx_binary
123
+ create_installer(:targets => [:nginx],
124
+ :nginx_dir => "#{@temp_dir}/nginx",
125
+ :lib_dir => PhusionPassenger.lib_dir)
126
+
127
+ @installer.should_receive(:download).twice.and_return do |url, output|
128
+ if url == nginx_binary_url
129
+ false
130
+ elsif url == nginx_source_url
131
+ create_tarball(output) do
132
+ create_dummy_nginx_source
133
+ end
134
+ true
135
+ else
136
+ raise "Unexpected download URL: #{url}"
137
+ end
138
+ end
139
+
140
+ @installer.should_receive(:check_for_download_tool)
141
+ @installer.should_receive(:check_dependencies).and_return(true)
142
+ @installer.should_not_receive(:compile_support_binaries)
143
+ @installer.should_receive(:strip_binary).
144
+ with(an_instance_of(String)).
145
+ and_return(true)
146
+ @installer.run
147
+
148
+ File.read("#{@temp_dir}/nginx/nginx").should == "ok\n"
149
+ File.read("#{@temp_dir}/configure.txt").should include(
150
+ "--add-module=#{PhusionPassenger.nginx_module_source_dir}")
151
+ end
152
+
153
+ context "when originally packaged" do
154
+ before :each do
155
+ PhusionPassenger.stub(:originally_packaged?).and_return(true)
156
+ PhusionPassenger.stub(:natively_packaged?).and_return(false)
157
+ end
158
+
159
+ it "downloads the support binaries from the Internet if :support_binaries is specified as target" do
160
+ create_installer(:targets => [:support_binaries],
161
+ :support_dir => "#{@temp_dir}/support")
162
+
163
+ @installer.should_receive(:download).
164
+ and_return do |url, output, options|
165
+ url.should == "#{binaries_url_root}/#{version}/support-#{cxx_compat_id}.tar.gz"
166
+ options[:use_cache].should be_true
167
+ create_tarball(output) do
168
+ create_dummy_support_binaries
169
+ end
170
+ true
171
+ end
172
+
173
+ @installer.should_receive(:check_for_download_tool)
174
+ @installer.should_not_receive(:check_depdendencies)
175
+ @installer.should_not_receive(:compile_support_binaries)
176
+ @installer.should_not_receive(:download_and_extract_nginx_sources)
177
+ @installer.should_not_receive(:compile_nginx)
178
+ @installer.run
179
+
180
+ File.exist?("#{@temp_dir}/support/agents/PassengerWatchdog").should be_true
181
+ end
182
+
183
+ it "downloads the Nginx binary from the Internet if :nginx is specified as target" do
184
+ test_download_nginx_binary
185
+ end
186
+
187
+ it "downloads everything if :support_binaries and :nginx are both specified as target" do
188
+ create_installer(:targets => [:support_binaries, :nginx],
189
+ :support_dir => "#{@temp_dir}/support",
190
+ :nginx_dir => "#{@temp_dir}/nginx",
191
+ :lib_dir => PhusionPassenger.lib_dir)
192
+
193
+ @installer.should_receive(:download).
194
+ twice.
195
+ and_return do |url, output, options|
196
+ if url == support_binaries_url
197
+ create_tarball(output) do
198
+ create_dummy_support_binaries
199
+ end
200
+ elsif url == nginx_binary_url
201
+ create_tarball(output) do
202
+ create_dummy_nginx_binary
203
+ end
204
+ else
205
+ raise "Unexpected download URL: #{url}"
206
+ end
207
+ options[:use_cache].should be_true
208
+ true
209
+ end
210
+
211
+ @installer.should_receive(:check_for_download_tool)
212
+ @installer.should_not_receive(:check_depdendencies)
213
+ @installer.should_not_receive(:compile_support_binaries)
214
+ @installer.should_not_receive(:download_and_extract_nginx_sources)
215
+ @installer.should_not_receive(:compile_nginx)
216
+ @installer.run
217
+
218
+ File.exist?("#{@temp_dir}/support/agents/PassengerWatchdog").should be_true
219
+ File.exist?("#{@temp_dir}/nginx/nginx").should be_true
220
+ end
221
+
222
+ it "builds the support binaries if it cannot be downloaded" do
223
+ create_installer(:targets => [:support_binaries],
224
+ :support_dir => "#{@temp_dir}/support")
225
+ nginx_libs = COMMON_LIBRARY.
226
+ only(*NGINX_LIBS_SELECTOR).
227
+ set_output_dir("#{@temp_dir}/support/libpassenger_common").
228
+ link_objects
229
+ built_files = nil
230
+
231
+ @installer.should_receive(:run_rake_task!).with(
232
+ "nginx_without_native_support CACHING=false OUTPUT_DIR='#{@temp_dir}/support'").
233
+ and_return do
234
+ FileUtils.mkdir_p("#{@temp_dir}/agents")
235
+ create_file("#{@temp_dir}/agents/PassengerWatchdog")
236
+
237
+ nginx_libs.each do |object_filename|
238
+ dir = File.dirname(object_filename)
239
+ FileUtils.mkdir_p(dir)
240
+ create_file(object_filename)
241
+ end
242
+
243
+ built_files = `find '#{@temp_dir}/support'`
244
+ end
245
+
246
+ @installer.should_receive(:check_for_download_tool)
247
+ @installer.should_receive(:download).and_return(false)
248
+ @installer.should_receive(:check_dependencies).and_return(true)
249
+ @installer.should_not_receive(:download_and_extract_nginx_sources)
250
+ @installer.should_not_receive(:compile_nginx)
251
+ @installer.run
252
+ `find '#{@temp_dir}/support'`.should == built_files
253
+ end
254
+
255
+ it "builds the Nginx binary if it cannot be downloaded" do
256
+ test_building_nginx_binary
257
+ end
258
+
259
+ it "aborts if the support binaries cannot be built" do
260
+ create_installer(:targets => [:support_binaries],
261
+ :support_dir => "#{@temp_dir}/support")
262
+
263
+ @installer.should_receive(:run_rake_task!).with(
264
+ "nginx_without_native_support CACHING=false OUTPUT_DIR='#{@temp_dir}/support'").
265
+ and_raise(RuntimeError, "Rake failed")
266
+
267
+ @installer.should_receive(:check_for_download_tool)
268
+ @installer.should_receive(:download).and_return(false)
269
+ @installer.should_receive(:check_dependencies).and_return(true)
270
+ @installer.should_not_receive(:download_and_extract_nginx_sources)
271
+ @installer.should_not_receive(:compile_nginx)
272
+ lambda { @installer.run }.should raise_error("Rake failed")
273
+ end
274
+ end
275
+
276
+ context "when natively packaged" do
277
+ before :each do
278
+ PhusionPassenger.stub(:source_root).and_return("/locations.ini")
279
+ PhusionPassenger.stub(:originally_packaged?).and_return(false)
280
+ PhusionPassenger.stub(:natively_packaged?).and_return(true)
281
+ end
282
+
283
+ it "refuses to accept :support_binaries as target" do
284
+ block = lambda do
285
+ create_installer(:targets => [:support_binaries],
286
+ :support_dir => "#{@temp_dir}/support")
287
+ end
288
+ block.should raise_error(ArgumentError, /You cannot specify :support_binaries/)
289
+ end
290
+
291
+ it "downloads the Nginx binary from the Internet if :nginx is specified as target" do
292
+ test_download_nginx_binary
293
+ end
294
+
295
+ it "builds the Nginx binary if it cannot be downloaded" do
296
+ test_building_nginx_binary
297
+ end
298
+ end
299
+
300
+ it "commits downloaded binaries after checking whether they're usable" do
301
+ create_installer(:targets => [:support_binaries, :nginx],
302
+ :support_dir => "#{@temp_dir}/support",
303
+ :nginx_dir => "#{@temp_dir}/nginx",
304
+ :lib_dir => PhusionPassenger.lib_dir)
305
+
306
+ @installer.should_receive(:download).
307
+ exactly(3).times.
308
+ and_return do |url, output, options|
309
+ if url == support_binaries_url
310
+ options[:use_cache].should be_true
311
+ create_tarball(output) do
312
+ create_dummy_support_binaries
313
+ end
314
+ elsif url == nginx_binary_url
315
+ options[:use_cache].should be_true
316
+ create_tarball(output) do
317
+ create_dummy_nginx_binary
318
+ end
319
+ elsif url == nginx_source_url
320
+ create_tarball(output) do
321
+ create_dummy_nginx_source
322
+ end
323
+ else
324
+ raise "Unexpected download URL: #{url}"
325
+ end
326
+ true
327
+ end
328
+
329
+ @installer.should_receive(:check_for_download_tool)
330
+ @installer.should_receive(:check_support_binaries).and_return(false)
331
+ @installer.should_receive(:check_nginx_binary).and_return(false)
332
+ @installer.should_receive(:check_dependencies).and_return(true)
333
+ @installer.should_receive(:compile_support_binaries)
334
+ @installer.should_receive(:compile_nginx)
335
+ @installer.run
336
+
337
+ Dir["#{@temp_dir}/nginx/*"].should be_empty
338
+ Dir["#{@temp_dir}/support/*"].should be_empty
339
+ end
340
+
341
+ it "aborts if the Nginx source tarball cannot be extracted" do
342
+ create_installer(:targets => [:nginx],
343
+ :nginx_dir => "#{@temp_dir}/nginx",
344
+ :lib_dir => PhusionPassenger.lib_dir)
345
+
346
+ @installer.should_receive(:download).twice.and_return do |url, output, options|
347
+ if url == nginx_binary_url
348
+ false
349
+ elsif url == nginx_source_url
350
+ File.open(output, "w") do |f|
351
+ f.write("garbage")
352
+ end
353
+ true
354
+ else
355
+ raise "Unexpected download URL: #{url}"
356
+ end
357
+ end
358
+
359
+ @installer.should_receive(:check_for_download_tool)
360
+ @installer.should_receive(:check_dependencies).and_return(true)
361
+ @installer.should_not_receive(:compile_support_binaries)
362
+ lambda { @installer.run }.should raise_error(SystemExit)
363
+ @logs.string.should =~ %r{Unable to download or extract Nginx source tarball}
364
+ end
365
+
366
+ it "aborts if the Nginx binary cannot be built" do
367
+ create_installer(:targets => [:nginx],
368
+ :nginx_dir => "#{@temp_dir}/nginx",
369
+ :lib_dir => PhusionPassenger.lib_dir)
370
+
371
+ @installer.should_receive(:download).twice.and_return do |url, output, options|
372
+ if url == nginx_binary_url
373
+ false
374
+ elsif url == nginx_source_url
375
+ create_tarball(output) do
376
+ Dir.mkdir("nginx-#{nginx_version}")
377
+ File.open("nginx-#{nginx_version}/configure", "w") do |f|
378
+ f.puts("#!/bin/bash")
379
+ f.puts("echo error")
380
+ f.puts("exit 1")
381
+ end
382
+ File.chmod(0700, "nginx-#{nginx_version}/configure")
383
+ end
384
+ true
385
+ else
386
+ raise "Unexpected download URL: #{url}"
387
+ end
388
+ end
389
+
390
+ @installer.should_receive(:check_for_download_tool)
391
+ @installer.should_receive(:check_dependencies).and_return(true)
392
+ @installer.should_not_receive(:compile_support_binaries)
393
+ lambda { @installer.run }.should raise_error(SystemExit)
394
+ @logs.string.should =~ %r{command failed:.*./configure}
395
+ end
396
+ end
397
+
398
+ end # module Standalone
399
+ end # module PhusionPassenger