| # Copyright 2020 The Bazel Authors. All rights reserved. | 
 | # | 
 | # Licensed under the Apache License, Version 2.0 (the "License"); | 
 | # you may not use this file except in compliance with the License. | 
 | # You may obtain a copy of the License at | 
 | # | 
 | #    http://www.apache.org/licenses/LICENSE-2.0 | 
 | # | 
 | # Unless required by applicable law or agreed to in writing, software | 
 | # distributed under the License is distributed on an "AS IS" BASIS, | 
 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | # See the License for the specific language governing permissions and | 
 | # limitations under the License. | 
 | """Tests for bazel_api.py.""" | 
 | import os | 
 | import unittest | 
 | from src.test.py.bazel import test_base | 
 | from tools.ctexplain.bazel_api import BazelApi | 
 | from tools.ctexplain.types import HostConfiguration | 
 | from tools.ctexplain.types import NullConfiguration | 
 |  | 
 |  | 
 | class BazelApiTest(test_base.TestBase): | 
 |  | 
 |   _bazel_api: BazelApi = None | 
 |  | 
 |   def setUp(self): | 
 |     test_base.TestBase.setUp(self) | 
 |     self._bazel_api = BazelApi(self.RunBazel) | 
 |     self.ScratchFile('WORKSPACE') | 
 |     self.CreateWorkspaceWithDefaultRepos('repo/WORKSPACE') | 
 |  | 
 |   def tearDown(self): | 
 |     test_base.TestBase.tearDown(self) | 
 |  | 
 |   def testBasicCquery(self): | 
 |     self.ScratchFile('testapp/BUILD', [ | 
 |         'filegroup(name = "fg", srcs = ["a.file"])', | 
 |     ]) | 
 |     res = self._bazel_api.cquery(['//testapp:all']) | 
 |     success = res[0] | 
 |     cts = res[2] | 
 |     self.assertTrue(success) | 
 |     self.assertEqual(len(cts), 1) | 
 |     self.assertEqual(cts[0].label, '//testapp:fg') | 
 |     self.assertIsNone(cts[0].config) | 
 |     self.assertGreater(len(cts[0].config_hash), 10) | 
 |     self.assertIn('PlatformConfiguration', cts[0].transitive_fragments) | 
 |  | 
 |   def testFailedCquery(self): | 
 |     self.ScratchFile('testapp/BUILD', [ | 
 |         'filegroup(name = "fg", srcs = ["a.file"])', | 
 |     ]) | 
 |     (success, stderr, cts) = self._bazel_api.cquery(['//testapp:typo']) | 
 |     self.assertFalse(success) | 
 |     self.assertEqual(len(cts), 0) | 
 |     self.assertIn("target 'typo' not declared in package 'testapp'", | 
 |                   os.linesep.join(stderr)) | 
 |  | 
 |   def testTransitiveFragmentsAccuracy(self): | 
 |     self.ScratchFile('testapp/BUILD', [ | 
 |         'filegroup(name = "fg", srcs = ["a.file"])', | 
 |         'filegroup(name = "ccfg", srcs = [":ccbin"])', | 
 |         'cc_binary(name = "ccbin", srcs = ["ccbin.cc"])' | 
 |     ]) | 
 |     cts1 = self._bazel_api.cquery(['//testapp:fg'])[2] | 
 |     self.assertNotIn('CppConfiguration', cts1[0].transitive_fragments) | 
 |     cts2 = self._bazel_api.cquery(['//testapp:ccfg'])[2] | 
 |     self.assertIn('CppConfiguration', cts2[0].transitive_fragments) | 
 |  | 
 |   def testGetTargetConfig(self): | 
 |     self.ScratchFile('testapp/BUILD', [ | 
 |         'filegroup(name = "fg", srcs = ["a.file"])', | 
 |     ]) | 
 |     cts = self._bazel_api.cquery(['//testapp:fg'])[2] | 
 |     config = self._bazel_api.get_config(cts[0].config_hash) | 
 |     expected_fragments = ['PlatformConfiguration', 'JavaConfiguration'] | 
 |     for exp in expected_fragments: | 
 |       self.assertIn(exp, config.fragments.keys()) | 
 |     core_options = config.options['CoreOptions'] | 
 |     self.assertIsNotNone(core_options) | 
 |     self.assertIn(('stamp', 'false'), core_options.items()) | 
 |  | 
 |   def testGetHostConfig(self): | 
 |     self.ScratchFile('testapp/BUILD', [ | 
 |         'genrule(', | 
 |         '    name = "g",', | 
 |         '    srcs = [],', | 
 |         '    cmd = "",', | 
 |         '    outs = ["g.out"],', | 
 |         '    tools = [":fg"])', | 
 |         'filegroup(name = "fg", srcs = ["a.file"])', | 
 |     ]) | 
 |     query = ['//testapp:fg', '--universe_scope=//testapp:g'] | 
 |     cts = self._bazel_api.cquery(query)[2] | 
 |     config = self._bazel_api.get_config(cts[0].config_hash) | 
 |     self.assertIsInstance(config, HostConfiguration) | 
 |     # We don't currently populate or read a host configuration's details. | 
 |     self.assertEqual(len(config.fragments), 0) | 
 |     self.assertEqual(len(config.options), 0) | 
 |  | 
 |   def testGetNullConfig(self): | 
 |     self.ScratchFile('testapp/BUILD', [ | 
 |         'filegroup(name = "fg", srcs = ["a.file"])', | 
 |     ]) | 
 |     cts = self._bazel_api.cquery(['//testapp:a.file'])[2] | 
 |     config = self._bazel_api.get_config(cts[0].config_hash) | 
 |     self.assertIsInstance(config, NullConfiguration) | 
 |     # Null configurations have no information by definition. | 
 |     self.assertEqual(len(config.fragments), 0) | 
 |     self.assertEqual(len(config.options), 0) | 
 |  | 
 |   def testConfigFragmentsMap(self): | 
 |     self.ScratchFile('testapp/BUILD', [ | 
 |         'filegroup(name = "fg", srcs = ["a.file"])', | 
 |     ]) | 
 |     cts = self._bazel_api.cquery(['//testapp:fg'])[2] | 
 |     fragments_map = self._bazel_api.get_config(cts[0].config_hash).fragments | 
 |     self.assertIn('PlatformOptions', fragments_map['PlatformConfiguration']) | 
 |     self.assertIn('ShellConfiguration$Options', | 
 |                   fragments_map['ShellConfiguration']) | 
 |  | 
 |   def testConfigWithDefines(self): | 
 |     self.ScratchFile('testapp/BUILD', [ | 
 |         'filegroup(name = "fg", srcs = ["a.file"])', | 
 |     ]) | 
 |     cquery_args = ['//testapp:fg', '--define', 'a=b'] | 
 |     cts = self._bazel_api.cquery(cquery_args)[2] | 
 |     config = self._bazel_api.get_config(cts[0].config_hash) | 
 |     user_defined_options = config.options['user-defined'] | 
 |     self.assertIsNotNone(user_defined_options) | 
 |     self.assertDictEqual(user_defined_options._dict, {'--define:a': 'b'}) | 
 |  | 
 |   def testConfigWithStarlarkFlags(self): | 
 |     self.ScratchFile('testapp/defs.bzl', [ | 
 |         'def _flag_impl(settings, attr):', | 
 |         '  pass', | 
 |         'string_flag = rule(', | 
 |         '  implementation = _flag_impl,', | 
 |         '  build_setting = config.string(flag = True)', | 
 |         ')', | 
 |     ]) | 
 |     self.ScratchFile('testapp/BUILD', [ | 
 |         'load(":defs.bzl", "string_flag")', | 
 |         'string_flag(name = "my_flag", build_setting_default = "nada")', | 
 |         'filegroup(name = "fg", srcs = ["a.file"])', | 
 |     ]) | 
 |     cquery_args = ['//testapp:fg', '--//testapp:my_flag', 'algo'] | 
 |     cts = self._bazel_api.cquery(cquery_args)[2] | 
 |     config = self._bazel_api.get_config(cts[0].config_hash) | 
 |     user_defined_options = config.options['user-defined'] | 
 |     self.assertIsNotNone(user_defined_options) | 
 |     self.assertDictEqual(user_defined_options._dict, | 
 |                          {'//testapp:my_flag': 'algo'}) | 
 |  | 
 |  | 
 | if __name__ == '__main__': | 
 |   unittest.main() |