realweb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 geemus (Wesley Beary)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,24 @@
1
+ = RealWeb
2
+
3
+ Boot a rack app in a thread or process to use as a real test endpoint.
4
+
5
+ === Usage
6
+
7
+ before(:each) do
8
+ @server = RealWeb.start_server("path/to/config.ru")
9
+ end
10
+
11
+ after(:each) do
12
+ @server.stop
13
+ end
14
+
15
+ it "runs some action that would normally hit the api" do
16
+ MyLibrary.get_list_of_things(@server.base_uri)
17
+ end
18
+
19
+
20
+ RealWeb.start_server boots the given config.ru in a thread. When you call stop on the server object, the server is killed.
21
+
22
+ You can specifically use a Process.fork server with start_server_in_fork.
23
+
24
+ RealWeb uses WEBrick for its pure ruby server. No extra dependencies or C extensions.
data/lib/realweb.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'realweb/in_thread_server'
2
+ require 'realweb/forking_server'
3
+
4
+ module RealWeb
5
+ class << self
6
+ def start_server_in_thread(*args)
7
+ InThreadServer.new(*args) { |server| server.start }
8
+ end
9
+ alias start_server start_server_in_thread
10
+
11
+ def start_server_in_fork(*args)
12
+ ForkingServer.new(*args) { |server| server.start }
13
+ end
14
+
15
+ def with_server_in_thread(*args, &block)
16
+ InThreadServer.with_rackup(*args, &block)
17
+ end
18
+ alias with_server with_server_in_thread
19
+
20
+ def with_server_in_fork(*args, &block)
21
+ ForkingServer.with_rackup(*args, &block)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,32 @@
1
+ require 'realweb/server'
2
+
3
+ module RealWeb
4
+ class ForkingServer < Server
5
+
6
+ def stop
7
+ kill_pid
8
+ super
9
+ end
10
+
11
+ protected
12
+
13
+ def kill_pid
14
+ return unless @pid
15
+ Process.kill 'INT', @pid
16
+ Process.kill 'TERM', @pid
17
+ Process.wait @pid
18
+ rescue
19
+ # noop
20
+ ensure
21
+ @pid = nil
22
+ end
23
+
24
+ def spawn_server
25
+ @pid ||= Process.fork do
26
+ boot_rack_server do |webrick_server|
27
+ trap(:TERM) { webrick_server.shutdown; exit!(0) }
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ require 'realweb/server'
2
+
3
+ module RealWeb
4
+ class InThreadServer < Server
5
+
6
+ def stop
7
+ @thread[:kill_server].call
8
+ @thread.kill
9
+ super
10
+ end
11
+
12
+ protected
13
+
14
+ def spawn_server
15
+ @thread ||= Thread.new do
16
+ boot_rack_server do |webrick_server|
17
+ Thread.current[:kill_server] = lambda { webrick_server.shutdown }
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,109 @@
1
+ require 'rack'
2
+ require 'webrick'
3
+ require 'stringio'
4
+ require 'logger'
5
+ require 'open-uri'
6
+
7
+ module RealWeb
8
+ class Server
9
+ DEFAULT_PORT_RANGE = 8000..10000
10
+
11
+ def self.with_rackup(*args)
12
+ new(*args) do |server|
13
+ server.start
14
+ yield server if block_given?
15
+ server.stop
16
+ end
17
+ end
18
+
19
+ attr_reader :port
20
+
21
+ def initialize(config_ru, pre_spawn_callback = nil, port_range = DEFAULT_PORT_RANGE)
22
+ @config_ru, @pre_spawn_callback, @port_range = config_ru, pre_spawn_callback, port_range
23
+ @running = false
24
+ yield self if block_given?
25
+ end
26
+
27
+ def running?
28
+ @running
29
+ end
30
+
31
+ def start
32
+ return if running?
33
+ find_port
34
+ run_pre_spawn
35
+ spawn_server
36
+ at_exit { stop }
37
+ wait_for_server
38
+ @running = true
39
+ end
40
+
41
+ def stop
42
+ @running = false
43
+ end
44
+
45
+ def host
46
+ "127.0.0.1"
47
+ end
48
+
49
+ def base_uri
50
+ URI.parse("http://#{host}:#{@port}/")
51
+ end
52
+
53
+ protected
54
+
55
+ def find_port
56
+ return if @port
57
+ begin
58
+ @port = random_port
59
+ end while system("lsof -i tcp:#{@port} > /dev/null")
60
+ end
61
+
62
+ def random_port
63
+ @port_range.to_a[rand(@port_range.to_a.size)]
64
+ end
65
+
66
+ def run_pre_spawn
67
+ @pre_spawn_callback.call(self) if @pre_spawn_callback
68
+ end
69
+
70
+ def spawn_server
71
+ raise "Not implemented"
72
+ end
73
+
74
+ # hack around Rack::Server not yielding the real server
75
+ def boot_rack_server(&block)
76
+ begin
77
+ rack_server = Rack::Server.new(
78
+ :Port => @port,
79
+ :config => @config_ru,
80
+ :server => 'webrick',
81
+ :Logger => Logger.new(StringIO.new), # quiet webrick
82
+ :AccessLog => [ StringIO.new, WEBrick::AccessLog::COMMON_LOG_FORMAT ]
83
+ )
84
+ webrick_handler = rack_server.server
85
+ wrapped_app = rack_server.send(:wrapped_app)
86
+ webrick_handler.run(wrapped_app, rack_server.options, &block)
87
+ rescue
88
+ $stderr.puts "Failed to start server"
89
+ $stderr.puts $!.inspect
90
+ $stderr.puts $!.backtrace
91
+ abort
92
+ end
93
+ end
94
+
95
+ def wait_for_server
96
+ 10.times do
97
+ begin
98
+ sleep 0.5
99
+ open(base_uri)
100
+ return
101
+ rescue Errno::ECONNREFUSED
102
+ puts "Connection refused; retrying..."
103
+ sleep 0.5
104
+ end
105
+ end
106
+ abort "Unable to reach RealWeb server: Problem booting #{@config_ru}"
107
+ end
108
+ end
109
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: realweb
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Ben Burkert
14
+ - Martin Emde
15
+ - Sam Merritt
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+
20
+ date: 2010-05-28 00:00:00 -07:00
21
+ default_executable:
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
24
+ prerelease: false
25
+ version_requirements: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ hash: 19
31
+ segments:
32
+ - 1
33
+ - 1
34
+ - 0
35
+ version: 1.1.0
36
+ requirement: *id001
37
+ type: :runtime
38
+ name: rack
39
+ description: Easily runs a rack app for tests that hit web APIs
40
+ email: cloud-engineering@engineyard.com
41
+ executables: []
42
+
43
+ extensions: []
44
+
45
+ extra_rdoc_files:
46
+ - README.rdoc
47
+ - LICENSE
48
+ files:
49
+ - lib/realweb/forking_server.rb
50
+ - lib/realweb/in_thread_server.rb
51
+ - lib/realweb/server.rb
52
+ - lib/realweb.rb
53
+ - README.rdoc
54
+ - LICENSE
55
+ has_rdoc: true
56
+ homepage: http://github.com/engineyard/realweb
57
+ licenses: []
58
+
59
+ post_install_message:
60
+ rdoc_options: []
61
+
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ hash: 3
70
+ segments:
71
+ - 0
72
+ version: "0"
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ hash: 3
79
+ segments:
80
+ - 0
81
+ version: "0"
82
+ requirements: []
83
+
84
+ rubyforge_project:
85
+ rubygems_version: 1.3.7
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Easily runs a rack app for tests that hit web APIs
89
+ test_files: []
90
+