aviator 0.0.9 → 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.
@@ -1,3 +1,3 @@
1
1
  module Aviator
2
- VERSION = "0.0.9"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -1,281 +1,436 @@
1
1
  require 'test_helper'
2
+ require 'mocha/setup'
2
3
 
3
- class Aviator::Test
4
+ require 'support/dummy/provider'
4
5
 
5
- describe 'aviator/core/session' do
6
6
 
7
- def config
8
- Environment
9
- end
7
+ describe 'Aviator::Session' do
10
8
 
9
+ # Methods/attributes shared across tests
11
10
 
12
- def klass
13
- Aviator::Session
14
- end
11
+ def stub_body
12
+ '{"key":"value"}'
13
+ end
15
14
 
16
15
 
17
- def log_file_path
18
- Pathname.new(__FILE__).expand_path.join('..', '..', '..', '..', 'tmp', 'aviator.log')
19
- end
16
+ def stub_headers
17
+ {}
18
+ end
20
19
 
21
20
 
22
- def new_session
23
- Aviator::Session.new(
24
- :config_file => config.path,
25
- :environment => 'openstack_admin',
26
- :log_file => log_file_path
27
- )
28
- end
21
+ def stub_http
22
+ mock_conn = mock('Faraday::Connection')
23
+ mock_http_req = mock('Faraday::Request')
24
+ mock_response = mock('Faraday::Response')
25
+ Faraday.expects(:new).returns(mock_conn)
26
+ mock_conn.stubs(:post).yields(mock_http_req).returns(mock_response)
27
+ mock_http_req.stubs(:url)
28
+ mock_http_req.stubs(:body=)
29
+ mock_response.stubs(:status).returns(200)
30
+ mock_response.stubs(:headers).returns(stub_headers)
31
+ mock_response.stubs(:body).returns(stub_body)
32
+ end
29
33
 
30
34
 
31
- describe '#authenticate' do
35
+ def valid_config
36
+ @valid_config ||= YAML::load <<-YAML
37
+ production:
38
+ provider: dummy
39
+ auth_service:
40
+ name: auth
41
+ host_uri: http://some.address.com
42
+ request: authenticate
43
+ validator: validate
44
+ auth_credentials:
45
+ username: myusername
46
+ password: mypassword
47
+ YAML
48
+ end
32
49
 
33
- it 'authenticates against the auth service indicated in the config file' do
34
- session = new_session
35
50
 
36
- session.authenticate
51
+ def valid_config_path
52
+ 'path/to/config.yml'
53
+ end
37
54
 
38
- session.authenticated?.must_equal true
39
- end
40
55
 
56
+ def valid_env
57
+ @valid_env ||= valid_config.keys.first
58
+ end
41
59
 
42
- it 'authenticates against the auth service using the credentials in the given block' do
43
- session = new_session
44
- credentials = config.openstack_admin[:auth_credentials]
45
60
 
46
- session.authenticate do |c|
47
- c[:username] = credentials[:username]
48
- c[:password] = credentials[:password]
49
- end
61
+ # Tests/expectations
50
62
 
51
- session.authenticated?.must_equal true
52
- end
63
+ describe '#authenticate' do
64
+
65
+ it 'authenticates against the auth service declared in its config' do
66
+ mock_conn = mock('Faraday::Connection')
67
+ mock_http_req = mock('Faraday::Request')
68
+ mock_response = mock('Faraday::Response')
69
+ Faraday.expects(:new).returns(mock_conn)
70
+ mock_conn.expects(:post).yields(mock_http_req).returns(mock_response)
71
+ mock_http_req.expects(:url)
72
+ mock_http_req.expects(:body=).with(){|json| JSON.load(json) == valid_config[valid_env]['auth_credentials']}
73
+ mock_response.expects(:status).returns(200)
74
+ mock_response.expects(:headers).returns({})
75
+ mock_response.expects(:body).returns({})
53
76
 
