From 64599cf6ef12ae9ddd32f9c85b2ed2ad7bd7173c Mon Sep 17 00:00:00 2001 From: "Javier G. Sogo" Date: Tue, 30 Jun 2020 13:45:57 +0200 Subject: [PATCH] [fix] Use 'profile_build' (if given) to create graph for the test_package functionality (#7182) * populate the profile_build for the test_package ('conan create' command) * test 'conan test' command * create from scratch * conditionally use profile_build * remove not used imports * remove TODO notes: not for this PR * refactor tests --- conans/client/graph/graph_manager.py | 11 ++- .../build_helpers/cmake_targets_test.py | 1 - .../cross_building/test_package_test.py | 78 +++++++++++++++++++ 3 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 conans/test/functional/cross_building/test_package_test.py diff --git a/conans/client/graph/graph_manager.py b/conans/client/graph/graph_manager.py index c0feccfd77f..f880e0ea9ee 100644 --- a/conans/client/graph/graph_manager.py +++ b/conans/client/graph/graph_manager.py @@ -66,18 +66,22 @@ def load_consumer_conanfile(self, conanfile_path, info_folder, graph_lock = graph_lock_file.graph_lock self._output.info("Using lockfile: '{}/conan.lock'".format(info_folder)) profile_host = graph_lock_file.profile_host + profile_build = graph_lock_file.profile_build self._output.info("Using cached profile from lockfile") except IOError: # Only if file is missing graph_lock = None # This is very dirty, should be removed for Conan 2.0 (source() method only) profile_host = self._cache.default_profile profile_host.process_settings(self._cache) + profile_build = None name, version, user, channel = None, None, None, None else: name, version, user, channel, _ = graph_info.root profile_host.process_settings(self._cache, preprocess=False) # This is the hack of recovering the options from the graph_info profile_host.options.update(graph_info.options) + if profile_build: + profile_build.process_settings(self._cache, preprocess=False) if conanfile_path.endswith(".py"): lock_python_requires = None if graph_lock and not test: # Only lock python requires if it is not test_package @@ -88,13 +92,18 @@ def load_consumer_conanfile(self, conanfile_path, info_folder, name=name, version=version, user=user, channel=channel, lock_python_requires=lock_python_requires) + + if profile_build: + conanfile.settings_build = profile_build.processed_settings.copy() + conanfile.settings_target = None + if test: conanfile.display_name = "%s (test package)" % str(test) conanfile.output.scope = conanfile.display_name run_configure_method(conanfile, down_options=None, down_ref=None, ref=None) else: - conanfile = self._loader.load_conanfile_txt(conanfile_path, profile_host) + conanfile = self._loader.load_conanfile_txt(conanfile_path, profile_host=profile_host) load_deps_info(info_folder, conanfile, required=deps_info_required) diff --git a/conans/test/functional/build_helpers/cmake_targets_test.py b/conans/test/functional/build_helpers/cmake_targets_test.py index c46f382d565..fd859938530 100644 --- a/conans/test/functional/build_helpers/cmake_targets_test.py +++ b/conans/test/functional/build_helpers/cmake_targets_test.py @@ -1,4 +1,3 @@ -import os import platform import unittest diff --git a/conans/test/functional/cross_building/test_package_test.py b/conans/test/functional/cross_building/test_package_test.py new file mode 100644 index 00000000000..fbd53befdb9 --- /dev/null +++ b/conans/test/functional/cross_building/test_package_test.py @@ -0,0 +1,78 @@ +import textwrap +import unittest + +from jinja2 import Template +from parameterized import parameterized + +from conans.client.tools import save +from conans.test.utils.tools import TestClient + + +class TestPackageTestCase(unittest.TestCase): + conanfile_tpl = Template(textwrap.dedent(""" + from conans import ConanFile, tools + + class Recipe(ConanFile): + settings = "os" + {{ build_requires|default("") }} + + {% raw %} + def build(self): + self.output.info(">> settings.os: {}".format(self.settings.os)) + self.output.info(">> settings_build.os: {}".format(self.settings_build.os)) + self.output.info(">> tools.get_env('INFO'): {}".format(tools.get_env("INFO"))) + + def package_info(self): + setattr(self.env_info, "INFO", "{}-{}".format(self.name, self.settings.os)) + + def test(self): + pass + {% endraw %} + + """)) + + conanfile_br = conanfile_tpl.render() + conanfile = conanfile_tpl.render(build_requires='build_requires = "br1/version"') + conanfile_test = conanfile_tpl.render(build_requires='build_requires = "br2/version"') + + settings_yml = textwrap.dedent(""" + os: + Host: + Build: + """) + + @parameterized.expand([("create conanfile.py name/version@",), + ("test test_package/conanfile.py name/version@",)]) + def test_command(self, command): + t = TestClient() + save(t.cache.settings_path, self.settings_yml) + t.save({'br.py': self.conanfile_br, + 'conanfile.py': self.conanfile, + 'test_package/conanfile.py': self.conanfile_test, + 'profile_host': '[settings]\nos=Host', + 'profile_build': '[settings]\nos=Build', }) + t.run("export br.py br1/version@") + t.run("export br.py br2/version@") + t.run("export conanfile.py name/version@") + + # Execute the actual command we are testing + t.run(command + " --build=missing --profile:host=profile_host --profile:build=profile_build") + + # Build requires are built in the 'build' context: + self.assertIn("br1/version: >> settings.os: Build", t.out) + self.assertIn("br1/version: >> settings_build.os: Build", t.out) + self.assertIn("br1/version: >> tools.get_env('INFO'): None", t.out) + + self.assertIn("br2/version: >> settings.os: Build", t.out) + self.assertIn("br2/version: >> settings_build.os: Build", t.out) + self.assertIn("br2/version: >> tools.get_env('INFO'): None", t.out) + + # Package 'name' is built for the 'host' context (br1 as build_requirement) + self.assertIn("name/version: >> settings.os: Host", t.out) + self.assertIn("name/version: >> settings_build.os: Build", t.out) + self.assertIn("name/version: >> tools.get_env('INFO'): br1-Build", t.out) + + # Test_package is executed with the same profiles as the package itself + self.assertIn("name/version (test package): >> settings.os: Host", t.out) + self.assertIn("name/version (test package): >> settings_build.os: Build", t.out) + self.assertIn("name/version (test package): >> tools.get_env('INFO'): br2-Build", t.out)