Permalink
Browse files

Get rid of passenger-stress-test.

  • Loading branch information...
1 parent b55822e commit 51bf6665a33228f1c27f660d89d1a3a18374fc75 @FooBarWidget FooBarWidget committed Nov 18, 2010
Showing with 5 additions and 347 deletions.
  1. +4 −0 NEWS
  2. +0 −345 bin/passenger-stress-test
  3. +1 −2 lib/phusion_passenger/packaging.rb
View
4 NEWS
@@ -26,6 +26,10 @@ Release 3.0.1
This is the command that people can run after donating. It allows people
to slightly modify Phusion Passenger's display name as a joke. In 3.0.0 it
was broken because of a typo. This has been fixed.
+ * Removed passenger-stress-test
+ This tool was used during the early life of Phusion Passenger for stress
+ testing websites. Its performance has never been very good and there are
+ much better tools for stress testing, so this tool has now been removed.
* [Apache] RailsEnv and RackEnv configuration options are now equivalent
In previous versions, RailsEnv only had effect on Rails 1 and Rails 2 apps
while RackEnv only had effect on Rack apps. Because Rails 3 apps are
View
@@ -1,345 +0,0 @@
-#!/usr/bin/env ruby
-# Phusion Passenger - http://www.modrails.com/
-# Copyright (c) 2010 Phusion
-#
-# "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-source_root = File.expand_path(File.dirname(__FILE__) + "/..")
-$LOAD_PATH.unshift("#{source_root}/lib")
-require 'phusion_passenger'
-require 'rubygems'
-require 'optparse'
-require 'socket'
-require 'thread'
-require 'phusion_passenger/platform_info'
-require 'phusion_passenger/message_channel'
-require 'phusion_passenger/utils'
-
-include PhusionPassenger
-include PhusionPassenger::Utils
-include PhusionPassenger::PlatformInfo
-
-# A thread or a process, depending on the Ruby VM implementation.
-class Subprocess
- attr_accessor :channel
-
- def initialize(name, &block)
- if RUBY_PLATFORM == "java"
- a, b = UNIXSocket.pair
- @thread = Thread.new do
- block.call(true, MessageChannel.new(b))
- end
- @channel = MessageChannel.new(a)
- @thread_channel = b
- else
- a, b = UNIXSocket.pair
- @pid = safe_fork(name) do
- a.close
- $0 = name
- Process.setsid
- block.call(false, MessageChannel.new(b))
- end
- b.close
- @channel = MessageChannel.new(a)
- end
- end
-
- def stop
- if RUBY_PLATFORM == "java"
- @thread.terminate
- @channel.close
- @thread_channel.close
- else
- Process.kill('SIGKILL', @pid) rescue nil
- Process.waitpid(@pid) rescue nil
- @channel.close
- end
- end
-end
-
-class StressTester
- def start
- @options = parse_options
- load_hawler
-
- Thread.abort_on_exception = true
- if GC.respond_to?(:copy_on_write_friendly=)
- GC.copy_on_write_friendly = true
- end
- @terminal_height = ENV['LINES'] ? ENV['LINES'].to_i : 24
- @terminal_width = ENV['COLUMNS'] ? ENV['COLUMNS'].to_i : 80
-
- if Process.euid != 0
- puts "*** WARNING: This program might not be able to restart " <<
- "Apache because it's not running as root. Please run " <<
- "this tool as root."
- puts
- puts "Press Enter to continue..."
- begin
- STDIN.readline
- rescue Interrupt
- exit 1
- end
- end
-
- run_crawlers
- end
-
- def parse_options
- options = {
- :concurrency => 20,
- :depth => 20,
- :nice => true,
- :apache_restart_interval => 24 * 60,
- :app_restart_interval => 55
- }
- parser = OptionParser.new do |opts|
- opts.banner = "Usage: passenger-stress-test <hostname> <app_root> [options]\n\n" <<
- "Stress test the given (Passenger-powered) website by:\n" <<
- " * crawling it with multiple concurrently running crawlers.\n" <<
- " * gracefully restarting Apache at random times (please point the 'APXS2'\n" <<
- " variable to your Apache's 'apxs' binary).\n" <<
- " * restarting the target (Passenger-powered) application at random time.\n" <<
- "\n" <<
- "Example:\n" <<
- " passenger-stress-test mywebsite.com /webapps/mywebsite\n" <<
- "\n"
-
- opts.separator "Options:"
- opts.on("-c", "--concurrency N", Integer,
- "Number of crawlers to start (default = #{options[:concurrency]})") do |v|
- options[:concurrency] = v
- end
- opts.on("-p", "--apache-restart-interval N", Integer,
- "Gracefully restart Apache after N minutes\n" <<
- (" " * 37) << "(default = #{options[:apache_restart_interval]})") do |v|
- options[:apache_restart_interval] = v
- end
- opts.on("-a", "--app-restart-interval N", Integer,
- "Restart the application after N minutes\n" <<
- (" " * 37) << "(default = #{options[:app_restart_interval]})") do |v|
- options[:app_restart_interval] = v
- end
- opts.on("-h", "--help", "Show this message") do
- puts opts
- exit
- end
- end
- parser.parse!
-
- options[:host] = ARGV[0]
- options[:app_root] = ARGV[1]
- if !options[:host] || !options[:app_root]
- puts parser
- exit 1
- end
- return options
- end
-
- def load_hawler
- begin
- require 'hawler'
- rescue LoadError
- STDERR.puts "This tool requires Hawler (http://tinyurl.com/ywgk6x). Please install it with:"
- STDERR.puts
- STDERR.puts " gem install --source http://spoofed.org/files/hawler/ hawler"
- exit 1
- end
- end
-
- def run_crawlers
- @started = false
- @crawlers = []
-
- # Start crawler processes.
- GC.start if GC.copy_on_write_friendly?
- @options[:concurrency].times do |i|
- STDOUT.write("Starting crawler #{i + 1} of #{@options[:concurrency]}...\n")
- STDOUT.flush
- process = Subprocess.new("crawler #{i + 1}") do |is_thread, channel|
- if !is_thread && @options[:nice]
- system("renice 1 #{Process.pid} >/dev/null 2>/dev/null")
- end
- while true
- crawl!(i + 1, channel)
- end
- end
- @crawlers << {
- :id => i + 1,
- :process => process,
- :channel => process.channel,
- :mutex => Mutex.new,
- :current_uri => nil,
- :crawled => 0
- }
- end
-
- puts
- if RUBY_PLATFORM != "java"
- # 'sleep' b0rks when running in JRuby?
- sleep 1
- end
- begin
- $0 = "Passenger Crawler: control process"
- io_to_crawler = {}
- ios = []
- @crawlers.each do |crawler|
- io_to_crawler[crawler[:channel].io] = crawler
- ios << crawler[:channel].io
- end
-
- # Tell each crawler to start crawling.
- @crawlers.each do |crawler|
- crawler[:channel].write("start")
- end
-
- # Show progress periodically.
- @start_time = Time.now
- progress_reporter = Thread.new(&method(:report_progress))
- @next_apache_restart = Time.now + @options[:apache_restart_interval] * 60
- apache_restarter = Thread.new(&method(:restart_apache))
- @next_app_restart = Time.now + @options[:app_restart_interval] * 60
- app_restarter = Thread.new(&method(:restart_app))
-
- while true
- note_progress(ios, io_to_crawler)
- end
- rescue Interrupt
- trap('SIGINT') {}
- puts "Shutting down..."
- @done = true
- @crawlers.each do |crawler|
- STDOUT.write("Stopping crawler #{crawler[:id]} of #{@options[:concurrency]}...\r")
- STDOUT.flush
- crawler[:process].stop
- end
- progress_reporter.join if progress_reporter
- apache_restarter.join if apache_restarter
- app_restarter.join if app_restarter
- puts
- end
- end
-
- def note_progress(ios, io_to_crawler)
- select(ios)[0].each do |io|
- crawler = io_to_crawler[io]
- uri = crawler[:channel].read[0]
- crawler[:mutex].synchronize do
- crawler[:current_uri] = uri
- crawler[:crawled] += 1
- end
- end
- end
-
- def report_progress
- while !@done
- output = "\n" * @terminal_height
- output << "### Running for #{duration(Time.now.to_i - @start_time.to_i)}\n"
- @crawlers.each do |crawler|
- crawler[:mutex].synchronize do
- line = sprintf("Crawler %-2d: %-3d -> %s",
- crawler[:id],
- crawler[:crawled],
- crawler[:current_uri])
- output << sprintf("%-#{@terminal_width}s\n", line)
- end
- end
- output << "Next Apache restart: in #{duration(@next_apache_restart.to_i - Time.now.to_i)}\n"
- output << "Next app restart : in #{duration(@next_app_restart.to_i - Time.now.to_i)}\n"
- STDOUT.write(output)
- sleep 0.5
- end
- end
-
- def restart_apache
- while !@done
- if Time.now > @next_apache_restart
- @next_apache_restart = Time.now + @options[:apache_restart_interval] * 60
- system("#{HTTPD} -k graceful")
- end
- end
- end
-
- def restart_app
- while !@done
- if Time.now > @next_app_restart
- @next_app_restart = Time.now + @options[:app_restart_interval] * 60
- system("touch #{@options[:app_root]}/tmp/restart.txt")
- end
- end
- end
-
- def duration(seconds)
- result = ""
- if seconds >= 60
- minutes = (seconds / 60)
- if minutes >= 60
- hours = minutes / 60
- minutes = minutes % 60
- if hours == 1
- result << "#{hours} hour "
- else
- result << "#{hours} hours "
- end
- end
-
- seconds = seconds % 60
- if minutes == 1
- result << "#{minutes} minute "
- else
- result << "#{minutes} minutes "
- end
- end
- result << "#{seconds} seconds"
- return result
- end
-
- def crawl!(id, channel)
- progress_reporter = lambda do |uri, referer, response|
- begin
- if !@started
- # At the beginning, wait until the control process
- # tells us to start.
- @started = true
- channel.read
- end
- channel.write(uri, referer, response)
- rescue
- if RUBY_PLATFORM == "java"
- Thread.current.terminate
- else
- Process.kill('SIGKILL', Process.pid)
- end
- end
- end
- crawler = Hawler.new(@options[:host], progress_reporter)
- if RUBY_PLATFORM == "java"
- trap('SIGINT') do
- raise Interrupt, "Interrupted"
- end
- end
- crawler.recurse = true
- crawler.depth = @options[:depth]
- crawler.start
- end
-end
-
-StressTester.new.start
@@ -37,8 +37,7 @@ module Packaging
'passenger',
'passenger-install-apache2-module',
'passenger-install-nginx-module',
- 'passenger-config',
- 'passenger-stress-test'
+ 'passenger-config'
]
SUPER_USER_EXECUTABLES = [

0 comments on commit 51bf666

Please sign in to comment.