mirage 2.4.2 → 3.0.0.alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.simplecov +6 -0
- data/Gemfile +11 -3
- data/Gemfile.lock +41 -14
- data/VERSION +1 -1
- data/features/client/clear.feature +41 -50
- data/features/client/configure.feature +2 -2
- data/features/client/put.feature +17 -6
- data/features/client/requests.feature +5 -9
- data/features/client/start.feature +19 -11
- data/features/client/stop.feature +10 -44
- data/features/server/commandline_interface/start.feature +2 -14
- data/features/server/commandline_interface/stop.feature +6 -4
- data/features/server/logging.feature +2 -2
- data/features/server/prime.feature +11 -66
- data/features/server/requests/delete.feature +34 -33
- data/features/server/requests/get.feature +21 -18
- data/features/server/save_and_revert.feature +24 -11
- data/features/server/templates/delete.feature +29 -32
- data/features/server/templates/get.feature +44 -25
- data/features/server/templates/put/put.feature +55 -78
- data/features/server/templates/put/put_with_substitutions.feature +12 -32
- data/features/server/templates/put/required_content.feature +118 -0
- data/features/step_definitions/my_steps.rb +51 -6
- data/features/support/env.rb +1 -1
- data/features/support/hooks.rb +2 -5
- data/{lib/mirage/client → features/support}/web.rb +14 -3
- data/lib/mirage/client.rb +5 -2
- data/lib/mirage/client/client.rb +22 -129
- data/lib/mirage/client/request.rb +25 -0
- data/lib/mirage/client/requests.rb +13 -0
- data/lib/mirage/client/runner.rb +4 -4
- data/lib/mirage/client/template.rb +108 -0
- data/lib/mirage/client/template_configuration.rb +22 -0
- data/lib/mirage/client/templates.rb +26 -0
- data/mirage.gemspec +42 -22
- data/mirage_server.rb +1 -135
- data/rakefile +22 -7
- data/server/app.rb +4 -0
- data/server/binary_data_checker.rb +15 -0
- data/server/helpers.rb +28 -0
- data/server/mock_response.rb +140 -58
- data/server/server.rb +167 -0
- data/spec/{cli_bridge_spec.rb → client/cli_bridge_spec.rb} +15 -11
- data/spec/client/client_spec.rb +139 -0
- data/spec/client/request_spec.rb +52 -0
- data/spec/client/requests_spec.rb +10 -0
- data/spec/{runner_spec.rb → client/runner_spec.rb} +3 -3
- data/spec/client/template_configuration_spec.rb +32 -0
- data/spec/client/template_spec.rb +241 -0
- data/spec/client/templates_spec.rb +79 -0
- data/spec/resources/binary.file +0 -0
- data/spec/server/binary_data_checker_spec.rb +22 -0
- data/spec/server/helpers_spec.rb +34 -0
- data/spec/server/mock_response_spec.rb +526 -0
- data/spec/server/server_spec.rb +132 -0
- data/spec/spec_helper.rb +61 -2
- data/test.html +12 -0
- data/test.rb +20 -17
- data/todo.lst +2 -0
- data/views/index.haml +22 -0
- data/views/response.haml +24 -0
- metadata +134 -49
- data/features/server/templates/put/put_as_default.feature +0 -42
- data/features/server/templates/put/put_with_delay.feature +0 -8
- data/features/server/templates/put/put_with_pattern.feature +0 -80
- data/lib/mirage/client/response.rb +0 -29
- data/spec/client_spec.rb +0 -38
- data/views/index.erb +0 -28
data/server/server.rb
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'helpers'
|
3
|
+
require 'base64'
|
4
|
+
module Mirage
|
5
|
+
|
6
|
+
class Server < Sinatra::Base
|
7
|
+
|
8
|
+
REQUESTS = {}
|
9
|
+
|
10
|
+
|
11
|
+
helpers Mirage::Server::Helpers
|
12
|
+
|
13
|
+
put '/mirage/templates/*' do |name|
|
14
|
+
content_type :json
|
15
|
+
mock_response = MockResponse.new(name, JSON.parse(request.body.read))
|
16
|
+
mock_response.requests_url = request.url.gsub("/mirage/templates/#{name}", "/mirage/requests/#{mock_response.response_id}")
|
17
|
+
{:id => mock_response.response_id}.to_json
|
18
|
+
end
|
19
|
+
|
20
|
+
%w(get post delete put).each do |http_method|
|
21
|
+
send(http_method, '/mirage/responses/*') do |name|
|
22
|
+
body, query_string = Rack::Utils.unescape(request.body.read.to_s), request.query_string
|
23
|
+
|
24
|
+
options = {:body => body,
|
25
|
+
:http_method => http_method,
|
26
|
+
:endpoint => name,
|
27
|
+
:params => request.params,
|
28
|
+
:headers => extract_http_headers(env)}
|
29
|
+
begin
|
30
|
+
record = MockResponse.find(options)
|
31
|
+
rescue ServerResponseNotFound
|
32
|
+
record = MockResponse.find_default(options)
|
33
|
+
end
|
34
|
+
|
35
|
+
REQUESTS[record.response_id] = request.dup
|
36
|
+
|
37
|
+
send_response(record, body, request, query_string)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
delete '/mirage/templates/:id' do
|
42
|
+
MockResponse.delete(response_id)
|
43
|
+
REQUESTS.delete(response_id)
|
44
|
+
200
|
45
|
+
end
|
46
|
+
|
47
|
+
delete '/mirage/requests' do
|
48
|
+
REQUESTS.clear
|
49
|
+
200
|
50
|
+
end
|
51
|
+
|
52
|
+
delete '/mirage/requests/:id' do
|
53
|
+
REQUESTS.delete(response_id)
|
54
|
+
200
|
55
|
+
end
|
56
|
+
|
57
|
+
delete '/mirage/templates' do
|
58
|
+
REQUESTS.clear
|
59
|
+
MockResponse.delete_all
|
60
|
+
200
|
61
|
+
end
|
62
|
+
|
63
|
+
get '/mirage/templates/:id' do
|
64
|
+
MockResponse.find_by_id(response_id).raw
|
65
|
+
end
|
66
|
+
|
67
|
+
get '/mirage/requests/:id' do
|
68
|
+
content_type :json
|
69
|
+
tracked_request = REQUESTS[response_id]
|
70
|
+
if tracked_request
|
71
|
+
|
72
|
+
tracked_request.body.rewind
|
73
|
+
body = tracked_request.body.read
|
74
|
+
|
75
|
+
parameters = tracked_request.params.dup.select{|key, value| key != body}
|
76
|
+
|
77
|
+
{ request_url: request.url,
|
78
|
+
headers: extract_http_headers(tracked_request.env),
|
79
|
+
parameters: parameters,
|
80
|
+
body: body}.to_json
|
81
|
+
|
82
|
+
else
|
83
|
+
404
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
get '/mirage' do
|
88
|
+
haml :index
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
put '/mirage/defaults' do
|
93
|
+
MockResponse.delete_all
|
94
|
+
if File.directory?(settings.defaults.to_s)
|
95
|
+
Dir["#{settings.defaults}/**/*.rb"].each do |default|
|
96
|
+
begin
|
97
|
+
eval File.read(default)
|
98
|
+
rescue Exception => e
|
99
|
+
raise "Unable to load default responses from: #{default}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
200
|
104
|
+
end
|
105
|
+
#
|
106
|
+
put '/mirage/backup' do
|
107
|
+
MockResponse.backup
|
108
|
+
200
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
put '/mirage' do
|
113
|
+
MockResponse.revert
|
114
|
+
200
|
115
|
+
end
|
116
|
+
|
117
|
+
get '/mirage/pid' do
|
118
|
+
"#{$$}"
|
119
|
+
end
|
120
|
+
|
121
|
+
error ServerResponseNotFound do
|
122
|
+
404
|
123
|
+
end
|
124
|
+
|
125
|
+
error do
|
126
|
+
erb request.env['sinatra.error'].message
|
127
|
+
end
|
128
|
+
|
129
|
+
helpers do
|
130
|
+
|
131
|
+
def response_id
|
132
|
+
params[:id].to_i
|
133
|
+
end
|
134
|
+
|
135
|
+
def prime &block
|
136
|
+
block.call Mirage::Client.new "http://localhost:#{settings.port}/mirage"
|
137
|
+
end
|
138
|
+
|
139
|
+
def send_response(response, body='', request={}, query_string='')
|
140
|
+
sleep response.response_spec['delay']
|
141
|
+
content_type(response.response_spec['content_type'])
|
142
|
+
status response.response_spec['status']
|
143
|
+
response.value(body, request, query_string)
|
144
|
+
end
|
145
|
+
|
146
|
+
def extract_http_headers(env)
|
147
|
+
headers = env.reject do |k, v|
|
148
|
+
!(/^HTTP_[A-Z_]+$/ === k) || v.nil?
|
149
|
+
end.map do |k, v|
|
150
|
+
[reconstruct_header_name(k), v]
|
151
|
+
end.inject(Rack::Utils::HeaderHash.new) do |hash, k_v|
|
152
|
+
k, v = k_v
|
153
|
+
hash[k] = v
|
154
|
+
hash
|
155
|
+
end
|
156
|
+
|
157
|
+
x_forwarded_for = (headers["X-Forwarded-For"].to_s.split(/, +/) << env["REMOTE_ADDR"]).join(", ")
|
158
|
+
|
159
|
+
headers.merge!("X-Forwarded-For" => x_forwarded_for)
|
160
|
+
end
|
161
|
+
|
162
|
+
def reconstruct_header_name(name)
|
163
|
+
name.sub(/^HTTP_/, "").gsub("_", "-")
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -3,7 +3,11 @@ require 'mirage/client'
|
|
3
3
|
|
4
4
|
describe Mirage::CLIBridge do
|
5
5
|
|
6
|
-
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
@bridge = Object.new
|
9
|
+
@bridge.extend(Mirage::CLIBridge)
|
10
|
+
end
|
7
11
|
|
8
12
|
describe 'Windows' do
|
9
13
|
|
@@ -15,8 +19,8 @@ describe Mirage::CLIBridge do
|
|
15
19
|
#{process_string_for_mirage(7002, 18904)}
|
16
20
|
#{process_string_for_mirage(7003, 18905)}"
|
17
21
|
|
18
|
-
|
19
|
-
mirage_process_ids([7001, 7002]).should == {"7001" => "18903", "7002" => "18904"}
|
22
|
+
@bridge.should_receive(:`).with(/tasklist.*/).any_number_of_times.and_return(tasklist_output)
|
23
|
+
@bridge.mirage_process_ids([7001, 7002]).should == {"7001" => "18903", "7002" => "18904"}
|
20
24
|
end
|
21
25
|
|
22
26
|
it 'should find the pids of mirage instances for all ports' do
|
@@ -24,13 +28,13 @@ describe Mirage::CLIBridge do
|
|
24
28
|
#{process_string_for_mirage(7002, 18904)}
|
25
29
|
#{process_string_for_mirage(7003, 18905)}"
|
26
30
|
|
27
|
-
|
28
|
-
mirage_process_ids([:all]).should == {"7001" => "18903", "7002" => "18904", "7003" => "18905"}
|
31
|
+
@bridge.should_receive(:`).with(/tasklist.*/).any_number_of_times.and_return(tasklist_output)
|
32
|
+
@bridge.mirage_process_ids([:all]).should == {"7001" => "18903", "7002" => "18904", "7003" => "18905"}
|
29
33
|
end
|
30
34
|
|
31
35
|
it 'should kill the given process id' do
|
32
|
-
|
33
|
-
kill(18903)
|
36
|
+
@bridge.should_receive(:`).with(/taskkill \/F \/T \/PID 18903/)
|
37
|
+
@bridge.kill(18903)
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
@@ -44,7 +48,7 @@ describe Mirage::CLIBridge do
|
|
44
48
|
#{process_string_for_mirage(7003, 18905)}"
|
45
49
|
|
46
50
|
IO.should_receive(:popen).with(/ps aux.*/).any_number_of_times.and_return(ps_aux_output)
|
47
|
-
mirage_process_ids([7001, 7002]).should == {"7001" => "18903", "7002" => "18904"}
|
51
|
+
@bridge.mirage_process_ids([7001, 7002]).should == {"7001" => "18903", "7002" => "18904"}
|
48
52
|
end
|
49
53
|
|
50
54
|
it 'should find the pids of mirage instances for all ports' do
|
@@ -53,12 +57,12 @@ describe Mirage::CLIBridge do
|
|
53
57
|
#{process_string_for_mirage(7003, 18905)}"
|
54
58
|
|
55
59
|
IO.should_receive(:popen).with(/ps aux.*/).any_number_of_times.and_return(ps_aux_output)
|
56
|
-
mirage_process_ids([:all]).should == {"7001" => "18903", "7002" => "18904", "7003" => "18905"}
|
60
|
+
@bridge.mirage_process_ids([:all]).should == {"7001" => "18903", "7002" => "18904", "7003" => "18905"}
|
57
61
|
end
|
58
62
|
|
59
63
|
it 'should kill the given process id' do
|
60
|
-
|
61
|
-
kill(18903)
|
64
|
+
@bridge.should_receive(:`).with(/kill -9 18903/)
|
65
|
+
@bridge.kill(18903)
|
62
66
|
end
|
63
67
|
end
|
64
68
|
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'mirage/client'
|
3
|
+
|
4
|
+
describe Mirage::Client do
|
5
|
+
Client = Mirage::Client
|
6
|
+
Templates = Mirage::Templates
|
7
|
+
Template = Mirage::Template
|
8
|
+
Requests = Mirage::Requests
|
9
|
+
Request = Mirage::Request
|
10
|
+
|
11
|
+
before :each do
|
12
|
+
@response = mock('response').as_null_object
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'configuration' do
|
16
|
+
it 'is configured to connect to local host port 7001 by default' do
|
17
|
+
Client.new.url.should == "http://localhost:7001/mirage"
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'can be configured with a url pointing to Mirage' do
|
21
|
+
mirage_url = "http://url.for.mirage"
|
22
|
+
Client.new(mirage_url).url.should == mirage_url
|
23
|
+
|
24
|
+
Client.new(:url => mirage_url).url.should == mirage_url
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'can be configured with a port refering to which port Mirage is running on on localhost' do
|
28
|
+
port = 9001
|
29
|
+
Client.new(:port => port).url.should == "http://localhost:#{port}/mirage"
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'raises an error if neither a port or url specified in the argument' do
|
33
|
+
expect { Client.new({}) }.to raise_error()
|
34
|
+
expect { Client.new("rubbish") }.to raise_error()
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should clear mirage' do
|
39
|
+
templates_mock = mock('templates')
|
40
|
+
Templates.should_receive(:new).and_return(templates_mock)
|
41
|
+
templates_mock.should_receive(:delete_all)
|
42
|
+
Client.new.clear
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
it 'should prime mirage' do
|
49
|
+
Client.should_receive(:put) do |url|
|
50
|
+
url.should == "http://localhost:7001/mirage/defaults"
|
51
|
+
end
|
52
|
+
Client.new.prime
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'templates' do
|
56
|
+
it 'should give access to templates' do
|
57
|
+
mirage = Client.new
|
58
|
+
mirage.templates.instance_of?(Templates).should == true
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should find a template' do
|
62
|
+
id = 1
|
63
|
+
mirage = Client.new
|
64
|
+
mock_template = mock('template')
|
65
|
+
Template.should_receive(:get).with("#{mirage.url}/templates/#{id}").and_return(mock_template)
|
66
|
+
mirage.templates(1).should == mock_template
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should put a response on mirage' do
|
70
|
+
endpoint, value, block = 'greeting', 'hello', Proc.new{}
|
71
|
+
|
72
|
+
templates_mock = mock('templates')
|
73
|
+
Templates.should_receive(:new).and_return(templates_mock)
|
74
|
+
|
75
|
+
templates_mock.should_receive(:put).with(endpoint, value, &block)
|
76
|
+
|
77
|
+
mirage = Client.new
|
78
|
+
mirage.put endpoint, value, &block
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'requests' do
|
83
|
+
it 'should give access to requests' do
|
84
|
+
mirage = Client.new
|
85
|
+
mirage.requests.instance_of?(Requests).should == true
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should find a request' do
|
89
|
+
id = 1
|
90
|
+
mirage = Client.new
|
91
|
+
Request.should_receive(:get).with("#{mirage.url}/requests/#{id}")
|
92
|
+
mirage.requests(id)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
#describe 'stop' do
|
97
|
+
#
|
98
|
+
#end
|
99
|
+
|
100
|
+
describe 'save' do
|
101
|
+
it 'should save the current template setup of mirage' do
|
102
|
+
mirage = Client.new
|
103
|
+
Client.should_receive(:put).with("#{mirage.url}/backup", :body => "")
|
104
|
+
mirage.save
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe 'revert' do
|
109
|
+
it 'should revert the current template set' do
|
110
|
+
mirage = Client.new
|
111
|
+
Client.should_receive(:put).with(mirage.url, :body => "")
|
112
|
+
mirage.revert
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
describe 'interface to mirage' do
|
118
|
+
|
119
|
+
after :each do
|
120
|
+
Mirage.stop
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'should set a response' do
|
124
|
+
client = Mirage.start
|
125
|
+
response = client.templates.put("greeting", "hello")
|
126
|
+
response.id.should == 1
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should find mirage running' do
|
130
|
+
Mirage.start
|
131
|
+
Mirage.running?.should == true
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should not find mirage running' do
|
135
|
+
Mirage.running?.should == false
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'mirage/client'
|
3
|
+
|
4
|
+
|
5
|
+
describe Mirage::Request do
|
6
|
+
Request = Mirage::Request
|
7
|
+
|
8
|
+
it 'delete a request' do
|
9
|
+
request_url = "url"
|
10
|
+
Request.should_receive(:delete).with(request_url)
|
11
|
+
request = Request.new
|
12
|
+
request.request_url = request_url
|
13
|
+
request.delete
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should load request data' do
|
17
|
+
request_url = "url"
|
18
|
+
trigger_url = "trigger url"
|
19
|
+
|
20
|
+
body = "body"
|
21
|
+
parameters = {"name" => "joe"}
|
22
|
+
headers = {"header" => "value"}
|
23
|
+
|
24
|
+
request_json = {
|
25
|
+
body: body,
|
26
|
+
headers: headers,
|
27
|
+
parameters: parameters,
|
28
|
+
request_url: trigger_url
|
29
|
+
}
|
30
|
+
|
31
|
+
Request.should_receive(:backedup_get).with(request_url,format: :json).and_return(request_json)
|
32
|
+
|
33
|
+
request = Request.get(request_url)
|
34
|
+
request.headers.should == headers
|
35
|
+
request.body.should == body
|
36
|
+
request.request_url.should == trigger_url
|
37
|
+
request.parameters.should == parameters
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should contain parameters' do
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should contain the request body' do
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should contain the triggering url' do
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'mirage/client'
|
3
|
+
|
4
|
+
describe 'Requests' do
|
5
|
+
it 'should delete all request data' do
|
6
|
+
base_url = "base_url"
|
7
|
+
Mirage::Requests.should_receive(:delete).with("#{base_url}/requests")
|
8
|
+
Mirage::Requests.new(base_url).delete_all
|
9
|
+
end
|
10
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'mirage/client'
|
3
3
|
|
4
|
-
include Mirage
|
5
4
|
|
6
5
|
describe Mirage do
|
6
|
+
Runner = Mirage::Runner
|
7
7
|
|
8
8
|
describe 'starting' do
|
9
9
|
before(:each) do
|
@@ -72,7 +72,7 @@ describe Mirage do
|
|
72
72
|
runner.should_not_receive(:kill)
|
73
73
|
Mirage::Runner.should_receive(:new).and_return(runner)
|
74
74
|
|
75
|
-
|
75
|
+
expect { runner.invoke(:stop, [], options) }.to raise_error(Mirage::ClientError)
|
76
76
|
end
|
77
77
|
|
78
78
|
|
@@ -131,7 +131,7 @@ describe Mirage do
|
|
131
131
|
runner.should_receive(:mirage_process_ids).with([7001]).any_number_of_times.and_return({})
|
132
132
|
|
133
133
|
Mirage::Runner.should_receive(:new).and_return(runner)
|
134
|
-
|
134
|
+
expect { runner.invoke(:stop, [], options) }.to_not raise_error(Mirage::ClientError)
|
135
135
|
end
|
136
136
|
|
137
137
|
end
|