MockFS 0.1.2

Except for the fact that you can pretend you're talking to the entirety
of the filesystem from the root directory, is there much use for this
that wouldn't be met by running:

mount -t tmpfs tmpfs /somewhere

ie. your unit test would be something like:

require 'test/unit'

def move_log

File.rename('/somewhere/var/log/httpd/access_log','/somewhere/home/franc
is/logs/access_log')
end

class TestMoveLog < Test::Unit::TestCase
  def test_move_log
    assert(system("mount -t tmpfs tmpfs /somewhere"))
    begin
        require 'pathname'
        Pathname.new('/somewhere/var/log/httpd/').mkpath
        Pathname.new( '/somewhere/home/francis/logs/').mkpath
        File.open('/somewhere/var/log/httpd/access_log', "a") do |f|
                f.puts "line 1 of the access log"
        end
        move_log
        assert( File.exist?( '/somewhere/home/francis/logs/access_log' )
)
        assert( !File.exist?( '/somewhere/var/log/httpd/access_log' ) )
        contents = File.open( '/somewhere/home/francis/logs/access_log'
) do |f|
                  f.gets( nil )
        end
        assert_equal( "line 1 of the access log\n", contents )
    ensure
        assert(system("umount /somewhere"))
    end
  end
end

Or am I not understanding the project properly?

···

-----Original Message-----
From: Francis Hwang [mailto:sera@fhwang.net]
Sent: Tuesday, 20 September 2005 12:27 PM
To: ruby-talk ML
Subject: ANN: MockFS 0.1.2

Hi everyone,

MockFS lumbers forward with its newest release, 0.1.2. Besides a liberal
heaping of bugfixes, this version adds override.rb, which does some
convenient but possibly dangerous redefining of global constants and
methods. Ooh, danger!

http://rubyforge.org/projects/mockfs/

== What's MockFS?

MockFS is nothing less than an attempt to simulate a file system in
memory for the purposes of testing. I wrote it for my own use, because I
write lots of tests and sometimes I get sick of cleaning up test files.
It's a lot simpler to just simulate the disk in memory and drop the
whole thing when you're done with your test.

It's not complete by a longshot, but it's complete enough that I'm able
to use it to help me write tests for production code--most notably, for
Rhizome.org, a community website that gets more than a million pageviews
a month.

== What's new in 0.1.2?

* First, a lot of little things have been fixed. MockFS now has a better
understanding of file permissions, of paths, and the multiple ways that
File, FileUtils, and Dir allow the same method to be called through
class or instance methods.

* I've also added override.rb, which redefines File, FileUtils, and Dir.
This is so your code doesn't have to reference MockFS directly; the test
cases can include override.rb and reference the mock file system that
way.

override.rb also includes a redefinition of Kernel.require, so that if a
file doesn't exist in the real file system, Kernel.require will look for
it in the mock file system. This might be useful in cases where you have
configuration files written in Ruby, and would like to swap them out
during testing.

Pretty much everything in override.rb is experimental, so I'd urge
caution in including the file.

== Help me make this useful for you

I'm putting this out in the hopes that it will be useful right now to
others, but also as a way of soliciting specific bug reports. I don't
expect to fill in the entire necessary functionality overnight, but if
people submit targeted bug reports about specific cases and methods, I
can fill those in first.

Thanks,
Francis

#####################################################################################
This email has been scanned by MailMarshal, an email content filter.
#####################################################################################

Daniel Sheppard wrote:

Except for the fact that you can pretend you're talking to the entirety
of the filesystem from the root directory, is there much use for this
that wouldn't be met by running:

mount -t tmpfs tmpfs /somewhere

Well, tmpfs is Unix (Linux?) specific. But I would think even if you care about portability, it would be a heck of a lot simpler to just write some code that ensures that your temp directory gets deleted when your test program exits. Something like (untested code ahead):

require 'fileutils'
require 'tmpdir'

# Creates a temp directory in the system's temp directory, arranges
# for it to be deleted when the program exits, and returns the name
# of the new directory.
def create_temp_dir(prefix)
   # find a name that doesn't already exist
   idx = rand 10000
   dir = File.join(Dir.tmpdir, prefix, idx.to_s)
   loop do
     Dir.mkdir dir
     break
   rescue Errno::EEXIST => e
     idx += 1
     dir = File.join(Dir.tmpdir, prefix, idx.to_s)
   end

   # Arrange for dir to be deleted at program exit
   at_exit { FileUtils.rm_rf dir }
   dir
end

This way you're working with a real filesystem, and don't have to worry about your program behaving differently during testing due to differences between your mock filesystem implementation and a real filesystem.

I have never used the progs, but I'd hope that using a mock fs i would
be save from some bug creeping in that makes me execute a

base = "~"
file = "."
rm_rf(File.join(base, file))

where base and file are filled in with their values by a stupid
programming mistake.

regards,

Brian

···

On 20/09/05, Daniel Sheppard <daniels@pronto.com.au> wrote:

Except for the fact that you can pretend you're talking to the entirety
of the filesystem from the root directory, is there much use for this
that wouldn't be met by running:

mount -t tmpfs tmpfs /somewhere

[snip]

--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/

Daniel Sheppard wrote:

Except for the fact that you can pretend you're talking to the entirety
of the filesystem from the root directory, is there much use for this
that wouldn't be met by running:

mount -t tmpfs tmpfs /somewhere

From the sparse documentation for tmpfs, I don't know if I'm entirely

clear on its usage. However, it appears to me that you'd use tmpfs to
mount a new filesystem alongside the ones you've already got. I can see
how this would be useful in many cases, but the problem I wanted to
address with MockFS was one of having lots of files all over the place.

For example, a well-factored system might have a bunch of classes
looking like this:

class DiskCache
  @@cache_path = '/tmp/disk_cache.yml'
  ...
end

class WelcomeToOurWebsiteEmail
  @@template = '/var/www/email_templates/welcome.tmpl'
  @@log_file = '/var/log/email.log'
  ...
end

etc, etc. If all those files lived in the same place, you might be able
to use tmpfs to put them somewhere neat and unmount it at the end. But
in my experience, non-trivial systems have files that need to live in
different places for different reasons, and you'd rather not have to
change those just to make testing easier.

Another issue is one of safety; you'd rather have real-life logs or
other files unaffected by your test cases. In running my tests, I'd
rather play it safe and create a mock file system that lets me write to
whatever file locations I want, and then just GCs the results when the
tests stop running.

Of course, there are pretty obvious tradeoffs; MockFS is still far from
complete, and using it introduces extra verbosity into your production
code. I personally think the tradeoffs are okay because I write lots of
tests -- more than 600 on the primary codebase at my day job -- so
already I think MockFS has been worth it for me.

F.

Brian Schröder wrote:

···

On 20/09/05, Daniel Sheppard <daniels@pronto.com.au> wrote:

Except for the fact that you can pretend you're talking to the entirety
of the filesystem from the root directory, is there much use for this
that wouldn't be met by running:

mount -t tmpfs tmpfs /somewhere

The fact that this command isn't cross platform? :slight_smile:

Not that I've checked to see if MockFS is cross platform...

Regards,

Dan

Hi

···

--- Daniel Berger <Daniel.Berger@qwest.com> wrote:

Not that I've checked to see if MockFS is cross platform...

It has some problems on Windows. I haven't reported it yet because I do not have an exact handle
on it yet ... but it did not run just out of the box.

-- shanko

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

Hi,

>
> Not that I've checked to see if MockFS is cross platform...
>

It has some problems on Windows. I haven't reported it yet because I do not have an exact handle
on it yet ... but it did not run just out of the box.

Ok, I figured it out. It requires extensions/all

  http://www.rubyforge.org/projects/extensions

A reference to this fact in the announcement would be nice.
(Or did I miss it somehow ;-))

