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)]
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()
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()
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()