def new_ci_test(self): client = TestClient() client.run('new MyPackage/1.3@myuser/testing -cis -ciw -cilg -cilc -cio -ciu=myurl') root = client.current_folder build_py = load(os.path.join(root, "build.py")) self.assertIn('builder.add_common_builds(shared_option_name="MyPackage:shared")', build_py) self.assertNotIn('visual_versions=', build_py) self.assertNotIn('gcc_versions=', build_py) self.assertNotIn('clang_versions=', build_py) self.assertNotIn('apple_clang_versions=', build_py) appveyor = load(os.path.join(root, "appveyor.yml")) self.assertIn("CONAN_UPLOAD: \"myurl\"", appveyor) self.assertIn('CONAN_REFERENCE: "MyPackage/1.3"', appveyor) self.assertIn('CONAN_USERNAME: "******"', appveyor) self.assertIn('CONAN_CHANNEL: "testing"', appveyor) self.assertIn('CONAN_VISUAL_VERSIONS: 12', appveyor) self.assertIn('CONAN_VISUAL_VERSIONS: 14', appveyor) self.assertIn('CONAN_VISUAL_VERSIONS: 15', appveyor) travis = load(os.path.join(root, ".travis.yml")) self.assertIn("- CONAN_UPLOAD: \"myurl\"", travis) self.assertIn('- CONAN_REFERENCE: "MyPackage/1.3"', travis) self.assertIn('- CONAN_USERNAME: "******"', travis) self.assertIn('- CONAN_CHANNEL: "testing"', travis) self.assertIn('env: CONAN_GCC_VERSIONS=5.4 CONAN_DOCKER_IMAGE=lasote/conangcc54', travis)
def test_profile_test_requires(self): client = TestClient() self._create(client) test_conanfile = """ import os from conans import ConanFile, tools class TestMyLib(ConanFile): requires = "MyLib/0.1@lasote/stable" def build(self): self.run("mytool") with tools.pythonpath(self): import mypythontool self.output.info(mypythontool.tool_hello_world()) def test(self): pass """ client.save({CONANFILE: lib_conanfile, "test_package/conanfile.py": test_conanfile, "profile.txt": profile, "profile2.txt": profile2}, clean_first=True) client.run("test_package --profile ./profile.txt --build missing") self.assertEqual(2, str(client.user_io.out).splitlines().count("Hello World!")) self.assertIn("MyLib/0.1@lasote/stable: Hello world from python tool!", client.user_io.out) self.assertIn("Project: Hello world from python tool!", client.user_io.out)
def test_path(self): base_folder = temp_folder() source_folder = os.path.join(base_folder, "source") current_folder = os.path.join(base_folder, "current") client = TestClient(current_folder=current_folder) files = cpp_hello_conan_files("Hello0", "0.1") conan_ref = ConanFileReference("Hello0", "0.1", "lasote", "stable") conanfile = files.pop("conanfile.py") client.save(files, path=source_folder) conanfile = conanfile.replace("exports = '*'", 'exports = "../source*"') client.save({"conanfile.py": conanfile}) client.run("export lasote/stable") reg_path = client.paths.export(conan_ref) manif = FileTreeManifest.loads(load(client.paths.digestfile_conanfile(conan_ref))) self.assertIn('%s: A new conanfile.py version was exported' % str(conan_ref), client.user_io.out) self.assertIn('%s: Folder: %s' % (str(conan_ref), reg_path), client.user_io.out) self.assertTrue(os.path.exists(reg_path)) for name in ['conanfile.py', 'conanmanifest.txt', 'source/main.cpp', 'source/executable', 'source/hello.cpp', 'source/CMakeLists.txt', 'source/helloHello0.h']: self.assertTrue(os.path.exists(os.path.join(reg_path, name))) expected_sums = {'source/hello.cpp': '4f005274b2fdb25e6113b69774dac184', 'source/main.cpp': '0479f3c223c9a656a718f3148e044124', 'source/CMakeLists.txt': '52546396c42f16be3daf72ecf7ab7143', 'conanfile.py': '3ac566eb5b2e4df4417003f0e606e237', 'source/executable': '68b329da9893e34099c7d8ad5cb9c940', 'source/helloHello0.h': '9448df034392fc8781a47dd03ae71bdd'} self.assertEqual(expected_sums, manif.file_sums)
def targets_own_flags_test(self): client = TestClient() client.save({"conanfile.py": conanfile_py.replace('version = "0.1"', 'version = "0.1"\n' ' settings = "compiler"')}) client.run("export . lasote/testing") cmake_targets = cmake.replace("conan_basic_setup()", "conan_basic_setup(TARGETS)\n" "get_target_property(HELLO_FLAGS CONAN_PKG::Hello" " INTERFACE_COMPILE_OPTIONS)\n" "get_target_property(HELLO_DEFINES CONAN_PKG::Hello" " INTERFACE_COMPILE_DEFINITIONS)") client.save({"conanfile.txt": conanfile, "CMakeLists.txt": cmake_targets}, clean_first=True) client.run('install . -g cmake') client.runner("cmake . -DCONAN_CXX_FLAGS=CmdCXXFlag", cwd=client.current_folder) cmake_cxx_flags = self._get_line(client.user_io.out, "CMAKE_CXX_FLAGS") self.assertNotIn("My", cmake_cxx_flags) self.assertIn("CmdCXXFlag", cmake_cxx_flags) self.assertIn("CONAN_CXX_FLAGS=MyFlag1 MyFlag2 CmdCXXFlag", client.user_io.out) self.assertIn("HELLO_CXX_FLAGS=-load;C:\some\path;MyFlag1;MyFlag2;" "$<$<CONFIG:Release>:;>;$<$<CONFIG:RelWithDebInfo>:;>;" "$<$<CONFIG:MinSizeRel>:;>;$<$<CONFIG:Debug>:;>", client.out) self.assertIn('HELLO_DEFINES=MY_DEF=My" \string;MY_DEF2=My${} other \string;', client.out)
def remove_specific_builds_test(self): client = TestClient() client.save({"conanfile.py": conanfile}) client.run("export user/channel") client.save({"conanfile.txt": consumer}, clean_first=True) client.run('install -s build_type=Debug') client.run('install -s build_type=Release') ref = ConanFileReference.loads("Pkg/0.1@user/channel") def _check_builds(): builds = client.client_cache.conan_builds(ref) self.assertEqual(1, len(builds)) packages = client.client_cache.conan_packages(ref) self.assertEqual(2, len(packages)) self.assertNotIn(builds[0], packages) return builds[0], packages build, packages = _check_builds() client.run("remove Pkg/0.1@user/channel -b %s -f" % packages[0]) _check_builds() client.run("remove Pkg/0.1@user/channel -b %s -f" % build) builds = client.client_cache.conan_builds(ref) self.assertEqual(0, len(builds)) packages = client.client_cache.conan_packages(ref) self.assertEqual(2, len(packages))
def remove_option_setting_test(self): # https://github.com/conan-io/conan/issues/2826 conanfile = """from conans import ConanFile class TestConan(ConanFile): settings = "os" options = {"opt": [True, False]} default_options = "opt=False" def package_id(self): self.output.info("OPTION OPT=%s" % self.info.options.opt) del self.info.settings.os del self.info.options.opt """ client = TestClient() client.save({"conanfile.py": conanfile}) client.run("create . Pkg/0.1@user/testing -s os=Windows") self.assertIn("Pkg/0.1@user/testing: OPTION OPT=False", client.out) self.assertIn("Pkg/0.1@user/testing: Package " "'5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9' created", client.out) client.run("create . Pkg/0.1@user/testing -s os=Linux -o Pkg:opt=True") self.assertIn("Pkg/0.1@user/testing: OPTION OPT=True", client.out) self.assertIn("Pkg/0.1@user/testing: Package " "'5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9' created", client.out)
def test_rel_path(self): base_folder = temp_folder() source_folder = os.path.join(base_folder, "source") current_folder = os.path.join(base_folder, "current") os.makedirs(current_folder) client = TestClient(current_folder=current_folder) files = cpp_hello_conan_files("Hello0", "0.1") conan_ref = ConanFileReference("Hello0", "0.1", "lasote", "stable") client.save(files, path=source_folder) client.run("export lasote/stable --path=../source") reg_path = client.paths.export(conan_ref) manif = FileTreeManifest.loads(load(client.paths.digestfile_conanfile(conan_ref))) self.assertIn('%s: A new conanfile.py version was exported' % str(conan_ref), client.user_io.out) self.assertIn('%s: Folder: %s' % (str(conan_ref), reg_path), client.user_io.out) self.assertTrue(os.path.exists(reg_path)) for name in list(files.keys()): self.assertTrue(os.path.exists(os.path.join(reg_path, name))) expected_sums = {'hello.cpp': '4f005274b2fdb25e6113b69774dac184', 'main.cpp': '0479f3c223c9a656a718f3148e044124', 'CMakeLists.txt': '52546396c42f16be3daf72ecf7ab7143', 'conanfile.py': '355949fbf0b4fc32b8f1c5a338dfe1ae', 'executable': '68b329da9893e34099c7d8ad5cb9c940', 'helloHello0.h': '9448df034392fc8781a47dd03ae71bdd'} self.assertEqual(expected_sums, manif.file_sums)
def scopes_test_package_test(self): client = TestClient() conanfile = """ from conans import ConanFile class HelloConan(ConanFile): name = "Hello" version = "0.1" def build(self): self.output.info("Scope: %s" % self.scope) """ test_conanfile = """ from conans import ConanFile, CMake import os class HelloReuseConan(ConanFile): requires = "Hello/0.1@lasote/stable" def test(self): self.conanfile_directory """ client.save({"conanfile.py": conanfile, "test/conanfile.py": test_conanfile}) client.run("test_package --scope Hello:dev=True --build=missing") self.assertIn("Hello/0.1@lasote/stable: Scope: dev=True", client.user_io.out)
def fail_test_package_test(self): client = TestClient() conanfile = """ from conans import ConanFile class HelloConan(ConanFile): name = "Hello" version = "0.1" exports = "*" def package(self): self.copy("*") """ test_conanfile = """ from conans import ConanFile, CMake import os class HelloReuseConan(ConanFile): requires = "Hello/0.1@lasote/stable" def test(self): self.conanfile_directory """ client.save({"conanfile.py": conanfile, "FindXXX.cmake": "Hello FindCmake", "test/conanfile.py": test_conanfile}) client.run("test_package") ref = PackageReference.loads("Hello/0.1@lasote/stable:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9") self.assertEqual("Hello FindCmake", load(os.path.join(client.paths.package(ref), "FindXXX.cmake"))) client.save({"FindXXX.cmake": "Bye FindCmake"}) client.run("test_package") self.assertEqual("Bye FindCmake", load(os.path.join(client.paths.package(ref), "FindXXX.cmake")))
def transitive_same_name_test(self): # https://github.com/conan-io/conan/issues/1366 client = TestClient() conanfile = ''' from conans import ConanFile class HelloConan(ConanFile): name = "HelloBar" version = "0.1" ''' test_package = ''' from conans import ConanFile class HelloTestConan(ConanFile): requires = "HelloBar/0.1@lasote/testing" def test(self): pass ''' client.save({"conanfile.py": conanfile, "test_package/conanfile.py": test_package}) client.run("test_package") self.assertIn("HelloBar/0.1@lasote/testing: WARN: Forced build from source", client.user_io.out) client.save({"conanfile.py": conanfile.replace("HelloBar", "Hello") + " requires='HelloBar/0.1@lasote/testing'", "test_package/conanfile.py": test_package.replace("HelloBar", "Hello")}) client.run("test_package") self.assertNotIn("HelloBar/0.1@lasote/testing: WARN: Forced build from source", client.user_io.out)
def test_package_env_test(self): client = TestClient() conanfile = ''' from conans import ConanFile class HelloConan(ConanFile): name = "Hello" version = "0.1" def package_info(self): self.env_info.PYTHONPATH.append("new/pythonpath/value") ''' test_package = ''' import os from conans import ConanFile class HelloTestConan(ConanFile): requires = "Hello/0.1@lasote/testing" def build(self): assert("new/pythonpath/value" in os.environ["PYTHONPATH"]) def test(self): assert("new/pythonpath/value" in os.environ["PYTHONPATH"]) ''' client.save({"conanfile.py": conanfile, "test_package/conanfile.py": test_package}) client.run("test_package")
def copy_test(self): client = TestClient() client.save({CONANFILE: conanfile}) client.run("export . lasote/stable") client.run("install Hello0/0.1@lasote/stable --build=missing") error = client.run("copy hello0/0.1@lasote/stable otheruser/testing", ignore_error=True) self._check(error, client)
class ProfileRequiresTest(unittest.TestCase): def setUp(self): self.client = TestClient() def _export(self, var_conanfile): self.client.save({CONANFILE: var_conanfile}, clean_first=True) self.client.run("export lasote/stable") def test_profile_requires(self): self._export(build_require_parent) self._export(build_require) self._export(build_require2) self._export(my_lib_parent) self._export(my_lib) self._export(my_lib2) reuse = """ [requires] MyLib/0.1@lasote/stable MyLib2/0.1@lasote/stable [generators] cmake gcc """ self.client.save({"profile.txt": profile, "conanfile.txt": reuse}, clean_first=True) self.client.run("install --profile ./profile.txt --build missing")
def test_disable_linter(self): client = TestClient() client.save({CONANFILE: conanfile}) client.run("config set general.recipe_linter=False") client.run("export lasote/stable") self.assertNotIn("ERROR: Py3 incompatibility", client.user_io.out) self.assertNotIn("WARN: Linter", client.user_io.out)
def patch_config_test(self): client = TestClient() conanfile = """from conans import ConanFile, CMake from conans.tools import save, load import os class AConan(ConanFile): settings = "os", "compiler", "build_type", "arch" def build(self): cmake = CMake(self) save("file1.cmake", "FOLDER " + self.package_folder) save("sub/file1.cmake", "FOLDER " + self.package_folder) cmake.patch_config_paths() def package(self): self.copy("*") self.output.info("RESULT: " + load(os.path.join(self.package_folder, "file1.cmake"))) self.output.info("RESULT2: " + load(os.path.join(self.package_folder, "sub/file1.cmake"))) """ client.save({"conanfile.py": conanfile}) client.run("create . Pkg/0.1@user/channel") self.assertIn("Pkg/0.1@user/channel: RESULT: FOLDER ${CONAN_PKG_ROOT}", client.out) self.assertIn("Pkg/0.1@user/channel: RESULT2: FOLDER ${CONAN_PKG_ROOT}", client.out) client.run("install .") error = client.run("build .", ignore_error=True) self.assertTrue(error) self.assertIn("ConanException: cmake.patch_config_paths() can't work without package name", client.out)
def test_patch_new_delete(self): conanfile = base_conanfile + ''' def build(self): from conans.tools import load, save save("oldfile", "legacy code") assert(os.path.exists("oldfile")) patch_content = """--- /dev/null +++ b/newfile @@ -0,0 +0,3 @@ +New file! +New file! +New file! --- a/oldfile +++ b/dev/null @@ -0,1 +0,0 @@ -legacy code """ patch(patch_string=patch_content) self.output.info("NEW FILE=%s" % load("newfile")) self.output.info("OLD FILE=%s" % os.path.exists("oldfile")) ''' client = TestClient() client.save({"conanfile.py": conanfile}) client.run("create . user/testing") self.assertIn("test/1.9.10@user/testing: NEW FILE=New file!\nNew file!\nNew file!\n", client.out) self.assertIn("test/1.9.10@user/testing: OLD FILE=False", client.out)
def no_signature_test(self): auth = AuthorizationHeaderSpy() retur = ReturnHandlerPlugin() server = TestServer(plugins=[auth, retur]) servers = {"default": server} client = TestClient(servers=servers, users={"default": [("lasote", "mypass")]}) client.save({"conanfile.py": conanfile}) client.run("export . lasote/stable") # Upload will fail, as conan_server is expecting a signed URL errors = client.run("upload Hello/0.1@lasote/stable", ignore_error=True) self.assertTrue(errors) expected_calls = [('get_conan_manifest_url', None), ('check_credentials', None), ('authenticate', 'Basic'), ('get_conanfile_snapshot', 'Bearer'), ('get_conanfile_upload_urls', 'Bearer'), ('put', 'Bearer')] self.assertEqual(len(expected_calls), len(auth.auths)) for i, (method, auth_type) in enumerate(expected_calls): real_call = auth.auths[i] self.assertEqual(method, real_call[0]) if auth_type: self.assertIn(auth_type, real_call[1]) # The Bearer of the last two calls must be identical self.assertEqual(auth.auths[-1][1], auth.auths[-2][1])
def generate_json_info_test(self): conanfile_py = """from conans import ConanFile class HelloConan(ConanFile): exports_sources = "*.h" def package(self): self.copy("*.h", dst="include") def package_info(self): self.env_info.MY_ENV_VAR = "foo" self.user_info.my_var = "my_value" """ client = TestClient() client.save({"conanfile.py": conanfile_py, "header.h": ""}) client.run("create . Hello/0.1@lasote/testing") client.run("install Hello/0.1@lasote/testing -g json") conan_json = os.path.join(client.current_folder, "conanbuildinfo.json") with open(conan_json) as f: data = json.load(f) self.assertEquals(data["deps_env_info"]["MY_ENV_VAR"], "foo") self.assertEquals(data["deps_user_info"]["Hello"]["my_var"], "my_value") hello_data = data["dependencies"][0] self.assertTrue(os.path.exists(hello_data["rootpath"])) include_path = hello_data["include_paths"][0] self.assertTrue(os.path.isabs(include_path)) self.assertTrue(os.path.exists(include_path))
def test_test_framework(self): client = TestClient() files = cpp_hello_conan_files("Test0") client.save(files, clean_first=True) client.run("export . lasote/stable") files = cpp_hello_conan_files("Test1", deps=["Test0/0.1@lasote/stable"]) client.save(files, clean_first=True) client.run("export . lasote/stable") # client.run("install Test1/0.1@lasote/stable --build=missing") client.save({"conanfile.py": conanfile, "test.cpp": test, "CMakeLists.txt": cmake, "profile.txt": test_profile}, clean_first=True) client.run("export . lasote/stable") client.run("install MyLib/0.1@lasote/stable --build=missing") self.assertIn("MyLib/0.1@lasote/stable: Generating the package", client.user_io.out) self.assertNotIn("100% tests passed", client.user_io.out) self.assertNotIn("Test0/0.1@lasote/stable", client.user_io.out) self.assertNotIn("Test1/0.1@lasote/stable", client.user_io.out) client.run("install MyLib/0.1@lasote/stable -pr=./profile.txt --build") self.assertIn("MyLib/0.1@lasote/stable: Generating the package", client.user_io.out) self.assertIn("Test0/0.1@lasote/stable", client.user_io.out) self.assertIn("Test1/0.1@lasote/stable", client.user_io.out) self.assertIn("100% tests passed", client.user_io.out)
def test_profile_override(self, conanfile): client = TestClient() client.save({CONANFILE: tool_conanfile2}, clean_first=True) client.run("export . lasote/stable") client.save({CONANFILE: conanfile, "profile.txt": profile, "profile2.txt": profile.replace("0.3", "[>0.2]")}, clean_first=True) client.run("export . lasote/stable") client.run("install MyLib/0.1@lasote/stable --profile ./profile.txt --build missing") self.assertNotIn("Tool/0.1", client.user_io.out) self.assertNotIn("Tool/0.2", client.user_io.out) self.assertIn("Tool/0.3@lasote/stable: Generating the package", client.user_io.out) self.assertIn("ToolPath: MyToolPath", client.user_io.out) client.run("install MyLib/0.1@lasote/stable") self.assertNotIn("Tool", client.user_io.out) self.assertIn("MyLib/0.1@lasote/stable: Already installed!", client.user_io.out) client.run("install MyLib/0.1@lasote/stable --profile ./profile2.txt --build") self.assertNotIn("Tool/0.1", client.user_io.out) self.assertNotIn("Tool/0.2", client.user_io.out) self.assertIn("Tool/0.3@lasote/stable: Generating the package", client.user_io.out) self.assertIn("ToolPath: MyToolPath", client.user_io.out)
def options_test(self): conanfile = """from conans import ConanFile class package(ConanFile): name = "first" version = "0.0.0" options = {"coverage": [True, False]} default_options = "coverage=False" def build(self): self.output.info("Coverage: %s" % self.options.coverage) """ client = TestClient() client.save({"conanfile.py": conanfile}) client.run("export . lasote/stable") consumer = """from conans import ConanFile class package(ConanFile): name = "second" version = "0.0.0" default_options = "first:coverage=True" build_requires = "first/0.0.0@lasote/stable" """ client.save({"conanfile.py": consumer}) client.run("install . --build=missing -o Pkg:someoption=3") self.assertIn("first/0.0.0@lasote/stable: Coverage: True", client.user_io.out)
def local_flow_test(self): """Use 'conan package' to process locally the package method""" client = TestClient() conanfile_template = """ from conans import ConanFile class MyConan(ConanFile): def package(self): self.copy(pattern="*.h", dst="include", src="include") """ files = {"include/file.h": "foo", CONANFILE: conanfile_template} client.save(files) origin_folder = client.current_folder client.run("install -g env -g txt") client.run("source") client.run("build") client.run("package .", ignore_error=True) self.assertIn("ERROR: Cannot 'conan package' to the build folder", client.user_io.out) package_folder = os.path.join(origin_folder, "package") mkdir(package_folder) client.current_folder = package_folder client.run('package .. --build_folder=..') content = load(os.path.join(client.current_folder, "include/file.h")) self.assertEqual(content, "foo")
def parallel_folders_test(self): client = TestClient() repo_folder = os.path.join(client.current_folder, "recipe") build_folder = os.path.join(client.current_folder, "build") package_folder = os.path.join(client.current_folder, "pkg") mkdir(repo_folder) mkdir(build_folder) mkdir(package_folder) client.current_folder = repo_folder # equivalent to git clone recipe client.save({"conanfile.py": conanfile, "file.h": "file_h_contents!"}) client.current_folder = build_folder client.run("install ../recipe") client.run("build ../recipe") client.current_folder = package_folder client.run("package ../recipe --build-folder=../build --package-folder='%s'" % package_folder) self._assert_pkg(package_folder) client.current_folder = repo_folder client.run("export . lasote/testing") client.run("export-pkg . Pkg/0.1@lasote/testing -bf=../pkg") ref = ConanFileReference.loads("Pkg/0.1@lasote/testing") cache_package_folder = client.client_cache.packages(ref) cache_package_folder = os.path.join(cache_package_folder, os.listdir(cache_package_folder)[0]) self._assert_pkg(cache_package_folder)
def test_basic(self): """ check that we do not generate anymore tgz with .c_src. also, they are not present any more in the cache layout, even if they come from a .c_src tgz server file """ test_server = TestServer() servers = {"default": test_server} client = TestClient(servers=servers, users={"default": [("lasote", "mypass")]}) client.save({"conanfile.py": """from conans import ConanFile class MyPkg(ConanFile): name= "Pkg" version = "0.1" exports_sources = "*.txt" """, "myfile.txt": "Hello world"}) client.run("export . lasote/testing") client.run("upload Pkg/0.1@lasote/testing") client.run("remove * -f") client.run("search") self.assertIn("There are no packages", client.user_io.out) conan_reference = ConanFileReference.loads("Pkg/0.1@lasote/testing") path = test_server.paths.export(conan_reference) sources_tgz = os.path.join(path, "conan_sources.tgz") self.assertTrue(os.path.exists(sources_tgz)) folder = temp_folder() with open(sources_tgz, 'rb') as file_handler: tar_extract(file_handler, folder) self.assertEqual(os.listdir(folder), ["myfile.txt"]) # Now install again client.run("install Pkg/0.1@lasote/testing --build=missing") export = client.client_cache.export(conan_reference) self.assertNotIn(EXPORT_SOURCES_DIR_OLD, os.listdir(export)) export_sources = client.client_cache.export_sources(conan_reference) self.assertEqual(os.listdir(export_sources), ["myfile.txt"])
def child_build_test(self): client = TestClient() repo_folder = client.current_folder build_folder = os.path.join(client.current_folder, "build") mkdir(build_folder) package_folder = os.path.join(build_folder, "package") mkdir(package_folder) client.save({"conanfile.py": conanfile_out}) client.current_folder = build_folder client.run("install ..") client.run("source ..") client.run("build .. --source-folder=.") client.current_folder = package_folder client.run("package ../.. --build-folder=../") self._assert_pkg(package_folder) rmdir(package_folder) client.current_folder = repo_folder client.run("export-pkg . Pkg/0.1@lasote/testing -bf=./build") ref = ConanFileReference.loads("Pkg/0.1@lasote/testing") cache_package_folder = client.client_cache.packages(ref) cache_package_folder = os.path.join(cache_package_folder, os.listdir(cache_package_folder)[0]) self._assert_pkg(cache_package_folder)
def install_from_remotes_test(self): for i in range(3): conan_reference = ConanFileReference.loads("Hello%d/0.1@lasote/stable" % i) files = cpp_hello_conan_files("Hello%d" % i, "0.1", build=False) self.client.save(files) self.client.run("export . lasote/stable") self.client.run("upload %s -r=remote%d" % (str(conan_reference), i)) self.client.run("info %s" % str(conan_reference)) self.assertIn("remote%d=http://" % i, self.client.user_io.out) # Now install it in other machine from remote 0 client2 = TestClient(servers=self.servers, users=self.users) files = cpp_hello_conan_files("HelloX", "0.1", deps=["Hello0/0.1@lasote/stable", "Hello1/0.1@lasote/stable", "Hello2/0.1@lasote/stable"]) files["conanfile.py"] = files["conanfile.py"].replace("def build(", "def build2(") client2.save(files) client2.run("install . --build=missing") self.assertIn("Hello0/0.1@lasote/stable from 'remote0'", client2.user_io.out) self.assertIn("Hello1/0.1@lasote/stable from 'remote1'", client2.user_io.out) self.assertIn("Hello2/0.1@lasote/stable from 'remote2'", client2.user_io.out) client2.run("info .") self.assertIn("Remote: remote0=http://", client2.user_io.out) self.assertIn("Remote: remote1=http://", client2.user_io.out) self.assertIn("Remote: remote2=http://", client2.user_io.out)
class PutPropertiesTest(unittest.TestCase): def setUp(self): test_server = TestServer() self.servers = {"default": test_server} def create_empty_property_file_test(self): files = cpp_hello_conan_files("Hello0", "0.1", build=False) client = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}) client.save(files) client.run("export lasote/stable") props_file = client.client_cache.put_headers_path self.assertTrue(os.path.exists(props_file)) def put_properties_test(self): wanted_vars = {"MyHeader1": "MyHeaderValue1;MyHeaderValue2", "Other": "Value"} class RequesterCheckHeaders(TestRequester): def put(self, url, data, headers=None, verify=None, auth=None): for name, value in wanted_vars.items(): value1 = headers[name] if value1 != value: raise Exception() return super(RequesterCheckHeaders, self).put(url, data, headers, verify, auth) self.client = TestClient(requester_class=RequesterCheckHeaders, servers=self.servers, users={"default": [("lasote", "mypass")]}) _create_property_files(self.client, wanted_vars) files = cpp_hello_conan_files("Hello0", "0.1", build=False) self.client.save(files) self.client.run("export lasote/stable") self.client.run("upload Hello0/0.1@lasote/stable -c")
def local_package_build_test(self): """Use 'conan package' to process locally the package method""" client = TestClient() conanfile_template = """ from conans import ConanFile class MyConan(ConanFile): exports = "*file.h" def package(self): self.copy(pattern="*.h", dst="include", src="include") """ files = {"include/file.h": "foo", "include/file2.h": "bar", CONANFILE: conanfile_template} client.save(files) origin_folder = client.current_folder build_folder = os.path.join(client.current_folder, "build") mkdir(build_folder) client.current_folder = build_folder client.run("install .. -g txt") # client.run("source ..") # self.assertEqual(os.listdir(os.path.join(client.current_folder, "include")), ["file.h"]) # client.run("build ..") client.current_folder = temp_folder() client.run('package "{0}" --build_folder="{0}/build" --source_folder="{0}"'.format(origin_folder)) content = load(os.path.join(client.current_folder, "include/file.h")) self.assertEqual(content, "foo")
def cmake_shared_flag_test(self): conanfile = """ import os from conans import ConanFile, CMake class MyLib(ConanFile): name = "MyLib" version = "0.1" options = {"shared": [True, False]} default_options= "shared=%s" settings = "arch", "compiler" def build(self): cmake = CMake(self) if self.options.shared: assert(cmake.definitions["BUILD_SHARED_LIBS"] == "ON") else: assert(cmake.definitions["BUILD_SHARED_LIBS"] == "OFF") """ client = TestClient() client.save({"conanfile.py": conanfile % "True"}) client.run("build .", ignore_error=True) self.assertIn("conanbuildinfo.txt file not found", client.user_io.out) client.run("install .") client.run("build .") client.save({"conanfile.py": conanfile % "False"}, clean_first=True) client.run("install .") client.run("build .")
def local_source_test(self): conanfile = ''' from conans import ConanFile from conans.util.files import save class ConanLib(ConanFile): def source(self): self.output.info("Running source!") err save("file1.txt", "Hello World") ''' # First, failing source() client = TestClient() client.save({CONANFILE: conanfile}) client.run("source .", ignore_error=True) self.assertIn("PROJECT: Running source!", client.user_io.out) self.assertIn("ERROR: PROJECT: Error in source() method, line 9", client.user_io.out) # Fix the error and repeat client.save({CONANFILE: conanfile.replace("err", "")}) client.run("source .") self.assertIn("PROJECT: Configuring sources in", client.user_io.out) self.assertIn("PROJECT: WARN: Your previous source command failed", client.user_io.out) self.assertIn("PROJECT: Running source!", client.user_io.out) self.assertEqual("Hello World", load(os.path.join(client.current_folder, "file1.txt")))
def test_force_file_type(self): client = TestClient() client.run('config install httpnonexisting --type=file', assert_error=True) self.assertIn("No such file or directory: 'httpnonexisting'", client.out)
class ConanSettingsPreprocessorTest(unittest.TestCase): def setUp(self): self.client = TestClient() self.conanfile = ''' from conans import ConanFile class HelloConan(ConanFile): name = "Hello0" version = "0.1" settings = "os", "compiler", "build_type" def configure(self): self.output.warn("Runtime: %s" % self.settings.get_safe("compiler.runtime")) ''' files = {"conanfile.py": self.conanfile} self.client.save(files) self.client.run("export . lasote/channel") def test_runtime_auto(self): # Ensure that compiler.runtime is not declared default_profile = load(self.client.cache.default_profile_path) self.assertNotIn(default_profile, "compiler.runtime") self.client.run("install Hello0/0.1@lasote/channel --build missing") if platform.system() == "Windows": self.assertIn("Runtime: MD", self.client.out) self.client.run("install Hello0/0.1@lasote/channel --build missing -s build_type=Debug") self.assertIn("Runtime: MDd", self.client.out) def test_runtime_not_present_ok(self): # Generate the settings.yml self.client.run("config init") default_settings = load(self.client.cache.settings_path) default_settings = default_settings.replace("runtime:", "# runtime:") save(self.client.cache.settings_path, default_settings) # Ensure the runtime setting is not there anymore self.client.run('install Hello0/0.1@lasote/channel --build missing -s ' 'compiler="Visual Studio" -s compiler.runtime="MDd"', assert_error=True) self.assertIn("'settings.compiler.runtime' doesn't exist for 'Visual Studio'", self.client.out) # Now install, the preprocessor shouldn't fail nor do anything self.client.run("install Hello0/0.1@lasote/channel --build missing") self.assertNotIn("Setting 'compiler.runtime' not declared, automatically", self.client.out)
def general_scope_options_test_package_test(self): client = TestClient() conanfile = """from conans import ConanFile class Pkg(ConanFile): options = {"shared": ["1", "2"]} def configure(self): self.output.info("BUILD SHARED: %s" % self.options.shared) """ test = """from conans import ConanFile class Pkg(ConanFile): def test(self): pass """ client.save({"conanfile.py": conanfile}) client.run("create . Pkg/0.1@user/testing -o *:shared=1") self.assertIn("Pkg/0.1@user/testing: BUILD SHARED: 1", client.out) client.run("create . Pkg/0.1@user/testing -o shared=2") self.assertIn("Pkg/0.1@user/testing: BUILD SHARED: 2", client.out) # With test_package client.save({ "conanfile.py": conanfile, "test_package/conanfile.py": test }) client.run("create . Pkg/0.1@user/testing -o *:shared=1") self.assertIn("Pkg/0.1@user/testing: BUILD SHARED: 1", client.out) client.run("create . Pkg/0.1@user/testing -o Pkg:shared=2") self.assertIn("Pkg/0.1@user/testing: BUILD SHARED: 2", client.out) client.run("create . Pkg/0.1@user/testing -o shared=1", assert_error=True) self.assertIn("'options.shared' doesn't exist", client.out) conanfile = """from conans import ConanFile class Pkg(ConanFile): pass """ client.save({"conanfile.py": conanfile}, clean_first=True) client.run("create . Pkg/0.1@user/testing -o *:shared=True") self.assertIn("Pkg/0.1@user/testing: Calling build()", client.out) client.run("create . Pkg/0.1@user/testing -o shared=False", assert_error=True) self.assertIn("'options.shared' doesn't exist", client.out) # With test_package client.save({ "conanfile.py": conanfile, "test_package/conanfile.py": test }) client.run("create . Pkg/0.1@user/testing -o *:shared=True") self.assertIn("Pkg/0.1@user/testing: Calling build()", client.out) self.assertIn("Pkg/0.1@user/testing (test package): Running build()", client.out)
def overridable_shared_option_test(self): client = TestClient() conanfile = GenConanfile().with_option("shared", [True, False])\ .with_default_option("shared", "False") client.save({"conanfile.py": conanfile}) client.run("create . liba/0.1@user/testing -o liba:shared=False") client.run("create . liba/0.1@user/testing -o liba:shared=True") consumer = textwrap.dedent(""" from conans import ConanFile class Pkg(ConanFile): requires = "liba/0.1@user/testing" options = {"shared": [True, False]} default_options = {"shared": False} def configure(self): if self.options.shared: self.options["*"].shared = True def package_id(self): self.info.shared_library_package_id() """) client.save({"conanfile.py": consumer}) # LibA STATIC for options in ("", "-o pkg:shared=False", "-o liba:shared=False", "-o pkg:shared=True -o liba:shared=False", "-o pkg:shared=False -o liba:shared=False"): client.run("create . pkg/0.1@user/testing %s" % options) self.assertIn( "liba/0.1@user/testing:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache", client.out) # LibA SHARED for options in ("-o pkg:shared=True", "-o pkg:shared=True -o liba:shared=True", "-o pkg:shared=False -o liba:shared=True"): client.run("create . pkg/0.1@user/testing %s" % options) self.assertIn( "liba/0.1@user/testing:2a623e3082a38f90cd2c3d12081161412de331b0 - Cache", client.out) # Pkg STATIC for options in ("", "-o pkg:shared=False", "-o liba:shared=False", "-o liba:shared=True", "-o pkg:shared=False -o liba:shared=False", "-o pkg:shared=False -o liba:shared=False"): client.run("create . pkg/0.1@user/testing %s" % options) self.assertIn( "pkg/0.1@user/testing:c74ab38053f265e63a1f3d819a41bc4b8332a6fc - Build", client.out) # Pkg SHARED, libA SHARED for options in ("-o pkg:shared=True", "-o pkg:shared=True -o liba:shared=True"): client.run("create . pkg/0.1@user/testing %s" % options) self.assertIn( "pkg/0.1@user/testing:fcaf52c0d66c3d68e6b6ae6330acafbcaae7dacf - Build", client.out) # Pkg SHARED, libA STATIC options = "-o pkg:shared=True -o liba:shared=False" client.run("create . pkg/0.1@user/testing %s" % options) self.assertIn( "pkg/0.1@user/testing:5e7619965702ca25bdff1b2ce672a8236b8da689 - Build", client.out)
def test_default_options(self): client = TestClient() conanfile = """ from conans import ConanFile class MyConanFile(ConanFile): name = "MyConanFile" version = "1.0" options = {"config": %s} default_options = "config%s" def configure(self): if self.options.config: self.output.info("Boolean evaluation") if self.options.config is None: self.output.info("None evaluation") if self.options.config == "None": self.output.info("String evaluation") """ # Using "ANY" as possible options client.save({"conanfile.py": conanfile % ("\"ANY\"", "")}) client.run("create . danimtb/testing", assert_error=True) self.assertIn("Error while initializing options.", client.out) client.save({"conanfile.py": conanfile % ("\"ANY\"", "=None")}) client.run("create . danimtb/testing") self.assertNotIn("Boolean evaluation", client.out) self.assertNotIn("None evaluation", client.out) self.assertIn("String evaluation", client.out) # Using None as possible options client.save({"conanfile.py": conanfile % ("[None]", "")}) client.run("create . danimtb/testing", assert_error=True) self.assertIn("Error while initializing options.", client.out) client.save({"conanfile.py": conanfile % ("[None]", "=None")}) client.run("create . danimtb/testing") self.assertNotIn("Boolean evaluation", client.out) self.assertNotIn("None evaluation", client.out) self.assertIn("String evaluation", client.out) # Using "None" as possible options client.save({"conanfile.py": conanfile % ("[\"None\"]", "")}) client.run("create . danimtb/testing", assert_error=True) self.assertIn("Error while initializing options.", client.out) client.save({"conanfile.py": conanfile % ("[\"None\"]", "=None")}) client.run("create . danimtb/testing") self.assertNotIn("Boolean evaluation", client.out) self.assertNotIn("None evaluation", client.out) self.assertIn("String evaluation", client.out) client.save( {"conanfile.py": conanfile % ("[\"None\"]", "=\\\"None\\\"")}) client.run("create . danimtb/testing", assert_error=True) self.assertIn("'\"None\"' is not a valid 'options.config' value", client.out) # Using "ANY" as possible options and "otherstringvalue" as default client.save( {"conanfile.py": conanfile % ("[\"otherstringvalue\"]", "")}) client.run("create . danimtb/testing", assert_error=True) self.assertIn("Error while initializing options.", client.out) client.save( {"conanfile.py": conanfile % ("\"ANY\"", "=otherstringvalue")}) client.run("create . danimtb/testing") self.assertIn("Boolean evaluation", client.out) self.assertNotIn("None evaluation", client.out) self.assertNotIn("String evaluation", client.out)
class ConfigInstallTest(unittest.TestCase): def setUp(self): self.client = TestClient() save(os.path.join(self.client.cache.profiles_path, "default"), "#default profile empty") save(os.path.join(self.client.cache.profiles_path, "linux"), "#empty linux profile") @staticmethod def _create_profile_folder(folder=None): folder = folder or temp_folder(path_with_spaces=False) save_files( folder, { "settings.yml": settings_yml, "remotes.txt": remotes, "profiles/linux": linux_profile, "profiles/windows": win_profile, "hooks/dummy": "#hook dummy", "hooks/foo.py": "#hook foo", "hooks/custom/custom.py": "#hook custom", ".git/hooks/foo": "foo", "hooks/.git/hooks/before_push": "before_push", "config/conan.conf": cache_conan_conf, "pylintrc": "#Custom pylint", "python/myfuncs.py": myfuncpy, "python/__init__.py": "" }) return folder def config_hooks_test(self): # Make sure the conan.conf hooks information is appended folder = temp_folder(path_with_spaces=False) conan_conf = textwrap.dedent(""" [hooks] foo custom/custom """) save_files(folder, {"config/conan.conf": conan_conf}) client = TestClient() client.run('config install "%s"' % folder) self.assertIn("Processing conan.conf", client.out) content = load(client.cache.conan_conf_path) self.assertEqual(1, content.count("foo")) self.assertEqual(1, content.count("custom/custom")) config = ConanClientConfigParser(client.cache.conan_conf_path) hooks = config.get_item("hooks") self.assertIn("foo", hooks) self.assertIn("custom/custom", hooks) self.assertIn("attribute_checker", hooks) client.run('config install "%s"' % folder) self.assertIn("Processing conan.conf", client.out) content = load(client.cache.conan_conf_path) self.assertEqual(1, content.count("foo")) self.assertEqual(1, content.count("custom/custom")) def _create_zip(self, zippath=None): folder = self._create_profile_folder() zippath = zippath or os.path.join(folder, "myconfig.zip") zipdir(folder, zippath) return zippath def _check(self, params): typ, uri, verify, args = [p.strip() for p in params.split(",")] configs = json.loads(load(self.client.cache.config_install_file)) config = _ConfigOrigin(configs[-1]) # Check the last one self.assertEqual(config.type, typ) self.assertEqual(config.uri, uri) self.assertEqual(str(config.verify_ssl), verify) self.assertEqual(str(config.args), args) settings_path = self.client.cache.settings_path self.assertEqual( load(settings_path).splitlines(), settings_yml.splitlines()) cache_remotes = self.client.cache.registry.load_remotes() self.assertEqual(list(cache_remotes.values()), [ Remote("myrepo1", "https://myrepourl.net", False, False), Remote("my-repo-2", "https://myrepo2.com", True, False), ]) self.assertEqual(sorted(os.listdir(self.client.cache.profiles_path)), sorted(["default", "linux", "windows"])) self.assertEqual( load(os.path.join(self.client.cache.profiles_path, "linux")).splitlines(), linux_profile.splitlines()) self.assertEqual( load(os.path.join(self.client.cache.profiles_path, "windows")).splitlines(), win_profile.splitlines()) conan_conf = ConanClientConfigParser(self.client.cache.conan_conf_path) self.assertEqual(conan_conf.get_item("log.run_to_output"), "False") self.assertEqual(conan_conf.get_item("log.run_to_file"), "False") self.assertEqual(conan_conf.get_item("log.level"), "10") self.assertEqual(conan_conf.get_item("general.compression_level"), "6") self.assertEqual( conan_conf.get_item("general.default_package_id_mode"), "full_package_mode") self.assertEqual(conan_conf.get_item("general.sysrequires_sudo"), "True") self.assertEqual(conan_conf.get_item("general.cpu_count"), "1") with six.assertRaisesRegex(self, ConanException, "'config_install' doesn't exist"): conan_conf.get_item("general.config_install") self.assertEqual(conan_conf.get_item("proxies.https"), "None") self.assertEqual(conan_conf.get_item("proxies.http"), "http://*****:*****@10.10.1.10:3128/") self.assertEqual( "#Custom pylint", load(os.path.join(self.client.cache_folder, "pylintrc"))) self.assertEqual( "", load( os.path.join(self.client.cache_folder, "python", "__init__.py"))) self.assertEqual( "#hook dummy", load(os.path.join(self.client.cache_folder, "hooks", "dummy"))) self.assertEqual( "#hook foo", load(os.path.join(self.client.cache_folder, "hooks", "foo.py"))) self.assertEqual( "#hook custom", load( os.path.join(self.client.cache_folder, "hooks", "custom", "custom.py"))) self.assertFalse( os.path.exists( os.path.join(self.client.cache_folder, "hooks", ".git"))) self.assertFalse( os.path.exists(os.path.join(self.client.cache_folder, ".git"))) def reuse_python_test(self): zippath = self._create_zip() self.client.run('config install "%s"' % zippath) conanfile = """from conans import ConanFile from myfuncs import mycooladd a = mycooladd(1, 2) assert a == 3 class Pkg(ConanFile): def build(self): self.output.info("A is %s" % a) """ self.client.save({"conanfile.py": conanfile}) self.client.run("create . Pkg/0.1@user/testing") self.assertIn("A is 3", self.client.out) def test_install_file_test(self): """ should install from a file in current dir """ zippath = self._create_zip() for filetype in ["", "--type=file"]: self.client.run('config install "%s" %s' % (zippath, filetype)) self._check("file, %s, True, None" % zippath) self.assertTrue(os.path.exists(zippath)) def test_install_config_file_test(self): """ should install from a settings and remotes file in configuration directory """ import tempfile profile_folder = self._create_profile_folder() self.assertTrue(os.path.isdir(profile_folder)) src_setting_file = os.path.join(profile_folder, "settings.yml") src_remote_file = os.path.join(profile_folder, "remotes.txt") # Install profile_folder without settings.yml + remotes.txt in order to install them manually tmp_dir = tempfile.mkdtemp() dest_setting_file = os.path.join(tmp_dir, "settings.yml") dest_remote_file = os.path.join(tmp_dir, "remotes.txt") shutil.move(src_setting_file, dest_setting_file) shutil.move(src_remote_file, dest_remote_file) self.client.run('config install "%s"' % profile_folder) shutil.move(dest_setting_file, src_setting_file) shutil.move(dest_remote_file, src_remote_file) shutil.rmtree(tmp_dir) for cmd_option in ["", "--type=file"]: self.client.run('config install "%s" %s' % (src_setting_file, cmd_option)) self.client.run('config install "%s" %s' % (src_remote_file, cmd_option)) self._check("file, %s, True, None" % src_remote_file) def test_install_dir_test(self): """ should install from a dir in current dir """ folder = self._create_profile_folder() self.assertTrue(os.path.isdir(folder)) for dirtype in ["", "--type=dir"]: self.client.run('config install "%s" %s' % (folder, dirtype)) self._check("dir, %s, True, None" % folder) def install_source_target_folders_test(self): folder = temp_folder() save_files(folder, { "subf/file.txt": "hello", "subf/subf/file2.txt": "bye" }) self.client.run('config install "%s" -sf=subf -tf=newsubf' % folder) content = load( os.path.join(self.client.cache_folder, "newsubf/file.txt")) self.assertEqual(content, "hello") content = load( os.path.join(self.client.cache_folder, "newsubf/subf/file2.txt")) self.assertEqual(content, "bye") def install_multiple_configs_test(self): folder = temp_folder() save_files(folder, { "subf/file.txt": "hello", "subf2/file2.txt": "bye" }) self.client.run('config install "%s" -sf=subf' % folder) content = load(os.path.join(self.client.cache_folder, "file.txt")) file2 = os.path.join(self.client.cache_folder, "file2.txt") self.assertEqual(content, "hello") self.assertFalse(os.path.exists(file2)) self.client.run('config install "%s" -sf=subf2' % folder) content = load(file2) self.assertEqual(content, "bye") save_files(folder, { "subf/file.txt": "HELLO!!", "subf2/file2.txt": "BYE!!" }) self.client.run('config install') content = load(os.path.join(self.client.cache_folder, "file.txt")) self.assertEqual(content, "HELLO!!") content = load(file2) self.assertEqual(content, "BYE!!") def test_dont_duplicate_configs(self): folder = temp_folder() save_files(folder, {"subf/file.txt": "hello"}) self.client.run('config install "%s" -sf=subf' % folder) self.client.run('config install "%s" -sf=subf' % folder) content = load(self.client.cache.config_install_file) self.assertEqual(1, content.count("subf")) self.client.run('config install "%s" -sf=other' % folder) content = load(self.client.cache.config_install_file) self.assertEqual(1, content.count("subf")) self.assertEqual(1, content.count("other")) def test_install_registry_txt_error(self): folder = temp_folder() save_files(folder, {"registry.txt": "myrepo1 https://myrepourl.net False"}) self.client.run('config install "%s"' % folder) self.assertIn( "WARN: registry.txt has been deprecated. Migrating to remotes.json", self.client.out) self.client.run("remote list") self.assertEqual( "myrepo1: https://myrepourl.net [Verify SSL: False]\n", self.client.out) def test_install_registry_json_error(self): folder = temp_folder() registry_json = { "remotes": [{ "url": "https://server.conan.io", "verify_ssl": True, "name": "conan.io" }] } save_files(folder, {"registry.json": json.dumps(registry_json)}) self.client.run('config install "%s"' % folder) self.assertIn( "WARN: registry.json has been deprecated. Migrating to remotes.json", self.client.out) self.client.run("remote list") self.assertEqual( "conan.io: https://server.conan.io [Verify SSL: True]\n", self.client.out) def test_install_remotes_json_error(self): folder = temp_folder() save_files(folder, {"remotes.json": ""}) self.client.run('config install "%s"' % folder, assert_error=True) self.assertIn( "ERROR: Failed conan config install: " "remotes.json install is not supported yet. Use 'remotes.txt'", self.client.out) def test_without_profile_folder(self): shutil.rmtree(self.client.cache.profiles_path) zippath = self._create_zip() self.client.run('config install "%s"' % zippath) self.assertEqual(sorted(os.listdir(self.client.cache.profiles_path)), sorted(["linux", "windows"])) self.assertEqual( load(os.path.join(self.client.cache.profiles_path, "linux")).splitlines(), linux_profile.splitlines()) def test_install_url(self): """ should install from a URL """ for origin in ["", "--type=url"]: def my_download(obj, url, filename, **kwargs): # @UnusedVariable self._create_zip(filename) with patch.object(FileDownloader, 'download', new=my_download): self.client.run( "config install http://myfakeurl.com/myconf.zip %s" % origin) self._check("url, http://myfakeurl.com/myconf.zip, True, None") # repeat the process to check self.client.run( "config install http://myfakeurl.com/myconf.zip %s" % origin) self._check("url, http://myfakeurl.com/myconf.zip, True, None") def install_change_only_verify_ssl_test(self): def my_download(obj, url, filename, **kwargs): # @UnusedVariable self._create_zip(filename) with patch.object(FileDownloader, 'download', new=my_download): self.client.run("config install http://myfakeurl.com/myconf.zip") self._check("url, http://myfakeurl.com/myconf.zip, True, None") # repeat the process to check self.client.run( "config install http://myfakeurl.com/myconf.zip --verify-ssl=False" ) self._check("url, http://myfakeurl.com/myconf.zip, False, None") def failed_install_repo_test(self): """ should install from a git repo """ self.client.run('config install notexistingrepo.git', assert_error=True) self.assertIn("ERROR: Failed conan config install: Can't clone repo", self.client.out) def failed_install_http_test(self): """ should install from a http zip """ self.client.run("config set general.retry_wait=0") self.client.run('config install httpnonexisting', assert_error=True) self.assertIn( "ERROR: Failed conan config install: " "Error while installing config from httpnonexisting", self.client.out) def install_repo_test(self): """ should install from a git repo """ folder = self._create_profile_folder() with self.client.chdir(folder): self.client.run_command('git init .') self.client.run_command('git add .') self.client.run_command('git config user.name myname') self.client.run_command( 'git config user.email [email protected]') self.client.run_command('git commit -m "mymsg"') self.client.run('config install "%s/.git"' % folder) check_path = os.path.join(folder, ".git") self._check("git, %s, True, None" % check_path) def install_repo_relative_test(self): relative_folder = "./config" absolute_folder = os.path.join(self.client.current_folder, "config") mkdir(absolute_folder) folder = self._create_profile_folder(absolute_folder) with self.client.chdir(folder): self.client.run_command('git init .') self.client.run_command('git add .') self.client.run_command('git config user.name myname') self.client.run_command( 'git config user.email [email protected]') self.client.run_command('git commit -m "mymsg"') self.client.run('config install "%s/.git"' % relative_folder) self._check("git, %s, True, None" % os.path.join("%s" % folder, ".git")) def install_custom_args_test(self): """ should install from a git repo """ folder = self._create_profile_folder() with self.client.chdir(folder): self.client.run_command('git init .') self.client.run_command('git add .') self.client.run_command('git config user.name myname') self.client.run_command( 'git config user.email [email protected]') self.client.run_command('git commit -m "mymsg"') self.client.run( 'config install "%s/.git" --args="-c init.templateDir=value"' % folder) check_path = os.path.join(folder, ".git") self._check("git, %s, True, -c init.templateDir=value" % check_path) def test_force_git_type(self): client = TestClient() client.run('config install httpnonexisting --type=git', assert_error=True) self.assertIn("Can't clone repo", client.out) def test_force_dir_type(self): client = TestClient() client.run('config install httpnonexisting --type=dir', assert_error=True) self.assertIn( "ERROR: Failed conan config install: No such directory: 'httpnonexisting'", client.out) def test_force_file_type(self): client = TestClient() client.run('config install httpnonexisting --type=file', assert_error=True) self.assertIn("No such file or directory: 'httpnonexisting'", client.out) def test_force_url_type(self): client = TestClient() client.run('config install httpnonexisting --type=url', assert_error=True) self.assertIn( "Error downloading file httpnonexisting: 'Invalid URL 'httpnonexisting'", client.out) def reinstall_error_test(self): """ should use configured URL in conan.conf """ self.client.run("config install", assert_error=True) self.assertIn("Called config install without arguments", self.client.out) def removed_credentials_from_url_unit_test(self): """ Unit tests to remove credentials in netloc from url when using basic auth # https://github.com/conan-io/conan/issues/2324 """ url_without_credentials = r"https://server.com/resource.zip" url_with_credentials = r"https://*****:*****@server.com/resource.zip" url_hidden_password = r"https://*****:*****@server.com/resource.zip" # Check url is the same when not using credentials self.assertEqual(_hide_password(url_without_credentials), url_without_credentials) # Check password is hidden using url with credentials self.assertEqual(_hide_password(url_with_credentials), url_hidden_password) # Check that it works with other protocols ftp ftp_with_credentials = r"ftp://*****:*****@server.com/resurce.zip" ftp_hidden_password = r"ftp://*****:*****@server.com/resurce.zip" self.assertEqual(_hide_password(ftp_with_credentials), ftp_hidden_password) # Check function also works for file paths *unix/windows unix_file_path = r"/tmp/test" self.assertEqual(_hide_password(unix_file_path), unix_file_path) windows_file_path = r"c:\windows\test" self.assertEqual(_hide_password(windows_file_path), windows_file_path) # Check works with empty string self.assertEqual(_hide_password(''), '') def remove_credentials_config_installer_test(self): """ Functional test to check credentials are not displayed in output but are still present in conan configuration # https://github.com/conan-io/conan/issues/2324 """ fake_url_with_credentials = "http://*****:*****@myfakeurl.com/myconf.zip" fake_url_hidden_password = "******" def my_download(obj, url, filename, **kwargs): # @UnusedVariable self.assertEqual(url, fake_url_with_credentials) self._create_zip(filename) with patch.object(FileDownloader, 'download', new=my_download): self.client.run("config install %s" % fake_url_with_credentials) # Check credentials are not displayed in output self.assertNotIn(fake_url_with_credentials, self.client.out) self.assertIn(fake_url_hidden_password, self.client.out) # Check credentials still stored in configuration self._check("url, %s, True, None" % fake_url_with_credentials) def ssl_verify_test(self): fake_url = "https://fakeurl.com/myconf.zip" def download_verify_false(obj, url, filename, **kwargs): # @UnusedVariable self.assertFalse(obj._verify_ssl) self._create_zip(filename) def download_verify_true(obj, url, filename, **kwargs): # @UnusedVariable self.assertTrue(obj._verify_ssl) self._create_zip(filename) with patch.object(FileDownloader, 'download', new=download_verify_false): self.client.run("config install %s --verify-ssl=False" % fake_url) with patch.object(FileDownloader, 'download', new=download_verify_true): self.client.run("config install %s --verify-ssl=True" % fake_url) def test_git_checkout_is_possible(self): folder = self._create_profile_folder() with self.client.chdir(folder): self.client.run_command('git init .') self.client.run_command('git add .') self.client.run_command('git config user.name myname') self.client.run_command( 'git config user.email [email protected]') self.client.run_command('git commit -m "mymsg"') self.client.run_command('git checkout -b other_branch') save(os.path.join(folder, "hooks", "cust", "cust.py"), "") self.client.run_command('git add .') self.client.run_command('git commit -m "my file"') self.client.run_command('git tag 0.0.1') self.client.run_command('git checkout master') # Without checkout self.client.run('config install "%s/.git"' % folder) check_path = os.path.join(folder, ".git") self._check("git, %s, True, None" % check_path) file_path = os.path.join(self.client.cache.hooks_path, "cust", "cust.py") self.assertFalse(os.path.exists(file_path)) # With checkout tag and reuse url self.client.run('config install --args="-b 0.0.1"') check_path = os.path.join(folder, ".git") self._check("git, %s, True, -b 0.0.1" % check_path) self.assertTrue(os.path.exists(file_path)) # With checkout branch and reuse url self.client.run('config install --args="-b other_branch"') check_path = os.path.join(folder, ".git") self._check("git, %s, True, -b other_branch" % check_path) self.assertTrue(os.path.exists(file_path)) # Add changes to that branch and update with self.client.chdir(folder): self.client.run_command('git checkout other_branch') save(os.path.join(folder, "hooks", "other", "other.py"), "") self.client.run_command('git add .') self.client.run_command('git commit -m "my other file"') self.client.run_command('git checkout master') other_path = os.path.join(self.client.cache_folder, "hooks", "other", "other.py") self.assertFalse(os.path.exists(other_path)) self.client.run('config install') check_path = os.path.join(folder, ".git") self._check("git, %s, True, -b other_branch" % check_path) self.assertTrue(os.path.exists(other_path)) def test_config_install_requester(self): # https://github.com/conan-io/conan/issues/4169 http_server = StoppableThreadBottle() path = self._create_zip() from bottle import static_file @http_server.server.get("/myconfig.zip") def get_zip(): return static_file(os.path.basename(path), os.path.dirname(path)) http_server.run_server() self.client.run("config install http://localhost:%s/myconfig.zip" % http_server.port) self.assertIn("Unzipping", self.client.out) http_server.stop() def test_error_missing_origin(self): path = self._create_zip() self.client.run('config install "%s"' % path) os.remove(path) self.client.run('config install', assert_error=True) self.assertIn("ERROR: Failed conan config install", self.client.out) def test_list_remove(self): path = self._create_zip() self.client.run('config install "%s"' % path) configs = json.loads( load(os.path.join(self.client.cache_folder, "config_install.json"))) self.assertIn("myconfig.zip", configs[0]["uri"]) self.client.run("config install --list") self.assertIn("myconfig.zip", self.client.out) self.client.run("config install --remove=0") configs = json.loads( load(os.path.join(self.client.cache_folder, "config_install.json"))) self.assertEqual(0, len(configs)) self.client.run("config install --list") self.assertNotIn("myconfig.zip", self.client.out) def test_list_empty_config(self): self.client.run("config install --list") self.assertEqual("", self.client.out) def test_remove_empty_config(self): self.client.run("config install --remove=0", assert_error=True) self.assertIn("There is no config data. Need to install config first.", self.client.out) def test_overwrite_read_only_file(self): source_folder = self._create_profile_folder() self.client.run('config install "%s"' % source_folder) # make existing settings.yml read-only make_file_read_only(self.client.cache.settings_path) self.assertFalse(os.access(self.client.cache.settings_path, os.W_OK)) # config install should overwrite the existing read-only file self.client.run('config install "%s"' % source_folder) self.assertTrue(os.access(self.client.cache.settings_path, os.W_OK)) def test_dont_copy_file_permissions(self): source_folder = self._create_profile_folder() # make source settings.yml read-only make_file_read_only(os.path.join(source_folder, 'remotes.txt')) self.client.run('config install "%s"' % source_folder) self.assertTrue(os.access(self.client.cache.settings_path, os.W_OK))
class ConfigInstallSchedTest(unittest.TestCase): def setUp(self): self.folder = temp_folder(path_with_spaces=False) save_files(self.folder, {"conan.conf": conanconf_interval}) self.client = TestClient() def test_config_install_sched_file(self): """ Config install can be executed without restriction """ self.client.run('config install "%s"' % self.folder) self.assertIn("Processing conan.conf", self.client.out) content = load(self.client.cache.conan_conf_path) self.assertEqual(1, content.count("config_install_interval")) self.assertIn("config_install_interval = 5m", content.splitlines()) self.assertTrue(os.path.exists(self.client.cache.config_install_file)) self.assertLess( os.path.getmtime(self.client.cache.config_install_file), time.time() + 1) def test_execute_more_than_once(self): """ Once executed by the scheduler, conan config install must executed again when invoked manually """ self.client.run('config install "%s"' % self.folder) self.assertIn("Processing conan.conf", self.client.out) self.client.run('config install "%s"' % self.folder) self.assertIn("Processing conan.conf", self.client.out) self.assertLess( os.path.getmtime(self.client.cache.config_install_file), time.time() + 1) def test_sched_timeout(self): """ Conan config install must be executed when the scheduled time reaches """ self.client.run('config install "%s"' % self.folder) self.client.run('config set general.config_install_interval=1m') self.assertNotIn("Processing conan.conf", self.client.out) past_time = int(time.time() - 120) # 120 seconds in the past os.utime(self.client.cache.config_install_file, (past_time, past_time)) self.client.run('search') # any command will fire it self.assertIn("Processing conan.conf", self.client.out) self.client.run('search') # not again, it was fired already self.assertNotIn("Processing conan.conf", self.client.out) self.client.run('config get general.config_install_interval') self.assertNotIn("Processing conan.conf", self.client.out) self.assertIn( "5m", self.client.out) # The previous 5 mins has been restored! def test_invalid_scheduler(self): """ An exception must be raised when conan_config.json is not listed """ self.client.run('config install "%s"' % self.folder) os.remove(self.client.cache.config_install_file) self.client.run('config get general.config_install_interval', assert_error=True) self.assertIn( "config_install_interval defined, but no config_install file", self.client.out) def test_invalid_time_interval(self): """ config_install_interval only accepts minutes, hours or days """ self.client.run('config set general.config_install_interval=1s') # Any conan invocation will fire the configuration error self.client.run('install .', assert_error=True) self.assertIn( "ERROR: Incorrect definition of general.config_install_interval: 1s", self.client.out) def test_config_install_remove_git_repo(self): """ config_install_interval must break when remote git has been removed """ with self.client.chdir(self.folder): self.client.run_command('git init .') self.client.run_command('git add .') self.client.run_command('git config user.name myname') self.client.run_command( 'git config user.email [email protected]') self.client.run_command('git commit -m "mymsg"') self.client.run('config install "%s/.git" --type git' % self.folder) self.assertIn("Processing conan.conf", self.client.out) self.assertIn("Repo cloned!", self.client.out) # git clone executed by scheduled task folder_name = self.folder new_name = self.folder + "_test" os.rename(self.folder, new_name) with patch("conans.client.command.is_config_install_scheduled", return_value=True): self.client.run("config --help", assert_error=True) # scheduled task has been executed. Without a remote, the user should fix the config self.assertIn( "ERROR: Failed conan config install: Can't clone repo", self.client.out) # restore the remote os.rename(new_name, folder_name) self.client.run("config --help") self.assertIn("Repo cloned!", self.client.out) def test_config_install_remove_config_repo(self): """ config_install_interval should not run when config list is empty """ with self.client.chdir(self.folder): self.client.run_command('git init .') self.client.run_command('git add .') self.client.run_command('git config user.name myname') self.client.run_command( 'git config user.email [email protected]') self.client.run_command('git commit -m "mymsg"') self.client.run('config install "%s/.git" --type git' % self.folder) self.assertIn("Processing conan.conf", self.client.out) self.assertIn("Repo cloned!", self.client.out) # force scheduled time for all commands with patch( "conans.client.conf.config_installer._is_scheduled_intervals", return_value=True): self.client.run("config --help") self.assertIn( "Repo cloned!", self.client.out) # git clone executed by scheduled task # config install must not run scheduled config self.client.run("config install --remove 0") self.assertEqual("", self.client.out) self.client.run("config install --list") self.assertEqual("", self.client.out) last_change = os.path.getmtime( self.client.cache.config_install_file) # without a config in configs file, scheduler only emits a warning self.client.run("help") self.assertIn( "WARN: Skipping scheduled config install, " "no config listed in config_install file", self.client.out) self.assertNotIn("Repo cloned!", self.client.out) # ... and updates the next schedule self.assertGreater( os.path.getmtime(self.client.cache.config_install_file), last_change)
class ManifestValidationTest(unittest.TestCase): def setUp(self): test_server = TestServer() self.servers = {"default": test_server} self.client = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}) conanfile = """from conans import ConanFile class ConanFileTest(ConanFile): name = "Hello" version = "0.1" exports = "*" """ self.files = {CONANFILE: conanfile, "data.txt": "MyData"} # Export and upload the conanfile self.reference = ConanFileReference.loads("Hello/0.1@lasote/stable") self.client.save(self.files) self.client.run("export lasote/stable") @parameterized.expand([(True, ), (False, )]) def test_package_test(self, use_abs_folder): self.client.run("install Hello/0.1@lasote/stable --build missing") conanfile = """from conans import ConanFile class ConsumerFileTest(ConanFile): name = "Chat" version = "0.1" requires = "Hello/0.1@lasote/stable" """ test_conanfile = """from conans import ConanFile class ConsumerFileTest(ConanFile): requires = "Chat/0.1@lasote/stable" def test(self): self.output.info("TEST OK") """ if use_abs_folder: output_folder = temp_folder() dest = '="%s"' % output_folder else: dest = "" output_folder = os.path.join(self.client.current_folder, ".conan_manifests") self.client.save({"conanfile.py": conanfile, "test_package/conanfile.py": test_conanfile}, clean_first=True) self.client.run("test_package --manifests%s" % dest) self.assertIn("Chat/0.1@lasote/stable test package: TEST OK", self.client.user_io.out) self.assertIn("Installed manifest for 'Chat/0.1@lasote/stable' from local cache", self.client.user_io.out) self.assertIn("Installed manifest for 'Hello/0.1@lasote/stable' from local cache", self.client.user_io.out) paths = SimplePaths(output_folder) self.assertTrue(os.path.exists(paths.digestfile_conanfile(self.reference))) package_reference = PackageReference.loads("Hello/0.1@lasote/stable:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9") self.assertTrue(os.path.exists(paths.digestfile_package(package_reference))) # now verify self.client.run("test_package --verify%s" % dest) self.assertIn("Manifest for 'Hello/0.1@lasote/stable': OK", self.client.user_io.out) self.assertIn("Manifest for '%s': OK" % str(package_reference), self.client.user_io.out) def _capture_verify_manifest(self, reference, remote="local cache", folder=""): self.client.run("install %s --build missing --manifests %s" % (str(reference), folder)) self.assertIn("Installed manifest for 'Hello/0.1@lasote/stable' from %s" % remote, self.client.user_io.out) self.assertIn("Installed manifest for 'Hello/0.1@lasote/stable:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9' from %s" % remote, self.client.user_io.out) real_folder = folder or ".conan_manifests" output_folder = os.path.join(self.client.current_folder, real_folder) paths = SimplePaths(output_folder) self.assertTrue(os.path.exists(paths.digestfile_conanfile(self.reference))) package_reference = PackageReference.loads("Hello/0.1@lasote/stable:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9") self.assertTrue(os.path.exists(paths.digestfile_package(package_reference))) # again should do nothing self.client.run("install %s --build missing --manifests %s" % (str(self.reference), folder)) self.assertNotIn("manifest", self.client.user_io.out) # now verify self.client.run("install %s --build missing --verify %s" % (str(self.reference), folder)) self.assertIn("Manifest for 'Hello/0.1@lasote/stable': OK", self.client.user_io.out) self.assertIn("Manifest for '%s': OK" % str(package_reference), self.client.user_io.out) def capture_verify_manifest_test(self): self._capture_verify_manifest("Hello/0.1@lasote/stable") def conanfile_capture_verify_manifest_test(self): files = {"conanfile.txt": "[requires]\nHello/0.1@lasote/stable"} self.client.save(files, clean_first=True) self._capture_verify_manifest(".") def capture_verify_manifest_folder_test(self): self._capture_verify_manifest("Hello/0.1@lasote/stable", folder="my_custom_folder") def conanfile_capture_verify_manifest_folder_test(self): files = {"conanfile.txt": "[requires]\nHello/0.1@lasote/stable"} self.client.save(files, clean_first=True) folder = "mymanifests" self._capture_verify_manifest(".", folder=folder) conanfile = """from conans import ConanFile class ConanFileTest(ConanFile): name = "Hello2" version = "0.1" """ client = TestClient(base_folder=self.client.base_folder) client.save({CONANFILE: conanfile}) client.run("export lasote/stable") files = {"conanfile.txt": "[requires]\nHello2/0.1@lasote/stable\nHello/0.1@lasote/stable"} self.client.save(files) self.client.run("install . --build missing --manifests %s" % folder) remote = "local cache" package_reference = PackageReference.loads("Hello/0.1@lasote/stable:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9") self.assertIn("Manifest for 'Hello/0.1@lasote/stable': OK", self.client.user_io.out) self.assertIn("Manifest for '%s': OK" % str(package_reference), self.client.user_io.out) self.assertIn("Installed manifest for 'Hello2/0.1@lasote/stable' from %s" % remote, self.client.user_io.out) self.assertIn("Installed manifest for 'Hello2/0.1@lasote/stable:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9' from %s" % remote, self.client.user_io.out) output_folder = os.path.join(self.client.current_folder, folder) paths = SimplePaths(output_folder) self.assertTrue(os.path.exists(paths.digestfile_conanfile(self.reference))) self.assertTrue(os.path.exists(paths.digestfile_package(package_reference))) package_reference = PackageReference.loads("Hello2/0.1@lasote/stable:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9") self.assertTrue(os.path.exists(paths.digestfile_package(package_reference))) def remote_capture_verify_manifest_test(self): self.client.run("upload %s --all" % str(self.reference)) self.client.run("remove Hello* -f") files = {"conanfile.txt": "[requires]\nHello/0.1@lasote/stable"} self.client.save(files, clean_first=True) self._capture_verify_manifest(".", remote="default:") def _failed_verify(self, reference, remote="local cache"): self.client.run("install %s --build missing --manifests" % str(reference)) self.assertIn("Installed manifest for 'Hello/0.1@lasote/stable' from %s" % remote, self.client.user_io.out) self.assertIn("Installed manifest for 'Hello/0.1@lasote/stable:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9' from %s" % remote, self.client.user_io.out) output_folder = os.path.join(self.client.current_folder, ".conan_manifests") paths = SimplePaths(output_folder) self.assertTrue(os.path.exists(paths.digestfile_conanfile(self.reference))) package_reference = PackageReference.loads("Hello/0.1@lasote/stable:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9") self.assertTrue(os.path.exists(paths.digestfile_package(package_reference))) client = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}) conanfile = """from conans import ConanFile class ConanFileTest(ConanFile): name = "Hello" version = "0.1" exports = "*" """ files = {CONANFILE: conanfile, "data.txt": "MyDataHacked"} # Export and upload the conanfile client.save(files) client.run("export lasote/stable") client.run("upload %s --all" % str(self.reference)) # now verify, with update self.client.run("remove Hello/0.1@lasote/stable -f") self.client.run("install %s --build missing --verify" % str(self.reference), ignore_error=True) self.assertNotIn("Manifest for 'Hello/0.1@lasote/stable': OK", self.client.user_io.out) self.assertNotIn("Manifest for '%s': OK" % str(package_reference), self.client.user_io.out) self.assertIn("Modified or new manifest 'Hello/0.1@lasote/stable' detected", self.client.user_io.out) def capture_verify_error_manifest_test(self): self._failed_verify("Hello/0.1@lasote/stable") def conanfile_capture_verify_error_manifest_test(self): files = {"conanfile.txt": "[requires]\nHello/0.1@lasote/stable"} self.client.save(files, clean_first=True) self._failed_verify(".") def _failed_package_verify(self, reference, remote="local cache"): self.client.run("install %s --build missing --manifests" % str(reference)) self.assertIn("Installed manifest for 'Hello/0.1@lasote/stable' from %s" % remote, self.client.user_io.out) self.assertIn("Installed manifest for 'Hello/0.1@lasote/stable:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9' from %s" % remote, self.client.user_io.out) output_folder = os.path.join(self.client.current_folder, ".conan_manifests") paths = SimplePaths(output_folder) self.assertTrue(os.path.exists(paths.digestfile_conanfile(self.reference))) package_reference = PackageReference.loads("Hello/0.1@lasote/stable:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9") self.assertTrue(os.path.exists(paths.digestfile_package(package_reference))) client = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}) client.save(self.files) client.run("export lasote/stable") client.run("install Hello/0.1@lasote/stable --build=missing") info = os.path.join(client.paths.package(package_reference), "conaninfo.txt") info_content = load(info) info_content += "# Dummy string" save(info, info_content) manifest = client.paths.load_package_manifest(package_reference) manifest.file_sums["conaninfo.txt"] = md5(info_content) save(client.paths.digestfile_package(package_reference), str(manifest)) manifest = client.paths.load_package_manifest(package_reference) client.run("upload %s --all" % str(self.reference)) # now verify, with update self.client.run("remove Hello/0.1@lasote/stable -f") self.client.run("install %s --build missing --verify" % str(self.reference), ignore_error=True) self.assertNotIn("Manifest for 'Hello/0.1@lasote/stable': OK", self.client.user_io.out) self.assertNotIn("Manifest for '%s': OK" % str(package_reference), self.client.user_io.out) self.assertIn("Modified or new manifest '%s' detected" % str(package_reference), self.client.user_io.out) def capture_verify_package_error_manifest_test(self): self._failed_package_verify("Hello/0.1@lasote/stable") def conanfile_capture_verify_package_error_manifest_test(self): files = {"conanfile.txt": "[requires]\nHello/0.1@lasote/stable"} self.client.save(files, clean_first=True) self._failed_package_verify(".") def manifest_wrong_folder_test(self): reference = "Hello/0.1@lasote/stable" self.client.run("install %s --build missing --verify whatever" % str(reference), ignore_error=True) self.assertIn("Manifest folder does not exist:", self.client.user_io.out) def manifest_wrong_args_test(self): reference = "Hello/0.1@lasote/stable" self.client.run("install %s --build missing --verify -m" % str(reference), ignore_error=True) self.assertIn("ERROR: Do not specify both", self.client.user_io.out) self.client.run("install %s --build missing -mi -m" % str(reference), ignore_error=True) self.assertIn("ERROR: Do not specify both", self.client.user_io.out) def test_corrupted_recipe(self): export_path = self.client.paths.export(self.reference) file_path = os.path.join(export_path, "data.txt") save(file_path, "BAD CONTENT") self.client.run("install %s --build missing --manifests" % str(self.reference), ignore_error=True) self.assertIn("Hello/0.1@lasote/stable local cache package is corrupted", self.client.user_io.out) def test_corrupted_package(self): self.client.run("install %s --build missing" % str(self.reference)) package_reference = PackageReference.loads("Hello/0.1@lasote/stable:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9") package_path = self.client.paths.package(package_reference) file_path = os.path.join(package_path, "conaninfo.txt") save(file_path, load(file_path) + "RANDOM STRING") self.client.run("install %s --build missing --manifests" % str(self.reference), ignore_error=True) self.assertIn("%s local cache package is corrupted" % str(package_reference), self.client.user_io.out)
def test_build_vs_project(self): conan_build_vs = """ from conans import ConanFile, MSBuild class HelloConan(ConanFile): name = "Hello" version = "1.2.1" exports = "*" settings = "os", "build_type", "arch", "compiler", "cppstd" def build(self): msbuild = MSBuild(self) msbuild.build("MyProject.sln", verbosity="normal") def package(self): self.copy(pattern="*.exe") """ client = TestClient() # Test cpp standard stuff files = get_vs_project_files(std="cpp17_2015") files[CONANFILE] = conan_build_vs client.save(files) with catch_deprecation_warning(self): client.run( 'create . Hello/1.2.1@lasote/stable -s cppstd=11 -s ' 'compiler="Visual Studio" -s compiler.version=14', assert_error=True) with catch_deprecation_warning(self, n=2): client.run('create . Hello/1.2.1@lasote/stable -s cppstd=17 ' '-s compiler="Visual Studio" -s compiler.version=14') self.assertIn("Packaged 1 '.exe' file: MyProject.exe", client.out) files = get_vs_project_files() files[CONANFILE] = conan_build_vs # Try to not update the project client.cache._config = None # Invalidate cached config replace_in_file(client.cache.conan_conf_path, "[general]", "[general]\nskip_vs_projects_upgrade = True", output=client.out) client.save(files, clean_first=True) client.run("create . Hello/1.2.1@lasote/stable --build") self.assertNotIn("devenv", client.out) self.assertIn("Skipped sln project upgrade", client.out) # Try with x86_64 client.save(files) client.run("export . lasote/stable") client.run("install Hello/1.2.1@lasote/stable --build -s arch=x86_64") self.assertIn("Release|x64", client.out) self.assertIn("Packaged 1 '.exe' file: MyProject.exe", client.out) # Try with x86 client.save(files, clean_first=True) client.run("export . lasote/stable") client.run("install Hello/1.2.1@lasote/stable --build -s arch=x86") self.assertIn("Release|x86", client.out) self.assertIn("Packaged 1 '.exe' file: MyProject.exe", client.out) # Try with x86 debug client.save(files, clean_first=True) client.run("export . lasote/stable") client.run( "install Hello/1.2.1@lasote/stable --build -s arch=x86 -s build_type=Debug" ) self.assertIn("Debug|x86", client.out) self.assertIn("Packaged 1 '.exe' file: MyProject.exe", client.out) # Try with a custom property file name files[CONANFILE] = conan_build_vs.replace( 'msbuild.build("MyProject.sln", verbosity="normal")', 'msbuild.build("MyProject.sln", verbosity="normal", property_file_name="mp.props")' ) client.save(files, clean_first=True) client.run( "create . Hello/1.2.1@lasote/stable --build -s arch=x86 -s build_type=Debug" ) self.assertIn("Debug|x86", client.out) self.assertIn("Packaged 1 '.exe' file: MyProject.exe", client.out) full_ref = "Hello/1.2.1@lasote/stable:b786e9ece960c3a76378ca4d5b0d0e922f4cedc1" pref = PackageReference.loads(full_ref) build_folder = client.cache.package_layout(pref.ref).build(pref) self.assertTrue(os.path.exists(os.path.join(build_folder, "mp.props")))
def test_force_git_type(self): client = TestClient() client.run('config install httpnonexisting --type=git', assert_error=True) self.assertIn("Can't clone repo", client.out)
def upload_test(self): test_server = TestServer([], # write permissions users={"lasote": "mypass"}) # exported users and passwords servers = {"default": test_server} client = TestClient(servers=servers, users={"default": [("lasote", "mypass")]}) files = {"conanfile.py": base} client.save(files) client.run("export lasote/channel") client.run("install lib/0.1@lasote/channel --build") client.run("upload lib/0.1@lasote/channel --all") client.run("remove lib/0.1@lasote/channel -f") client.run("search") self.assertIn("There are no packages", client.user_io.out) for download in ("", "--all"): client2 = TestClient(servers=servers, users={"default": [("lasote", "mypass")]}) client2.run("install lib/0.1@lasote/channel %s" % download) reference = ConanFileReference.loads("lib/0.1@lasote/channel") export_folder = client2.client_cache.export(reference) export_files = os.listdir(export_folder) self.assertNotIn('conan_export.tgz', export_files) package_ref = PackageReference.loads("lib/0.1@lasote/channel:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9") package_folder = client2.client_cache.package(package_ref, short_paths=None) if platform.system() == "Windows": original_folder = client2.client_cache.package(package_ref) link = load(os.path.join(original_folder, ".conan_link")) self.assertEqual(link, package_folder) files = os.listdir(package_folder) self.assertIn("myfile.txt", files) self.assertIn("myfile2.txt", files) self.assertNotIn("conan_package.tgz", files)
def per_package_test(self): client = TestClient() files = {'conanfile.py': base_conanfile.replace("%GLOBAL%", "")} client.save(files) client.run("export . user/testing") client.run("install Test/0.1@user/testing --build missing") self.assertIn("*+Running system requirements+*", client.user_io.out) ref = ConanFileReference.loads("Test/0.1@user/testing") self.assertFalse(os.path.exists(client.cache.system_reqs(ref))) pref = PackageReference(ref, "f0ba3ca2c218df4a877080ba99b65834b9413798") load_file = load(client.cache.system_reqs_package(pref)) self.assertIn("Installed my stuff", load_file) # Run again client.run("install Test/0.1@user/testing --build missing") self.assertNotIn("*+Running system requirements+*", client.user_io.out) self.assertFalse(os.path.exists(client.cache.system_reqs(ref))) load_file = load(client.cache.system_reqs_package(pref)) self.assertIn("Installed my stuff", load_file) # Run with different option client.run( "install Test/0.1@user/testing -o myopt=False --build missing") self.assertIn("*+Running system requirements+*", client.user_io.out) self.assertFalse(os.path.exists(client.cache.system_reqs(ref))) pref2 = PackageReference(ref, NO_SETTINGS_PACKAGE_ID) load_file = load(client.cache.system_reqs_package(pref2)) self.assertIn("Installed my stuff", load_file) # remove packages client.run("remove Test* -f -p 544") self.assertTrue(os.path.exists(client.cache.system_reqs_package(pref))) client.run( "remove Test* -f -p f0ba3ca2c218df4a877080ba99b65834b9413798") self.assertFalse(os.path.exists( client.cache.system_reqs_package(pref))) self.assertTrue(os.path.exists( client.cache.system_reqs_package(pref2))) client.run("remove Test* -f -p %s" % NO_SETTINGS_PACKAGE_ID) self.assertFalse(os.path.exists( client.cache.system_reqs_package(pref))) self.assertFalse( os.path.exists(client.cache.system_reqs_package(pref2)))
def package_copier_test(self): client = TestClient() files = {"conanfile.py": base} client.save(files) client.run("export lasote/channel") client.run("install lib/0.1@lasote/channel --build") client.run("copy lib/0.1@lasote/channel memsharded/stable") client.run("search") self.assertIn("lib/0.1@lasote/channel", client.user_io.out) self.assertIn("lib/0.1@memsharded/stable", client.user_io.out) client.run("search lib/0.1@lasote/channel") self.assertIn("Package_ID: 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", client.user_io.out) client.run("search lib/0.1@memsharded/stable") self.assertIn("Package_ID: 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", client.user_io.out) if platform.system() == "Windows": conan_ref = ConanFileReference.loads("lib/0.1@lasote/channel") package_ref = PackageReference(conan_ref, "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9") package_folder = client.client_cache.package(package_ref) link_package = load(os.path.join(package_folder, ".conan_link")) self.assertTrue(os.path.exists(link_package))
def test_user_properties_multifile(self): conan_build_vs = textwrap.dedent(""" from conans import ConanFile, MSBuild class HelloConan(ConanFile): exports = "*" settings = "os", "build_type", "arch", "compiler" def build(self): msbuild = MSBuild(self) msbuild.build("MyProject.sln", verbosity="normal", definitions={"MyCustomDef": "MyCustomValue"}, user_property_file_name=["myuser.props", "myuser2.props"]) def package(self): self.copy(pattern="*.exe") """) client = TestClient() files = get_vs_project_files() files[CONANFILE] = conan_build_vs props = textwrap.dedent("""<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ImportGroup Label="PropertySheets" /> <PropertyGroup Label="UserMacros" /> <ItemDefinitionGroup> <ClCompile> <PreprocessorDefinitions>MyCustomDef2=MyValue2;%(PreprocessorDefinitions) </PreprocessorDefinitions> </ClCompile> </ItemDefinitionGroup> <ItemGroup /> </Project> """) props2 = textwrap.dedent("""<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ImportGroup Label="PropertySheets" /> <PropertyGroup Label="UserMacros" /> <ItemDefinitionGroup> <ClCompile> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> </ClCompile> </ItemDefinitionGroup> <ItemGroup /> </Project> """) files["myuser.props"] = props files["myuser2.props"] = props2 client.save(files) client.run('create . Hello/1.2.1@lasote/stable') self.assertNotIn("/EHsc /MD", client.out) self.assertIn("/EHsc /MT", client.out) self.assertIn("/D MyCustomDef=MyCustomValue", client.out) self.assertIn("/D MyCustomDef2=MyValue2", client.out) self.assertIn("Packaged 1 '.exe' file: MyProject.exe", client.out) full_ref = "Hello/1.2.1@lasote/stable:6cc50b139b9c3d27b3e9042d5f5372d327b3a9f7" pref = PackageReference.loads(full_ref) build_folder = client.cache.package_layout(pref.ref).build(pref) self.assertTrue( os.path.exists(os.path.join(build_folder, "myuser.props"))) conan_props = os.path.join(build_folder, "conan_build.props") content = load(conan_props) self.assertIn("<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>", content)
def test_file_api(): """ simple library providing 3 targets: - decoder - encoder - transcoder (requires decoder and encoder) generates the following targets: - triunfo::decoder - triunfo::encoder - triunfo::transcoder (depends on triunfo::decoder and triunfo::encoder) consumer uses find_package(triunfo COMPONENTS <component>) """ client = TestClient() conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMake, CMakeFileAPI from conan.tools.files import CppPackage class Triunfo(ConanFile): name = "triunfo" version = "1.0" settings = "os", "compiler", "arch", "build_type" exports_sources = "*CMakeLists.txt", "*.cpp", "*.h" generators = "CMakeToolchain" def build(self): file_api = CMakeFileAPI(self) file_api.query(CMakeFileAPI.CODEMODELV2) cmake = CMake(self) cmake.configure() reply = file_api.reply(CMakeFileAPI.CODEMODELV2) package = reply.to_conan_package() package.save() cmake.build() def package(self): cmake = CMake(self) cmake.install() self.copy(CppPackage.DEFAULT_FILENAME) def package_info(self): cpp_package = CppPackage.load(CppPackage.DEFAULT_FILENAME) cpp_package.package_info(self) """) decoder_cpp = gen_function_cpp(name="decoder", includes=["decoder"]) encoder_cpp = gen_function_cpp(name="encoder", includes=["encoder"]) transcoder_cpp = gen_function_cpp( name="transcoder", calls=["decoder", "encoder"], includes=["transcoder", "../decoder/decoder", "../encoder/encoder"]) decoder_h = gen_function_h(name="decoder") encoder_h = gen_function_h(name="encoder") transcoder_h = gen_function_h(name="transcoder") decoder_cmake = gen_cmakelists(libname="decoder", libsources=["decoder.cpp"], install=True, public_header="decoder.h") encoder_cmake = gen_cmakelists(libname="encoder", libsources=["encoder.cpp"], install=True, public_header="encoder.h") transcoder_cmake = gen_cmakelists(libname="transcoder", libsources=["transcoder.cpp"], install=True, public_header="transcoder.h", deps=["decoder", "encoder"]) common_cmake = textwrap.dedent(""" cmake_minimum_required(VERSION 2.8) project(triunfo) add_subdirectory(decoder) add_subdirectory(encoder) add_subdirectory(transcoder) """) client.save({ "conanfile.py": conanfile, os.path.join("decoder", "decoder.cpp"): decoder_cpp, os.path.join("encoder", "encoder.cpp"): encoder_cpp, os.path.join("transcoder", "transcoder.cpp"): transcoder_cpp, os.path.join("decoder", "decoder.h"): decoder_h, os.path.join("encoder", "encoder.h"): encoder_h, os.path.join("transcoder", "transcoder.h"): transcoder_h, os.path.join("decoder", "CMakeLists.txt"): decoder_cmake, os.path.join("encoder", "CMakeLists.txt"): encoder_cmake, os.path.join("transcoder", "CMakeLists.txt"): transcoder_cmake, "CMakeLists.txt": common_cmake, }) client.run("create .") conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMake, CMakeFileAPI from conan.tools.files import CppPackage class Elogio(ConanFile): name = "elogio" version = "1.0" requires = "triunfo/1.0" settings = "os", "compiler", "arch", "build_type" exports_sources = "*CMakeLists.txt", "*.cpp", "*.h" generators = "CMakeDeps", "CMakeToolchain" def build(self): file_api = CMakeFileAPI(self) file_api.query(CMakeFileAPI.CODEMODELV2) cmake = CMake(self) cmake.configure() reply = file_api.reply(CMakeFileAPI.CODEMODELV2) package = reply.to_conan_package() package.save() cmake.build() """) use_decoder_cpp = gen_function_cpp(name="main", includes=["decoder"], calls=["decoder"]) use_encoder_cpp = gen_function_cpp(name="main", includes=["encoder"], calls=["encoder"]) use_transcoder_cpp = gen_function_cpp(name="main", includes=["transcoder"], calls=["transcoder"]) use_decoder_cmake = gen_cmakelists(appname="use_decoder", appsources=["use_decoder.cpp"], find_package={"triunfo": "decoder"}) use_encoder_cmake = gen_cmakelists(appname="use_encoder", appsources=["use_encoder.cpp"], find_package={"triunfo": "encoder"}) use_transcoder_cmake = gen_cmakelists( appname="use_transcoder", appsources=["use_transcoder.cpp"], find_package={"triunfo": "transcoder"}) common_cmake = textwrap.dedent(""" cmake_minimum_required(VERSION 2.8) project(elogio) add_subdirectory(use_decoder) add_subdirectory(use_encoder) add_subdirectory(use_transcoder) """) client.save( { "conanfile.py": conanfile, os.path.join("use_decoder", "use_decoder.cpp"): use_decoder_cpp, os.path.join("use_encoder", "use_encoder.cpp"): use_encoder_cpp, os.path.join("use_transcoder", "use_transcoder.cpp"): use_transcoder_cpp, os.path.join("use_decoder", "CMakeLists.txt"): use_decoder_cmake, os.path.join("use_encoder", "CMakeLists.txt"): use_encoder_cmake, os.path.join("use_transcoder", "CMakeLists.txt"): use_transcoder_cmake, "CMakeLists.txt": common_cmake, }, clean_first=True) client.run("install .") client.run("build .")
def remove_test(self): short_home = tempfile.mkdtemp(dir=CONAN_TEST_FOLDER) client = TestClient() files = {"conanfile.py": base.replace("108", "90"), "path/"*20 + "file0.txt": "file0 content"} # shorten to pass appveyor client.save(files) with environment_append({"CONAN_USER_HOME_SHORT": short_home}): client.run("export lasote/channel") client.run("install lib/0.1@lasote/channel --build") client.run('remove "lib*" -b -p -f') client.run("install lib/0.1@lasote/channel --build") client.run('remove "lib*" -s -f') client.run("install lib/0.1@lasote/channel --build") client.run('remove "*" -f') self.assertEqual(len(os.listdir(short_home)), 0)
def cmake_multi_test(self): if platform.system() not in ["Windows", "Darwin"]: return client = TestClient() client.save(multi_config_files("Hello0", test=False), clean_first=True) client.run("export lasote/testing") client.run("install Hello0/0.1@lasote/testing --build=missing") client.save(package_files("Hello1", ["Hello0"]), clean_first=True) client.run("export lasote/testing") if platform.system() == "Windows": generator = "Visual Studio 14 Win64" debug_install = '-s compiler="Visual Studio" -s compiler.version=14 -s compiler.runtime=MDd' release_install = '-s compiler="Visual Studio" -s compiler.version=14 -s compiler.runtime=MD' elif platform.system() == "Darwin": generator = "Xcode" debug_install = '' release_install = '' # better in one test instead of two, because install time is amortized for cmake_file in ( cmake, cmake_targets, ): client.save( { "conanfile.txt": conanfile, "CMakeLists.txt": cmake_file, "main.cpp": main }, clean_first=True) client.run('install -s build_type=Debug %s --build=missing' % debug_install) client.run('install -s build_type=Release %s --build=missing' % release_install) client.runner('cmake . -G "%s"' % generator, cwd=client.current_folder) self.assertNotIn("WARN: Unknown compiler '", client.user_io.out) self.assertNotIn("', skipping the version check...", client.user_io.out) client.runner('cmake --build . --config Debug', cwd=client.current_folder) hello_comand = os.sep.join([".", "Debug", "say_hello"]) client.runner(hello_comand, cwd=client.current_folder) self.assertIn("Hello0:Debug Hello1:Debug", client.user_io.out) self.assertIn("Hello0Def:Debug Hello1Def:Debug", client.user_io.out) self.assertIn("Hello Debug Hello1", client.user_io.out) self.assertIn("Hello Debug Hello0", client.user_io.out) client.runner('cmake --build . --config Release', cwd=client.current_folder) hello_comand = os.sep.join([".", "Release", "say_hello"]) client.runner(hello_comand, cwd=client.current_folder) self.assertIn("Hello0:Release Hello1:Release", client.user_io.out) self.assertIn("Hello0Def:Release Hello1Def:Release", client.user_io.out) self.assertIn("Hello Release Hello1", client.user_io.out) self.assertIn("Hello Release Hello0", client.user_io.out) if cmake_file == cmake_targets: self.assertIn("Conan: Using cmake targets configuration", client.user_io.out) else: self.assertIn("Conan: Using cmake global configuration", client.user_io.out)
def source_test(self): client = TestClient() files = {"conanfile.py": base} client.save(files) client.run("export user/channel") conan_ref = ConanFileReference.loads("lib/0.1@user/channel") client.run("source lib/0.1@user/channel") self.assertIn("Configuring sources", client.user_io.out) if platform.system() == "Windows": source_folder = client.client_cache.source(conan_ref) link_source = load(os.path.join(source_folder, ".conan_link")) self.assertTrue(os.path.exists(link_source)) # Nothing changes, so source is still there client.run("export user/channel") client.run("source lib/0.1@user/channel") self.assertNotIn("Configuring sources", client.user_io.out) # But if we remove the source, it will retrieve sources again client.run("remove lib/0.1@user/channel -s -f") client.run("source lib/0.1@user/channel") self.assertIn("Configuring sources", client.user_io.out)
def test_gcc_and_environment(self): if platform.system() == "SunOS": return # If is using sun-cc the gcc generator doesn't work # CREATE A DUMMY LIBRARY WITH GCC (could be generated with other build system) client = TestClient() client.save({CONANFILE: conanfile, "mean.cpp": mylib, "mean.h": mylibh}) client.run("export lasote/stable") client.run("install Mean/0.1@lasote/stable --build") # Reuse the mean library using only the generator reuse_gcc_conanfile = ''' import platform from conans import ConanFile from conans.tools import environment_append class ConanReuseLib(ConanFile): requires = "Mean/0.1@lasote/stable" generators = "gcc" settings = "os", "compiler", "build_type", "arch" def build(self): self.run("c++ example.cpp @conanbuildinfo.gcc -o mean_exe ") self.run("./mean_exe" if platform.system() != "Windows" else "mean_exe") ''' client.save({CONANFILE: reuse_gcc_conanfile, "example.cpp": example}) client.run("install . --build missing") client.run("build .") self.assertIn("15", client.user_io.out) self.assertIn("Active var!!!", client.user_io.out) client.run("install . --build missing -o Mean:activate_define=False") client.run("build .") self.assertIn("15", client.user_io.out) self.assertNotIn("Active var!!!", client.user_io.out) if platform.system() != "Windows": # MinGW 32 bits apps not running correctly client.run("install . --build missing -o Mean:activate_define=False -s arch=x86") client.run("build .") md5_binary = md5sum(os.path.join(client.current_folder, "mean_exe")) # Pass the optimize option that will append a cflag to -O2, the binary will be different client.run("install . --build missing -o Mean:activate_define=False -o Mean:optimize=True -s arch=x86") client.run("build .") md5_binary2 = md5sum(os.path.join(client.current_folder, "mean_exe")) self.assertNotEquals(md5_binary, md5_binary2) # Rebuid the same binary, same md5sum client.run("install . --build missing -o Mean:activate_define=False -o Mean:optimize=True -s arch=x86") client.run("build .") md5_binary = md5sum(os.path.join(client.current_folder, "mean_exe")) self.assertEquals(md5_binary, md5_binary2)
def build_windows_subsystem(profile, make_program): """ The AutotoolsDeps can be used also in pure Makefiles, if the makefiles follow the Autotools conventions """ # FIXME: cygwin in CI (my local machine works) seems broken for path with spaces client = TestClient(path_with_spaces=False) client.run("new hello/0.1 --template=cmake_lib") # TODO: Test Windows subsystems in CMake, at least msys is broken os.rename(os.path.join(client.current_folder, "test_package"), os.path.join(client.current_folder, "test_package2")) client.save({"profile": profile}) client.run("create . --profile=profile") main = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) makefile = gen_makefile(apps=["app"]) conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.gnu import AutotoolsToolchain, Autotools, AutotoolsDeps class TestConan(ConanFile): requires = "hello/0.1" settings = "os", "compiler", "arch", "build_type" exports_sources = "Makefile" generators = "AutotoolsDeps", "AutotoolsToolchain" def build(self): autotools = Autotools(self) autotools.make() """) client.save( { "app.cpp": main, "Makefile": makefile, "conanfile.py": conanfile, "profile": profile }, clean_first=True) client.run("install . --profile=profile") cmd = environment_wrap_command( ["conanbuildenv", "conanautotoolstoolchain", "conanautotoolsdeps"], make_program, cwd=client.current_folder) client.run_command(cmd) client.run_command("app") # TODO: fill compiler version when ready check_exe_run(client.out, "main", "gcc", None, "Release", "x86_64", None) assert "hello/0.1: Hello World Release!" in client.out client.save({ "app.cpp": gen_function_cpp(name="main", msg="main2", includes=["hello"], calls=["hello"]) }) # Make sure it is newer t = time.time() + 1 touch(os.path.join(client.current_folder, "app.cpp"), (t, t)) client.run("build .") client.run_command("app") # TODO: fill compiler version when ready check_exe_run(client.out, "main2", "gcc", None, "Release", "x86_64", None, cxx11_abi=0) assert "hello/0.1: Hello World Release!" in client.out return client.out
def test_validate_compatible_also_invalid_fail(self): client = TestClient() conanfile = textwrap.dedent(""" from conans import ConanFile from conans.errors import ConanInvalidConfiguration class Pkg(ConanFile): settings = "os", "build_type" def validate(self): if self.settings.os == "Windows": raise ConanInvalidConfiguration("Windows not supported") def package_id(self): if self.settings.build_type == "Debug": compatible_pkg = self.info.clone() compatible_pkg.settings.build_type = "Release" self.compatible_packages.append(compatible_pkg) """) client.save({"conanfile.py": conanfile}) client.run("create . pkg/0.1@ -s os=Linux -s build_type=Release") self.assertIn( "pkg/0.1: Package '24c3aa2d6c5929d53bd86b31e020c55d96b265c7' created", client.out) # compatible_packges fallback works client.run("install pkg/0.1@ -s os=Linux -s build_type=Debug") self.assertIn( "pkg/0.1:24c3aa2d6c5929d53bd86b31e020c55d96b265c7 - Cache", client.out) # Windows invalid configuration error = client.run( "create . pkg/0.1@ -s os=Windows -s build_type=Release", assert_error=True) self.assertEqual(error, ERROR_INVALID_CONFIGURATION) self.assertIn("pkg/0.1: Invalid ID: Windows not supported", client.out) error = client.run( "install pkg/0.1@ -s os=Windows -s build_type=Release", assert_error=True) self.assertEqual(error, ERROR_INVALID_CONFIGURATION) self.assertIn("pkg/0.1: Invalid ID: Windows not supported", client.out) # Windows missing binary: INVALID error = client.run( "install pkg/0.1@ -s os=Windows -s build_type=Debug", assert_error=True) self.assertEqual(error, ERROR_INVALID_CONFIGURATION) self.assertIn("pkg/0.1: Invalid ID: Windows not supported", client.out) error = client.run( "create . pkg/0.1@ -s os=Windows -s build_type=Debug", assert_error=True) self.assertEqual(error, ERROR_INVALID_CONFIGURATION) self.assertIn("pkg/0.1: Invalid ID: Windows not supported", client.out) # info client.run("info pkg/0.1@ -s os=Windows") self.assertIn("ID: INVALID", client.out) client.run("info pkg/0.1@ -s os=Windows -s build_type=Debug") self.assertIn("ID: INVALID", client.out)
def test_toolchain_win_multi(self): client = TestClient(path_with_spaces=False) settings = { "compiler": "Visual Studio", "compiler.version": "15", "compiler.cppstd": "17" } settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) client.run("new hello/0.1 -s") configs = [("Release", "x86", True), ("Release", "x86_64", True), ("Debug", "x86", False), ("Debug", "x86_64", False)] for build_type, arch, shared in configs: # Build the profile according to the settings provided runtime = "MT" if build_type == "Release" else "MTd" client.run( "create . hello/0.1@ %s -s build_type=%s -s arch=%s -s compiler.runtime=%s " " -o hello:shared=%s" % (settings, build_type, arch, runtime, shared)) # Prepare the actual consumer package client.save( { "conanfile.py": self.conanfile, "MyProject.sln": sln_file, "MyApp/MyApp.vcxproj": myapp_vcxproj, "MyApp/MyApp.cpp": self.app }, clean_first=True) # Run the configure corresponding to this test case for build_type, arch, shared in configs: runtime = "MT" if build_type == "Release" else "MTd" client.run( "install . %s -s build_type=%s -s arch=%s -s compiler.runtime=%s -if=conan" " -o hello:shared=%s" % (settings, build_type, arch, runtime, shared)) vs_path = vs_installation_path("15") vcvars_path = os.path.join(vs_path, "VC/Auxiliary/Build/vcvarsall.bat") for build_type, arch, shared in configs: platform_arch = "x86" if arch == "x86" else "x64" if build_type == "Release" and shared: configuration = "ReleaseShared" else: configuration = build_type # The "conan build" command is not good enough, cannot do the switch between configs cmd = ('set "VSCMD_START_DIR=%%CD%%" && ' '"%s" x64 && msbuild "MyProject.sln" /p:Configuration=%s ' '/p:Platform=%s ' % (vcvars_path, configuration, platform_arch)) client.run_command(cmd) self.assertIn("Visual Studio 2017", client.out) self.assertIn("[vcvarsall.bat] Environment initialized for: 'x64'", client.out) self._run_app(client, arch, build_type, shared) check_exe_run(client.out, "main", "msvc", "19.1", build_type, arch, "17", { "DEFINITIONS_BOTH": "True", "DEFINITIONS_CONFIG": build_type }) new_cmd = "conan\\%s\\%s\\MyApp.exe" % (arch, configuration) vcvars = vcvars_command(version="15", architecture="amd64") cmd = ('%s && dumpbin /dependents "%s"' % (vcvars, new_cmd)) client.run_command(cmd) if shared: self.assertIn("hello.dll", client.out) else: self.assertNotIn("hello.dll", client.out) self.assertIn("KERNEL32.dll", client.out)
class VersionCheckTest(unittest.TestCase): def check_versions_test(self): # Client deprecated self.servers = {"default": self._get_server(10, 5)} self.client = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}, client_version=4) errors = self.client.run("search something -r default", ignore_error=True) self.assertIn( "Your conan's client version is deprecated for the current remote (v10). " "Upgrade conan client.", self.client.user_io.out) self.assertTrue(errors) # Not Errors # Client outdated self.servers = {"default": self._get_server(10, 4)} self.client = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}, client_version=4) errors = self.client.run("search something -r default", ignore_error=False) self.assertIn( " A new conan version (v10) is available in current remote. Please, " "upgrade conan client to avoid deprecation.", self.client.user_io.out) self.assertFalse(errors) # Not Errors # Client ok self.servers = {"default": self._get_server(10, 4)} self.client = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}, client_version=10) errors = self.client.run("search something -r default", ignore_error=False) self.assertNotIn("conan client", self.client.user_io.out) self.assertFalse(errors) # Not Errors # Server outdated self.servers = {"default": self._get_server(1, 1)} self.client = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}, client_version=10, min_server_compatible_version=1) errors = self.client.run("search something -r default", ignore_error=True) self.assertNotIn( "The conan remote version is outdated (v1). Please, contact" " with your system administrator and upgrade the remote to" " avoid deprecation", self.client.user_io.out) self.assertFalse(errors) # No Errors # Server deprecated self.servers = {"default": self._get_server(1, 1)} self.client = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}, client_version=10, min_server_compatible_version=2) errors = self.client.run("search something -r default", ignore_error=True) self.assertIn( "Your conan's client is incompatible with this remote." " The server is deprecated. " "(v1). Please, contact with your system administrator and" " upgrade the server.", self.client.user_io.out) self.assertTrue(errors) # Errors def check_multi_server_test(self): # Check what happen if we have 2 servers and one is outdated # The expected behavior: If we specify the remote with (-r), the commmand will fail # if the client fot that remote is outdated. If we are looking for a package (not with -r) # the client will look for the package on each remote. # Client deprecated for "the_last_server" but OK for "normal_server" self.servers = OrderedDict([("the_last_server", self._get_server(10, 4)), ("normal_server", self._get_server(4, 2))]) # First upload a package ok with an ok client tmp_client = TestClient(servers=self.servers, users={ "normal_server": [("lasote", "mypass")], "the_last_server": [("lasote", "mypass")] }, client_version=4) files = cpp_hello_conan_files("Hello0", "0.1", build=False) tmp_client.save(files) tmp_client.run("export . lasote/stable") errors = tmp_client.run( "upload Hello0/0.1@lasote/stable -r normal_server --all") errors |= tmp_client.run( "upload Hello0/0.1@lasote/stable -r the_last_server --all") self.assertFalse(errors) tmp_client.run("remote remove_ref Hello0/0.1@lasote/stable") # Now with a conflictive client...try to look in servers self.client = TestClient(servers=self.servers, users={ "normal_server": [("lasote", "mypass")], "the_last_server": [("lasote", "mypass")] }, client_version=2) errors = self.client.run("search something -r the_last_server", ignore_error=True) self.assertIn( "Your conan's client version is deprecated for the current remote (v10). " "Upgrade conan client.", self.client.user_io.out) self.assertTrue(errors) # Errors errors = self.client.run( "install Hello0/0.1@lasote/stable --build missing", ignore_error=True) self.assertIn( "Your conan's client version is deprecated for the current remote (v10). " "Upgrade conan client.", self.client.user_io.out) self.assertTrue(errors) # Errors! because it fails in the first remote def _get_server(self, server_version, min_client_compatible_version): server_version = str(server_version) min_client_compatible_version = str(min_client_compatible_version) return TestServer( [], # write permissions users={"lasote": "mypass"}, server_version=Version(server_version), min_client_compatible_version=Version( min_client_compatible_version))
class SettingsTest(unittest.TestCase): def setUp(self): self.client = TestClient() def settings_as_a_str_test(self): content = """ from conans import ConanFile class SayConan(ConanFile): name = "Say" version = "0.1" settings = "os" """ self.client.save({CONANFILE: content}) self.client.run("install -s os=Windows --build missing") # Now read the conaninfo and verify that settings applied is only os and value is windows conan_info = ConanInfo.loads( load(os.path.join(self.client.current_folder, CONANINFO))) self.assertEquals(conan_info.settings.os, "Windows") self.client.run("install -s os=Linux --build missing") # Now read the conaninfo and verify that settings applied is only os and value is windows conan_info = ConanInfo.loads( load(os.path.join(self.client.current_folder, CONANINFO))) self.assertEquals(conan_info.settings.os, "Linux") def settings_as_a_list_conanfile_test(self): """Declare settings as a list""" # Now with conanfile as a list content = """ from conans import ConanFile class SayConan(ConanFile): name = "Say" version = "0.1" settings = "os", "arch" """ self.client.save({CONANFILE: content}) self.client.run("install -s os=Windows --build missing") conan_info = ConanInfo.loads( load(os.path.join(self.client.current_folder, CONANINFO))) self.assertEquals(conan_info.settings.os, "Windows") self.assertEquals(conan_info.settings.fields, ["arch", "os"]) def settings_as_a_dict_conanfile_test(self): """Declare settings as a dict""" # Now with conanfile as a dict # XXX: this test only works on machines that default arch to "x86" or "x86_64" or "sparc" or "sparcv9" content = """ from conans import ConanFile class SayConan(ConanFile): name = "Say" version = "0.1" settings = {"os": ["Windows"], "arch": ["x86", "x86_64", "sparc", "sparcv9"]} """ self.client.save({CONANFILE: content}) self.client.run("install -s os=Windows --build missing") conan_info = ConanInfo.loads( load(os.path.join(self.client.current_folder, CONANINFO))) self.assertEquals(conan_info.settings.os, "Windows") self.assertEquals(conan_info.settings.fields, ["arch", "os"]) def invalid_settings_test(self): '''Test wrong values and wrong constraints''' self.client.client_cache.default_profile default_conf = load(self.client.paths.default_profile_path) new_conf = default_conf.replace("os=", "# os=") save(self.client.paths.default_profile_path, new_conf) # MISSING VALUE FOR A SETTING content = """ from conans import ConanFile class SayConan(ConanFile): name = "Say" version = "0.1" settings = "os", "build_type" """ self.client.save({CONANFILE: content}) self.client.run("install --build missing", ignore_error=True) self.assertIn(str(undefined_value("settings.os")), str(self.client.user_io.out)) def invalid_settings_test2(self): # MISSING A DEFAULT VALUE BECAUSE ITS RESTRICTED TO OTHER, SO ITS REQUIRED content = """ from conans import ConanFile class SayConan(ConanFile): name = "Say" version = "0.1" settings = {"os": ["Windows", "Linux", "Macos", "FreeBSD", "SunOS"], "compiler": ["Visual Studio"]} """ self.client.save({CONANFILE: content}) self.client.run( "install -s compiler=gcc -s compiler.version=4.8 --build missing", ignore_error=True) self.assertIn( bad_value_msg("settings.compiler", "gcc", ["Visual Studio"]), str(self.client.user_io.out)) def invalid_settings_test3(self): # dict without options content = """ from conans import ConanFile class SayConan(ConanFile): name = "Say" version = "0.1" settings = {"os": None, "compiler": ["Visual Studio"]} """ self.client.save({CONANFILE: content}) self.client.run( "install -s compiler=gcc -s compiler.version=4.8 --build missing", ignore_error=True) self.assertIn( bad_value_msg("settings.compiler", "gcc", ["Visual Studio"]), str(self.client.user_io.out)) # Test wrong settings in conanfile content = """ from conans import ConanFile class SayConan(ConanFile): name = "Say" version = "0.1" settings = invalid """ self.client.save({CONANFILE: content}) self.client.run("install --build missing", ignore_error=True) self.assertIn("invalid' is not defined", str(self.client.user_io.out)) # Test wrong values in conanfile def invalid_settings_test4(self): content = """ from conans import ConanFile class SayConan(ConanFile): name = "Say" version = "0.1" settings = "os" """ self.client.save({CONANFILE: content}) self.client.run("install -s os=ChromeOS --build missing", ignore_error=True) self.assertIn( bad_value_msg("settings.os", "ChromeOS", [ 'Android', 'Arduino', 'FreeBSD', 'Linux', 'Macos', 'SunOS', 'Windows', 'iOS' ]), str(self.client.user_io.out)) # Now add new settings to config and try again config = load(self.client.paths.settings_path) config = config.replace( "Windows:%s" % os.linesep, "Windows:%s ChromeOS:%s" % (os.linesep, os.linesep)) save(self.client.paths.settings_path, config) self.client.run("install -s os=ChromeOS --build missing") self.assertIn('Generated conaninfo.txt', str(self.client.user_io.out)) # Settings is None content = """ from conans import ConanFile class SayConan(ConanFile): name = "Say" version = "0.1" settings = None """ self.client.save({CONANFILE: content}) self.client.run("install --build missing") self.assertIn('Generated conaninfo.txt', str(self.client.user_io.out)) conan_info = ConanInfo.loads( load(os.path.join(self.client.current_folder, CONANINFO))) self.assertEquals(conan_info.settings.dumps(), "") # Settings is {} content = """ from conans import ConanFile class SayConan(ConanFile): name = "Say" version = "0.1" settings = {} """ self.client.save({CONANFILE: content}) self.client.run("install --build missing") self.assertIn('Generated conaninfo.txt', str(self.client.user_io.out)) conan_info = ConanInfo.loads( load(os.path.join(self.client.current_folder, CONANINFO))) self.assertEquals(conan_info.settings.dumps(), "")
def test_basic(self, short_paths): client = TestClient() conanfile = """ from conans import ConanFile class TestConan(ConanFile): name = "Hello" version = "0.1" settings = "os" def package(self): self.copy("*") """ if short_paths: conanfile += " short_paths = True" client.save({CONANFILE: conanfile}) client.run("export . lasote/stable") client.save({"include/header.h": "//Windows header"}) client.run("export-pkg . Hello/0.1@lasote/stable -s os=Windows") ref = ConanFileReference.loads("Hello/0.1@lasote/stable") win_pref = PackageReference( ref, "3475bd55b91ae904ac96fde0f106a136ab951a5e") package_folder = client.cache.package_layout( win_pref.ref, short_paths=short_paths).package(win_pref) if short_paths and platform.system() == "Windows": cache_pkg_folder = client.cache.package_layout( win_pref.ref, False).package(win_pref) self.assertEqual( load(os.path.join(cache_pkg_folder, ".conan_link")), package_folder) else: self.assertEqual( client.cache.package_layout(win_pref.ref).package(win_pref), package_folder) self.assertEqual( load(os.path.join(package_folder, "include/header.h")), "//Windows header") self._consume(client, ". -s os=Windows") self.assertIn( "Hello/0.1@lasote/stable:3475bd55b91ae904ac96fde0f106a136ab951a5e", client.out) # Now repeat client.save( { CONANFILE: conanfile, "include/header.h": "//Windows header2" }, clean_first=True) # Without force it fails err = client.run("export-pkg . Hello/0.1@lasote/stable -s os=Windows", assert_error=True) self.assertIn( "Package already exists. Please use --force, -f to overwrite it", client.out) self.assertTrue(err) # With force works client.run("export-pkg . Hello/0.1@lasote/stable -s os=Windows -f") self.assertEqual( load(os.path.join(package_folder, "include/header.h")), "//Windows header2") # Now use --install-folder client.save( { CONANFILE: conanfile, "include/header.h": "//Windows header3" }, clean_first=True) # Without force it fails client.run("install . --install-folder=inst -s os=Windows") err = client.run("export-pkg . Hello/0.1@lasote/stable -if inst", assert_error=True) self.assertTrue(err) self.assertIn( "Package already exists. Please use --force, -f to overwrite it", client.out) # With force works client.run("export-pkg . Hello/0.1@lasote/stable -if inst -f") self.assertIn( "Hello/0.1@lasote/stable: Package '3475bd55b91ae904ac96fde0f106a136ab951a5e'" " created", client.out) self.assertEqual( load(os.path.join(package_folder, "include/header.h")), "//Windows header3") # we can specify settings too client.save({"include/header.h": "//Windows header4"}) client.run( "export-pkg . Hello/0.1@lasote/stable -if inst -f -s os=Windows") self.assertIn( "Hello/0.1@lasote/stable: Package '3475bd55b91ae904ac96fde0f106a136ab951a5e'" " created", client.out) self.assertEqual( load(os.path.join(package_folder, "include/header.h")), "//Windows header4") # Try to specify a install folder with no files client.run("export-pkg . Hello/0.1@lasote/stable -if fake", assert_error=True) self.assertIn("ERROR: Failed to load graphinfo file in install-folder", client.out)
class SettingsCppStdScopedPackageTests(unittest.TestCase): # Validation of scoped settings is delayed until graph computation, a conanfile can # declare a different set of settings, so we should wait until then to validate it. default_profile = textwrap.dedent(""" [settings] os=Linux arch=x86 compiler=gcc compiler.version=7 compiler.libcxx=libstdc++11 """) def run(self, *args, **kwargs): default_profile_path = os.path.join(temp_folder(), "default.profile") save(default_profile_path, self.default_profile) with environment_append( {"CONAN_DEFAULT_PROFILE_PATH": default_profile_path}): unittest.TestCase.run(self, *args, **kwargs) def setUp(self): self.t = TestClient(cache_folder=temp_folder()) settings = ["os", "compiler", "build_type", "arch"] if self.recipe_cppstd: settings += ["cppstd"] conanfile = textwrap.dedent(""" from conans import ConanFile class Lib(ConanFile): settings = "{}" """.format('", "'.join(settings))) self.t.save({"conanfile.py": conanfile}) def test_value_invalid(self): self.t.run( "create . hh/0.1@user/channel -shh:compiler=apple-clang " "-shh:compiler.cppstd=144", assert_error=True) self.assertIn( "Invalid setting '144' is not a valid 'settings.compiler.cppstd' value", self.t.out) def test_value_different_with_scoped_setting(self): self.t.run( "create . hh/0.1@user/channel" " -s hh:cppstd=11" " -s hh:compiler=gcc" " -s hh:compiler.cppstd=14", assert_error=True) self.assertIn( "ERROR: Error in resulting settings for package 'hh': Do not use settings" " 'compiler.cppstd' together with 'cppstd'", self.t.out) def test_value_different_with_general_setting(self): deprecation_number = 1 if self.recipe_cppstd else 0 with catch_deprecation_warning(self, n=deprecation_number): self.t.run( "create . hh/0.1@user/channel" " -s cppstd=17" " -s hh:compiler=gcc" " -s hh:compiler.cppstd=14", assert_error=True) self.assertIn( "ERROR: Error in resulting settings for package 'hh': Do not use settings" " 'compiler.cppstd' together with 'cppstd'", self.t.out) def test_conanfile_without_compiler(self): conanfile = textwrap.dedent(""" from conans import ConanFile class Lib(ConanFile): settings = "os", "arch" """) t = TestClient(cache_folder=temp_folder()) t.save({'conanfile.py': conanfile}) with catch_deprecation_warning(self): # No mismatch, because settings for this conanfile does not include `compiler` t.run( "create . hh/0.1@user/channel" " -s cppstd=17" " -s hh:compiler=gcc" " -s hh:compiler.cppstd=14", assert_error=True) self.assertIn( "ERROR: Error in resulting settings for package 'hh': Do not use settings" " 'compiler.cppstd' together with 'cppstd'", t.out) def test_conanfile_without_compiler_but_cppstd(self): conanfile = textwrap.dedent(""" from conans import ConanFile class Lib(ConanFile): settings = "os", "arch", "cppstd" def configure(self): self.output.info(">>> cppstd: {}".format(self.settings.cppstd)) """) t = TestClient(cache_folder=temp_folder()) t.save({'conanfile.py': conanfile}, clean_first=True) with catch_deprecation_warning(self): # No mismatch, because settings for this conanfile does not include `compiler` t.run( "create . hh/0.1@user/channel" " -s cppstd=17" " -s hh:compiler=gcc" " -s hh:compiler.cppstd=14", assert_error=True) self.assertIn( "ERROR: Error in resulting settings for package 'hh': Do not use settings" " 'compiler.cppstd' together with 'cppstd'", t.out)
class ExportPkgTest(unittest.TestCase): def test_dont_touch_server(self): # https://github.com/conan-io/conan/issues/3432 client = TestClient(servers={"default": None}, requester_class=None, users={"default": [("lasote", "mypass")]}) client.save({ "conanfile.py": GenConanfile().with_name("Pkg").with_version("0.1") }) client.run("install .") client.run("export-pkg . Pkg/0.1@user/testing") def test_dont_touch_server_build_require(self): client = TestClient(servers={"default": None}, requester_class=None, users={"default": [("lasote", "mypass")]}) profile = dedent(""" [build_requires] some/other@pkg/notexists """) client.save({"conanfile.py": GenConanfile(), "myprofile": profile}) client.run("export-pkg . Pkg/0.1@user/testing -pr=myprofile") def test_transitive_without_settings(self): # https://github.com/conan-io/conan/issues/3367 client = TestClient() client.save({CONANFILE: GenConanfile()}) client.run("create . PkgC/0.1@user/testing") conanfile = """from conans import ConanFile class PkgB(ConanFile): settings = "arch" requires = "PkgC/0.1@user/testing" """ client.save({CONANFILE: conanfile}) client.run("create . PkgB/0.1@user/testing") conanfile = """from conans import ConanFile class PkgA(ConanFile): requires = "PkgB/0.1@user/testing" def build(self): self.output.info("BUILDING PKGA") """ client.save({CONANFILE: conanfile}) client.run("install . -if=build") client.run("build . -bf=build") client.run("export-pkg . PkgA/0.1@user/testing -bf=build -pr=default") self.assertIn( "PkgA/0.1@user/testing: Package " "'8f97510bcea8206c1c046cc8d71cc395d4146547' created", client.out) def test_package_folder_errors(self): # https://github.com/conan-io/conan/issues/2350 client = TestClient() client.save({CONANFILE: GenConanfile()}) mkdir(os.path.join(client.current_folder, "pkg")) client.run("export-pkg . Hello/0.1@lasote/stable -pf=pkg -bf=.", assert_error=True) self.assertIn( "ERROR: package folder definition incompatible with build and source folders", client.out) client.run("export-pkg . Hello/0.1@lasote/stable -pf=pkg -sf=.", assert_error=True) self.assertIn( "ERROR: package folder definition incompatible with build and source folders", client.out) client.run("export-pkg . Hello/0.1@lasote/stable -pf=pkg") self.assertIn( "Hello/0.1@lasote/stable: WARN: No files in this package!", client.out) def test_package_folder(self): # https://github.com/conan-io/conan/issues/2350 conanfile = """from conans import ConanFile class HelloPythonConan(ConanFile): settings = "os" def package(self): self.output.info("PACKAGE NOT CALLED") raise Exception("PACKAGE NOT CALLED") """ client = TestClient() client.save({ CONANFILE: conanfile, "pkg/myfile.h": "", "profile": "[settings]\nos=Windows" }) client.run("export-pkg . Hello/0.1@lasote/stable -pf=pkg -pr=profile") self.assertNotIn("PACKAGE NOT CALLED", client.out) self.assertIn( "Hello/0.1@lasote/stable: Packaged 1 '.h' file: myfile.h", client.out) self.assertNotIn("No files in this package!", client.out) ref = ConanFileReference.loads("Hello/0.1@lasote/stable") pkg_folder = client.cache.package_layout(ref).packages() folders = os.listdir(pkg_folder) pkg_folder = os.path.join(pkg_folder, folders[0]) conaninfo = load(os.path.join(pkg_folder, "conaninfo.txt")) self.assertEqual(2, conaninfo.count("os=Windows")) manifest = load(os.path.join(pkg_folder, "conanmanifest.txt")) self.assertIn("conaninfo.txt: f395060da1ffdeb934be8b62e4bd8a3a", manifest) self.assertIn("myfile.h: d41d8cd98f00b204e9800998ecf8427e", manifest) def test_develop(self): # https://github.com/conan-io/conan/issues/2513 conanfile = """from conans import ConanFile class HelloPythonConan(ConanFile): def package(self): self.output.info("DEVELOP IS: %s!" % self.develop) """ client = TestClient() client.save({CONANFILE: conanfile}) client.run("export-pkg . Hello/0.1@lasote/stable") self.assertIn("Hello/0.1@lasote/stable: DEVELOP IS: True!", client.out) def test_options(self): # https://github.com/conan-io/conan/issues/2242 conanfile = """from conans import ConanFile class HelloPythonConan(ConanFile): name = "Hello" options = { "optionOne": [True, False, 123] } default_options = "optionOne=True" """ client = TestClient() client.save({CONANFILE: conanfile}) client.run("export-pkg . Hello/0.1@lasote/stable") client.run("search Hello/0.1@lasote/stable") self.assertIn("optionOne: True", client.out) self.assertNotIn("optionOne: False", client.out) self.assertNotIn("optionOne: 123", client.out) client.run("export-pkg . Hello/0.1@lasote/stable -o optionOne=False") client.run("search Hello/0.1@lasote/stable") self.assertIn("optionOne: True", client.out) self.assertIn("optionOne: False", client.out) self.assertNotIn("optionOne: 123", client.out) client.run( "export-pkg . Hello/0.1@lasote/stable -o Hello:optionOne=123") client.run("search Hello/0.1@lasote/stable") self.assertIn("optionOne: True", client.out) self.assertIn("optionOne: False", client.out) self.assertIn("optionOne: 123", client.out) def test_profile_environment(self): # https://github.com/conan-io/conan/issues/4832 conanfile = dedent(""" import os from conans import ConanFile class HelloPythonConan(ConanFile): def package(self): self.output.info("ENV-VALUE: %s!!!" % os.getenv("MYCUSTOMVAR")) """) profile = dedent(""" [env] MYCUSTOMVAR=MYCUSTOMVALUE """) client = TestClient() client.save({CONANFILE: conanfile, "myprofile": profile}) client.run("export-pkg . Hello/0.1@lasote/stable -pr=myprofile") self.assertIn("Hello/0.1@lasote/stable: ENV-VALUE: MYCUSTOMVALUE!!!", client.out) def test_profile_environment_conaninfo(self): # https://github.com/conan-io/conan/issues/6603 profile = dedent(""" [env] MYCUSTOMVAR=MYCUSTOMVALUE """) client = TestClient() client.save({ "conanfile.py": GenConanfile().with_name("Hello").with_version("0.1"), "myprofile": profile }) client.run("export-pkg . Hello/0.1@lasote/stable -pr=myprofile") ref = ConanFileReference.loads("Hello/0.1@lasote/stable") pkg_folder = client.cache.package_layout(ref).packages() folders = os.listdir(pkg_folder) pkg_folder = os.path.join(pkg_folder, folders[0]) conaninfo = load(os.path.join(pkg_folder, "conaninfo.txt")) self.assertIn("MYCUSTOMVAR=MYCUSTOMVALUE", conaninfo) def test_options_install(self): # https://github.com/conan-io/conan/issues/2242 conanfile = """from conans import ConanFile class HelloPythonConan(ConanFile): name = "Hello" options = { "optionOne": [True, False, 123] } default_options = "optionOne=True" """ client = TestClient() client.save({CONANFILE: conanfile}) client.run("install .") client.run("export-pkg . Hello/0.1@lasote/stable") client.run("search Hello/0.1@lasote/stable") self.assertIn("optionOne: True", client.out) client.run("install . -o optionOne=False") client.run("export-pkg . Hello/0.1@lasote/stable") client.run("search Hello/0.1@lasote/stable") self.assertIn("optionOne: True", client.out) self.assertIn("optionOne: False", client.out) client.run("install . -o Hello:optionOne=123") client.run("export-pkg . Hello/0.1@lasote/stable") client.run("search Hello/0.1@lasote/stable") self.assertIn("optionOne: True", client.out) self.assertIn("optionOne: False", client.out) self.assertIn("optionOne: 123", client.out) @parameterized.expand([(False, ), (True, )]) @pytest.mark.skipif( get_env("TESTING_REVISIONS_ENABLED", False), reason="This test exports several RREVS assuming that the " "packages will be preserved and they will be removed") def test_basic(self, short_paths): client = TestClient() conanfile = """ from conans import ConanFile class TestConan(ConanFile): name = "Hello" version = "0.1" settings = "os" def package(self): self.copy("*") """ if short_paths: conanfile += " short_paths = True" client.save({CONANFILE: conanfile}) client.run("export . lasote/stable") client.save({"include/header.h": "//Windows header"}) client.run("export-pkg . Hello/0.1@lasote/stable -s os=Windows") ref = ConanFileReference.loads("Hello/0.1@lasote/stable") win_pref = PackageReference( ref, "3475bd55b91ae904ac96fde0f106a136ab951a5e") package_folder = client.cache.package_layout( win_pref.ref, short_paths=short_paths).package(win_pref) if short_paths and platform.system() == "Windows": cache_pkg_folder = client.cache.package_layout( win_pref.ref, False).package(win_pref) self.assertEqual( load(os.path.join(cache_pkg_folder, ".conan_link")), package_folder) else: self.assertEqual( client.cache.package_layout(win_pref.ref).package(win_pref), package_folder) self.assertEqual( load(os.path.join(package_folder, "include/header.h")), "//Windows header") self._consume(client, ". -s os=Windows") self.assertIn( "Hello/0.1@lasote/stable:3475bd55b91ae904ac96fde0f106a136ab951a5e", client.out) # Now repeat client.save( { CONANFILE: conanfile, "include/header.h": "//Windows header2" }, clean_first=True) # Without force it fails err = client.run("export-pkg . Hello/0.1@lasote/stable -s os=Windows", assert_error=True) self.assertIn( "Package already exists. Please use --force, -f to overwrite it", client.out) self.assertTrue(err) # With force works client.run("export-pkg . Hello/0.1@lasote/stable -s os=Windows -f") self.assertEqual( load(os.path.join(package_folder, "include/header.h")), "//Windows header2") # Now use --install-folder client.save( { CONANFILE: conanfile, "include/header.h": "//Windows header3" }, clean_first=True) # Without force it fails client.run("install . --install-folder=inst -s os=Windows") err = client.run("export-pkg . Hello/0.1@lasote/stable -if inst", assert_error=True) self.assertTrue(err) self.assertIn( "Package already exists. Please use --force, -f to overwrite it", client.out) # With force works client.run("export-pkg . Hello/0.1@lasote/stable -if inst -f") self.assertIn( "Hello/0.1@lasote/stable: Package '3475bd55b91ae904ac96fde0f106a136ab951a5e'" " created", client.out) self.assertEqual( load(os.path.join(package_folder, "include/header.h")), "//Windows header3") # we can specify settings too client.save({"include/header.h": "//Windows header4"}) client.run( "export-pkg . Hello/0.1@lasote/stable -if inst -f -s os=Windows") self.assertIn( "Hello/0.1@lasote/stable: Package '3475bd55b91ae904ac96fde0f106a136ab951a5e'" " created", client.out) self.assertEqual( load(os.path.join(package_folder, "include/header.h")), "//Windows header4") # Try to specify a install folder with no files client.run("export-pkg . Hello/0.1@lasote/stable -if fake", assert_error=True) self.assertIn("ERROR: Failed to load graphinfo file in install-folder", client.out) def _consume(self, client, install_args): consumer = """ from conans import ConanFile class TestConan(ConanFile): requires = "Hello/0.1@lasote/stable" settings = "os" """ client.save({CONANFILE: consumer}, clean_first=True) client.run("install %s" % install_args) self.assertIn("Hello/0.1@lasote/stable: Already installed!", client.out) def test_new(self): client = TestClient() client.run("new Hello/0.1 --bare") client.save({"lib/libmycoollib.a": ""}) settings = ( '-s os=Windows -s compiler=gcc -s compiler.version=4.9 ' '-s compiler.libcxx=libstdc++ -s build_type=Release -s arch=x86') client.run("export-pkg . Hello/0.1@lasote/stable %s" % settings) self.assertIn( "Hello/0.1@lasote/stable: A new conanfile.py version was exported", client.out) self.assertNotIn( "Hello/0.1@lasote/stable package(): WARN: No files in this package!", client.out) # --bare include a now mandatory package() method! self.assertIn("Packaged 1 '.a' file: libmycoollib.a", client.out) self._consume(client, settings + " . -g cmake") cmakeinfo = client.load("conanbuildinfo.cmake") self.assertIn("set(CONAN_LIBS_HELLO mycoollib)", cmakeinfo) self.assertIn("set(CONAN_LIBS mycoollib ${CONAN_LIBS})", cmakeinfo) # ensure the recipe hash is computed and added client.run("search Hello/0.1@lasote/stable") self.assertIn("Outdated from recipe: False", client.out) def test_build_folders(self): client = TestClient() conanfile = """ from conans import ConanFile class TestConan(ConanFile): name = "Hello" version = "0.1" settings = "os" def package(self): self.copy("*.h", src="include", dst="inc") self.copy("*.lib", src="lib", dst="lib") """ client.save( { CONANFILE: conanfile, "include/header.h": "//Windows header", "include/header.txt": "", "libs/what": "", "lib/hello.lib": "My Lib", "lib/bye.txt": "" }, clean_first=True) client.run( "export-pkg . Hello/0.1@lasote/stable -s os=Windows --build-folder=." ) ref = ConanFileReference.loads("Hello/0.1@lasote/stable") pref = PackageReference(ref, "3475bd55b91ae904ac96fde0f106a136ab951a5e") package_folder = client.cache.package_layout(pref.ref).package(pref) inc = os.path.join(package_folder, "inc") self.assertEqual(os.listdir(inc), ["header.h"]) self.assertEqual(load(os.path.join(inc, "header.h")), "//Windows header") lib = os.path.join(package_folder, "lib") self.assertEqual(os.listdir(lib), ["hello.lib"]) self.assertEqual(load(os.path.join(lib, "hello.lib")), "My Lib") def test_default_source_folder(self): client = TestClient() conanfile = """from conans import ConanFile class TestConan(ConanFile): def package(self): self.copy("*.h", src="src", dst="include") self.copy("*.lib", dst="lib", keep_path=False) """ client.save({ CONANFILE: conanfile, "src/header.h": "contents", "build/lib/hello.lib": "My Lib" }) client.run( "export-pkg . Hello/0.1@lasote/stable -s os=Windows --build-folder=build" ) ref = ConanFileReference.loads("Hello/0.1@lasote/stable") pref = PackageReference(ref, NO_SETTINGS_PACKAGE_ID) package_folder = client.cache.package_layout(pref.ref).package(pref) header = os.path.join(package_folder, "include/header.h") self.assertTrue(os.path.exists(header)) hello_path = os.path.join(package_folder, "lib", "hello.lib") self.assertTrue(os.path.exists(hello_path)) def test_build_source_folders(self): client = TestClient() conanfile = """from conans import ConanFile class TestConan(ConanFile): settings = "os" def package(self): self.copy("*.h", src="include", dst="inc") self.copy("*.lib", src="lib", dst="lib") """ client.save({ CONANFILE: conanfile, "src/include/header.h": "//Windows header", "src/include/header.txt": "", "build/libs/what": "", "build/lib/hello.lib": "My Lib", "build/lib/bye.txt": "" }) client.run( "export-pkg . Hello/0.1@lasote/stable -s os=Windows --build-folder=build " "--source-folder=src") ref = ConanFileReference.loads("Hello/0.1@lasote/stable") pref = PackageReference(ref, "3475bd55b91ae904ac96fde0f106a136ab951a5e") package_folder = client.cache.package_layout(pref.ref).package(pref) inc = os.path.join(package_folder, "inc") self.assertEqual(os.listdir(inc), ["header.h"]) self.assertEqual(load(os.path.join(inc, "header.h")), "//Windows header") lib = os.path.join(package_folder, "lib") self.assertEqual(os.listdir(lib), ["hello.lib"]) self.assertEqual(load(os.path.join(lib, "hello.lib")), "My Lib") def test_partial_references(self): client = TestClient() conanfile = """ from conans import ConanFile class TestConan(ConanFile): name = "Hello" version = "0.1" settings = "os" def package(self): self.copy("*") """ # Partial reference is ok client.save({CONANFILE: conanfile, "file.txt": "txt contents"}) client.run("export-pkg . conan/stable") self.assertIn( "Hello/0.1@conan/stable package(): Packaged 1 '.txt' file: file.txt", client.out) # Specify different name or version is not working client.run("export-pkg . lib/1.0@conan/stable -f", assert_error=True) self.assertIn("ERROR: Package recipe with name lib!=Hello", client.out) client.run("export-pkg . Hello/1.1@conan/stable -f", assert_error=True) self.assertIn("ERROR: Package recipe with version 1.1!=0.1", client.out) conanfile = """ from conans import ConanFile class TestConan(ConanFile): settings = "os" def package(self): self.copy("*") """ # Partial reference is ok client.save({CONANFILE: conanfile, "file.txt": "txt contents"}) client.run("export-pkg . anyname/1.222@conan/stable") self.assertIn( "anyname/1.222@conan/stable package(): Packaged 1 '.txt' file: file.txt", client.out) def test_with_deps(self): hello_ref = ConanFileReference.loads("Hello/0.1@lasote/stable") client = TestClient() conanfile = GenConanfile().with_name("Hello").with_version("0.1") client.save({"conanfile.py": str(conanfile)}) client.run("export . lasote/stable") client.run("install Hello/0.1@lasote/stable --build") conanfile = GenConanfile().with_name("Hello1").with_version("0.1")\ .with_require(hello_ref) conanfile = str(conanfile) + """\n def package_info(self): self.cpp_info.libs = self.collect_libs() def package(self): self.copy("*") """ client.save({"conanfile.py": conanfile}, clean_first=True) client.save({"Release_x86/lib/libmycoollib.a": ""}) settings = ( '-s os=Windows -s compiler=gcc -s compiler.version=4.9 ' '-s compiler.libcxx=libstdc++ -s build_type=Release -s arch=x86') client.run("export-pkg . Hello1/0.1@lasote/stable %s -bf=Release_x86" % settings) # consumer consumer = """ from conans import ConanFile class TestConan(ConanFile): requires = "Hello1/0.1@lasote/stable" settings = "os" """ client.save({CONANFILE: consumer}, clean_first=True) client.run("install conanfile.py -g cmake") self.assertIn("Hello/0.1@lasote/stable: Already installed!", client.out) self.assertIn("Hello1/0.1@lasote/stable: Already installed!", client.out) cmakeinfo = client.load("conanbuildinfo.cmake") self.assertIn("set(CONAN_LIBS_HELLO1 mycoollib)", cmakeinfo) self.assertIn("set(CONAN_LIBS mycoollib ${CONAN_LIBS})", cmakeinfo) def test_export_pkg_json(self): def _check_json_output_no_folder(): json_path = os.path.join(self.client.current_folder, "output.json") self.assertTrue(os.path.exists(json_path)) json_content = load(json_path) output = json.loads(json_content) self.assertEqual(True, output["error"]) self.assertEqual([], output["installed"]) self.assertEqual(2, len(output)) def _check_json_output(with_error=False): json_path = os.path.join(self.client.current_folder, "output.json") self.assertTrue(os.path.exists(json_path)) json_content = load(json_path) output = json.loads(json_content) self.assertEqual(output["error"], with_error) tmp = ConanFileReference.loads( output["installed"][0]["recipe"]["id"]) if self.client.cache.config.revisions_enabled: self.assertIsNotNone(tmp.revision) self.assertEqual(str(tmp), "mypackage/0.1.0@danimtb/testing") self.assertFalse(output["installed"][0]["recipe"]["dependency"]) self.assertTrue(output["installed"][0]["recipe"]["exported"]) if with_error: self.assertEqual(output["installed"][0]["packages"], []) else: self.assertEqual(output["installed"][0]["packages"][0]["id"], NO_SETTINGS_PACKAGE_ID) self.assertTrue( output["installed"][0]["packages"][0]["exported"]) conanfile = """from conans import ConanFile class MyConan(ConanFile): name = "mypackage" version = "0.1.0" """ self.client = TestClient() self.client.save({"conanfile.py": conanfile}) # Wrong folders self.client.run( "export-pkg . danimtb/testing -bf build -sf sources " "--json output.json", assert_error=True) _check_json_output_no_folder() # Deafult folders self.client.run( "export-pkg . danimtb/testing --json output.json --force") _check_json_output() # Without package_folder self.client.save({"sources/kk.cpp": "", "build/kk.lib": ""}) self.client.run( "export-pkg . danimtb/testing -bf build -sf sources --json output.json " "--force") _check_json_output() # With package_folder self.client.save({"package/kk.lib": ""}) self.client.run( "export-pkg . danimtb/testing -pf package --json output.json --force" ) _check_json_output() def test_json_with_dependencies(self): def _check_json_output(with_error=False): json_path = os.path.join(self.client.current_folder, "output.json") self.assertTrue(os.path.exists(json_path)) json_content = load(json_path) output = json.loads(json_content) self.assertEqual(output["error"], with_error) tmp = ConanFileReference.loads( output["installed"][0]["recipe"]["id"]) if self.client.cache.config.revisions_enabled: self.assertIsNotNone(tmp.revision) self.assertEqual(str(tmp), "pkg2/1.0@danimtb/testing") self.assertFalse(output["installed"][0]["recipe"]["dependency"]) self.assertTrue(output["installed"][0]["recipe"]["exported"]) if with_error: self.assertEqual(output["installed"][0]["packages"], []) else: self.assertEqual(output["installed"][0]["packages"][0]["id"], "5825778de2dc9312952d865df314547576f129b3") self.assertTrue( output["installed"][0]["packages"][0]["exported"]) tmp = ConanFileReference.loads( output["installed"][1]["recipe"]["id"]) if self.client.cache.config.revisions_enabled: self.assertIsNotNone(tmp.revision) self.assertEqual(str(tmp), "pkg1/1.0@danimtb/testing") self.assertTrue(output["installed"][1]["recipe"]["dependency"]) conanfile = """from conans import ConanFile class MyConan(ConanFile): pass """ self.client = TestClient() self.client.save({ "conanfile_dep.py": conanfile, "conanfile.py": conanfile + " requires = \"pkg1/1.0@danimtb/testing\"" }) self.client.run("export conanfile_dep.py pkg1/1.0@danimtb/testing") self.client.run( "export-pkg conanfile.py pkg2/1.0@danimtb/testing --json output.json" ) _check_json_output() # Error on missing dependency self.client.run("remove pkg1/1.0@danimtb/testing --force") self.client.run("remove pkg2/1.0@danimtb/testing --force") self.client.run( "export-pkg conanfile.py pkg2/1.0@danimtb/testing --json output.json", assert_error=True) _check_json_output(with_error=True) def test_export_pkg_no_ref(self): client = TestClient() conanfile = """from conans import ConanFile class TestConan(ConanFile): name = "Hello" version = "0.1" def package(self): self.copy("*.h", src="src", dst="include") """ client.save({CONANFILE: conanfile, "src/header.h": "contents"}) client.run("export-pkg . -s os=Windows") ref = ConanFileReference.loads("Hello/0.1@") pref = PackageReference(ref, NO_SETTINGS_PACKAGE_ID) package_folder = client.cache.package_layout(pref.ref).package(pref) header = os.path.join(package_folder, "include/header.h") self.assertTrue(os.path.exists(header)) def test_export_pkg_clean_dirty(self): # https://github.com/conan-io/conan/issues/6449 client = TestClient() conanfile = textwrap.dedent(""" from conans import ConanFile class Pkg(ConanFile): def build(self): if self.in_local_cache: raise Exception("Can't build while installing") """) client.save({"conanfile.py": conanfile}) client.run("create . pkg/0.1@", assert_error=True) self.assertIn("Can't build while installing", client.out) ref = ConanFileReference.loads("pkg/0.1") layout = client.cache.package_layout(ref) pref = PackageReference(ref, "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9") build_folder = layout.build(pref) self.assertTrue(is_dirty(build_folder)) self.assertTrue(layout.package_is_dirty(pref)) client.run("export-pkg . pkg/0.1@") self.assertFalse(layout.package_is_dirty(pref)) client.run("install pkg/0.1@") self.assertIn("pkg/0.1: Already installed!", client.out) def test_invalid_folder(self): """ source, build and package path must exists, otherwise, raise ConanException """ for folder in ["source", "build", "package"]: client = TestClient() client.save({ CONANFILE: GenConanfile().with_name("foo").with_version("0.1.0") }) client.run("export-pkg . foo/0.1.0@user/testing -{}f={}".format( folder[0], folder), assert_error=True) self.assertIn( "ERROR: The {} folder '{}' does not exist.".format( folder, os.path.join(client.current_folder, folder)), client.out)
class JsonOutputTest(unittest.TestCase): def setUp(self): self.servers = {"default": TestServer()} self.client = TestClient(servers=self.servers) def test_simple_fields(self): # Result of a create files = cpp_hello_conan_files("CC", "1.0", build=False) self.client.save(files, clean_first=True) self.client.run("create . private_user/channel --json=myfile.json") my_json = json.loads( load(os.path.join(self.client.current_folder, "myfile.json"))) self.assertFalse(my_json["error"]) self.assertEquals(my_json["installed"][0]["recipe"]["id"], "CC/1.0@private_user/channel") self.assertFalse(my_json["installed"][0]["recipe"]["dependency"]) self.assertTrue(my_json["installed"][0]["recipe"]["exported"]) self.assertFalse(my_json["installed"][0]["recipe"]["downloaded"]) self.assertIsNone(my_json["installed"][0]["recipe"]["remote"]) self.assertTrue(my_json["installed"][0]["packages"][0]["built"]) self.assertTrue(my_json["installed"][0]["packages"][0]["cpp_info"]) # Result of an install retrieving only the recipe self.client.run("upload CC/1.0@private_user/channel -c") self.client.run("remove '*' -f") self.client.run( "install CC/1.0@private_user/channel --json=myfile.json --build missing " ) my_json = json.loads( load(os.path.join(self.client.current_folder, "myfile.json"))) the_time_str = my_json["installed"][0]["recipe"]["time"] self.assertIn("T", the_time_str) # Weak validation of the ISO 8601 self.assertFalse(my_json["error"]) self.assertEquals(my_json["installed"][0]["recipe"]["id"], "CC/1.0@private_user/channel") self.assertTrue(my_json["installed"][0]["recipe"]["dependency"]) self.assertTrue(my_json["installed"][0]["recipe"]["downloaded"]) self.assertIsNotNone(my_json["installed"][0]["recipe"]["remote"]) self.assertTrue(my_json["installed"][0]["packages"][0]["built"]) self.assertTrue(my_json["installed"][0]["packages"][0]["cpp_info"]) # Upload the binary too self.client.run("upload CC/1.0@private_user/channel --all -c") self.client.run("remove '*' -f") self.client.run( "install CC/1.0@private_user/channel --json=myfile.json") my_json = json.loads( load(os.path.join(self.client.current_folder, "myfile.json"))) self.assertFalse(my_json["error"]) self.assertEquals(my_json["installed"][0]["recipe"]["id"], "CC/1.0@private_user/channel") self.assertTrue(my_json["installed"][0]["recipe"]["downloaded"]) self.assertIsNotNone(my_json["installed"][0]["recipe"]["remote"]) self.assertFalse(my_json["installed"][0]["packages"][0]["built"]) self.assertTrue(my_json["installed"][0]["packages"][0]["downloaded"]) self.assertTrue(my_json["installed"][0]["packages"][0]["cpp_info"]) # Force build self.client.run("remove '*' -f") self.client.run( "install CC/1.0@private_user/channel --json=myfile.json --build") my_json = json.loads( load(os.path.join(self.client.current_folder, "myfile.json"))) self.assertFalse(my_json["error"]) self.assertEquals(my_json["installed"][0]["recipe"]["id"], "CC/1.0@private_user/channel") self.assertTrue(my_json["installed"][0]["recipe"]["downloaded"]) self.assertIsNotNone(my_json["installed"][0]["recipe"]["remote"]) self.assertTrue(my_json["installed"][0]["packages"][0]["built"]) self.assertFalse(my_json["installed"][0]["packages"][0]["downloaded"]) self.assertTrue(my_json["installed"][0]["packages"][0]["cpp_info"]) def test_errors(self): # Missing recipe self.client.run( "install CC/1.0@private_user/channel --json=myfile.json", assert_error=True) my_json = json.loads( load(os.path.join(self.client.current_folder, "myfile.json"))) self.assertTrue(my_json["error"]) self.assertEquals(len(my_json["installed"]), 1) self.assertFalse(my_json["installed"][0]["recipe"]["downloaded"]) self.assertEquals( my_json["installed"][0]["recipe"]["error"], { 'type': 'missing', 'remote': None, 'description': "Unable to find 'CC/1.0@private_user/channel' in remotes" }) # Missing binary package files = cpp_hello_conan_files("CC", "1.0", build=False) self.client.save(files, clean_first=True) self.client.run("create . private_user/channel --json=myfile.json ") self.client.run("upload CC/1.0@private_user/channel -c") self.client.run("remove '*' -f") self.client.run( "install CC/1.0@private_user/channel --json=myfile.json", assert_error=True) my_json = json.loads( load(os.path.join(self.client.current_folder, "myfile.json"))) self.assertTrue(my_json["error"]) self.assertEquals(len(my_json["installed"]), 1) self.assertTrue(my_json["installed"][0]["recipe"]["downloaded"]) self.assertFalse(my_json["installed"][0]["recipe"]["error"]) self.assertEquals(len(my_json["installed"][0]["packages"]), 1) self.assertFalse(my_json["installed"][0]["packages"][0]["downloaded"]) self.assertEquals( my_json["installed"][0]["packages"][0]["error"]["type"], "missing") self.assertIsNone( my_json["installed"][0]["packages"][0]["error"]["remote"]) self.assertIn( "Can't find a 'CC/1.0@private_user/channel' package", my_json["installed"][0]["packages"][0]["error"]["description"]) # Error building files["conanfile.py"] = files["conanfile.py"].replace( "def build2(self):", """ def build(self): raise Exception("Build error!") """) self.client.save(files, clean_first=True) self.client.run("create . private_user/channel --json=myfile.json ", assert_error=True) my_json = json.loads( load(os.path.join(self.client.current_folder, "myfile.json"))) self.assertTrue(my_json["error"]) self.assertEquals( my_json["installed"][0]["packages"][0]["error"]["type"], "building") self.assertIsNone( my_json["installed"][0]["packages"][0]["error"]["remote"]) self.assertIn( "CC/1.0@private_user/channel: Error in build() method, line 36", my_json["installed"][0]["packages"][0]["error"]["description"]) def test_json_generation(self): files = cpp_hello_conan_files("CC", "1.0", build=False) self.client.save(files, clean_first=True) self.client.run("create . private_user/channel --json=myfile.json ") self.client.run('upload "*" -c --all') files = cpp_hello_conan_files("BB", "1.0", build=False) files["conanfile.py"] += """ def configure(self): self.options["CC"].static = False def build_requirements(self): self.build_requires("CC/1.0@private_user/channel") """ self.client.save(files, clean_first=True) self.client.run("create . private_user/channel --build missing") self.client.run('upload "*" -c --all') files = cpp_hello_conan_files("AA", "1.0", deps=["BB/1.0@private_user/channel"], build=False) self.client.save(files, clean_first=True) self.client.run("create . private_user/channel") self.client.run('upload "*" -c --all') save( os.path.join(self.client.client_cache.profiles_path, "mybr"), """ include(default) [build_requires] AA*: CC/1.0@private_user/channel """) files = cpp_hello_conan_files("PROJECT", "1.0", deps=["AA/1.0@private_user/channel"], build=False) self.client.save(files, clean_first=True) self.client.run( "install . --profile mybr --json=myfile.json --build AA --build BB" ) my_json = load(os.path.join(self.client.current_folder, "myfile.json")) my_json = json.loads(my_json) self.assertTrue(my_json["installed"][0]["recipe"]["dependency"]) self.assertTrue(my_json["installed"][1]["recipe"]["dependency"]) self.assertTrue(my_json["installed"][2]["recipe"]["dependency"]) # Installed the build require CC with two options self.assertEquals(len(my_json["installed"][2]["packages"]), 2) self.assertEquals(my_json["installed"][2]["recipe"]["id"], "CC/1.0@private_user/channel") self.assertFalse(my_json["installed"][2]["recipe"]["downloaded"]) self.assertFalse(my_json["installed"][2]["packages"][0]["downloaded"]) self.assertFalse(my_json["installed"][2]["packages"][1]["downloaded"])
def update_pkg_test(self): server = TestServer() client = TestClient(servers={"default": server}, users={"default": [("lasote", "mypass")]}) conanfile = """from conans import ConanFile class HelloReuseConan(ConanFile): def package_info(self): self.output.info("PACKAGE_INFO {}") """ client.save({"conanfile.py": conanfile.format("1.1")}) client.run("create . Pkg/1.1@lasote/testing") client.save({"conanfile.py": conanfile.format("1.2")}) client.run("create . Pkg/1.2@lasote/testing") client.run("upload Pkg* -r=default --all --confirm") consumer = """from conans import ConanFile class HelloReuseConan(ConanFile): requires = "Pkg/[~1]@lasote/testing" """ client.save({"conanfile.py": consumer}) client.run("install .") # Resolves to local package self.assertIn("Pkg/1.2@lasote/testing: Already installed!", client.out) self.assertIn("Pkg/1.2@lasote/testing: PACKAGE_INFO 1.2", client.out) # modify remote 1.2 client2 = TestClient(servers={"default": server}, users={"default": [("lasote", "mypass")]}) client2.save({"conanfile.py": conanfile.format("*1.2*")}) client2.run("create . Pkg/1.2@lasote/testing") # Make sure timestamp increases, in some machines in testing, # it can fail due to same timestamp inc_recipe_manifest_timestamp(client2.cache, "Pkg/1.2@lasote/testing", 1) inc_package_manifest_timestamp( client2.cache, "Pkg/1.2@lasote/testing:%s" % NO_SETTINGS_PACKAGE_ID, 1) client2.run("upload Pkg* -r=default --all --confirm") client.run("install .") # Resolves to local package self.assertIn("Pkg/1.2@lasote/testing: Already installed!", client.out) self.assertIn("Pkg/1.2@lasote/testing: PACKAGE_INFO 1.2", client.out) client.run("install . --update") # Resolves to remote new recipe and package self.assertIn("Pkg/1.2@lasote/testing: Package installed", client.out) self.assertNotIn("Pkg/1.2@lasote/testing: PACKAGE_INFO 1.2", client.out) self.assertIn("Pkg/1.2@lasote/testing: PACKAGE_INFO *1.2*", client.out)
def test_options_install(self): # https://github.com/conan-io/conan/issues/2242 conanfile = """from conans import ConanFile class HelloPythonConan(ConanFile): name = "Hello" options = { "optionOne": [True, False, 123] } default_options = "optionOne=True" """ client = TestClient() client.save({CONANFILE: conanfile}) client.run("install .") client.run("export-pkg . Hello/0.1@lasote/stable") client.run("search Hello/0.1@lasote/stable") self.assertIn("optionOne: True", client.out) client.run("install . -o optionOne=False") client.run("export-pkg . Hello/0.1@lasote/stable") client.run("search Hello/0.1@lasote/stable") self.assertIn("optionOne: True", client.out) self.assertIn("optionOne: False", client.out) client.run("install . -o Hello:optionOne=123") client.run("export-pkg . Hello/0.1@lasote/stable") client.run("search Hello/0.1@lasote/stable") self.assertIn("optionOne: True", client.out) self.assertIn("optionOne: False", client.out) self.assertIn("optionOne: 123", client.out)