Example #1
0
 def setUp(self):
     self.conan_reference = ConanFileReference.loads("openssl/2.0.3@lasote/testing")
     self.package_reference = PackageReference(self.conan_reference, "123123123")
     self.remote_client = MockRemoteClient()
     self.output = TestBufferConanOutput()
     self.client_cache = ClientCache(temp_folder(), temp_folder(), self.output)
     self.remotes = [("default", "url1"), ("other", "url2"), ("last", "url3")]
     self.manager = RemoteManager(self.client_cache, self.remote_client, self.output)
Example #2
0
    def __init__(self,
                 base_folder=None,
                 current_folder=None,
                 servers=None,
                 users=None,
                 client_version=CLIENT_VERSION,
                 min_server_compatible_version=MIN_SERVER_COMPATIBLE_VERSION,
                 requester_class=None,
                 runner=None,
                 path_with_spaces=True):
        """
        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 or {
            "default":
            [(TESTING_REMOTE_PRIVATE_USER, TESTING_REMOTE_PRIVATE_PASS)]
        }
        self.servers = servers or {}

        self.client_version = Version(str(client_version))
        self.min_server_compatible_version = Version(
            str(min_server_compatible_version))

        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.client_cache = ClientCache(self.base_folder, self.storage_folder,
                                        TestBufferConanOutput())

        search_adapter = DiskSearchAdapter()
        self.search_manager = DiskSearchManager(self.client_cache,
                                                search_adapter)

        self._default_settings(get_env("CONAN_COMPILER", "gcc"),
                               get_env("CONAN_COMPILER_VERSION", "4.8"),
                               get_env("CONAN_LIBCXX", "libstdc++"))

        self.requester_class = requester_class
        self.conan_runner = runner

        self.init_dynamic_vars()

        save(self.client_cache.registry, "")
        registry = RemoteRegistry(self.client_cache.registry,
                                  TestBufferConanOutput())
        for name, server in self.servers.items():
            if isinstance(server, TestServer):
                registry.add(name, server.fake_url)
            else:
                registry.add(name, server)

        logger.debug("Client storage = %s" % self.storage_folder)
        self.current_folder = current_folder or temp_folder(path_with_spaces)
Example #3
0
def migrate_and_get_client_cache(base_folder, out, manager, storage_folder=None):
    # Init paths
    client_cache = ClientCache(base_folder, storage_folder, out)

    # Migration system
    migrator = ClientMigrator(client_cache, Version(CLIENT_VERSION), out, manager)
    migrator.migrate()

    # Init again paths, migration could change config
    client_cache = ClientCache(base_folder, storage_folder, out)
    return client_cache
Example #4
0
    def __init__(self,
                 base_folder=None,
                 current_folder=None,
                 servers=None,
                 users=None,
                 client_version=CLIENT_VERSION,
                 min_server_compatible_version=MIN_SERVER_COMPATIBLE_VERSION,
                 requester_class=None,
                 runner=None,
                 path_with_spaces=True,
                 default_profile=True):
        """
        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 or {
            "default":
            [(TESTING_REMOTE_PRIVATE_USER, TESTING_REMOTE_PRIVATE_PASS)]
        }

        self.client_version = Version(str(client_version))
        self.min_server_compatible_version = Version(
            str(min_server_compatible_version))

        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.client_cache = ClientCache(self.base_folder, self.storage_folder,
                                        TestBufferConanOutput())

        search_adapter = DiskSearchAdapter()
        self.search_manager = DiskSearchManager(self.client_cache,
                                                search_adapter)

        self.requester_class = requester_class
        self.conan_runner = runner

        self.update_servers(servers)
        self.init_dynamic_vars()

        logger.debug("Client storage = %s" % self.storage_folder)
        self.current_folder = current_folder or temp_folder(path_with_spaces)

        # Enforcing VS 2015, even if VS2017 is auto detected
        if default_profile:
            profile = self.client_cache.default_profile
            if profile.settings.get("compiler.version") == "15":
                profile.settings["compiler.version"] = "14"
                save(self.client_cache.default_profile_path, profile.dumps())
