Module: FFI::Libfuse::TestHelper
- Defined in:
- lib/ffi/libfuse/test_helper.rb
Overview
Can be included test classes to assist with running/debugging filesystems
Instance Method Summary collapse
- #mac_fuse? ⇒ Boolean
- #mounted?(mnt, _filesystem = '.*') ⇒ Boolean
-
#run_filesystem(filesystem, *args, env: {}) {|mnt| ... } ⇒ Array
Runs a filesystem in a separate process.
- #safe_fuse ⇒ Object
- #unmount(mnt) ⇒ Object
-
#with_fuse(operations, *args, **options) {|mnt| ... } ⇒ void
Runs the fuse loop on a pre configured fuse filesystem.
Instance Method Details
#mac_fuse? ⇒ Boolean
103 104 105 |
# File 'lib/ffi/libfuse/test_helper.rb', line 103 def mac_fuse? FFI::Platform::IS_MAC end |
#mounted?(mnt, _filesystem = '.*') ⇒ Boolean
80 81 82 83 84 |
# File 'lib/ffi/libfuse/test_helper.rb', line 80 def mounted?(mnt, _filesystem = '.*') type, prefix = mac_fuse? ? %w[macfuse /private] : %w[fuse] mounts = Sys::Filesystem.mounts.select { |m| m.mount_type == type } mounts.detect { |m| m.mount_point == "#{prefix}#{mnt}" } end |
#run_filesystem(filesystem, *args, env: {}) {|mnt| ... } ⇒ Array
Note:
if the filesystem is configured to daemonize then no output will be captured
Runs a filesystem in a separate process
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/ffi/libfuse/test_helper.rb', line 55 def run_filesystem(filesystem, *args, env: {}) fsname = File.basename(filesystem) t, err = safe_fuse do |mnt| t = Thread.new { open3_filesystem(args, env, filesystem, fsname, mnt) } sleep 1 begin raise Error, "#{fsname} not mounted at #{mnt}" if block_given? && !mounted?(mnt, fsname) yield mnt if block_given? [t, nil] rescue Minitest::Assertion, StandardError => e [t, e] end end o, e, s = t.value return [o, e, s.exitstatus] unless err warn "Errors\n#{e}" unless e.empty? warn "Output\n#{o}" unless o.empty? raise err end |
#safe_fuse ⇒ Object
94 95 96 97 98 99 100 101 |
# File 'lib/ffi/libfuse/test_helper.rb', line 94 def safe_fuse Dir.mktmpdir('ffi-libfuse-spec') do |mountpoint| yield mountpoint ensure # Attempt to force unmount. unmount(mountpoint) if mounted?(mountpoint) end end |
#unmount(mnt) ⇒ Object
86 87 88 89 90 91 92 |
# File 'lib/ffi/libfuse/test_helper.rb', line 86 def unmount(mnt) if mac_fuse? system("diskutil unmount force #{mnt} >/dev/null 2>&1") else system("fusermount#{FUSE_MAJOR_VERSION == 3 ? '3' : ''} -zu #{mnt} >/dev/null 2>&1") end end |
#with_fuse(operations, *args, **options) {|mnt| ... } ⇒ void
This method returns an undefined value.
Runs the fuse loop on a pre configured fuse filesystem
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/ffi/libfuse/test_helper.rb', line 22 def with_fuse(operations, *args, **) raise ArgumentError, 'Needs block' unless block_given? # ignore MacOS special files args << '-onoappledouble,noapplexattr' if mac_fuse? safe_fuse do |mnt| # Start the fork before loading fuse (for MacOS) fpid = Process.fork do sleep 2.5 # Give fuse a chance to start yield mnt end run_fuse(mnt, *args, operations: operations, **) do # TODO: Work out why waitpid2 hangs on mac unless the process has already finished sleep 10 if mac_fuse? _pid, block_status = Process.waitpid2(fpid) block_exit = block_status.exitstatus raise FFI::Libfuse::Error, "forked file operations failed with #{block_exit}" unless block_exit.zero? end end end |