77
+ session = Aviator::Session.new(:config => valid_config[valid_env])
78
+ session.authenticate
79
+
80
+ session.authenticated?.must_equal true
81
+ end
54
82
 
55
- it 'raises an AuthenticationError when authentication fails' do
56
- session = new_session
57
- credentials = config.openstack_admin[:auth_credentials]
58
83
 
59
- the_method = lambda do
60
- session.authenticate do |c|
61
- c[:username] = 'invalidusername'
62
- c[:password] = 'invalidpassword'
63
- end
84
+ it 'authenticates against the auth service using the credentials in the given block' do
85
+ # Keys below are dependent on whatever is declared in
86
+ # the request classes referenced by auth_service:request
87
+ # in the config file
88
+ params = {
89
+ 'username' => 'someuser',
90
+ 'password' => 'password'
91
+ }
92
+
93
+ mock_conn = mock('Faraday::Connection')
94
+ mock_http_req = mock('Faraday::Request')
95
+ mock_response = mock('Faraday::Response')
96
+ Faraday.expects(:new).returns(mock_conn)
97
+ mock_conn.expects(:post).yields(mock_http_req).returns(mock_response)
98
+ mock_http_req.expects(:url)
99
+ mock_http_req.expects(:body=).with(){|json| JSON.load(json) == params }
100
+ mock_response.expects(:status).returns(200)
101
+ mock_response.expects(:headers).returns({})
102
+ mock_response.expects(:body).returns({})
103
+
104
+ session = Aviator::Session.new(:config => valid_config[valid_env])
105
+ session.authenticate do |p|
106
+ params.each do |key, value|
107
+ p[key] = value
64
108
  end
109
+ end
110
+
111
+ session.authenticated?.must_equal true
112
+ end
65
113
 
66
- the_method.must_raise Aviator::Session::AuthenticationError
114
+
115
+ it 'raises an AuthenticationError when authentication fails' do
116
+ Faraday.expects(:new).returns(mock_conn = mock('Faraday::Connection'))
117
+ mock_conn.expects(:post).returns(mock_response = mock('Faraday::Response'))
118
+ mock_response.expects(:status).returns(401)
119
+ mock_response.expects(:body).returns({})
120
+
121
+ session = Aviator::Session.new(:config => valid_config[valid_env])
122
+ # Wrapping the next method call in a lambda so that we can
123
+ # check if an AuthenticationError was raised. See assertion.
124
+ auth_method = lambda do
125
+ session.authenticate do |c|
126
+ c[:username] = 'invalidusername'
127
+ c[:password] = 'invalidpassword'
128
+ end
67
129
  end
68
130
 
131
+ auth_method.must_raise Aviator::Session::AuthenticationError
132
+ end
69
133
 
70
- it 'updates the session data of its service objects' do
71
- session = new_session
72
- session.authenticate
73
134
 
74
- keystone = session.identity_service
135
+ it 'updates the session data of its service objects' do
136
+ # This test ensures that Session will always update the session
137
+ # data in Service objects that were created before reauthentication
138
+ mock_conn = mock('Faraday::Connection')
139
+ mock_http_req = mock('Faraday::Request')
140
+ mock_response_1 = mock('Faraday::Response')
141
+ mock_response_2 = mock('Faraday::Response')
142
+ Faraday.expects(:new).returns(mock_conn)
143
+ mock_conn.stubs(:post).yields(mock_http_req).returns(mock_response_1, mock_response_2)
144
+ mock_http_req.stubs(:url)
145
+ mock_http_req.stubs(:body=)
146
+ mock_response_1.stubs(:status).returns(200)
147
+ mock_response_1.stubs(:headers).returns({})
148
+ mock_response_1.stubs(:body).returns('{"session_data":1}')
149
+ mock_response_2.stubs(:status).returns(200)
150
+ mock_response_2.stubs(:headers).returns({})
151
+ mock_response_2.stubs(:body).returns('{"session_data":2}')
152
+
153
+ # First authentication
154
+ session = Aviator::Session.new(:config => valid_config[valid_env])
155
+ session.authenticate
156
+ session.authenticated?.must_equal true
157
+
158
+ # Capture session data
159
+ auth_service = session.auth_service
160
+ session_data_1 = auth_service.default_session_data
161
+
162
+ # Second authentication
163
+ session.authenticate
164
+ session.authenticated?.must_equal true
165
+
166
+ # Check second session data
167
+ session.auth_service.must_equal auth_service
168
+ auth_service.default_session_data.wont_equal session_data_1
169
+ end
75
170
 