Example #5
0
class RemoteManagerTest(unittest.TestCase):
    """Unit test"""
    def setUp(self):
        self.conan_reference = ConanFileReference.loads(
            "openssl/2.0.3@lasote/testing")
        self.package_reference = PackageReference(self.conan_reference,
                                                  "123123123")
        self.remote_client = MockRemoteClient()
        self.output = TestBufferConanOutput()
        self.client_cache = ClientCache(temp_folder(), temp_folder(),
                                        self.output)
        self.manager = RemoteManager(self.client_cache, self.remote_client,
                                     self.output)

    def test_no_remotes(self):
        client = TestClient()
        files = cpp_hello_conan_files("Hello0", "0.1")
        client.save(files)
        client.run("export lasote/stable")
        client.run("upload Hello0/0.1@lasote/stable", ignore_error=True)
        self.assertIn("ERROR: No default remote defined", client.user_io.out)

    def method_called_test(self):

        save(
            os.path.join(self.client_cache.package(self.package_reference),
                         CONANINFO), "asdasd")
        manifest = FileTreeManifest.create(
            self.client_cache.package(self.package_reference))
        save(
            os.path.join(self.client_cache.package(self.package_reference),
                         CONAN_MANIFEST), str(manifest))

        self.assertFalse(self.remote_client.upload_package.called)
        self.manager.upload_package(self.package_reference,
                                    Remote("other", "url", True), 1, 0)
        self.assertTrue(self.remote_client.upload_package.called)

        self.assertFalse(self.remote_client.get_conan_digest.called)
        self.manager.get_conan_digest(self.conan_reference,
                                      Remote("other", "url", True))
        self.assertTrue(self.remote_client.get_conan_digest.called)

        self.assertFalse(self.remote_client.get_recipe.called)
        self.manager.get_recipe(self.conan_reference, temp_folder(),
                                Remote("other", "url", True))
        self.assertTrue(self.remote_client.get_recipe.called)

        self.assertFalse(self.remote_client.get_package.called)
        self.manager.get_package(self.package_reference, temp_folder(),
                                 Remote("other", "url", True))
        self.assertTrue(self.remote_client.get_package.called)
Example #6
0
class RemoteManagerTest(unittest.TestCase):
    """Unit test"""

    def setUp(self):
        self.conan_reference = ConanFileReference.loads("openssl/2.0.3@lasote/testing")
        self.package_reference = PackageReference(self.conan_reference, "123123123")
        self.remote_client = MockRemoteClient()
        self.output = TestBufferConanOutput()
        self.client_cache = ClientCache(temp_folder(), temp_folder(), self.output)
        self.remotes = [("default", "url1"), ("other", "url2"), ("last", "url3")]
        self.manager = RemoteManager(self.client_cache, self.remote_client, self.output)

    def test_no_remotes(self):
        client = TestClient()
        files = cpp_hello_conan_files("Hello0", "0.1")
        client.save(files)
        client.run("export lasote/stable")
        client.run("upload Hello0/0.1@lasote/stable", ignore_error=True)
        self.assertIn("ERROR: No default remote defined", client.user_io.out)

    def remote_selection_test(self):
        save(os.path.join(self.client_cache.export(self.conan_reference), CONANFILE), "asdasd")
        save(os.path.join(self.client_cache.export(self.conan_reference), CONAN_MANIFEST), "asdasd")

        # If no remote is specified will look to first
        self.assertRaises(NotFoundException, self.manager.upload_conan, self.conan_reference, None)

        # If remote is specified took it
        self.assertRaises(NotFoundException,
                          self.manager.upload_conan, self.conan_reference, Remote("other", "url"))

    def method_called_test(self):

        save(os.path.join(self.client_cache.package(self.package_reference), CONANINFO), "asdasd")
        manifest = FileTreeManifest.create(self.client_cache.package(self.package_reference))
        save(os.path.join(self.client_cache.package(self.package_reference), CONAN_MANIFEST), str(manifest))

        self.assertFalse(self.remote_client.upload_package.called)
        self.manager.upload_package(self.package_reference, Remote("other", "url"))
        self.assertTrue(self.remote_client.upload_package.called)

        self.assertFalse(self.remote_client.get_conan_digest.called)
        self.manager.get_conan_digest(self.conan_reference, Remote("other", "url"))
        self.assertTrue(self.remote_client.get_conan_digest.called)

        self.assertFalse(self.remote_client.get_recipe.called)
        self.manager.get_recipe(self.conan_reference, temp_folder(), Remote("other", "url"))
        self.assertTrue(self.remote_client.get_recipe.called)

        self.assertFalse(self.remote_client.get_package.called)
        self.manager.get_package(self.package_reference, temp_folder(), Remote("other", "url"))
        self.assertTrue(self.remote_client.get_package.called)
