deltadsl 1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,92 @@
1
+ Deltacloud API client DSL
2
+ -------------------------
3
+
4
+ Documentation
5
+
6
+ <a href="http://rdoc.info/github/mifo/deltadsl/master/frames">rdoc.info/github/mifo/deltadsl/master/frames</a>
7
+
8
+ Installation:
9
+
10
+ * No installation available yet ;-)
11
+
12
+ Prerequires:
13
+
14
+ * Deltacloud API server and client gems installed:
15
+
16
+ $ gem install deltacloud-core deltacloud-client
17
+
18
+ * Eventmachine (gem install eventmachine)
19
+ * Thin (gem install thin)
20
+
21
+ Examples
22
+ -------------------------
23
+
24
+ Simple scenario:
25
+
26
+ <script src="https://gist.github.com/1933563.js?file=dsl_sample.rb"></script>
27
+
28
+ @sample = Deltacloud::DSL::Task('launch some EC2 and RHEV-M instances') do
29
+
30
+ instances(:driver => :ec2, :username => '', :password => '') do
31
+ instance 'test-ec2-1' do
32
+ realm 'us-west-1'
33
+ image 'ami-12345'
34
+ profile 't1.micro'
35
+ end
36
+
37
+ instance 'test-ec2-2' do
38
+ realm 'us-west-1'
39
+ image 'ami-54321'
40
+ profile 't1.micro'
41
+ end
42
+ end
43
+
44
+ instances(:driver => :rhevm, :username => '', :password => '', :provider => '') do
45
+ instance 'test-rhev-1' do
46
+ image '12345-12345-12345-12345'
47
+ profile 'SERVER' do |p|
48
+ p.memory = 512
49
+ p.cpu = 4
50
+ end
51
+ end
52
+ end
53
+
54
+ on(:instance_started) do |i|
55
+ # i.pool_for_ssh ??
56
+ end
57
+
58
+ on(:running) do
59
+ ec2_instance('test-ec2-1') do |i|
60
+ # do something with this instance
61
+ end
62
+
63
+ rhevm_instance('test-rhev-1') do |i|
64
+ # Do someting ;-)
65
+ end
66
+ end
67
+ end
68
+
69
+ # Thing above is just an definition, so now let start it:
70
+
71
+ @sample.start!
72
+
73
+ # All instances will be started in parallel (using threads)
74
+
75
+
76
+ License
77
+ -----------------
78
+
79
+ Licensed to the Apache Software Foundation (ASF) under one or more
80
+ contributor license agreements. See the NOTICE file distributed with
81
+ this work for additional information regarding copyright ownership. The
82
+ ASF licenses this file to you under the Apache License, Version 2.0 (the
83
+ "License"); you may not use this file except in compliance with the
84
+ License. You may obtain a copy of the License at
85
+
86
+ http://www.apache.org/licenses/LICENSE-2.0
87
+
88
+ Unless required by applicable law or agreed to in writing, software
89
+ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
90
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
91
+ License for the specific language governing permissions and limitations
92
+ under the License.
@@ -0,0 +1,17 @@
1
+ require 'deltacloud'
2
+
3
+ module Deltacloud
4
+
5
+ def self.Client(d)
6
+ config = {
7
+ :driver => d.configuration.driver || :mock,
8
+ :username => d.configuration.user || 'mockuser',
9
+ :password => d.configuration.password || 'mockpassword',
10
+ }
11
+ config.merge!({
12
+ :provider => d.configuration.provider
13
+ }) unless d.configuration.provider.nil?
14
+ DeltaCloud::API.new(nil, nil, d.configuration.url || 'http://localhost:3001/api').with_config(config)
15
+ end
16
+
17
+ end
@@ -0,0 +1,21 @@
1
+ module Deltacloud
2
+ module DSL
3
+
4
+ def self.Task(name, &block)
5
+ Task.new(name, &block)
6
+ end
7
+
8
+ def self.Instance(name, &block)
9
+ Instance.new(name, &block) if block_given?
10
+ end
11
+
12
+ def self.Configuration(params={})
13
+ InstanceConfiguration.new(params)
14
+ end
15
+
16
+ def self.Instances(configuration={}, &block)
17
+ InstanceDefinition.new(configuration, &block) if block_given?
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,194 @@
1
+ module Deltacloud
2
+ module DSL
3
+
4
+ class Instance
5
+
6
+ include EM::Deferrable
7
+
8
+ attr_reader :name
9
+ attr_reader :parameters
10
+
11
+ def initialize(name, &block)
12
+ @name = name
13
+ @parameters = {
14
+ :state => :new
15
+ }
16
+ instance_eval(&block) if block_given?
17
+ warn "WARNING: Realm is not defined for instance '#{name}'. (Default driver realm will be used)." if params.realm_id.nil?
18
+ raise "Image is not defined for instance '#{@name}'" if params.image_id.nil?
19
+ raise "Profile is not defined for instance '#{@name}'" if params.profile.nil?
20
+ end
21
+
22
+ # Make call to Deltacloud to create this instance object
23
+ # Please note that this call will put the instance into
24
+ # PENDING state in most cases (except Mock).
25
+ #
26
+ # Use .wait_for_running! to pool Deltacloud until instance
27
+ # is not RUNNING
28
+ #
29
+ def create(definition)
30
+ @client = Deltacloud::Client(@definition = definition)
31
+ instance_opts = {
32
+ :name => self.name
33
+ }
34
+ instance_opts.merge!(profile.to_instance_params)
35
+ instance_opts.merge!({
36
+ :realm_id => instance_realm_id,
37
+ })
38
+ from_instance!(@client.create_instance(instance_image_id, instance_opts))
39
+ self
40
+ end
41
+
42
+ # Pool Deltacloud API for the state change of instance every 5 seconds.
43
+ # This will block program execution for time needed to transient from
44
+ #
45
+
46
+ %w(running stopped pending).each do |state|
47
+ define_method :"wait_for_#{state}!" do |*max_retries|
48
+ retries = 0
49
+ return if state_is?(state)
50
+ begin
51
+ update!
52
+ # Some Deltacloud drivers (like RHEV-M) put instance to STOPPED state
53
+ # instead of RUNNING. Is not an error, but backend cloud behavior.
54
+ # If instance transient to STOPPED, then we try to START it without
55
+ # incrementing retry counter.
56
+ if state == 'running' and is_stopped?
57
+ start!
58
+ raise 'NotRunning'
59
+ else
60
+ retries += 1
61
+ raise 'NotInState' if (!state_is?(state)) && sleep(5)
62
+ end
63
+ rescue => e
64
+ retry if (e.message == 'NotInState') && (retries <= max_retries.first)
65
+ raise "Failed to put instance '#{self.name}' in #{state} state."
66
+ end
67
+ end
68
+ end
69
+
70
+ # This method will try to connect to Deltacloud API and refresh all attributes
71
+ #
72
+ def update!
73
+ raise 'Instance must be created first in order to call update' if @definition.nil?
74
+ from_instance!(@client.instance(params.instance_id))
75
+ end
76
+
77
+ # Instance actions:
78
+ #
79
+ # instance.start! will start stopped instance (if supported)
80
+ # instance.stop! will stop running instance (if supported)
81
+ # instance.destroy! will destroy instance and set state to ':destroyed'
82
+ #
83
+ %w(start stop destroy).each do |action|
84
+ define_method :"#{action}!" do
85
+ instance_action(action.intern)
86
+ end
87
+ end
88
+
89
+ # Helper for instance actions
90
+ #
91
+ def instance_action(action)
92
+ must_have_definition!
93
+ @client.instance(params.instance_id).send(:"#{action}!")
94
+ instance = @client.instance(params.instance_id)
95
+ if instance.nil?
96
+ @parameters[:state] = :destroyed
97
+ @parameters.delete(:instance_id)
98
+ self
99
+ else
100
+ from_instance!(instance)
101
+ end
102
+ end
103
+
104
+ # Convert attributes from DeltaCloud::Instance object to Instance
105
+ #
106
+ def from_instance!(instance)
107
+ attrs = {
108
+ :instance_id => instance.id,
109
+ :state => instance.state.downcase.intern,
110
+ :public_addresses => instance.public_addresses,
111
+ :private_addresses => instance.private_addresses
112
+ }
113
+ attrs.merge!(:owner_id => instance.owner_id)
114
+ @parameters.merge!(attrs)
115
+ self
116
+ end
117
+
118
+ # Assing InstanceProfile to the instance.
119
+ # If no profile name is provided, will return the active profile
120
+ #
121
+ # InstanceProfile DSL example:
122
+ #
123
+ # instance 'test-instance' do
124
+ # profile 'm1-small' do |p|
125
+ # p.memory = 500
126
+ # end
127
+ # end
128
+ #
129
+ def profile(name=nil, &block)
130
+ if name
131
+ @parameters[:profile] = Deltacloud::DSL::InstanceProfile(name, &block)
132
+ else
133
+ instance_profile
134
+ end
135
+ end
136
+
137
+ # Convert instance param hash to OpenStruct object for easy retrieval
138
+ #
139
+ def params
140
+ Deltacloud::DSL::Configuration(@parameters)
141
+ end
142
+
143
+ # Define various helper methods:
144
+ #
145
+ # instance_[attribute] -> retrieve instance attribute (instance_state,
146
+ # instance_public_addresses, etc...)
147
+ # is_[state]? -> true if instance is in given state
148
+ # is_not_[state]? -> same as above just negated
149
+ #
150
+ # Whatever else method is called on this object with some parameters,
151
+ # this method will automatically be transformed to instance variable.
152
+ #
153
+ def method_missing(name, *args)
154
+ if name.to_s =~ /^instance_([\w_]+)$/
155
+ @parameters[$1.intern]
156
+ elsif name.to_s =~ /^is_(\w+)\?$/
157
+ state_is?($1.intern)
158
+ elsif name.to_s =~ /^is_not_(\w+)\?$/
159
+ !state_is?($1.intern)
160
+ elsif !args.empty?
161
+ set_param(name.to_sym, args)
162
+ else
163
+ super
164
+ end
165
+ end
166
+
167
+ private
168
+
169
+ def state_is?(state)
170
+ instance_state == state.to_sym
171
+ end
172
+
173
+ def must_have_definition!
174
+ raise 'Instance must be created first in order to start it' if @definition.nil?
175
+ end
176
+
177
+ def convert_id_param(name)
178
+ case name
179
+ when :realm then :realm_id
180
+ when :image then :image_id
181
+ else name
182
+ end
183
+ end
184
+
185
+ def set_param(key, val)
186
+ @parameters ||= {}
187
+ k = convert_id_param(key)
188
+ @parameters[k] = (val.size == 1) ? val[0] : val
189
+ end
190
+
191
+ end
192
+
193
+ end
194
+ end
@@ -0,0 +1,13 @@
1
+ require 'ostruct'
2
+
3
+ module Deltacloud
4
+ module DSL
5
+
6
+ class InstanceConfiguration < OpenStruct
7
+ def initialize(params={})
8
+ super(params)
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,45 @@
1
+ module Deltacloud
2
+ module DSL
3
+
4
+ class InstanceDefinition
5
+ include Enumerable
6
+
7
+ attr_reader :instances, :configuration
8
+
9
+ def initialize(configuration, &block)
10
+ @instances = []
11
+ @configuration = Deltacloud::DSL::Configuration(configuration)
12
+ define &block
13
+ end
14
+
15
+ def define(&block)
16
+ instance_eval(&block) if block_given?
17
+ end
18
+
19
+ # Add more instances to this instance definition
20
+ #
21
+ # @task.mock_instances.first << Deltacloud::DSL::Instance('instance-2') do
22
+ # realm 'us'
23
+ # image 'img1'
24
+ # end
25
+ #
26
+ def <<(instance)
27
+ @instances << instance
28
+ end
29
+
30
+ # Syntax suggar for adding new instances to instance definition
31
+ #
32
+ def instance(name, &block)
33
+ self << Deltacloud::DSL::Instance(name, &block) if block_given?
34
+ end
35
+
36
+ # Make instance definition enumerative for instances
37
+ #
38
+ def each(&block)
39
+ @instances.each { |instance| block.call(instance) }
40
+ end
41
+
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,37 @@
1
+ require 'ostruct'
2
+
3
+ module Deltacloud
4
+ module DSL
5
+
6
+ def self.InstanceProfile(name, &block)
7
+ InstanceProfile.new(name, &block) if block_given?
8
+ end
9
+
10
+ class InstanceProfile < OpenStruct
11
+
12
+ def initialize(name, &block)
13
+ super(:name => name)
14
+ define &block
15
+ end
16
+
17
+ def define(&block)
18
+ yield self if block_given?
19
+ end
20
+
21
+ # Convert InstanceProfile to DeltaCloud create_instance method parameters.
22
+ # Some property names varies from the names used in DeltaCloud. This
23
+ # method will deal with them.
24
+ #
25
+ def to_instance_params
26
+ params = self.marshal_dump
27
+ params[:hardware_profile] = params.delete(:name)
28
+ params[:hwp_memory] = params.delete(:memory) unless params[:memory].nil?
29
+ params[:hwp_cpu] = params.delete(:cpu) unless params[:cpu].nil?
30
+ params[:hwp_storage] = params.delete(:storage) unless params[:storage].nil?
31
+ params
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+
3
+ # Workaround for Ruby 1.8 which does not have 'require_relative'
4
+ # method defined
5
+ #
6
+ unless Kernel.respond_to?(:require_relative)
7
+ module Kernel
8
+ def require_relative(path)
9
+ require File.join(File.dirname(caller[0]), path.to_str)
10
+ end
11
+ end
12
+ end
13
+
14
+ require_relative 'client'
15
+ require_relative 'dsl'
16
+ require_relative 'task'
17
+ require_relative 'instance'
18
+ require_relative 'instance_configuration'
19
+ require_relative 'instance_definition'
20
+ require_relative 'instance_profile'
@@ -0,0 +1,142 @@
1
+ require 'eventmachine'
2
+ require 'logger'
3
+
4
+ module Deltacloud
5
+ module DSL
6
+
7
+ class Task
8
+
9
+ attr_reader :name, :state_machine, :log
10
+
11
+ def initialize(name, &block)
12
+ @name = name
13
+ @state_machine = {}
14
+ @log = Logger.new(STDERR)
15
+ define &block
16
+ end
17
+
18
+ def define(&block)
19
+ instance_eval(&block) if block_given?
20
+ end
21
+
22
+ # Configure group of instances that would be launched
23
+ # using specified configuration.
24
+ #
25
+ # Configuration:
26
+ #
27
+ # :driver - Deltacloud API driver to use (default: mock)
28
+ # :provider - API_PROVIDER (eg. URL to RHEV-M API)
29
+ # :username - API key (default: mockuser)
30
+ # :password - API secret (default: mockpassword)
31
+ # :url - Deltacloud API url (default: http://localhost:3001/api)
32
+ #
33
+ # The block should define single instances:
34
+ #
35
+ # instances(:driver => :ec2, :username => API_KEY, :password => API_SECRET) do
36
+ # instance 'instance-1' do
37
+ # # instance configuration here
38
+ # end
39
+ # end
40
+ #
41
+ def instances(configuration={}, &block)
42
+ return find_instances_by_driver(configuration) if configuration.kind_of? Symbol
43
+ @instances ||= []
44
+ @instances << Deltacloud::DSL::Instances(configuration, &block) if block_given?
45
+ @instances
46
+ end
47
+
48
+ # Declare a set of methods dynamically:
49
+ #
50
+ # find_instances_by_[attribute] => returns InstanceDefinition objects that
51
+ # match the value of attribute provided in method name
52
+ #
53
+ # [driver]_instances => return InstanceDefinition objects that correspond
54
+ # to given driver
55
+ #
56
+ # [driver]_instance => return Instance object that match with name
57
+ # eg. mock_instance 'test-mock-1' will find this
58
+ # instance.
59
+ #
60
+ # instances_[state] => return Instance objects with corresponding state
61
+ #
62
+ def method_missing(name, *args)
63
+ if name.to_s =~ /^find_instances_by_([\w_]+)$/
64
+ @instances.select { |i| i.configuration.respond_to?($1.intern) && args.include?(i.configuration.send($1.intern)) }
65
+ elsif name.to_s =~ /^(\w+)_instances$/
66
+ find_instances_by_driver($1.intern)
67
+ elsif name.to_s =~ /^(\w+)_instance$/
68
+ inst = find_instances_by_driver($1.intern).map { |instances| instances.find { |i| args.include?(i.name) } }.flatten.compact.first
69
+ yield inst if block_given?
70
+ inst
71
+ elsif name.to_s =~ /^instances_(\w+)\?$/
72
+ @instances.any? { |d| d.map { |i| (i.update! rescue true) && i.instance_state == $1.intern }.include? true }
73
+ else
74
+ super
75
+ end
76
+ end
77
+
78
+ # Start executing given task.
79
+ #
80
+ # This method will try to start all instances defined for all drivers.
81
+ # Then it will wait for instances to become running.
82
+ #
83
+ # Various callback can be provided for different state:
84
+ #
85
+ # on(:running) callback is triggered when all instances are running
86
+ # on(:instance_started) callback is triggered for every instance when become running
87
+ #
88
+ def start!
89
+ task = self
90
+ EventMachine::run do
91
+ inst_arr = []
92
+ task.instances.each do |definition|
93
+ inst_arr += definition.instances
94
+ definition.instances.each do |instance|
95
+ Thread.new do
96
+ begin
97
+ instance.create(definition).wait_for_running!
98
+ perform(:instance_started, instance)
99
+ log.info "Instance #{instance.name}[#{definition.configuration.driver}] successfully started."
100
+ rescue => e
101
+ log.error "ERROR: #{e.message}"
102
+ ensure
103
+ inst_arr.delete(instance)
104
+ end
105
+ end
106
+ end
107
+ end
108
+ until inst_arr.empty?; end
109
+ perform(:running)
110
+ EM.stop
111
+ end
112
+ end
113
+
114
+ # Handler for callback definition:
115
+ #
116
+ # on(:running) do
117
+ # end
118
+ #
119
+ # on(:instance_started) do |instance|
120
+ # end
121
+ #
122
+ def on(state, &block)
123
+ @state_machine[state] = block if block_given?
124
+ end
125
+
126
+ # Syntax sugar for @state_machine callbacks
127
+ #
128
+ def state(state)
129
+ @state_machine[state]
130
+ end
131
+
132
+ # Syntax sugar for performing callbacks
133
+ #
134
+ def perform(s, item=nil)
135
+ return unless @state_machine.keys.include?(s)
136
+ state(s).call(item)
137
+ end
138
+
139
+ end
140
+
141
+ end
142
+ end
@@ -0,0 +1,52 @@
1
+ # 1.8 compatibility fix
2
+ unless Kernel.respond_to?(:require_relative)
3
+ module Kernel
4
+ def require_relative(path)
5
+ require File.join(File.dirname(caller[0]), path.to_str)
6
+ end
7
+ end
8
+ end
9
+
10
+ require_relative '../lib/models'
11
+ require 'minitest/autorun'
12
+ require 'minitest/benchmark'
13
+
14
+ describe Deltacloud::DSL::Task do
15
+
16
+ def prepare_threaded_sample(prefix)
17
+ @threaded_sample = Deltacloud::DSL::Task('threaded pool') do
18
+
19
+ # Say we want to launch 80 instances in Mock
20
+ instances(:driver => :mock) do
21
+ 1.upto(80) do |i|
22
+ instance "test-#{prefix}-#{i}" do
23
+ realm 'us'
24
+ image 'img1'
25
+ profile 'm1-large' do |p|
26
+ p.memory = 7680
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ # After benchmarch destroy all instances
33
+ on(:ready) do
34
+ mock_instances.each do |d|
35
+ d.instances.each do |i|
36
+ i.stop!.wait_for_stopped!
37
+ i.destroy!
38
+ end
39
+ end
40
+ end
41
+
42
+ end
43
+ end
44
+
45
+ bench_performance_linear "threaded_pool" do |n|
46
+ 10.times do
47
+ threaded_sample = prepare_threaded_sample(Time.now.to_i)
48
+ threaded_sample.start!
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,203 @@
1
+ # 1.8 compatibility fix
2
+ unless Kernel.respond_to?(:require_relative)
3
+ module Kernel
4
+ def require_relative(path)
5
+ require File.join(File.dirname(caller[0]), path.to_str)
6
+ end
7
+ end
8
+ end
9
+
10
+ require_relative '../lib/models'
11
+ require 'minitest/autorun'
12
+
13
+ describe Deltacloud::DSL::Task do
14
+ before do
15
+ @sample = Deltacloud::DSL::Task('launch instance') do
16
+ instances(:driver => :mock) do
17
+ instance 'test-instance-1' do
18
+ realm 'us'
19
+ image 'img1'
20
+ profile('m1-large') do |p|
21
+ p.memory = 7680
22
+ end
23
+ end
24
+ instance 'test-instance-2' do
25
+ realm 'us'
26
+ image 'img1'
27
+ profile('m1-large') do |p|
28
+ p.memory = 10000
29
+ end
30
+ end
31
+ instance 'test-instance-3' do
32
+ realm 'eu'
33
+ image 'img1'
34
+ profile('m1-large') do |p|
35
+ p.memory = 10000
36
+ end
37
+ end
38
+ instance 'test-instance-4' do
39
+ realm 'us'
40
+ image 'img1'
41
+ profile('m1-large') do |p|
42
+ p.memory = 10000
43
+ end
44
+ end
45
+ instance 'test-instance-5' do
46
+ realm 'eu'
47
+ image 'img1'
48
+ profile('m1-large') do |p|
49
+ p.memory = 10000
50
+ end
51
+ end
52
+ end
53
+ on :instance_started do |i|
54
+ puts i.params.state
55
+ end
56
+ on :running do
57
+ mock_instance 'test-instance-1' do |i|
58
+ #puts "Getting IP address out of test-instance-1"
59
+ #puts i.params.public_addresses
60
+ end
61
+ mock_instance 'test-instance-2' do |i|
62
+ #puts "Destroying instance test-instance-2..."
63
+ i.stop!.wait_for_stopped!
64
+ i.destroy!
65
+ #puts i.params.state
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ describe Deltacloud::DSL::Task do
72
+ it 'should be constructed' do
73
+ @sample.must_be_instance_of Deltacloud::DSL::Task
74
+ end
75
+
76
+ it 'should have proper name' do
77
+ @sample.name.must_equal 'launch instance'
78
+ end
79
+
80
+ it 'should have state machine' do
81
+ @sample.state_machine.must_be_instance_of Hash
82
+ end
83
+
84
+ it 'should find instance by driver' do
85
+ @sample.find_instances_by_driver(:mock).must_be_instance_of Array
86
+ @sample.find_instances_by_driver(:mock).size.must_equal 1
87
+ @sample.find_instances_by_driver(:mock).first.must_be_instance_of Deltacloud::DSL::InstanceDefinition
88
+ end
89
+
90
+ it 'should return all mock instances' do
91
+ @sample.mock_instances.must_be_instance_of Array
92
+ @sample.mock_instances.size.must_equal 1
93
+ @sample.mock_instances.first.must_be_instance_of Deltacloud::DSL::InstanceDefinition
94
+ end
95
+
96
+ it 'should be able to find single instance by name' do
97
+ @sample.mock_instance('test-instance-1').must_be_instance_of Deltacloud::DSL::Instance
98
+ @sample.mock_instance('test-instance-1') do |i|
99
+ i.must_be_instance_of Deltacloud::DSL::Instance
100
+ end
101
+ end
102
+
103
+ it 'should figure out if instances are new or running' do
104
+ @sample.instances_running?.must_equal false
105
+ @sample.instances_new?.must_equal true
106
+ end
107
+
108
+ it 'should run' do
109
+ @sample.start!
110
+ end
111
+
112
+ end
113
+
114
+ describe Deltacloud::DSL::InstanceDefinition do
115
+
116
+ it 'should return all defined instances' do
117
+ @sample.instances.must_be_instance_of Array
118
+ @sample.instances.size.must_equal 1
119
+ @sample.instances.each do |i|
120
+ i.must_be_instance_of Deltacloud::DSL::InstanceDefinition
121
+ end
122
+ end
123
+
124
+ it 'should have configuration set for every instances' do
125
+ @sample.instances.first.configuration.wont_be_nil
126
+ end
127
+
128
+ it 'should have mock driver configuration' do
129
+ @sample.instances.first.configuration.driver.must_equal :mock
130
+ end
131
+
132
+ it 'should find instances using driver' do
133
+ @sample.find_instances_by_driver(:mock).must_be_instance_of Array
134
+ @sample.find_instances_by_driver(:mock).size.must_equal 1
135
+ @sample.find_instances_by_driver(:mock).first.must_be_instance_of Deltacloud::DSL::InstanceDefinition
136
+ end
137
+
138
+ end
139
+
140
+ describe Deltacloud::DSL::Instance do
141
+
142
+ it 'should be all valid instances' do
143
+ @sample.mock_instances.first.each do |inst|
144
+ inst.must_be_instance_of Deltacloud::DSL::Instance
145
+ end
146
+ end
147
+
148
+ it 'should find mock instance by name' do
149
+ @sample.mock_instance('test-instance-1') do |i|
150
+ i.wont_be_nil
151
+ i.must_be_instance_of Deltacloud::DSL::Instance
152
+ i.name.must_equal 'test-instance-1'
153
+ end
154
+ end
155
+
156
+ it 'should all have have valid name' do
157
+ @sample.mock_instances.first.each do |inst|
158
+ inst.name.wont_be_nil
159
+ end
160
+ end
161
+
162
+ it 'should have realm_id and image_id parameters defined' do
163
+ @sample.mock_instances.first.each do |inst|
164
+ ['us', 'eu'].must_include inst.params.realm_id
165
+ inst.params.image_id.must_equal 'img1'
166
+ end
167
+ end
168
+
169
+ it 'should have valid instance profile defined' do
170
+ @sample.mock_instances.first.each do |inst|
171
+ inst.instance_profile.must_be_instance_of Deltacloud::DSL::InstanceProfile
172
+ inst.instance_profile.name.wont_be_nil
173
+ end
174
+ end
175
+
176
+ it 'should have memory specified in instance profile' do
177
+ @sample.mock_instances.first.each do |inst|
178
+ inst.instance_profile.memory.wont_be_nil
179
+ inst.instance_profile.memory.must_be_instance_of Fixnum
180
+ end
181
+ end
182
+
183
+ it 'should allow manipulation of instances' do
184
+ definition = @sample.mock_instances.first
185
+ instance = @sample.mock_instance('test-instance-3')
186
+ instance.create(definition).must_be_instance_of Deltacloud::DSL::Instance
187
+ instance.instance_owner_id.must_equal 'mockuser'
188
+ instance.params.state.must_equal :running
189
+ instance.is_running?.must_equal true
190
+ instance.is_not_running?.must_equal false
191
+ instance.is_stopped?.must_equal false
192
+ instance.stop!.must_be_instance_of Deltacloud::DSL::Instance
193
+ instance.params.state.must_equal :stopped
194
+ instance.is_running?.must_equal false
195
+ instance.is_stopped?.must_equal true
196
+ instance.destroy!.must_be_instance_of Deltacloud::DSL::Instance
197
+ instance.is_destroyed?.must_equal true
198
+ instance.params.instance_id.must_be_nil
199
+ end
200
+
201
+ end
202
+
203
+ end
@@ -0,0 +1,28 @@
1
+ require 'minitest/autorun'
2
+
3
+ class Meme
4
+ def initialize
5
+ end
6
+
7
+ def i_can_has_cheezburger?
8
+ 'OHAI!'
9
+ end
10
+ end
11
+
12
+ describe Meme do
13
+ before do
14
+ @meme = Meme.new
15
+ end
16
+
17
+ describe "when asked about cheeseburgers" do
18
+ it "must respond positively" do
19
+ @meme.i_can_has_cheezburger?.must_equal "OHAI!"
20
+ end
21
+ end
22
+
23
+ describe "when asked about blending possibilities" do
24
+ it "won't say no" do
25
+ @meme.will_it_blend?.wont_match /^no/i
26
+ end
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: deltadsl
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michal Fojtik
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: deltacloud-client
16
+ requirement: &70175076503460 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.5.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70175076503460
25
+ - !ruby/object:Gem::Dependency
26
+ name: eventmachine
27
+ requirement: &70175076501840 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70175076501840
36
+ - !ruby/object:Gem::Dependency
37
+ name: minitest
38
+ requirement: &70175076500080 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70175076500080
47
+ description: Deltacloud API powered DSL for creating complex deployments
48
+ email: dev@deltacloud.apache.org
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files:
52
+ - README.md
53
+ files:
54
+ - README.md
55
+ - lib/client.rb
56
+ - lib/dsl.rb
57
+ - lib/instance.rb
58
+ - lib/instance_configuration.rb
59
+ - lib/instance_definition.rb
60
+ - lib/instance_profile.rb
61
+ - lib/models.rb
62
+ - lib/task.rb
63
+ - tests/deltacloud_perf_test.rb
64
+ - tests/dsl_test.rb
65
+ - tests/test_test.rb
66
+ homepage: http://www.deltacloud.org
67
+ licenses: []
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 1.8.15
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Deltacloud API DSL
90
+ test_files:
91
+ - tests/deltacloud_perf_test.rb
92
+ - tests/dsl_test.rb
93
+ - tests/test_test.rb