rfuse 1.1.2 → 1.2.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.
@@ -1,63 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe RFuse::Fuse do
4
-
5
- let(:mockfs) { m = mock("fuse"); m.stub(:getattr).and_return(nil) ; m }
6
- let(:mountpoint) { tempmount() }
7
-
8
- context "#loop" do
9
- it "should exit from another thread and allow multiple loops" do
10
-
11
- fuse = RFuse::FuseDelegator.new(mockfs,mountpoint)
12
- t = Thread.new { sleep 0.2; fuse.exit }
13
- fuse.loop()
14
- t.join
15
- t = Thread.new { sleep 0.2; fuse.exit }
16
- fuse.loop
17
- t.join
18
- fuse.unmount
19
- fuse.mounted?.should be(false)
20
- end
21
-
22
-
23
- # This will never work!
24
- #it "should allow threads to operate on the filesystem" do
25
- #
26
- # mockfs = mock("fuse")
27
- # mockfs.stub(:getattr).and_return(nil)
28
- #
29
- # fuse = RFuse::FuseDelegator.new(mockfs,"/tmp/rfuse-spec")
30
- #
31
- # t = Thread.new { sleep 0.5 ; File.stat("/tmp/rfuse-spec/thread") ; fuse.exit }
32
- #
33
- # fuse.loop()
34
- # fuse.unmount()
35
- #end
36
-
37
- it "should allow other threads to be scheduled" do
38
-
39
- file_stat = RFuse::Stat.file(0444)
40
-
41
- thread_ran = false
42
-
43
- mockfs.stub(:getattr).with(anything(),"/before") {
44
- thread_ran.should be(false)
45
- file_stat
46
- }
47
-
48
- mockfs.stub(:getattr).with(anything(),"/missing") {
49
- #GC.start()
50
- thread_ran.should be(true)
51
- file_stat
52
- }
53
-
54
- t = Thread.new() { sleep 0.5 ; thread_ran = true }
55
- with_fuse(mountpoint,mockfs) do
56
- File.stat("#{mountpoint}/before");
57
- sleep 1;
58
- File.stat("#{mountpoint}/missing");
59
- end
60
- end
61
- end
62
- end
63
-
data/spec/run_spec.rb DELETED
@@ -1,60 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe RFuse::Fuse do
4
- context "#run" do
5
-
6
- let(:file_stat) { RFuse::Stat.file(0444) }
7
- let(:mountpoint) { tempmount() }
8
- let(:mockfs) { m = double("fuse"); allow(m).to receive(:getattr) { |ctx,path| puts "#{ctx},#{path}"}; m }
9
- let(:fuse) { RFuse::FuseDelegator.new(mockfs,mountpoint) }
10
-
11
- it "runs a mounted filesystem with default traps" do
12
-
13
- # expect traps to be set
14
- expect(mockfs).to receive(:sighup) { }
15
- expect(mockfs).to receive(:getattr).with(anything(),"/run").and_return(file_stat)
16
-
17
- # Need to call this before we fork..
18
- expect(fuse.mountpoint).to eq(mountpoint)
19
-
20
- pid = Process.pid
21
-
22
- fpid = Kernel.fork do
23
- File.stat("#{mountpoint}/run")
24
- Process.kill("HUP",pid)
25
- sleep(0.1)
26
- Process.kill("TERM",pid)
27
- end
28
-
29
- fuse.run
30
-
31
- rpid,result = Process.waitpid2(fpid)
32
- expect(result).to be_success
33
-
34
- expect(fuse).not_to be_mounted
35
- expect(Signal.trap("HUP","DEFAULT")).to eq("DEFAULT")
36
- end
37
-
38
- it "unmounts the filesystem and resets traps on exception" do
39
- expect(mockfs).to receive(:getattr).with(anything(),"/run").and_return(file_stat)
40
- # raising an error in a sighandler will exit the loop..
41
- expect(mockfs).to receive(:sighup).and_raise("oh noes")
42
- pid = Process.pid
43
- # Need to call this before we fork..
44
- expect(fuse.mountpoint).to eq(mountpoint)
45
-
46
- fpid = Kernel.fork do
47
- File.stat("#{mountpoint}/run")
48
- Process.kill("HUP",pid)
49
- end
50
-
51
- expect { fuse.run }.to raise_error
52
-
53
- pid,result = Process.waitpid2(fpid)
54
-
55
- expect(fuse).not_to be_mounted
56
- expect(Signal.trap("HUP","DEFAULT")).to eq("DEFAULT")
57
- end
58
-
59
- end
60
- end
data/spec/signals_spec.rb DELETED
@@ -1,108 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe RFuse::Fuse do
4
-
5
- let(:mountpoint) { tempmount() }
6
- let(:fuse) { RFuse::Fuse.new(mountpoint) }
7
-
8
- before(:each) do
9
- # Override traps (note rspec itself traps "INT") with "DEFAULT"
10
- @traps = ["INT","TERM","HUP","USR1","USR2"].inject({}) { |h,signame| h[signame] = Signal.trap(signame,"DEFAULT"); h }
11
- end
12
-
13
- after(:each) do
14
- fuse.unmount()
15
- # Restore previously set traps
16
- @traps.each_pair { |signame,prev_trap| Signal.trap(signame,prev_trap) }
17
- end
18
-
19
- context "#trap_signals" do
20
-
21
- it "returns the list of signals trapped" do
22
-
23
- allow(fuse).to receive(:sighup)
24
-
25
- expect(fuse.trap_signals("HUP")).to include("HUP")
26
- expect(Signal.trap("HUP","DEFAULT")).not_to eq("DEFAULT")
27
- end
28
-
29
- it "does not override previously set traps" do
30
-
31
- allow(fuse).to receive(:sighup)
32
-
33
- Signal.trap("HUP","HUPCOMMAND")
34
-
35
- expect(fuse.trap_signals()).not_to include("HUP")
36
- expect(Signal.trap("HUP","DEFAULT")).to eq("HUPCOMMAND")
37
- end
38
-
39
- it "only traps the specified signals" do
40
-
41
- allow(fuse).to receive(:sighup)
42
- allow(fuse).to receive(:sigusr2)
43
-
44
- expect(fuse.trap_signals("HUP")).to include("HUP")
45
- expect(Signal.trap("HUP","DEFAULT")).not_to eq("DEFAULT")
46
- expect(Signal.trap("USR2","DEFAULT")).to eq("DEFAULT")
47
- end
48
-
49
- it "allows signals to be handled by the filesystem" do
50
- expect(fuse).to receive(:sighup) { fuse.exit }
51
-
52
- expect(fuse.trap_signals("HUP")).to include("HUP")
53
-
54
- pid = Process.pid
55
- fork_fuse(fuse) { Process.kill("HUP",pid) }
56
- # Exitted loop, but still mounted - ie not with fusermount -u
57
- expect(fuse).to be_mounted
58
- end
59
-
60
- it "exits on INT by default" do
61
- pid = Process.pid
62
- expect(fuse.trap_signals("INT")).to include("INT")
63
-
64
- fork_fuse(fuse) { Process.kill("INT",pid) }
65
- expect(fuse).to be_mounted
66
- end
67
-
68
- it "exits on TERM by default" do
69
- pid = Process.pid
70
- expect(fuse.trap_signals("TERM")).to include("TERM")
71
-
72
- fork_fuse(fuse) { Process.kill("TERM",pid) }
73
- expect(fuse).to be_mounted
74
- end
75
-
76
- context "with a delegated filesystem" do
77
- let(:mockfs) { m = mock("fuse"); m.stub(:getattr).and_return(nil); m }
78
- let(:fuse) { RFuse::FuseDelegator.new(mockfs,mountpoint) }
79
-
80
- it "enables FuseDelegator debugging on USR1" do
81
-
82
- pid = Process.pid
83
- expect(fuse.trap_signals("USR1","INT")).to include("USR1")
84
-
85
- expect(fuse.debug?).to be(false)
86
-
87
- fork_fuse(fuse) do
88
- Process.kill("USR1",pid)
89
- sleep(0.1)
90
- Process.kill("INT",pid)
91
- end
92
-
93
- expect(fuse.debug?).to be(true)
94
- end
95
-
96
- it "allows delegate filesystem to override default sig handler method" do
97
- expect(mockfs).to receive(:sigint) { fuse.exit }
98
-
99
- pid = Process.pid
100
- fuse.trap_signals("INT")
101
-
102
- fork_fuse(fuse) do
103
- Process.kill("INT",pid)
104
- end
105
- end
106
- end
107
- end
108
- end
data/spec/spec_helper.rb DELETED
@@ -1,109 +0,0 @@
1
- require 'rfuse'
2
- require 'tmpdir'
3
-
4
- class FileModeMatcher
5
- def initialize(expected)
6
- @expected = expected
7
- end
8
-
9
- def description
10
- "file mode #{@expected}"
11
- end
12
-
13
- def ==(actual)
14
- (actual | RFuse::Stat::S_IFMT) == (@expected | RFuse::Stat::S_IFMT)
15
- end
16
- end
17
-
18
- module DoubleAliases
19
- def mock(*args, &block)
20
- double(*args, &block)
21
- end
22
- alias stub mock
23
- end
24
-
25
-
26
- module RFuseHelper
27
- # Runs the single threaded fuse loop
28
- # on a pre configured mock fuse filesystem
29
- # Executes fork block in a separate process
30
- # that is expected to return success
31
- def with_fuse(mnt,mockfs,*options,&fork_block)
32
-
33
- fuse = RFuse::FuseDelegator.new(mockfs,mnt,*options)
34
- fuse.mounted?.should be(true)
35
- fork_fuse(fuse) do
36
- begin
37
- fork_block.call() if fork_block
38
- ensure
39
- fusermount(mnt)
40
- end
41
- end
42
- fuse.open_files.should be_empty()
43
- fuse.mounted?.should be(false)
44
- end
45
-
46
- def fork_fuse(fuse,&fork_block)
47
-
48
- fpid = Kernel.fork() { fork_block.call() }
49
-
50
- fuse.loop
51
-
52
- pid,result = Process.waitpid2(fpid)
53
- result.should be_success
54
- end
55
-
56
- def fusermount(mnt)
57
- unless system("fusermount -u #{mnt} >/dev/null 2>&1")
58
- sleep(0.5)
59
- system("fusermount -u #{mnt}")
60
- end
61
- end
62
-
63
- def file_mode(mode)
64
- FileModeMatcher.new(mode)
65
- end
66
-
67
- def tempmount()
68
- Dir.mktmpdir("rfuse-spec")
69
- end
70
-
71
- # Generate a set of times with non-zero usec values
72
- def usec_times(*increments)
73
- increments.collect { |inc|
74
- begin
75
- time = Time.now() + inc
76
- sleep(0.001)
77
- end until time.usec != 0
78
- time
79
- }
80
- end
81
-
82
- end
83
-
84
- RSpec.configure do |config|
85
- config.expect_with :rspec do |c|
86
- c.syntax = [:should, :expect]
87
- end
88
- config.mock_with :rspec do |c|
89
- c.syntax = [:should, :expect]
90
- end
91
-
92
- config.after(:suite) do
93
- Dir.glob(Dir.tmpdir + "/rfuse-spec*") do |dir|
94
- count = 0
95
- begin
96
- system("fusermount -u #{dir} >/dev/null 2>&1")
97
- FileUtils.rmdir(dir)
98
- rescue Errno::EBUSY
99
- #puts "Cleaning up #{dir} is busy, retrying..."
100
- sleep(0.5)
101
- count = count + 1
102
- retry unless count > 3
103
- end
104
- end
105
- end
106
-
107
- config.include RFuseHelper
108
- config.include DoubleAliases
109
- end
data/spec/xattr_spec.rb DELETED
@@ -1,49 +0,0 @@
1
- require 'spec_helper'
2
- require 'ffi-xattr'
3
-
4
- describe RFuse::Fuse do
5
- it "should handle extended attributes" do
6
- mockfs = mock("fuse")
7
-
8
- file_stat = RFuse::Stat.file(0444,:size => 11)
9
-
10
- mockfs.stub(:getattr).and_return(file_stat)
11
- mockfs.stub(:getxattr) { |ctx,path,name|
12
- case name
13
- when "user.one"
14
- "1"
15
- when "user.two"
16
- "2"
17
- when "user.large"
18
- "x" * 1000
19
- else
20
- ""
21
- end
22
- }
23
-
24
- mockfs.stub(:listxattr).with(anything(),"/myfile").and_return([ "user.one","user.two","user.large" ])
25
- mockfs.should_receive(:setxattr).with(anything(),"/myfile","user.three","updated",anything())
26
- mockfs.should_receive(:removexattr).with(anything(),"/myfile","user.one")
27
-
28
- mountpoint = tempmount()
29
-
30
- with_fuse(mountpoint,mockfs) do
31
- xattr = Xattr.new("#{mountpoint}/myfile")
32
- xattr.list.should include("user.one")
33
- xattr.list.should include("user.two")
34
- xattr.list.size.should == 3
35
-
36
- xattr['user.one'].should == "1"
37
- xattr['user.two'].should == "2"
38
- xattr['user.three']= "updated"
39
- xattr['xxxxx'].should be_nil
40
- xattr.remove('user.one')
41
- # And now with a non-ruby system #TODO. There'd be a way to guard this properly
42
- if system("getfattr --version")
43
- system("getfattr -d #{mountpoint}/myfile > /dev/null").should be(true)
44
- else
45
- puts "Warning Skipping getfattr test"
46
- end
47
- end
48
- end
49
- end