Example #7
0
    def _init_collaborators(self, user_io=None):

        output = TestBufferConanOutput()
        self.user_io = user_io or MockedUserIO(self.users, out=output)
        self.client_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):  # Just URI
                real_servers = True

        with tools.environment_append(self.client_cache.conan_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.client_cache,
                                            get_request_timeout())

            self.hook_manager = HookManager(self.client_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.client_cache, self.user_io,
                self.client_version, self.min_server_compatible_version,
                self.hook_manager)
            set_global_instances(output, self.requester)
Example #8
0
 def setUp(self):
     self.conan_reference = ConanFileReference.loads("openssl/2.0.3@lasote/testing")
     self.package_reference = PackageReference(self.conan_reference, "123123123")
     self.remote_client = MockRemoteClient()
     self.output = TestBufferConanOutput()
     self.client_cache = ClientCache(temp_folder(), temp_folder(), self.output)
     self.manager = RemoteManager(self.client_cache, self.remote_client, self.output)
Example #9
0
def get_command():
    def instance_remote_manager(client_cache):
        requester = requests.Session()
        requester.proxies = client_cache.conan_config.proxies
        # Verify client version against remotes
        version_checker_requester = VersionCheckerRequester(
            requester, Version(CLIENT_VERSION),
            Version(MIN_SERVER_COMPATIBLE_VERSION), out)
        # To handle remote connections
        rest_api_client = RestApiClient(out,
                                        requester=version_checker_requester)
        # To store user and token
        localdb = LocalDB(client_cache.localdb)
        # Wraps RestApiClient to add authentication support (same interface)
        auth_manager = ConanApiAuthManager(rest_api_client, user_io, localdb)
        # Handle remote connections
        remote_manager = RemoteManager(client_cache, auth_manager, out)
        return remote_manager

    use_color = get_env("CONAN_COLOR_DISPLAY", 1)
    if use_color and hasattr(sys.stdout, "isatty") and sys.stdout.isatty():
        import colorama
        colorama.init()
        color = True
    else:
        color = False
    out = ConanOutput(sys.stdout, color)
    user_io = UserIO(out=out)

    user_folder = os.getenv("CONAN_USER_HOME", conan_expand_user("~"))

    try:
        # To capture exceptions in conan.conf parsing
        client_cache = ClientCache(user_folder, None, out)
        # obtain a temp ConanManager instance to execute the migrations
        remote_manager = instance_remote_manager(client_cache)

        # Get a DiskSearchManager
        search_adapter = DiskSearchAdapter()
        search_manager = DiskSearchManager(client_cache, search_adapter)
        manager = ConanManager(client_cache, user_io, ConanRunner(),
                               remote_manager, search_manager)

        client_cache = migrate_and_get_client_cache(user_folder, out, manager)
    except Exception as e:
        out.error(str(e))
        sys.exit(True)

    # Get the new command instance after migrations have been done
    remote_manager = instance_remote_manager(client_cache)

    # Get a search manager
    search_adapter = DiskSearchAdapter()
    search_manager = DiskSearchManager(client_cache, search_adapter)
    command = Command(client_cache, user_io, ConanRunner(), remote_manager,
                      search_manager)
    return command
Example #10
0
def migrate_and_get_client_cache(base_folder, out, storage_folder=None):
    # Init paths
    client_cache = ClientCache(base_folder, storage_folder, out)

    # Migration system
    migrator = ClientMigrator(client_cache, Version(client_version), out)
    migrator.migrate()

    return client_cache
