antilles 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +47 -0
- data/LICENSE +22 -0
- data/README.md +44 -0
- data/Rakefile +10 -0
- data/antilles.gemspec +32 -0
- data/lib/antilles.rb +117 -0
- data/lib/antilles/cucumber.rb +12 -0
- data/lib/antilles/version.rb +3 -0
- data/spec/antilles_spec.rb +128 -0
- data/spec/spec_helper.rb +2 -0
- metadata +147 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.swp
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
antilles (0.1.0)
|
5
|
+
bundler
|
6
|
+
daemons
|
7
|
+
httparty
|
8
|
+
json
|
9
|
+
mimic
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: http://rubygems.org/
|
13
|
+
specs:
|
14
|
+
crack (0.1.8)
|
15
|
+
daemons (1.1.4)
|
16
|
+
diff-lcs (1.1.3)
|
17
|
+
httparty (0.7.8)
|
18
|
+
crack (= 0.1.8)
|
19
|
+
json (1.5.4)
|
20
|
+
mimic (0.4.3)
|
21
|
+
json
|
22
|
+
plist
|
23
|
+
rack
|
24
|
+
sinatra
|
25
|
+
plist (3.1.0)
|
26
|
+
rack (1.3.2)
|
27
|
+
rake (0.9.2)
|
28
|
+
rspec (2.6.0)
|
29
|
+
rspec-core (~> 2.6.0)
|
30
|
+
rspec-expectations (~> 2.6.0)
|
31
|
+
rspec-mocks (~> 2.6.0)
|
32
|
+
rspec-core (2.6.4)
|
33
|
+
rspec-expectations (2.6.0)
|
34
|
+
diff-lcs (~> 1.1.2)
|
35
|
+
rspec-mocks (2.6.0)
|
36
|
+
sinatra (1.2.6)
|
37
|
+
rack (~> 1.1)
|
38
|
+
tilt (>= 1.2.2, < 2.0)
|
39
|
+
tilt (1.3.3)
|
40
|
+
|
41
|
+
PLATFORMS
|
42
|
+
ruby
|
43
|
+
|
44
|
+
DEPENDENCIES
|
45
|
+
antilles!
|
46
|
+
rake
|
47
|
+
rspec
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2011 Solano Labs, Inc.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Antilles
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
|
5
|
+
Antilles sets up a stub HTTP server using mimic and exposes a simple interface
|
6
|
+
to configure the server. Antilles is meant to work with aruba to make it easier
|
7
|
+
to test command line tools that communicate with Web APIs.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Antilles works best with cucumber, but it can be used with any testing tool.
|
12
|
+
|
13
|
+
### Install the gem:
|
14
|
+
|
15
|
+
gem install antilles
|
16
|
+
|
17
|
+
or use bundler:
|
18
|
+
|
19
|
+
group :test do
|
20
|
+
gem :antilles
|
21
|
+
end
|
22
|
+
|
23
|
+
### Set up environment:
|
24
|
+
|
25
|
+
# features/support/antilles.rb
|
26
|
+
require 'antilles/cucumber'
|
27
|
+
|
28
|
+
Antilles.configure do |server|
|
29
|
+
server.port = 9876 # defaults to 8080
|
30
|
+
server.log = STDOUT # defaults to nil for no logging
|
31
|
+
end
|
32
|
+
|
33
|
+
Requiring `antilles/cucumber` will automatically start a server before all
|
34
|
+
Scenarios tagged `@mimic`, and tear down the server when the test exits.
|
35
|
+
|
36
|
+
## Usage
|
37
|
+
|
38
|
+
Antilles can be configured to do anything mimic can do, but the basic mode of
|
39
|
+
operation is to `install` stubs:
|
40
|
+
|
41
|
+
Given /^creating a membership fails with: (.*)$/ do |error|
|
42
|
+
user="a@b.com"
|
43
|
+
Antilles.install(:post, "/memberships/#{user}", {:status=>1, :explanation=>error}, :code=>409)
|
44
|
+
end
|
data/Rakefile
ADDED
data/antilles.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "antilles/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "antilles"
|
6
|
+
s.version = AntillesVersion::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Solano Labs"]
|
9
|
+
s.email = ["info@tddium.com"]
|
10
|
+
s.homepage = "http://www.tddium.com/"
|
11
|
+
s.summary = %q{Easy API Mimicing for Cucumber}
|
12
|
+
s.description = <<-EOF
|
13
|
+
Antilles uses Mimic to set up a stub HTTP server that a CLI tool being tested
|
14
|
+
with cucumber/aruba can communicate with.
|
15
|
+
EOF
|
16
|
+
|
17
|
+
s.rubyforge_project = "tddium"
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
|
24
|
+
s.add_runtime_dependency("json")
|
25
|
+
s.add_runtime_dependency("bundler")
|
26
|
+
s.add_runtime_dependency("mimic")
|
27
|
+
s.add_runtime_dependency("httparty")
|
28
|
+
s.add_runtime_dependency("daemons")
|
29
|
+
|
30
|
+
s.add_development_dependency("rspec")
|
31
|
+
s.add_development_dependency("rake")
|
32
|
+
end
|
data/lib/antilles.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'mimic'
|
3
|
+
require 'timeout'
|
4
|
+
require 'daemons'
|
5
|
+
require 'httparty'
|
6
|
+
|
7
|
+
class Antilles
|
8
|
+
attr_accessor :port
|
9
|
+
attr_accessor :log
|
10
|
+
|
11
|
+
def initialize(port=nil, log=nil)
|
12
|
+
@port = port || 8080
|
13
|
+
@pid_list = []
|
14
|
+
@log = log
|
15
|
+
end
|
16
|
+
|
17
|
+
def started?
|
18
|
+
@pid_list.size > 0
|
19
|
+
end
|
20
|
+
|
21
|
+
def start
|
22
|
+
pid = Kernel.fork
|
23
|
+
if pid.nil? then
|
24
|
+
args = {:fork => false,
|
25
|
+
:host => 'localhost',
|
26
|
+
:port => @port,
|
27
|
+
:remote_configuration_path => '/api'}
|
28
|
+
args[:log] = @log if @log
|
29
|
+
Mimic.mimic(args) do
|
30
|
+
[:INT, :TERM].each { |sig| trap(sig) { Kernel.exit!(0) } }
|
31
|
+
end
|
32
|
+
Kernel.exit!(0)
|
33
|
+
end
|
34
|
+
@pid_list.push(pid)
|
35
|
+
wait
|
36
|
+
end
|
37
|
+
|
38
|
+
def stop
|
39
|
+
@pid_list.each do |pid|
|
40
|
+
Process.kill("TERM", pid)
|
41
|
+
end
|
42
|
+
@pid_list = []
|
43
|
+
end
|
44
|
+
|
45
|
+
def wait
|
46
|
+
5.times do
|
47
|
+
if ping then
|
48
|
+
break
|
49
|
+
end
|
50
|
+
Kernel.sleep(0.1)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def ping
|
55
|
+
begin
|
56
|
+
http = call_api(:get, '/api/ping')
|
57
|
+
rescue Exception, Timeout::Error
|
58
|
+
return false
|
59
|
+
end
|
60
|
+
return http.code == 200
|
61
|
+
end
|
62
|
+
|
63
|
+
def clear
|
64
|
+
http = call_api(:post, '/api/clear')
|
65
|
+
return http
|
66
|
+
end
|
67
|
+
|
68
|
+
def install(verb, path, body, options={})
|
69
|
+
api_headers = options.delete(:api_headers)
|
70
|
+
params = { 'path' => path, 'body' => body.to_json }.merge(options)
|
71
|
+
http = call_api(:post, "/api/#{verb}", params.to_json, api_headers)
|
72
|
+
return http
|
73
|
+
end
|
74
|
+
|
75
|
+
def call_api(method, path, params = {}, headers = {})
|
76
|
+
tries = 0
|
77
|
+
retries = 7
|
78
|
+
done = false
|
79
|
+
while (tries <= retries) && !done
|
80
|
+
begin
|
81
|
+
http = HTTParty.send(method, "http://localhost:#{@port}#{path}",
|
82
|
+
:body => params, :headers => headers)
|
83
|
+
done = true
|
84
|
+
rescue SystemCallError
|
85
|
+
Kernel.sleep(0.5)
|
86
|
+
rescue Timeout::Error
|
87
|
+
Kernel.sleep(0.5)
|
88
|
+
ensure
|
89
|
+
tries += 1
|
90
|
+
end
|
91
|
+
end
|
92
|
+
raise Timeout::Error if tries > retries && retries >= 0
|
93
|
+
return http
|
94
|
+
end
|
95
|
+
|
96
|
+
class << self
|
97
|
+
def configure(&block)
|
98
|
+
yield server
|
99
|
+
end
|
100
|
+
|
101
|
+
def start
|
102
|
+
return server if server.started?
|
103
|
+
server.start
|
104
|
+
server
|
105
|
+
end
|
106
|
+
|
107
|
+
def server
|
108
|
+
@server ||= Antilles.new
|
109
|
+
@server
|
110
|
+
end
|
111
|
+
|
112
|
+
def clear
|
113
|
+
@server.clear rescue nil
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Antilles do
|
4
|
+
SAMPLE_PID = 12345
|
5
|
+
SAMPLE_PORT = 12346
|
6
|
+
SAMPLE_MIMIC_ARGS = {:fork => false,
|
7
|
+
:host => 'localhost',
|
8
|
+
:port => SAMPLE_PORT,
|
9
|
+
:remote_configuration_path => "/api"}
|
10
|
+
|
11
|
+
|
12
|
+
describe ".configure" do
|
13
|
+
it "should yield an object that can set port and log" do
|
14
|
+
Antilles.configure do |server|
|
15
|
+
server.port = 9875
|
16
|
+
server.log = STDERR
|
17
|
+
end
|
18
|
+
Antilles.server.port.should == 9875
|
19
|
+
Antilles.server.log.should == STDERR
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe ".server" do
|
24
|
+
it "should return an Antilles" do
|
25
|
+
Antilles.server.should be_a(Antilles)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should save what it creates" do
|
29
|
+
s1 = Antilles.server
|
30
|
+
s2 = Antilles.server
|
31
|
+
s1.should == s2
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe ".start" do
|
36
|
+
let(:server) { mock(Antilles) }
|
37
|
+
it "should start a server" do
|
38
|
+
server.stub(:start)
|
39
|
+
server.stub(:started?) { false }
|
40
|
+
server.should_receive(:start)
|
41
|
+
Antilles.stub(:server) { server }
|
42
|
+
|
43
|
+
Antilles.start
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should not start a server if it's already started" do
|
47
|
+
server.stub(:start)
|
48
|
+
server.stub(:started?) { true }
|
49
|
+
server.should_not_receive(:start)
|
50
|
+
Antilles.stub(:server) { server }
|
51
|
+
|
52
|
+
Antilles.start
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#new" do
|
57
|
+
it "should set port and log" do
|
58
|
+
s = Antilles.new(10)
|
59
|
+
s.port.should == 10
|
60
|
+
s = Antilles.new(10, STDERR)
|
61
|
+
s.port.should == 10
|
62
|
+
s.log.should == STDERR
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def stub_start
|
67
|
+
Kernel.stub(:fork) { SAMPLE_PID }
|
68
|
+
Process.stub(:kill).with("TERM", SAMPLE_PID)
|
69
|
+
Kernel.stub(:exit!)
|
70
|
+
Mimic.stub(:mimic)
|
71
|
+
Antilles.any_instance.stub(:wait)
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#started?" do
|
75
|
+
before { stub_start }
|
76
|
+
it "should start false" do
|
77
|
+
subject.should_not be_started
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should be true after starting the server" do
|
81
|
+
subject.start
|
82
|
+
subject.should be_started
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should be false after stopping the server" do
|
86
|
+
subject.start
|
87
|
+
subject.stop
|
88
|
+
subject.should_not be_started
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#start" do
|
93
|
+
subject { Antilles.new(SAMPLE_PORT) }
|
94
|
+
|
95
|
+
before do
|
96
|
+
Kernel.stub(:fork) { nil }
|
97
|
+
Mimic.stub(:mimic)
|
98
|
+
Kernel.stub(:exit!)
|
99
|
+
subject.stub(:wait)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should start mimic on the right port" do
|
103
|
+
Mimic.should_receive(:mimic).with(SAMPLE_MIMIC_ARGS)
|
104
|
+
subject.start
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should start mimic with the log set" do
|
108
|
+
Mimic.should_receive(:mimic).with(SAMPLE_MIMIC_ARGS.merge(:log=>STDERR))
|
109
|
+
subject.log = STDERR
|
110
|
+
subject.start
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "#wait" do
|
115
|
+
before { Kernel.stub(:sleep) }
|
116
|
+
it "should ping" do
|
117
|
+
subject.stub(:ping) { true }
|
118
|
+
subject.should_receive(:ping).once
|
119
|
+
subject.wait
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should retry" do
|
123
|
+
subject.stub(:ping) { false }
|
124
|
+
subject.should_receive(:ping).exactly(5).times
|
125
|
+
subject.wait
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: antilles
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Solano Labs
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-09-03 00:00:00 -07:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: json
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "0"
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: mimic
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: httparty
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
type: :runtime
|
59
|
+
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: daemons
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
type: :runtime
|
70
|
+
version_requirements: *id005
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: rspec
|
73
|
+
prerelease: false
|
74
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: "0"
|
80
|
+
type: :development
|
81
|
+
version_requirements: *id006
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: rake
|
84
|
+
prerelease: false
|
85
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: "0"
|
91
|
+
type: :development
|
92
|
+
version_requirements: *id007
|
93
|
+
description: |
|
94
|
+
Antilles uses Mimic to set up a stub HTTP server that a CLI tool being tested
|
95
|
+
with cucumber/aruba can communicate with.
|
96
|
+
|
97
|
+
email:
|
98
|
+
- info@tddium.com
|
99
|
+
executables: []
|
100
|
+
|
101
|
+
extensions: []
|
102
|
+
|
103
|
+
extra_rdoc_files: []
|
104
|
+
|
105
|
+
files:
|
106
|
+
- .gitignore
|
107
|
+
- Gemfile
|
108
|
+
- Gemfile.lock
|
109
|
+
- LICENSE
|
110
|
+
- README.md
|
111
|
+
- Rakefile
|
112
|
+
- antilles.gemspec
|
113
|
+
- lib/antilles.rb
|
114
|
+
- lib/antilles/cucumber.rb
|
115
|
+
- lib/antilles/version.rb
|
116
|
+
- spec/antilles_spec.rb
|
117
|
+
- spec/spec_helper.rb
|
118
|
+
has_rdoc: true
|
119
|
+
homepage: http://www.tddium.com/
|
120
|
+
licenses: []
|
121
|
+
|
122
|
+
post_install_message:
|
123
|
+
rdoc_options: []
|
124
|
+
|
125
|
+
require_paths:
|
126
|
+
- lib
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
none: false
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: "0"
|
133
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
|
+
none: false
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: "0"
|
139
|
+
requirements: []
|
140
|
+
|
141
|
+
rubyforge_project: tddium
|
142
|
+
rubygems_version: 1.6.2
|
143
|
+
signing_key:
|
144
|
+
specification_version: 3
|
145
|
+
summary: Easy API Mimicing for Cucumber
|
146
|
+
test_files: []
|
147
|
+
|