fog-voxel 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.rubocop.yml +20 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +19 -0
- data/CONTRIBUTING.md +18 -0
- data/CONTRIBUTORS.md +5 -0
- data/Gemfile +4 -0
- data/LICENSE.md +20 -0
- data/README.md +34 -0
- data/Rakefile +18 -0
- data/fog-voxel.gemspec +35 -0
- data/gemfiles/Gemfile.1.9.2- +8 -0
- data/gemfiles/Gemfile.1.9.3+ +7 -0
- data/lib/fog/bin/voxel.rb +29 -0
- data/lib/fog/compute/voxel.rb +127 -0
- data/lib/fog/compute/voxel/image.rb +11 -0
- data/lib/fog/compute/voxel/images.rb +24 -0
- data/lib/fog/compute/voxel/real.rb +6 -0
- data/lib/fog/compute/voxel/real/devices_list.rb +22 -0
- data/lib/fog/compute/voxel/real/devices_power.rb +20 -0
- data/lib/fog/compute/voxel/real/images_list.rb +29 -0
- data/lib/fog/compute/voxel/real/voxcloud_create.rb +20 -0
- data/lib/fog/compute/voxel/real/voxcloud_delete.rb +18 -0
- data/lib/fog/compute/voxel/real/voxcloud_status.rb +22 -0
- data/lib/fog/compute/voxel/server.rb +71 -0
- data/lib/fog/compute/voxel/servers.rb +26 -0
- data/lib/fog/parsers/compute.rb +7 -0
- data/lib/fog/parsers/compute/voxel.rb +14 -0
- data/lib/fog/parsers/compute/voxel/basic.rb +27 -0
- data/lib/fog/parsers/compute/voxel/devices_list.rb +107 -0
- data/lib/fog/parsers/compute/voxel/images_list.rb +55 -0
- data/lib/fog/parsers/compute/voxel/voxcloud_create.rb +36 -0
- data/lib/fog/parsers/compute/voxel/voxcloud_delete.rb +27 -0
- data/lib/fog/parsers/compute/voxel/voxcloud_status.rb +42 -0
- data/lib/fog/voxel.rb +25 -0
- data/lib/fog/voxel/compute.rb +0 -0
- data/lib/fog/voxel/version.rb +5 -0
- data/spec/minitest_helper.rb +31 -0
- data/tests/helper.rb +37 -0
- data/tests/helpers/collection_helper.rb +97 -0
- data/tests/helpers/compute/flavors_helper.rb +32 -0
- data/tests/helpers/compute/server_helper.rb +25 -0
- data/tests/helpers/compute/servers_helper.rb +10 -0
- data/tests/helpers/formats_helper.rb +98 -0
- data/tests/helpers/formats_helper_tests.rb +110 -0
- data/tests/helpers/mock_helper.rb +117 -0
- data/tests/helpers/model_helper.rb +31 -0
- data/tests/helpers/responds_to_helper.rb +11 -0
- data/tests/helpers/schema_validator_tests.rb +107 -0
- data/tests/helpers/succeeds_helper.rb +9 -0
- data/tests/requests/compute/image_tests.rb +52 -0
- data/tests/requests/compute/server_tests.rb +123 -0
- metadata +225 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
module Fog
|
2
|
+
module Parsers
|
3
|
+
module Compute
|
4
|
+
module Voxel
|
5
|
+
class VoxcloudCreate < Fog::Parsers::Base
|
6
|
+
def reset
|
7
|
+
@response = { 'device' => {} }
|
8
|
+
end
|
9
|
+
|
10
|
+
def start_element(name, attrs = [])
|
11
|
+
super
|
12
|
+
|
13
|
+
case name
|
14
|
+
when 'err'
|
15
|
+
@response['err'] = {
|
16
|
+
'code' => attr_value('code', attrs),
|
17
|
+
'msg' => attr_value('msg', attrs)
|
18
|
+
}
|
19
|
+
when 'rsp'
|
20
|
+
@response['stat'] = attr_value('stat', attrs)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def end_element(name)
|
25
|
+
case name
|
26
|
+
when 'id'
|
27
|
+
@response['device'][name] = value
|
28
|
+
when 'last_update'
|
29
|
+
@response['device'][name] = Time.at(value.to_i)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Fog
|
2
|
+
module Parsers
|
3
|
+
module Compute
|
4
|
+
module Voxel
|
5
|
+
class VoxcloudDelete < Fog::Parsers::Base
|
6
|
+
def reset
|
7
|
+
@response = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def start_element(name, attrs = [])
|
11
|
+
super
|
12
|
+
|
13
|
+
case name
|
14
|
+
when 'rsp'
|
15
|
+
@response['stat'] = attr_value('stat', attrs)
|
16
|
+
when 'err'
|
17
|
+
@response['err'] = {
|
18
|
+
'code' => attr_value('code', attrs),
|
19
|
+
'msg' => attr_value('msg', attrs)
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Fog
|
2
|
+
module Parsers
|
3
|
+
module Compute
|
4
|
+
module Voxel
|
5
|
+
class VoxcloudStatus < Fog::Parsers::Base
|
6
|
+
def reset
|
7
|
+
@response = { 'devices' => [] }
|
8
|
+
@device = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def start_element(name, attrs = [])
|
12
|
+
super
|
13
|
+
|
14
|
+
case name
|
15
|
+
when 'rsp'
|
16
|
+
@response['stat'] = attr_value('stat', attrs)
|
17
|
+
when 'err'
|
18
|
+
@response['err'] = {
|
19
|
+
'code' => attr_value('code', attrs),
|
20
|
+
'msg' => attr_value('msg', attrs)
|
21
|
+
}
|
22
|
+
when 'device'
|
23
|
+
@device = {}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def end_element(name)
|
28
|
+
case name
|
29
|
+
when 'device'
|
30
|
+
@response['devices'] << @device
|
31
|
+
@device = {}
|
32
|
+
when 'id', 'status'
|
33
|
+
@device[name] = value
|
34
|
+
when 'last_update'
|
35
|
+
@device[name] = Time.at(value.to_i)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/fog/voxel.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'fog/voxel/version'
|
2
|
+
require 'fog/core'
|
3
|
+
require 'fog/xml'
|
4
|
+
require 'digest/md5'
|
5
|
+
|
6
|
+
module Fog
|
7
|
+
module Voxel
|
8
|
+
extend Fog::Provider
|
9
|
+
|
10
|
+
service(:voxel, 'Compute')
|
11
|
+
|
12
|
+
def self.create_signature(secret, options)
|
13
|
+
to_sign = options.keys.map { |k| k.to_s }.sort.map { |k| "#{k}#{options[k.to_sym]}" }.join("")
|
14
|
+
Digest::MD7.hexdigest( secret + to_sign )
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module Compute
|
19
|
+
autoload :Voxel, 'fog/compute/voxel'
|
20
|
+
end
|
21
|
+
|
22
|
+
module Parsers
|
23
|
+
autoload :Compute, 'fog/parsers/compute'
|
24
|
+
end
|
25
|
+
end
|
File without changes
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'minitest/spec'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'turn'
|
4
|
+
|
5
|
+
Turn.config do |c|
|
6
|
+
# use one of output formats:
|
7
|
+
# :outline - turn's original case/test outline mode [default]
|
8
|
+
# :progress - indicates progress with progress bar
|
9
|
+
# :dotted - test/unit's traditional dot-progress mode
|
10
|
+
# :pretty - new pretty reporter
|
11
|
+
# :marshal - dump output as YAML (normal run mode only)
|
12
|
+
# :cue - interactive testing
|
13
|
+
# c.format = :outline
|
14
|
+
# turn on invoke/execute tracing, enable full backtrace
|
15
|
+
c.trace = 20
|
16
|
+
# use humanized test names (works only with :outline format)
|
17
|
+
c.natural = true
|
18
|
+
end
|
19
|
+
|
20
|
+
if ENV['COVERAGE']
|
21
|
+
require 'coveralls'
|
22
|
+
require 'simplecov'
|
23
|
+
|
24
|
+
SimpleCov.start do
|
25
|
+
add_filter '/spec/'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
require File.join(File.dirname(__FILE__), '../lib/fog/exoscale.rb')
|
30
|
+
|
31
|
+
Coveralls.wear! if ENV['COVERAGE']
|
data/tests/helper.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'excon'
|
2
|
+
require 'fog/core'
|
3
|
+
|
4
|
+
if ENV['COVERAGE']
|
5
|
+
require 'coveralls'
|
6
|
+
require 'simplecov'
|
7
|
+
|
8
|
+
SimpleCov.start do
|
9
|
+
add_filter '/spec/'
|
10
|
+
add_filter '/test/'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/fog/voxel'))
|
15
|
+
|
16
|
+
Coveralls.wear! if ENV['COVERAGE']
|
17
|
+
|
18
|
+
Excon.defaults.merge!(:debug_request => true, :debug_response => true)
|
19
|
+
|
20
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helpers', 'mock_helper'))
|
21
|
+
|
22
|
+
# This overrides the default 600 seconds timeout during live test runs
|
23
|
+
if Fog.mocking?
|
24
|
+
FOG_TESTING_TIMEOUT = ENV['FOG_TEST_TIMEOUT'] || 2000
|
25
|
+
Fog.timeout = 2000
|
26
|
+
Fog::Logger.warning "Setting default fog timeout to #{Fog.timeout} seconds"
|
27
|
+
else
|
28
|
+
FOG_TESTING_TIMEOUT = Fog.timeout
|
29
|
+
end
|
30
|
+
|
31
|
+
def lorem_file
|
32
|
+
File.open(File.dirname(__FILE__) + '/lorem.txt', 'r')
|
33
|
+
end
|
34
|
+
|
35
|
+
def array_differences(array_a, array_b)
|
36
|
+
(array_a - array_b) | (array_b - array_a)
|
37
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
def collection_tests(collection, params = {}, mocks_implemented = true)
|
2
|
+
tests('success') do
|
3
|
+
|
4
|
+
tests("#new(#{params.inspect})").succeeds do
|
5
|
+
pending if Fog.mocking? && !mocks_implemented
|
6
|
+
collection.new(params)
|
7
|
+
end
|
8
|
+
|
9
|
+
tests("#create(#{params.inspect})").succeeds do
|
10
|
+
pending if Fog.mocking? && !mocks_implemented
|
11
|
+
@instance = collection.create(params)
|
12
|
+
end
|
13
|
+
# FIXME: work around for timing issue on AWS describe_instances mocks
|
14
|
+
|
15
|
+
if Fog.mocking? && @instance.respond_to?(:ready?)
|
16
|
+
@instance.wait_for { ready? }
|
17
|
+
end
|
18
|
+
|
19
|
+
tests("#all").succeeds do
|
20
|
+
pending if Fog.mocking? && !mocks_implemented
|
21
|
+
collection.all
|
22
|
+
end
|
23
|
+
|
24
|
+
if !Fog.mocking? || mocks_implemented
|
25
|
+
@identity = @instance.identity
|
26
|
+
end
|
27
|
+
|
28
|
+
tests("#get(#{@identity})").succeeds do
|
29
|
+
pending if Fog.mocking? && !mocks_implemented
|
30
|
+
collection.get(@identity)
|
31
|
+
end
|
32
|
+
|
33
|
+
tests('Enumerable') do
|
34
|
+
pending if Fog.mocking? && !mocks_implemented
|
35
|
+
|
36
|
+
methods = [
|
37
|
+
'all?', 'any?', 'find', 'detect', 'collect', 'map',
|
38
|
+
'find_index', 'flat_map', 'collect_concat', 'group_by',
|
39
|
+
'none?', 'one?'
|
40
|
+
]
|
41
|
+
|
42
|
+
# JRuby 1.7.5+ issue causes a SystemStackError: stack level too deep
|
43
|
+
# https://github.com/jruby/jruby/issues/1265
|
44
|
+
if RUBY_PLATFORM == "java" and JRUBY_VERSION =~ /1\.7\.[5-8]/
|
45
|
+
methods.delete('all?')
|
46
|
+
end
|
47
|
+
|
48
|
+
methods.each do |enum_method|
|
49
|
+
if collection.respond_to?(enum_method)
|
50
|
+
tests("##{enum_method}").succeeds do
|
51
|
+
block_called = false
|
52
|
+
collection.send(enum_method) {|x| block_called = true }
|
53
|
+
block_called
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
[
|
59
|
+
'max_by','min_by'
|
60
|
+
].each do |enum_method|
|
61
|
+
if collection.respond_to?(enum_method)
|
62
|
+
tests("##{enum_method}").succeeds do
|
63
|
+
block_called = false
|
64
|
+
collection.send(enum_method) {|x| block_called = true; 0 }
|
65
|
+
block_called
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
if block_given?
|
74
|
+
yield(@instance)
|
75
|
+
end
|
76
|
+
|
77
|
+
if !Fog.mocking? || mocks_implemented
|
78
|
+
@instance.destroy
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
tests('failure') do
|
83
|
+
|
84
|
+
if !Fog.mocking? || mocks_implemented
|
85
|
+
@identity = @identity.to_s
|
86
|
+
@identity = @identity.gsub(/[a-zA-Z]/) { Fog::Mock.random_letters(1) }
|
87
|
+
@identity = @identity.gsub(/\d/) { Fog::Mock.random_numbers(1) }
|
88
|
+
@identity
|
89
|
+
end
|
90
|
+
|
91
|
+
tests("#get('#{@identity}')").returns(nil) do
|
92
|
+
pending if Fog.mocking? && !mocks_implemented
|
93
|
+
collection.get(@identity)
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
def flavors_tests(connection, params = {}, mocks_implemented = true)
|
2
|
+
tests('success') do
|
3
|
+
|
4
|
+
tests("#all").succeeds do
|
5
|
+
pending if Fog.mocking? && !mocks_implemented
|
6
|
+
connection.flavors.all
|
7
|
+
end
|
8
|
+
|
9
|
+
if !Fog.mocking? || mocks_implemented
|
10
|
+
@identity = connection.flavors.first.identity
|
11
|
+
end
|
12
|
+
|
13
|
+
tests("#get('#{@identity}')").succeeds do
|
14
|
+
pending if Fog.mocking? && !mocks_implemented
|
15
|
+
connection.flavors.get(@identity)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
tests('failure') do
|
21
|
+
|
22
|
+
if !Fog.mocking? || mocks_implemented
|
23
|
+
invalid_flavor_identity = connection.flavors.first.identity.to_s.gsub(/\w/, '0')
|
24
|
+
end
|
25
|
+
|
26
|
+
tests("#get('#{invalid_flavor_identity}')").returns(nil) do
|
27
|
+
pending if Fog.mocking? && !mocks_implemented
|
28
|
+
connection.flavors.get(invalid_flavor_identity)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
def server_tests(connection, params = {}, mocks_implemented = true)
|
2
|
+
model_tests(connection.servers, params, mocks_implemented) do
|
3
|
+
|
4
|
+
tests('#reload').returns(true) do
|
5
|
+
pending if Fog.mocking? && !mocks_implemented
|
6
|
+
@instance.wait_for { ready? }
|
7
|
+
identity = @instance.identity
|
8
|
+
!identity.nil? && identity == @instance.reload.identity
|
9
|
+
end
|
10
|
+
|
11
|
+
responds_to([:ready?, :state])
|
12
|
+
yield if block_given?
|
13
|
+
|
14
|
+
tests('#reboot').succeeds do
|
15
|
+
pending if Fog.mocking? && !mocks_implemented
|
16
|
+
@instance.wait_for { ready? }
|
17
|
+
@instance.reboot
|
18
|
+
end
|
19
|
+
|
20
|
+
if !Fog.mocking? || mocks_implemented
|
21
|
+
@instance.wait_for { ready? }
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require "fog/schema/data_validator"
|
2
|
+
|
3
|
+
# format related hackery
|
4
|
+
# allows both true.is_a?(Fog::Boolean) and false.is_a?(Fog::Boolean)
|
5
|
+
# allows both nil.is_a?(Fog::Nullable::String) and ''.is_a?(Fog::Nullable::String)
|
6
|
+
module Fog
|
7
|
+
module Boolean; end
|
8
|
+
module Nullable
|
9
|
+
module Boolean; end
|
10
|
+
module Integer; end
|
11
|
+
module String; end
|
12
|
+
module Time; end
|
13
|
+
module Float; end
|
14
|
+
module Hash; end
|
15
|
+
module Array; end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
[FalseClass, TrueClass].each {|klass| klass.send(:include, Fog::Boolean)}
|
19
|
+
[FalseClass, TrueClass, NilClass, Fog::Boolean].each {|klass| klass.send(:include, Fog::Nullable::Boolean)}
|
20
|
+
[NilClass, String].each {|klass| klass.send(:include, Fog::Nullable::String)}
|
21
|
+
[NilClass, Time].each {|klass| klass.send(:include, Fog::Nullable::Time)}
|
22
|
+
[Integer, NilClass].each {|klass| klass.send(:include, Fog::Nullable::Integer)}
|
23
|
+
[Float, NilClass].each {|klass| klass.send(:include, Fog::Nullable::Float)}
|
24
|
+
[Hash, NilClass].each {|klass| klass.send(:include, Fog::Nullable::Hash)}
|
25
|
+
[Array, NilClass].each {|klass| klass.send(:include, Fog::Nullable::Array)}
|
26
|
+
|
27
|
+
module Shindo
|
28
|
+
class Tests
|
29
|
+
# Generates a Shindo test that compares a hash schema to the result
|
30
|
+
# of the passed in block returning true if they match.
|
31
|
+
#
|
32
|
+
# The schema that is passed in is a Hash or Array of hashes that
|
33
|
+
# have Classes in place of values. When checking the schema the
|
34
|
+
# value should match the Class.
|
35
|
+
#
|
36
|
+
# Strict mode will fail if the data has additional keys. Setting
|
37
|
+
# +strict+ to +false+ will allow additional keys to appear.
|
38
|
+
#
|
39
|
+
# @param [Hash] schema A Hash schema
|
40
|
+
# @param [Hash] options Options to change validation rules
|
41
|
+
# @option options [Boolean] :allow_extra_keys
|
42
|
+
# If +true+ does not fail when keys are in the data that are
|
43
|
+
# not specified in the schema. This allows new values to
|
44
|
+
# appear in API output without breaking the check.
|
45
|
+
# @option options [Boolean] :allow_optional_rules
|
46
|
+
# If +true+ does not fail if extra keys are in the schema
|
47
|
+
# that do not match the data. Not recommended!
|
48
|
+
# @yield Data to check with schema
|
49
|
+
#
|
50
|
+
# @example Using in a test
|
51
|
+
# Shindo.tests("comparing welcome data against schema") do
|
52
|
+
# data = {:welcome => "Hello" }
|
53
|
+
# data_matches_schema(:welcome => String) { data }
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# comparing welcome data against schema
|
57
|
+
# + data matches schema
|
58
|
+
#
|
59
|
+
# @example Example schema
|
60
|
+
# {
|
61
|
+
# "id" => String,
|
62
|
+
# "ram" => Integer,
|
63
|
+
# "disks" => [
|
64
|
+
# {
|
65
|
+
# "size" => Float
|
66
|
+
# }
|
67
|
+
# ],
|
68
|
+
# "dns_name" => Fog::Nullable::String,
|
69
|
+
# "active" => Fog::Boolean,
|
70
|
+
# "created" => DateTime
|
71
|
+
# }
|
72
|
+
#
|
73
|
+
# @return [Boolean]
|
74
|
+
def data_matches_schema(schema, options = {})
|
75
|
+
test('data matches schema') do
|
76
|
+
validator = Fog::Schema::DataValidator.new
|
77
|
+
valid = validator.validate(yield, schema, options)
|
78
|
+
@message = validator.message unless valid
|
79
|
+
valid
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# @deprecated #formats is deprecated. Use #data_matches_schema instead
|
84
|
+
def formats(format, strict = true)
|
85
|
+
test('has proper format') do
|
86
|
+
if strict
|
87
|
+
options = {:allow_extra_keys => false, :allow_optional_rules => true}
|
88
|
+
else
|
89
|
+
options = {:allow_extra_keys => true, :allow_optional_rules => true}
|
90
|
+
end
|
91
|
+
validator = Fog::Schema::DataValidator.new
|
92
|
+
valid = validator.validate(yield, format, options)
|
93
|
+
@message = validator.message unless valid
|
94
|
+
valid
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|