mocktopus 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5c7dd5e4c53bbd5b1aff16acb47abbffae3be411
4
+ data.tar.gz: 4517dbbda052ffb494852ec3586f698151e45e00
5
+ SHA512:
6
+ metadata.gz: 072bb9f8221692ce8b2ecf0a8222733096a0584068b4922d2c26be6dec79cfa9411f0e401203f947d93028aad4bacb5f114ad7643534ba0196fa482c99295480
7
+ data.tar.gz: 4a9c3716d2a2dad0681cc0c5643a4179ad366dad33f78c25c7644ae23753bd2ed82bf91ec694b3520aae5245a6b9c1eebb030ad5fe761078ba23ec7bbc31e334
data/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *DS_STORE
2
+ /Gemfile.lock
3
+ *.gem
4
+ coverage/
5
+ .ruby-version
6
+ *.log.*
7
+ *.log
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
4
+ - 2.0.0
5
+ - 1.9.3
6
+ notifications:
7
+ email:
8
+ - justin.brown@rackspace.com
9
+ script: "rake test"
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2015 Rackspace, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,309 @@
1
+ [![Build Status](https://travis-ci.org/rackspaceautomationco/mocktopus.svg?branch=v0.0.1)](https://travis-ci.org/rackspaceautomationco/mocktopus) [![Coverage Status](https://coveralls.io/repos/rackspaceautomationco/mocktopus/badge.svg?branch=master)](https://coveralls.io/r/rackspaceautomationco/mocktopus?branch=master) [![Gem Version](https://badge.fury.io/rb/mocktopus.svg)](http://badge.fury.io/rb/mocktopus)
2
+
3
+ . .
4
+ -|-|-. .-,
5
+ '-' '-`'-
6
+ . .
7
+ ,-,-. ,-. ,-. | , |- ,-. ,-. . . ,-.
8
+ | | | | | | |< | | | | | | | `-.
9
+ ' ' ' `-' `-' ' ` `' `-' |-' `-^ `-'
10
+ |
11
+ '
12
+ .....
13
+ .
14
+ . ..
15
+ .. ......
16
+ .. ........ .....
17
+ .. .. .. .. .. .
18
+ . .......... .
19
+ . .. .. .
20
+ . ...... . .
21
+ . ...... . ..
22
+ .. ........ ...
23
+ ............................ ......
24
+ ....................... .
25
+ ... ......... .
26
+ .. ........... .
27
+ .. .......... .. ..
28
+ . .... .. .. ...... ... .
29
+ .. .. .. ..... .. ... .
30
+ .. .. .. . .. . . ..... ...
31
+ ...... . . . .. . . ...
32
+ . . . . . . .
33
+ . . . . .. . . .
34
+ . .. . .. .. . .
35
+ ...... . . ... ..
36
+ . . ..... ....
37
+ . . ....
38
+ .. . ..
39
+ . . .
40
+ . ... ...
41
+ ..
42
+ ........
43
+
44
+ ## About
45
+
46
+ The Mocktopus is a Sinatra/thin-based Web API that lets you mock your app's dependencies. A few setup-related endpoints allow you to tell The Mocktopus how to intercept and respond to any combination of uri/method/uri/headers/body.
47
+
48
+ Written in Ruby, The Mocktopus differs from similar tools in its lack of plugin or code-driven setups. The Mocktopus is meant to run standalone, primed, and configured exclusively by The Mocktopus Web API. This means that an instance of The Mocktopus can be configured on the fly and independently of your apps/code. [Inspiration](https://www.youtube.com/watch?v=JJ4S9khZKjk).
49
+
50
+ ## Usage
51
+
52
+ 1. Install The Mocktopus gem
53
+
54
+ `$ gem install mocktopus`
55
+
56
+ 2. Start The Mocktopus (add -p {PORT} to specify a port other than default/8081)
57
+
58
+ `$ mocktopus start`
59
+
60
+ 3. Tell The Mocktopus how to behave by [creating an input](#create-an-input)
61
+
62
+ `POST 'http://localhost:8081/mocktopus/inputs/:name' ...`
63
+
64
+ 4. Point your app to The Mocktopus to fake dependencies or prototype new code
65
+
66
+ >The Mocktopus does not persist the mocks that have been set up, which means that if the service is restarted, any mock setups that have been created will have to be resubmitted.
67
+
68
+ ## Endpoints
69
+
70
+ This section describes the endpoints that The Mocktopus provides for managing mocks as well as reviewing any calls that it receives.
71
+
72
+ ### Create an input
73
+
74
+ `POST '/mocktopus/inputs/:name'`
75
+
76
+ Creates a setup instructing The Mocktopus on how to behave for a specific call. :name is for your use only in identifying, updating, or deleting the setup later. A sample payload follows:
77
+
78
+ ```json
79
+ {
80
+ "uri" : "/domain/domain.com/users",
81
+ "headers" : {
82
+ "whitelisting_key_here" : "value"
83
+ },
84
+ "body" : {
85
+ "name" : "the mocktopus",
86
+ "email" : "the_mocktopus@the_mocktopus.com"
87
+ },
88
+ "verb" : "POST",
89
+ "response" : {
90
+ "code" : "202",
91
+ "delay": 5000,
92
+ "headers" : {},
93
+ "body" : "Thanks!"
94
+ }
95
+ }
96
+ ```
97
+
98
+ > POSTing to the same :name will overwrite any existing payload at that :name with the new payload.
99
+
100
+ The uri, verb, and response properties are all required. Within the response property, code is the only required property.
101
+
102
+ | Property | Description |
103
+ |---|---|
104
+ | uri | The path and query for the mock |
105
+ | headers | Required headers for matching. Only the headers included will be used for matching purposes. Any additional headers supplied by a client hitting The Mocktopus will be ignored |
106
+ | body | The request body content used for matching |
107
+ | verb | The request verb used for matching |
108
+ | response | The response sent back to the client upon a successful match |
109
+
110
+ Response Properties
111
+
112
+ | Property | Description |
113
+ |---|---|
114
+ | code | The HTTP status code returned for the response
115
+ | delay | The amount of time in milliseconds to wait before sending the mocked response back on a successful match
116
+ | headers | A collection of headers to send back with the response |
117
+ | body | The content returned on a successful match
118
+
119
+ While The Mocktopus only accepts JSON for creating and managing mocked endpoints, it can return just about whatever you like: SOAP, XML, plain text or JSON:
120
+
121
+ ```json
122
+ {
123
+ "uri" : "/domain/domain.com/users",
124
+ "headers" : {},
125
+ "body" : null,
126
+ "verb" : "GET",
127
+ "response" : {
128
+ "code" : "200",
129
+ "headers" : {
130
+ "Content-Type": "application/xml"
131
+ },
132
+ "body" : "<users><user><id>1</id><name>John</name></user><user><id>2</id><name>Jane</name></user></users>"
133
+ }
134
+ }
135
+ ```
136
+
137
+ #### Matching Rules
138
+
139
+ The Mocktopus matches incoming requests against the uri, headers, body, and verb provided in the mock. In the case of headers, only the headers that are actually provided in the mock are validated. Any additional headers provided by the client are ignored.
140
+
141
+ Matches are **case-sensitive** when checking against the uri and body elements. For header matching, the header key is not case-sensitive, however the test against the header value is.
142
+
143
+ Query string parameters can be included in the uri property. Both the keys and values are case-sensitive, and the order of the query string parameters must be the same.
144
+
145
+ >Because The Mocktopus does exact matching, with JSON in particular an empty JSON object **{}** is different from a null or empty incoming payload. To create a mock to match against an empty payload, omit the **body** element from the mock setup or set it to null.
146
+
147
+ If The Mocktopus cannot find a match, it will return status code 428 and a text/html response describing the request it couldn't match:
148
+
149
+ ```
150
+ Match not found
151
+ Unable to find a match from the following API call:
152
+ Path:
153
+ /domain/domain.com/usersaadsfad
154
+ Verb:
155
+ GET
156
+ Headers:
157
+ {"version"=>"HTTP/1.1", "host"=>"127.0.0.1:8081", "connection"=>"keep-alive", "cache_control"=>"no-cache", "accept"=>"*/*", "dnt"=>"1", "accept_encoding"=>"gzip, deflate, sdch", "accept_language"=>"en-US,en;q=0.8"}
158
+ Body:
159
+ ```
160
+
161
+ #### Response Queueing
162
+
163
+ The Mocktopus allows you to queue up multiple responses for the same match. For example, suppose you have an external service that allows you to submit a request to create something. This process takes awhile, so the external services helpfully provide you with a URL where you can check the status of that thing, and when it's ready, the URL will return a 201 Created. You can simulate that polling process using response queuing.
164
+
165
+ The process you're trying to mock might look like this:
166
+
167
+ 1. POST a request to create a thing
168
+ 2. Receive back a payload with a URL you can use to poll
169
+ 3. GET the URL you were given in step 2 until you receive back a 201 status code
170
+
171
+ With request queueing, you can set up several responses to the same request. Each match will pop a response off of the queue until there are no more, then that response will **always** be returned for any subsequent requests.
172
+
173
+ To mock this scenario, start with a mock for the initial POST and the response that is returned.
174
+
175
+ ```json
176
+ {
177
+ "uri" : "/some-resource-collection-that-takes-forever",
178
+ "headers" : {},
179
+ "body" : {
180
+ "name" : "huge-thing",
181
+ "size" : "1000 petabytes"
182
+ },
183
+ "verb" : "POST",
184
+ "response" : {
185
+ "code" : "202",
186
+ "headers" : {},
187
+ "body" : {
188
+ "statusLink": "http://mocktopusip:8081/monitor/1",
189
+ "status": "creating"
190
+ }
191
+ }
192
+ }
193
+ ```
194
+ With the initial POST setup, you can move to set up the monitoring calls, using the **statusLink** as set up in the body as your mocked endpoint:
195
+
196
+ ```json
197
+ {
198
+ "uri" : "/monitor/1",
199
+ "headers" : {},
200
+ "body" : null,
201
+ "verb" : "GET",
202
+ "response" : {
203
+ "code" : "200",
204
+ "headers" : {},
205
+ "body" : {
206
+ "statusLink": "http://mocktopusip:8081/monitor/1",
207
+ "status": "Still going"
208
+ }
209
+ }
210
+ }
211
+ ```
212
+ ```json
213
+ {
214
+ "uri" : "/monitor/1",
215
+ "headers" : {},
216
+ "body" : null,
217
+ "verb" : "GET",
218
+ "response" : {
219
+ "code" : "200",
220
+ "headers" : {},
221
+ "body" : {
222
+ "statusLink": "http://mocktopusip:8081/monitor/1",
223
+ "status": "Yep, still going"
224
+ }
225
+ }
226
+ }
227
+ ```
228
+ ```json
229
+ {
230
+ "uri" : "/monitor/1",
231
+ "headers" : {},
232
+ "body" : null,
233
+ "verb" : "GET",
234
+ "response" : {
235
+ "code" : "200",
236
+ "headers" : {},
237
+ "body" : {
238
+ "statusLink": "http://mocktopusip:8081/monitor/1",
239
+ "status": "Almost there..."
240
+ }
241
+ }
242
+ }
243
+ ```
244
+
245
+ With this, you have set up three responses for the same request match. While The Mocktopus doesn't have a concept of returning a request for a period of time, you can set up as many responses to the same request as you want.
246
+
247
+ Now that you have set up your request to simulate polling, you can add your final request which will be returned when a client hits the /monitor/1 resource:
248
+
249
+
250
+ ```json
251
+ {
252
+ "uri" : "/monitor/1",
253
+ "headers" : {},
254
+ "body" : null,
255
+ "verb" : "GET",
256
+ "response" : {
257
+ "code" : "201",
258
+ "headers" : {},
259
+ "body" : {
260
+ "self": "http://mocktopusip:8081/some-resource-collection-that-takes-forever/huge-thing"
261
+ }
262
+ }
263
+ }
264
+ ```
265
+
266
+ You could continue this mock setup by then mocking the /some-resource-collection-that-takes-forever/huge-thing endpoint with the correct payload.
267
+
268
+
269
+ It's important to note that even though these are matching against the same request, the mocks still have to be POSTed to unique endpoints within The Mocktopus, otherwise the responses would be overwritten, not queued:
270
+
271
+ - POST /mocktopus/inputs/1
272
+ - POST /mocktopus/inputs/2
273
+ - POST /mocktopus/inputs/3
274
+
275
+ ### Retrieve an input
276
+
277
+ `GET '/mocktopus/inputs/[:name]' `
278
+
279
+ Retrieves a specific input by name (if specified), or a serialized list of all inputs.
280
+
281
+ ### Delete input(s)
282
+
283
+ `DELETE '/mocktopus/inputs/[:name]' `
284
+
285
+ Deletes a specific input by name (if specified), or deletes all inputs.
286
+
287
+ ### Get all calls received by The Mocktopus
288
+
289
+ `GET '/mocktopus/mock_api_calls' `
290
+
291
+ Retrieves a serialized list of all calls received by The Mocktopus (excluding setups).
292
+
293
+ ### Delete all calls
294
+
295
+ `DELETE '/mocktopus/mock_api_calls' `
296
+
297
+ Deletes all stored calls.
298
+
299
+ ## Contributing
300
+
301
+ 1. Fork/clone The Mocktopus repo
302
+ 2. Make sure tests pass by running `rake` at the root of the project
303
+ 3. Add tests for your change. Make your change, and make sure that tests pass by running `rake` again
304
+ 4. Commit to your fork using a good commit message
305
+ 5. Push and submit a pull request
306
+
307
+ ## License
308
+
309
+ Distributed under the [MIT-LICENSE](/MIT-LICENSE)
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'bundler/gem_tasks'
4
+
5
+ require 'rake/testtask'
6
+ Rake::TestTask.new(:test) do |test|
7
+ test.libs << 'lib' << 'test'
8
+ test.pattern = 'test/**/*_test.rb'
9
+ end
10
+
11
+ task :default => [:test]
data/ascii.rb ADDED
@@ -0,0 +1,44 @@
1
+ ascii = <<-EOH
2
+ . .
3
+ -|-|-. .-,
4
+ '-' '-`'-
5
+ . .
6
+ ,-,-. ,-. ,-. | , |- ,-. ,-. . . ,-.
7
+ | | | | | | |< | | | | | | | `-.
8
+ ' ' ' `-' `-' ' ` `' `-' |-' `-^ `-'
9
+ |
10
+ '
11
+ .....
12
+ .
13
+ . ..
14
+ .. ......
15
+ .. ........ .....
16
+ .. .. .. .. .. .
17
+ . .......... .
18
+ . .. .. .
19
+ . ...... . .
20
+ . ...... . ..
21
+ .. ........ ...
22
+ ............................ ......
23
+ ....................... .
24
+ ... ......... .
25
+ .. ........... .
26
+ .. .......... .. ..
27
+ . .... .. .. ...... ... .
28
+ .. .. .. ..... .. ... .
29
+ .. .. .. . .. . . ..... ...
30
+ ...... . . . .. . . ...
31
+ . . . . . . .
32
+ . . . . .. . . .
33
+ . .. . .. .. . .
34
+ ...... . . ... ..
35
+ . . ..... ....
36
+ . . ....
37
+ .. . ..
38
+ . . .
39
+ . ... ...
40
+ ..
41
+ ........
42
+ EOH
43
+
44
+ puts ascii
data/bin/mocktopus ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ require "pathname"
3
+ pn = Pathname.new(__FILE__)
4
+ bin_file = pn.realpath
5
+ $:.unshift File.expand_path("../../lib", bin_file)
6
+
7
+ require 'mocktopus/cli'
8
+
9
+ root = File.expand_path('../..', bin_file)
10
+ ENV['BUNDLE_GEMFILE'] = "#{root}/Gemfile"
11
+ ENV['CONFIG_RU'] = "#{root}/config.ru"
12
+
13
+ Mocktopus::CLI.source_root(File.expand_path('../../', bin_file))
14
+ Mocktopus::CLI.start(ARGV)
data/config.ru ADDED
@@ -0,0 +1,3 @@
1
+ require 'mocktopus'
2
+
3
+ run Sinatra::Application
data/lib/mocktopus.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'logger'
2
+ LOGGER = Logger.new('mocktopus.log', 'daily')
3
+
4
+ require 'mocktopus/response'
5
+ require 'mocktopus/input'
6
+ require 'mocktopus/mock_api_call'
7
+ require 'mocktopus/input_container'
8
+ require 'mocktopus/mock_api_call_container'
9
+ require 'mocktopus/cli'
10
+ require 'mocktopus/app'
11
+
12
+ module Mocktopus
13
+ end