mirage-on-thin 3.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/.simplecov +6 -0
  5. data/.travis.yml +3 -0
  6. data/Gemfile +29 -0
  7. data/Gemfile.lock +151 -0
  8. data/HISTORY +22 -0
  9. data/README.md +156 -0
  10. data/Rakefile +10 -0
  11. data/VERSION +1 -0
  12. data/bin/mirage +14 -0
  13. data/features/.nav +29 -0
  14. data/features/client/clear.feature +78 -0
  15. data/features/client/configure.feature +72 -0
  16. data/features/client/model.feature +95 -0
  17. data/features/client/preview_responses.feature +33 -0
  18. data/features/client/prime.feature +32 -0
  19. data/features/client/put.feature +111 -0
  20. data/features/client/readme.md +3 -0
  21. data/features/client/requests.feature +20 -0
  22. data/features/client/running.feature +51 -0
  23. data/features/client/save_and_revert.feature +39 -0
  24. data/features/client/start.feature +46 -0
  25. data/features/client/stop.feature +53 -0
  26. data/features/commandline_interface/help.feature +17 -0
  27. data/features/commandline_interface/readme.md +1 -0
  28. data/features/commandline_interface/start.feature +18 -0
  29. data/features/commandline_interface/stop.feature +42 -0
  30. data/features/logging.feature +6 -0
  31. data/features/prime.feature +35 -0
  32. data/features/readme.md +7 -0
  33. data/features/requests/delete.feature +48 -0
  34. data/features/requests/get.feature +36 -0
  35. data/features/save_and_revert.feature +35 -0
  36. data/features/step_definitions/my_steps.rb +98 -0
  37. data/features/step_definitions/observation_steps.rb +103 -0
  38. data/features/support/command_line.rb +33 -0
  39. data/features/support/env.rb +22 -0
  40. data/features/support/hooks.rb +26 -0
  41. data/features/support/mirage.rb +12 -0
  42. data/features/support/web.rb +20 -0
  43. data/features/templates/delete.feature +45 -0
  44. data/features/templates/get.feature +54 -0
  45. data/features/templates/path_wildcards.feature +10 -0
  46. data/features/templates/preview.feature +18 -0
  47. data/features/templates/put.feature +77 -0
  48. data/features/templates/put_with_substitutions.feature +22 -0
  49. data/features/templates/readme.md +4 -0
  50. data/features/templates/required_content.feature +113 -0
  51. data/features/web_user_interface.feature +44 -0
  52. data/full_build.sh +100 -0
  53. data/lib/mirage/client.rb +10 -0
  54. data/lib/mirage/client/cli_bridge.rb +30 -0
  55. data/lib/mirage/client/client.rb +73 -0
  56. data/lib/mirage/client/error.rb +22 -0
  57. data/lib/mirage/client/helpers/method_builder.rb +19 -0
  58. data/lib/mirage/client/request.rb +26 -0
  59. data/lib/mirage/client/requests.rb +13 -0
  60. data/lib/mirage/client/runner.rb +103 -0
  61. data/lib/mirage/client/template.rb +56 -0
  62. data/lib/mirage/client/template/configuration.rb +44 -0
  63. data/lib/mirage/client/template/model.rb +48 -0
  64. data/lib/mirage/client/template/model/common_methods.rb +24 -0
  65. data/lib/mirage/client/template/model/instance_methods.rb +95 -0
  66. data/lib/mirage/client/templates.rb +50 -0
  67. data/mirage-on-thin.gemspec +175 -0
  68. data/mirage_server.rb +35 -0
  69. data/server/app.rb +4 -0
  70. data/server/binary_data_checker.rb +15 -0
  71. data/server/extensions/hash.rb +10 -0
  72. data/server/extensions/object.rb +5 -0
  73. data/server/helpers.rb +3 -0
  74. data/server/helpers/http_headers.rb +31 -0
  75. data/server/helpers/template_requirements.rb +33 -0
  76. data/server/mock_response.rb +242 -0
  77. data/server/server.rb +184 -0
  78. data/spec/client/cli_bridge_spec.rb +63 -0
  79. data/spec/client/client_spec.rb +179 -0
  80. data/spec/client/helpers/method_builder_spec.rb +40 -0
  81. data/spec/client/request_spec.rb +39 -0
  82. data/spec/client/requests_spec.rb +9 -0
  83. data/spec/client/runner_spec.rb +138 -0
  84. data/spec/client/template/configuration_spec.rb +32 -0
  85. data/spec/client/template/model/common_methods_spec.rb +25 -0
  86. data/spec/client/template/model/instance_methods_spec.rb +169 -0
  87. data/spec/client/template/model_spec.rb +119 -0
  88. data/spec/client/template_spec.rb +146 -0
  89. data/spec/client/templates_spec.rb +197 -0
  90. data/spec/resources/binary.file +0 -0
  91. data/spec/server/binary_data_checker_spec.rb +21 -0
  92. data/spec/server/helpers/http_headers_spec.rb +20 -0
  93. data/spec/server/helpers/template_requirements_spec.rb +34 -0
  94. data/spec/server/mock_response_spec.rb +577 -0
  95. data/spec/server/server_spec.rb +156 -0
  96. data/spec/spec_helper.rb +85 -0
  97. data/tasks/application.rake +7 -0
  98. data/tasks/packaging.rake +28 -0
  99. data/tasks/tests.rake +25 -0
  100. data/views/index.haml +16 -0
  101. data/views/response.haml +46 -0
  102. metadata +337 -0
