travis-saucelabs-api 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +22 -0
- data/README.md +67 -0
- data/Rakefile +8 -0
- data/bin/travis-saucelabs +85 -0
- data/lib/travis-saucelabs-api.rb +83 -0
- data/lib/travis-saucelabs-api/version.rb +5 -0
- data/spec/fixtures/allow_outgoing.json +1 -0
- data/spec/fixtures/capacity.json +1 -0
- data/spec/fixtures/instance_info.json +1 -0
- data/spec/fixtures/instances.json +1 -0
- data/spec/fixtures/kill_instance.json +1 -0
- data/spec/fixtures/save_image.json +1 -0
- data/spec/fixtures/start_instance.json +1 -0
- data/spec/spec_helper.rb +50 -0
- data/spec/travis-saucelabs-api_spec.rb +135 -0
- data/travis-saucelabs-api.gemspec +23 -0
- metadata +115 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9a020d8e584148b881c96d7060206d23d527886c
|
4
|
+
data.tar.gz: e8280c6e4bbdd885ed75f91ba220bd4ea784e605
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ec8900ed99b31da6d0a1d4f9708f74aeaca8b2e8032d86e78a7c2ab5f02c1dd774345a8c7cde179978dce23008a73d78e8177656375f89dafb79128819459182
|
7
|
+
data.tar.gz: 158a5a18df2bed7ef52197ad75b6b49400537e0ed0c031e82d62a0701080adc4cf072d4509015eec6a7edc2e0e7ad668057dc5eeacc2e548f7480bbe615d3d3b
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Henrik Hodne
|
2
|
+
|
3
|
+
MIT License
|
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
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# Travis::SaucelabsAPI
|
2
|
+
|
3
|
+
This is an API wrapper to the Travis<->Saucelabs API for Mac VMs
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'travis-saucelabs-api'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install travis-saucelabs-api
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
``` ruby
|
22
|
+
require 'travis-saucelabs-api'
|
23
|
+
|
24
|
+
api = Travis::SaucelabsAPI.new('http://user:password@api.example.com:1234')
|
25
|
+
|
26
|
+
# The available capacity for the cloud
|
27
|
+
#
|
28
|
+
# ichef is the VM type
|
29
|
+
api.capacity # => { 'ichef' => 10 }
|
30
|
+
|
31
|
+
# Start up a VM instance
|
32
|
+
api.start_instance # => { 'instance_id' => '38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1' }
|
33
|
+
|
34
|
+
# Get a list of the running instances
|
35
|
+
api.list_instances # => { 'instances' => [ '38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1' ]}
|
36
|
+
|
37
|
+
# Get information about an instance
|
38
|
+
api.instance_info('38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1') # => {
|
39
|
+
# 'public_ip' => '10.10.10.10',
|
40
|
+
# 'vnc_port' => '5900',
|
41
|
+
# 'FQDN' => 'vm1.example.com',
|
42
|
+
# 'time_created' => 1355294100.609689,
|
43
|
+
# 'instance_id' => '38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1',
|
44
|
+
# 'image_id' => 'ichef-osx8-10.8-working',
|
45
|
+
# 'State' => 'Running',
|
46
|
+
# 'private_ip' => '10.10.20.10',
|
47
|
+
# 'real_image_id' => 'ichef-osx8-10.8-working',
|
48
|
+
# }
|
49
|
+
|
50
|
+
# Stop a VM instance (like unplugging its power)
|
51
|
+
api.kill_instance('38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1')
|
52
|
+
|
53
|
+
# Open the firewall for a given VM instance to allow outgoing connections
|
54
|
+
# (firewalled off by default, watch out.)
|
55
|
+
api.open_outgoing('38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1')
|
56
|
+
|
57
|
+
# Save a disk image from a running VM. Use this sparingly.
|
58
|
+
api.save_image('38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1')
|
59
|
+
```
|
60
|
+
|
61
|
+
## Contributing
|
62
|
+
|
63
|
+
1. Fork it
|
64
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
65
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
66
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
67
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'thor'
|
3
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
4
|
+
require 'travis-saucelabs-api'
|
5
|
+
|
6
|
+
class TravisSaucelabs < Thor
|
7
|
+
desc 'list', 'Print a list of the currently running instances'
|
8
|
+
def list
|
9
|
+
instances = api.list_instances['instances']
|
10
|
+
instances.each do |instance_id|
|
11
|
+
info = api.instance_info(instance_id)
|
12
|
+
puts "Instance ID: #{info['instance_id']}"
|
13
|
+
info.each do |key, value|
|
14
|
+
puts " #{key}: #{value}"
|
15
|
+
end
|
16
|
+
puts
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'start', 'Starts a new VM instance'
|
21
|
+
option :hostname
|
22
|
+
option :password
|
23
|
+
def start
|
24
|
+
instance_id = api.start_instance(startup_info)['instance_id']
|
25
|
+
puts "Started instance with ID #{instance_id}"
|
26
|
+
print "Allowing outgoing connections..."
|
27
|
+
api.allow_outgoing(instance_id)
|
28
|
+
puts "done"
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'kill INSTANCE_ID', 'Kills the instance with the given instance ID'
|
32
|
+
def kill(instance_id)
|
33
|
+
puts api.kill_instance(instance_id)['message']
|
34
|
+
end
|
35
|
+
|
36
|
+
desc 'kill_pid PID', 'Kills all instances belonging to a PID'
|
37
|
+
def kill_pid(pid)
|
38
|
+
instances = api.list_instances['instances'].select do |instance_id|
|
39
|
+
info = api.instance_info(instance_id)
|
40
|
+
info['extra_info'] &&
|
41
|
+
info['extra_info']['hostname'] &&
|
42
|
+
info['extra_info']['hostname'] =~ /^testing-saucelabs-mac-#{pid}/
|
43
|
+
end
|
44
|
+
|
45
|
+
instances.each do |instance_id|
|
46
|
+
kill(instance_id)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
desc 'save_image INSTANCE_ID NAME', 'Saves an image of instance with name'
|
51
|
+
def save_image(instance_id, name)
|
52
|
+
puts api.save_image(instance_id, name)['message']
|
53
|
+
end
|
54
|
+
|
55
|
+
desc 'allow_incoming INSTANCE_ID CIDR PORT', 'Opens an incoming port in the firewall'
|
56
|
+
def allow_incoming(instance_id, cidr, port)
|
57
|
+
puts api.allow_incoming(instance_id, cidr, port)['message']
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def api
|
63
|
+
@api ||= begin
|
64
|
+
unless ENV['TRAVIS_SAUCE_API_URI']
|
65
|
+
puts 'You need to set the TRAVIS_SAUCE_API_URI environment variable'
|
66
|
+
puts ' export TRAVIS_SAUCE_API_URI="http://user:password@api-endpoint:port"'
|
67
|
+
exit 1
|
68
|
+
end
|
69
|
+
Travis::SaucelabsAPI.new(ENV['TRAVIS_SAUCE_API_URI'])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def startup_info
|
74
|
+
if options[:hostname] || options[:password]
|
75
|
+
startup_info = {}
|
76
|
+
startup_info[:hostname] = options[:hostname] if options[:hostname]
|
77
|
+
startup_info[:password] = options[:password] if options[:password]
|
78
|
+
startup_info
|
79
|
+
else
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
TravisSaucelabs.start
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'travis-saucelabs-api/version'
|
2
|
+
require 'faraday'
|
3
|
+
require 'faraday_middleware'
|
4
|
+
|
5
|
+
module Travis
|
6
|
+
class SaucelabsAPI
|
7
|
+
class NotFoundError < StandardError; end
|
8
|
+
|
9
|
+
DEFAULT_IMAGE = 'ichef-osx8-10.8-travis'
|
10
|
+
|
11
|
+
# Public: Initialize a new API client instance
|
12
|
+
#
|
13
|
+
# uri - The URI or String endpoint for the API. This should include the
|
14
|
+
# username and password used for authentication.
|
15
|
+
def initialize(uri)
|
16
|
+
@connection = Faraday.new(uri) do |connection|
|
17
|
+
connection.use FaradayMiddleware::EncodeJson
|
18
|
+
connection.use FaradayMiddleware::ParseJson, content_type: /\bjson$/
|
19
|
+
connection.adapter Faraday.default_adapter
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def capacity
|
24
|
+
handle_response(@connection.get('/capacity'))
|
25
|
+
end
|
26
|
+
|
27
|
+
def start_instance(startup_info=nil, image=DEFAULT_IMAGE)
|
28
|
+
response = @connection.post('/instances', startup_info) do |request|
|
29
|
+
request.params.update(image: image)
|
30
|
+
end
|
31
|
+
|
32
|
+
handle_response(response)
|
33
|
+
end
|
34
|
+
|
35
|
+
def list_instances
|
36
|
+
handle_response(@connection.get('/instances'))
|
37
|
+
end
|
38
|
+
|
39
|
+
def instance_info(instance_id)
|
40
|
+
handle_response(@connection.get("/instances/#{uri_escape(instance_id)}"))
|
41
|
+
end
|
42
|
+
|
43
|
+
def kill_instance(instance_id)
|
44
|
+
instance_id = uri_escape(instance_id)
|
45
|
+
handle_response(@connection.delete("/instances/#{instance_id}"))
|
46
|
+
end
|
47
|
+
|
48
|
+
def allow_outgoing(instance_id)
|
49
|
+
instance_id = uri_escape(instance_id)
|
50
|
+
handle_response(@connection.post("/instances/#{instance_id}/allow_outgoing"))
|
51
|
+
end
|
52
|
+
|
53
|
+
def allow_incoming(instance_id, cidr, port)
|
54
|
+
instance_id = uri_escape(instance_id)
|
55
|
+
response = @connection.post("/instances/#{instance_id}/allow_incoming") do |request|
|
56
|
+
request.params.update(cidr: cidr, port: port)
|
57
|
+
end
|
58
|
+
|
59
|
+
handle_response(response)
|
60
|
+
end
|
61
|
+
|
62
|
+
def save_image(instance_id, name)
|
63
|
+
instance_id = uri_escape(instance_id)
|
64
|
+
response = @connection.post("/instances/#{instance_id}/save_image") do |request|
|
65
|
+
request.params.update(name: name)
|
66
|
+
end
|
67
|
+
|
68
|
+
handle_response(response)
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def handle_response(response)
|
74
|
+
raise NotFoundError if response.status == 404
|
75
|
+
|
76
|
+
response.body
|
77
|
+
end
|
78
|
+
|
79
|
+
def uri_escape(str)
|
80
|
+
Faraday::Utils.escape(str)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"message": "outgoing connections allowed"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"ichef": 3}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"public_ip": "10.10.10.10", "vnc_port": "5900", "FQDN": "vm1.example.com", "time_created": 1355294100.609689, "instance_id": "38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1", "image_id": "ichef-osx8-10.8-working", "State": "Running", "private_ip": "10.10.20.10", "real_image_id": "ichef-osx8-10.8-working"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"instances": ["38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1"]}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"message": "stopped '38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1'"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"message": "in progress"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"instance_id": "38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1"}
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'travis-saucelabs-api'
|
2
|
+
require 'rspec'
|
3
|
+
require 'webmock/rspec'
|
4
|
+
|
5
|
+
RSpec.configure do |rspec|
|
6
|
+
rspec.expect_with(:rspec) do |config|
|
7
|
+
config.syntax = :expect
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def a_delete(endpoint, path)
|
12
|
+
a_request(:delete, endpoint + path)
|
13
|
+
end
|
14
|
+
|
15
|
+
def a_get(endpoint, path)
|
16
|
+
a_request(:get, endpoint + path)
|
17
|
+
end
|
18
|
+
|
19
|
+
def a_post(endpoint, path)
|
20
|
+
a_request(:post, endpoint + path)
|
21
|
+
end
|
22
|
+
|
23
|
+
def a_put(endpoint, path)
|
24
|
+
a_request(:put, endpoint + path)
|
25
|
+
end
|
26
|
+
|
27
|
+
def stub_delete(endpoint, path)
|
28
|
+
stub_request(:delete, endpoint + path)
|
29
|
+
end
|
30
|
+
|
31
|
+
def stub_get(endpoint, path)
|
32
|
+
stub_request(:get, endpoint + path)
|
33
|
+
end
|
34
|
+
|
35
|
+
def stub_post(endpoint, path)
|
36
|
+
stub_request(:post, endpoint + path)
|
37
|
+
end
|
38
|
+
|
39
|
+
def stub_put(endpoint, path)
|
40
|
+
stub_request(:put, endpoint + path)
|
41
|
+
end
|
42
|
+
|
43
|
+
def fixture_path
|
44
|
+
File.expand_path('../fixtures', __FILE__)
|
45
|
+
end
|
46
|
+
|
47
|
+
def fixture(file)
|
48
|
+
File.new(fixture_path + '/' + file)
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Travis::SaucelabsAPI do
|
4
|
+
let(:endpoint) { 'http://user:password@travis-saucelabs.dev:1234' }
|
5
|
+
let(:api) { Travis::SaucelabsAPI.new(endpoint) }
|
6
|
+
|
7
|
+
describe '#capacity' do
|
8
|
+
before do
|
9
|
+
stub_get(endpoint, '/capacity').to_return(body: fixture('capacity.json'), headers: { content_type: 'text/html' })
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'requests the correct resource' do
|
13
|
+
api.capacity
|
14
|
+
expect(a_get(endpoint, '/capacity')).to have_been_made
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'returns the number of available VMs' do
|
18
|
+
expect(api.capacity).to eq({ 'ichef' => 3 })
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#start_instance' do
|
23
|
+
context 'with no parameters' do
|
24
|
+
before do
|
25
|
+
stub_post(endpoint, '/instances').with(query: { image: Travis::SaucelabsAPI::DEFAULT_IMAGE }).to_return(body: fixture('start_instance.json'), headers: { content_type: 'text/html' })
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'requests the correct resource' do
|
29
|
+
api.start_instance
|
30
|
+
expect(a_post(endpoint, '/instances').with(query: { image: Travis::SaucelabsAPI::DEFAULT_IMAGE })).to have_been_made
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns the instance ID' do
|
34
|
+
expect(api.start_instance).to eq({ 'instance_id' => '38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1' })
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'with a different image' do
|
39
|
+
before do
|
40
|
+
stub_post(endpoint, '/instances').with(query: { image: 'custom-image' }).to_return(body: fixture('start_instance.json'), headers: { content_type: 'text/html' })
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'requests the correct resource' do
|
44
|
+
api.start_instance(nil, 'custom-image')
|
45
|
+
expect(a_post(endpoint, '/instances').with(query: { image: 'custom-image' })).to have_been_made
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'with startup info' do
|
50
|
+
before do
|
51
|
+
stub_post(endpoint, '/instances').with(query: { image: Travis::SaucelabsAPI::DEFAULT_IMAGE }, body: { foo: 'bar' }).to_return(body: fixture('start_instance.json'), headers: { content_type: 'text/html' })
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'requests the correct resource' do
|
55
|
+
api.start_instance({ foo: 'bar' }, Travis::SaucelabsAPI::DEFAULT_IMAGE)
|
56
|
+
expect(a_post(endpoint, '/instances').with(query: { image: Travis::SaucelabsAPI::DEFAULT_IMAGE }, body: { foo: 'bar' })).to have_been_made
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#list_instances' do
|
62
|
+
before do
|
63
|
+
stub_get(endpoint, '/instances').to_return(body: fixture('instances.json'), content_type: 'text/html')
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'requests the correct resource' do
|
67
|
+
api.list_instances
|
68
|
+
expect(a_get(endpoint, '/instances')).to have_been_made
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'returns the running instances' do
|
72
|
+
expect(api.list_instances).to eq({ 'instances' => ['38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1'] })
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#instance_info' do
|
77
|
+
before do
|
78
|
+
stub_get(endpoint, '/instances/38257917-4fac-68fc-11f4-1575d2ec6847@travis1%23itako13252').to_return(body: fixture('instance_info.json'), content_type: 'text/html')
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'requests the correct resource' do
|
82
|
+
api.instance_info('38257917-4fac-68fc-11f4-1575d2ec6847@travis1#itako13252')
|
83
|
+
expect(a_get(endpoint, '/instances/38257917-4fac-68fc-11f4-1575d2ec6847@travis1%23itako13252')).to have_been_made
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'returns information about the instance' do
|
87
|
+
expect(api.instance_info('38257917-4fac-68fc-11f4-1575d2ec6847@travis1#itako13252')).to eq({
|
88
|
+
'public_ip' => '10.10.10.10',
|
89
|
+
'vnc_port' => '5900',
|
90
|
+
'FQDN' => 'vm1.example.com',
|
91
|
+
'time_created' => 1355294100.609689,
|
92
|
+
'instance_id' => '38257917-4fac-68fc-11f4-1575d2ec6847@api#vm1',
|
93
|
+
'image_id' => 'ichef-osx8-10.8-working',
|
94
|
+
'State' => 'Running',
|
95
|
+
'private_ip' => '10.10.20.10',
|
96
|
+
'real_image_id' => 'ichef-osx8-10.8-working',
|
97
|
+
})
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe '#kill_instance' do
|
102
|
+
before do
|
103
|
+
stub_delete(endpoint, '/instances/38257917-4fac-68fc-11f4-1575d2ec6847@travis1%23itako13252').to_return(body: fixture('kill_instance.json'), content_type: 'text/html')
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'requests the correct resource' do
|
107
|
+
api.kill_instance('38257917-4fac-68fc-11f4-1575d2ec6847@travis1#itako13252')
|
108
|
+
expect(a_delete(endpoint, '/instances/38257917-4fac-68fc-11f4-1575d2ec6847@travis1%23itako13252')).to have_been_made
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe '#allow_outgoing' do
|
113
|
+
before do
|
114
|
+
stub_post(endpoint, '/instances/38257917-4fac-68fc-11f4-1575d2ec6847@travis1%23itako13252/allow_outgoing').to_return(body: fixture('allow_outgoing.json'), content_type: 'text/html')
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'requests the correct resource' do
|
118
|
+
api.allow_outgoing('38257917-4fac-68fc-11f4-1575d2ec6847@travis1#itako13252')
|
119
|
+
expect(a_post(endpoint, '/instances/38257917-4fac-68fc-11f4-1575d2ec6847@travis1%23itako13252/allow_outgoing')).to have_been_made
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe '#save_image' do
|
124
|
+
before do
|
125
|
+
stub_post(endpoint, '/instances/38257917-4fac-68fc-11f4-1575d2ec6847@travis1%23itako13252/save_image?name=foo').to_return(body: fixture('save_image.json'), content_type: 'text/html')
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'requests the correct resource' do
|
129
|
+
api.save_image('38257917-4fac-68fc-11f4-1575d2ec6847@travis1#itako13252', 'foo')
|
130
|
+
expect(a_post(endpoint, '/instances/38257917-4fac-68fc-11f4-1575d2ec6847@travis1%23itako13252/save_image?name=foo')).to have_been_made
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'travis-saucelabs-api/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "travis-saucelabs-api"
|
8
|
+
gem.version = Travis::SaucelabsAPI::VERSION
|
9
|
+
gem.authors = ["Henrik Hodne"]
|
10
|
+
gem.email = ["me@henrikhodne.com"]
|
11
|
+
gem.description = %q{Ruby client library for the API Travis uses to spin up OS X VMs}
|
12
|
+
gem.summary = %q{Travis/Sauce Labs API client}
|
13
|
+
gem.homepage = 'https://github.com/henrikhodne/travis-saucelabs-api'
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_runtime_dependency('faraday', '~> 0.7')
|
21
|
+
gem.add_runtime_dependency('faraday_middleware', '~> 0.9')
|
22
|
+
gem.add_runtime_dependency('thor', '~> 0.14')
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: travis-saucelabs-api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Henrik Hodne
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-07-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.7'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday_middleware
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.9'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: thor
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.14'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.14'
|
55
|
+
description: Ruby client library for the API Travis uses to spin up OS X VMs
|
56
|
+
email:
|
57
|
+
- me@henrikhodne.com
|
58
|
+
executables:
|
59
|
+
- travis-saucelabs
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- .gitignore
|
64
|
+
- .rspec
|
65
|
+
- .travis.yml
|
66
|
+
- Gemfile
|
67
|
+
- LICENSE.txt
|
68
|
+
- README.md
|
69
|
+
- Rakefile
|
70
|
+
- bin/travis-saucelabs
|
71
|
+
- lib/travis-saucelabs-api.rb
|
72
|
+
- lib/travis-saucelabs-api/version.rb
|
73
|
+
- spec/fixtures/allow_outgoing.json
|
74
|
+
- spec/fixtures/capacity.json
|
75
|
+
- spec/fixtures/instance_info.json
|
76
|
+
- spec/fixtures/instances.json
|
77
|
+
- spec/fixtures/kill_instance.json
|
78
|
+
- spec/fixtures/save_image.json
|
79
|
+
- spec/fixtures/start_instance.json
|
80
|
+
- spec/spec_helper.rb
|
81
|
+
- spec/travis-saucelabs-api_spec.rb
|
82
|
+
- travis-saucelabs-api.gemspec
|
83
|
+
homepage: https://github.com/henrikhodne/travis-saucelabs-api
|
84
|
+
licenses: []
|
85
|
+
metadata: {}
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
requirements: []
|
101
|
+
rubyforge_project:
|
102
|
+
rubygems_version: 2.0.3
|
103
|
+
signing_key:
|
104
|
+
specification_version: 4
|
105
|
+
summary: Travis/Sauce Labs API client
|
106
|
+
test_files:
|
107
|
+
- spec/fixtures/allow_outgoing.json
|
108
|
+
- spec/fixtures/capacity.json
|
109
|
+
- spec/fixtures/instance_info.json
|
110
|
+
- spec/fixtures/instances.json
|
111
|
+
- spec/fixtures/kill_instance.json
|
112
|
+
- spec/fixtures/save_image.json
|
113
|
+
- spec/fixtures/start_instance.json
|
114
|
+
- spec/spec_helper.rb
|
115
|
+
- spec/travis-saucelabs-api_spec.rb
|