deltadsl 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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