data/server/server.rb ADDED
@@ -0,0 +1,184 @@
1
+ require 'sinatra'
2
+ require 'helpers'
3
+ require 'base64'
4
+ module Mirage
5
+
6
+ class Server < Sinatra::Base
7
+
8
+ REQUESTS = {}
9
+
10
+ helpers Helpers::TemplateRequirements, Helpers::HttpHeaders
11
+
12
+ put '/templates/*' do |name|
13
+ content_type :json
14
+ mock_response = synchronize do
15
+ MockResponse.new(name, JSON.parse(request.body.read))
16
+ end
17
+
18
+ mock_response.requests_url = request.url.gsub("/templates/#{name}", "/requests/#{mock_response.response_id}")
19
+ {:id => mock_response.response_id}.to_json
20
+ end
21
+
22
+ %w(get post delete put).each do |http_method|
23
+ send(http_method, '/responses/*') do |name|
24
+ body, query_string = Rack::Utils.unescape(request.body.read.to_s), request.query_string
25
+
26
+ options = {:body => body,
27
+ :http_method => http_method,
28
+ :endpoint => name,
29
+ :params => request.params,
30
+ :headers => extract_http_headers(env)}
31
+ begin
32
+ record = MockResponse.find(options)
33
+ rescue ServerResponseNotFound
34
+ record = MockResponse.find_default(options)
35
+ end
36
+
37
+ synchronize do
38
+ REQUESTS[record.response_id] = request.dup
39
+ end
40
+
41
+
42
+ send_response(record, body, request, query_string)
43
+ end
44
+ end
45
+
46
+ get '/templates/:id/preview' do
47
+ send_response(MockResponse.find_by_id(response_id), '', {}, '')
48
+ end
49
+
50
+ delete '/templates/:id' do
51
+ synchronize do
52
+ MockResponse.delete(response_id)
53
+ REQUESTS.delete(response_id)
54
+ end
55
+
56
+ 200
57
+ end
58
+
59
+ delete '/requests' do
60
+ synchronize do
61
+ REQUESTS.clear
62
+ end
63
+
64
+ 200
65
+ end
66
+
67
+ delete '/requests/:id' do
68
+ synchronize do
69
+ REQUESTS.delete(response_id)
70
+ end
71
+
72
+ 200
73
+ end
74
+
75
+ delete '/templates' do
76
+ synchronize do
77
+ REQUESTS.clear
78
+ MockResponse.delete_all
79
+ end
80
+
81
+ 200
82
+ end
83
+
84
+ get '/templates/:id' do
85
+ MockResponse.find_by_id(response_id).raw
86
+ end
87
+
88
+ get '/requests/:id' do
89
+ content_type :json
90
+ tracked_request = REQUESTS[response_id]
91
+ if tracked_request
92
+
93
+ tracked_request.body.rewind
94
+ body = tracked_request.body.read
95
+
96
+ parameters = tracked_request.params.dup.select { |key, value| key != body }
97
+
98
+ {id: request.url,
99
+ request_url: tracked_request.url,
100
+ headers: extract_http_headers(tracked_request.env),
101
+ parameters: parameters,
102
+ body: body}.to_json
103
+
104
+ else
105
+ 404
106
+ end
107
+ end
108
+
109
+ get '/' do
110
+ haml :index
111
+ end
112
+
113
+
114
+ put '/defaults' do
115
+ synchronize do
116
+ MockResponse.delete_all
117
+ if File.directory?(settings.defaults.to_s)
118
+ Dir["#{settings.defaults}/**/*.rb"].each do |default|
119
+ begin
120
+ eval File.read(default)
121
+ rescue Exception => e
122
+ raise "Unable to load default responses from: #{default}"
123
+ end
124
+ end
125
+ end
126
+ end
127
+ 200
128
+ end
129
+ #
130
+ put '/backup' do
131
+ synchronize do
132
+ MockResponse.backup
133
+ end
134
+
135
+ 200
136
+ end
137
+
138
+
139
+ put '/' do
140
+ synchronize do
141
+ MockResponse.revert
142
+ end
143
+
144
+ 200
145
+ end
146
+
147
+ get '/pid' do
148
+ "#{$$}"
149
+ end
150
+
151
+ error ServerResponseNotFound do
152
+ 404
153
+ end
154
+
155
+ error do
156
+ erb request.env['sinatra.error'].message
157
+ end
158
+
159
+ helpers do
160
+
161
+ def synchronize &block
162
+ Mutex.new.synchronize &block
163
+ end
164
+
165
+ def response_id
166
+ params[:id].to_i
167
+ end
168
+
169
+ def prime &block
170
+ block.call Mirage::Client.new "http://localhost:#{settings.port}"
171
+ end
172
+
173
+ def send_response(mock_response, body='', request={}, query_string='')
174
+ sleep mock_response.response_spec['delay']
175
+ content_type(mock_response.response_spec['content_type'])
176
+ status mock_response.response_spec['status']
177
+ headers mock_response.headers
178
+ mock_response.value(body, request, query_string)
179
+ end
180
+
181
+
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+ require 'mirage/client'
3
+
4
+ describe CLIBridge do
5
+ def mapping port
6
+ {port.to_s => port_pid_mappings[port.to_s]}
7
+ end
8
+
9
+ let(:port_pid_mappings) do
10
+ {"7001" => "18903", "7002" => "18904", "7003" => "18905"}
11
+ end
12
+
13
+ let(:operating_system) do
14
+ Hashie::Mash.new({
15
+ :windows => {
16
+ :kill_string => "taskkill /F /T /PID %d",
17
+ :set_ps_cmd_expectation => proc{bridge.stub(:`).with(/tasklist.*/).and_return(tasklist_output)}
18
+ },
19
+ :linux => {
20
+ :kill_string => "kill -9 %d",
21
+ :set_ps_cmd_expectation => proc{IO.stub(:popen).with(/ps aux.*/).and_return(tasklist_output)}
22
+ }
23
+ })
24
+ end
25
+
26
+ [:linux,:windows].each do |os_name|
27
+
28
+ describe os_name do
29
+ let(:os){operating_system[os_name]}
30
+ let!(:bridge) do
31
+ bridge = Object.new
32
+ bridge.extend(CLIBridge)
33
+ end
34
+
35
+ include_context os_name do
36
+
37
+ let(:tasklist_output) do
38
+ output = []
39
+ port_pid_mappings.each do |port, pid|
40
+ output << process_string_for_mirage(port, pid)
41
+ end
42
+ output.join("\n")
43
+ end
44
+
45
+ it 'should find the pids of mirage instances for given ports' do
46
+ os.set_ps_cmd_expectation.call
47
+ bridge.mirage_process_ids([7001, 7002]).should == mapping(7001).merge(mapping(7002))
48
+ end
49
+
50
+ it 'should find the pids of mirage instances for all ports' do
51
+ os.set_ps_cmd_expectation.call
52
+ bridge.mirage_process_ids([:all]).should == port_pid_mappings
53
+ end
54
+
55
+ it 'should kill the given process id' do
56
+ bridge.should_receive(:`).with(os.kill_string % 18903)
57
+ bridge.kill(18903)
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ end
@@ -0,0 +1,179 @@
1
+ require 'spec_helper'
2
+ require 'mirage/client'
3
+
4
+ describe Mirage::Client do
5
+
6
+
7
+ before :each do
8
+ @response = double('response').as_null_object
9
+ end
10
+
11
+ describe 'configuration' do
12
+ it 'is configured to connect to local host port 7001 by default' do
13
+ Client.new.url.should == "http://localhost:7001"
14
+ end
15
+
16
+ it 'can be configured with a url pointing to Mirage' do
17
+ mirage_url = "http://url.for.mirage"
18
+ Client.new(mirage_url).url.should == mirage_url
19
+
20
+ Client.new(:url => mirage_url).url.should == mirage_url
21
+ end
22
+
23
+ it 'can be configured with a port refering to which port Mirage is running on on localhost' do
24
+ port = 9001
25
+ Client.new(:port => port).url.should == "http://localhost:#{port}"
26
+ end
27
+
28
+ it 'raises an error if neither a port or url specified in the argument' do
29
+ expect { Client.new({}) }.to raise_error()
30
+ expect { Client.new("rubbish") }.to raise_error()
31
+ end
32
+
33
+
34
+ describe 'defaults' do
35
+ it 'can be configured with template defaults on initialize' do
36
+ templates, config = Templates.new("url"), proc {}
37
+ Templates.should_receive(:new).and_return(templates)
38
+ templates.should_receive(:default_config) do |&block|
39
+ block.should == config
40
+ end
41
+ Client.new &config
42
+ end
43
+
44
+ it 'can be configured with template defaults on after initalize' do
45
+ templates, config = Templates.new("url"), proc {}
46
+ Templates.should_receive(:new).and_return(templates)
47
+ templates.should_receive(:default_config) do |&block|
48
+ block.should == config
49
+ end
50
+ Client.new.configure &config
51
+ end
52
+
53
+ it 'can be reset' do
54
+ client = Client.new do
55
+ http_method :post
56
+ end
57
+
58
+ client.reset
59
+ client.templates.default_config.should == Template::Configuration.new
60
+ end
61
+
62
+ end
63
+ end
64
+
65
+ it 'should clear mirage' do
66
+ templates_mock = double('templates')
67
+ Templates.should_receive(:new).and_return(templates_mock)
68
+ templates_mock.should_receive(:delete_all)
69
+ Client.new.clear
70
+ end
71
+
72
+
73
+
74
+
75
+ it 'should prime mirage' do
76
+ Client.should_receive(:put) do |url|
77
+ url.should == "http://localhost:7001/defaults"
78
+ end
79
+ Client.new.prime
80
+ end
81
+
82
+ describe 'templates' do
83
+ it 'should give access to templates' do
84
+ mirage = Client.new
85
+ mirage.templates.instance_of?(Templates).should == true
86
+ end
87
+
88
+ it 'The templates instance should be the one created on construction otherwise the defaults passed in will get lost' do
89
+ mirage = Client.new
90
+ mirage.templates.should == mirage.templates
91
+ end
92
+
93
+ it 'should find a template' do
94
+ id = 1
95
+ mirage = Client.new
96
+ mock_template = double('template')
97
+ Template.should_receive(:get).with("#{mirage.url}/templates/#{id}").and_return(mock_template)
98
+ mirage.templates(1).should == mock_template
99
+ end
100
+
101
+
102
+ describe 'put' do
103
+ it "should put a response on mirage by passing args on to template's put method " do
104
+ endpoint, value, block = 'greeting', 'hello', Proc.new{}
105
+
106
+ templates_mock = double('templates')
107
+ Templates.should_receive(:new).and_return(templates_mock)
108
+
109
+ templates_mock.should_receive(:put).with(endpoint, value, &block)
110
+
111
+ mirage = Client.new
112
+ mirage.put endpoint, value, &block
113
+ end
114
+ end
115
+ end
116
+
117
+ describe 'requests' do
118
+ it 'should give access to requests' do
119
+ mirage = Client.new
120
+ mirage.requests.instance_of?(Requests).should == true
121
+ end
122
+
123
+ it 'should find a request' do
124
+ id = 1
125
+ mirage = Client.new
126
+ Request.should_receive(:get).with("#{mirage.url}/requests/#{id}")
127
+ mirage.requests(id)
128
+ end
129
+ end
130
+
131
+ describe 'save' do
132
+ it 'should save the current template setup of mirage' do
133
+ mirage = Client.new
134
+ Client.should_receive(:put).with("#{mirage.url}/backup", :body => "")
135
+ mirage.save
136
+ end
137
+ end
138
+
139
+ describe 'revert' do
140
+ it 'should revert the current template set' do
141
+ mirage = Client.new
142
+ Client.should_receive(:put).with(mirage.url, :body => "")
143
+ mirage.revert
144
+ end
145
+ end
146
+
147
+ describe 'running?' do
148
+ it 'should check if mirage is runing' do
149
+ url = 'http://some_url'
150
+
151
+ Mirage.should_receive(:running?).with url
152
+ Client.new(url).running?
153
+ end
154
+ end
155
+
156
+
157
+ describe 'interface to mirage' do
158
+
159
+ after :each do
160
+ Mirage.stop
161
+ end
162
+
163
+ it 'should set a response' do
164
+ client = Mirage.start
165
+ response = client.templates.put("greeting", "hello")
166
+ response.id.should == 1
167
+ end
168
+
169
+ it 'should find mirage running' do
170
+ Mirage.start
171
+ Mirage.running?.should == true
172
+ end
173
+
174
+ it 'should not find mirage running' do
175
+ Mirage.running?.should == false
176
+ end
177
+
178
+ end
179
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe Helpers::MethodBuilder do
4
+
5
+ describe 'a builder method' do
6
+ let :model do
7
+ model_class = Class.new do
8
+ extend Helpers::MethodBuilder
9
+
10
+ builder_method :name
11
+ end
12
+ model_class.new
13
+ end
14
+
15
+ it 'should set a value' do
16
+ model.name(:joe)
17
+ model.name.should == :joe
18
+ end
19
+
20
+ it 'should chain' do
21
+ model.name(:joe).should == model
22
+ end
23
+
24
+ it 'should work with booleans' do
25
+ model.name(false)
26
+ model.name.should == false
27
+ end
28
+ end
29
+
30
+
31
+ it 'should let you define more than one builder method at a time' do
32
+ model_class = Class.new do
33
+ extend Helpers::MethodBuilder
34
+ builder_methods :foo, :bar
35
+ end
36
+ model = model_class.new
37
+ model.respond_to?(:foo).should be_true
38
+ model.respond_to?(:bar).should be_true
39
+ end
40
+ end