ceph-ruby-livelink 1.5.1
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 +7 -0
- data/.cluster.example.yml +19 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.rubocop.yml +2 -0
- data/Gemfile +4 -0
- data/Guardfile +20 -0
- data/LICENSE.txt +22 -0
- data/README.md +1 -0
- data/Rakefile +7 -0
- data/ceph-ruby.gemspec +31 -0
- data/lib/ceph-ruby.rb +32 -0
- data/lib/ceph-ruby/cluster.rb +129 -0
- data/lib/ceph-ruby/cluster_helper.rb +39 -0
- data/lib/ceph-ruby/lib/rados.rb +158 -0
- data/lib/ceph-ruby/lib/rbd.rb +65 -0
- data/lib/ceph-ruby/pool.rb +117 -0
- data/lib/ceph-ruby/pool_enumerator.rb +32 -0
- data/lib/ceph-ruby/pool_helper.rb +46 -0
- data/lib/ceph-ruby/rados_aio_completion.rb +42 -0
- data/lib/ceph-ruby/rados_aio_object.rb +37 -0
- data/lib/ceph-ruby/rados_block_device.rb +118 -0
- data/lib/ceph-ruby/rados_block_device_helper.rb +39 -0
- data/lib/ceph-ruby/rados_object.rb +124 -0
- data/lib/ceph-ruby/rados_object_enumerator.rb +89 -0
- data/lib/ceph-ruby/version.rb +3 -0
- data/lib/ceph-ruby/xattr.rb +67 -0
- data/lib/ceph-ruby/xattr_enumerator.rb +62 -0
- data/spec/ceph_ruby_cluster_spec.rb +101 -0
- data/spec/ceph_ruby_pool_enumerator_spec.rb +55 -0
- data/spec/ceph_ruby_pool_spec.rb +177 -0
- data/spec/ceph_ruby_rados_object_enumerator_spec.rb +88 -0
- data/spec/ceph_ruby_rados_object_spec.rb +303 -0
- data/spec/ceph_ruby_xattr_enumerator_spec.rb +88 -0
- data/spec/ceph_ruby_xattr_spec.rb +122 -0
- data/spec/spec_helper.rb +23 -0
- data/tasks/rspec.rake +4 -0
- data/tasks/rubocop.rake +13 -0
- metadata +236 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CephRuby::Pool do
|
4
|
+
let(:config) { cluster_config }
|
5
|
+
let(:spconfig) { spec_config }
|
6
|
+
let(:cluster) { ::CephRuby::Cluster.new(config) }
|
7
|
+
let(:name) { spconfig[:pool][:name] }
|
8
|
+
let(:pool_enumerator) { cluster.pools }
|
9
|
+
subject { pool_enumerator }
|
10
|
+
before do
|
11
|
+
RSpec.configure do |c|
|
12
|
+
c.filter_run_excluding(
|
13
|
+
requires_create_delete: true
|
14
|
+
) unless spconfig[:pool][:create_delete]
|
15
|
+
c.filter_run_excluding(
|
16
|
+
requires_create_delete: false
|
17
|
+
) if spconfig[:pool][:create_delete]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'PoolEnumerator Object' do
|
22
|
+
it 'Should be a ::CephRuby::PoolEnumerator object' do
|
23
|
+
expect(subject).to be_a ::CephRuby::PoolEnumerator
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should respond to each' do
|
27
|
+
expect(subject).to respond_to :each
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should respond to size' do
|
31
|
+
expect(subject).to respond_to :size
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'without the test pool created', requires_create_delete: true do
|
35
|
+
it 'should not include the test pool' do
|
36
|
+
expect(subject.include?(cluster.pool(name))).to be false
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'with the test pool created', requires_create_delete: true do
|
40
|
+
before { cluster.pool(name, &:create) }
|
41
|
+
after { cluster.pool(name, &:destroy) }
|
42
|
+
subject { cluster.pools }
|
43
|
+
it 'should include the test pool' do
|
44
|
+
expect(subject.include?(cluster.pool(name))).to be true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'when already created', requires_create_delete: false do
|
50
|
+
it 'should include the test pool' do
|
51
|
+
expect(subject.include?(cluster.pool(name))).to be true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CephRuby::Pool do
|
4
|
+
let(:config) { cluster_config }
|
5
|
+
let(:cluster) { ::CephRuby::Cluster.new(config) }
|
6
|
+
let(:name) { config[:pool][:name] }
|
7
|
+
let(:pool) { cluster.pool(name) }
|
8
|
+
subject { pool }
|
9
|
+
before do
|
10
|
+
RSpec.configure do |c|
|
11
|
+
c.filter_run_excluding(
|
12
|
+
requires_create_delete: true
|
13
|
+
) unless config[:pool][:create_delete]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'Pool Object' do
|
18
|
+
it 'Should be a ::CephRuby::Pool object' do
|
19
|
+
expect(subject).to be_a ::CephRuby::Pool
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'should respond to' do
|
23
|
+
it 'close' do
|
24
|
+
expect(subject).to respond_to :close
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'rados_object' do
|
28
|
+
expect(subject).to respond_to :rados_object
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'rados_object_enumerator' do
|
32
|
+
expect(subject).to respond_to :rados_object_enumerator
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'rados_block_device' do
|
36
|
+
expect(subject).to respond_to :rados_block_device
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'open?' do
|
40
|
+
expect(subject).to respond_to 'open?'
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'ensure_open' do
|
44
|
+
expect(subject).to respond_to :ensure_open
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'create' do
|
48
|
+
expect(subject).to respond_to :create
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'id' do
|
52
|
+
expect(subject).to respond_to :id
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'auid=' do
|
56
|
+
expect(subject).to respond_to :auid=
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'auid' do
|
60
|
+
expect(subject).to respond_to :auid
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'open' do
|
64
|
+
expect(subject).to respond_to :open
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'create' do
|
68
|
+
expect(subject).to respond_to :create
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'destroy' do
|
72
|
+
expect(subject).to respond_to :destroy
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'stat' do
|
76
|
+
expect(subject).to respond_to :stat
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'flush_aio' do
|
80
|
+
expect(subject).to respond_to :flush_aio
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe 'before creation', requires_create_delete: true do
|
85
|
+
it 'should not exist' do
|
86
|
+
expect(subject.exist?).to be false
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should have the same name' do
|
90
|
+
expect(subject.name).to equal name
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should not be open' do
|
94
|
+
expect(subject.open?).to be false
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'destroy should error' do
|
98
|
+
expect { subject.destroy }.to raise_exception(Errno::ENOENT)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should be creatable' do
|
102
|
+
expect { subject.create }.not_to raise_exception
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe 'after creation' do
|
107
|
+
it 'should not be creatable' do
|
108
|
+
expect { subject.create }.to raise_exception Errno::EEXIST
|
109
|
+
end
|
110
|
+
|
111
|
+
describe 'auid' do
|
112
|
+
it 'should be an integer' do
|
113
|
+
expect(subject.auid).to be_a Integer
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe 'stat' do
|
118
|
+
subject { pool.stat }
|
119
|
+
|
120
|
+
it 'should be a hash' do
|
121
|
+
expect(subject).to be_a Hash
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should have the correct keys' do
|
125
|
+
expect(subject.key?(:num_bytes)).to be true
|
126
|
+
expect(subject.key?(:num_kb)).to be true
|
127
|
+
expect(subject.key?(:num_objects)).to be true
|
128
|
+
expect(subject.key?(:num_object_clones)).to be true
|
129
|
+
expect(subject.key?(:num_object_copies)).to be true
|
130
|
+
expect(subject.key?(:num_objects_missing_on_primary)).to be true
|
131
|
+
expect(subject.key?(:num_objects_unfound)).to be true
|
132
|
+
expect(subject.key?(:num_objects_degraded)).to be true
|
133
|
+
expect(subject.key?(:num_rd)).to be true
|
134
|
+
expect(subject.key?(:num_wr)).to be true
|
135
|
+
expect(subject.key?(:num_wr_kb)).to be true
|
136
|
+
end
|
137
|
+
end
|
138
|
+
describe 'when opened' do
|
139
|
+
it 'open? should be true' do
|
140
|
+
subject.open
|
141
|
+
expect(subject.open?).to be true
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'should still be open after ensure_open is called' do
|
145
|
+
subject.ensure_open
|
146
|
+
expect(subject.open?).to be true
|
147
|
+
end
|
148
|
+
|
149
|
+
describe 'when closed' do
|
150
|
+
it 'should be closed' do
|
151
|
+
subject.close
|
152
|
+
expect(subject.open?).to be false
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should be open after ensure_open is called' do
|
156
|
+
subject.ensure_open
|
157
|
+
expect(subject.open?).to be true
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe 'when opening a rados_object' do
|
163
|
+
it 'should return a RadosObject' do
|
164
|
+
expect(
|
165
|
+
subject.rados_object('test_object')
|
166
|
+
).to be_a ::CephRuby::RadosObject
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe 'when destroying the pool', requires_create_delete: true do
|
171
|
+
it 'should not be destroyable' do
|
172
|
+
expect { subject.destroy }.to_not raise_exception
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CephRuby::RadosObjectEnumerator do
|
4
|
+
let(:config) { cluster_config }
|
5
|
+
let(:cluster) { ::CephRuby::Cluster.new(config) }
|
6
|
+
let(:pool_name) { config[:pool][:name] }
|
7
|
+
let(:crush_id) { config[:pool][:rule_id] }
|
8
|
+
let(:pool) { cluster.pool(pool_name) }
|
9
|
+
let(:object_name) { config[:pool][:object_name] }
|
10
|
+
|
11
|
+
describe 'pool creation', requires_create_delete: true do
|
12
|
+
subject { pool }
|
13
|
+
it 'should be creatable' do
|
14
|
+
expect { pool.create(rule_id: crush_id) }.to_not raise_exception
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'RadosObjectEnumerator' do
|
19
|
+
let(:enumerator) { pool.rados_object_enumerator }
|
20
|
+
|
21
|
+
subject { enumerator }
|
22
|
+
|
23
|
+
describe 'instance' do
|
24
|
+
it 'should respond to paginate' do
|
25
|
+
expect(subject).to respond_to :paginate
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should respond to each' do
|
29
|
+
expect(subject).to respond_to :each
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should respond to page' do
|
33
|
+
expect(subject).to respond_to :page
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should respond to position' do
|
37
|
+
expect(subject).to respond_to :position
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should respond to close' do
|
41
|
+
expect(subject).to respond_to :close
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should respond to open' do
|
45
|
+
expect(subject).to respond_to :open
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should respond to open?' do
|
49
|
+
expect(subject).to respond_to :open?
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should be a CephRuby::RadosObjectEnumerator' do
|
53
|
+
expect(subject).to be_a ::CephRuby::RadosObjectEnumerator
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'on new pool' do
|
58
|
+
it 'should be empty' do
|
59
|
+
expect(subject.inject(0) { |a, _e| a + 1 }).to be 0
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe 'after adding 10 objects' do
|
64
|
+
before do
|
65
|
+
10.times do |i|
|
66
|
+
pool.rados_object("#{object_name}.#{i}") do |obj|
|
67
|
+
obj.overwrite('some random content')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should now have 10 items in it' do
|
72
|
+
expect(subject.inject(0) { |a, _e| a + 1 }).to be 10
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should yield RadosObjects from each' do
|
76
|
+
expect(subject.first).to be_a ::CephRuby::RadosObject
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'pool tidyup', requires_create_delete: true do
|
83
|
+
subject { pool }
|
84
|
+
it 'should be destroyable' do
|
85
|
+
expect { pool.destroy }.to_not raise_exception
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,303 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CephRuby::RadosObject do
|
4
|
+
let(:config) { cluster_config }
|
5
|
+
let(:cluster) { ::CephRuby::Cluster.new(config) }
|
6
|
+
let(:pool_name) { config[:pool][:name] }
|
7
|
+
let(:crush_id) { config[:pool][:rule_id] }
|
8
|
+
let(:pool) { cluster.pool(pool_name) }
|
9
|
+
let(:object_name) { config[:pool][:object_name] }
|
10
|
+
|
11
|
+
describe 'pool creation', requires_create_delete: true do
|
12
|
+
subject { pool }
|
13
|
+
it 'should be creatable' do
|
14
|
+
expect { pool.create(rule_id: crush_id) }.to_not raise_exception
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'Named Rados Object' do
|
19
|
+
let(:rados_object) { pool.rados_object(object_name) }
|
20
|
+
subject { rados_object }
|
21
|
+
let(:xattribute_key) { 'testxattr_key' }
|
22
|
+
let(:xattribute_val) { 'testxattr_value' }
|
23
|
+
|
24
|
+
it 'Should be a ::CephRuby::RadosObject object' do
|
25
|
+
expect(subject).to be_a ::CephRuby::RadosObject
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should respond to name with the name passed to the constructor' do
|
29
|
+
expect(subject.name).to equal object_name
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'should respond to' do
|
33
|
+
it 'write' do
|
34
|
+
expect(subject).to respond_to :write
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'overwrite' do
|
38
|
+
expect(subject).to respond_to :overwrite
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'append' do
|
42
|
+
expect(subject).to respond_to :append
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'read' do
|
46
|
+
expect(subject).to respond_to :read
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'destroy' do
|
50
|
+
expect(subject).to respond_to :destroy
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'resize' do
|
54
|
+
expect(subject).to respond_to :resize
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'xattr' do
|
58
|
+
expect(subject).to respond_to :xattr
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'xattr_enumerator' do
|
62
|
+
expect(subject).to respond_to :xattr_enumerator
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'stat' do
|
66
|
+
expect(subject).to respond_to :stat
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'size' do
|
70
|
+
expect(subject).to respond_to :size
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'mtime' do
|
74
|
+
expect(subject).to respond_to :mtime
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'exist?' do
|
78
|
+
expect(subject).to respond_to 'exist?'
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'exists?' do
|
82
|
+
expect(subject).to respond_to 'exists?'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe 'object interaction ' do
|
87
|
+
let(:content) do
|
88
|
+
'sample text sample text sample text sample text '\
|
89
|
+
'sample text sample text sample text sample text sample text'
|
90
|
+
end
|
91
|
+
let(:larger_content) do
|
92
|
+
'larger sample text larger sample text larger sample '\
|
93
|
+
'text larger sample text larger sample text larger sample '\
|
94
|
+
'text larger sample text larger sample text larger sample text'
|
95
|
+
end
|
96
|
+
|
97
|
+
describe 'before creation' do
|
98
|
+
it 'calling stat should raise an exception' do
|
99
|
+
expect { subject.stat }.to raise_exception Errno::ENOENT
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'should not exist' do
|
103
|
+
expect(subject.exist?).to be false
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should not be readable' do
|
107
|
+
expect { subject.read(0, 1) }.to raise_exception Errno::ENOENT
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should be able to write data to the object' do
|
111
|
+
expect { subject.write(0, content) }.not_to raise_exception
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe 'once created' do
|
116
|
+
it 'should exist' do
|
117
|
+
expect(subject.exist?).to be true
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should not raise an exception for stat' do
|
121
|
+
expect { subject.stat }.not_to raise_exception
|
122
|
+
end
|
123
|
+
|
124
|
+
describe 'stat' do
|
125
|
+
subject { rados_object.stat }
|
126
|
+
it 'should be a hash' do
|
127
|
+
expect(subject).to be_a ::Hash
|
128
|
+
end
|
129
|
+
|
130
|
+
describe 'mtime key' do
|
131
|
+
it 'should exist' do
|
132
|
+
expect(subject.key?(:mtime)).to be true
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'should equal object mtime' do
|
136
|
+
expect(rados_object.mtime).to eq subject[:mtime]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe 'size key' do
|
141
|
+
it 'should exist' do
|
142
|
+
expect(subject.key?(:size)).to be true
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'should equal object size' do
|
146
|
+
expect(rados_object.size).to eq subject[:size]
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should have the same object size as smaller content' do
|
152
|
+
expect(subject.size).to eq(content.bytesize)
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should match the content on read' do
|
156
|
+
expect(subject.read(0, subject.size)).to eq(content)
|
157
|
+
end
|
158
|
+
|
159
|
+
describe 'reading the object' do
|
160
|
+
let(:limit) { 50 }
|
161
|
+
let(:offset) { 5 }
|
162
|
+
|
163
|
+
describe 'with a limit' do
|
164
|
+
describe 'with 0 offset' do
|
165
|
+
subject { rados_object.read(0, limit) }
|
166
|
+
|
167
|
+
it 'should be #{limit} bytes long' do
|
168
|
+
expect(subject.length).to eq(limit)
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should match the content substring for that range' do
|
172
|
+
expect(subject).to eq(content[0..(limit - 1)])
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe 'with an offset' do
|
177
|
+
subject { rados_object.read(offset, limit) }
|
178
|
+
|
179
|
+
it 'should be the correct length' do
|
180
|
+
expect(subject.length).to eq(limit)
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'should match the content substring for that range' do
|
184
|
+
expect(subject).to eq(content[offset..(offset + limit - 1)])
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe 'with no limit' do
|
190
|
+
describe 'with an offset' do
|
191
|
+
subject { rados_object.read(offset, rados_object.size) }
|
192
|
+
|
193
|
+
it 'should be the correct length' do
|
194
|
+
expect(subject.length).to eq(content.bytesize - offset)
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'should match the content substring for that range' do
|
198
|
+
expect(subject).to eq(content[offset..-1])
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe 'resize' do
|
205
|
+
let(:truncate_size) { 15 }
|
206
|
+
|
207
|
+
it 'should not raise exception' do
|
208
|
+
expect { subject.resize(truncate_size) }.not_to raise_exception
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'should make the object size equal the new size' do
|
212
|
+
expect(subject.size).to eq truncate_size
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
describe 'when re-writing with larger content with offset 0' do
|
218
|
+
it 'should be able to write data to the object' do
|
219
|
+
expect { subject.write(0, larger_content) }.not_to raise_exception
|
220
|
+
end
|
221
|
+
|
222
|
+
describe 'after writing larger content' do
|
223
|
+
it 'should have the new object size' do
|
224
|
+
expect(subject.size).not_to eq(content.bytesize)
|
225
|
+
expect(subject.size).to eq(larger_content.bytesize)
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'contents should match the larger content' do
|
229
|
+
expect(subject.read(0, subject.size)).to eq(larger_content)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe 'when re-re-writing the smaller content with 0 offset' do
|
234
|
+
before { subject.write(0, content) }
|
235
|
+
it 'should match the larger file size' do
|
236
|
+
expect(subject.size).to eq(larger_content.bytesize)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
describe 'when overwriting with the smaller content' do
|
242
|
+
it 'should be able to overwrite the object' do
|
243
|
+
expect { subject.overwrite(content) }.not_to raise_exception
|
244
|
+
end
|
245
|
+
|
246
|
+
it 'should have the correct size' do
|
247
|
+
expect(subject.size).to eq(content.bytesize)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
describe 'when appending with the smaller content' do
|
252
|
+
it 'should not raise exception' do
|
253
|
+
expect { subject.append(content) }.not_to raise_exception
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'should increase the file size by content.bytesize' do
|
257
|
+
expect(subject.size).to eq(2 * content.bytesize)
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'has added the smaller content to the file' do
|
261
|
+
expect(subject.read(0, subject.size)).to eq("#{content}#{content}")
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
describe 'on destroying the object' do
|
266
|
+
it 'should not throw an exception' do
|
267
|
+
expect { subject.destroy }.not_to raise_exception
|
268
|
+
end
|
269
|
+
|
270
|
+
describe 'after destroying file' do
|
271
|
+
it 'should raise an exception on stat' do
|
272
|
+
expect { subject.stat }.to raise_exception Errno::ENOENT
|
273
|
+
end
|
274
|
+
|
275
|
+
it 'should not exist' do
|
276
|
+
expect(subject.exist?).to be false
|
277
|
+
end
|
278
|
+
|
279
|
+
describe 'when appending' do
|
280
|
+
it 'should be able to append with larger content' do
|
281
|
+
expect { subject.append(larger_content) }.not_to raise_exception
|
282
|
+
end
|
283
|
+
|
284
|
+
it 'should have larger content size' do
|
285
|
+
expect(subject.size).to eq(larger_content.bytesize)
|
286
|
+
end
|
287
|
+
|
288
|
+
it 'should still be destroyable' do
|
289
|
+
expect { subject.destroy }.not_to raise_exception
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
describe 'pool tidyup', requires_create_delete: true do
|
298
|
+
subject { pool }
|
299
|
+
it 'should be destroyable' do
|
300
|
+
expect { pool.destroy }.to_not raise_exception
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|