76
- session_data_1 = keystone.default_session_data
171
+ end
77
172
 
78
- session.authenticate
79
173
 
80
- session.identity_service.must_equal keystone
174
+ describe '#dump' do
81
175
 
82
- new_token = session.identity_service.default_session_data[:body][:access][:token][:id]
83
- new_token.wont_equal session_data_1[:body][:access][:token][:id]
84
- keystone.default_session_data[:body][:access][:token][:id].must_equal new_token
85
- end
176
+ it 'serializes the session data for caching' do
177
+ stub_http
86
178
 
87
- end # describe '#authenticate'
179
+ session = Aviator::Session.new(:config => valid_config[valid_env])
180
+ session.authenticate
181
+ session.authenticated?.must_equal true
88
182
 
183
+ expected = JSON.generate({
184
+ :config => valid_config[valid_env],
185
+ :auth_response => Hashish.new({ :headers => stub_headers, :body => JSON.load(stub_body) })
186
+ })
89
187
 
90
- describe '#dump' do
188
+ # Convert back to json since key ordering is not preserved in Ruby 1.8
189
+ JSON.load(session.dump).must_equal JSON.load(expected)
190
+ end
91
191
 
92
- it 'serializes the session data for caching' do
93
- session = new_session
94
- session.authenticate
192
+ end
95
193
 
96
- str = session.dump
97
194
 
98
- expected = JSON.generate({
99
- :environment => session.send(:environment),
100
- :auth_response => session.send(:auth_response)
101
- })
195
+ describe '#load' do
102
196
 
103
- str.must_equal expected
104
- end
197
+ it 'returns itself' do
198
+ stub_http
199
+
200
+ session = Aviator::Session.new(:config => valid_config[valid_env])
201
+ session.authenticate
105
202
 
203
+ session.authenticated?.must_equal true
204
+ session.load(session.dump).must_equal session
106
205
  end
107
206
 
108
207
 
109
- describe '#load' do
208
+ it 'updates the session data of its service objects' do
209
+ # This test ensures that Session will always update the session
210
+ # data in Service objects that were created before reload
211
+ mock_conn = mock('Faraday::Connection')
212
+ mock_http_req = mock('Faraday::Request')
213
+ mock_response_1 = mock('Faraday::Response')
214
+ mock_response_2 = mock('Faraday::Response')
215
+ Faraday.stubs(:new).returns(mock_conn)
216
+ mock_conn.stubs(:post).yields(mock_http_req).returns(mock_response_1, mock_response_2)
217
+ mock_http_req.stubs(:url)
218
+ mock_http_req.stubs(:body=)
219
+ mock_response_1.stubs(:status).returns(200)
220
+ mock_response_1.stubs(:headers).returns({})
221
+ mock_response_1.stubs(:body).returns('{"session_data":1}')
222
+ mock_response_2.stubs(:status).returns(200)
223
+ mock_response_2.stubs(:headers).returns({})
224
+ mock_response_2.stubs(:body).returns('{"session_data":2}')
225
+
226
+ # First session
227
+ session1 = Aviator::Session.new(:config => valid_config[valid_env])
228
+ session1.authenticate
229
+ session1.authenticated?.must_equal true
230
+ auth_service_1 = session1.auth_service
231
+
232
+ # Second session
233
+ session2 = Aviator::Session.new(:config => valid_config[valid_env])
234
+ session2.authenticate
235
+ session2.authenticated?.must_equal true
236
+ auth_service_2 = session2.auth_service
237
+
238
+ session1.load(session2.dump)
239
+
240
+ session1.wont_equal session2
241
+ session1.auth_service.wont_equal session2.auth_service
242
+ auth_service_1.default_session_data.must_equal auth_service_2.default_session_data
243
+ end
110
244
 
