1#!/usr/bin/env python 2 3# This Source Code Form is subject to the terms of the Mozilla Public 4# License, v. 2.0. If a copy of the MPL was not distributed with this file, 5# You can obtain one at http://mozilla.org/MPL/2.0/. 6 7from __future__ import absolute_import 8 9import os 10import shutil 11import tempfile 12import unittest 13 14import mozunit 15 16from manifestparser import convert, ManifestParser 17 18 19class TestSymlinkConversion(unittest.TestCase): 20 """ 21 test conversion of a directory tree with symlinks to a manifest structure 22 """ 23 24 def create_stub(self, directory=None): 25 """stub out a directory with files in it""" 26 27 files = ("foo", "bar", "fleem") 28 if directory is None: 29 directory = tempfile.mkdtemp() 30 for i in files: 31 open(os.path.join(directory, i), "w").write(i) 32 subdir = os.path.join(directory, "subdir") 33 os.mkdir(subdir) 34 open(os.path.join(subdir, "subfile"), "w").write("baz") 35 return directory 36 37 def test_relpath(self): 38 """test convert `relative_to` functionality""" 39 40 oldcwd = os.getcwd() 41 stub = self.create_stub() 42 try: 43 # subdir with in-memory manifest 44 files = ["../bar", "../fleem", "../foo", "subfile"] 45 subdir = os.path.join(stub, "subdir") 46 os.chdir(subdir) 47 parser = convert([stub], relative_to=".") 48 self.assertEqual([i["name"] for i in parser.tests], files) 49 except BaseException: 50 raise 51 finally: 52 shutil.rmtree(stub) 53 os.chdir(oldcwd) 54 55 @unittest.skipIf( 56 not hasattr(os, "symlink"), "symlinks unavailable on this platform" 57 ) 58 def test_relpath_symlink(self): 59 """ 60 Ensure `relative_to` works in a symlink. 61 Not available on windows. 62 """ 63 64 oldcwd = os.getcwd() 65 workspace = tempfile.mkdtemp() 66 try: 67 tmpdir = os.path.join(workspace, "directory") 68 os.makedirs(tmpdir) 69 linkdir = os.path.join(workspace, "link") 70 os.symlink(tmpdir, linkdir) 71 self.create_stub(tmpdir) 72 73 # subdir with in-memory manifest 74 files = ["../bar", "../fleem", "../foo", "subfile"] 75 subdir = os.path.join(linkdir, "subdir") 76 os.chdir(os.path.realpath(subdir)) 77 for directory in (tmpdir, linkdir): 78 parser = convert([directory], relative_to=".") 79 self.assertEqual([i["name"] for i in parser.tests], files) 80 finally: 81 shutil.rmtree(workspace) 82 os.chdir(oldcwd) 83 84 # a more complicated example 85 oldcwd = os.getcwd() 86 workspace = tempfile.mkdtemp() 87 try: 88 tmpdir = os.path.join(workspace, "directory") 89 os.makedirs(tmpdir) 90 linkdir = os.path.join(workspace, "link") 91 os.symlink(tmpdir, linkdir) 92 self.create_stub(tmpdir) 93 files = ["../bar", "../fleem", "../foo", "subfile"] 94 subdir = os.path.join(linkdir, "subdir") 95 subsubdir = os.path.join(subdir, "sub") 96 os.makedirs(subsubdir) 97 linksubdir = os.path.join(linkdir, "linky") 98 linksubsubdir = os.path.join(subsubdir, "linky") 99 os.symlink(subdir, linksubdir) 100 os.symlink(subdir, linksubsubdir) 101 for dest in (subdir,): 102 os.chdir(dest) 103 for directory in (tmpdir, linkdir): 104 parser = convert([directory], relative_to=".") 105 self.assertEqual([i["name"] for i in parser.tests], files) 106 finally: 107 shutil.rmtree(workspace) 108 os.chdir(oldcwd) 109 110 @unittest.skipIf( 111 not hasattr(os, "symlink"), "symlinks unavailable on this platform" 112 ) 113 def test_recursion_symlinks(self): 114 workspace = tempfile.mkdtemp() 115 self.addCleanup(shutil.rmtree, workspace) 116 117 # create two dirs 118 os.makedirs(os.path.join(workspace, "dir1")) 119 os.makedirs(os.path.join(workspace, "dir2")) 120 121 # create cyclical symlinks 122 os.symlink(os.path.join("..", "dir1"), os.path.join(workspace, "dir2", "ldir1")) 123 os.symlink(os.path.join("..", "dir2"), os.path.join(workspace, "dir1", "ldir2")) 124 125 # create one file in each dir 126 open(os.path.join(workspace, "dir1", "f1.txt"), "a").close() 127 open(os.path.join(workspace, "dir1", "ldir2", "f2.txt"), "a").close() 128 129 data = [] 130 131 def callback(rootdirectory, directory, subdirs, files): 132 for f in files: 133 data.append(f) 134 135 ManifestParser._walk_directories([workspace], callback) 136 self.assertEqual(sorted(data), ["f1.txt", "f2.txt"]) 137 138 139if __name__ == "__main__": 140 mozunit.main() 141