beaker-openstack 0.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,238 @@
1
+ require 'spec_helper'
2
+ require 'fog'
3
+
4
+ module Beaker
5
+ describe Openstack do
6
+
7
+ let(:options) { make_opts.merge({'logger' => double().as_null_object}) }
8
+
9
+ let(:openstack) {
10
+ Openstack.new(@hosts, options)
11
+ }
12
+
13
+ before :each do
14
+ @hosts = make_hosts()
15
+
16
+ @compute_client = double().as_null_object
17
+ @network_client = double().as_null_object
18
+
19
+ allow( Fog::Compute ).to receive( :new ).and_return( @compute_client )
20
+ allow( Fog::Network ).to receive( :new ).and_return( @network_client )
21
+ end
22
+
23
+ context 'keystone version support' do
24
+ it 'supports keystone v2' do
25
+ credentials = openstack.instance_eval('@credentials')
26
+ expect(credentials[:openstack_user_domain]).to be_nil
27
+ expect(credentials[:openstack_project_domain]).to be_nil
28
+ end
29
+
30
+ it 'supports keystone v3 with implicit arguments' do
31
+ v3_options = options
32
+ v3_options[:openstack_auth_url] = 'https://example.com/identity/v3/auth'
33
+
34
+ credentials = Openstack.new(@hosts, v3_options).instance_eval('@credentials')
35
+ expect(credentials[:openstack_user_domain]).to eq('Default')
36
+ expect(credentials[:openstack_project_domain]).to eq('Default')
37
+ end
38
+
39
+ it 'supports keystone v3 with explicit arguments' do
40
+ v3_options = options
41
+ v3_options[:openstack_auth_url] = 'https://example.com/identity/v3/auth'
42
+ v3_options[:openstack_user_domain] = 'acme.com'
43
+ v3_options[:openstack_project_domain] = 'R&D'
44
+
45
+ credentials = Openstack.new(@hosts, v3_options).instance_eval('@credentials')
46
+ expect(credentials[:openstack_user_domain]).to eq('acme.com')
47
+ expect(credentials[:openstack_project_domain]).to eq('R&D')
48
+ end
49
+ end
50
+
51
+ describe '#provision' do
52
+
53
+ it 'check openstack options during initialization' do
54
+ options = openstack.instance_eval('@options')
55
+ expect(options['openstack_api_key']).to eq('P1as$w0rd')
56
+ expect(options['openstack_username']).to eq('user')
57
+ expect(options['openstack_auth_url']).to eq('http://openstack_hypervisor.labs.net:5000/v2.0/tokens')
58
+ expect(options['openstack_tenant']).to eq('testing')
59
+ expect(options['openstack_network']).to eq('testing')
60
+ expect(options['openstack_keyname']).to eq('nopass')
61
+ expect(options['security_group']).to eq(['my_sg', 'default'])
62
+ expect(options['floating_ip_pool']).to eq('my_pool')
63
+ end
64
+
65
+ it 'check hosts options during initialization' do
66
+ @hosts.each do |host|
67
+ expect(host['image']).to eq('default_image')
68
+ expect(host['flavor']).to eq('m1.large')
69
+ expect(host['user_data']).to eq('#cloud-config\nmanage_etc_hosts: true\nfinal_message: "The host is finally up!"')
70
+ end
71
+ end
72
+
73
+ it 'check host options during server creation' do
74
+
75
+ mock_flavor = Object.new
76
+ allow( mock_flavor ).to receive( :id ).and_return( 12345 )
77
+ allow( openstack ).to receive( :flavor ).and_return( mock_flavor )
78
+ expect( openstack ).to receive( :flavor ).with( 'm1.large' )
79
+
80
+ mock_image = Object.new
81
+ allow( mock_image ).to receive( :id ).and_return( 54321 )
82
+ allow( openstack ).to receive( :image ).and_return( mock_image )
83
+ expect( openstack ).to receive( :image ).with( 'default_image' )
84
+
85
+ mock_servers = double().as_null_object
86
+ allow( @compute_client ).to receive( :servers ).and_return( mock_servers )
87
+
88
+ expect(mock_servers).to receive(:create).with(hash_including(
89
+ :user_data => '#cloud-config\nmanage_etc_hosts: true\nfinal_message: "The host is finally up!"',
90
+ :flavor_ref => 12345,
91
+ :image_ref => 54321)
92
+ )
93
+
94
+ @hosts.each do |host|
95
+ allow(host).to receive(:wait_for_port).and_return(true)
96
+ end
97
+
98
+ openstack.provision
99
+ end
100
+
101
+ it 'generates valid keynames during server creation' do
102
+ # Simulate getting a dynamic IP from OpenStack to test key generation code
103
+ # after provisioning. See _validate_new_key_pair in openstack/nova for reference
104
+ mock_ip = double().as_null_object
105
+ allow( openstack ).to receive( :get_ip ).and_return( mock_ip )
106
+ allow( mock_ip ).to receive( :ip ).and_return( '172.16.0.1' )
107
+ openstack.instance_eval('@options')['openstack_keyname'] = nil
108
+
109
+ @hosts.each do |host|
110
+ allow(host).to receive(:wait_for_port).and_return(true)
111
+ end
112
+
113
+ openstack.provision
114
+
115
+ @hosts.each do |host|
116
+ expect(host[:keyname]).to match(/^[_\-0-9a-zA-Z]+$/)
117
+ end
118
+ end
119
+
120
+ it 'get_ip always allocates a new floatingip' do
121
+ # Assume beaker is being executed in parallel N times by travis (or similar).
122
+ # IPs are allocated (but not associated) before an instance is created; it is
123
+ # hightly possible the first instance will allocate a new IP and create an ssh
124
+ # key. While the instance is being created the other N-1 instances come along,
125
+ # find the unused IP and try to use it as well which causes keyname clashes
126
+ # and other IP related shenannigans. Ensure we allocate a new IP each and every
127
+ # time
128
+ mock_addresses = double().as_null_object
129
+ mock_ip = double().as_null_object
130
+ allow(@compute_client).to receive(:addresses).and_return(mock_addresses)
131
+ allow(mock_addresses).to receive(:create).and_return(mock_ip)
132
+ expect(mock_addresses).to receive(:create).exactly(3).times
133
+ (1..3).each { openstack.get_ip }
134
+ end
135
+
136
+ context 'volume creation option' do
137
+ it 'provisions volume by default' do
138
+ mock_flavor = Object.new
139
+ allow( mock_flavor ).to receive( :id ).and_return( 12345 )
140
+ allow( openstack ).to receive( :flavor ).and_return( mock_flavor )
141
+ mock_image = Object.new
142
+ allow( mock_image ).to receive( :id ).and_return( 54321 )
143
+ allow( openstack ).to receive( :image ).and_return( mock_image )
144
+ mock_servers = double().as_null_object
145
+ allow( @compute_client ).to receive( :servers ).and_return( mock_servers )
146
+
147
+ @hosts.each do |host|
148
+ allow(host).to receive(:wait_for_port).and_return(true)
149
+ expect(openstack).to receive(:provision_storage)
150
+ end
151
+
152
+ openstack.provision
153
+ end
154
+
155
+ it 'skips provisioning when disabled' do
156
+ mock_flavor = Object.new
157
+ allow( mock_flavor ).to receive( :id ).and_return( 12345 )
158
+ allow( openstack ).to receive( :flavor ).and_return( mock_flavor )
159
+ mock_image = Object.new
160
+ allow( mock_image ).to receive( :id ).and_return( 54321 )
161
+ allow( openstack ).to receive( :image ).and_return( mock_image )
162
+ mock_servers = double().as_null_object
163
+ allow( @compute_client ).to receive( :servers ).and_return( mock_servers )
164
+
165
+ openstack.instance_eval('@options')['openstack_volume_support'] = false
166
+
167
+ @hosts.each do |host|
168
+ allow(host).to receive(:wait_for_port).and_return(true)
169
+ expect(openstack).not_to receive(:provision_storage)
170
+ end
171
+
172
+ openstack.provision
173
+ end
174
+ end
175
+ end
176
+
177
+ describe '#provision_storage' do
178
+
179
+ it 'creates volumes with cinder v1' do
180
+ # Mock a volume
181
+ allow(openstack).to receive(:get_volumes).and_return({'volume1' => {'size' => 1000000 }})
182
+
183
+ # Stub out the call to create the client and hard code the return value
184
+ allow(openstack).to receive(:volume_client_create).and_return(nil)
185
+ client = double().as_null_object
186
+ openstack.instance_variable_set(:@volume_client, client)
187
+ allow(openstack).to receive(:get_volume_api_version).and_return(1)
188
+
189
+ # Check the parameters are valid, correct 'name' parameter and correct size conversion
190
+ mock_volume = double().as_null_object
191
+ expect(client).to receive(:create).with(:display_name => 'volume1',
192
+ :description => 'Beaker volume: host=alan volume=volume1',
193
+ :size => 1000
194
+ ).and_return(mock_volume)
195
+ allow(mock_volume).to receive(:wait_for).and_return(nil)
196
+
197
+ # Perform the test!
198
+ mock_vm = double().as_null_object
199
+ allow(mock_volume).to receive(:id).and_return('Fake ID')
200
+ expect(mock_vm).to receive(:attach_volume).with('Fake ID', '/dev/vdb')
201
+
202
+ mock_host = double().as_null_object
203
+ allow(mock_host).to receive(:name).and_return('alan')
204
+
205
+ openstack.provision_storage mock_host, mock_vm
206
+ end
207
+
208
+ it 'creates volumes with cinder v2' do
209
+ # Mock a volume
210
+ allow(openstack).to receive(:get_volumes).and_return({'volume1' => {'size' => 1000000 }})
211
+
212
+ # Stub out the call to create the client and hard code the return value
213
+ allow(openstack).to receive(:volume_client_create).and_return(nil)
214
+ client = double().as_null_object
215
+ openstack.instance_variable_set(:@volume_client, client)
216
+ allow(openstack).to receive(:get_volume_api_version).and_return(-1)
217
+
218
+ # Check the parameters are valid, correct 'name' parameter and correct size conversion
219
+ mock_volume = double().as_null_object
220
+ expect(client).to receive(:create).with(:name => 'volume1',
221
+ :description => 'Beaker volume: host=alan volume=volume1',
222
+ :size => 1000
223
+ ).and_return(mock_volume)
224
+ allow(mock_volume).to receive(:wait_for).and_return(nil)
225
+
226
+ # Perform the test!
227
+ mock_vm = double().as_null_object
228
+ allow(mock_volume).to receive(:id).and_return('Fake ID')
229
+ expect(mock_vm).to receive(:attach_volume).with('Fake ID', '/dev/vdb')
230
+
231
+ mock_host = double().as_null_object
232
+ allow(mock_host).to receive(:name).and_return('alan')
233
+
234
+ openstack.provision_storage mock_host, mock_vm
235
+ end
236
+ end
237
+ end
238
+ end
@@ -0,0 +1,17 @@
1
+ require 'simplecov'
2
+ require 'rspec/its'
3
+ require 'beaker'
4
+
5
+ Dir.glob(Dir.pwd + '/lib/beaker/hypervisor/*.rb') {|file| require file}
6
+
7
+ # setup & require beaker's spec_helper.rb
8
+ beaker_gem_spec = Gem::Specification.find_by_name('beaker')
9
+ beaker_gem_dir = beaker_gem_spec.gem_dir
10
+ beaker_spec_path = File.join(beaker_gem_dir, 'spec')
11
+ $LOAD_PATH << beaker_spec_path
12
+ require File.join(beaker_spec_path, 'spec_helper.rb')
13
+
14
+ RSpec.configure do |config|
15
+ config.include TestFileHelpers
16
+ config.include HostHelpers
17
+ end
metadata ADDED
@@ -0,0 +1,212 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: beaker-openstack
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Rishi Javia, Kevin Imber, Tony Vu
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-07-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec-its
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: fakefs
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '0.6'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '0.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '10.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '10.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '0.10'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '0.10'
97
+ - !ruby/object:Gem::Dependency
98
+ name: yard
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: markdown
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ! '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: thin
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ! '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: stringify-hash
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ~>
144
+ - !ruby/object:Gem::Version
145
+ version: 0.0.0
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ~>
151
+ - !ruby/object:Gem::Version
152
+ version: 0.0.0
153
+ - !ruby/object:Gem::Dependency
154
+ name: fog
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ~>
158
+ - !ruby/object:Gem::Version
159
+ version: '1.38'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ~>
165
+ - !ruby/object:Gem::Version
166
+ version: '1.38'
167
+ description: For use for the Beaker acceptance testing tool
168
+ email:
169
+ - rishi.javia@puppet.com, kevin.imber@puppet.com, tony.vu@puppet.com
170
+ executables:
171
+ - beaker-openstack
172
+ extensions: []
173
+ extra_rdoc_files: []
174
+ files:
175
+ - .gitignore
176
+ - .simplecov
177
+ - Gemfile
178
+ - LICENSE
179
+ - README.md
180
+ - Rakefile
181
+ - beaker-openstack.gemspec
182
+ - bin/beaker-openstack
183
+ - lib/beaker-openstack/version.rb
184
+ - lib/beaker/hypervisor/openstack.rb
185
+ - openstack.md
186
+ - spec/beaker/hypervisor/openstack_spec.rb
187
+ - spec/spec_helper.rb
188
+ homepage: https://github.com/puppetlabs/beaker-openstack
189
+ licenses:
190
+ - Apache2
191
+ metadata: {}
192
+ post_install_message:
193
+ rdoc_options: []
194
+ require_paths:
195
+ - lib
196
+ required_ruby_version: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ! '>='
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ required_rubygems_version: !ruby/object:Gem::Requirement
202
+ requirements:
203
+ - - ! '>='
204
+ - !ruby/object:Gem::Version
205
+ version: '0'
206
+ requirements: []
207
+ rubyforge_project:
208
+ rubygems_version: 2.4.6
209
+ signing_key:
210
+ specification_version: 4
211
+ summary: Beaker DSL Extension Helpers!
212
+ test_files: []