#!/usr/bin/env python # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. import os import shutil import tempfile import unittest from manifestparser import convert, ManifestParser class TestSymlinkConversion(unittest.TestCase): """ test conversion of a directory tree with symlinks to a manifest structure """ def create_stub(self, directory=None): """stub out a directory with files in it""" files = ('foo', 'bar', 'fleem') if directory is None: directory = tempfile.mkdtemp() for i in files: file(os.path.join(directory, i), 'w').write(i) subdir = os.path.join(directory, 'subdir') os.mkdir(subdir) file(os.path.join(subdir, 'subfile'), 'w').write('baz') return directory def test_relpath(self): """test convert `relative_to` functionality""" oldcwd = os.getcwd() stub = self.create_stub() try: # subdir with in-memory manifest files = ['../bar', '../fleem', '../foo', 'subfile'] subdir = os.path.join(stub, 'subdir') os.chdir(subdir) parser = convert([stub], relative_to='.') self.assertEqual([i['name'] for i in parser.tests], files) except: raise finally: shutil.rmtree(stub) os.chdir(oldcwd) @unittest.skipIf(not hasattr(os, 'symlink'), "symlinks unavailable on this platform") def test_relpath_symlink(self): """ Ensure `relative_to` works in a symlink. Not available on windows. """ oldcwd = os.getcwd() workspace = tempfile.mkdtemp() try: tmpdir = os.path.join(workspace, 'directory') os.makedirs(tmpdir) linkdir = os.path.join(workspace, 'link') os.symlink(tmpdir, linkdir) self.create_stub(tmpdir) # subdir with in-memory manifest files = ['../bar', '../fleem', '../foo', 'subfile'] subdir = os.path.join(linkdir, 'subdir') os.chdir(os.path.realpath(subdir)) for directory in (tmpdir, linkdir): parser = convert([directory], relative_to='.') self.assertEqual([i['name'] for i in parser.tests], files) finally: shutil.rmtree(workspace) os.chdir(oldcwd) # a more complicated example oldcwd = os.getcwd() workspace = tempfile.mkdtemp() try: tmpdir = os.path.join(workspace, 'directory') os.makedirs(tmpdir) linkdir = os.path.join(workspace, 'link') os.symlink(tmpdir, linkdir) self.create_stub(tmpdir) files = ['../bar', '../fleem', '../foo', 'subfile'] subdir = os.path.join(linkdir, 'subdir') subsubdir = os.path.join(subdir, 'sub') os.makedirs(subsubdir) linksubdir = os.path.join(linkdir, 'linky') linksubsubdir = os.path.join(subsubdir, 'linky') os.symlink(subdir, linksubdir) os.symlink(subdir, linksubsubdir) for dest in (subdir,): os.chdir(dest) for directory in (tmpdir, linkdir): parser = convert([directory], relative_to='.') self.assertEqual([i['name'] for i in parser.tests], files) finally: shutil.rmtree(workspace) os.chdir(oldcwd) @unittest.skipIf(not hasattr(os, 'symlink'), "symlinks unavailable on this platform") def test_recursion_symlinks(self): workspace = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, workspace) # create two dirs os.makedirs(os.path.join(workspace, 'dir1')) os.makedirs(os.path.join(workspace, 'dir2')) # create cyclical symlinks os.symlink(os.path.join('..', 'dir1'), os.path.join(workspace, 'dir2', 'ldir1')) os.symlink(os.path.join('..', 'dir2'), os.path.join(workspace, 'dir1', 'ldir2')) # create one file in each dir open(os.path.join(workspace, 'dir1', 'f1.txt'), 'a').close() open(os.path.join(workspace, 'dir1', 'ldir2', 'f2.txt'), 'a').close() data = [] def callback(rootdirectory, directory, subdirs, files): for f in files: data.append(f) ManifestParser._walk_directories([workspace], callback) self.assertEqual(sorted(data), ['f1.txt', 'f2.txt']) if __name__ == '__main__': unittest.main()