summaryrefslogtreecommitdiffstats
path: root/python/mozbuild/mozbuild/test/controller/test_clobber.py
blob: fff3c5a4384d73d8d28f3b0cf818e5ff803f1651 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# 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 mozunit import main

from mozbuild.base import MozbuildObject
from mozbuild.controller.building import BuildDriver
from mozbuild.controller.clobber import Clobberer
from mozbuild.test.common import prepare_tmp_topsrcdir


class TestClobberer(unittest.TestCase):
    def setUp(self):
        self._temp_dirs = []
        self._old_env = dict(os.environ)
        os.environ.pop("MOZCONFIG", None)
        os.environ.pop("MOZ_OBJDIR", None)

        return unittest.TestCase.setUp(self)

    def tearDown(self):
        os.environ.clear()
        os.environ.update(self._old_env)

        for d in self._temp_dirs:
            shutil.rmtree(d, ignore_errors=True)

        return unittest.TestCase.tearDown(self)

    def get_tempdir(self):
        t = tempfile.mkdtemp()
        self._temp_dirs.append(t)
        return t

    def get_topsrcdir(self):
        t = self.get_tempdir()
        prepare_tmp_topsrcdir(t)
        p = os.path.join(t, "CLOBBER")
        with open(p, "a"):
            pass

        return t

    def test_no_objdir(self):
        """If topobjdir does not exist, no clobber is needed."""

        tmp = os.path.join(self.get_tempdir(), "topobjdir")
        self.assertFalse(os.path.exists(tmp))

        c = Clobberer(self.get_topsrcdir(), tmp)
        self.assertFalse(c.clobber_needed())

        required, performed, reason = c.maybe_do_clobber(os.getcwd(), True)
        self.assertFalse(required)
        self.assertFalse(performed)
        self.assertIsNone(reason)

        self.assertFalse(os.path.isdir(tmp))
        self.assertFalse(os.path.exists(os.path.join(tmp, "CLOBBER")))

    def test_objdir_no_clobber_file(self):
        """If CLOBBER does not exist in topobjdir, treat as empty."""

        c = Clobberer(self.get_topsrcdir(), self.get_tempdir())
        self.assertFalse(c.clobber_needed())

        required, performed, reason = c.maybe_do_clobber(os.getcwd(), True)
        self.assertFalse(required)
        self.assertFalse(performed)
        self.assertIsNone(reason)

        self.assertFalse(os.path.exists(os.path.join(c.topobjdir, "CLOBBER")))

    def test_objdir_clobber_newer(self):
        """If CLOBBER in topobjdir is newer, do nothing."""

        c = Clobberer(self.get_topsrcdir(), self.get_tempdir())
        with open(c.obj_clobber, "a"):
            pass

        required, performed, reason = c.maybe_do_clobber(os.getcwd(), True)
        self.assertFalse(required)
        self.assertFalse(performed)
        self.assertIsNone(reason)

    def test_objdir_clobber_older(self):
        """If CLOBBER in topobjdir is older, we clobber."""

        c = Clobberer(self.get_topsrcdir(), self.get_tempdir())
        with open(c.obj_clobber, "a"):
            pass

        dummy_path = os.path.join(c.topobjdir, "foo")
        with open(dummy_path, "a"):
            pass

        self.assertTrue(os.path.exists(dummy_path))

        old_time = os.path.getmtime(c.src_clobber) - 60
        os.utime(c.obj_clobber, (old_time, old_time))

        self.assertTrue(c.clobber_needed())

        required, performed, reason = c.maybe_do_clobber(os.getcwd(), True)
        self.assertTrue(required)
        self.assertTrue(performed)

        self.assertFalse(os.path.exists(dummy_path))
        self.assertFalse(os.path.exists(c.obj_clobber))

    def test_objdir_is_srcdir(self):
        """If topobjdir is the topsrcdir, refuse to clobber."""

        tmp = self.get_topsrcdir()
        c = Clobberer(tmp, tmp)

        self.assertFalse(c.clobber_needed())

    def test_cwd_is_topobjdir(self):
        """If cwd is topobjdir, we can still clobber."""
        c = Clobberer(self.get_topsrcdir(), self.get_tempdir())

        with open(c.obj_clobber, "a"):
            pass

        dummy_file = os.path.join(c.topobjdir, "dummy_file")
        with open(dummy_file, "a"):
            pass

        dummy_dir = os.path.join(c.topobjdir, "dummy_dir")
        os.mkdir(dummy_dir)

        self.assertTrue(os.path.exists(dummy_file))
        self.assertTrue(os.path.isdir(dummy_dir))

        old_time = os.path.getmtime(c.src_clobber) - 60
        os.utime(c.obj_clobber, (old_time, old_time))

        self.assertTrue(c.clobber_needed())

        required, performed, reason = c.maybe_do_clobber(c.topobjdir, True)
        self.assertTrue(required)
        self.assertTrue(performed)

        self.assertFalse(os.path.exists(dummy_file))
        self.assertFalse(os.path.exists(dummy_dir))

    def test_cwd_under_topobjdir(self):
        """If cwd is under topobjdir, we can't clobber."""

        c = Clobberer(self.get_topsrcdir(), self.get_tempdir())

        with open(c.obj_clobber, "a"):
            pass

        old_time = os.path.getmtime(c.src_clobber) - 60
        os.utime(c.obj_clobber, (old_time, old_time))

        d = os.path.join(c.topobjdir, "dummy_dir")
        os.mkdir(d)

        required, performed, reason = c.maybe_do_clobber(d, True)
        self.assertTrue(required)
        self.assertFalse(performed)
        self.assertIn("Cannot clobber while the shell is inside", reason)

    def test_mozconfig_opt_in(self):
        """Auto clobber iff AUTOCLOBBER is in the environment."""

        topsrcdir = self.get_topsrcdir()
        topobjdir = self.get_tempdir()

        obj_clobber = os.path.join(topobjdir, "CLOBBER")
        with open(obj_clobber, "a"):
            pass

        dummy_file = os.path.join(topobjdir, "dummy_file")
        with open(dummy_file, "a"):
            pass

        self.assertTrue(os.path.exists(dummy_file))

        old_time = os.path.getmtime(os.path.join(topsrcdir, "CLOBBER")) - 60
        os.utime(obj_clobber, (old_time, old_time))

        # Check auto clobber is off by default
        env = dict(os.environ)
        if env.get("AUTOCLOBBER", False):
            del env["AUTOCLOBBER"]

        mbo = MozbuildObject(topsrcdir, None, None, topobjdir)
        build = mbo._spawn(BuildDriver)

        status = build._check_clobber(build.mozconfig, env)

        self.assertEqual(status, True)
        self.assertTrue(os.path.exists(dummy_file))

        # Check auto clobber opt-in works
        env["AUTOCLOBBER"] = "1"

        status = build._check_clobber(build.mozconfig, env)
        self.assertFalse(status)
        self.assertFalse(os.path.exists(dummy_file))


if __name__ == "__main__":
    main()