示例#1
0
    def create(self):
        """Create a pool with dmg.

        To use dmg, the test needs to set dmg_command through the constructor.
        For example,

            self.pool = TestPool(self.context, DmgCommand(self.bin))

        If it wants to use --nsvc option, it needs to set the value to
        svcn.value. Otherwise, 1 is used. If it wants to use --group, it needs
        to set groupname.value. If it wants to use --user, it needs to set
        username.value. If it wants to add other options, directly set it
        to self.dmg.action_command. Refer dmg_utils.py pool_create method for
        more details.

        To test the negative case on create, the test needs to catch
        CommandFailure. Thus, we need to make more than one line modification
        to the test only for this purpose.
        Currently, pool_svc is the only test that needs this change.
        """
        self.destroy()
        if self.target_list.value is not None:
            self.log.info(
                "Creating a pool on targets %s", self.target_list.value)
        else:
            self.log.info("Creating a pool")

        self.pool = DaosPool(self.context)

        kwargs = {
            "uid": self.uid,
            "gid": self.gid,
            "size": self.size.value,
            "tier_ratio": self.tier_ratio.value,
            "scm_size": self.scm_size.value,
            "nranks": self.nranks.value,
            "properties": self.properties.value,
            "acl_file": self.acl_file.value,
            "label": self.label.value
        }
        for key in ("target_list", "svcn", "nvme_size"):
            value = getattr(self, key).value
            if value is not None:
                kwargs[key] = value

        # Create a pool with the dmg command and store its CmdResult
        self._log_method("dmg.pool_create", kwargs)
        data = self.dmg.pool_create(**kwargs)

        if self.dmg.result.exit_status == 0:
            # Convert the string of service replicas from the dmg command
            # output into an ctype array for the DaosPool object using the
            # same technique used in DaosPool.create().
            service_replicas = [
                int(value) for value in data["svc"].split(",")]
            rank_t = ctypes.c_uint * len(service_replicas)
            rank = rank_t(*service_replicas)
            rl_ranks = ctypes.POINTER(ctypes.c_uint)(rank)
            self.pool.svc = daos_cref.RankList(
                rl_ranks, len(service_replicas))

            # Set UUID and attached to the DaosPool object
            self.uuid = data["uuid"]
            self.pool.attached = 1

        # Set the TestPool attributes for the created pool
        if self.pool.attached:
            self.svc_ranks = [
                int(self.pool.svc.rl_ranks[index])
                for index in range(self.pool.svc.rl_nr)]