111
- it 'returns itself' do
112
- session = new_session
113
- session.authenticate
245
+ end
114
246
 
115
- str = session.dump
116
- session.load(str).must_equal session
117
- end
118
247
 
248
+ describe '::load' do
119
249
 
120
- it 'updates the session data of its service objects' do
121
- session1 = new_session
122
- session1.authenticate
123
- keystone1 = session1.identity_service
250
+ it 'creates a new instance from the given session dump' do
251
+ stub_http
124
252
 
125
- session2 = new_session
126
- session2.authenticate
127
- keystone2 = session2.identity_service
253
+ session1 = Aviator::Session.new(:config => valid_config[valid_env])
254
+ session1.authenticate
255
+ session1.authenticated?.must_equal true
256
+ auth_service_1 = session1.auth_service
128
257
 
129
- session1.load(session2.dump)
258
+ session2 = Aviator::Session.load(session1.dump)
259
+ session2.authenticated?.must_equal true
260
+ auth_service_2 = session2.auth_service
130
261
 
131
- keystone1.wont_equal keystone2
132
- keystone1.default_session_data.must_equal keystone2.default_session_data
133
- end
262
+ session1.wont_equal session2
263
+ session1.auth_service.wont_equal session2.auth_service
264
+ auth_service_1.default_session_data.must_equal auth_service_2.default_session_data
265
+ end
134
266
 
135
- end # describe '#load'
267
+ end
136
268
 
137
269
 
138
- describe '::load' do
270
+ describe '::new' do
139
271
 
140
- it 'creates a new instance from the given session dump' do
141
- session = new_session
142
- session.authenticate
272
+ it 'accepts a config file and environment name' do
273
+ Pathname.any_instance.stubs(:file?).returns(true)
274
+ YAML.expects(:load_file).with(valid_config_path).returns(valid_config)
143
275
 
144
- str = session.dump
145
- session = Aviator::Session.load(str)
146
- expected = Hashish.new(JSON.parse(str))
276
+ session = Aviator::Session.new(:config_file => valid_config_path,
277
+ :environment => valid_env)
147
278
 
148
- session.authenticated?.must_equal true
279
+ session.config.must_equal Hashish.new(valid_config[valid_env])
280
+ end
149
281
 
150
- # This is bad testing practice (testing a private method) but
151
- # I'll go ahead and do it anyway just to be sure.
152
- session.send(:environment).must_equal expected[:environment]
153
- session.send(:auth_response).must_equal expected[:auth_response]
154
- end
155
282
 
283
+ it 'accepts a hash object as configuration' do
284
+ hash = valid_config[valid_env]
156
285
 
157
- it 'uses the loaded auth info for its services' do
158
- session = new_session
159
- session.authenticate
286
+ session = Aviator::Session.new(:config => hash)
160
287
 
161
- expected = Hashish.new(JSON.parse(session.dump))
162
- session = Aviator::Session.load(session.dump)
163
- service = session.identity_service
288
+ session.config.must_equal Hashish.new(hash)
289
+ end
164
290
 
165
- service.default_session_data.must_equal expected[:auth_response]
166
- end
167
291
 
