ruby-manta 1.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.
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ class MantaClient
2
+ LIB_VERSION = '1.1.0'
3
+ end
@@ -0,0 +1,27 @@
1
+ require File.expand_path('../lib/version', __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'ruby-manta'
5
+ s.version = MantaClient::LIB_VERSION
6
+ s.date = '2013-06-24'
7
+ s.summary = "Interface for Joyent's Manta service."
8
+ s.description = "A simple low-abstraction layer which communicates with Joyent's Manta service."
9
+ s.authors = ['Joyent']
10
+ s.email = 'marsell@joyent.com'
11
+ s.homepage = 'http://github.com/joyent/ruby-manta/'
12
+ s.license = 'MIT'
13
+
14
+ s.add_dependency('net-ssh', '>= 2.6.0')
15
+ s.add_dependency('httpclient', '>= 2.3.0.1')
16
+
17
+ s.files = ['LICENSE',
18
+ 'README.md',
19
+ 'ruby-manta.gemspec',
20
+ 'example.rb',
21
+ 'lib/version.rb',
22
+ 'lib/ruby-manta.rb',
23
+ 'tests/test_ruby-manta.rb']
24
+
25
+ s.test_files = s.files.grep(%r{^test})
26
+ s.require_paths = %w{lib}
27
+ end
@@ -0,0 +1,653 @@
1
+ require 'minitest/autorun'
2
+ require 'httpclient'
3
+ require File.expand_path('../../lib/ruby-manta', __FILE__)
4
+
5
+
6
+
7
+ class TestMantaClient < MiniTest::Unit::TestCase
8
+ @@client = nil
9
+ @@user = nil
10
+
11
+ def setup
12
+ if ! @@client
13
+ host = ENV['HOST']
14
+ key = ENV['KEY' ]
15
+ @@user = ENV['USER']
16
+
17
+ unless host && key && @@user
18
+ $stderr.puts 'Require HOST, USER and KEY env variables to run tests.'
19
+ $stderr.puts 'E.g. USER=john KEY=~/.ssh/john HOST=https://us-east.manta.joyent.com ruby tests/test_ruby-manta.rb'
20
+ exit
21
+ end
22
+
23
+ priv_key_data = File.read(key)
24
+ @@client = MantaClient.new(host, @@user, priv_key_data,
25
+ :disable_ssl_verification => true)
26
+
27
+ @@test_dir_path = '/%s/stor/ruby-manta-test' % @@user
28
+ end
29
+
30
+ teardown()
31
+
32
+ @@client.put_directory(@@test_dir_path)
33
+ end
34
+
35
+
36
+
37
+ def teardown
38
+ listing, _ = @@client.list_directory(@@test_dir_path)
39
+ listing.each do |entry, _|
40
+ path = @@test_dir_path + '/' + entry['name']
41
+ if entry['type'] == 'directory'
42
+ @@client.delete_directory(path)
43
+ else
44
+ @@client.delete_object(path)
45
+ end
46
+ end
47
+
48
+ @@client.delete_directory(@@test_dir_path)
49
+ rescue MantaClient::ResourceNotFound
50
+ end
51
+
52
+
53
+
54
+ def test_paths
55
+ def check(&blk)
56
+ begin
57
+ yield blk
58
+ assert false
59
+ rescue ArgumentError
60
+ end
61
+ end
62
+
63
+ good_obj_path = "/#{@@user}/stor/ruby-manta-test"
64
+ bad_obj_path = "/#{@@user}/stora/ruby-manta-test"
65
+
66
+ check { @@client.put_directory(bad_obj_path) }
67
+ check { @@client.put_object(bad_obj_path, 'asd') }
68
+ check { @@client.get_object(bad_obj_path) }
69
+ check { @@client.delete_object(bad_obj_path) }
70
+ check { @@client.put_directory(bad_obj_path) }
71
+ check { @@client.list_directory(bad_obj_path) }
72
+ check { @@client.delete_directory(bad_obj_path) }
73
+ check { @@client.put_snaplink(good_obj_path, bad_obj_path) }
74
+ check { @@client.put_snaplink(bad_obj_path, good_obj_path) }
75
+
76
+ good_job_path = "/#{@@user}/job/ruby-manta-test"
77
+ bad_job_path = "/#{@@user}/joba/ruby-manta-test"
78
+
79
+ check { @@client.get_job(bad_job_path) }
80
+ check { @@client.get_job_errors(bad_job_path) }
81
+ check { @@client.cancel_job(bad_job_path) }
82
+ check { @@client.add_job_keys(bad_job_path, [good_obj_path]) }
83
+ check { @@client.add_job_keys(good_job_path, [bad_obj_path]) }
84
+ check { @@client.end_job_input(bad_job_path) }
85
+ check { @@client.get_job_input(bad_job_path) }
86
+ check { @@client.get_job_output(bad_job_path) }
87
+ check { @@client.get_job_failures(bad_job_path) }
88
+ check { @@client.gen_signed_url(Time.now, :get, bad_obj_path) }
89
+ end
90
+
91
+
92
+
93
+ def test_directories
94
+ result, headers = @@client.put_directory(@@test_dir_path)
95
+ assert_equal result, true
96
+ assert headers.is_a? Hash
97
+
98
+ result, headers = @@client.put_directory(@@test_dir_path + '/dir1')
99
+ assert_equal result, true
100
+ assert headers.is_a? Hash
101
+
102
+ # since idempotent
103
+ result, headers = @@client.put_directory(@@test_dir_path + '/dir1')
104
+ assert_equal result, true
105
+ assert headers.is_a? Hash
106
+
107
+ result, headers = @@client.put_object(@@test_dir_path + '/obj1', 'obj1-data')
108
+ assert_equal result, true
109
+ assert headers.is_a? Hash
110
+
111
+ result, headers = @@client.put_object(@@test_dir_path + '/obj2', 'obj2-data')
112
+ assert_equal result, true
113
+ assert headers.is_a? Hash
114
+
115
+ result, headers = @@client.list_directory(@@test_dir_path)
116
+ assert headers.is_a? Hash
117
+ assert_equal result.size, 3
118
+
119
+ assert_equal result[0]['name'], 'dir1'
120
+ assert_equal result[0]['type'], 'directory'
121
+ assert result[0]['mtime'].match(/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{3}Z$/)
122
+
123
+ assert_equal result[1]['name'], 'obj1'
124
+ assert_equal result[1]['type'], 'object'
125
+ assert_equal result[1]['size'], 9
126
+ assert result[1]['mtime'].match(/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{3}Z$/)
127
+
128
+ assert_equal result[2]['name'], 'obj2'
129
+ assert_equal result[2]['type'], 'object'
130
+ assert_equal result[2]['size'], 9
131
+ assert result[2]['mtime'].match(/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{3}Z$/)
132
+
133
+ result, _ = @@client.list_directory(@@test_dir_path, :limit => 2)
134
+ assert_equal result.size, 2
135
+ assert_equal result[0]['name'], 'dir1'
136
+ assert_equal result[1]['name'], 'obj1'
137
+
138
+ result, _ = @@client.list_directory(@@test_dir_path, :limit => 1)
139
+ assert_equal result.size, 1
140
+ assert_equal result[0]['name'], 'dir1'
141
+
142
+ result, _ = @@client.list_directory(@@test_dir_path, :limit => 2,
143
+ :marker => 'obj1')
144
+ assert_equal result.size, 2
145
+ assert_equal result[0]['name'], 'obj1'
146
+ assert_equal result[1]['name'], 'obj2'
147
+
148
+ result, headers = @@client.list_directory(@@test_dir_path, :head => true)
149
+ assert_equal result, true
150
+ assert_equal headers['Result-Set-Size'], '3'
151
+
152
+ begin
153
+ @@client.delete_directory(@@test_dir_path)
154
+ assert false
155
+ rescue MantaClient::DirectoryNotEmpty
156
+ end
157
+
158
+ @@client.delete_directory(@@test_dir_path + '/dir1')
159
+ @@client.delete_object(@@test_dir_path + '/obj1')
160
+ @@client.delete_object(@@test_dir_path + '/obj2')
161
+
162
+ result, headers = @@client.delete_directory(@@test_dir_path)
163
+ assert_equal result, true
164
+ assert headers.is_a? Hash
165
+
166
+ begin
167
+ @@client.list_directory(@@test_dir_path + '/does-not-exist')
168
+ assert false
169
+ rescue MantaClient::ResourceNotFound
170
+ end
171
+
172
+ begin
173
+ @@client.put_directory(@@test_dir_path + '/dir1')
174
+ assert false
175
+ rescue MantaClient::DirectoryDoesNotExist
176
+ end
177
+ end
178
+
179
+
180
+
181
+ def test_objects
182
+ result, headers = @@client.put_object(@@test_dir_path + '/obj1', 'foo-data')
183
+ assert_equal result, true
184
+ assert headers.is_a? Hash
185
+
186
+ result, headers = @@client.get_object(@@test_dir_path + '/obj1')
187
+ assert_equal result, 'foo-data'
188
+ assert_equal headers['Content-Type'], 'application/x-www-form-urlencoded'
189
+
190
+ @@client.put_object(@@test_dir_path + '/obj1', 'bar-data',
191
+ :content_type => 'application/wacky',
192
+ :durability_level => 3)
193
+
194
+ result, headers = @@client.get_object(@@test_dir_path + '/obj1')
195
+ assert_equal result, 'bar-data'
196
+ assert_equal headers['Content-Type'], 'application/wacky'
197
+
198
+ result, headers = @@client.get_object(@@test_dir_path + '/obj1', :head => true)
199
+ assert_equal result, true
200
+ assert_equal headers['Content-Type'], 'application/wacky'
201
+
202
+ begin
203
+ @@client.put_object(@@test_dir_path + '/obj1', 'bar-data',
204
+ :durability_level => 999)
205
+ assert false
206
+ rescue MantaClient::InvalidDurabilityLevel
207
+ end
208
+
209
+ begin
210
+ @@client.get_object(@@test_dir_path + '/does-not-exist')
211
+ assert false
212
+ rescue MantaClient::ResourceNotFound
213
+ end
214
+
215
+ begin
216
+ @@client.delete_object(@@test_dir_path + '/does-not-exist')
217
+ assert false
218
+ rescue MantaClient::ResourceNotFound
219
+ end
220
+
221
+ result, headers = @@client.delete_object(@@test_dir_path + '/obj1')
222
+ assert_equal result, true
223
+ assert headers.is_a? Hash
224
+ end
225
+
226
+
227
+
228
+ def test_public
229
+ host = ENV['HOST'].gsub('https', 'http')
230
+ test_pub_dir_path = '/%s/public/ruby-manta-test' % @@user
231
+
232
+ @@client.put_directory(test_pub_dir_path)
233
+ @@client.put_object(test_pub_dir_path + '/obj1', 'foo-data')
234
+
235
+ client = HTTPClient.new
236
+ client.ssl_config.verify_mode = nil # temp hack
237
+ result = client.get(host + test_pub_dir_path + '/obj1')
238
+ assert_equal result.body, 'foo-data'
239
+
240
+ @@client.delete_object(test_pub_dir_path + '/obj1')
241
+ @@client.delete_directory(test_pub_dir_path)
242
+ end
243
+
244
+
245
+
246
+ def test_cors
247
+ cors_args = {
248
+ :access_control_allow_credentials => true,
249
+ :access_control_allow_headers => 'X-Random, X-Bar',
250
+ :access_control_allow_methods => 'GET, POST, DELETE',
251
+ :access_control_allow_origin => 'https://example.com:1234 http://127.0.0.1',
252
+ :access_control_expose_headers => 'X-Last-Read, X-Foo',
253
+ :access_control_max_age => 30
254
+ }
255
+
256
+ @@client.put_object(@@test_dir_path + '/obj1', 'foo-data', cors_args)
257
+
258
+ result, headers = @@client.get_object(@@test_dir_path + '/obj1')
259
+ assert_equal result, 'foo-data'
260
+
261
+ for name, value in [[ 'access-control-allow-methods', 'GET, POST, DELETE' ],
262
+ [ 'access-control-allow-origin', 'https://example.com:1234 http://127.0.0.1' ],
263
+ [ 'access-control-expose-headers', 'x-foo, x-last-read' ],
264
+ [ 'access-control-max-age', '30' ] ]
265
+ assert_equal headers[name], value
266
+ end
267
+
268
+ result, headers = @@client.get_object(@@test_dir_path + '/obj1',
269
+ :origin => 'https://example.com:1234')
270
+
271
+ assert_equal result, 'foo-data'
272
+
273
+ for name, value in [[ 'access-control-allow-methods', 'GET, POST, DELETE' ],
274
+ [ 'access-control-allow-origin', nil ],
275
+ [ 'access-control-expose-headers', 'x-foo, x-last-read' ],
276
+ [ 'access-control-max-age', nil ]]
277
+ assert_equal headers[name], value
278
+ end
279
+
280
+ @@client.put_directory(@@test_dir_path + '/dir', cors_args)
281
+
282
+ result, headers = @@client.list_directory(@@test_dir_path + '/dir')
283
+
284
+ for name, value in [[ 'access-control-allow-methods', 'GET, POST, DELETE' ],
285
+ [ 'access-control-allow-origin', 'https://example.com:1234 http://127.0.0.1' ],
286
+ [ 'access-control-expose-headers', 'x-foo, x-last-read' ],
287
+ [ 'access-control-max-age', '30' ] ]
288
+ assert_equal headers[name], value
289
+ end
290
+ end
291
+
292
+
293
+
294
+ def test_signed_urls
295
+ @@client.put_object(@@test_dir_path + '/obj1', 'foo-data')
296
+
297
+ url = @@client.gen_signed_url(Time.now + 500000, :get,
298
+ @@test_dir_path + '/obj1')
299
+
300
+ client = HTTPClient.new
301
+ result = client.get('http://' + url)
302
+ assert_equal result.body, 'foo-data'
303
+ end
304
+
305
+
306
+
307
+ def test_snaplinks
308
+ begin
309
+ @@client.put_snaplink(@@test_dir_path + '/obj1',
310
+ @@test_dir_path + '/obj2')
311
+ assert false
312
+ rescue MantaClient::SourceObjectNotFound
313
+ end
314
+
315
+ @@client.put_object(@@test_dir_path + '/obj1', 'foo-data')
316
+
317
+ result, headers = @@client.put_snaplink(@@test_dir_path + '/obj1',
318
+ @@test_dir_path + '/obj2')
319
+ assert_equal result, true
320
+ assert headers.is_a? Hash
321
+
322
+ @@client.put_object(@@test_dir_path + '/obj1', 'bar-data')
323
+
324
+ result, _ = @@client.get_object(@@test_dir_path + '/obj1')
325
+ assert_equal result, 'bar-data'
326
+
327
+ result, _ = @@client.get_object(@@test_dir_path + '/obj2')
328
+ assert_equal result, 'foo-data'
329
+ end
330
+
331
+
332
+
333
+ def test_reports
334
+ begin
335
+ @@client.list_directory('/%s/reportse' % @@user)
336
+ assert fail
337
+ rescue ArgumentError
338
+ end
339
+
340
+ result, headers = @@client.list_directory('/%s/reports' % @@user)
341
+ assert headers.is_a? Hash
342
+ assert result.is_a? Array
343
+ assert result.length > 0
344
+
345
+ result, headers = @@client.list_directory('/%s/reports/usage' % @@user)
346
+ assert headers.is_a? Hash
347
+ assert result.is_a? Array
348
+ assert result.length > 0
349
+ end
350
+
351
+
352
+
353
+ def test_conditionals_on_objects
354
+ result, headers = @@client.put_object(@@test_dir_path + '/obj1', 'foo-data',
355
+ :if_modified_since => Time.now)
356
+ assert_equal result, true
357
+
358
+ modified = headers['Last-Modified']
359
+ assert modified
360
+
361
+ sleep 1
362
+
363
+ begin
364
+ @@client.put_object(@@test_dir_path + '/obj1', 'bar-data',
365
+ :if_modified_since => modified)
366
+ assert fail
367
+ rescue MantaClient::PreconditionFailed
368
+ end
369
+
370
+ result, headers = @@client.get_object(@@test_dir_path + '/obj1')
371
+ assert_equal result, 'foo-data'
372
+ assert_equal headers['Last-Modified'], modified
373
+
374
+ @@client.put_object(@@test_dir_path + '/obj1', 'bar-data',
375
+ :if_unmodified_since => modified)
376
+
377
+ result, headers = @@client.get_object(@@test_dir_path + '/obj1')
378
+ assert_equal result, 'bar-data'
379
+ assert headers['Last-Modified'] != modified
380
+
381
+ etag = headers['Etag']
382
+
383
+ begin
384
+ @@client.put_object(@@test_dir_path + '/obj1', 'foo-data',
385
+ :if_none_match => etag)
386
+ assert false
387
+ rescue MantaClient::PreconditionFailed
388
+ end
389
+
390
+ result, headers = @@client.get_object(@@test_dir_path + '/obj1')
391
+ assert_equal result, 'bar-data'
392
+ assert_equal headers['Etag'], etag
393
+
394
+ @@client.put_object(@@test_dir_path + '/obj1', 'foo-data',
395
+ :if_match => etag)
396
+
397
+ result, headers = @@client.get_object(@@test_dir_path + '/obj1')
398
+ assert_equal result, 'foo-data'
399
+ assert headers['Etag'] != etag
400
+
401
+ begin
402
+ @@client.get_object(@@test_dir_path + '/obj1', :if_match => etag)
403
+ assert false
404
+ rescue MantaClient::PreconditionFailed
405
+ end
406
+
407
+ etag = headers['Etag']
408
+ modified = headers['Last-Modified']
409
+
410
+ result, headers = @@client.get_object(@@test_dir_path + '/obj1',
411
+ :if_match => etag)
412
+ assert_equal result, 'foo-data'
413
+ assert_equal headers['Etag'], etag
414
+
415
+ result, headers = @@client.get_object(@@test_dir_path + '/obj1',
416
+ :if_none_match => etag)
417
+ assert_equal result, nil
418
+ assert_equal headers['Etag'], etag
419
+
420
+ result, headers = @@client.get_object(@@test_dir_path + '/obj1',
421
+ :if_none_match => 'blahblah')
422
+ assert_equal result, 'foo-data'
423
+ assert_equal headers['Etag'], etag
424
+
425
+ begin
426
+ @@client.put_snaplink(@@test_dir_path + '/obj1',
427
+ @@test_dir_path + '/obj2',
428
+ :if_none_match => etag)
429
+ assert false
430
+ rescue MantaClient::PreconditionFailed
431
+ end
432
+
433
+ result, headers = @@client.put_snaplink(@@test_dir_path + '/obj1',
434
+ @@test_dir_path + '/obj2',
435
+ :if_match => etag)
436
+ assert true
437
+ assert_equal headers['Etag'], etag
438
+
439
+ begin
440
+ @@client.put_snaplink(@@test_dir_path + '/obj1',
441
+ @@test_dir_path + '/obj3',
442
+ :if_modified_since => modified)
443
+ assert false
444
+ rescue MantaClient::PreconditionFailed
445
+ end
446
+
447
+ @@client.put_snaplink(@@test_dir_path + '/obj1', @@test_dir_path + '/obj3',
448
+ :if_unmodified_since => modified)
449
+
450
+ result, headers = @@client.put_snaplink(@@test_dir_path + '/obj1',
451
+ @@test_dir_path + '/obj4',
452
+ :if_unmodified_since => modified)
453
+ assert true
454
+
455
+ modified = headers['Last Modified']
456
+
457
+ begin
458
+ @@client.delete_object(@@test_dir_path + '/obj1', :if_none_match => etag)
459
+ assert false
460
+ rescue MantaClient::PreconditionFailed
461
+ end
462
+
463
+ result, _ = @@client.delete_object(@@test_dir_path + '/obj1', :if_match => etag)
464
+ assert_equal result, true
465
+
466
+ sleep 1
467
+
468
+ begin
469
+ @@client.delete_object(@@test_dir_path + '/obj3', :if_unmodified_since => Time.now - 10000)
470
+ assert false
471
+ rescue MantaClient::PreconditionFailed
472
+ end
473
+
474
+ begin
475
+ @@client.delete_object(@@test_dir_path + '/obj3', :if_modified_since => Time.now)
476
+ assert false
477
+ rescue MantaClient::PreconditionFailed
478
+ end
479
+
480
+ @@client.delete_object(@@test_dir_path + '/obj3', :if_unmodified_since => Time.now)
481
+ @@client.delete_object(@@test_dir_path + '/obj4', :if_modified_since=> Time.now - 10000)
482
+
483
+
484
+ for obj_name in ['/obj1', '/obj3', '/obj4']
485
+ begin
486
+ @@client.get_object(@@test_dir_path + obj_name)
487
+ assert false
488
+ rescue MantaClient::ResourceNotFound
489
+ end
490
+ end
491
+ end
492
+
493
+
494
+
495
+ # This test is definitely not pretty, but splitting it up will make it
496
+ # take much longer due to the redundant creation of jobs. Perhaps that's
497
+ # the wrong choice...
498
+ def test_jobs
499
+ result, headers = @@client.list_jobs(:running)
500
+ assert headers.is_a? Hash
501
+
502
+ result.each do |entry|
503
+ path = '/%s/jobs/%s' % [ @@user, entry['name'] ]
504
+ @@client.cancel_job(path)
505
+ end
506
+
507
+ begin
508
+ @@client.create_job({})
509
+ assert false
510
+ rescue ArgumentError
511
+ end
512
+
513
+ result, headers = @@client.list_jobs(:running)
514
+ assert_equal result, []
515
+ assert headers.is_a? Hash
516
+
517
+ path, headers = @@client.create_job({ :phases => [{ :exec => 'grep foo' }] })
518
+ assert path =~ Regexp.new('^/' + @@user + '/jobs/.+')
519
+ assert headers.is_a? Hash
520
+
521
+ result, headers = @@client.cancel_job(path)
522
+ assert_equal result, true
523
+ assert headers.is_a? Hash
524
+
525
+ path, _ = @@client.create_job({ :phases => [{ :exec => 'grep foo' }] })
526
+
527
+ result, _ = @@client.list_jobs(:all)
528
+ result.each do |job|
529
+ assert job['name' ] =~ /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
530
+ assert job['mtime'] =~ /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d\d\dZ$/
531
+ assert_equal job['type'], 'directory'
532
+ end
533
+
534
+ assert result.size >= 1
535
+
536
+ begin
537
+ @@client.list_jobs(:some)
538
+ assert false
539
+ rescue ArgumentError
540
+ end
541
+
542
+ jobs, _ = @@client.list_jobs(:running)
543
+ assert_equal jobs.size, 1
544
+ assert_equal jobs[0]['type'], 'directory'
545
+ assert_equal jobs[0]['name'], path.split('/').last
546
+
547
+ # Commented out until HEAD here by Manta
548
+ # jobs, headers = @@client.list_jobs(:running, :head => true)
549
+ # assert_equal jobs, true
550
+ # assert_equal headers['Result-Set-Size'], 1
551
+
552
+ job, headers = @@client.get_job(path)
553
+ assert headers.is_a? Hash
554
+ assert job['name' ].is_a? String
555
+ assert job['phases' ].is_a? Array
556
+ assert job['timeCreated'].match(/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d\d\dZ$/)
557
+ assert_equal job['id' ], path.split('/').last
558
+ assert_equal job['state' ], 'running'
559
+ assert_equal job['cancelled'], false
560
+ assert_equal job['timeDone' ], nil
561
+
562
+ @@client.put_object(@@test_dir_path + '/obj1', 'foo-data')
563
+ @@client.put_object(@@test_dir_path + '/obj2', 'bar-data')
564
+
565
+ obj_key_paths = [@@test_dir_path + '/obj1',
566
+ @@test_dir_path + '/obj2',
567
+ @@test_dir_path + '/obj3']
568
+
569
+ result, headers = @@client.add_job_keys(path, obj_key_paths)
570
+ assert_equal result, true
571
+ assert headers.is_a? Hash
572
+
573
+ result, headers = @@client.get_job_input(path)
574
+ assert_equal result.sort, obj_key_paths.sort
575
+ assert headers.is_a? Hash
576
+
577
+ begin
578
+ @@client.get_job_input(path + 'a')
579
+ assert false
580
+ rescue MantaClient::ResourceNotFound
581
+ end
582
+
583
+ begin
584
+ @@client.get_job_output(path + 'a')
585
+ assert false
586
+ rescue MantaClient::ResourceNotFound
587
+ end
588
+
589
+ begin
590
+ @@client.get_job_failures(path + 'a')
591
+ assert false
592
+ rescue MantaClient::ResourceNotFound
593
+ end
594
+
595
+ begin
596
+ @@client.get_job_errors(path + 'a')
597
+ assert false
598
+ rescue MantaClient::ResourceNotFound
599
+ end
600
+
601
+ begin
602
+ @@client.end_job_input(path + 'a')
603
+ assert false
604
+ rescue MantaClient::ResourceNotFound
605
+ end
606
+
607
+ result, headers = @@client.end_job_input(path)
608
+ assert_equal result, true
609
+ assert headers.is_a? Hash
610
+
611
+ for i in (1...10)
612
+ job, _ = @@client.get_job(path)
613
+ break if job['state'] == 'done'
614
+ sleep 1
615
+ end
616
+
617
+ result, headers = @@client.get_job_output(path)
618
+ assert headers.is_a? Hash
619
+
620
+ result, _ = @@client.get_object(result.first)
621
+ assert_equal result, "foo-data\n"
622
+
623
+ result, headers = @@client.get_job_failures(path)
624
+ assert_equal result.sort, obj_key_paths.slice(1, 2).sort
625
+ assert headers.is_a? Hash
626
+
627
+ result, headers = @@client.get_job_errors(path)
628
+ assert_equal result.size, 2
629
+ assert headers.is_a? Hash
630
+
631
+ obj2_result, obj3_result = result.sort { |i,j| i['input'] <=> j['input'] }
632
+
633
+ assert obj2_result['what']
634
+ assert obj2_result['stderr']
635
+ assert_equal obj2_result['code' ], 'UserTaskError'
636
+ assert_equal obj2_result['message'], 'user command exited with code 1'
637
+ assert_equal obj2_result['input' ], obj_key_paths[1]
638
+ assert_equal obj2_result['phase' ], '0'
639
+
640
+ assert obj3_result['what']
641
+ assert obj2_result['stderr']
642
+ assert_equal obj3_result['code' ], 'ResourceNotFoundError'
643
+ assert obj3_result['message'] =~ /^no such object/
644
+ assert_equal obj3_result['input' ], obj_key_paths[2]
645
+ assert_equal obj3_result['phase' ], '0'
646
+
647
+ begin
648
+ @@client.cancel_job(path)
649
+ assert fail
650
+ rescue MantaClient::InvalidJobState
651
+ end
652
+ end
653
+ end