示例#2
0
    def create(self):
        """Create a pool with either API or dmg.

        To use dmg, the test needs to set control_method.value to USE_DMG
        prior to calling this method. The recommended way is to specify the
        pool block in yaml. For example,

        pool:
            control_method: dmg

        This tells this method to use dmg. The test also needs to set
        dmg_bin_path through the constructor if dmg is used. For example,

        self.pool = TestPool(self.context,
                             dmg_bin_path=self.basepath + '/install/bin')

        If it wants to use --nsvc option, it needs to set the value to
        svcn.value. Otherwise, 1 is used. If it wants to use --group, it needs
        to set groupname.value. If it wants to use --user, it needs to set
        username.value. If it wants to add other options, directly set it
        to self.dmg.action_command. Refer dmg_utils.py pool_create method for
        more details.

        To test the negative case on create, the test needs to catch
        CommandFailure for dmg and DaosApiError for API. Thus, we need to make
        more than one line modification to the test only for this purpose.
        Currently, pool_svc is the only test that needs this change.
        """
        self.destroy()
        if self.target_list.value is not None:
            self.log.info(
                "Creating a pool on targets %s", self.target_list.value)
        else:
            self.log.info("Creating a pool")
        self.pool = DaosPool(self.context)
        if self.control_method.value == self.USE_API:
            kwargs = {
                "mode": self.mode.value, "uid": self.uid, "gid": self.gid,
                "scm_size": self.scm_size.value, "group": self.name.value}
            for key in ("target_list", "svcn", "nvme_size"):
                value = getattr(self, key).value
                if value is not None:
                    kwargs[key] = value
            self._call_method(self.pool.create, kwargs)
        else:
            if self.dmg is None:
                raise DaosTestError(
                    "self.dmg is None. dmg_command needs to be set through "
                    "the constructor of TestPool to create pool with dmg.")
            self.dmg.request.value = "pool"
            # Currently, there is one test that creates the pool over the
            # subset of the server hosts; pool/evict_test. To do so, the test
            # needs to set the rank(s) to target_list.value starting from 0.
            # e.g., if you're using 4 server hosts; wolf-1, wolf-2, wolf-3, and
            # wolf-4, and want to create a pool over the first two hosts;
            # wolf-1 and 2, then set the list [0, 1] to target_list.value.
            # We'll convert it to the comma separated string and set it to dmg.
            # For instance, [0, 1] will result in dmg pool create -r 0,1. If
            # you don't set target_list.value, -r won't be used, in which case
            # the pool is created over all the server hosts.
            if self.target_list.value is None:
                ranks_comma_separated = None
            else:
                ranks_comma_separated = ""
                for i in range(len(self.target_list.value)):
                    ranks_comma_separated += str(self.target_list.value[i])
                    # If this element is not the last one, append comma
                    if i < len(self.target_list.value) - 1:
                        ranks_comma_separated += ","
            # Call the dmg pool create command
            self.dmg.action.value = "create"
            self.dmg.get_action_command()
            # uid/gid used in API correspond to --user and --group in dmg.
            # group, or self.name.value, used in API is called server group and
            # it's different from the group name passed in to --group. Server
            # group isn't used in dmg. We don't pass it into the command, but
            # we'll still use it to set self.pool.group
            self.dmg.action_command.group.value = self.groupname.value
            self.dmg.action_command.user.value = self.username.value
            self.dmg.action_command.scm_size.value = self.scm_size.value
            self.dmg.action_command.nvme_size.value = self.nvme_size.value
            self.dmg.action_command.ranks.value = ranks_comma_separated
            self.dmg.action_command.nsvc.value = self.svcn.value
            create_result = self.dmg.run()
            self.log.info("Result stdout = %s", create_result.stdout)
            self.log.info("Result exit status = %s", create_result.exit_status)
            # Get UUID and service replica from the output
            uuid_svc = get_pool_uuid_service_replicas_from_stdout(
                create_result.stdout)
            new_uuid = uuid_svc[0]
            service_replica = uuid_svc[1]

            # 3. Create DaosPool object. The process is similar to the one in
            # DaosPool.create, but there are some modifications
            if self.name.value is None:
                self.pool.group = None
            else:
                self.pool.group = ctypes.create_string_buffer(self.name.value)
            # Modification 1: Use the list of service replicas returned from
            # dmg pool create.
            service_replicas = [int(num) for num in service_replica.split(",")]
            rank_t = ctypes.c_uint * len(service_replicas)
            # Modification 2: Use the service_replicas list to generate rank.
            # In DaosPool, we first use some garbage 999999 values and let DAOS
            # set the correct values, but we can't do that here, so we need to
            # set the correct rank value by ourself
            rank = rank_t(*list([svc for svc in service_replicas]))
            rl_ranks = ctypes.POINTER(ctypes.c_uint)(rank)
            # Modification 3: Similar to 1. Use the length of service_replicas
            # list instead of self.svcn.value
            self.pool.svc = daos_cref.RankList(rl_ranks, len(service_replicas))

            # 4. Set UUID and attached to the DaosPool object
            self.pool.set_uuid_str(new_uuid)
            self.pool.attached = 1

        self.svc_ranks = [
            int(self.pool.svc.rl_ranks[index])
            for index in range(self.pool.svc.rl_nr)]
        self.uuid = self.pool.get_uuid_str()