Anyway, I was able to run the following snippet without any error:

  require 'mockfs'
  MockFS.file_utils.mv( "C:\\temp\\junk.txt", "C:\\atest\\bunk.txt" )

But the tests that came with it failed miserably.

Francis?

-- shanko

···

--- Shashank Date <shanko_date@yahoo.com> wrote:

--- Daniel Berger <Daniel.Berger@qwest.com> wrote:

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

Shashank Date wrote:

Ok, I figured it out. It requires extensions/all

  http://www.rubyforge.org/projects/extensions

A reference to this fact in the announcement would be nice.
(Or did I miss it somehow ;-))

Sorry about that. I put the dependency in the README and in the gem,
but not in the announcement. I'll remember that for future reference.

Anyway, I was able to run the following snippet without any error:

  require 'mockfs'
  MockFS.file_utils.mv( "C:\\temp\\junk.txt", "C:\\atest\\bunk.txt" )

But the tests that came with it failed miserably.

I think I put this disclaimer in earlier announcements, but not this
one: I have no idea how well MockFS works for Windows, since I never
use Windows. Shashank, I'd really love it if you could try it out for
Windows and send me bug reports.

As for the tests, I'd guess that about 50% of them will fail--because
some of those tests run directly against the real filesystem, and they
assume that filesystem is a *nix FS. Each unit test in the current
release runs exactly twice, actually, once against the real FS and once
against the mock FS. (I actually wrote the bulk of the tests in a
module, then included it twice in different test cases that specify
whether to use the real or mock FS.)

Anyway, if you want to just send me the output of your test run, I can
work on cleaning that up for Windows.

Yeah, MockFS is still pretty beta.

f.

Hi Francis,

mockfs_tests.err (16.9 KB)

···

--- Francis Hwang <sera@fhwang.net> wrote:

Anyway, if you want to just send me the output of your test run, I can
work on cleaning that up for Windows.

Here you go ...file attached

HTH,
--shanko

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com