miasma 0.2.22 → 0.2.24

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c819001bad6e06682bf9a373462a1acf4cf317cb
4
- data.tar.gz: 0d477fdeaba9b395fceea08c51e5230aff885528
3
+ metadata.gz: 9ad1bada860e09a472096990620ec270dbb3e61c
4
+ data.tar.gz: 4ff7b4e6f102527bada9c77eff33b04bf3926ebc
5
5
  SHA512:
6
- metadata.gz: 34e65fa95bfd5f6ad77a4f587dbe006fe38b6cad19bb62541f156b9559f760be6bba9cd442220686925b9dda29d8c4a9003d7c91dfc79d42474968ee617efa41
7
- data.tar.gz: d9f32e1b81c4bc143dd043542be3a66b7dc4957abc8dd18a6bb022be892839e904b84028662c91b1562722e5ba63b82dbe5bffd40c6543e0d44e4c02d3162bae
6
+ metadata.gz: b6d497bf68b667171a443bfab973856aa2fc9b87a48f13e8ab8ae9b26ca43e414f8aa07b5297e86a2060a96a381cba4a17ab398d61ac3e1de0caaced53bc3ea0
7
+ data.tar.gz: d90757a5e25193d975313e72226a0266e210aa615e20dc867a02b44c8d7c7e895bc6a25834f4898487b4e363f4908de7457d508388a5d9312640c14d59b43d3a
@@ -1,3 +1,7 @@
1
+ # v0.2.24
2
+ * Add support for `http_proxy`, `https_proxy`, and `no_proxy` (#11)
3
+ * Use common helper modules for bogo library (#10)
4
+
1
5
  # v0.2.22
2
6
  * Fix lazy attribute loading on subclasses
3
7
 
@@ -1,5 +1,7 @@
1
1
  # Load in dependencies
2
2
  require 'http'
3
+ require 'bogo'
4
+ require 'bogo/http_proxy'
3
5
  require 'multi_json'
4
6
  require 'multi_xml'
5
7
 
@@ -4,25 +4,7 @@ module Miasma
4
4
 
5
5
  module Utils
6
6
  # Animal stylings on strings
7
- module AnimalStrings
8
-
9
- # Camel case string
10
- # @param string [String]
11
- # @return [String]
12
- def camel(string)
13
- string.to_s.split('_').map{|k| "#{k.slice(0,1).upcase}#{k.slice(1,k.length)}"}.join
14
- end
15
-
16
- # Snake case (underscore) string
17
- #
18
- # @param string [String]
19
- # @return [String]
20
- def snake(string)
21
- string.to_s.gsub(/([a-z])([A-Z])/, '\1_\2').gsub('-', '_').downcase
22
- end
23
-
24
- end
25
-
7
+ AnimalStrings = Bogo::AnimalStrings
26
8
  extend AnimalStrings
27
9
  end
28
10
 
@@ -4,233 +4,6 @@ require 'digest/sha2'
4
4
  module Miasma
5
5
  module Utils
6
6
  # Adds functionality to facilitate laziness
7
- module Lazy
8
-
9
- # Instance methods for laziness
10
- module InstanceMethods
11
-
12
- # @return [Smash] argument hash
13
- def data
14
- unless(@data)
15
- @data = Smash.new
16
- end
17
- @data
18
- end
19
-
20
- # @return [Smash] updated data
21
- def dirty
22
- unless(@dirty)
23
- @dirty = Smash.new
24
- end
25
- @dirty
26
- end
27
-
28
- # @return [Smash] current data state
29
- def attributes
30
- data.merge(dirty)
31
- end
32
-
33
- # Create new instance
34
- #
35
- # @param args [Hash]
36
- # @return [self]
37
- def load_data(args={})
38
- args = args.to_smash
39
- @data = Smash.new
40
- self.class.attributes.each do |name, options|
41
- val = args[name]
42
- if(options[:required] && !args.has_key?(name) && !options.has_key?(:default))
43
- raise ArgumentError.new("Missing required option: `#{name}`")
44
- end
45
- if(val.nil? && !args.has_key?(name) && options[:default])
46
- if(options[:default])
47
- val = options[:default].respond_to?(:call) ? options[:default].call : options[:default]
48
- end
49
- end
50
- if(args.has_key?(name) || val)
51
- self.send("#{name}=", val)
52
- end
53
- end
54
- self
55
- end
56
-
57
- # Identifies valid state and automatically
58
- # merges dirty attributes into data, clears
59
- # dirty attributes
60
- #
61
- # @return [self]
62
- def valid_state
63
- data.merge!(dirty)
64
- dirty.clear
65
- @_checksum = Digest::SHA256.hexdigest(MultiJson.dump(data))
66
- self
67
- end
68
-
69
- # Model is dirty or specific attribute is dirty
70
- #
71
- # @param attr [String, Symbol] name of attribute
72
- # @return [TrueClass, FalseClass] model or attribute is dirty
73
- def dirty?(attr=nil)
74
- if(attr)
75
- dirty.has_key?(attr)
76
- else
77
- if(@_checksum)
78
- !dirty.empty? ||
79
- @_checksum != Digest::SHA256.hexdigest(MultiJson.dump(data))
80
- else
81
- true
82
- end
83
- end
84
- end
85
-
86
- # @return [String]
87
- def to_s
88
- "<#{self.class.name}:#{object_id}>"
89
- end
90
-
91
- # @return [String]
92
- def inspect
93
- "<#{self.class.name}:#{object_id} [#{data.inspect}]>"
94
- end
95
-
96
- end
97
-
98
- # Class methods for laziness
99
- module ClassMethods
100
-
101
- # Add new attributes to class
102
- #
103
- # @param name [String]
104
- # @param type [Class, Array<Class>]
105
- # @param options [Hash]
106
- # @option options [TrueClass, FalseClass] :required must be provided on initialization
107
- # @option options [Object, Proc] :default default value
108
- # @option options [Proc] :coerce
109
- # @return [nil]
110
- def attribute(name, type, options={})
111
- name = name.to_sym
112
- options = options.to_smash
113
- attributes[name] = Smash.new(:type => type).merge(options)
114
- coerce = attributes[name][:coerce]
115
- valid_types = [attributes[name][:type], NilClass].flatten.compact
116
- allowed_values = attributes[name][:allowed]
117
- multiple_values = attributes[name][:multiple]
118
- depends_on = attributes[name][:depends]
119
- define_method(name) do
120
- send(depends_on) if depends_on
121
- self.class.on_missing(self) unless data.has_key?(name) || dirty.has_key?(name)
122
- dirty[name] || data[name] || self.class.attributes[name][:default]
123
- end
124
- define_method("#{name}=") do |val|
125
- values = multiple_values && val.is_a?(Array) ? val : [val]
126
- values.map! do |item|
127
- valid_type = valid_types.detect do |klass|
128
- item.is_a?(klass)
129
- end
130
- if(coerce && !valid_type)
131
- item = coerce.arity == 2 ? coerce.call(item, self) : coerce.call(item)
132
- end
133
- valid_type = valid_types.detect do |klass|
134
- item.is_a?(klass)
135
- end
136
- unless(valid_type)
137
- raise TypeError.new("Invalid type for `#{name}` (#{item} <#{item.class}>). Valid - #{valid_types.map(&:to_s).join(',')}")
138
- end
139
- if(allowed_values)
140
- unless(allowed_values.include?(item))
141
- raise ArgumentError.new("Invalid value provided for `#{name}` (#{item.inspect}). Allowed - #{allowed_values.map(&:inspect).join(', ')}")
142
- end
143
- end
144
- item
145
- end
146
- if(!multiple_values && !val.is_a?(Array))
147
- dirty[name] = values.first
148
- else
149
- dirty[name] = values
150
- end
151
- end
152
- define_method("#{name}?") do
153
- send(depends_on) if depends_on
154
- self.class.on_missing(self) unless data.has_key?(name)
155
- !!data[name]
156
- end
157
- nil
158
- end
159
-
160
- # Return attributes
161
- #
162
- # @param args [Symbol] :required or :optional
163
- # @return [Array<Hash>]
164
- def attributes(*args)
165
- @attributes ||= Smash.new
166
- if(args.include?(:required))
167
- Smash[@attributes.find_all{|k,v| v[:required]}]
168
- elsif(args.include?(:optional))
169
- Smash[@attributes.find_all{|k,v| !v[:required]}]
170
- else
171
- @attributes
172
- end
173
- end
174
-
175
- # Instance method to call on missing attribute or
176
- # object to call method on if set
177
- #
178
- # @param param [Symbol, Object]
179
- # @return [Symbol]
180
- def on_missing(param=nil)
181
- if(param)
182
- if(param.is_a?(Symbol))
183
- @missing_method = param
184
- else
185
- if(@missing_method && !@calling_on_missing)
186
- @calling_on_missing = true
187
- begin
188
- param.send(@missing_method)
189
- ensure
190
- @calling_on_missing = false
191
- end
192
- end
193
- @missing_method
194
- end
195
- else
196
- @missing_method
197
- end
198
- end
199
-
200
- # Directly set attribute hash
201
- #
202
- # @param attrs [Hash]
203
- # @return [TrueClass]
204
- # @todo need deep dup here
205
- def set_attributes(attrs)
206
- @attributes = attrs.to_smash
207
- true
208
- end
209
-
210
- end
211
-
212
- class << self
213
-
214
- # Injects laziness into class
215
- #
216
- # @param klass [Class]
217
- def included(klass)
218
- klass.class_eval do
219
- include InstanceMethods
220
- extend ClassMethods
221
-
222
- class << self
223
-
224
- def inherited(klass)
225
- klass.set_attributes(self.attributes.to_smash)
226
- end
227
-
228
- end
229
- end
230
- end
231
-
232
- end
233
-
234
- end
7
+ Lazy = Bogo::Lazy
235
8
  end
236
9
  end
@@ -3,53 +3,6 @@ require 'miasma'
3
3
  module Miasma
4
4
  module Utils
5
5
  # Memoization helpers
6
- module Memoization
7
-
8
- # Memoize data
9
- #
10
- # @param key [String, Symbol] identifier for data
11
- # @param direct [Truthy, Falsey] direct skips key prepend of object id
12
- # @yield block to create data
13
- # @yieldreturn data to memoize
14
- # @return [Object] data
15
- def memoize(key, direct=false)
16
- unless(direct)
17
- key = "#{self.object_id}_#{key}"
18
- end
19
- unless(_memo.has_key?(key))
20
- _memo[key] = yield
21
- end
22
- _memo[key]
23
- end
24
-
25
- def _memo
26
- Thread.current[:miasma_memoization] ||= Smash.new
27
- end
28
-
29
- # Remove memoized value
30
- #
31
- # @param key [String, Symbol] identifier for data
32
- # @param direct [Truthy, Falsey] direct skips key prepend of object id
33
- # @return [NilClass]
34
- def unmemoize(key, direct=false)
35
- unless(direct)
36
- key = "#{self.object_id}_#{key}"
37
- end
38
- _memo.delete(key)
39
- end
40
-
41
- # Remove all memoized values
42
- #
43
- # @return [TrueClass]
44
- def clear_memoizations!
45
- _memo.keys.find_all do |key|
46
- key.to_s.start_with?("#{self.object_id}_")
47
- end.each do |key|
48
- _memo.delete(key)
49
- end
50
- true
51
- end
52
-
53
- end
6
+ Memoization = Bogo::Memoization
54
7
  end
55
8
  end
@@ -1,154 +1,8 @@
1
- require 'hashie'
2
- require 'digest/sha2'
3
1
  require 'miasma'
4
2
 
5
3
  module Miasma
6
4
  module Utils
7
-
8
5
  # Customized Hash
9
- class Smash < Hash
10
- include Hashie::Extensions::IndifferentAccess
11
- include Hashie::Extensions::MergeInitializer
12
- include Hashie::Extensions::DeepMerge
13
- include Hashie::Extensions::Coercion
14
-
15
- coerce_value Hash, Smash
16
-
17
- # Create new instance
18
- #
19
- # @param args [Object] argument list
20
- def initialize(*args)
21
- base = nil
22
- if(args.first.is_a?(::Hash))
23
- base = args.shift
24
- end
25
- super *args
26
- if(base)
27
- self.replace(base.to_smash)
28
- end
29
- end
30
-
31
- def merge!(hash)
32
- hash = hash.to_smash
33
- super(hash)
34
- end
35
-
36
- # Get value at given path
37
- #
38
- # @param args [String, Symbol] key path to walk
39
- # @return [Object, NilClass]
40
- def retrieve(*args)
41
- args.inject(self) do |memo, key|
42
- if(memo.is_a?(Hash))
43
- memo.to_smash[key]
44
- else
45
- nil
46
- end
47
- end
48
- end
49
- alias_method :get, :retrieve
50
-
51
- # Fetch value at given path or return a default value
52
- #
53
- # @param args [String, Symbol, Object] key path to walk. last value default to return
54
- # @return [Object] value at key or default value
55
- def fetch(*args)
56
- default_value = args.pop
57
- retrieve(*args) || default_value
58
- end
59
-
60
- # Set value at given path
61
- #
62
- # @param args [String, Symbol, Object] key path to walk. set last value to given path
63
- # @return [Object] value set
64
- def set(*args)
65
- unless(args.size > 1)
66
- raise ArgumentError.new 'Set requires at least one key and a value'
67
- end
68
- value = args.pop
69
- set_key = args.pop
70
- leaf = args.inject(self) do |memo, key|
71
- unless(memo[key].is_a?(Hash))
72
- memo[key] = Smash.new
73
- end
74
- memo[key]
75
- end
76
- leaf[set_key] = value
77
- value
78
- end
79
-
80
- # Convert to Hash
81
- #
82
- # @return [Hash]
83
- def to_hash(*args)
84
- self.to_type_converter(::Hash, :to_hash, *args)
85
- end
86
-
87
- # Calculate checksum of hash (sha256)
88
- #
89
- # @return [String] checksum
90
- def checksum
91
- Digest::SHA256.hexdigest(self.to_smash(:sorted).to_s)
92
- end
93
-
94
- end
6
+ Smash = Bogo::Smash
95
7
  end
96
-
97
- end
98
-
99
- # Hook helper into toplevel `Hash`
100
- class Hash
101
-
102
- # Convert to Smash
103
- #
104
- # @return [Smash]
105
- def to_smash(*args)
106
- self.to_type_converter(::Smash, :to_smash, *args)
107
- end
108
- alias_method :hulk_smash, :to_smash
109
-
110
- protected
111
-
112
- # Convert to type
113
- #
114
- # @param type [Class] hash type
115
- # @param convert_call [Symbol] builtin hash convert
116
- # @return [Smash]
117
- def to_type_converter(type, convert_call, *args)
118
- type.new.tap do |smash|
119
- if(args.include?(:sorted))
120
- process = self.sort_by do |entry|
121
- entry.first.to_s
122
- end
123
- else
124
- process = self
125
- end
126
- process.each do |k,v|
127
- smash[k.is_a?(Symbol) ? k.to_s : k] = smash_conversion(v, convert_call, *args)
128
- end
129
- end
130
- end
131
-
132
- # Convert object to smash if applicable
133
- #
134
- # @param obj [Object]
135
- # @param convert_call [Symbol] builtin hash convert
136
- # @return [Smash, Object]
137
- def smash_conversion(obj, convert_call, *args)
138
- case obj
139
- when Hash
140
- obj.send(convert_call, *args)
141
- when Array
142
- obj.map do |i|
143
- smash_conversion(i, convert_call, *args)
144
- end
145
- else
146
- obj
147
- end
148
- end
149
-
150
- end
151
-
152
- unless(defined?(Smash))
153
- Smash = Miasma::Utils::Smash
154
8
  end
@@ -1,4 +1,4 @@
1
1
  module Miasma
2
2
  # current library version
3
- VERSION = Gem::Version.new('0.2.22')
3
+ VERSION = Gem::Version.new('0.2.24')
4
4
  end
@@ -10,11 +10,11 @@ Gem::Specification.new do |s|
10
10
  s.description = 'Smoggy API'
11
11
  s.license = 'Apache 2.0'
12
12
  s.require_path = 'lib'
13
- s.add_runtime_dependency 'hashie'
14
13
  s.add_runtime_dependency 'http'
15
14
  s.add_runtime_dependency 'multi_json'
16
15
  s.add_runtime_dependency 'multi_xml'
17
16
  s.add_runtime_dependency 'xml-simple'
17
+ s.add_runtime_dependency 'bogo', '>= 0.1.20', '< 1.0'
18
18
  # Include provider libs that do not have outside deps
19
19
  s.add_runtime_dependency 'miasma-aws'
20
20
  s.add_runtime_dependency 'miasma-open-stack'
@@ -25,5 +25,5 @@ Gem::Specification.new do |s|
25
25
  s.add_development_dependency 'minitest'
26
26
  s.add_development_dependency 'vcr'
27
27
  s.add_development_dependency 'webmock'
28
- s.files = Dir['{bin,lib,test}/**/*'] + %w(miasma.gemspec README.md CHANGELOG.md LICENSE)
28
+ s.files = Dir['{bin,lib}/**/*'] + %w(miasma.gemspec README.md CHANGELOG.md LICENSE)
29
29
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: miasma
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.22
4
+ version: 0.2.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Roberts
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-23 00:00:00.000000000 Z
11
+ date: 2015-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: hashie
14
+ name: http
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: http
28
+ name: multi_json
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: multi_json
42
+ name: multi_xml
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: multi_xml
56
+ name: xml-simple
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,19 +67,25 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: xml-simple
70
+ name: bogo
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: 0.1.20
76
+ - - "<"
77
+ - !ruby/object:Gem::Version
78
+ version: '1.0'
76
79
  type: :runtime
77
80
  prerelease: false
78
81
  version_requirements: !ruby/object:Gem::Requirement
79
82
  requirements:
80
83
  - - ">="
81
84
  - !ruby/object:Gem::Version
82
- version: '0'
85
+ version: 0.1.20
86
+ - - "<"
87
+ - !ruby/object:Gem::Version
88
+ version: '1.0'
83
89
  - !ruby/object:Gem::Dependency
84
90
  name: miasma-aws
85
91
  requirement: !ruby/object:Gem::Requirement
@@ -231,15 +237,6 @@ files:
231
237
  - lib/miasma/utils/smash.rb
232
238
  - lib/miasma/version.rb
233
239
  - miasma.gemspec
234
- - test/spec.rb
235
- - test/specs/miasma_spec.rb
236
- - test/specs/models/compute_abstract.rb
237
- - test/specs/models/load_balancer_abstract.rb
238
- - test/specs/models/orchestration_abstract.rb
239
- - test/specs/models/storage_abstract.rb
240
- - test/specs/utils/animal_strings_spec.rb
241
- - test/specs/utils/memoization_spec.rb
242
- - test/specs/utils/smash_spec.rb
243
240
  homepage: https://github.com/miasma-rb/miasma
244
241
  licenses:
245
242
  - Apache 2.0
@@ -1,20 +0,0 @@
1
- require 'vcr'
2
- require 'webmock/minitest'
3
- require 'minitest/autorun'
4
-
5
- require 'miasma'
6
-
7
- spec_dir = File.join(File.dirname(__FILE__), 'specs')
8
-
9
- Dir.glob(File.join(spec_dir, 'models', '*.rb')).each do |path|
10
- require File.expand_path(path)
11
- end
12
-
13
- Dir.glob(File.join(spec_dir, '**/**/*_spec.rb')).each do |path|
14
- require File.expand_path(path)
15
- end
16
-
17
- VCR.configure do |c|
18
- c.cassette_library_dir = File.join(spec_dir, 'cassettes')
19
- c.hook_into :webmock
20
- end
@@ -1,33 +0,0 @@
1
- describe Miasma do
2
- it 'should provide an #api entry method' do
3
- Miasma.respond_to?(:api).must_equal true
4
- end
5
-
6
- describe 'Miasma.api' do
7
-
8
- it 'should require `:type` argument' do
9
- lambda do
10
- Miasma.api(:provider => '', :credentials => {})
11
- end.must_raise ArgumentError
12
- end
13
-
14
- it 'should require `:provider` argument' do
15
- lambda do
16
- Miasma.api(:type => '', :credentials => {})
17
- end.must_raise ArgumentError
18
- end
19
-
20
- it 'should require `:credentials` argument' do
21
- lambda do
22
- Miasma.api(:provider => '', :type => '')
23
- end.must_raise ArgumentError
24
- end
25
-
26
- it 'should fail to load unknown provider' do
27
- lambda do
28
- Miasma.api(:provider => :unknown, :type => :compute, :credentials => {})
29
- end.must_raise Miasma::Error
30
- end
31
-
32
- end
33
- end
@@ -1,118 +0,0 @@
1
- MIASMA_COMPUTE_ABSTRACT = ->{
2
-
3
- # Required `let`s:
4
- # * compute: compute API
5
- # * build_args: server build arguments [Smash]
6
- # * cassette_prefix: cassette file prefix [String]
7
-
8
- describe Miasma::Models::Compute do
9
-
10
- it 'should provide #servers collection' do
11
- compute.servers.must_be_kind_of Miasma::Models::Compute::Servers
12
- end
13
-
14
- describe Miasma::Models::Compute::Servers do
15
-
16
- it 'should provide instance class used within collection' do
17
- compute.servers.model.must_equal Miasma::Models::Compute::Server
18
- end
19
-
20
- it 'should build new instance for collection' do
21
- instance = compute.servers.build(:name => 'test')
22
- instance.must_be_kind_of Miasma::Models::Compute::Server
23
- end
24
-
25
- it 'should provide #all servers' do
26
- VCR.use_cassette("#{cassette_prefix}_servers_all") do
27
- compute.servers.all.must_be_kind_of Array
28
- end
29
- end
30
-
31
- end
32
-
33
- describe Miasma::Models::Compute::Server do
34
-
35
- before do
36
- @instance = compute.servers.build(build_args)
37
- VCR.use_cassette("#{cassette_prefix}_server_before_create") do |obj|
38
- @instance.save
39
- until(@instance.state == :running)
40
- sleep(obj.recording? ? 60 : 0.01)
41
- @instance.reload
42
- end
43
- end
44
- end
45
-
46
- after do
47
- VCR.use_cassette("#{cassette_prefix}_server_after_destroy") do
48
- @instance.destroy
49
- end
50
- end
51
-
52
- let(:instance){ @instance }
53
-
54
- describe 'instance methods' do
55
-
56
- it 'should have a name' do
57
- instance.name.must_equal build_args[:name]
58
- end
59
-
60
- it 'should have an image_id' do
61
- instance.image_id.must_equal build_args[:image_id]
62
- end
63
-
64
- it 'should have a flavor_id' do
65
- instance.flavor_id.must_equal build_args[:flavor_id]
66
- end
67
-
68
- it 'should have an address' do
69
- instance.addresses.detect do |addr|
70
- addr.version == 4
71
- end.address.must_match /^(\d+)+\.(\d+)\.(\d+)\.(\d+)$/
72
- end
73
-
74
- it 'should have a status' do
75
- instance.status.wont_be_nil
76
- end
77
-
78
- it 'should be in :running state' do
79
- instance.state.must_equal :running
80
- end
81
-
82
- end
83
-
84
- end
85
-
86
- describe 'instance lifecycle' do
87
- it 'should create new server, reload details and destroy server' do
88
- VCR.use_cassette("#{cassette_prefix}_servers_create") do |obj|
89
- instance = compute.servers.build(build_args)
90
- instance.save
91
- instance.id.wont_be_nil
92
- instance.state.must_equal :pending
93
- compute.servers.reload.get(instance.id).wont_be_nil
94
- until(instance.state == :running)
95
- sleep(obj.recording? ? 60 : 0.01)
96
- instance.reload
97
- end
98
- instance.state.must_equal :running
99
- instance.destroy
100
- while(instance.state == :running)
101
- sleep(obj.recording? ? 10 : 0.01)
102
- instance.reload
103
- end
104
- [:pending, :terminated].must_include instance.state
105
- if(instance.state == :pending)
106
- until(instance.state == :terminated)
107
- sleep(obj.recording? ? 60 : 0.01)
108
- instance.reload
109
- end
110
- instance.state.must_equal :terminated
111
- end
112
- end
113
- end
114
-
115
- end
116
-
117
- end
118
- }
@@ -1,88 +0,0 @@
1
- MIASMA_LOAD_BALANCER_ABSTRACT = ->{
2
-
3
- # Required `let`s:
4
- # * load_balancer: load balancer API
5
- # * build_args: load balancer build arguments [Smash]
6
- # * cassette_prefix: cassette file prefix [String]
7
-
8
- describe Miasma::Models::LoadBalancer do
9
-
10
- it 'should provide #balancers collection' do
11
- load_balancer.balancers.must_be_kind_of Miasma::Models::LoadBalancer::Balancers
12
- end
13
-
14
- describe Miasma::Models::LoadBalancer::Balancers do
15
-
16
- it 'should provide instance class used within collection' do
17
- load_balancer.balancers.model.must_equal Miasma::Models::LoadBalancer::Balancer
18
- end
19
-
20
- it 'should build new instance for collection' do
21
- instance = load_balancer.balancers.build
22
- instance.must_be_kind_of Miasma::Models::LoadBalancer::Balancer
23
- end
24
-
25
- it 'should provide #all balancers' do
26
- VCR.use_cassette("#{cassette_prefix}_balancers_all") do
27
- load_balancer.balancers.all.must_be_kind_of Array
28
- end
29
- end
30
-
31
- end
32
-
33
- describe Miasma::Models::LoadBalancer::Balancer do
34
-
35
- before do
36
- @balancer = load_balancer.balancers.build(build_args)
37
- VCR.use_cassette("#{cassette_prefix}_balancer_before_create") do |obj|
38
- @balancer.save
39
- until(@balancer.state == :active)
40
- sleep(obj.recording? ? 60 : 0.01)
41
- @balancer.reload
42
- end
43
- end
44
- end
45
-
46
- after do
47
- VCR.use_cassette("#{cassette_prefix}_balancer_after_destroy") do
48
- @balancer.destroy
49
- end
50
- end
51
-
52
- let(:balancer){ @balancer }
53
-
54
- describe 'collection' do
55
-
56
- it 'should include balancer' do
57
- VCR.use_cassette("#{cassette_prefix}_balancer_direct_fetch") do
58
- load_balancer.balancers.reload.get(balancer.id).wont_be_nil
59
- end
60
- end
61
-
62
- end
63
-
64
- describe 'balancer methods' do
65
-
66
- it 'should have a name' do
67
- balancer.name.must_equal build_args[:name]
68
- end
69
-
70
- it 'should be in :active state' do
71
- balancer.state.must_equal :active
72
- end
73
-
74
- it 'should have a status' do
75
- balancer.status.wont_be_nil
76
- balancer.status.must_be_kind_of String
77
- end
78
-
79
- it 'should have a public address' do
80
- balancer.public_addresses.wont_be :empty?
81
- end
82
-
83
- end
84
-
85
- end
86
-
87
- end
88
- }
@@ -1,123 +0,0 @@
1
- MIASMA_ORCHESTRATION_ABSTRACT = ->{
2
-
3
- # Required `let`s:
4
- # * orchestration: orchestration API
5
- # * build_args: stack build arguments [Smash]
6
- # * cassette_prefix: cassette file prefix [String]
7
-
8
- describe Miasma::Models::Orchestration do
9
-
10
- it 'should provide #stacks collection' do
11
- orchestration.stacks.must_be_kind_of Miasma::Models::Orchestration::Stacks
12
- end
13
-
14
- describe Miasma::Models::Orchestration::Stacks do
15
-
16
- it 'should provide instance class used within collection' do
17
- orchestration.stacks.model.must_equal Miasma::Models::Orchestration::Stack
18
- end
19
-
20
- it 'should build new instance for collection' do
21
- instance = orchestration.stacks.build
22
- instance.must_be_kind_of Miasma::Models::Orchestration::Stack
23
- end
24
-
25
- it 'should provide #all stacks' do
26
- VCR.use_cassette("#{cassette_prefix}_stacks_all") do
27
- orchestration.stacks.all.must_be_kind_of Array
28
- end
29
- end
30
-
31
- end
32
-
33
- describe Miasma::Models::Orchestration::Stacks do
34
-
35
- before do
36
- @stack = orchestration.stacks.build(build_args)
37
- VCR.use_cassette("#{cassette_prefix}_stacks_before_create") do |obj|
38
- @stack.save
39
- until(@stack.state == :create_complete)
40
- sleep(obj.recording? ? 60 : 0.01)
41
- @stack.reload
42
- end
43
- @stack.template
44
- orchestration.stacks.reload
45
- end
46
- end
47
-
48
- after do
49
- VCR.use_cassette("#{cassette_prefix}_stacks_after_destroy") do
50
- @stack.destroy
51
- end
52
- end
53
-
54
- let(:stack){ @stack }
55
-
56
- describe 'collection' do
57
-
58
- it 'should include stack' do
59
- VCR.use_cassette("#{cassette_prefix}_stacks_direct_fetch") do
60
- orchestration.stacks.all.detect{|s| s.id == stack.id}.wont_be_nil
61
- orchestration.stacks.get(stack.id).wont_be_nil
62
- end
63
- end
64
-
65
- end
66
-
67
- describe 'instance methods' do
68
-
69
- it 'should have a name' do
70
- stack.name.must_equal build_args[:name]
71
- end
72
-
73
- it 'should be in :create_complete state' do
74
- stack.state.must_equal :create_complete
75
- end
76
-
77
- it 'should have a status' do
78
- stack.status.must_be_kind_of String
79
- end
80
-
81
- it 'should have a creation time' do
82
- stack.created.must_be_kind_of Time
83
- end
84
-
85
- it 'should have parameters used for creation' do
86
- stack.parameters.to_smash.must_equal build_args[:parameters].to_smash
87
- end
88
-
89
- it 'should include the templated used for creation' do
90
- stack.template.to_smash.must_equal build_args[:template].to_smash
91
- end
92
-
93
- end
94
-
95
- end
96
-
97
- describe 'instance lifecycle' do
98
- it 'should create new stack, reload details and destroy stack' do
99
- VCR.use_cassette("#{cassette_prefix}_stack_create") do |obj|
100
- stack = orchestration.stacks.build(build_args.merge(:name => 'miasma-test-stack-2'))
101
- stack.save
102
- stack.id.wont_be_nil
103
- stack.state.must_equal :create_in_progress
104
- orchestration.stacks.reload.get(stack.id).wont_be_nil
105
- until(stack.state == :create_complete)
106
- sleep(obj.recording? ? 60 : 0.01)
107
- stack.reload
108
- end
109
- stack.state.must_equal :create_complete
110
- stack.destroy
111
- [:delete_in_progress, :delete_complete].must_include stack.state
112
- until(stack.state == :delete_complete)
113
- sleep(obj.recording? ? 60 : 0.01)
114
- stack.reload
115
- end
116
- stack.state.must_equal :delete_complete
117
- end
118
- end
119
-
120
- end
121
-
122
- end
123
- }
@@ -1,120 +0,0 @@
1
- require 'open-uri'
2
-
3
- MIASMA_STORAGE_ABSTRACT = ->{
4
-
5
- # Required `let`s:
6
- # * storage: storage API
7
- # * cassette_prefix: cassette file prefix [String]
8
-
9
- describe Miasma::Models::Storage do
10
-
11
- it 'should provide #buckets collection' do
12
- storage.buckets.must_be_kind_of Miasma::Models::Storage::Buckets
13
- end
14
-
15
- describe Miasma::Models::Storage::Buckets do
16
-
17
- it 'should provide instance class used within collection' do
18
- storage.buckets.model.must_equal Miasma::Models::Storage::Bucket
19
- end
20
-
21
- it 'should build new instance for collection' do
22
- storage.buckets.build.must_be_kind_of Miasma::Models::Storage::Bucket
23
- end
24
-
25
- it 'should provide #all buckets' do
26
- VCR.use_cassette("#{cassette_prefix}_buckets_all") do
27
- storage.buckets.all.must_be_kind_of Array
28
- end
29
- end
30
-
31
- end
32
-
33
- describe Miasma::Models::Storage::Bucket do
34
-
35
- it 'should act like a bucket' do
36
- bucket = storage.buckets.build(:name => 'miasma-test-bucket-010')
37
- VCR.use_cassette("#{cassette_prefix}_storage_bucket") do |obj|
38
- bucket.save
39
- bucket.reload
40
-
41
- # should include the bucket
42
- storage.buckets.reload.get('miasma-test-bucket-010').wont_be_nil
43
- # should have a name
44
- bucket.name.must_equal 'miasma-test-bucket-010'
45
- # should have a #files collection
46
- bucket.files.must_be_kind_of Miasma::Models::Storage::Files
47
- #should provide #all files
48
- bucket.files.all.must_be_kind_of Array
49
- # should include reference to containing bucket
50
- bucket.files.bucket.must_equal bucket
51
- # should build new instance for collection
52
- bucket.files.build.must_be_kind_of Miasma::Models::Storage::File
53
-
54
- file_content = 'blahblahblah'
55
- file = bucket.files.build
56
- file.name = 'miasma-test-file'
57
- file.body = file_content
58
- file.save
59
- file.reload
60
-
61
- # should have a name
62
- file.name.must_equal 'miasma-test-file'
63
- # should have a size
64
- file.size.must_equal file_content.size
65
- # should have an updated timestamp
66
- file.updated.must_be_kind_of Time
67
- # should create a valid url
68
- open(file.url).read.must_equal file_content
69
- # should have a body
70
- file.body.must_respond_to :readpartial
71
- file.body.readpartial(Miasma::Models::Storage::READ_BODY_CHUNK_SIZE).must_equal file_content
72
- file.destroy
73
-
74
- big_file_content = '*' * Miasma::Models::Storage::MAX_BODY_SIZE_FOR_STRINGIFY
75
- big_file = bucket.files.build
76
- big_file.name = 'miasma-test-file-big'
77
- big_file.body = big_file_content
78
- big_file.save
79
- big_file.reload
80
-
81
- # should be the correct size
82
- big_file.size.must_equal big_file.size
83
- # should provide streaming body
84
- big_file.body.must_respond_to :readpartial
85
- content = big_file.body.readpartial(big_file.size)
86
- content.must_equal big_file_content
87
- big_file.destroy
88
-
89
- require 'tempfile'
90
- local_io_file = Tempfile.new('miasma-storage-test')
91
- big_io_content = '*' * (Miasma::Models::Storage::MAX_BODY_SIZE_FOR_STRINGIFY * 2)
92
- local_io_file.write big_io_content
93
- local_io_file.flush
94
- local_io_file.rewind
95
- remote_file = bucket.files.build
96
- remote_file.name = 'miasma-test-io-object-010'
97
- remote_file.body = local_io_file
98
- remote_file.save
99
- remote_file.reload
100
-
101
- # should be the correct size
102
- remote_file.size.must_equal local_io_file.size
103
- # should provide streaming body
104
- remote_file.body.must_respond_to :readpartial
105
- content = ''
106
- while(chunk = remote_file.body.readpartial(1024))
107
- content << chunk
108
- end
109
- content.must_equal big_io_content
110
- remote_file.destroy
111
- bucket.destroy
112
- end
113
-
114
- end
115
-
116
-
117
- end
118
-
119
- end
120
- }
@@ -1,15 +0,0 @@
1
- describe Miasma::Utils::AnimalStrings do
2
-
3
- it 'should camel case strings' do
4
- Miasma::Utils.camel('fubar_foobar_fuobar').must_equal 'FubarFoobarFuobar'
5
- end
6
-
7
- it 'should camel case symbols' do
8
- Miasma::Utils.camel(:fubar_foobar_fuobar).must_equal 'FubarFoobarFuobar'
9
- end
10
-
11
- it 'should snake case strings' do
12
- Miasma::Utils.snake('FubarFoobarFuobar').must_equal 'fubar_foobar_fuobar'
13
- end
14
-
15
- end
@@ -1,83 +0,0 @@
1
- describe Miasma::Utils::Memoization do
2
-
3
- before do
4
- @memo = Object.new
5
- @memo.extend Miasma::Utils::Memoization
6
- end
7
-
8
- after do
9
- Thread.current[:miasma_memoization] = nil
10
- end
11
-
12
- let(:memo){ @memo }
13
-
14
- it 'should #memoize the value returned by block' do
15
- value = Kernel.rand
16
- memo.memoize(:test) do
17
- value
18
- end.must_equal value
19
- memo.memoize(:test){ Kernel.rand }.must_equal value
20
- end
21
-
22
- it 'should not return #memoize value from other instance' do
23
- memo2 = Object.new
24
- memo2.extend Miasma::Utils::Memoization
25
- value = Kernel.rand
26
- memo.memoize(:test) do
27
- value
28
- end.must_equal value
29
- memo.memoize(:test){ Kernel.rand }.must_equal value
30
- memo2.memoize(:test){ Kernel.rand }.wont_equal value
31
- end
32
-
33
- it 'should #unmemoize a memoized value' do
34
- value = Kernel.rand
35
- value2 = Kernel.rand
36
- memo.memoize(:test) do
37
- value
38
- end.must_equal value
39
- memo.unmemoize(:test)
40
- memo.memoize(:test) do
41
- value2
42
- end.must_equal value2
43
- end
44
-
45
- it 'should allow direct #memoize not restricted to object' do
46
- memo2 = Object.new
47
- memo2.extend Miasma::Utils::Memoization
48
- value = Kernel.rand
49
- memo.memoize(:test, true) do
50
- value
51
- end.must_equal value
52
- memo.memoize(:test, true){ Kernel.rand }.must_equal value
53
- memo2.memoize(:test, true){ Kernal.rand }.must_equal value
54
- end
55
-
56
- it 'should clear all non-direct memoizations with #clear_memoizations!' do
57
- memo2 = Object.new
58
- memo2.extend Miasma::Utils::Memoization
59
- value = Kernel.rand
60
- memo.memoize(:test, true) do
61
- value
62
- end.must_equal value
63
- memo.memoize(:test){ value }.must_equal value
64
- memo2.memoize(:test){ value }.must_equal value
65
-
66
- memo.memoize(:test, true){ Kernel.rand }.must_equal value
67
- memo2.memoize(:test, true){ Kernel.rand }.must_equal value
68
- memo.memoize(:test){ Kernel.rand }.must_equal value
69
- memo2.memoize(:test){ Kernel.rand }.must_equal value
70
-
71
- memo.clear_memoizations!
72
- memo.memoize(:test){ Kernel.rand }.wont_equal value
73
- memo2.memoize(:test){ Kernel.rand }.must_equal value
74
-
75
- memo2.clear_memoizations!
76
- memo.memoize(:test){ Kernel.rand }.wont_equal value
77
- memo2.memoize(:test){ Kernel.rand }.wont_equal value
78
-
79
- memo.memoize(:test, true){ Kernel.rand }.must_equal value
80
- memo2.memoize(:test, true){ Kernel.rand }.must_equal value
81
- end
82
-
83
- end
@@ -1,107 +0,0 @@
1
- describe Miasma::Utils::Smash do
2
-
3
- it 'should provide top level constant' do
4
- defined?(::Smash).wont_be_nil
5
- end
6
-
7
- it 'should provide #to_smash on Hash' do
8
- Hash.instance_methods.must_include :to_smash
9
- end
10
-
11
- it 'should convert Hash to Smash' do
12
- {:a => 1}.to_smash.must_equal Smash.new(:a => 1)
13
- end
14
-
15
- it 'should sort keys when converting' do
16
- hash = {:z => 1, :d => 3, :m => 1}
17
- smash = Smash.new(:d => 3, :m => 1, :z => 1)
18
- hash.to_smash.must_equal smash
19
- end
20
-
21
- it 'should convert deep nested Hashes to Smashes' do
22
- hash = {
23
- :a => 1,
24
- :b => [
25
- {:c => 2},
26
- {:d => 3}
27
- ]
28
- }
29
- smash = Smash.new(
30
- :a => 1,
31
- :b => [
32
- Smash.new(:c => 2),
33
- Smash.new(:d => 3)
34
- ]
35
- )
36
- hash.to_smash.must_equal smash
37
- end
38
-
39
- it 'should #get deeply nested value' do
40
- smash = {
41
- :a => {
42
- :b => {
43
- :c => {
44
- :d => 1
45
- }
46
- }
47
- }
48
- }.to_smash
49
- smash.get(:a, :b, :c, :d).must_equal 1
50
- end
51
-
52
- it 'should #get nil on missing deeply nested value' do
53
- smash = {
54
- :a => {
55
- :b => {
56
- :c => {
57
- :d => 1
58
- }
59
- }
60
- }
61
- }.to_smash
62
- smash.get(:a, :b, :c, :x).must_be_nil
63
- end
64
-
65
- it 'should #set deeply nested value' do
66
- smash = Smash.new
67
- smash.set(:a, :b, :c, 1)
68
- smash.get(:a, :b, :c).must_equal 1
69
- end
70
-
71
- it 'should #fetch default value on missing' do
72
- smash = {
73
- :a => {
74
- :b => {
75
- :c => {
76
- :d => 1
77
- }
78
- }
79
- }
80
- }.to_smash
81
- smash.fetch(:a, :b, :c, :x, 1).must_equal 1
82
- end
83
-
84
- it 'should #fetch value when availble' do
85
- smash = {
86
- :a => {
87
- :b => {
88
- :c => {
89
- :d => 1
90
- }
91
- }
92
- }
93
- }.to_smash
94
- smash.fetch(:a, :b, :c, :d, 0).must_equal 1
95
- end
96
-
97
- it 'should generate a #checksum' do
98
- Smash.new(:a => 1).checksum.must_be_kind_of String
99
- end
100
-
101
- it 'should generate equal #checksum' do
102
- hash = {:z => 1, :d => 3}
103
- smash = Smash.new(:d => 3, :z => 1)
104
- hash.to_smash.checksum.must_equal smash.checksum
105
- end
106
-
107
- end