def _init_collaborators(self, user_io=None): output = TestBufferConanOutput() self.user_io = user_io or MockedUserIO(self.users, out=output) self.cache = ClientCache(self.base_folder, self.storage_folder, output) self.runner = TestRunner(output, runner=self.conan_runner) # Check if servers are real real_servers = False for server in self.servers.values(): if isinstance(server, str) or isinstance( server, ArtifactoryServer): # Just URI real_servers = True break with tools.environment_append(self.cache.config.env_vars): if real_servers: requester = requests.Session() else: if self.requester_class: requester = self.requester_class(self.servers) else: requester = TestRequester(self.servers) self.requester = ConanRequester(requester, self.cache, get_request_timeout()) self.hook_manager = HookManager(self.cache.hooks_path, get_env("CONAN_HOOKS", list()), self.user_io.out) self.localdb, self.rest_api_client, self.remote_manager = \ Conan.instance_remote_manager(self.requester, self.cache, self.user_io, self.hook_manager) return output, self.requester
def get_conaninfo(info): package_id = info["installed"][0]["packages"][0]["id"] pref = PackageReference.loads("lib/1.0@conan/stable:%s" % package_id) cache = ClientCache(api.cache_folder, TestBufferConanOutput()) folder = cache.package_layout(pref.ref).package(pref) return load(os.path.join(folder, "conaninfo.txt"))
def __init__(self, output, build_info_file, lockfile, user=None, password=None, apikey=None): self._build_info_file = build_info_file self._lockfile = lockfile self._user = user self._password = password self._apikey = apikey self._output = output self._conan_cache = ClientCache(os.path.join(get_conan_user_home(), ".conan"), output)
def __init__(self, base_folder=None, current_folder=None, servers=None, users=None, requester_class=None, runner=None, path_with_spaces=True, revisions_enabled=None, cpu_count=1): """ storage_folder: Local storage path current_folder: Current execution folder servers: dict of {remote_name: TestServer} logins is a list of (user, password) for auto input in order if required==> [("lasote", "mypass"), ("other", "otherpass")] """ self.all_output = "" # For debugging purpose, append all the run outputs self.users = users if self.users is None: self.users = { "default": [(TESTING_REMOTE_PRIVATE_USER, TESTING_REMOTE_PRIVATE_PASS)] } self.base_folder = base_folder or temp_folder(path_with_spaces) # Define storage_folder, if not, it will be read from conf file & pointed to real user home self.storage_folder = os.path.join(self.base_folder, ".conan", "data") self.cache = ClientCache(self.base_folder, self.storage_folder, TestBufferConanOutput()) self.requester_class = requester_class self.conan_runner = runner if revisions_enabled is None: revisions_enabled = get_env("TESTING_REVISIONS_ENABLED", False) self.tune_conan_conf(base_folder, cpu_count, revisions_enabled) if servers and len(servers) > 1 and not isinstance( servers, OrderedDict): raise Exception( """Testing framework error: Servers should be an OrderedDict. e.g: servers = OrderedDict() servers["r1"] = server servers["r2"] = TestServer() """) self.servers = servers or {} if servers is not False: # Do not mess with registry remotes self.update_servers() self.init_dynamic_vars() logger.debug("Client storage = %s" % self.storage_folder) self.current_folder = current_folder or temp_folder(path_with_spaces)
def __init__(self, output, build_info_file, lockfile, multi_module=True, skip_env=True, user=None, password=None, apikey=None): self._build_info_file = build_info_file self._lockfile = lockfile self._multi_module = multi_module self._skip_env = skip_env self._user = user self._password = password self._apikey = apikey self._conan_cache = ClientCache(os.path.join(get_conan_user_home(), ".conan"), output)
class CacheTest(unittest.TestCase): def setUp(self): tmp_dir = temp_folder() stream = StringIO() output = ConanOutput(stream) self.cache = ClientCache(tmp_dir, output) self.ref = ConanFileReference.loads("lib/1.0@conan/stable") def test_recipe_exists(self): layout = self.cache.package_layout(self.ref) self.assertFalse(layout.recipe_exists()) mkdir(layout.export()) self.assertTrue(layout.recipe_exists()) # But if ref has revision and it doesn't match, it doesn't exist with layout.update_metadata() as metadata: metadata.clear() ref2 = self.ref.copy_with_rev("revision") layout2 = self.cache.package_layout(ref2) self.assertFalse(layout2.recipe_exists()) # Fake the metadata and check again with layout.update_metadata() as metadata: metadata.recipe.revision = "revision" self.assertTrue(layout2.recipe_exists()) def test_package_exists(self): pref = PackageReference(self.ref, "999") layout = self.cache.package_layout(self.ref) self.assertFalse(layout.package_exists(pref)) mkdir(layout.export()) mkdir(layout.package(pref)) save( os.path.join( self.cache.package_layout(self.ref).package_metadata()), PackageMetadata().dumps()) self.assertTrue(layout.package_exists(pref)) # But if ref has revision and it doesn't match, it doesn't exist ref2 = self.ref.copy_with_rev("revision") pref2 = PackageReference(ref2, "999", "prevision") layout2 = self.cache.package_layout(ref2) self.assertFalse(layout2.package_exists(pref2)) # Fake the metadata and check again with layout2.update_metadata() as metadata: metadata.recipe.revision = "revision" metadata.packages[pref2.id].revision = "prevision" self.assertTrue(layout2.package_exists(pref2))
def test_cache_config(self): cache = ClientCache(temp_folder(), TestBufferConanOutput()) file_path = os.path.join(cache.cache_folder, "whatever_cacert") replace_in_file(cache.conan_conf_path, "# cacert_path", "cacert_path={}".format(file_path), output=TestBufferConanOutput()) save(file_path, "") cache.invalidate() requester = ConanRequester(cache.config) mocked_requester = MockRequesterGet() requester._http_requester = mocked_requester requester.get(url="bbbb", verify=True) self.assertEqual(mocked_requester.verify, file_path)
def is_config_install_scheduled(api): """ Validate if the next config install is scheduled to occur now When config_install_interval is not configured, config install should not run When configs file is empty, scheduled config install should not run When config_install_interval is configured, config install will respect the delta from: last conan install execution (sched file) + config_install_interval value < now :param api: Conan API instance :return: True, if it should occur now. Otherwise, False. """ cache = ClientCache(api.cache_folder, api.out) interval = cache.config.config_install_interval config_install_file = cache.config_install_file if interval is not None: if not os.path.exists(config_install_file): raise ConanException( "config_install_interval defined, but no config_install file") scheduled = _is_scheduled_intervals(config_install_file, interval) if scheduled and not _load_configs(config_install_file): api.out.warn("Skipping scheduled config install, " "no config listed in config_install file") os.utime(config_install_file, None) else: return scheduled
def test_remote_none(self): """ RemoteRegistry should be able to deal when the URL is None """ f = os.path.join(temp_folder(), "add_none_test") Remotes().save(f) cache = ClientCache(os.path.dirname(f), TestBufferConanOutput()) registry = cache.registry registry.add("foobar", None) self.assertEqual( list(registry.load_remotes().values()), [("conancenter", "https://center.conan.io", True, False), ("conan-center", "https://conan.bintray.com", True, False), ("foobar", None, True, False)]) self.assertIn( "WARN: The URL is empty. It must contain scheme and hostname.", cache._output) registry.remove("foobar") registry.update("conan-center", None) self.assertEqual( list(registry.load_remotes().values()), [("conancenter", "https://center.conan.io", True, False), ("conan-center", None, True, False)]) self.assertIn( "WARN: The URL is empty. It must contain scheme and hostname.", cache._output)
def stop_build_info(output): paths = ClientCache(os.path.join(get_conan_user_home(), ".conan"), output) artifact_properties_file = paths.artifacts_properties_path try: save(artifact_properties_file, "") except Exception: raise ConanException("Can't write properties file in %s" % artifact_properties_file)
def insert_test(self): tmp_folder = temp_folder() f = os.path.join(tmp_folder, "remotes.json") save(f, """ { "remotes": [ { "url": "https://server.conan.io", "verify_ssl": true, "name": "conan.io" } ] } """) output = TestBufferConanOutput() cache = ClientCache(tmp_folder, output) registry = RemoteRegistry(cache, output) registry.add("repo1", "url1", True, insert=0) self.assertEqual(list(registry.load_remotes().values()), [Remote("repo1", "url1", True, False), Remote("conan.io", "https://server.conan.io", True, False)]) registry.add("repo2", "url2", True, insert=1) self.assertEqual(list(registry.load_remotes().values()), [Remote("repo1", "url1", True, False), Remote("repo2", "url2", True, False), Remote("conan.io", "https://server.conan.io", True, False)]) registry.add("repo3", "url3", True, insert=5) self.assertEqual(list(registry.load_remotes().values()), [Remote("repo1", "url1", True, False), Remote("repo2", "url2", True, False), Remote("conan.io", "https://server.conan.io", True, False), Remote("repo3", "url3", True, False)])
def enable_disable_remotes_test(self): f = os.path.join(temp_folder(), "aux_file") Remotes().save(f) cache = ClientCache(os.path.dirname(f), TestBufferConanOutput()) registry = cache.registry registry.add("local", "http://localhost:9300") registry.set_disabled_state("local", True) self.assertEqual( list(registry.load_remotes().all_values()), [("conan-center", "https://conan.bintray.com", True, False), ("local", "http://localhost:9300", True, True)]) self.assertEqual( list(registry.load_remotes().values()), [("conan-center", "https://conan.bintray.com", True, False)]) registry.set_disabled_state("conan-center", True) self.assertEqual( list(registry.load_remotes().all_values()), [("conan-center", "https://conan.bintray.com", True, True), ("local", "http://localhost:9300", True, True)]) self.assertEqual(list(registry.load_remotes().values()), []) registry.set_disabled_state("*", False) self.assertEqual( list(registry.load_remotes().values()), [("conan-center", "https://conan.bintray.com", True, False), ("local", "http://localhost:9300", True, False)]) registry.set_disabled_state("*", True) self.assertEqual(list(registry.load_remotes().values()), [])
def check_required_conan_version(cache_folder, out): """ Check if the required Conan version in config file matches to the current Conan version When required_conan_version is not configured, it's skipped When required_conan_version is configured, Conan's version must matches the required version When it doesn't match, an ConanException is raised :param cache_folder: Conan cache folder :param out: Output stream :return: None """ cache = ClientCache(cache_folder, out) required_version = cache.config.required_conan_version if required_version: try: Range(required_version, False) except ValueError: raise ConanException( "The required version expression '{}' is not valid.".format( required_version)) result = satisfies(client_version, required_version) if not result: raise ConanException( "The current Conan version ({}) does not match to the required" " version ({}).".format(client_version, required_version))
def start_build_info(output, build_name, build_number): paths = ClientCache(os.path.join(get_conan_user_home(), ".conan"), output) content = "artifact_property_build.name={}\n" \ "artifact_property_build.number={}\n".format(build_name, build_number) artifact_properties_file = paths.put_headers_path try: save(artifact_properties_file, content) except Exception: raise ConanException("Can't write properties file in %s" % artifact_properties_file)
def start_build_info(output, build_name, build_number): paths = ClientCache(os.path.join(get_conan_user_home(), ".conan"), output) content = ARTIFACTS_PROPERTIES_PUT_PREFIX + "build.name={}\n".format(build_name) + \ ARTIFACTS_PROPERTIES_PUT_PREFIX + "build.number={}\n".format(build_number) artifact_properties_file = paths.artifacts_properties_path try: save(artifact_properties_file, content) except Exception: raise ConanException("Can't write properties file in %s" % artifact_properties_file)
def test_build_info_stop(self, mock_cache): conan_user_home = temp_folder(True) mock_cache.return_value = ClientCache( os.path.join(conan_user_home, ".conan"), TestBufferConanOutput()) sys.argv = ["conan_build_info", "--v2", "stop"] run() with open(mock_cache.return_value.artifacts_properties_path) as f: content = f.read() self.assertEqual("", content)
def retro_compatibility_test(self): folder = temp_folder() f = os.path.join(folder, ".conan", "registry.txt") save(f, "conan.io https://server.conan.io") # Without SSL parameter cache = ClientCache(folder, TestBufferConanOutput()) migrate_registry_file(cache, TestBufferConanOutput()) registry = RemoteRegistry(cache) self.assertEqual(list(registry.load_remotes().values()), [("conan.io", "https://server.conan.io", True)])
def basic_test(self): folder = temp_folder() paths = ClientCache(folder, TestBufferConanOutput()) ref = ConanFileReference.loads("opencv/2.4.10@lasote/testing") pref = PackageReference(ref, "456fa678eae68") expected_base = os.path.join( folder, "data", os.path.sep.join(["opencv", "2.4.10", "lasote", "testing"])) layout = paths.package_layout(ref) self.assertEqual(layout.base_folder(), expected_base) self.assertEqual(layout.export(), os.path.join(expected_base, EXPORT_FOLDER)) self.assertEqual( layout.build(pref), os.path.join(expected_base, BUILD_FOLDER, "456fa678eae68")) self.assertEqual( layout.package(pref), os.path.join(expected_base, PACKAGES_FOLDER, "456fa678eae68"))
def _copy_cache_folder(target_folder): # Some variables affect to cache population (take a different default folder) cache_key = hash(os.environ.get(CONAN_V2_MODE_ENVVAR, None)) master_folder = _copy_cache_folder.master.setdefault(cache_key, temp_folder(create_dir=False)) if not os.path.exists(master_folder): # Create and populate the cache folder with the defaults cache = ClientCache(master_folder, TestBufferConanOutput()) cache.initialize_config() cache.registry.initialize_remotes() cache.initialize_default_profile() cache.initialize_settings() shutil.copytree(master_folder, target_folder)
def test_build_info_start(self, mock_cache): conan_user_home = temp_folder(True) mock_cache.return_value = ClientCache( os.path.join(conan_user_home, ".conan"), TestBufferConanOutput()) sys.argv = ["conan_build_info", "--v2", "start", "MyBuildName", "42"] run() with open(mock_cache.return_value.put_headers_path) as f: content = f.read() self.assertIn("MyBuildName", content) self.assertIn("42", content)
def test_user_agent(self): cache_folder = temp_folder() cache = ClientCache(cache_folder, TestBufferConanOutput()) mock_http_requester = MagicMock() requester = ConanRequester(cache.config, mock_http_requester) requester.get(url="aaa") headers = mock_http_requester.get.call_args[1]["headers"] self.assertIn("Conan/%s" % __version__, headers["User-Agent"]) requester.get(url="aaa", headers={"User-Agent": "MyUserAgent"}) headers = mock_http_requester.get.call_args[1]["headers"] self.assertEqual("MyUserAgent", headers["User-Agent"])
def env_setting_override_test(self): tmp_dir = temp_folder() out = MockOut() cache = ClientCache(tmp_dir, None, out) base_settings = OrderedDict( detect_defaults_settings(out, profile_path="~/.conan/profiles/default")) with tools.environment_append({"CONAN_ENV_COMPILER_VERSION": "4.6"}): expected = copy.copy(base_settings) expected["compiler.version"] = "4.6" self.assertEqual(cache.default_profile.settings, expected) tmp_dir = temp_folder() cache = ClientCache(tmp_dir, None, out) with tools.environment_append({}): self.assertEqual(cache.default_profile.settings, base_settings) tmp_dir = temp_folder() cache = ClientCache(tmp_dir, None, out) # If compiler is overwritten compiler subsettings are not assigned with tools.environment_append({"CONAN_ENV_COMPILER": "Visual Studio"}): expected = copy.copy(base_settings) expected["compiler"] = "Visual Studio" self.assertEqual(cache.default_profile.settings, expected) tmp_dir = temp_folder() cache = ClientCache(tmp_dir, None, out) with tools.environment_append({ "CONAN_ENV_COMPILER": "Visual Studio", "CONAN_ENV_COMPILER_VERSION": "14", "CONAN_ENV_COMPILER_RUNTIME": "MDd" }): expected = copy.copy(base_settings) expected["compiler"] = "Visual Studio" expected["compiler.runtime"] = "MDd" expected["compiler.version"] = "14" self.assertEqual(cache.default_profile.settings, expected)
def init_dynamic_vars(self, user_io=None): # Migration system output = TestBufferConanOutput() self.user_io = user_io or MockedUserIO(self.users, out=output) self.cache = ClientCache(self.base_folder, output) # Migration system migrator = ClientMigrator(self.cache, Version(__version__), output) migrator.migrate() http_requester = self._get_http_requester() config = self.cache.config if self.conan_runner: self.runner = self.conan_runner else: self.runner = ConanRunner(config.print_commands_to_output, config.generate_run_log_file, config.log_run_to_output, output=output) self.requester = ConanRequester(config, http_requester) self.hook_manager = HookManager(self.cache.hooks_path, config.hooks, self.user_io.out) put_headers = self.cache.read_put_headers() self.rest_api_client = RestApiClient( self.user_io.out, self.requester, revisions_enabled=config.revisions_enabled, put_headers=put_headers) # To store user and token self.localdb = LocalDB.create(self.cache.localdb) # Wraps RestApiClient to add authentication support (same interface) auth_manager = ConanApiAuthManager(self.rest_api_client, self.user_io, self.localdb) # Handle remote connections self.remote_manager = RemoteManager(self.cache, auth_manager, self.user_io.out, self.hook_manager) return output, self.requester
def retro_compatibility_test(self): folder = temp_folder() f = os.path.join(folder, "registry.txt") save(f, textwrap.dedent("""conan.io https://server.conan.io pkg/0.1@user/testing some_remote """)) output = TestBufferConanOutput() cache = ClientCache(folder, output) migrate_registry_file(cache, output) registry = RemoteRegistry(cache, output) self.assertEqual(list(registry.load_remotes().values()), [("conan.io", "https://server.conan.io", True, False)])
def test_add_remove_update(self): f = os.path.join(temp_folder(), "aux_file") Remotes().save(f) cache = ClientCache(os.path.dirname(f), TestBufferConanOutput()) registry = cache.registry # Add registry.add("local", "http://localhost:9300") self.assertEqual( list(registry.load_remotes().values()), [("conancenter", "https://center.conan.io", True, False), ("conan-center", "https://conan.bintray.com", True, False), ("local", "http://localhost:9300", True, False)]) # Add registry.add("new", "new_url", False) self.assertEqual( list(registry.load_remotes().values()), [("conancenter", "https://center.conan.io", True, False), ("conan-center", "https://conan.bintray.com", True, False), ("local", "http://localhost:9300", True, False), ("new", "new_url", False, False)]) with self.assertRaises(ConanException): registry.add("new", "new_url") # Update registry.update("new", "other_url") self.assertEqual( list(registry.load_remotes().values()), [("conancenter", "https://center.conan.io", True, False), ("conan-center", "https://conan.bintray.com", True, False), ("local", "http://localhost:9300", True, False), ("new", "other_url", True, False)]) with self.assertRaises(ConanException): registry.update("new2", "new_url") registry.update("new", "other_url", False) self.assertEqual( list(registry.load_remotes().values()), [("conancenter", "https://center.conan.io", True, False), ("conan-center", "https://conan.bintray.com", True, False), ("local", "http://localhost:9300", True, False), ("new", "other_url", False, False)]) # Remove registry.remove("local") self.assertEqual( list(registry.load_remotes().values()), [("conancenter", "https://center.conan.io", True, False), ("conan-center", "https://conan.bintray.com", True, False), ("new", "other_url", False, False)]) with self.assertRaises(ConanException): registry.remove("new2")
def setUp(self): self.output = TestBufferConanOutput() cache_folder = temp_folder() cache = ClientCache(cache_folder, self.output) self.cache = cache self.remote_manager = MockRemoteManager() self.resolver = RangeResolver(cache, self.remote_manager) proxy = ConanProxy(cache, self.output, self.remote_manager) self.loader = ConanFileLoader(None, self.output, ConanPythonRequire(None, None)) self.manager = GraphManager(self.output, cache, self.remote_manager, self.loader, proxy, self.resolver) hook_manager = Mock() recorder = Mock() self.binary_installer = BinaryInstaller(cache, self.output, self.remote_manager, recorder, hook_manager)
def check_required_conan_version(cache_folder, out): """ Check if the required Conan version in config file matches to the current Conan version When required_conan_version is not configured, it's skipped When required_conan_version is configured, Conan's version must matches the required version When it doesn't match, an ConanException is raised :param cache_folder: Conan cache folder :param out: Output stream :return: None """ cache = ClientCache(cache_folder, out) required_range = cache.config.required_conan_version if required_range: validate_conan_version(required_range)
def wrapper(api, *args, **kwargs): try: # getcwd can fail if Conan runs on an unexisting folder old_curdir = os.getcwd() except EnvironmentError: old_curdir = None try: # TODO: Removing ConanApp creation, should we make it different for 2.0? # Also removing the logger call, maybe conan_command can handle it cache = ClientCache(api.cache_folder, api.out) with environment_append(cache.config.env_vars): return f(api, *args, **kwargs) except Exception as exc: msg = exception_message_safe(exc) try: api.out.error("{} ({})".format(str(exc.__class__.__name__), msg)) except BaseException: pass raise finally: if old_curdir: os.chdir(old_curdir)
def _make_migrations(self, old_version): # ############### FILL THIS METHOD WITH THE REQUIRED ACTIONS ############## # VERSION 0.1 if old_version is None: return # Migrate the settings if they were the default for that version cache = ClientCache(self.cache_folder, self.out) self._update_settings_yml(cache, old_version) if old_version < Version("1.0"): _migrate_lock_files(cache, self.out) if old_version < Version("1.12.0"): migrate_plugins_to_hooks(cache) if old_version < Version("1.13.0"): # MIGRATE LOCAL CACHE TO GENERATE MISSING METADATA.json _migrate_create_metadata(cache, self.out) if old_version < Version("1.14.0"): migrate_config_install(cache) if old_version < Version("1.14.2"): _migrate_full_metadata(cache, self.out) if old_version < Version("1.15.0"): migrate_registry_file(cache, self.out) if old_version < Version("1.19.0"): migrate_localdb_refresh_token(cache, self.out) if old_version < Version("1.26.0"): migrate_editables_use_conanfile_name(cache) if old_version < Version("1.31.0"): migrate_tgz_location(cache, self.out) if old_version < Version("1.40.3"): remove_buggy_cacert(cache, self.out)
def is_config_install_scheduled(api): """ Validate if the next config install is scheduled to occur now When config_install_interval is not configured, config install should not run When config_install_interval is configured, config install will respect the delta from: last conan install execution (sched file) + config_install_interval value < now :param api: Conan API instance :return: True, if it should occur now. Otherwise, False. """ cache = ClientCache(api.cache_folder, api.out) interval = cache.config.config_install_interval config_install_file = cache.config_install_file if interval is not None: if os.path.exists(config_install_file): timestamp = os.path.getmtime(config_install_file) sched = datetime.fromtimestamp(timestamp, tz=gettz()) sched += interval now = datetime.now(gettz()) return now > sched else: raise ConanException("config_install_interval defined, but no config_install file")