blob: e3d404c4f329eb6e8e22e60943e7eb1c36760061 [file] [log] [blame]
Greg Estren2323dfe2020-07-15 12:02:51 -07001# Lint as: python3
2# Copyright 2020 The Bazel Authors. All rights reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15"""Tests for bazel_api.py."""
16import os
17import unittest
18from src.test.py.bazel import test_base
19from tools.ctexplain.bazel_api import BazelApi
20from tools.ctexplain.types import HostConfiguration
21from tools.ctexplain.types import NullConfiguration
22
23
24class BazelApiTest(test_base.TestBase):
25
26 _bazel_api: BazelApi = None
27
28 def setUp(self):
29 test_base.TestBase.setUp(self)
30 self._bazel_api = BazelApi(self.RunBazel)
31 self.ScratchFile('WORKSPACE')
32 self.CreateWorkspaceWithDefaultRepos('repo/WORKSPACE')
33
34 def tearDown(self):
35 test_base.TestBase.tearDown(self)
36
37 def testBasicCquery(self):
38 self.ScratchFile('testapp/BUILD', [
39 'filegroup(name = "fg", srcs = ["a.file"])',
40 ])
41 res = self._bazel_api.cquery(['//testapp:all'])
42 success = res[0]
43 cts = res[2]
44 self.assertTrue(success)
45 self.assertEqual(len(cts), 1)
46 self.assertEqual(cts[0].label, '//testapp:fg')
47 self.assertIsNone(cts[0].config)
48 self.assertGreater(len(cts[0].config_hash), 10)
49 self.assertIn('PlatformConfiguration', cts[0].transitive_fragments)
50
51 def testFailedCquery(self):
52 self.ScratchFile('testapp/BUILD', [
53 'filegroup(name = "fg", srcs = ["a.file"])',
54 ])
55 (success, stderr, cts) = self._bazel_api.cquery(['//testapp:typo'])
56 self.assertFalse(success)
57 self.assertEqual(len(cts), 0)
58 self.assertIn("target 'typo' not declared in package 'testapp'",
59 os.linesep.join(stderr))
60
61 def testTransitiveFragmentsAccuracy(self):
62 self.ScratchFile('testapp/BUILD', [
63 'filegroup(name = "fg", srcs = ["a.file"])',
64 'filegroup(name = "ccfg", srcs = [":ccbin"])',
65 'cc_binary(name = "ccbin", srcs = ["ccbin.cc"])'
66 ])
67 cts1 = self._bazel_api.cquery(['//testapp:fg'])[2]
68 self.assertNotIn('CppConfiguration', cts1[0].transitive_fragments)
69 cts2 = self._bazel_api.cquery(['//testapp:ccfg'])[2]
70 self.assertIn('CppConfiguration', cts2[0].transitive_fragments)
71
72 def testGetTargetConfig(self):
73 self.ScratchFile('testapp/BUILD', [
74 'filegroup(name = "fg", srcs = ["a.file"])',
75 ])
76 cts = self._bazel_api.cquery(['//testapp:fg'])[2]
77 config = self._bazel_api.get_config(cts[0].config_hash)
78 expected_fragments = ['PlatformConfiguration', 'JavaConfiguration']
79 for exp in expected_fragments:
Greg Estrenc1d70872020-08-25 07:17:08 -070080 self.assertIn(exp, config.fragments.keys())
Greg Estren2323dfe2020-07-15 12:02:51 -070081 core_options = config.options['CoreOptions']
82 self.assertIsNotNone(core_options)
83 self.assertIn(('stamp', 'false'), core_options.items())
84
85 def testGetHostConfig(self):
86 self.ScratchFile('testapp/BUILD', [
87 'genrule(',
88 ' name = "g",',
89 ' srcs = [],',
90 ' cmd = "",',
91 ' outs = ["g.out"],',
92 ' tools = [":fg"])',
93 'filegroup(name = "fg", srcs = ["a.file"])',
94 ])
95 query = ['//testapp:fg', '--universe_scope=//testapp:g']
96 cts = self._bazel_api.cquery(query)[2]
97 config = self._bazel_api.get_config(cts[0].config_hash)
98 self.assertIsInstance(config, HostConfiguration)
99 # We don't currently populate or read a host configuration's details.
100 self.assertEqual(len(config.fragments), 0)
101 self.assertEqual(len(config.options), 0)
102
103 def testGetNullConfig(self):
104 self.ScratchFile('testapp/BUILD', [
105 'filegroup(name = "fg", srcs = ["a.file"])',
106 ])
107 cts = self._bazel_api.cquery(['//testapp:a.file'])[2]
108 config = self._bazel_api.get_config(cts[0].config_hash)
109 self.assertIsInstance(config, NullConfiguration)
110 # Null configurations have no information by definition.
111 self.assertEqual(len(config.fragments), 0)
112 self.assertEqual(len(config.options), 0)
113
Greg Estrenc1d70872020-08-25 07:17:08 -0700114 def testConfigFragmentsMap(self):
115 self.ScratchFile('testapp/BUILD', [
116 'filegroup(name = "fg", srcs = ["a.file"])',
117 ])
118 cts = self._bazel_api.cquery(['//testapp:fg'])[2]
119 fragments_map = self._bazel_api.get_config(cts[0].config_hash).fragments
120 self.assertIn('PlatformOptions', fragments_map['PlatformConfiguration'])
121 self.assertIn('ShellConfiguration$Options',
122 fragments_map['ShellConfiguration'])
123
Greg Estren2323dfe2020-07-15 12:02:51 -0700124 def testConfigWithDefines(self):
125 self.ScratchFile('testapp/BUILD', [
126 'filegroup(name = "fg", srcs = ["a.file"])',
127 ])
128 cquery_args = ['//testapp:fg', '--define', 'a=b']
129 cts = self._bazel_api.cquery(cquery_args)[2]
130 config = self._bazel_api.get_config(cts[0].config_hash)
131 user_defined_options = config.options['user-defined']
132 self.assertIsNotNone(user_defined_options)
133 self.assertDictEqual(user_defined_options._dict, {'--define:a': 'b'})
134
135 def testConfigWithStarlarkFlags(self):
136 self.ScratchFile('testapp/defs.bzl', [
137 'def _flag_impl(settings, attr):', ' pass', 'string_flag = rule(',
138 ' implementation = _flag_impl,',
139 ' build_setting = config.string(flag = True)'
140 ')'
141 ])
142 self.ScratchFile('testapp/BUILD', [
143 'load(":defs.bzl", "string_flag")',
144 'string_flag(name = "my_flag", build_setting_default = "nada")',
145 'filegroup(name = "fg", srcs = ["a.file"])',
146 ])
147 cquery_args = ['//testapp:fg', '--//testapp:my_flag', 'algo']
148 cts = self._bazel_api.cquery(cquery_args)[2]
149 config = self._bazel_api.get_config(cts[0].config_hash)
150 user_defined_options = config.options['user-defined']
151 self.assertIsNotNone(user_defined_options)
152 self.assertDictEqual(user_defined_options._dict,
153 {'//testapp:my_flag': 'algo'})
154
155
156if __name__ == '__main__':
157 unittest.main()