Example #11
0
    def __init__(self,
                 base_folder=None,
                 current_folder=None,
                 servers=None,
                 users=None,
                 client_version=CLIENT_VERSION,
                 min_server_compatible_version=MIN_SERVER_COMPATIBLE_VERSION,
                 requester_class=None,
                 runner=None,
                 path_with_spaces=True):
        """
        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 or {
            "default":
            [(TESTING_REMOTE_PRIVATE_USER, TESTING_REMOTE_PRIVATE_PASS)]
        }

        self.client_version = Version(str(client_version))
        self.min_server_compatible_version = Version(
            str(min_server_compatible_version))

        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.client_cache = ClientCache(self.base_folder, self.storage_folder,
                                        TestBufferConanOutput())

        self.requester_class = requester_class
        self.conan_runner = runner

        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)
Example #12
0
    def conan_compiler_info(self):
        """return the compiler and its version readed in conan.conf"""
        out = ConanOutput(sys.stdout)
        cache = ClientCache(os.environ.get("CONAN_USER_HOME", "~/"), None, out)

        if hasattr(cache, "default_profile"):
            profile = cache.default_profile
            settings = profile.settings
        else:
            settings = dict(cache.conan_config.get_conf("settings_defaults"))

        return settings["compiler"], settings["compiler.version"]
    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))

        with tools.environment_append({"CONAN_ENV_COMPILER_VERSION": "4.6"}):
            expected = copy.copy(base_settings)
            expected["compiler.version"] = "4.6"
            self.assertEquals(cache.default_profile.settings, expected)

        tmp_dir = temp_folder()
        cache = ClientCache(tmp_dir, None, out)
        with tools.environment_append({}):
            self.assertEquals(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.assertEquals(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.assertEquals(cache.default_profile.settings, expected)
Example #14
0
 def setUp(self):
     folder = temp_folder()
     self.paths = ClientCache(folder,
                              store_folder=folder,
                              output=TestBufferConanOutput())
Example #15
0
class TestClient(object):
    """ Test wrap of the conans application to launch tests in the same way as
    in command line
    """
    def __init__(self,
                 base_folder=None,
                 current_folder=None,
                 servers=None,
                 users=None,
                 client_version=CLIENT_VERSION,
                 min_server_compatible_version=MIN_SERVER_COMPATIBLE_VERSION,
                 requester_class=None,
                 runner=None,
                 path_with_spaces=True,
                 default_profile=True):
        """
        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 or {
            "default":
            [(TESTING_REMOTE_PRIVATE_USER, TESTING_REMOTE_PRIVATE_PASS)]
        }

        self.client_version = Version(str(client_version))
        self.min_server_compatible_version = Version(
            str(min_server_compatible_version))

        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.client_cache = ClientCache(self.base_folder, self.storage_folder,
                                        TestBufferConanOutput())

        search_adapter = DiskSearchAdapter()
        self.search_manager = DiskSearchManager(self.client_cache,
                                                search_adapter)

        self.requester_class = requester_class
        self.conan_runner = runner

        self.update_servers(servers)
        self.init_dynamic_vars()

        logger.debug("Client storage = %s" % self.storage_folder)
        self.current_folder = current_folder or temp_folder(path_with_spaces)

        # Enforcing VS 2015, even if VS2017 is auto detected
        if default_profile:
            profile = self.client_cache.default_profile
        #     if profile.settings.get("compiler.version") == "15":
        #         profile.settings["compiler.version"] = "14"
        #         save(self.client_cache.default_profile_path, profile.dumps())

    def update_servers(self, servers):
        self.servers = servers or {}
        save(self.client_cache.registry, "")
        registry = RemoteRegistry(self.client_cache.registry,
                                  TestBufferConanOutput())
        for name, server in self.servers.items():
            if isinstance(server, TestServer):
                registry.add(name, server.fake_url)
            else:
                registry.add(name, server)

    @property
    def paths(self):
        return self.client_cache

    @property
    def default_compiler_visual_studio(self):
        settings = self.client_cache.default_profile.settings
        return settings.get("compiler", None) == "Visual Studio"

    @property
    def out(self):
        return self.user_io.out

    @contextmanager
    def chdir(self, newdir):
        old_dir = self.current_folder
        if not os.path.isabs(newdir):
            newdir = os.path.join(old_dir, newdir)
        mkdir(newdir)
        self.current_folder = newdir
        try:
            yield
        finally:
            self.current_folder = old_dir

    def _init_collaborators(self, user_io=None):

        output = TestBufferConanOutput()
        self.user_io = user_io or MockedUserIO(self.users, out=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):  # Just URI
                real_servers = True

        if real_servers:
            requester = requests
        else:
            if self.requester_class:
                requester = self.requester_class(self.servers)
            else:
                requester = TestRequester(self.servers)

        # Verify client version against remotes
        self.requester = VersionCheckerRequester(
            requester, self.client_version, self.min_server_compatible_version,
            output)

        put_headers = self.client_cache.read_put_headers()
        self.rest_api_client = RestApiClient(output,
                                             requester=self.requester,
                                             put_headers=put_headers)
        # To store user and token
        self.localdb = LocalDB(self.client_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.client_cache, auth_manager,
                                            self.user_io.out)

        set_global_instances(output, self.requester)

    def init_dynamic_vars(self, user_io=None):
        # Migration system
        self.client_cache = migrate_and_get_client_cache(
            self.base_folder,
            TestBufferConanOutput(),
            storage_folder=self.storage_folder)

        # Maybe something have changed with migrations
        self._init_collaborators(user_io)

    def run(self, command_line, user_io=None, ignore_error=False):
        """ run a single command as in the command line.
            If user or password is filled, user_io will be mocked to return this
            tuple if required
        """
        self.init_dynamic_vars(user_io)
        conan = Conan(self.client_cache, self.user_io, self.runner,
                      self.remote_manager, self.search_manager,
                      settings_preprocessor)
        outputer = CommandOutputer(self.user_io, self.client_cache)
        command = Command(conan, self.client_cache, self.user_io, outputer)
        args = shlex.split(command_line)
        current_dir = os.getcwd()
        os.chdir(self.current_folder)
        old_path = sys.path[:]
        sys.path.append(os.path.join(self.client_cache.conan_folder, "python"))
        old_modules = list(sys.modules.keys())
        try:
            error = command.run(args)
        finally:
            sys.path = old_path
            os.chdir(current_dir)
            # Reset sys.modules to its prev state. A .copy() DOES NOT WORK
            added_modules = set(sys.modules).difference(old_modules)
            for added in added_modules:
                sys.modules.pop(added, None)

        if not ignore_error and error:
            logger.error(self.user_io.out)
            print(self.user_io.out)
            raise Exception("Command failed:\n%s" % command_line)

        self.all_output += str(self.user_io.out)
        return error

    def save(self, files, path=None, clean_first=False):
        """ helper metod, will store files in the current folder
        param files: dict{filename: filecontents}
        """
        path = path or self.current_folder
        if clean_first:
            shutil.rmtree(self.current_folder, ignore_errors=True)
        save_files(path, files)
        if not files:
            mkdir(self.current_folder)
