Skip to content

Commit

Permalink
refactor test usage of ConanAPI (#17494)
Browse files Browse the repository at this point in the history
* refactor test usage of ConanAPI

* fix test

* reuse functional fixtures

* fix test
  • Loading branch information
memsharded authored Dec 18, 2024
1 parent c914779 commit e997512
Show file tree
Hide file tree
Showing 59 changed files with 264 additions and 254 deletions.
15 changes: 6 additions & 9 deletions conan/test/utils/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from requests.exceptions import HTTPError
from webtest.app import TestApp

from conan.api.subapi.config import ConfigAPI
from conan.api.subapi.remotes import _save
from conan.cli.exit_codes import SUCCESS, ERROR_GENERAL
from conan.internal.cache.cache import PackageLayout, RecipeLayout, PkgCache
Expand Down Expand Up @@ -457,7 +458,7 @@ def __init__(self, cache_folder=None, current_folder=None, servers=None, inputs=
# create default profile
if light:
text = "[settings]\nos=Linux" # Needed at least build-os
save(self.cache.settings_path, "os: [Linux, Windows]")
save(self.paths.settings_path, "os: [Linux, Windows]")
else:
text = default_profiles[platform.system()]
save(os.path.join(self.cache_folder, "profiles", "default"), text)
Expand All @@ -476,15 +477,11 @@ def load_home(self, filename):
@property
def cache(self):
# Returns a temporary cache object intended for inspecting it
api = ConanAPI(cache_folder=self.cache_folder)
global_conf = api.config.global_conf

class MyCache(PkgCache, HomePaths): # Temporary class to avoid breaking all tests
def __init__(self, cache_folder):
PkgCache.__init__(self, cache_folder, global_conf)
HomePaths.__init__(self, cache_folder)
return PkgCache(self.cache_folder, ConfigAPI.load_config(self.cache_folder))

return MyCache(self.cache_folder)
@property
def paths(self):
return HomePaths(self.cache_folder)

@property
def base_folder(self):
Expand Down
30 changes: 15 additions & 15 deletions test/functional/command/config_install_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ def make_file_read_only(file_path):
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")
save(os.path.join(self.client.paths.profiles_path, "default"), "#default profile empty")
save(os.path.join(self.client.paths.profiles_path, "linux"), "#empty linux profile")

@staticmethod
def _create_profile_folder(folder=None):
Expand Down Expand Up @@ -134,19 +134,19 @@ def _create_tgz(self, tgz_path=None):
return tgz_with_contents(files, tgz_path)

def _check(self, params):
settings_path = self.client.cache.settings_path
settings_path = self.client.paths.settings_path
self.assertEqual(load(settings_path).splitlines(), settings_yml.splitlines())
api = self.client.api
cache_remotes = api.remotes.list()
self.assertEqual(list(cache_remotes), [
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)),
self.assertEqual(sorted(os.listdir(self.client.paths.profiles_path)),
sorted(["default", "linux", "windows"]))
self.assertEqual(load(os.path.join(self.client.cache.profiles_path, "linux")).splitlines(),
self.assertEqual(load(os.path.join(self.client.paths.profiles_path, "linux")).splitlines(),
linux_profile.splitlines())
self.assertEqual(load(os.path.join(self.client.cache.profiles_path,
self.assertEqual(load(os.path.join(self.client.paths.profiles_path,
"windows")).splitlines(),
win_profile.splitlines())
self.assertEqual("#Custom pylint",
Expand Down Expand Up @@ -260,12 +260,12 @@ def test_install_remotes_json(self):
assert "repojson2: https://repojson2.com [Verify SSL: True, Enabled: True]" in self.client.out

def test_without_profile_folder(self):
shutil.rmtree(self.client.cache.profiles_path)
shutil.rmtree(self.client.paths.profiles_path)
zippath = self._create_zip()
self.client.run('config install "%s"' % zippath)
self.assertEqual(sorted(os.listdir(self.client.cache.profiles_path)),
self.assertEqual(sorted(os.listdir(self.client.paths.profiles_path)),
sorted(["linux", "windows"]))
self.assertEqual(load(os.path.join(self.client.cache.profiles_path, "linux")).splitlines(),
self.assertEqual(load(os.path.join(self.client.paths.profiles_path, "linux")).splitlines(),
linux_profile.splitlines())

def test_install_url(self):
Expand Down Expand Up @@ -496,7 +496,7 @@ def test_git_checkout_is_possible(self):
self.client.run('config install "%s/.git" --args "-b other_branch"' % folder)
check_path = os.path.join(folder, ".git")
self._check("git, %s, True, -b other_branch" % check_path)
file_path = os.path.join(self.client.cache.hooks_path, "cust", "cust.py")
file_path = os.path.join(self.client.paths.hooks_path, "cust", "cust.py")
assert load(file_path) == ""

# Add changes to that branch and update
Expand Down Expand Up @@ -525,20 +525,20 @@ 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))
make_file_read_only(self.client.paths.settings_path)
self.assertFalse(os.access(self.client.paths.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))
self.assertTrue(os.access(self.client.paths.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.json'))

self.client.run('config install "%s"' % source_folder)
self.assertTrue(os.access(self.client.cache.settings_path, os.W_OK))
self.assertTrue(os.access(self.client.paths.settings_path, os.W_OK))


class ConfigInstallSchedTest(unittest.TestCase):
Expand Down Expand Up @@ -587,7 +587,7 @@ def test_config_fails_git_folder(self):
assert ".gitlab-conan" in client.cache_folder
assert os.path.basename(client.cache_folder) == DEFAULT_CONAN_HOME
client.run('config install "%s/.git" --type git' % self.folder)
conf = load(client.cache.new_config_path)
conf = load(client.paths.new_config_path)
dirs = os.listdir(client.cache_folder)
assert ".git" not in dirs

Expand Down
2 changes: 1 addition & 1 deletion test/functional/command/export_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def test_revision_mode_scm_excluded_files(self, conf_excluded, recipe_excluded):
t = TestClient()
recipe_excluded = f'revision_mode_excluded = {recipe_excluded}' if recipe_excluded else ""
conf_excluded = f'core.scm:excluded={conf_excluded}' if conf_excluded else ""
save(t.cache.global_conf_path, conf_excluded)
save(t.paths.global_conf_path, conf_excluded)
conanfile = GenConanfile("pkg", "0.1").with_class_attribute('revision_mode = "scm"') \
.with_class_attribute(recipe_excluded)
commit = t.init_git_repo({'conanfile.py': str(conanfile),
Expand Down
8 changes: 4 additions & 4 deletions test/functional/command/profile_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ def test_list(self):
if platform.system() != "Windows":
profiles.append("symlink_me" + os.path.sep + "profile7")
for profile in profiles:
save(os.path.join(client.cache.profiles_path, profile), "")
save(os.path.join(client.paths.profiles_path, profile), "")

if platform.system() != "Windows":
os.symlink(os.path.join(client.cache.profiles_path, 'symlink_me'),
os.path.join(client.cache.profiles_path, 'link'))
os.symlink(os.path.join(client.paths.profiles_path, 'symlink_me'),
os.path.join(client.paths.profiles_path, 'link'))
# profile7 will be shown twice because it is symlinked.
profiles.append("link" + os.path.sep + "profile7")

Expand Down Expand Up @@ -62,7 +62,7 @@ def test_show(self):
[conf]
tools.build:jobs=20
""")
save(os.path.join(client.cache.profiles_path, "profile1"), profile1)
save(os.path.join(client.paths.profiles_path, "profile1"), profile1)

client.run("profile show -pr=profile1")
self.assertIn("[settings]\nos=Windows", client.out)
Expand Down
2 changes: 1 addition & 1 deletion test/functional/command/runner_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def test_create_docker_runner_cache_shared_profile_from_cache():
remove=True
""")

client.save({"default_host": profile_host, "default_build": profile_build}, path=client.cache.profiles_path)
client.save({"default_host": profile_host, "default_build": profile_build}, path=client.paths.profiles_path)
client.run("new cmake_lib -d name=pkg -d version=0.2")
client.run("create . -pr:h default_host -pr:b default_build")

Expand Down
86 changes: 37 additions & 49 deletions test/functional/command/test_install_deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,50 +13,38 @@
from conans.util.files import save


@pytest.fixture(scope="module")
def _client():
c = TestClient()
c.run("new cmake_lib -d name=hello -d version=0.1")
c.run("create . -o *:shared=True -tf=")
@pytest.fixture()
def client(matrix_client_shared):
c = matrix_client_shared
conanfile = textwrap.dedent("""
import os
from conan import ConanFile
from conan.tools.files import save
class Tool(ConanFile):
name = "tool"
version = "1.0"
def package(self):
save(self, os.path.join(self.package_folder, "build", "my_tools.cmake"),
'set(MY_TOOL_VARIABLE "Hello world!")')
def package_info(self):
self.cpp_info.includedirs = []
self.cpp_info.libdirs = []
self.cpp_info.bindirs = []
path_build_modules = os.path.join("build", "my_tools.cmake")
self.cpp_info.set_property("cmake_build_modules", [path_build_modules])
""")
import os
from conan import ConanFile
from conan.tools.files import save
class Tool(ConanFile):
name = "tool"
version = "1.0"
def package(self):
save(self, os.path.join(self.package_folder, "build", "my_tools.cmake"),
'set(MY_TOOL_VARIABLE "Hello world!")')
def package_info(self):
self.cpp_info.includedirs = []
self.cpp_info.libdirs = []
self.cpp_info.bindirs = []
path_build_modules = os.path.join("build", "my_tools.cmake")
self.cpp_info.set_property("cmake_build_modules", [path_build_modules])
""")
c.save({"conanfile.py": conanfile}, clean_first=True)
c.run("create .")
return c


@pytest.fixture()
def client(_client):
""" this is much faster than creating and uploading everythin
"""
client = TestClient(default_server_user=True)
shutil.rmtree(client.cache_folder)
shutil.copytree(_client.cache_folder, client.cache_folder)
return client


@pytest.mark.tool("cmake")
@pytest.mark.parametrize("powershell", [False, True])
def test_install_deploy(client, powershell):
c = client
custom_content = 'message(STATUS "MY_TOOL_VARIABLE=${MY_TOOL_VARIABLE}!")'
cmake = gen_cmakelists(appname="my_app", appsources=["main.cpp"], find_package=["hello", "tool"],
cmake = gen_cmakelists(appname="my_app", appsources=["main.cpp"], find_package=["matrix", "tool"],
custom_content=custom_content)
deploy = textwrap.dedent("""
import os, shutil
Expand All @@ -69,20 +57,20 @@ def deploy(graph, output_folder, **kwargs):
shutil.copytree(d.package_folder, new_folder)
d.set_deploy_folder(new_folder)
""")
c.save({"conanfile.txt": "[requires]\nhello/0.1\ntool/1.0",
c.save({"conanfile.txt": "[requires]\nmatrix/1.0\ntool/1.0",
"deploy.py": deploy,
"CMakeLists.txt": cmake,
"main.cpp": gen_function_cpp(name="main", includes=["hello"], calls=["hello"])},
"main.cpp": gen_function_cpp(name="main", includes=["matrix"], calls=["matrix"])},
clean_first=True)
pwsh = "-c tools.env.virtualenv:powershell=True" if powershell else ""
c.run("install . -o *:shared=True "
f"--deployer=deploy.py -of=mydeploy -g CMakeToolchain -g CMakeDeps {pwsh}")
c.run("remove * -c") # Make sure the cache is clean, no deps there
arch = c.get_default_host_profile().settings['arch']
deps = c.load(f"mydeploy/hello-release-{arch}-data.cmake")
assert 'set(hello_PACKAGE_FOLDER_RELEASE "${CMAKE_CURRENT_LIST_DIR}/hello")' in deps
assert 'set(hello_INCLUDE_DIRS_RELEASE "${hello_PACKAGE_FOLDER_RELEASE}/include")' in deps
assert 'set(hello_LIB_DIRS_RELEASE "${hello_PACKAGE_FOLDER_RELEASE}/lib")' in deps
deps = c.load(f"mydeploy/matrix-release-{arch}-data.cmake")
assert 'set(matrix_PACKAGE_FOLDER_RELEASE "${CMAKE_CURRENT_LIST_DIR}/matrix")' in deps
assert 'set(matrix_INCLUDE_DIRS_RELEASE "${matrix_PACKAGE_FOLDER_RELEASE}/include")' in deps
assert 'set(matrix_LIB_DIRS_RELEASE "${matrix_PACKAGE_FOLDER_RELEASE}/lib")' in deps

# We can fully move it to another folder, and still works
tmp = os.path.join(temp_folder(), "relocated")
Expand All @@ -101,18 +89,18 @@ def deploy(graph, output_folder, **kwargs):
cmd = r"mydeploy\conanrun.bat && Release\my_app.exe"
# For Lunux: cmd = ". mydeploy/conanrun.sh && ./my_app"
c2.run_command(cmd)
assert "hello/0.1: Hello World Release!" in c2.out
assert "matrix/1.0: Hello World Release!" in c2.out


@pytest.mark.tool("cmake")
def test_install_full_deploy_layout(client):
c = client
custom_content = 'message(STATUS "MY_TOOL_VARIABLE=${MY_TOOL_VARIABLE}!")'
cmake = gen_cmakelists(appname="my_app", appsources=["main.cpp"], find_package=["hello", "tool"],
cmake = gen_cmakelists(appname="my_app", appsources=["main.cpp"], find_package=["matrix", "tool"],
custom_content=custom_content)
conanfile = textwrap.dedent("""
[requires]
hello/0.1
matrix/1.0
tool/1.0
[generators]
CMakeDeps
Expand All @@ -122,18 +110,18 @@ def test_install_full_deploy_layout(client):
""")
c.save({"conanfile.txt": conanfile,
"CMakeLists.txt": cmake,
"main.cpp": gen_function_cpp(name="main", includes=["hello"], calls=["hello"])},
"main.cpp": gen_function_cpp(name="main", includes=["matrix"], calls=["matrix"])},
clean_first=True)
c.run("install . -o *:shared=True --deployer=full_deploy.py")
c.run("remove * -c") # Make sure the cache is clean, no deps there
arch = c.get_default_host_profile().settings['arch']
folder = "/Release" if platform.system() != "Windows" else ""
rel_path = "../../" if platform.system() == "Windows" else "../../../"
deps = c.load(f"build{folder}/generators/hello-release-{arch}-data.cmake")
assert 'set(hello_PACKAGE_FOLDER_RELEASE "${CMAKE_CURRENT_LIST_DIR}/' \
f'{rel_path}full_deploy/host/hello/0.1/Release/{arch}")' in deps
assert 'set(hello_INCLUDE_DIRS_RELEASE "${hello_PACKAGE_FOLDER_RELEASE}/include")' in deps
assert 'set(hello_LIB_DIRS_RELEASE "${hello_PACKAGE_FOLDER_RELEASE}/lib")' in deps
deps = c.load(f"build{folder}/generators/matrix-release-{arch}-data.cmake")
assert 'set(matrix_PACKAGE_FOLDER_RELEASE "${CMAKE_CURRENT_LIST_DIR}/' \
f'{rel_path}full_deploy/host/matrix/1.0/Release/{arch}")' in deps
assert 'set(matrix_INCLUDE_DIRS_RELEASE "${matrix_PACKAGE_FOLDER_RELEASE}/include")' in deps
assert 'set(matrix_LIB_DIRS_RELEASE "${matrix_PACKAGE_FOLDER_RELEASE}/lib")' in deps

# We can fully move it to another folder, and still works
tmp = os.path.join(temp_folder(), "relocated")
Expand All @@ -151,7 +139,7 @@ def test_install_full_deploy_layout(client):
cmd = r"generators\conanrun.bat && Release\my_app.exe"
# For Lunux: cmd = ". mydeploy/conanrun.sh && ./my_app"
c2.run_command(cmd)
assert "hello/0.1: Hello World Release!" in c2.out
assert "matrix/1.0: Hello World Release!" in c2.out


def test_copy_files_deploy():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,26 @@
@pytest.fixture(scope="session")
def _matrix_client():
"""
engine/1.0->matrix/1.0
matrix/1.0, just static, no test_package
"""
c = TestClient()
c.run("new cmake_lib -d name=matrix -d version=1.0")
c.run("create . -tf=")
return c


@pytest.fixture(scope="session")
def _matrix_client_shared(_matrix_client):
_matrix_client.run("create . -o *:shared=True -tf=")
return _matrix_client


@pytest.fixture(scope="session")
def _matrix_client_debug(_matrix_client):
_matrix_client.run("create . -s build_type=Debug -tf=")
return _matrix_client


@pytest.fixture()
def matrix_client(_matrix_client):
c = TestClient()
Expand All @@ -28,6 +40,30 @@ def matrix_client(_matrix_client):
return c


@pytest.fixture()
def matrix_client_shared(_matrix_client_shared):
c = TestClient()
c.cache_folder = os.path.join(temp_folder(), ".conan2")
shutil.copytree(_matrix_client_shared.cache_folder, c.cache_folder)
return c


@pytest.fixture()
def matrix_client_shared_debug(_matrix_client_shared, _matrix_client_debug):
c = TestClient()
c.cache_folder = os.path.join(temp_folder(), ".conan2")
shutil.copytree(_matrix_client_shared.cache_folder, c.cache_folder)
return c


@pytest.fixture()
def matrix_client_debug(_matrix_client_debug):
c = TestClient()
c.cache_folder = os.path.join(temp_folder(), ".conan2")
shutil.copytree(_matrix_client_debug.cache_folder, c.cache_folder)
return c


@pytest.fixture(scope="session")
def _transitive_libraries(_matrix_client):
"""
Expand Down
2 changes: 1 addition & 1 deletion test/functional/layout/test_build_system_layout_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def layout(self):
""")
client = TestClient()
client.save({"conanfile.py": conanfile})
save(client.cache.settings_path, settings_yml)
save(client.paths.settings_path, settings_yml)
client.run('install . -s os=Windows -s build_type=Release -s arch=x86_64 '
'-s compiler=gcc -s compiler.version=8 '
'-s:b os=Windows -s:b build_type=Release -s:b arch=x86_64 '
Expand Down
Loading

0 comments on commit e997512

Please sign in to comment.