libgfapi-ruby 0.0.7 → 0.0.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bc23e8e61cab7ae1e59207844201a7f1d3e61919
4
- data.tar.gz: a06dd442af33340a906cac88244668b90554b585
3
+ metadata.gz: f2cf4e28e5936b345b94a5b64495a3aee76b48e6
4
+ data.tar.gz: 52d88565ff4b52182ec47e0d7495b4eca46df4ca
5
5
  SHA512:
6
- metadata.gz: 4483213f2ef51f6c96c225e04f6b794da819a275332e91edc8f06510ed50a18e4f3740985d3e03221369e512e2794ec400b29114d34f7c2a3e165a023f4c245e
7
- data.tar.gz: ef0c69e51653edd3075105aa89e5a87d1da6d45401fad0d2330a0a1966400371d9330ce587920dc572c7b7f19cfb3897740daae06368b5faefedd8f4ad7443dc
6
+ metadata.gz: 64da0439a3d8bedf46943b3a98dba14ad1b1938a53871f6489f47df036cb711b165a318513689b030ce15bf5eea59aa0e9569c2d9307e1cd3abbca4ce8c432b8
7
+ data.tar.gz: d85a6a1eea2c1fc5609a17c8217a0f41cb52598284bbde20db89aabbc21d6c49e67be55b96574b20f4a066bd1fff2d12d53df67abccb810d9bbda049dbb2f636
data/README.md CHANGED
@@ -5,7 +5,7 @@ Ruby bindings for [libgfapi](https://github.com/gluster/glusterfs/blob/master/ap
5
5
 
6
6
  ## Warning
7
7
 
8
- This library is currently under active development, and is not ready for production yet.
8
+ This library is currently under active development, and API may break often.
9
9
 
10
10
  ## Installation
11
11
 
@@ -37,6 +37,8 @@ dir.create
37
37
  # Delete a directory
38
38
  dir = GlusterDS::Directory.new(volume, '/some_dir')
39
39
  dir.delete
40
+ # or
41
+ volume.delete_dir('/some_dir')
40
42
 
41
43
  # Create a file from string or bytes
42
44
  file = GlusterFS::File.new(volume, '/gfs/file/path')
@@ -60,7 +62,9 @@ puts "Tempfile path: #{tempfile.path}"
60
62
 
61
63
  # Delete a file
62
64
  file = GlusterFS::File.new(volume, '/gfs/file/path')
63
- file.unlink
65
+ file.delete
66
+ # or
67
+ volume.delete_file('/gfs/file/path')
64
68
 
65
69
  # Unmount virtual mount
66
70
  volume.unmount
@@ -85,6 +89,11 @@ export GFS_SERVER_PORT=24007
85
89
  rake spec
86
90
  ```
87
91
 
92
+ ## TODO
93
+
94
+ Major things missing:
95
+ - Directory listing
96
+
88
97
  ## Contributing
89
98
 
90
99
  1. Fork it ( http://github.com/spajus/libgfapi-ruby/fork )
@@ -338,6 +338,28 @@ module GlusterFS
338
338
  =end
339
339
  attach_function :lstat, :glfs_lstat, [:pointer, :string, :pointer], :int
340
340
 
341
+ =begin
342
+ glfs_fd_t *glfs_opendir (glfs_t *fs, const char *path) __THROW;
343
+ =end
344
+ attach_function :opendir, :glfs_opendir, [:pointer, :string], :pointer
345
+
346
+ =begin
347
+ int glfs_closedir (glfs_fd_t *fd) __THROW;
348
+ =end
349
+ attach_function :closedir, :glfs_closedir, [:pointer], :int
350
+
351
+ =begin
352
+ @glfs_readdir_r and @glfs_readdirplus_r ARE thread safe AND re-entrant,
353
+ but the interface has ambiguity about the size of @dirent to be allocated
354
+ before calling the APIs. 512 byte buffer (for @dirent) is sufficient for
355
+ all known systems which are tested againt glusterfs/gfapi, but may be
356
+ insufficient in the future.
357
+
358
+ int glfs_readdir_r (glfs_fd_t *fd, struct dirent *dirent,
359
+ struct dirent **result) __THROW;
360
+ =end
361
+ attach_function :readdir_r, :glfs_readdir_r, [:pointer, :pointer, :pointer], :int
362
+
341
363
  # TODO the rest
342
364
 
343
365
  end
@@ -0,0 +1,7 @@
1
+ class GlusterFS::Dirent < FFI::Struct
2
+ layout :d_ino, :ino_t,
3
+ :d_off, :ulong,
4
+ :d_reclen, :ushort,
5
+ :d_type, :char,
6
+ :d_name, :string
7
+ end
@@ -1,3 +1,3 @@
1
1
  module GlusterFS
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
@@ -1,5 +1,5 @@
1
1
  class GlusterFS::Volume
2
- attr_reader :name, :fs, :mounted
2
+ attr_reader :name, :fs, :mounted, :protocol, :host, :port
3
3
 
4
4
  def initialize(name)
5
5
  @name = name
@@ -8,16 +8,39 @@ class GlusterFS::Volume
8
8
  end
9
9
 
10
10
  def mount(host, port = 24007, protocol = 'tcp')
11
+ raise GlusterFS::Error, "Already mounted: #{self}" if mounted?
11
12
  GlusterFS.set_volfile_server(@fs, protocol, host, port)
12
13
  result = GlusterFS.init(@fs)
13
- if result != 0
14
- raise GlusterFS::Error,
15
- "Failed to mount volume '#{volume_name}' on #{protocol}://#{host}:#{port}"
16
- end
14
+ raise GlusterFS::Error, "Failed to mount volume #{self}" if result != 0
17
15
  @mounted = true
16
+ @host = host
17
+ @protocol = protocol
18
+ @port = port
18
19
  self
19
20
  end
20
21
 
22
+ def lstat(path)
23
+ check_mounted
24
+ data = GlusterFS::Stat.new
25
+ GlusterFS.lstat(@fs, path, data)
26
+ data
27
+ end
28
+
29
+ def list(path)
30
+ dir = Directory.new(volume, path)
31
+ dir.list
32
+ end
33
+
34
+ def delete_file(path)
35
+ check_mounted
36
+ GlusterFS.unlink(@fs, path)
37
+ end
38
+
39
+ def delete_dir(path)
40
+ check_mounted
41
+ GlusterFS.rmdir(@fs, path)
42
+ end
43
+
21
44
  def mounted?
22
45
  @mounted
23
46
  end
@@ -29,4 +52,18 @@ class GlusterFS::Volume
29
52
  true
30
53
  end
31
54
  end
55
+
56
+ private
57
+
58
+ def to_s
59
+ if mounted?
60
+ "GlusterFS::Volume['#{@name}' on #{protocol}://#{host}:#{port}]"
61
+ else
62
+ "GlusterFS::Volume['#{@name}' (unmounted)]"
63
+ end
64
+ end
65
+
66
+ def check_mounted
67
+ raise GlusterFS::Error, "Volume not mounted: #{self}" unless mounted?
68
+ end
32
69
  end
data/lib/glusterfs.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  require "ffi"
2
2
  require "glusterfs/version"
3
+ require "glusterfs/dirent"
4
+ require "glusterfs/stat"
3
5
  require "glusterfs/bindings"
4
6
  require "glusterfs/error"
5
7
  require "glusterfs/file"
6
8
  require "glusterfs/directory"
7
9
  require "glusterfs/volume"
8
- require "glusterfs/stat"
9
10
 
10
11
  module GlusterFS
11
12
  end
@@ -1,26 +1,28 @@
1
1
  require 'ruby-mass'
2
2
  module GlusterFS
3
3
 
4
+ # Set MEM_PRINT=1 MEM_ITERATIONS=10000 to get a stress test
5
+
4
6
  def self.mem_size
5
- # ObjectSpace.garbage_collect
6
- # sleep 3
7
7
  _, size = `ps ax -o pid,rss | grep -E "^[[:space:]]*#{$$}"`.strip.split.map(&:to_i)
8
8
  size.to_i
9
9
  end
10
10
 
11
11
  describe 'memleaks' do
12
12
 
13
- let(:iterations) { 10000 }
13
+ let(:iterations) { (ENV['MEM_ITERATIONS'] || 100).to_i }
14
14
 
15
15
  before(:all) do
16
- puts "GC Settings"
17
- puts "RUBY_HEAP_MIN_SLOTS=#{ENV['RUBY_HEAP_MIN_SLOTS']}"
18
- puts "RUBY_HEAP_SLOTS_INCREMENT=#{ENV['RUBY_HEAP_SLOTS_INCREMENT']}"
19
- puts "RUBY_HEAP_SLOTS_GROWTH_FACTOR=#{ENV['RUBY_HEAP_SLOTS_GROWTH_FACTOR']}"
20
- puts "RUBY_GC_MALLOC_LIMIT=#{ENV['RUBY_GC_MALLOC_LIMIT']}"
21
- puts "RUBY_FREE_MIN=#{ENV['RUBY_FREE_MIN']}"
22
- puts "Initial memory use: #{GlusterFS.mem_size}"
23
- Mass.print
16
+ if ENV['MEM_PRINT']
17
+ puts "GC Settings"
18
+ puts "RUBY_HEAP_MIN_SLOTS=#{ENV['RUBY_HEAP_MIN_SLOTS']}"
19
+ puts "RUBY_HEAP_SLOTS_INCREMENT=#{ENV['RUBY_HEAP_SLOTS_INCREMENT']}"
20
+ puts "RUBY_HEAP_SLOTS_GROWTH_FACTOR=#{ENV['RUBY_HEAP_SLOTS_GROWTH_FACTOR']}"
21
+ puts "RUBY_GC_MALLOC_LIMIT=#{ENV['RUBY_GC_MALLOC_LIMIT']}"
22
+ puts "RUBY_FREE_MIN=#{ENV['RUBY_FREE_MIN']}"
23
+ puts "Initial memory use: #{GlusterFS.mem_size}"
24
+ Mass.print
25
+ end
24
26
  end
25
27
 
26
28
  let(:random_blob) do
@@ -35,7 +37,7 @@ module GlusterFS
35
37
  before { root_dir.create }
36
38
  after { root_dir.delete }
37
39
  specify do
38
- puts "Iterations: #{iterations}"
40
+ puts "Dir Iterations: #{iterations}"
39
41
  mem_size_before = GlusterFS.mem_size
40
42
  iterations.times do |i|
41
43
  dir = Directory.new(volume, "#{root_dir.path}/subdir-#{i}")
@@ -44,7 +46,7 @@ module GlusterFS
44
46
  end
45
47
  mem_size = GlusterFS.mem_size
46
48
  puts "Mem growth: #{mem_size - mem_size_before}"
47
- Mass.print
49
+ Mass.print if ENV['MEM_PRINT']
48
50
  (mem_size - mem_size_before).should be < 10240
49
51
  end
50
52
  end
@@ -53,7 +55,7 @@ module GlusterFS
53
55
  before { root_dir.create }
54
56
  after { root_dir.delete }
55
57
  specify do
56
- puts "Iterations: #{iterations}"
58
+ puts "File Iterations: #{iterations}"
57
59
  mem_size_before = GlusterFS.mem_size
58
60
  iterations.times do |i|
59
61
  file = File.new(volume, "#{root_dir.path}/file-#{i}")
@@ -62,7 +64,7 @@ module GlusterFS
62
64
  end
63
65
  mem_size = GlusterFS.mem_size
64
66
  puts "Mem growth: #{mem_size - mem_size_before}"
65
- Mass.print
67
+ Mass.print if ENV['MEM_PRINT']
66
68
  (mem_size - mem_size_before).should be < 10240
67
69
  end
68
70
  end
@@ -4,6 +4,8 @@ module GlusterFS
4
4
  describe Volume do
5
5
  let(:volume) { Volume.new(GFS_VOLUME) }
6
6
 
7
+ after(:each) { volume.unmount if volume.mounted? }
8
+
7
9
  context '#mount' do
8
10
  before { volume.mount(GFS_SERVER_HOST, GFS_SERVER_PORT) }
9
11
  subject { volume.mounted? }
@@ -19,7 +21,64 @@ module GlusterFS
19
21
  it { should_not be_true }
20
22
  end
21
23
 
24
+ context '#lstat' do
25
+ context 'on file' do
26
+ let(:file_name) { "test-stat-#{Time.now.to_i}" }
27
+ let(:file) { File.new(volume, file_name) }
28
+ let(:data) { '123' }
29
+ before do
30
+ volume.mount(GFS_SERVER_HOST, GFS_SERVER_PORT)
31
+ file.write(data)
32
+ end
33
+ after { file.delete }
34
+ subject { volume.lstat(file.path) }
35
+ its([:st_size]) { should == file.size }
36
+ end
37
+
38
+ context 'on directory' do
39
+ let(:dir_name) { "test-#{Time.now.to_i}" }
40
+ let(:dir) { Directory.new(volume, dir_name) }
41
+ before do
42
+ volume.mount(GFS_SERVER_HOST, GFS_SERVER_PORT)
43
+ dir.create
44
+ end
45
+ after { dir.delete }
46
+ subject { volume.lstat(dir.path) }
47
+ its([:st_blksize]) { should == dir.lstat[:st_blksize] }
48
+ end
49
+
50
+ specify 'raise error when unmounted' do
51
+ expect { volume.lstat('/foo/bar') }.to raise_error(GlusterFS::Error)
52
+ end
53
+ end
54
+
55
+ context '#delete_dir' do
56
+ let(:dir_name) { "test-#{Time.now.to_i}" }
57
+ let(:dir) { Directory.new(volume, dir_name) }
58
+ before do
59
+ volume.mount(GFS_SERVER_HOST, GFS_SERVER_PORT)
60
+ dir.create
61
+ end
62
+ before { volume.delete_dir(dir.path) }
63
+ subject { dir.exists? }
64
+ it { should_not be_true }
65
+ end
66
+
67
+ context '#delete_file' do
68
+ let(:file_name) { "test-stat-#{Time.now.to_i}" }
69
+ let(:file) { File.new(volume, file_name) }
70
+ let(:data) { '123' }
71
+ before do
72
+ volume.mount(GFS_SERVER_HOST, GFS_SERVER_PORT)
73
+ file.write(data)
74
+ end
75
+ before { volume.delete_file(file.path) }
76
+ subject { file.exists? }
77
+ it { should_not be_true }
78
+ end
79
+
22
80
  context '#mounted?' do
81
+ before { volume.unmount }
23
82
  subject { volume.mounted? }
24
83
 
25
84
  context 'on mounted volume' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libgfapi-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomas Varaneckas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-03 00:00:00.000000000 Z
11
+ date: 2014-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -95,6 +95,7 @@ files:
95
95
  - lib/glusterfs.rb
96
96
  - lib/glusterfs/bindings.rb
97
97
  - lib/glusterfs/directory.rb
98
+ - lib/glusterfs/dirent.rb
98
99
  - lib/glusterfs/error.rb
99
100
  - lib/glusterfs/file.rb
100
101
  - lib/glusterfs/stat.rb
@@ -103,7 +104,7 @@ files:
103
104
  - libgfapi-ruby.gemspec
104
105
  - spec/glusterfs/directory_spec.rb
105
106
  - spec/glusterfs/file_spec.rb
106
- - spec/glusterfs/memleak_spec.rb
107
+ - spec/glusterfs/stress/memleak_spec.rb
107
108
  - spec/glusterfs/volume_spec.rb
108
109
  - spec/spec_helper.rb
109
110
  homepage: https://github.com/spajus/libgfapi-ruby
@@ -133,7 +134,7 @@ summary: Ruby bindings for libgfapi (GlusterFS API)
133
134
  test_files:
134
135
  - spec/glusterfs/directory_spec.rb
135
136
  - spec/glusterfs/file_spec.rb
136
- - spec/glusterfs/memleak_spec.rb
137
+ - spec/glusterfs/stress/memleak_spec.rb
137
138
  - spec/glusterfs/volume_spec.rb
138
139
  - spec/spec_helper.rb
139
140
  has_rdoc: