summaryrefslogtreecommitdiffstats
path: root/python/mozbuild/mozbuild/test/backend/test_partialconfigenvironment.py
blob: 13b1656981259e2ac0cd839efd4a7c54783c6e9b (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
# 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 unittest
from shutil import rmtree
from tempfile import mkdtemp

import buildconfig
import mozpack.path as mozpath
from mozunit import main

from mozbuild.backend.configenvironment import PartialConfigEnvironment

config = {
    "defines": {
        "MOZ_FOO": "1",
        "MOZ_BAR": "2",
    },
    "substs": {
        "MOZ_SUBST_1": "1",
        "MOZ_SUBST_2": "2",
        "CPP": "cpp",
    },
}


class TestPartial(unittest.TestCase):
    def setUp(self):
        self._old_env = dict(os.environ)

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

    def _objdir(self):
        objdir = mkdtemp(dir=buildconfig.topsrcdir)
        self.addCleanup(rmtree, objdir)
        return objdir

    def test_auto_substs(self):
        """Test the automatically set values of ACDEFINES, and ALLDEFINES"""
        env = PartialConfigEnvironment(self._objdir())
        env.write_vars(config)
        self.assertEqual(env.substs["ACDEFINES"], "-DMOZ_BAR=2 -DMOZ_FOO=1")
        self.assertEqual(
            env.defines["ALLDEFINES"],
            {
                "MOZ_BAR": "2",
                "MOZ_FOO": "1",
            },
        )

    def test_remove_subst(self):
        """Test removing a subst from the config. The file should be overwritten with 'None'"""
        env = PartialConfigEnvironment(self._objdir())
        path = mozpath.join(env.topobjdir, "config.statusd", "substs", "MYSUBST")
        myconfig = config.copy()
        env.write_vars(myconfig)
        with self.assertRaises(KeyError):
            _ = env.substs["MYSUBST"]
        self.assertFalse(os.path.exists(path))

        myconfig["substs"]["MYSUBST"] = "new"
        env.write_vars(myconfig)

        self.assertEqual(env.substs["MYSUBST"], "new")
        self.assertTrue(os.path.exists(path))

        del myconfig["substs"]["MYSUBST"]
        env.write_vars(myconfig)
        with self.assertRaises(KeyError):
            _ = env.substs["MYSUBST"]
        # Now that the subst is gone, the file still needs to be present so that
        # make can update dependencies correctly. Overwriting the file with
        # 'None' is the same as deleting it as far as the
        # PartialConfigEnvironment is concerned, but make can't track a
        # dependency on a file that doesn't exist.
        self.assertTrue(os.path.exists(path))

    def _assert_deps(self, env, deps):
        deps = sorted(
            [
                "$(wildcard %s)" % (mozpath.join(env.topobjdir, "config.statusd", d))
                for d in deps
            ]
        )
        self.assertEqual(sorted(env.get_dependencies()), deps)

    def test_dependencies(self):
        """Test getting dependencies on defines and substs."""
        env = PartialConfigEnvironment(self._objdir())
        env.write_vars(config)
        self._assert_deps(env, [])

        self.assertEqual(env.defines["MOZ_FOO"], "1")
        self._assert_deps(env, ["defines/MOZ_FOO"])

        self.assertEqual(env.defines["MOZ_BAR"], "2")
        self._assert_deps(env, ["defines/MOZ_FOO", "defines/MOZ_BAR"])

        # Getting a define again shouldn't add a redundant dependency
        self.assertEqual(env.defines["MOZ_FOO"], "1")
        self._assert_deps(env, ["defines/MOZ_FOO", "defines/MOZ_BAR"])

        self.assertEqual(env.substs["MOZ_SUBST_1"], "1")
        self._assert_deps(
            env, ["defines/MOZ_FOO", "defines/MOZ_BAR", "substs/MOZ_SUBST_1"]
        )

        with self.assertRaises(KeyError):
            _ = env.substs["NON_EXISTENT"]
        self._assert_deps(
            env,
            [
                "defines/MOZ_FOO",
                "defines/MOZ_BAR",
                "substs/MOZ_SUBST_1",
                "substs/NON_EXISTENT",
            ],
        )
        self.assertEqual(env.substs.get("NON_EXISTENT"), None)

    def test_set_subst(self):
        """Test setting a subst"""
        env = PartialConfigEnvironment(self._objdir())
        env.write_vars(config)

        self.assertEqual(env.substs["MOZ_SUBST_1"], "1")
        env.substs["MOZ_SUBST_1"] = "updated"
        self.assertEqual(env.substs["MOZ_SUBST_1"], "updated")

        # A new environment should pull the result from the file again.
        newenv = PartialConfigEnvironment(env.topobjdir)
        self.assertEqual(newenv.substs["MOZ_SUBST_1"], "1")

    def test_env_override(self):
        """Test overriding a subst with an environment variable"""
        env = PartialConfigEnvironment(self._objdir())
        env.write_vars(config)

        self.assertEqual(env.substs["MOZ_SUBST_1"], "1")
        self.assertEqual(env.substs["CPP"], "cpp")

        # Reset the environment and set some environment variables.
        env = PartialConfigEnvironment(env.topobjdir)
        os.environ["MOZ_SUBST_1"] = "subst 1 environ"
        os.environ["CPP"] = "cpp environ"

        # The MOZ_SUBST_1 should be overridden by the environment, while CPP is
        # a special variable and should not.
        self.assertEqual(env.substs["MOZ_SUBST_1"], "subst 1 environ")
        self.assertEqual(env.substs["CPP"], "cpp")

    def test_update(self):
        """Test calling update on the substs or defines pseudo dicts"""
        env = PartialConfigEnvironment(self._objdir())
        env.write_vars(config)

        mysubsts = {"NEW": "new"}
        mysubsts.update(env.substs.iteritems())
        self.assertEqual(mysubsts["NEW"], "new")
        self.assertEqual(mysubsts["CPP"], "cpp")

        mydefines = {"DEBUG": "1"}
        mydefines.update(env.defines.iteritems())
        self.assertEqual(mydefines["DEBUG"], "1")
        self.assertEqual(mydefines["MOZ_FOO"], "1")


if __name__ == "__main__":
    main()