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
17from manifestparser import ManifestParser
18
19here = os.path.dirname(os.path.abspath(__file__))
20
21# In some cases tempfile.mkdtemp() may returns a path which contains
22# symlinks. Some tests here will then break, as the manifestparser.convert
23# function returns paths that does not contains symlinks.
24#
25# Workaround is to use the following function, if absolute path of temp dir
26# must be compared.
27
28
29def create_realpath_tempdir():
30    """
31    Create a tempdir without symlinks.
32    """
33    return os.path.realpath(tempfile.mkdtemp())
34
35
36class TestDirectoryConversion(unittest.TestCase):
37    """test conversion of a directory tree to a manifest structure"""
38
39    def create_stub(self, directory=None):
40        """stub out a directory with files in it"""
41
42        files = ("foo", "bar", "fleem")
43        if directory is None:
44            directory = create_realpath_tempdir()
45        for i in files:
46            open(os.path.join(directory, i), "w").write(i)
47        subdir = os.path.join(directory, "subdir")
48        os.mkdir(subdir)
49        open(os.path.join(subdir, "subfile"), "w").write("baz")
50        return directory
51
52    def test_directory_to_manifest(self):
53        """
54        Test our ability to convert a static directory structure to a
55        manifest.
56        """
57
58        # create a stub directory
59        stub = self.create_stub()
60        try:
61            stub = stub.replace(os.path.sep, "/")
62            self.assertTrue(os.path.exists(stub) and os.path.isdir(stub))
63
64            # Make a manifest for it
65            manifest = convert([stub])
66            out_tmpl = """[%(stub)s/bar]
67
68[%(stub)s/fleem]
69
70[%(stub)s/foo]
71
72[%(stub)s/subdir/subfile]
73
74"""  # noqa
75            self.assertEqual(str(manifest), out_tmpl % dict(stub=stub))
76        except BaseException:
77            raise
78        finally:
79            shutil.rmtree(stub)  # cleanup
80
81    def test_convert_directory_manifests_in_place(self):
82        """
83        keep the manifests in place
84        """
85
86        stub = self.create_stub()
87        try:
88            ManifestParser.populate_directory_manifests([stub], filename="manifest.ini")
89            self.assertEqual(
90                sorted(os.listdir(stub)),
91                ["bar", "fleem", "foo", "manifest.ini", "subdir"],
92            )
93            parser = ManifestParser()
94            parser.read(os.path.join(stub, "manifest.ini"))
95            self.assertEqual(
96                [i["name"] for i in parser.tests], ["subfile", "bar", "fleem", "foo"]
97            )
98            parser = ManifestParser()
99            parser.read(os.path.join(stub, "subdir", "manifest.ini"))
100            self.assertEqual(len(parser.tests), 1)
101            self.assertEqual(parser.tests[0]["name"], "subfile")
102        except BaseException:
103            raise
104        finally:
105            shutil.rmtree(stub)
106
107    def test_manifest_ignore(self):
108        """test manifest `ignore` parameter for ignoring directories"""
109
110        stub = self.create_stub()
111        try:
112            ManifestParser.populate_directory_manifests(
113                [stub], filename="manifest.ini", ignore=("subdir",)
114            )
115            parser = ManifestParser()
116            parser.read(os.path.join(stub, "manifest.ini"))
117            self.assertEqual([i["name"] for i in parser.tests], ["bar", "fleem", "foo"])
118            self.assertFalse(
119                os.path.exists(os.path.join(stub, "subdir", "manifest.ini"))
120            )
121        except BaseException:
122            raise
123        finally:
124            shutil.rmtree(stub)
125
126    def test_pattern(self):
127        """test directory -> manifest with a file pattern"""
128
129        stub = self.create_stub()
130        try:
131            parser = convert([stub], pattern="f*", relative_to=stub)
132            self.assertEqual([i["name"] for i in parser.tests], ["fleem", "foo"])
133
134            # test multiple patterns
135            parser = convert([stub], pattern=("f*", "s*"), relative_to=stub)
136            self.assertEqual(
137                [i["name"] for i in parser.tests], ["fleem", "foo", "subdir/subfile"]
138            )
139        except BaseException:
140            raise
141        finally:
142            shutil.rmtree(stub)
143
144    def test_update(self):
145        """
146        Test our ability to update tests from a manifest and a directory of
147        files
148        """
149
150        # boilerplate
151        tempdir = create_realpath_tempdir()
152        for i in range(10):
153            open(os.path.join(tempdir, str(i)), "w").write(str(i))
154
155        # otherwise empty directory with a manifest file
156        newtempdir = create_realpath_tempdir()
157        manifest_file = os.path.join(newtempdir, "manifest.ini")
158        manifest_contents = str(convert([tempdir], relative_to=tempdir))
159        with open(manifest_file, "w") as f:
160            f.write(manifest_contents)
161
162        # get the manifest
163        manifest = ManifestParser(manifests=(manifest_file,))
164
165        # All of the tests are initially missing:
166        paths = [str(i) for i in range(10)]
167        self.assertEqual([i["name"] for i in manifest.missing()], paths)
168
169        # But then we copy one over:
170        self.assertEqual(manifest.get("name", name="1"), ["1"])
171        manifest.update(tempdir, name="1")
172        self.assertEqual(sorted(os.listdir(newtempdir)), ["1", "manifest.ini"])
173
174        # Update that one file and copy all the "tests":
175        open(os.path.join(tempdir, "1"), "w").write("secret door")
176        manifest.update(tempdir)
177        self.assertEqual(
178            sorted(os.listdir(newtempdir)),
179            ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "manifest.ini"],
180        )
181        self.assertEqual(
182            open(os.path.join(newtempdir, "1")).read().strip(), "secret door"
183        )
184
185        # clean up:
186        shutil.rmtree(tempdir)
187        shutil.rmtree(newtempdir)
188
189
190if __name__ == "__main__":
191    mozunit.main()
192