Example #16
0
class TestClient(object):

    """ Test wrap of the conans application to launch tests in the same way as
    in command line
    """

    def __init__(self, base_folder=None, current_folder=None,
                 servers=None, users=None, client_version=CLIENT_VERSION,
                 min_server_compatible_version=MIN_SERVER_COMPATIBLE_VERSION,
                 requester_class=None, runner=None, path_with_spaces=True):
        """
        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 or {"default":
                               [(TESTING_REMOTE_PRIVATE_USER, TESTING_REMOTE_PRIVATE_PASS)]}
        self.servers = servers or {}

        self.client_version = Version(str(client_version))
        self.min_server_compatible_version = Version(str(min_server_compatible_version))

        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.client_cache = ClientCache(self.base_folder, self.storage_folder, TestBufferConanOutput())

        search_adapter = DiskSearchAdapter()
        self.search_manager = DiskSearchManager(self.client_cache, search_adapter)

        self._default_settings(get_env("CONAN_COMPILER", "gcc"),
                               get_env("CONAN_COMPILER_VERSION", "4.8"),
                               get_env("CONAN_LIBCXX", "libstdc++"))

        self.requester_class = requester_class
        self.conan_runner = runner

        self.init_dynamic_vars()

        save(self.client_cache.registry, "")
        registry = RemoteRegistry(self.client_cache.registry, TestBufferConanOutput())
        for name, server in self.servers.items():
            if isinstance(server, TestServer):
                registry.add(name, server.fake_url)
            else:
                registry.add(name, server)

        logger.debug("Client storage = %s" % self.storage_folder)
        self.current_folder = current_folder or temp_folder(path_with_spaces)

    @property
    def paths(self):
        return self.client_cache

    def _default_settings(self, compiler, compiler_version, libcxx):
        """ allows to change the default settings in the file, to change compiler, version
        """
        # Set default settings in global defined
        self.client_cache.conan_config  # For create the default file if not existing
        text = load(self.client_cache.conan_conf_path)
        # prevent TestClient instances with reused paths to write again the compiler
        if compiler != "Visual Studio":
            text = text.replace("compiler.runtime=MD", "")
        if "compiler=" not in text:
            # text = text.replace("build_type=Release", "")

            text += "\ncompiler=%s" % compiler
            text += "\ncompiler.version=%s" % compiler_version
            if compiler != "Visual Studio":
                text += "\ncompiler.libcxx=%s" % libcxx
            save(self.client_cache.conan_conf_path, text)

    @property
    def default_compiler_visual_studio(self):
        text = load(self.client_cache.conan_conf_path)
        return "compiler=Visual Studio" in text

    def _init_collaborators(self, user_io=None):

        output = TestBufferConanOutput()
        self.user_io = user_io or MockedUserIO(self.users, out=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):  # Just URI
                real_servers = True

        if real_servers:
            requester = requests
        else:
            if self.requester_class:
                requester = self.requester_class(self.servers)
            else:
                requester = TestRequester(self.servers)

        # Verify client version against remotes
        self.requester = VersionCheckerRequester(requester, self.client_version,
                                                 self.min_server_compatible_version, output)

        put_headers = self.client_cache.read_put_headers()
        self.rest_api_client = RestApiClient(output, requester=self.requester, put_headers=put_headers)
        # To store user and token
        self.localdb = LocalDB(self.client_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.client_cache, auth_manager, self.user_io.out)

    def init_dynamic_vars(self, user_io=None):
        # Migration system
        self.client_cache = migrate_and_get_client_cache(self.base_folder, TestBufferConanOutput(),
                                                         storage_folder=self.storage_folder)

        # Maybe something have changed with migrations
        self._init_collaborators(user_io)

    def run(self, command_line, user_io=None, ignore_error=False):
        """ run a single command as in the command line.
            If user or password is filled, user_io will be mocked to return this
            tuple if required
        """
        self.init_dynamic_vars(user_io)

        command = Command(self.client_cache, self.user_io, self.runner, self.remote_manager, self.search_manager)
        args = shlex.split(command_line)
        current_dir = os.getcwd()
        os.chdir(self.current_folder)

        old_modules = list(sys.modules.keys())
        try:
            error = command.run(args)
        finally:
            os.chdir(current_dir)
            # Reset sys.modules to its prev state. A .copy() DOES NOT WORK
            added_modules = set(sys.modules).difference(old_modules)
            for added in added_modules:
                sys.modules.pop(added, None)

        if not ignore_error and error:
            logger.error(self.user_io.out)
            raise Exception("Command failed:\n%s" % command_line)

        self.all_output += str(self.user_io.out)
        return error

    def save(self, files, path=None, clean_first=False):
        """ helper metod, will store files in the current folder
        param files: dict{filename: filecontents}
        """
        path = path or self.current_folder
        if clean_first:
            shutil.rmtree(self.current_folder, ignore_errors=True)
        save_files(path, files)
Example #17
0
    def __init__(self,
                 base_folder=None,
                 current_folder=None,
                 servers=None,
                 users=None,
                 client_version=CLIENT_VERSION,
                 min_server_compatible_version=MIN_SERVER_COMPATIBLE_VERSION,
                 requester_class=None,
                 runner=None,
                 path_with_spaces=True,
                 block_v2=None,
                 revisions=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.block_v2 = block_v2 or get_env("CONAN_API_V2_BLOCKED", True)

        if self.block_v2:
            self.revisions = False
        else:
            self.revisions = revisions or get_env(
                "CONAN_CLIENT_REVISIONS_ENABLED", False)
            self.block_v2 = False

        self.all_output = ""  # For debugging purpose, append all the run outputs
        self.users = users or {
            "default":
            [(TESTING_REMOTE_PRIVATE_USER, TESTING_REMOTE_PRIVATE_PASS)]
        }

        self.client_version = Version(str(client_version))
        self.min_server_compatible_version = Version(
            str(min_server_compatible_version))

        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.client_cache = ClientCache(self.base_folder, self.storage_folder,
                                        TestBufferConanOutput())

        self.requester_class = requester_class
        self.conan_runner = runner

        if cpu_count:
            self.client_cache.conan_config
            replace_in_file(os.path.join(self.client_cache.conan_conf_path),
                            "# cpu_count = 1",
                            "cpu_count = %s" % cpu_count,
                            output=TestBufferConanOutput())
            # Invalidate the cached config
            self.client_cache.invalidate()
        if self.revisions:
            # Generate base file
            self.client_cache.conan_config
            replace_in_file(os.path.join(self.client_cache.conan_conf_path),
                            "revisions_enabled = False",
                            "revisions_enabled = True",
                            strict=False)
            # Invalidate the cached config
            self.client_cache.invalidate()

        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)
Example #18
0
class TestClient(object):
    """ Test wrap of the conans application to launch tests in the same way as
    in command line
    """
    def __init__(self,
                 base_folder=None,
                 current_folder=None,
                 servers=None,
                 users=None,
                 client_version=CLIENT_VERSION,
                 min_server_compatible_version=MIN_SERVER_COMPATIBLE_VERSION,
                 requester_class=None,
                 runner=None,
                 path_with_spaces=True,
                 block_v2=None,
                 revisions=None):
        """
        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.block_v2 = block_v2 or get_env("CONAN_API_V2_BLOCKED", True)

        if self.block_v2:
            self.revisions = False
        else:
            self.revisions = revisions or get_env(
                "CONAN_CLIENT_REVISIONS_ENABLED", False)
            self.block_v2 = False

        self.all_output = ""  # For debugging purpose, append all the run outputs
        self.users = users or {
            "default":
            [(TESTING_REMOTE_PRIVATE_USER, TESTING_REMOTE_PRIVATE_PASS)]
        }

        self.client_version = Version(str(client_version))
        self.min_server_compatible_version = Version(
            str(min_server_compatible_version))

        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.client_cache = ClientCache(self.base_folder, self.storage_folder,
                                        TestBufferConanOutput())

        self.requester_class = requester_class
        self.conan_runner = runner

        if self.revisions:
            # Generate base file
            self.client_cache.conan_config
            replace_in_file(os.path.join(self.client_cache.conan_conf_path),
                            "revisions_enabled = False",
                            "revisions_enabled = True",
                            strict=False)
            # Invalidate the cached config
            self.client_cache.invalidate()

        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 update_servers(self):

        save(self.client_cache.registry, dump_registry({}, {}, {}))

        registry = RemoteRegistry(self.client_cache.registry,
                                  TestBufferConanOutput())

        def add_server_to_registry(name, server):
            if isinstance(server, TestServer):
                registry.remotes.add(name, server.fake_url)
            else:
                registry.remotes.add(name, server)

        for name, server in self.servers.items():
            if name == "default":
                add_server_to_registry(name, server)

        for name, server in self.servers.items():
            if name != "default":
                add_server_to_registry(name, server)

    @property
    def remote_registry(self):
        return RemoteRegistry(self.client_cache.registry,
                              TestBufferConanOutput())

    @property
    def paths(self):
        return self.client_cache

    @property
    def default_compiler_visual_studio(self):
        settings = self.client_cache.default_profile.settings
        return settings.get("compiler", None) == "Visual Studio"

    @property
    def out(self):
        return self.user_io.out

    @contextmanager
    def chdir(self, newdir):
        old_dir = self.current_folder
        if not os.path.isabs(newdir):
            newdir = os.path.join(old_dir, newdir)
        mkdir(newdir)
        self.current_folder = newdir
        try:
            yield
        finally:
            self.current_folder = old_dir

    def _init_collaborators(self, user_io=None):

        output = TestBufferConanOutput()
        self.user_io = user_io or MockedUserIO(self.users, out=output)
        self.client_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):  # Just URI
                real_servers = True

        with tools.environment_append(self.client_cache.conan_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.client_cache,
                                            get_request_timeout())

            self.hook_manager = HookManager(self.client_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.client_cache, self.user_io,
                self.client_version, self.min_server_compatible_version,
                self.hook_manager)
            self.rest_api_client.block_v2 = self.block_v2
            return output, self.requester

    def init_dynamic_vars(self, user_io=None):
        # Migration system
        self.client_cache = migrate_and_get_client_cache(
            self.base_folder,
            TestBufferConanOutput(),
            storage_folder=self.storage_folder)

        # Maybe something have changed with migrations
        return self._init_collaborators(user_io)

    def run(self,
            command_line,
            user_io=None,
            ignore_error=False,
            should_error=False):
        """ run a single command as in the command line.
            If user or password is filled, user_io will be mocked to return this
            tuple if required
        """
        output, requester = self.init_dynamic_vars(user_io)
        with tools.environment_append(self.client_cache.conan_config.env_vars):
            # Settings preprocessor
            interactive = not get_env("CONAN_NON_INTERACTIVE", False)
            conan = Conan(self.client_cache,
                          self.user_io,
                          self.runner,
                          self.remote_manager,
                          self.hook_manager,
                          interactive=interactive)
        outputer = CommandOutputer(self.user_io, self.client_cache)
        command = Command(conan, self.client_cache, self.user_io, outputer)
        args = shlex.split(command_line)
        current_dir = os.getcwd()
        os.chdir(self.current_folder)
        old_path = sys.path[:]
        sys.path.append(os.path.join(self.client_cache.conan_folder, "python"))
        old_modules = list(sys.modules.keys())

        old_output, old_requester = set_global_instances(output, requester)
        try:
            error = command.run(args)
        finally:
            set_global_instances(old_output, old_requester)
            sys.path = old_path
            os.chdir(current_dir)
            # Reset sys.modules to its prev state. A .copy() DOES NOT WORK
            added_modules = set(sys.modules).difference(old_modules)
            for added in added_modules:
                sys.modules.pop(added, None)

        if not ignore_error and error and not should_error:
            exc_message = "\n{command_header}\n{command}\n{output_header}\n{output}\n{output_footer}\n".format(
                command_header='{:-^80}'.format(" Command failed: "),
                output_header='{:-^80}'.format(" Output: "),
                output_footer='-' * 80,
                command=command_line,
                output=self.user_io.out)
            raise Exception(exc_message)

        if should_error and not error:
            raise Exception("This command should have failed: %s" %
                            command_line)

        self.all_output += str(self.user_io.out)
        return error

    def save(self, files, path=None, clean_first=False):
        """ helper metod, will store files in the current folder
        param files: dict{filename: filecontents}
        """
        path = path or self.current_folder
        if clean_first:
            shutil.rmtree(self.current_folder, ignore_errors=True)
        save_files(path, files)
        if not files:
            mkdir(self.current_folder)

    def get_revision(self, conan_ref):
        return self.client_cache.load_metadata(conan_ref).recipe.revision

    def get_package_revision(self, package_ref):
        metadata = self.client_cache.load_metadata(package_ref.conan)
        return metadata.packages[package_ref.package_id].revision