Skip to main content

File System Overlay - filesystem layering for unit testing

Project description

File System Overlay (FSO) allows side-effect free unit testing of file I/O operations. It does this by creating a caching overlay over the local file system, allowing read-through access, but storing modifications in memory. These in-memory changes can be inspected, to validate unit tests, and when the test completes, all changes to the file system will be vaporized (to quote Dr. Stanley Goodspeed: http://www.youtube.com/watch?v=K-uEbYq9kNU&t=6m29s).

Project

TL;DR

Install:

$ pip install fso

Use:

import unittest, fso

class MyTest(unittest.TestCase):

  def setUp(self):
    fso.push()

  def tearDown(self):
    fso.pop()

  def test_fs_changes(self):

    self.assertFalse(os.path.exists('/etc/foobar.conf'))

    with open('/etc/foobar.conf', 'wb') as fp:
      fp.write('some-data')

    self.assertTrue(os.path.exists('/etc/foobar.conf'))
    self.assertEqual(open('/etc/foobar.conf', 'rb').read(), 'some-data')

    # BUT, when testing ends, /etc/foobar.conf will not exist! *awesome*! :)

Overview

Traditionally, testing I/O operations on the file system requires modifying the implementation so that there is a pluggable layer of file operations that gets replaced with mocks when performing tests (http://stackoverflow.com/questions/2655697/python-unittest-howto).

This is, IMHO, a terrible approach, since it means that the real code is not being executed, and may well hide some very real bugs.

Instead, the fso package switches out the implementation of the low-level file system calls, and caches changes in-memory, never actually modifying the file system.

Although this is a very “pure” approach, there are many gotchas… So, currently, only very basic file operations are supported (such as writing to a new file) – if you are doing more complex things, fso is not ready for you yet! But, if you don’t mind, please help identify those holes by either reporting issues or providing patches… any contributions will be merged and very much appreciated!

Supported Operations

Currently, only the following I/O functions have replacements implemented:

  • builtin.open

  • os.path.exists

  • os.makedirs

  • os.access

  • os.unlink

Unsupported Operations

The following need to be implemented in order to bring I/O coverage to a respectable minimum:

  • os.stat

  • os.path.isdir (might be covered by os.stat?)

  • os.path.isfile (might be covered by os.stat?)

  • os.path.islink (might be covered by os.stat?)

  • os.listdir

Known Limitations

  • The current implementation is very “bare bones” – user be warned!

  • File permissions are currently NOT enforced (and might be overkill).

  • Since changes are explicitly stored in-memory, changes that exceed the local machine’s memory will cause problems.

Usage

FSO supports context managers! Example:

import unittest, fso

class TestWithContextManager(unittest.TestCase):

  def test_with_cm(self):

    self.assertFalse(os.path.exists('no-such-file'))

    with fso.push() as overlay:

      self.assertFalse(os.path.exists('no-such-file'))

      with open('no-such-file', 'wb') as fp:
        fp.write('created')

      self.assertTrue(os.path.exists('no-such-file'))
      self.assertEqual(len(overlay.entries), 1)
      entry = overlay.entries.values()[0]
      self.assertEqual(entry.path, 'no-such-file')
      self.assertEqual(entry.type, 'file')
      self.assertEqual(entry.content, 'created')

    self.assertFalse(os.path.exists('no-such-file'))

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fso-0.1.0.tar.gz (6.9 kB view details)

Uploaded Source

File details

Details for the file fso-0.1.0.tar.gz.

File metadata

  • Download URL: fso-0.1.0.tar.gz
  • Upload date:
  • Size: 6.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for fso-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ed038f322a77d4ab84b41fbfe7d2d1012bcd32cb5ed1a676083bf26b55005d46
MD5 f6ed504061bfb537e448f6e7df534502
BLAKE2b-256 a6e3fcad180748f083087c0192c3fa3a1d755b9ba912548b76c2aa923dcc42c4

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page