コード例 #1
0
ファイル: tools.py プロジェクト: lachlankrautz/conan
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)
コード例 #2
0
ファイル: tools.py プロジェクト: niosHD/conan
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)