aliyun-sdk 0.1.3 → 0.1.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/examples/aliyun/oss/bucket.rb +144 -0
- data/examples/aliyun/oss/object.rb +182 -0
- data/examples/aliyun/oss/resumable_download.rb +40 -0
- data/examples/aliyun/oss/resumable_upload.rb +46 -0
- data/examples/aliyun/oss/streaming.rb +124 -0
- data/lib/aliyun/oss/bucket.rb +78 -23
- data/lib/aliyun/oss/client.rb +2 -0
- data/lib/aliyun/oss/download.rb +62 -27
- data/lib/aliyun/oss/http.rb +6 -2
- data/lib/aliyun/oss/iterator.rb +18 -0
- data/lib/aliyun/oss/logging.rb +5 -2
- data/lib/aliyun/oss/multipart.rb +3 -2
- data/lib/aliyun/oss/object.rb +1 -1
- data/lib/aliyun/oss/protocol.rb +17 -21
- data/lib/aliyun/oss/upload.rb +58 -19
- data/lib/aliyun/oss/util.rb +1 -0
- data/lib/aliyun/oss/version.rb +1 -1
- data/spec/aliyun/oss/client/bucket_spec.rb +88 -2
- data/spec/aliyun/oss/client/resumable_download_spec.rb +8 -5
- data/spec/aliyun/oss/client/resumable_upload_spec.rb +7 -4
- data/spec/aliyun/oss/multipart_spec.rb +0 -10
- data/spec/aliyun/oss/object_spec.rb +9 -10
- data/tests/test_content_type.rb +100 -0
- data/tests/test_large_file.rb +66 -0
- data/tests/test_multipart.rb +105 -0
- data/tests/test_object_key.rb +71 -0
- data/tests/test_resumable.rb +41 -0
- metadata +19 -2
@@ -75,8 +75,9 @@ module Aliyun
|
|
75
75
|
expect(File.exist?("#{@file}.cpt")).to be false
|
76
76
|
expect(Dir.glob("#{@file}.part.*").empty?).to be true
|
77
77
|
|
78
|
-
expect(File.read(@file)
|
79
|
-
|
78
|
+
expect(File.read(@file).lines)
|
79
|
+
.to match_array((1..10).map{ |i| mock_object(i) })
|
80
|
+
expect(prg.size).to eq(10)
|
80
81
|
end
|
81
82
|
|
82
83
|
it "should resume when download part fails" do
|
@@ -103,7 +104,8 @@ module Aliyun
|
|
103
104
|
success = false
|
104
105
|
4.times do
|
105
106
|
begin
|
106
|
-
@bucket.resumable_download(
|
107
|
+
@bucket.resumable_download(
|
108
|
+
@object_key, @file, :part_size => 10, :threads => 1)
|
107
109
|
success = true
|
108
110
|
rescue
|
109
111
|
# pass
|
@@ -158,7 +160,8 @@ module Aliyun
|
|
158
160
|
success = false
|
159
161
|
4.times do
|
160
162
|
begin
|
161
|
-
@bucket.resumable_download(
|
163
|
+
@bucket.resumable_download(
|
164
|
+
@object_key, @file, :part_size => 10, :threads => 1)
|
162
165
|
success = true
|
163
166
|
rescue
|
164
167
|
# pass
|
@@ -197,7 +200,7 @@ module Aliyun
|
|
197
200
|
begin
|
198
201
|
@bucket.resumable_download(
|
199
202
|
@object_key, @file, :part_size => 10,
|
200
|
-
:cpt_file => cpt_file, :disable_cpt => true)
|
203
|
+
:cpt_file => cpt_file, :disable_cpt => true, :threads => 1)
|
201
204
|
success = true
|
202
205
|
rescue
|
203
206
|
# pass
|
@@ -96,7 +96,7 @@ module Aliyun
|
|
96
96
|
:post, /#{object_url}\?uploadId.*/).times(1)
|
97
97
|
|
98
98
|
expect(File.exist?("#{@file}.cpt")).to be false
|
99
|
-
expect(prg).to
|
99
|
+
expect(prg.size).to eq(10)
|
100
100
|
end
|
101
101
|
|
102
102
|
it "should restart when begin txn fails" do
|
@@ -149,7 +149,8 @@ module Aliyun
|
|
149
149
|
success = false
|
150
150
|
4.times do
|
151
151
|
begin
|
152
|
-
@bucket.resumable_upload(
|
152
|
+
@bucket.resumable_upload(
|
153
|
+
@object_key, @file, part_size: 10, threads: 1)
|
153
154
|
success = true
|
154
155
|
rescue
|
155
156
|
# pass
|
@@ -206,7 +207,8 @@ module Aliyun
|
|
206
207
|
success = false
|
207
208
|
4.times do
|
208
209
|
begin
|
209
|
-
@bucket.resumable_upload(
|
210
|
+
@bucket.resumable_upload(
|
211
|
+
@object_key, @file, part_size: 10, threads: 1)
|
210
212
|
success = true
|
211
213
|
rescue
|
212
214
|
# pass
|
@@ -251,7 +253,8 @@ module Aliyun
|
|
251
253
|
success = false
|
252
254
|
3.times do
|
253
255
|
begin
|
254
|
-
@bucket.resumable_upload(
|
256
|
+
@bucket.resumable_upload(
|
257
|
+
@object_key, @file, part_size: 10, threads: 1)
|
255
258
|
success = true
|
256
259
|
rescue
|
257
260
|
# pass
|
@@ -38,7 +38,6 @@ module Aliyun
|
|
38
38
|
xml.ListMultipartUploadsResult {
|
39
39
|
{
|
40
40
|
:prefix => 'Prefix',
|
41
|
-
:delimiter => 'Delimiter',
|
42
41
|
:limit => 'MaxUploads',
|
43
42
|
:id_marker => 'UploadIdMarker',
|
44
43
|
:next_id_marker => 'NextUploadIdMarker',
|
@@ -414,7 +413,6 @@ module Aliyun
|
|
414
413
|
query = {
|
415
414
|
'uploads' => '',
|
416
415
|
'prefix' => 'foo-',
|
417
|
-
'delimiter' => '-',
|
418
416
|
'upload-id-marker' => 'id-marker',
|
419
417
|
'key-marker' => 'key-marker',
|
420
418
|
'max-uploads' => 10,
|
@@ -426,7 +424,6 @@ module Aliyun
|
|
426
424
|
@protocol.list_multipart_uploads(
|
427
425
|
@bucket,
|
428
426
|
:prefix => 'foo-',
|
429
|
-
:delimiter => '-',
|
430
427
|
:id_marker => 'id-marker',
|
431
428
|
:key_marker => 'key-marker',
|
432
429
|
:limit => 10,
|
@@ -442,7 +439,6 @@ module Aliyun
|
|
442
439
|
query = {
|
443
440
|
'uploads' => '',
|
444
441
|
'prefix' => 'foo-',
|
445
|
-
'delimiter' => '-',
|
446
442
|
'upload-id-marker' => 'id-marker',
|
447
443
|
'key-marker' => 'key-marker',
|
448
444
|
'max-uploads' => 100,
|
@@ -459,7 +455,6 @@ module Aliyun
|
|
459
455
|
|
460
456
|
return_more = {
|
461
457
|
:prefix => 'foo-',
|
462
|
-
:delimiter => '-',
|
463
458
|
:id_marker => 'id-marker',
|
464
459
|
:key_marker => 'key-marker',
|
465
460
|
:next_id_marker => 'next-id-marker',
|
@@ -474,7 +469,6 @@ module Aliyun
|
|
474
469
|
txns, more = @protocol.list_multipart_uploads(
|
475
470
|
@bucket,
|
476
471
|
:prefix => 'foo-',
|
477
|
-
:delimiter => '-',
|
478
472
|
:id_marker => 'id-marker',
|
479
473
|
:key_marker => 'key-marker',
|
480
474
|
:limit => 100,
|
@@ -492,7 +486,6 @@ module Aliyun
|
|
492
486
|
query = {
|
493
487
|
'uploads' => '',
|
494
488
|
'prefix' => 'foo-',
|
495
|
-
'delimiter' => '-',
|
496
489
|
'upload-id-marker' => 'id-marker',
|
497
490
|
'key-marker' => 'key-marker',
|
498
491
|
'max-uploads' => 100,
|
@@ -516,7 +509,6 @@ module Aliyun
|
|
516
509
|
|
517
510
|
return_more = {
|
518
511
|
:prefix => 'foo-',
|
519
|
-
:delimiter => '中国のruby',
|
520
512
|
:id_marker => 'id-marker',
|
521
513
|
:key_marker => '杭州のruby',
|
522
514
|
:next_id_marker => 'next-id-marker',
|
@@ -528,7 +520,6 @@ module Aliyun
|
|
528
520
|
|
529
521
|
es_more = {
|
530
522
|
:prefix => 'foo-',
|
531
|
-
:delimiter => CGI.escape('中国のruby'),
|
532
523
|
:id_marker => 'id-marker',
|
533
524
|
:key_marker => CGI.escape('杭州のruby'),
|
534
525
|
:next_id_marker => 'next-id-marker',
|
@@ -545,7 +536,6 @@ module Aliyun
|
|
545
536
|
txns, more = @protocol.list_multipart_uploads(
|
546
537
|
@bucket,
|
547
538
|
:prefix => 'foo-',
|
548
|
-
:delimiter => '-',
|
549
539
|
:id_marker => 'id-marker',
|
550
540
|
:key_marker => 'key-marker',
|
551
541
|
:limit => 100,
|
@@ -54,16 +54,15 @@ module Aliyun
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def mock_delete(objects, opts = {})
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end.to_xml
|
57
|
+
# It may have invisible chars in object key which will corrupt
|
58
|
+
# libxml. So we're constructing xml body manually here.
|
59
|
+
body = '<?xml version="1.0"?>'
|
60
|
+
body << '<Delete>'
|
61
|
+
body << '<Quiet>' << (opts[:quiet]? true : false).to_s << '</Quiet>'
|
62
|
+
objects.each { |k|
|
63
|
+
body << '<Object><Key>' << k << '</Key></Object>'
|
64
|
+
}
|
65
|
+
body << '</Delete>'
|
67
66
|
end
|
68
67
|
|
69
68
|
def mock_delete_result(deleted, opts = {})
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'yaml'
|
3
|
+
$LOAD_PATH.unshift(File.expand_path("../../lib", __FILE__))
|
4
|
+
require 'aliyun/oss'
|
5
|
+
|
6
|
+
class TestContentType < Minitest::Test
|
7
|
+
def setup
|
8
|
+
Aliyun::OSS::Logging.set_log_level(Logger::DEBUG)
|
9
|
+
conf_file = '~/.oss.yml'
|
10
|
+
conf = YAML.load(File.read(File.expand_path(conf_file)))
|
11
|
+
client = Aliyun::OSS::Client.new(
|
12
|
+
:endpoint => conf['endpoint'],
|
13
|
+
:cname => conf['cname'],
|
14
|
+
:access_key_id => conf['id'],
|
15
|
+
:access_key_secret => conf['key'])
|
16
|
+
@bucket = client.get_bucket(conf['bucket'])
|
17
|
+
|
18
|
+
@types = {
|
19
|
+
"html" => "text/html",
|
20
|
+
"js" => "application/javascript",
|
21
|
+
"xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
22
|
+
"xltx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
|
23
|
+
"potx" => "application/vnd.openxmlformats-officedocument.presentationml.template",
|
24
|
+
"ppsx" => "application/vnd.openxmlformats-officedocument.presentationml.slideshow",
|
25
|
+
"pptx" => "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
26
|
+
"sldx" => "application/vnd.openxmlformats-officedocument.presentationml.slide",
|
27
|
+
"docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
28
|
+
"dotx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
|
29
|
+
"xlam" => "application/vnd.ms-excel.addin.macroEnabled.12",
|
30
|
+
"xlsb" => "application/vnd.ms-excel.sheet.binary.macroEnabled.12",
|
31
|
+
"apk" => "application/vnd.android.package-archive",
|
32
|
+
"" => "application/octet-stream"
|
33
|
+
}
|
34
|
+
|
35
|
+
@prefix = "tests/content_type/"
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_key(p, k)
|
39
|
+
"#{@prefix}#{p}obj" + (k.empty? ? "" : ".#{k}")
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_type_from_key
|
43
|
+
@types.each do |k, v|
|
44
|
+
key = get_key('from_key', k)
|
45
|
+
@bucket.put_object(key)
|
46
|
+
assert_equal v, @bucket.get_object(key).content_type
|
47
|
+
|
48
|
+
copy_key = get_key('copy.from_key', k)
|
49
|
+
@bucket.copy_object(key, copy_key)
|
50
|
+
assert_equal v, @bucket.get_object(copy_key).content_type
|
51
|
+
|
52
|
+
append_key = get_key('append.from_key', k)
|
53
|
+
@bucket.append_object(append_key, 0)
|
54
|
+
assert_equal v, @bucket.get_object(append_key).content_type
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_type_from_file
|
59
|
+
@types.each do |k, v|
|
60
|
+
upload_file = "/tmp/upload_file"
|
61
|
+
upload_file += ".#{k}" unless k.empty?
|
62
|
+
`touch #{upload_file}`
|
63
|
+
|
64
|
+
key = get_key('from_file', k)
|
65
|
+
@bucket.put_object(key, :file => upload_file)
|
66
|
+
assert_equal v, @bucket.get_object(key).content_type
|
67
|
+
|
68
|
+
append_key = get_key('append.from_file', k)
|
69
|
+
@bucket.append_object(append_key, 0, :file => upload_file)
|
70
|
+
assert_equal v, @bucket.get_object(append_key).content_type
|
71
|
+
|
72
|
+
multipart_key = get_key('multipart.from_file', k)
|
73
|
+
@bucket.resumable_upload(multipart_key, upload_file)
|
74
|
+
assert_equal v, @bucket.get_object(multipart_key).content_type
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_type_from_user
|
79
|
+
@types.each do |k, v|
|
80
|
+
upload_file = "/tmp/upload_file.html"
|
81
|
+
`touch #{upload_file}`
|
82
|
+
|
83
|
+
key = get_key('from_user', k)
|
84
|
+
@bucket.put_object(key, :file => upload_file, :content_type => v)
|
85
|
+
assert_equal v, @bucket.get_object(key).content_type
|
86
|
+
|
87
|
+
copy_key = get_key('copy.from_user', k)
|
88
|
+
@bucket.copy_object(key, copy_key, :content_type => v)
|
89
|
+
assert_equal v, @bucket.get_object(copy_key).content_type
|
90
|
+
|
91
|
+
append_key = get_key('append.from_user', k)
|
92
|
+
@bucket.append_object(append_key, 0, :file => upload_file, :content_type => v)
|
93
|
+
assert_equal v, @bucket.get_object(append_key).content_type
|
94
|
+
|
95
|
+
multipart_key = get_key('multipart.from_file', k)
|
96
|
+
@bucket.resumable_upload(multipart_key, upload_file, :content_type => v)
|
97
|
+
assert_equal v, @bucket.get_object(multipart_key).content_type
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'benchmark'
|
4
|
+
require 'yaml'
|
5
|
+
$LOAD_PATH.unshift(File.expand_path("../../lib", __FILE__))
|
6
|
+
require 'aliyun/oss'
|
7
|
+
|
8
|
+
class TestObjectKey < Minitest::Test
|
9
|
+
def setup
|
10
|
+
conf_file = '~/.oss.yml'
|
11
|
+
conf = YAML.load(File.read(File.expand_path(conf_file)))
|
12
|
+
client = Aliyun::OSS::Client.new(
|
13
|
+
:endpoint => conf['endpoint'],
|
14
|
+
:cname => conf['cname'],
|
15
|
+
:access_key_id => conf['id'],
|
16
|
+
:access_key_secret => conf['key'])
|
17
|
+
@bucket = client.get_bucket(conf['bucket'])
|
18
|
+
@prefix = 'tests/large_file/'
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_key(k)
|
22
|
+
@prefix + k
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_large_file_1gb
|
26
|
+
key = get_key("large_file_1gb")
|
27
|
+
Benchmark.bm(32) do |bm|
|
28
|
+
bm.report("Upload with put_object: ") do
|
29
|
+
@bucket.put_object(key, :file => './large_file_1gb')
|
30
|
+
end
|
31
|
+
|
32
|
+
bm.report("Upload with resumable_upload: ") do
|
33
|
+
@bucket.resumable_upload(key, './large_file_1gb')
|
34
|
+
end
|
35
|
+
|
36
|
+
bm.report("Download with get_object: ") do
|
37
|
+
@bucket.get_object(key, :file => './large_file_1gb')
|
38
|
+
end
|
39
|
+
|
40
|
+
bm.report("Download with resumable_download: ") do
|
41
|
+
@bucket.resumable_download(key, './large_file_1gb')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_large_file_8gb
|
47
|
+
key = get_key("large_file_8gb")
|
48
|
+
Benchmark.bm(32) do |bm|
|
49
|
+
bm.report("Upload with put_object: ") do
|
50
|
+
@bucket.put_object(key, :file => './large_file_8gb')
|
51
|
+
end
|
52
|
+
|
53
|
+
bm.report("Upload with resumable_upload: ") do
|
54
|
+
@bucket.resumable_upload(key, './large_file_8gb')
|
55
|
+
end
|
56
|
+
|
57
|
+
bm.report("Download with get_object: ") do
|
58
|
+
@bucket.get_object(key, :file => './large_file_8gb')
|
59
|
+
end
|
60
|
+
|
61
|
+
bm.report("Download with resumable_download: ") do
|
62
|
+
@bucket.resumable_download(key, './large_file_8gb')
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'yaml'
|
4
|
+
$LOAD_PATH.unshift(File.expand_path("../../lib", __FILE__))
|
5
|
+
require 'aliyun/oss'
|
6
|
+
|
7
|
+
class TestMultipart < Minitest::Unit::TestCase
|
8
|
+
def setup
|
9
|
+
conf_file = '~/.oss.yml'
|
10
|
+
conf = YAML.load(File.read(File.expand_path(conf_file)))
|
11
|
+
opts = {
|
12
|
+
endpoint: conf['endpoint'],
|
13
|
+
cname: conf['cname'],
|
14
|
+
access_key_id: conf['id'],
|
15
|
+
access_key_secret: conf['key'],
|
16
|
+
}
|
17
|
+
client = Aliyun::OSS::Client.new(opts)
|
18
|
+
@bucket_name = conf['bucket']
|
19
|
+
@bucket = client.get_bucket(@bucket_name)
|
20
|
+
@protocol = Aliyun::OSS::Protocol.new(Aliyun::OSS::Config.new(opts))
|
21
|
+
@prefix = 'tests/multipart/'
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_key(k)
|
25
|
+
@prefix + k
|
26
|
+
end
|
27
|
+
|
28
|
+
def clear_uploads
|
29
|
+
all = @bucket.list_uploads.to_a
|
30
|
+
all.each { |t| @bucket.abort_upload(t.id, t.object) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_key_marker
|
34
|
+
clear_uploads
|
35
|
+
|
36
|
+
# initiate 5 uploads
|
37
|
+
ids = []
|
38
|
+
5.times { |i|
|
39
|
+
id = @protocol.initiate_multipart_upload(@bucket_name, get_key("obj-#{i}"))
|
40
|
+
ids << id
|
41
|
+
}
|
42
|
+
|
43
|
+
all = @bucket.list_uploads(limit: 1).to_a
|
44
|
+
assert_equal ids, all.map(&:id)
|
45
|
+
|
46
|
+
after_1 = @bucket.list_uploads(key_marker: get_key("obj-0")).to_a
|
47
|
+
assert_equal ids[1, 5], after_1.map(&:id)
|
48
|
+
|
49
|
+
after_5 = @bucket.list_uploads(key_marker: get_key("obj-4")).to_a
|
50
|
+
assert after_5.empty?, after_5.to_s
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_id_marker
|
54
|
+
clear_uploads
|
55
|
+
|
56
|
+
# initiate 5 uploads
|
57
|
+
ids = []
|
58
|
+
5.times { |i|
|
59
|
+
id = @protocol.initiate_multipart_upload(@bucket_name, get_key("object"))
|
60
|
+
ids << id
|
61
|
+
}
|
62
|
+
ids.sort!
|
63
|
+
|
64
|
+
all = @bucket.list_uploads.to_a
|
65
|
+
assert_equal ids, all.map(&:id)
|
66
|
+
|
67
|
+
# id_marker is ignored
|
68
|
+
after_1 = @bucket.list_uploads(id_marker: ids[0]).to_a
|
69
|
+
assert_equal ids, after_1.map(&:id)
|
70
|
+
|
71
|
+
# id_marker is ignored
|
72
|
+
after_5 = @bucket.list_uploads(id_marker: ids[4]).to_a
|
73
|
+
assert_equal ids, after_5.map(&:id)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_id_key_marker
|
77
|
+
clear_uploads
|
78
|
+
|
79
|
+
# initiate 5 uploads
|
80
|
+
foo_ids = []
|
81
|
+
5.times { |i|
|
82
|
+
id = @protocol.initiate_multipart_upload(@bucket_name, get_key("foo"))
|
83
|
+
foo_ids << id
|
84
|
+
}
|
85
|
+
foo_ids.sort!
|
86
|
+
|
87
|
+
bar_ids = []
|
88
|
+
5.times { |i|
|
89
|
+
id = @protocol.initiate_multipart_upload(@bucket_name, get_key("bar"))
|
90
|
+
bar_ids << id
|
91
|
+
}
|
92
|
+
bar_ids.sort!
|
93
|
+
|
94
|
+
after_1 = @bucket.list_uploads(
|
95
|
+
id_marker: bar_ids[0], key_marker: get_key("bar"), limit: 1).to_a
|
96
|
+
assert_equal bar_ids[1, 5] + foo_ids, after_1.map(&:id)
|
97
|
+
|
98
|
+
after_5 = @bucket.list_uploads(
|
99
|
+
id_marker: bar_ids[4], key_marker: get_key("bar")).to_a
|
100
|
+
assert_equal foo_ids, after_5.map(&:id)
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_prefix
|
104
|
+
end
|
105
|
+
end
|