rfusefs 1.0.2 → 1.1.3
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 +5 -13
- data/.yardopts +2 -0
- data/CHANGES.md +43 -0
- data/LICENSE +24 -0
- data/README.md +83 -0
- data/TODO.md +7 -0
- data/lib/fuse/fusedir.rb +17 -2
- data/lib/fuse/rfusefs-fuse.rb +446 -414
- data/lib/fusefs/metadir.rb +5 -5
- data/lib/fusefs/pathmapper.rb +7 -7
- data/lib/fusefs/sqlitemapper.rb +7 -2
- data/lib/rfusefs.rb +20 -48
- data/lib/rfusefs/version.rb +1 -1
- metadata +35 -53
- data/.gitignore +0 -9
- data/.travis.yml +0 -8
- data/Gemfile +0 -4
- data/History.rdoc +0 -28
- data/README.rdoc +0 -107
- data/Rakefile +0 -22
- data/TODO.txt +0 -6
- data/rfusefs.gemspec +0 -31
- data/samples/demo.rb +0 -57
- data/samples/dictfs.rb +0 -74
- data/samples/hello.rb +0 -20
- data/samples/openurifs.rb +0 -53
- data/samples/railsfs.rb +0 -77
- data/samples/sqlfs.rb +0 -134
- data/samples/yamlfs.rb +0 -168
- data/spec-fusefs/fusefs_spec.rb +0 -12
- data/spec/metadir_spec.rb +0 -364
- data/spec/mount_unmount_spec.rb +0 -21
- data/spec/pathmapper_spec.rb +0 -417
- data/spec/rfusefs_spec.rb +0 -497
- data/spec/sample_spec.rb +0 -30
- data/spec/spec_helper.rb +0 -42
- data/spec/sqlitemapper_spec.rb +0 -135
data/samples/sqlfs.rb
DELETED
@@ -1,134 +0,0 @@
|
|
1
|
-
# sqlfs.rb
|
2
|
-
#
|
3
|
-
# The SQL-db proof of concept for FuseFS
|
4
|
-
#
|
5
|
-
# Author: Greg Millam
|
6
|
-
|
7
|
-
require "rubygems"
|
8
|
-
require 'fusefs'
|
9
|
-
|
10
|
-
require 'mysql'
|
11
|
-
|
12
|
-
class SqlFS < FuseFS::FuseDir
|
13
|
-
class DBTable
|
14
|
-
attr_accessor :name, :key, :fields
|
15
|
-
end
|
16
|
-
def initialize(host,user,pass,db)
|
17
|
-
@sql = Mysql.connect(host,user,pass,db)
|
18
|
-
@tables = Hash.new(nil)
|
19
|
-
|
20
|
-
tables = @sql.query('show tables')
|
21
|
-
|
22
|
-
tables.each do |i,|
|
23
|
-
table = DBTable.new
|
24
|
-
table.name = i
|
25
|
-
table.fields = {}
|
26
|
-
res = @sql.query("describe #{i}")
|
27
|
-
res.each do |field,type,null,key,default,extra|
|
28
|
-
table.fields[field] = type
|
29
|
-
if (key =~ /pri/i)
|
30
|
-
table.key = field
|
31
|
-
end
|
32
|
-
end
|
33
|
-
@tables[i] = table if table.key
|
34
|
-
end
|
35
|
-
end
|
36
|
-
def directory?(path)
|
37
|
-
tname, key, field = scan_path(path)
|
38
|
-
table = @tables[tname]
|
39
|
-
case
|
40
|
-
when tname.nil?
|
41
|
-
true # This means "/"
|
42
|
-
when table.nil?
|
43
|
-
false
|
44
|
-
when field
|
45
|
-
false # Always a file
|
46
|
-
when key
|
47
|
-
res = @sql.query("SELECT #{table.key}, 1 FROM #{table.name} WHERE #{table.key} = '#{Mysql.escape_string(key)}'")
|
48
|
-
res.num_rows > 0 # If there was a result, it exists.
|
49
|
-
else
|
50
|
-
true # It's just a table.
|
51
|
-
end
|
52
|
-
end
|
53
|
-
def file?(path)
|
54
|
-
tname, key, field = scan_path(path)
|
55
|
-
table = @tables[tname]
|
56
|
-
case
|
57
|
-
when field.nil?
|
58
|
-
false # Only field entries are files.
|
59
|
-
when table.nil?
|
60
|
-
false
|
61
|
-
when ! @tables[tname].fields.include?(field)
|
62
|
-
false # Invalid field.
|
63
|
-
when field
|
64
|
-
res = @sql.query("SELECT #{table.key}, 1 FROM #{table.name} WHERE #{table.key} = '#{Mysql.escape_string(key)}'")
|
65
|
-
res.num_rows > 0
|
66
|
-
end
|
67
|
-
end
|
68
|
-
def can_delete?(path)
|
69
|
-
# This helps editors, but we don't really use it.
|
70
|
-
true
|
71
|
-
end
|
72
|
-
def can_write?(path)
|
73
|
-
# Since this is basically only for editing files,
|
74
|
-
# we just call file?
|
75
|
-
file?(path)
|
76
|
-
end
|
77
|
-
def contents(path)
|
78
|
-
# since this is only called when directory? is true,
|
79
|
-
# We'll assume valid entries.
|
80
|
-
tname, key, field = scan_path(path)
|
81
|
-
table = @tables[tname]
|
82
|
-
case
|
83
|
-
when tname.nil?
|
84
|
-
@tables.keys.sort # Just the tables.
|
85
|
-
when key
|
86
|
-
table.fields.keys.sort
|
87
|
-
else
|
88
|
-
# I limit to 200 so 'ls' doesn't hang all the time :D
|
89
|
-
res = @sql.query("SELECT #{table.key}, 1 FROM #{table.name} ORDER BY #{table.key} LIMIT 100")
|
90
|
-
ret = []
|
91
|
-
res.each do |val,one|
|
92
|
-
ret << val if val.size > 0
|
93
|
-
end
|
94
|
-
ret
|
95
|
-
end
|
96
|
-
end
|
97
|
-
def write_to(path,body)
|
98
|
-
# Since this is only called after can_write?(), we assume
|
99
|
-
# Valid fields.
|
100
|
-
tname, key, field = scan_path(path)
|
101
|
-
table = @tables[tname]
|
102
|
-
res = @sql.query("UPDATE #{table.name} SET #{field} = '#{Mysql.escape_string(body)}' WHERE #{table.key} = '#{key}'")
|
103
|
-
end
|
104
|
-
def read_file(path)
|
105
|
-
# Again, as this is only called after file?, assume valid fields.
|
106
|
-
tname, key, field = scan_path(path)
|
107
|
-
table = @tables[tname]
|
108
|
-
res = @sql.query("SELECT #{field} FROM #{table.name} WHERE #{table.key} = '#{key}'")
|
109
|
-
res.fetch_row[0]
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
if (File.basename($0) == File.basename(__FILE__))
|
114
|
-
if ARGV.size != 5
|
115
|
-
puts "Usage: #{$0} <directory> <host> <user> <pass> <db>"
|
116
|
-
exit
|
117
|
-
end
|
118
|
-
|
119
|
-
dirname, host, user, pass, db = ARGV
|
120
|
-
|
121
|
-
if (! File.directory?(dirname))
|
122
|
-
puts "#{dirname} is not a directory"
|
123
|
-
end
|
124
|
-
|
125
|
-
root = SqlFS.new(host,user,pass,db)
|
126
|
-
|
127
|
-
# Set the root FuseFS
|
128
|
-
FuseFS.set_root(root)
|
129
|
-
|
130
|
-
# root.contents("/quotes")
|
131
|
-
|
132
|
-
FuseFS.mount_under(dirname)
|
133
|
-
FuseFS.run # This doesn't return until we're unmounted.
|
134
|
-
end
|
data/samples/yamlfs.rb
DELETED
@@ -1,168 +0,0 @@
|
|
1
|
-
# yamlfs.rb
|
2
|
-
#
|
3
|
-
|
4
|
-
require "rubygems"
|
5
|
-
require 'fusefs'
|
6
|
-
include FuseFS
|
7
|
-
|
8
|
-
require 'yaml'
|
9
|
-
|
10
|
-
class YAMLFS < FuseFS::FuseDir
|
11
|
-
def initialize(filename)
|
12
|
-
@filename = filename
|
13
|
-
begin
|
14
|
-
@fs = YAML.load(IO.read(filename))
|
15
|
-
rescue Exception
|
16
|
-
@fs = Hash.new()
|
17
|
-
end
|
18
|
-
end
|
19
|
-
def save
|
20
|
-
File.open(@filename,'w') do |fout|
|
21
|
-
fout.puts(YAML.dump(@fs))
|
22
|
-
end
|
23
|
-
end
|
24
|
-
def contents(path)
|
25
|
-
items = scan_path(path)
|
26
|
-
node = items.inject(@fs) do |node,item|
|
27
|
-
item ? node[item] : node
|
28
|
-
end
|
29
|
-
node.keys.sort
|
30
|
-
end
|
31
|
-
def directory?(path)
|
32
|
-
items = scan_path(path)
|
33
|
-
node = items.inject(@fs) do |node,item|
|
34
|
-
item ? node[item] : node
|
35
|
-
end
|
36
|
-
node.is_a?(Hash)
|
37
|
-
end
|
38
|
-
def file?(path)
|
39
|
-
items = scan_path(path)
|
40
|
-
node = items.inject(@fs) do |node,item|
|
41
|
-
item ? node[item] : node
|
42
|
-
end
|
43
|
-
node.is_a?(String)
|
44
|
-
end
|
45
|
-
def touch(path)
|
46
|
-
puts "#{path} has been pushed like a button!"
|
47
|
-
end
|
48
|
-
|
49
|
-
# File reading
|
50
|
-
def read_file(path)
|
51
|
-
items = scan_path(path)
|
52
|
-
node = items.inject(@fs) do |node,item|
|
53
|
-
item ? node[item] : node
|
54
|
-
end
|
55
|
-
node.to_s
|
56
|
-
end
|
57
|
-
|
58
|
-
def size(path)
|
59
|
-
read_file(path).size
|
60
|
-
end
|
61
|
-
|
62
|
-
# File writing
|
63
|
-
def can_write?(path)
|
64
|
-
items = scan_path(path)
|
65
|
-
name = items.pop # Last is the filename.
|
66
|
-
node = items.inject(@fs) do |node,item|
|
67
|
-
item ? node[item] : node
|
68
|
-
end
|
69
|
-
node.is_a?(Hash)
|
70
|
-
rescue Exception => er
|
71
|
-
puts "Error! #{er}"
|
72
|
-
end
|
73
|
-
def write_to(path,body)
|
74
|
-
items = scan_path(path)
|
75
|
-
name = items.pop # Last is the filename.
|
76
|
-
node = items.inject(@fs) do |node,item|
|
77
|
-
item ? node[item] : node
|
78
|
-
end
|
79
|
-
node[name] = body
|
80
|
-
self.save
|
81
|
-
rescue Exception => er
|
82
|
-
puts "Error! #{er}"
|
83
|
-
end
|
84
|
-
|
85
|
-
# Delete a file
|
86
|
-
def can_delete?(path)
|
87
|
-
items = scan_path(path)
|
88
|
-
node = items.inject(@fs) do |node,item|
|
89
|
-
item ? node[item] : node
|
90
|
-
end
|
91
|
-
node.is_a?(String)
|
92
|
-
rescue Exception => er
|
93
|
-
puts "Error! #{er}"
|
94
|
-
end
|
95
|
-
def delete(path)
|
96
|
-
items = scan_path(path)
|
97
|
-
name = items.pop # Last is the filename.
|
98
|
-
node = items.inject(@fs) do |node,item|
|
99
|
-
item ? node[item] : node
|
100
|
-
end
|
101
|
-
node.delete(name)
|
102
|
-
self.save
|
103
|
-
rescue Exception => er
|
104
|
-
puts "Error! #{er}"
|
105
|
-
end
|
106
|
-
|
107
|
-
# mkdirs
|
108
|
-
def can_mkdir?(path)
|
109
|
-
items = scan_path(path)
|
110
|
-
name = items.pop # Last is the filename.
|
111
|
-
node = items.inject(@fs) do |node,item|
|
112
|
-
item ? node[item] : node
|
113
|
-
end
|
114
|
-
node.is_a?(Hash)
|
115
|
-
rescue Exception => er
|
116
|
-
puts "Error! #{er}"
|
117
|
-
end
|
118
|
-
def mkdir(path)
|
119
|
-
items = scan_path(path)
|
120
|
-
name = items.pop # Last is the filename.
|
121
|
-
node = items.inject(@fs) do |node,item|
|
122
|
-
item ? node[item] : node
|
123
|
-
end
|
124
|
-
node[name] = Hash.new
|
125
|
-
self.save
|
126
|
-
end
|
127
|
-
|
128
|
-
# rmdir
|
129
|
-
def can_rmdir?(path)
|
130
|
-
items = scan_path(path)
|
131
|
-
node = items.inject(@fs) do |node,item|
|
132
|
-
item ? node[item] : node
|
133
|
-
end
|
134
|
-
node.is_a?(Hash) && node.empty?
|
135
|
-
end
|
136
|
-
def rmdir(path)
|
137
|
-
items = scan_path(path)
|
138
|
-
name = items.pop # Last is the filename.
|
139
|
-
node = items.inject(@fs) do |node,item|
|
140
|
-
item ? node[item] : node
|
141
|
-
end
|
142
|
-
node.delete(name)
|
143
|
-
self.save
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
if (File.basename($0) == File.basename(__FILE__))
|
148
|
-
if (ARGV.size < 2)
|
149
|
-
puts "Usage: #{$0} <directory> <yamlfile> <options>"
|
150
|
-
exit
|
151
|
-
end
|
152
|
-
|
153
|
-
dirname, yamlfile = ARGV.shift, ARGV.shift
|
154
|
-
|
155
|
-
unless File.directory?(dirname)
|
156
|
-
puts "Usage: #{dirname} is not a directory."
|
157
|
-
exit
|
158
|
-
end
|
159
|
-
|
160
|
-
root = YAMLFS.new(yamlfile)
|
161
|
-
|
162
|
-
# Set the root FuseFS
|
163
|
-
FuseFS.set_root(root)
|
164
|
-
|
165
|
-
FuseFS.mount_under(dirname, *ARGV)
|
166
|
-
|
167
|
-
FuseFS.run # This doesn't return until we're unmounted.
|
168
|
-
end
|
data/spec-fusefs/fusefs_spec.rb
DELETED
data/spec/metadir_spec.rb
DELETED
@@ -1,364 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'tmpdir'
|
3
|
-
require 'sys/filesystem'
|
4
|
-
require 'ffi-xattr'
|
5
|
-
|
6
|
-
describe FuseFS::MetaDir do
|
7
|
-
|
8
|
-
context "in ruby" do
|
9
|
-
|
10
|
-
before(:each) do
|
11
|
-
@metadir = FuseFS::MetaDir.new()
|
12
|
-
@metadir.mkdir("/test")
|
13
|
-
@metadir.mkdir("/test/hello")
|
14
|
-
@metadir.mkdir("/test/hello/emptydir")
|
15
|
-
@metadir.write_to("/test/hello/hello.txt","Hello World!\n")
|
16
|
-
end
|
17
|
-
|
18
|
-
context "general directory methods" do
|
19
|
-
it "should list directory contents" do
|
20
|
-
@metadir.contents("/").should =~ [ "test" ]
|
21
|
-
@metadir.contents("/test").should =~ [ "hello" ]
|
22
|
-
@metadir.contents("/test/hello").should =~ ["hello.txt", "emptydir" ]
|
23
|
-
end
|
24
|
-
|
25
|
-
it "should indicate paths which are/are not directories" do
|
26
|
-
@metadir.directory?("/test").should be_true
|
27
|
-
@metadir.directory?("/test/hello").should be_true
|
28
|
-
@metadir.directory?("/test/hello/hello.txt").should be_false
|
29
|
-
@metadir.directory?("/nodir").should be_false
|
30
|
-
@metadir.directory?("/test/nodir").should be_false
|
31
|
-
end
|
32
|
-
|
33
|
-
it "should indicate paths which are/are not files" do
|
34
|
-
@metadir.file?("/test").should be_false
|
35
|
-
@metadir.file?("/test/nodir").should be_false
|
36
|
-
@metadir.file?("/test/hello").should be_false
|
37
|
-
@metadir.file?("/test/hello/hello.txt").should be_true
|
38
|
-
end
|
39
|
-
|
40
|
-
it "should indicate the size of a file" do
|
41
|
-
@metadir.size("/test/hello/hello.txt").should be "Hello World!\n".length
|
42
|
-
end
|
43
|
-
|
44
|
-
it "should report filesystem statistics" do
|
45
|
-
@metadir.statistics("/").should == [ 13, 5, nil, nil ]
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
context "with write access" do
|
50
|
-
|
51
|
-
around(:each) do |example|
|
52
|
-
FuseFS::RFuseFS.context(fuse_context(),&example)
|
53
|
-
end
|
54
|
-
|
55
|
-
before(:each) do
|
56
|
-
FuseFS::reader_uid.should == Process.uid
|
57
|
-
FuseFS::reader_gid.should == Process.gid
|
58
|
-
end
|
59
|
-
|
60
|
-
|
61
|
-
it "should allow directory creation" do
|
62
|
-
@metadir.can_mkdir?("/test/otherdir").should be_true
|
63
|
-
end
|
64
|
-
|
65
|
-
it "should allow file creation and update" do
|
66
|
-
@metadir.can_write?("/test/hello/newfile").should be_true
|
67
|
-
@metadir.can_write?("/test/hello/hello.txt").should be_true
|
68
|
-
end
|
69
|
-
|
70
|
-
it "should read files" do
|
71
|
-
@metadir.read_file("/test/hello/hello.txt").should == "Hello World!\n"
|
72
|
-
end
|
73
|
-
|
74
|
-
it "should update existing files" do
|
75
|
-
@metadir.write_to("/test/hello/hello.txt","new contents")
|
76
|
-
@metadir.read_file("/test/hello/hello.txt").should == "new contents"
|
77
|
-
end
|
78
|
-
|
79
|
-
it "should not allow deletion of non empty directories" do
|
80
|
-
@metadir.can_rmdir?("/test/hello").should be_false
|
81
|
-
end
|
82
|
-
|
83
|
-
it "should delete directories" do
|
84
|
-
@metadir.rmdir("/test/hello/emptydir")
|
85
|
-
@metadir.contents("/test/hello").should =~ ["hello.txt"]
|
86
|
-
end
|
87
|
-
|
88
|
-
it "should allow and delete files" do
|
89
|
-
@metadir.can_delete?("/test/hello/hello.txt").should be_true
|
90
|
-
@metadir.delete("/test/hello/hello.txt")
|
91
|
-
@metadir.contents("/test/hello").should =~ ["emptydir"]
|
92
|
-
end
|
93
|
-
|
94
|
-
it "should move directories at same level" do
|
95
|
-
before = @metadir.contents("/test/hello")
|
96
|
-
@metadir.rename("/test/hello","/test/moved").should be_true
|
97
|
-
@metadir.directory?("/test/moved").should be_true
|
98
|
-
@metadir.contents("/test/moved").should =~ before
|
99
|
-
@metadir.read_file("/test/moved/hello.txt").should == "Hello World!\n"
|
100
|
-
end
|
101
|
-
|
102
|
-
it "should move directories between different paths" do
|
103
|
-
@metadir.mkdir("/test/other")
|
104
|
-
@metadir.mkdir("/test/other/more")
|
105
|
-
before = @metadir.contents("/test/hello")
|
106
|
-
@metadir.rename("/test/hello","/test/other/more/hello").should be_true
|
107
|
-
@metadir.contents("/test/other/more/hello").should =~ before
|
108
|
-
@metadir.read_file("/test/other/more/hello/hello.txt").should == "Hello World!\n"
|
109
|
-
end
|
110
|
-
|
111
|
-
it "should maintain filesystem statistics" do
|
112
|
-
# remove a directory
|
113
|
-
@metadir.rmdir("/test/hello/emptydir")
|
114
|
-
|
115
|
-
# replace text for (the only) existing file
|
116
|
-
@metadir.write_to("/test/hello/hello.txt","new text")
|
117
|
-
|
118
|
-
@metadir.statistics("/").should == [ 8, 4, nil, nil ]
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
context "with readonly access" do
|
123
|
-
around(:each) do |example|
|
124
|
-
#Simulate a different userid..
|
125
|
-
FuseFS::RFuseFS.context(fuse_context(-1,-1),&example)
|
126
|
-
end
|
127
|
-
|
128
|
-
before(:each) do
|
129
|
-
FuseFS::reader_uid.should_not == Process.uid
|
130
|
-
FuseFS::reader_gid.should_not == Process.gid
|
131
|
-
end
|
132
|
-
|
133
|
-
it "should not allow directory creation" do
|
134
|
-
@metadir.can_mkdir?("/test/anydir").should be_false
|
135
|
-
@metadir.can_mkdir?("/test/hello/otherdir").should be_false
|
136
|
-
end
|
137
|
-
|
138
|
-
it "should not allow file creation or write access" do
|
139
|
-
@metadir.can_write?("/test/hello/hello.txt").should be_false
|
140
|
-
@metadir.can_write?("/test/hello/newfile").should be_false
|
141
|
-
end
|
142
|
-
|
143
|
-
it "should not allow file deletion" do
|
144
|
-
@metadir.can_delete?("/test/hello/hello.txt").should be_false
|
145
|
-
end
|
146
|
-
|
147
|
-
it "should not allow directory deletion" do
|
148
|
-
@metadir.can_rmdir?("/test/emptydir").should be_false
|
149
|
-
end
|
150
|
-
|
151
|
-
it "should not allow directory renames" do
|
152
|
-
@metadir.rename("/test/emptydir","/test/otherdir").should be_false
|
153
|
-
#TODO and make sure it doesn't rename
|
154
|
-
end
|
155
|
-
|
156
|
-
it "should not allow file renames" do
|
157
|
-
@metadir.rename("test/hello/hello.txt","test/hello.txt2").should be_false
|
158
|
-
#TODO and make sure it doesn't rename
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
context "with subdirectory containing another FuseFS" do
|
163
|
-
around(:each) do |example|
|
164
|
-
FuseFS::RFuseFS.context(fuse_context(),&example)
|
165
|
-
end
|
166
|
-
|
167
|
-
before(:each) do
|
168
|
-
@fusefs = mock("mock_fusefs")
|
169
|
-
@metadir.mkdir("/test")
|
170
|
-
@metadir.mkdir("/test/fusefs",@fusefs)
|
171
|
-
end
|
172
|
-
|
173
|
-
api_methods = [:directory?, :file?, :contents, :executable?, :size, :times, :read_file, :can_write?, :can_delete?, :delete, :can_mkdir?, :can_rmdir?, :rmdir, :touch, :raw_open, :raw_truncate, :raw_read, :raw_write, :raw_close]
|
174
|
-
api_methods.each do |method|
|
175
|
-
it "should pass on #{method}" do
|
176
|
-
arity = FuseFS::FuseDir.instance_method(method).arity().abs - 1
|
177
|
-
args = Array.new(arity) { |i| i }
|
178
|
-
@fusefs.should_receive(method).with("/path/to/file",*args).and_return("anything")
|
179
|
-
@metadir.send(method,"/test/fusefs/path/to/file",*args)
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
it "should pass on :write_to" do
|
184
|
-
@fusefs.should_receive(:write_to).with("/path/to/file","new contents\n")
|
185
|
-
@metadir.write_to("/test/fusefs/path/to/file","new contents\n")
|
186
|
-
end
|
187
|
-
|
188
|
-
it "should pass on :mkdir" do
|
189
|
-
@fusefs.should_receive(:mkdir).with("/path/to/file",nil).once().and_raise(ArgumentError)
|
190
|
-
@fusefs.should_receive(:mkdir).with("/path/to/file").once().and_return("true")
|
191
|
-
@metadir.mkdir("/test/fusefs/path/to/file")
|
192
|
-
end
|
193
|
-
|
194
|
-
it "should rename within same directory" do
|
195
|
-
@fusefs.should_receive(:rename).with("/oldfile","/newfile")
|
196
|
-
@metadir.rename("/test/fusefs/oldfile","/test/fusefs/newfile")
|
197
|
-
end
|
198
|
-
|
199
|
-
it "should pass rename down common directories" do
|
200
|
-
@fusefs.should_receive(:rename).with("/path/to/file" ,"/new/path/to/file")
|
201
|
-
@metadir.rename("/test/fusefs/path/to/file","/test/fusefs/new/path/to/file")
|
202
|
-
end
|
203
|
-
|
204
|
-
it "should rename across directories if from_path is a FuseFS object that accepts extended rename" do
|
205
|
-
@fusefs.should_receive(:rename).with("/path/to/file","/nonfusepath",
|
206
|
-
an_instance_of(FuseFS::MetaDir)) do | myPath, extPath, extFS |
|
207
|
-
extFS.write_to(extPath,"look Mum, no hands!")
|
208
|
-
end
|
209
|
-
|
210
|
-
@metadir.rename("/test/fusefs/path/to/file","/test/nonfusepath").should be_true
|
211
|
-
@metadir.read_file("/test/nonfusepath").should == "look Mum, no hands!"
|
212
|
-
end
|
213
|
-
|
214
|
-
it "should quietly return false if from_path is a FuseFS object that does not accept extended rename" do
|
215
|
-
@fusefs.should_receive(:rename).
|
216
|
-
with("/path/to/file","/nonfusepath",an_instance_of(FuseFS::MetaDir)).
|
217
|
-
and_raise(ArgumentError)
|
218
|
-
@metadir.rename("/test/fusefs/path/to/file","/test/nonfusepath").should be_false
|
219
|
-
|
220
|
-
end
|
221
|
-
|
222
|
-
it "should not attempt rename file unless :can_write? the destination" do
|
223
|
-
@fusefs.should_receive(:can_write?).with("/newpath/to/file").and_return(false)
|
224
|
-
@metadir.write_to("/test/aFile","some contents")
|
225
|
-
@metadir.rename("/test/aFile","/test/fusefs/newpath/to/file").should be_false
|
226
|
-
end
|
227
|
-
|
228
|
-
it "should not attempt rename directory unless :can_mkdir? the destination" do
|
229
|
-
@fusefs.should_receive(:can_mkdir?).with("/newpath/to/dir").and_return(false)
|
230
|
-
@metadir.mkdir("/test/aDir","some contents")
|
231
|
-
@metadir.rename("/test/aDir","/test/fusefs/newpath/to/dir").should be_false
|
232
|
-
end
|
233
|
-
|
234
|
-
it "should pass on #statistics" do
|
235
|
-
@fusefs.should_receive(:statistics).with("/path/to/file")
|
236
|
-
|
237
|
-
@metadir.statistics("test/fusefs/path/to/file")
|
238
|
-
end
|
239
|
-
|
240
|
-
it "should pass on #statistics for root" do
|
241
|
-
@fusefs.should_receive(:statistics).with("/")
|
242
|
-
|
243
|
-
@metadir.statistics("test/fusefs")
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
end
|
248
|
-
context "in a mounted FUSE filesystem" do
|
249
|
-
|
250
|
-
let(:mountpoint) { Pathname.new(Dir.mktmpdir(["rfusefs","metadir"])) }
|
251
|
-
let(:metadir) { FuseFS::MetaDir.new() }
|
252
|
-
let(:testdir) { mountpoint + "test" }
|
253
|
-
let(:testfile) { testdir + "hello.txt" }
|
254
|
-
|
255
|
-
before(:all) do
|
256
|
-
metadir.mkdir("/test")
|
257
|
-
metadir.write_to("/test/hello.txt","Hello World!\n")
|
258
|
-
metadir.xattr("/test/hello.txt")["user.test"] = "an extended attribute"
|
259
|
-
metadir.xattr("/test")["user.test"] = "a dir attribute"
|
260
|
-
FuseFS.mount(metadir,mountpoint)
|
261
|
-
#Give FUSE some time to get started
|
262
|
-
sleep(0.5)
|
263
|
-
end
|
264
|
-
|
265
|
-
after(:all) do
|
266
|
-
FuseFS.unmount(mountpoint)
|
267
|
-
sleep(0.5)
|
268
|
-
FileUtils.rm_r(mountpoint)
|
269
|
-
end
|
270
|
-
|
271
|
-
it "should list directory contents" do
|
272
|
-
testdir.entries().should =~ pathnames(".","..","hello.txt")
|
273
|
-
end
|
274
|
-
|
275
|
-
it "should read files" do
|
276
|
-
testfile.file?.should be_true
|
277
|
-
testfile.read().should == "Hello World!\n"
|
278
|
-
end
|
279
|
-
|
280
|
-
it "should read and write extended attributes from files" do
|
281
|
-
x = Xattr.new(testfile.to_s)
|
282
|
-
x["user.test"].should == "an extended attribute"
|
283
|
-
|
284
|
-
x["user.new"] = "new"
|
285
|
-
|
286
|
-
Xattr.new(testfile.to_s)["user.new"].should == "new"
|
287
|
-
end
|
288
|
-
|
289
|
-
it "should write extended attributes for directories" do
|
290
|
-
x = Xattr.new(testdir.to_s)
|
291
|
-
|
292
|
-
x["user.test"].should == "a dir attribute"
|
293
|
-
x["user.new"] = "new dir"
|
294
|
-
|
295
|
-
Xattr.new(testdir.to_s)["user.new"].should == "new dir"
|
296
|
-
end
|
297
|
-
|
298
|
-
|
299
|
-
it "should create directories" do
|
300
|
-
newdir = testdir + "newdir"
|
301
|
-
newdir.mkdir()
|
302
|
-
newdir.directory?.should be_true
|
303
|
-
testdir.entries().should =~ pathnames(".","..","hello.txt","newdir")
|
304
|
-
end
|
305
|
-
|
306
|
-
it "should create files" do
|
307
|
-
newfile = testdir + "newfile"
|
308
|
-
newfile.open("w") do |file|
|
309
|
-
file << "A new file\n"
|
310
|
-
end
|
311
|
-
newfile.read.should == "A new file\n"
|
312
|
-
end
|
313
|
-
|
314
|
-
it "should move directories" do
|
315
|
-
fromdir = testdir + "fromdir"
|
316
|
-
fromdir.mkdir()
|
317
|
-
subfile = fromdir + "afile"
|
318
|
-
subfile.open("w") do |file|
|
319
|
-
file << "testfile\n"
|
320
|
-
end
|
321
|
-
|
322
|
-
movedir = (mountpoint + "movedir")
|
323
|
-
movedir.directory?.should be_false
|
324
|
-
fromdir.rename(movedir)
|
325
|
-
movedir.directory?.should be_true
|
326
|
-
|
327
|
-
subfile = movedir + "afile"
|
328
|
-
subfile.file?.should be_true
|
329
|
-
subfile.read.should == "testfile\n"
|
330
|
-
end
|
331
|
-
|
332
|
-
it "should move files" do
|
333
|
-
movefile = (mountpoint + "moved.txt")
|
334
|
-
movefile.file?.should be_false
|
335
|
-
testfile.should be_true
|
336
|
-
testfile.rename(movefile)
|
337
|
-
movefile.read.should == "Hello World!\n"
|
338
|
-
end
|
339
|
-
|
340
|
-
|
341
|
-
it "should report filesystem statistics" do
|
342
|
-
bigfile = testdir + "bigfile"
|
343
|
-
bigfile.open("w") do |file|
|
344
|
-
file << ("x" * 2048)
|
345
|
-
end
|
346
|
-
|
347
|
-
statfs = Sys::Filesystem.stat(mountpoint.to_s)
|
348
|
-
|
349
|
-
# These are fixed
|
350
|
-
statfs.block_size.should == 1024
|
351
|
-
statfs.fragment_size.should == 1024
|
352
|
-
|
353
|
-
# These are dependant on the tests above creating files/directories
|
354
|
-
statfs.files.should == 8
|
355
|
-
statfs.files_available == 8
|
356
|
-
|
357
|
-
# assume test are less than 1 block, so dependant on bigfile above
|
358
|
-
statfs.blocks.should == 2
|
359
|
-
statfs.blocks_available.should == 0
|
360
|
-
statfs.blocks_free.should == 0
|
361
|
-
end
|
362
|
-
end
|
363
|
-
|
364
|
-
end
|