292
+ it 'accepts a session dump' do
293
+ mock_conn = mock('Faraday::Connection')
294
+ mock_http_req = mock('Faraday::Request')
295
+ mock_response = mock('Faraday::Response')
296
+ Faraday.expects(:new).returns(mock_conn)
297
+ mock_conn.stubs(:post).yields(mock_http_req).returns(mock_response)
298
+ mock_http_req.stubs(:url)
299
+ mock_http_req.stubs(:body=)
300
+ mock_response.stubs(:status).returns(200)
301
+ mock_response.stubs(:headers).returns({})
302
+ mock_response.stubs(:body).returns('{"session_data":1}')
303
+
304
+ session1 = Aviator::Session.new(:config => valid_config[valid_env])
305
+ session1.authenticate
306
+ session1.authenticated?.must_equal true
307
+
308
+ session2 = Aviator::Session.new(:session_dump => session1.dump)
309
+
310
+ session2.authenticated?.must_equal true
311
+ session2.config.must_equal Hashish.new(valid_config[valid_env])
168
312
  end
169
313
 
170
314
 
171
- describe '::new' do
315
+ it 'optionally accepts a log file path' do
316
+ hash = valid_config[valid_env]
317
+ path = '/path/to/log/file.log'
172
318
 
173
- it 'can accept a hash object as configuration' do
174
- config = {
175
- :provider => 'openstack',
176
- :auth_service => {
177
- :name => 'identity',
178
- :host_uri => 'http://devstack:5000/v2.0',
179
- :request => 'create_token',
180
- :validator => 'list_tenants'
181
- },
182
- :auth_credentials => {
183
- :username => 'myusername',
184
- :password => 'mypassword',
185
- :tenant_name => 'myproject'
186
- }
187
- }
319
+ session = Aviator::Session.new(:config => hash, :log_file => path)
188
320
 
189
- session = klass.new(:config => config)
321
+ session.log_file.must_equal path
322
+ end
190
323
 
191
- session.send(:environment).must_equal Hashish.new(config)
192
324
 
193
- auth_service = session.send(:auth_service)
194
- auth_service.send(:service).must_equal config[:auth_service][:name]
195
- end
325
+ it 'raises an error when required constructor keys are missing' do
326
+ new_method = lambda { Aviator::Session.new(:log_file => '/path/to/log/file/log') }
327
+ new_method.must_raise Aviator::Session::InitializationError
196
328
 
329
+ error = new_method.call rescue $!
197
330
 
198
- it 'directs log entries to the given log file' do
199
- log_file_path.delete if log_file_path.file?
331
+ error.message.wont_be_nil
332
+ end
200
333
 
201
- session = new_session
202
- session.authenticate
334
+ end
203
335
 
204
- log_file_path.file?.must_equal true
205
- end
206
336
 
337
+ describe '#request' do
207
338
 
208
- it 'raises an error when constructor keys are missing' do
209
- the_method = lambda { klass.new }
210
- the_method.must_raise Aviator::Session::InitializationError
339
+ it 'delegates to Service#request' do
340
+ request_name = :create_server
341
+ request_opts = {}
342
+ request_params = lambda do |params|
343
+ params[:key1] = :value1
344
+ params[:key2] = :value2
345
+ end
346
+ yielded_params = {}
211
347
 
212
- error = the_method.call rescue $!
348
+ mock_auth = mock('Aviator::Service')
349
+ mock_compute = mock('Aviator::Service')
350
+ mock_response = mock('Aviator::Response')
213
351
 
214
- error.message.wont_be_nil
215
- end
352
+ Aviator::Service.expects(:new).twice.returns(mock_auth, mock_compute)
353
+ mock_response.stubs(:status).returns(200)
354
+ mock_response.stubs(:headers).returns({})
355
+ mock_response.stubs(:body).returns('{}')
356
+ mock_auth.expects(:request).returns(mock_response)
357
+ mock_compute.expects(:request).with(request_name, request_opts).yields(yielded_params).returns(mock_response)
358
+
359
+ session = Aviator::Session.new(:config => valid_config[valid_env])
360
+ session.authenticate
216
361
 
362
+ session.request :compute, request_name, request_opts, &request_params
363
+ yielded_params.wont_be_empty
217
364
  end
