Permalink
Browse files

Stripped out built-in daemonizing support in favour of providing an o…

…ption to disable forking

(which is redundant if you're going to daemonize) and handling signals correctly, with an 
example mimic daemon script provided.
  • Loading branch information...
1 parent 89af201 commit 1613a1d3828fe0530b0f1964787438f89d4a6366 Luke Redpath committed Jan 13, 2011
View
@@ -0,0 +1,11 @@
+#!/usr/bin/env ruby
+lib_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
+$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
+
+require 'mimic'
+
+Daemons.run_proc("mimic") do
+ Mimic.mimic(:fork => false, :remote_configuration_path => "/api") do
+ get("/ping") { "pong\n" }
+ end
+end
@@ -4,7 +4,7 @@ Feature: Configuring Mimic via an HTTP interface
I want to be able to configure a background Mimic process using an HTTP REST API
Scenario: Stubbing a request path via GET using the HTTP API
- Given that Mimic is daemonized and accepting remote configuration on "/api"
+ Given that Mimic is running and accepting remote configuration on "/api"
When I make an HTTP POST request to "http://localhost:11988/api/get" with the payload:
"""
{"path": "/anything"}
@@ -14,7 +14,7 @@ Feature: Configuring Mimic via an HTTP interface
Then I should receive an HTTP 200 response with an empty body
Scenario: Stubbing a request path via POST the HTTP API for a
- Given that Mimic is daemonized and accepting remote configuration on "/api"
+ Given that Mimic is running and accepting remote configuration on "/api"
When I make an HTTP POST request to "http://localhost:11988/api/post" with the payload:
"""
{"path": "/anything"}
@@ -24,7 +24,7 @@ Feature: Configuring Mimic via an HTTP interface
Then I should receive an HTTP 200 response with an empty body
Scenario: Stubbing a request path via PUT using the HTTP API
- Given that Mimic is daemonized and accepting remote configuration on "/api"
+ Given that Mimic is running and accepting remote configuration on "/api"
When I make an HTTP POST request to "http://localhost:11988/api/put" with the payload:
"""
{"path": "/anything"}
@@ -34,7 +34,7 @@ Feature: Configuring Mimic via an HTTP interface
Then I should receive an HTTP 200 response with an empty body
Scenario: Stubbing a request path via DELETE the HTTP API for a
- Given that Mimic is daemonized and accepting remote configuration on "/api"
+ Given that Mimic is running and accepting remote configuration on "/api"
When I make an HTTP POST request to "http://localhost:11988/api/delete" with the payload:
"""
{"path": "/anything"}
@@ -44,7 +44,7 @@ Feature: Configuring Mimic via an HTTP interface
Then I should receive an HTTP 200 response with an empty body
Scenario: Stubbing a request path via HEAD using the HTTP API
- Given that Mimic is daemonized and accepting remote configuration on "/api"
+ Given that Mimic is running and accepting remote configuration on "/api"
When I make an HTTP POST request to "http://localhost:11988/api/head" with the payload:
"""
{"path": "/anything"}
@@ -54,7 +54,7 @@ Feature: Configuring Mimic via an HTTP interface
Then I should receive an HTTP 200 response with an empty body
Scenario: Stubbing a request path to return a custom response body
- Given that Mimic is daemonized and accepting remote configuration on "/api"
+ Given that Mimic is running and accepting remote configuration on "/api"
When I make an HTTP POST request to "http://localhost:11988/api/get" with the payload:
"""
{"path": "/anything", "body": "Hello World"}
@@ -64,7 +64,7 @@ Feature: Configuring Mimic via an HTTP interface
Then I should receive an HTTP 200 response with a body matching "Hello World"
Scenario: Stubbing a request path to return a custom status code
- Given that Mimic is daemonized and accepting remote configuration on "/api"
+ Given that Mimic is running and accepting remote configuration on "/api"
When I make an HTTP POST request to "http://localhost:11988/api/get" with the payload:
"""
{"path": "/anything", "code": 301}
@@ -74,7 +74,7 @@ Feature: Configuring Mimic via an HTTP interface
Then I should receive an HTTP 301 response with an empty body
Scenario: Stubbing a request path to return custom headers
- Given that Mimic is daemonized and accepting remote configuration on "/api"
+ Given that Mimic is running and accepting remote configuration on "/api"
When I make an HTTP POST request to "http://localhost:11988/api/get" with the payload:
"""
{"path": "/anything", "headers": {"X-TEST-HEADER": "TESTING"}}
@@ -84,7 +84,7 @@ Feature: Configuring Mimic via an HTTP interface
Then I should receive an HTTP 200 response with the value "TESTING" for the header "X-TEST-HEADER"
Scenario: Stubbing a request using the HTTP API in plist format
- Given that Mimic is daemonized and accepting remote configuration on "/api"
+ Given that Mimic is running and accepting remote configuration on "/api"
When I make an HTTP POST request with a "application/plist" content-type to "http://localhost:11988/api/get" and the payload:
"""
<?xml version="1.0" encoding="UTF-8"?>
@@ -101,7 +101,7 @@ Feature: Configuring Mimic via an HTTP interface
Then I should receive an HTTP 200 response with an empty body
Scenario: Configuring multiple stubs for a single verb in a single request
- Given that Mimic is daemonized and accepting remote configuration on "/api"
+ Given that Mimic is running and accepting remote configuration on "/api"
When I make an HTTP POST request to "http://localhost:11988/api/get" with the payload:
"""
{"stubs":[{"path": "/anything"}, {"path": "/something"}]}
@@ -113,7 +113,7 @@ Feature: Configuring Mimic via an HTTP interface
Then I should receive an HTTP 200 response with an empty body
Scenario: Configuring multiple stubs for different verbs in a single request
- Given that Mimic is daemonized and accepting remote configuration on "/api"
+ Given that Mimic is running and accepting remote configuration on "/api"
When I make an HTTP POST request to "http://localhost:11988/api/multi" with the payload:
"""
{"stubs":[{"method": "GET", "path": "/anything"}, {"method": "POST", "path": "/something"}]}
@@ -1,35 +0,0 @@
-Feature: Running Mimic as a daemon
- In order to use Mimic out of process
- As a developer
- I want to be able to start Mimic as a background daemon
-
- Scenario: Starting Mimic in the background with no pre-configured stubs
- Given I execute the script:
- """
- Mimic.daemonize({:port => 11988}, :ARGV => ['run'])
- """
- When I make an HTTP GET request to "http://localhost:11988/anything"
- Then I should receive an HTTP 404 response with an empty body
-
- Scenario: Starting Mimic in the background with pre-configured stubs
- Given I execute the script:
- """
- Mimic.daemonize({:port => 11988}, :ARGV => ['run']) do
- get("/preconfigured").returning("test response")
- end
- """
- When I make an HTTP GET request to "http://localhost:11988/preconfigured"
- Then I should receive an HTTP 200 response with a body matching "test response"
-
- Scenario: Starting Mimic in the background with pre-configured stubs in a file
- Given the file "/tmp/test_stubs.rb" exists with the contents:
- """
- get("/stub_one").returning("test response")
- """
- When I execute the script:
- """
- Mimic.daemonize({:port => 11988, :stub_file => "/tmp/test_stubs.rb"}, :ARGV => ['run'])
- """
- And I make an HTTP GET request to "http://localhost:11988/stub_one"
- Then I should receive an HTTP 200 response with a body matching "test response"
-
@@ -2,8 +2,8 @@
MimicRunner.new.evaluate(string)
end
-Given /^that Mimic is daemonized and accepting remote configuration on "([^\"]*)"$/ do |api_endpoint|
- Mimic.daemonize({:port => 11988, :remote_configuration_path => api_endpoint}, :ARGV => ['run'])
+Given /^that Mimic is running and accepting remote configuration on "([^\"]*)"$/ do |api_endpoint|
+ Mimic.mimic(:port => 11988, :remote_configuration_path => api_endpoint)
end
After do
View
@@ -8,35 +8,27 @@ module Mimic
MIMIC_DEFAULT_PORT = 11988
MIMIC_DEFAULT_OPTIONS = {
- :hostname => 'localhost',
+ :hostname => 'localhost',
:port => MIMIC_DEFAULT_PORT,
:remote_configuration_path => nil,
- :stub_file => nil
+ :stub_file => nil,
+ :fork => true
}
-
+
def self.mimic(options = {}, &block)
options = MIMIC_DEFAULT_OPTIONS.merge(options)
-
+
FakeHost.new(options[:hostname], options[:remote_configuration_path]).tap do |host|
host.instance_eval(&block) if block_given?
if options[:stub_file]
host.evaluate_file(options[:stub_file])
end
- Server.instance.serve(host, options[:port])
+ Server.instance.serve(host, options[:port], options[:fork])
end
end
-
- def self.daemonize(options = {}, daemon_options = {}, &block)
- @daemon = Daemons.run_proc('mimic', daemon_options) { mimic(options, &block) }
- end
-
+
def self.cleanup!
Mimic::Server.instance.shutdown
-
- if @daemon
- @daemon.zap_all
- @daemon = nil
- end
end
class Server
@@ -46,28 +38,40 @@ def logger
@logger ||= Logger.new(StringIO.new)
end
- def serve(host_app, port)
- @thread = Thread.fork do
- Rack::Handler::WEBrick.run(host_app.url_map,
- :Port => port,
- :Logger => logger,
- :AccessLog => logger
-
- ) { |server| @server = server }
+ def serve(host_app, port, should_fork)
+ if should_fork
+ @thread = Thread.fork do
+ start_service(host_app, port)
+ end
+
+ wait_for_service(host_app.hostname, port)
+
+ else
+ start_service(host_app, port)
end
-
- wait_for_service(host_app.hostname, port)
end
-
- def shutdown
- if @thread
- Thread.kill(@thread)
- @server.shutdown
+
+ def start_service(host_app, port)
+ Rack::Handler::WEBrick.run(host_app.url_map, {
+ :Port => port,
+ :Logger => logger,
+ :AccessLog => logger,
+
+ }) do |server|
+ @server = server
+
+ trap("TERM") { @server.shutdown }
+ trap("INT") { @server.shutdown }
end
end
-
+
+ def shutdown
+ Thread.kill(@thread) if @thread
+ @server.shutdown if @server
+ end
+
# courtesy of http://is.gd/eoYho
-
+
def listening?(host, port)
begin
socket = TCPSocket.new(host, port)

0 comments on commit 1613a1d

Please sign in to comment.