antilles 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in tddium.gemspec
4
+ gemspec
5
+
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
@@ -0,0 +1,10 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec) do |t|
7
+ t.rspec_opts = "--color"
8
+ end
9
+ task :default => :spec
10
+
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,12 @@
1
+ Before('@mimic') do
2
+ MimicServer.start
3
+ end
4
+
5
+ After('@mimic') do
6
+ MimicServer.clear
7
+ end
8
+
9
+ at_exit do
10
+ server = MimicServer.server
11
+ server.stop if server
12
+ end
@@ -0,0 +1,3 @@
1
+ module AntillesVersion
2
+ VERSION = '0.1.0'
3
+ end
@@ -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
@@ -0,0 +1,2 @@
1
+ require "antilles"
2
+
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
+