Source code for tl.testing.fs
# Copyright (c) 2008 Thomas Lotze
# See also LICENSE.txt
"""Sandboxes of directories and files.
"""
import os
import os.path
import shutil
import tempfile
original_cwd = None
sandboxes = []
[docs]def new_sandbox(specification):
"""Create a directory with items given as lines of text, and chdir to it.
The specification is a multi-line string each of whose lines takes one of
the following forms:
``d foo``
create a directory named foo
``f foo/bar asdf``
create a file named bar inside foo/ with content 'asdf'
``l baz -> foo/bar``
create a symbolic link named baz, pointing to foo/bar
The sandbox directory will be added to the known sandboxes so it can be
removed when the test setup is torn down.
"""
root = tempfile.mkdtemp()
sandboxes.append(root)
root = os.path.join(root, '')
for line in specification.splitlines():
type_, raw_path, comment = (line.split(None, 2) + [''])[:3]
path = os.path.normpath(os.path.join(root, raw_path))
if not path.startswith(root):
raise ValueError('"%s" points outside the sandbox.' % raw_path)
if type_ == 'f':
f = open(path, 'w')
f.write(comment)
f.close()
elif type_ == 'd':
os.mkdir(path)
elif type_ == 'l':
assert comment.startswith('-> ')
os.symlink(comment[3:], path)
os.chdir(root)
[docs]def ls():
"""Print text lines listing the current working directory recursively.
The format of the text lines is the same as read by the ``new_sandbox()``
function. Lines are printed in alphabetical order.
"""
root = os.path.join(os.getcwd(), '')
items = []
def handle_symlink(path):
if os.path.islink(path):
items.append((path, 'l', '-> ' + os.readlink(path)))
return True
return False
for dirpath, dirnames, filenames in os.walk(root):
for name in dirnames:
path = os.path.join(dirpath, name)
if not handle_symlink(path):
items.append((path, 'd', ''))
for name in filenames:
path = os.path.join(dirpath, name)
if not handle_symlink(path):
items.append((path, 'f', open(path).read()))
for path, type_, comment in sorted(items):
assert path.startswith(root)
print type_, path[len(root):], comment
[docs]def setup_sandboxes(test=None):
"""Sandbox-related test set-up handler.
As creating a sandbox changes the current working directory to it, the
original working directory is saved by the test setup so it may be
restored upon tear-down.
"""
global original_cwd
original_cwd = os.getcwd()
[docs]def teardown_sandboxes(test=None):
"""Sandbox-related test tear-down handler.
Sandboxes created by the test are removed and the working directory is
changed back to the current one before the test.
"""
for path in sandboxes:
shutil.rmtree(path, ignore_errors=True)
del sandboxes[:]
os.chdir(original_cwd)