218
365
 
366
+ end
219
367
 
220
- describe '#validate' do
221
368
 
222
- it 'returns true if session is still valid' do
223
- session = new_session
224
- session.authenticate
369
+ describe '#validate' do
225
370
 
226
- session.validate.must_equal true
227
- end
371
+ it 'returns true if session is still valid' do
372
+ stub_http
228
373
 
374
+ session = Aviator::Session.new(:config => valid_config[valid_env])
375
+ session.authenticate
229
376
 
230
- it 'returns false if session is no longer valid' do
231
- session = new_session
232
- session.authenticate
377
+ session.validate.must_equal true
378
+ end
233
379
 
234
- session.send(:auth_response)[:body][:access][:token][:id] = 'invalidtokenid'
235
380
 
236
- session.validate.must_equal false
237
- end
381
+ it 'returns false if session is no longer valid' do
382
+ mock_conn = mock('Faraday::Connection')
383
+ mock_http_req = mock('Faraday::Request')
384
+ mock_response = mock('Faraday::Response')
385
+ Faraday.expects(:new).returns(mock_conn)
386
+ mock_conn.stubs(:post).yields(mock_http_req).returns(mock_response)
387
+ mock_http_req.stubs(:url)
388
+ mock_http_req.stubs(:body=)
389
+ mock_response.stubs(:status).returns(200)
390
+ mock_response.stubs(:headers).returns(stub_headers)
391
+ mock_response.stubs(:body).returns(stub_body)
238
392
 
393
+ session = Aviator::Session.new(:config => valid_config[valid_env])
394
+ session.authenticate
239
395
 
240
- it 'raises an error if called before authenticating' do
241
- the_method = lambda { new_session.validate }
396
+ session.validate.must_equal true
242
397
 
243
- the_method.must_raise Aviator::Session::NotAuthenticatedError
244
- end
398
+ # Stub response status to 401 this time
399
+ mock_response.stubs(:status).returns(401)
245
400
 
401
+ session.validate.must_equal false
402
+ end
246
403
 
247
- it 'returns true even when a default token is used' do
248
- session = new_session
249
- credentials = config.openstack_admin[:auth_credentials]
250
404
 
251
- session.authenticate do |c|
252
- c[:username] = credentials[:username]
253
- c[:password] = credentials[:password]
254
- end
405
+ it 'raises an error if called before authenticating and no default session data is provided' do
406
+ session = Aviator::Session.new(:config => valid_config[valid_env])
255
407
 
256
- session.validate.must_equal true
257
- end
408
+ the_method = lambda { session.validate }
258
409
 
410
+ the_method.must_raise Aviator::Session::NotAuthenticatedError
259
411
  end
260
412
 
413
+ end
261
414
 
262
- describe '#xxx_service' do
263
415
 
264
- it 'returns an instance of the indicated service' do
265
- session = new_session
266
- session.authenticate
416
+ describe '#xxxxx_service' do
267
417
 
268
- session.identity_service.wont_be_nil
269
- end
418
+ it 'returns an instance of the indicated service' do
419
+ stub_http
270
420
 
271
- it 'returns an instance of the indicated service even if not authenticated' do
272
- session = new_session
273
- session.compute_service.wont_be_nil
274
- session.authenticated?.must_equal false
275
- end
421
+ session = Aviator::Session.new(:config => valid_config[valid_env])
422
+ session.authenticate
423
+
424
+ session.compute_service.wont_be_nil
425
+ end
426
+
427
+ it 'returns an instance of the indicated service even if not authenticated' do
428
+ session = Aviator::Session.new(:config => valid_config[valid_env])
276
429
 
430
+ session.authenticated?.must_equal false
431
+ session.compute_service.wont_be_nil
277
432
  end
278
433
 
279
- end # describe 'aviator/core/service'
434
+ end
280
435
 
281
- end # class Aviator::Test
436
+ end