示例#3
0
    def create(self):
        """Create a pool with either API or dmg.

        To use dmg, the test needs to set control_method.value to USE_DMG
        prior to calling this method. The recommended way is to specify the
        pool block in yaml. For example,

            pool:
                control_method: dmg

        This tells this method to use dmg. The test also needs to set
        dmg_bin_path through the constructor if dmg is used. For example,

            self.pool = TestPool(
                self.context, dmg_bin_path=self.basepath + '/install/bin')

        If it wants to use --nsvc option, it needs to set the value to
        svcn.value. Otherwise, 1 is used. If it wants to use --group, it needs
        to set groupname.value. If it wants to use --user, it needs to set
        username.value. If it wants to add other options, directly set it
        to self.dmg.action_command. Refer dmg_utils.py pool_create method for
        more details.

        To test the negative case on create, the test needs to catch
        CommandFailure for dmg and DaosApiError for API. Thus, we need to make
        more than one line modification to the test only for this purpose.
        Currently, pool_svc is the only test that needs this change.
        """
        self.destroy()
        if self.target_list.value is not None:
            self.log.info("Creating a pool on targets %s",
                          self.target_list.value)
        else:
            self.log.info("Creating a pool")

        self.pool = DaosPool(self.context)
        kwargs = {
            "uid": self.uid,
            "gid": self.gid,
            "scm_size": self.scm_size.value,
            "group": self.name.value
        }
        for key in ("target_list", "svcn", "nvme_size"):
            value = getattr(self, key).value
            if value is not None:
                kwargs[key] = value

        if self.control_method.value == self.USE_API:
            # Create a pool with the API method
            kwargs["mode"] = self.mode.value
            self._call_method(self.pool.create, kwargs)

        elif self.control_method.value == self.USE_DMG and self.dmg:
            # Create a pool with the dmg command
            self._log_method("dmg.pool_create", kwargs)
            result = self.dmg.pool_create(**kwargs)
            # self.cmd_output to keep the actual stdout of dmg command for
            # checking the negative/warning message.
            self.cmd_output = result.stdout
            uuid, svc = get_pool_uuid_service_replicas_from_stdout(
                result.stdout)

            # Populte the empty DaosPool object with the properties of the pool
            # created with dmg pool create.
            if self.name.value:
                self.pool.group = ctypes.create_string_buffer(self.name.value)

            # Convert the string of service replicas from the dmg command output
            # into an ctype array for the DaosPool object using the same
            # technique used in DaosPool.create().
            service_replicas = [int(value) for value in svc.split(",")]
            rank_t = ctypes.c_uint * len(service_replicas)
            rank = rank_t(*list([svc for svc in service_replicas]))
            rl_ranks = ctypes.POINTER(ctypes.c_uint)(rank)
            self.pool.svc = daos_cref.RankList(rl_ranks, len(service_replicas))

            # Set UUID and attached to the DaosPool object
            self.pool.set_uuid_str(uuid)
            self.pool.attached = 1

        elif self.control_method.value == self.USE_DMG:
            self.log.error("Error: Undefined dmg command")

        else:
            self.log.error("Error: Undefined control_method: %s",
                           self.control_method.value)

        # Set the TestPool attributes for the created pool
        self.svc_ranks = [
            int(self.pool.svc.rl_ranks[index])
            for index in range(self.pool.svc.rl_nr)
        ]
        self.uuid = self.pool.get_uuid_str()
示例#4
0
    def create(self):
        """Create a pool with dmg.

        To use dmg, the test needs to set dmg_command through the constructor.
        For example,

            self.pool = TestPool(self.context, DmgCommand(self.bin))

        If it wants to use --nsvc option, it needs to set the value to
        svcn.value. Otherwise, 1 is used. If it wants to use --group, it needs
        to set groupname.value. If it wants to use --user, it needs to set
        username.value. If it wants to add other options, directly set it
        to self.dmg.action_command. Refer dmg_utils.py pool_create method for
        more details.

        To test the negative case on create, the test needs to catch
        CommandFailure. Thus, we need to make more than one line modification
        to the test only for this purpose.
        Currently, pool_svc is the only test that needs this change.
        """
        self.destroy()
        if self.target_list.value is not None:
            self.log.info("Creating a pool on targets %s",
                          self.target_list.value)
        else:
            self.log.info("Creating a pool")

        self.pool = DaosPool(self.context)
        kwargs = {
            "uid": self.uid,
            "gid": self.gid,
            "scm_size": self.scm_size.value,
            "group": self.name.value
        }
        for key in ("target_list", "svcn", "nvme_size"):
            value = getattr(self, key).value
            if value is not None:
                kwargs[key] = value

        if self.control_method.value == self.USE_API:
            raise CommandFailure(
                "Error: control method {} not supported for create()".format(
                    self.control_method.value))

        elif self.control_method.value == self.USE_DMG and self.dmg:
            # Create a pool with the dmg command
            self._log_method("dmg.pool_create", kwargs)
            data = self.dmg.pool_create(**kwargs)

            # Populate the empty DaosPool object with the properties of the pool
            # created with dmg pool create.
            if self.name.value:
                self.pool.group = ctypes.create_string_buffer(self.name.value)

            # Convert the string of service replicas from the dmg command output
            # into an ctype array for the DaosPool object using the same
            # technique used in DaosPool.create().
            service_replicas = [int(value) for value in data["svc"].split(",")]
            rank_t = ctypes.c_uint * len(service_replicas)
            rank = rank_t(*list([svc for svc in service_replicas]))
            rl_ranks = ctypes.POINTER(ctypes.c_uint)(rank)
            self.pool.svc = daos_cref.RankList(rl_ranks, len(service_replicas))

            # Set UUID and attached to the DaosPool object
            self.pool.set_uuid_str(data["uuid"])
            self.pool.attached = 1

        elif self.control_method.value == self.USE_DMG:
            self.log.error("Error: Undefined dmg command")

        else:
            self.log.error("Error: Undefined control_method: %s",
                           self.control_method.value)

        # Set the TestPool attributes for the created pool
        self.svc_ranks = [
            int(self.pool.svc.rl_ranks[index])
            for index in range(self.pool.svc.rl_nr)
        ]
        self.uuid = self.pool.get_uuid_str()