def check_pool_info(self, pi_uuid=None, pi_ntargets=None, pi_nnodes=None, pi_ndisabled=None, pi_map_ver=None, pi_leader=None, pi_bits=None): # pylint: disable=unused-argument """Check the pool info attributes. Args: pi_uuid (str, optional): pool uuid. Defaults to None. pi_ntargets (int, optional): number of targets. Defaults to None. pi_nnodes (int, optional): number of nodes. Defaults to None. pi_ndisabled (int, optional): number of disabled. Defaults to None. pi_map_ver (int, optional): pool map version. Defaults to None. pi_leader (int, optional): pool leader. Defaults to None. pi_bits (int, optional): pool bits. Defaults to None. Note: Arguments may also be provided as a string with a number preceeded by '<', '<=', '>', or '>=' for other comparisions besides the default '=='. Returns: bool: True if at least one expected value is specified and all the specified values match; False otherwise """ self.get_info() checks = [ (key, c_uuid_to_str(getattr(self.info, key)) if key == "pi_uuid" else getattr(self.info, key), val) for key, val in locals().items() if key != "self" and val is not None] return self._check_info(checks)
def setUp(self): """ set up method """ super(Snapshot, self).setUp() # get parameters from yaml file createmode = self.params.get("mode", '/run/poolparams/createmode/') createuid = os.geteuid() creategid = os.getegid() createsetid = self.params.get("setname", '/run/poolparams/createset/') createsize = self.params.get("size", '/run/poolparams/createsize/') self.log.info("==In setUp, self.context= %s", self.context) try: # initialize a python pool object then create the underlying # daos storage self.pool = DaosPool(self.context) self.pool.create(createmode, createuid, creategid, createsize, createsetid, None) # need a connection to the pool with rw permission # DAOS_PC_RO = int(1 << 0) # DAOS_PC_RW = int(1 << 1) # DAOS_PC_EX = int(1 << 2) self.pool.connect(1 << 1) # create a container self.container = DaosContainer(self.context) self.container.create(self.pool.handle) except DaosApiError as error: self.log.info("Error detected in DAOS pool container setup: %s", str(error)) self.log.info(traceback.format_exc()) self.fail("##Test failed on setUp, before snapshot taken") # now open it self.container.open() # do a query and compare the UUID returned from create with # that returned by query self.container.query() if self.container.get_uuid_str() != c_uuid_to_str( self.container.info.ci_uuid): self.fail("##Container UUID did not match the one in info.")
def test_container_basics(self): """ Test basic container create/destroy/open/close/query. :avocado:tags=all,pr,container,containercreate,containerdestroy,basecont """ try: # Parameters used in pool create pool_mode = self.params.get("mode", '/run/pool/createmode/') pool_name = self.params.get("setname", '/run/pool/createset/') pool_size = self.params.get("size", '/run/pool/createsize/') # Create pool and connect self.pool = get_pool(self.context, pool_mode, pool_size, pool_name, 1, self.d_log) # Create a container and open self.container = get_container(self.context, self.pool, self.d_log) # Query and compare the UUID returned from create with # that returned by query self.container.query() if self.container.get_uuid_str() != c_uuid_to_str( self.container.info.ci_uuid): self.fail("Container UUID did not match the one in info'n") self.container.close() # Wait and destroy time.sleep(5) self.container.destroy() except DaosApiError as excep: print(excep) print(traceback.format_exc()) self.fail("Test was expected to pass but it failed.\n") except Exception as excep: self.fail("Daos code segfaulted most likely, error: %s" % excep) finally: self.log.info("Clean up pool") if self.pool is not None: self.pool.disconnect() self.pool.destroy(1)
def test_container_basics(self): """ Test basic container create/destroy/open/close/query. Nothing fancy just making sure they work at a rudimentary level :avocado: tags=container,containercreate,containerdestroy,basecont """ pool = None hostlist = None try: hostlist = self.params.get("test_machines", '/run/hosts/*') hostfile = write_host_file.write_host_file(hostlist, self.workdir) self.agent_sessions = AgentUtils.run_agent(self.basepath, hostlist) server_utils.run_server(hostfile, self.server_group, self.basepath) # give it time to start time.sleep(2) # parameters used in pool create createmode = self.params.get("mode", '/run/conttests/createmode/') createuid = self.params.get("uid", '/run/conttests/createuid/') creategid = self.params.get("gid", '/run/conttests/creategid/') createsetid = self.params.get("setname", '/run/conttests/createset/') createsize = self.params.get("size", '/run/conttests/createsize/') # initialize a python pool object then create the underlying # daos storage pool = DaosPool(self.context) pool.create(createmode, createuid, creategid, createsize, createsetid, None) # need a connection to create container pool.connect(1 << 1) # create a container container = DaosContainer(self.context) container.create(pool.handle) # now open it container.open() # do a query and compare the UUID returned from create with # that returned by query container.query() if container.get_uuid_str() != c_uuid_to_str( container.info.ci_uuid): self.fail("Container UUID did not match the one in info'n") container.close() # wait a few seconds and then destroy time.sleep(5) container.destroy() except DaosApiError as excep: print(excep) print(traceback.format_exc()) self.fail("Test was expected to pass but it failed.\n") except Exception as excep: self.fail("Daos code segfaulted most likely, error: %s" % excep) finally: # cleanup the pool if pool is not None: pool.disconnect() pool.destroy(1) if self.agent_sessions: AgentUtils.stop_agent(hostlist, self.agent_sessions) server_utils.stop_server(hosts=hostlist)
def test_array_obj(self): """ Test ID: DAOS-961 Test Description: Writes an array to an object and then reads it back and verifies it. :avocado: tags=object,arrayobj,regression,vm,small """ try: # parameters used in pool create createmode = self.params.get("mode", '/run/conttests/createmode/') createsetid = self.params.get("setname", '/run/conttests/createset/') createsize = self.params.get("size", '/run/conttests/createsize/') createuid = os.geteuid() creategid = os.getegid() print("uid is {} gid is {}".format(createuid, creategid)) # initialize a python pool object then create the underlying # daos storage pool = DaosPool(self.Context) pool.create(createmode, createuid, creategid, createsize, createsetid, None) self.pl.info("Pool %s created.", pool.get_uuid_str()) # need a connection to create container pool.connect(1 << 1) # create a container container = DaosContainer(self.Context) container.create(pool.handle) self.pl.info("Container %s created.", container.get_uuid_str()) # now open it container.open() # do a query and compare the UUID returned from create with # that returned by query container.query() if container.get_uuid_str() != c_uuid_to_str( container.info.ci_uuid): self.fail("Container UUID did not match the one in info\n") # create an object and write some data into it thedata = [] thedata.append("data string one") thedata.append("data string two") thedata.append("data string tre") dkey = "this is the dkey" akey = "this is the akey" self.pl.info("writing array to dkey >%s< akey >%s<.", dkey, akey) oid, epoch = container.write_an_array_value(thedata, dkey, akey) # read the data back and make sure its correct length = len(thedata[0]) thedata2 = container.read_an_array(len(thedata), length + 1, dkey, akey, oid, epoch) if thedata[0][0:length - 1] != thedata2[0][0:length - 1]: self.pl.error("Data mismatch") self.pl.error("Wrote: >%s<" (thedata[0])) self.pl.error("Read: >%s<" (thedata2[0])) self.fail("Write data, read it back, didn't match\n") if thedata[2][0:length - 1] != thedata2[2][0:length - 1]: self.pl.error("Data mismatch") self.pl.error("Wrote: >%s<" (thedata[2])) self.pl.error("Read: >%s<" (thedata2[2])) self.fail("Write data, read it back, didn't match\n") container.close() # wait a few seconds and then destroy time.sleep(5) container.destroy() # cleanup the pool pool.disconnect() pool.destroy(1) self.pl.info("Test Complete") except ValueError as e: self.pl.error("Test Failed, exception was thrown.") print e print traceback.format_exc() self.fail("Test was expected to pass but it failed.\n")
def test_container_basics(self): """ Test basic container create/destroy/open/close/query. Nothing fancy just making sure they work at a rudimentary level :avocado: tags=container,containercreate,containerdestroy,basecont """ pool = None hostlist = None try: hostlist = self.params.get("test_machines", '/run/hosts/*') hostfile = write_host_file.write_host_file(hostlist, self.workdir) self.agent_sessions = agent_utils.run_agent(self.basepath, hostlist) server_utils.run_server(hostfile, self.server_group, self.basepath) # give it time to start time.sleep(2) # parameters used in pool create createmode = self.params.get("mode", '/run/conttests/createmode/') createuid = self.params.get("uid", '/run/conttests/createuid/') creategid = self.params.get("gid", '/run/conttests/creategid/') createsetid = self.params.get("setname", '/run/conttests/createset/') createsize = self.params.get("size", '/run/conttests/createsize/') # initialize a python pool object then create the underlying # daos storage pool = DaosPool(self.context) pool.create(createmode, createuid, creategid, createsize, createsetid, None) # need a connection to create container pool.connect(1 << 1) # create a container container = DaosContainer(self.context) container.create(pool.handle) # now open it container.open() # do a query and compare the UUID returned from create with # that returned by query container.query() if container.get_uuid_str() != c_uuid_to_str( container.info.ci_uuid): self.fail("Container UUID did not match the one in info'n") container.close() # wait a few seconds and then destroy time.sleep(5) container.destroy() except DaosApiError as excep: print(excep) print(traceback.format_exc()) self.fail("Test was expected to pass but it failed.\n") except Exception as excep: self.fail("Daos code segfaulted most likely, error: %s" % excep) finally: # cleanup the pool if pool is not None: pool.disconnect() pool.destroy(1) if self.agent_sessions: agent_utils.stop_agent(self.agent_sessions) server_utils.stop_server(hosts=hostlist)
def test_simple_query(self): """ Test querying a pool created on a single server. :avocado: tags=pool,poolquery,infotest """ # create pool mode = self.params.get("mode", '/run/testparams/modes/*', 0731) if mode == 73: self.cancel('Cancel the mode test 73 because of DAOS-1877') uid = os.geteuid() gid = os.getegid() size = self.params.get("size", '/run/testparams/sizes/*', 0) group = self.server_group self.pool.create(mode, uid, gid, size, group, None) # connect to the pool flags = self.params.get("perms", '/run/testparams/connectperms/*', '') connect_flags = 1 << flags self.pool.connect(connect_flags) # query the pool pool_info = self.pool.pool_query() # check uuid uuid_str = c_uuid_to_str(pool_info.pi_uuid) if uuid_str != self.pool.get_uuid_str(): self.d_log.error("UUID str does not match expected string") self.fail("UUID str does not match expected string") ''' # validate size of pool is what we expect This check is currently disabled, as space is not implemented in DAOS C API yet. if size != pool_info.pi_space: self.d_log.error("expected size {0} did not match actual size {1}" .format(size, pool_info.pi_space)) self.fail("expected size {0} did not match actual size {1}" .format(size, pool_info.pi_space)) ''' # number of targets if pool_info.pi_ntargets != len(self.hostlist): self.d_log.error("found number of targets in pool did not match " "expected number, 1. num targets: {0}".format( pool_info.pi_ntargets)) self.fail("found number of targets in pool did not match " "expected number, 1. num targets: {0}".format( pool_info.pi_ntargets)) # number of disabled targets if pool_info.pi_ndisabled > 0: self.d_log.error("found disabled targets, none expected to be") self.fail("found disabled targets, none expected to be disabled") # mode if pool_info.pi_mode != mode: self.d_log.error( "found different mode than expected. expected {0}, " "found {1}.".format(mode, pool_info.pi_mode)) self.fail("found different mode than expected. expected {0}, " "found {1}.".format(mode, pool_info.pi_mode)) # uid if pool_info.pi_uid != uid: self.d_log.error( "found actual pool uid {0} does not match expected " "uid {1}".format(pool_info.pi_uid, uid)) self.fail("found actual pool uid {0} does not match expected uid " "{1}".format(pool_info.pi_uid, uid)) # gid if pool_info.pi_gid != gid: self.d_log.error( "found actual pool gid {0} does not match expected " "gid {1}".format(pool_info.pi_gid, gid)) self.fail("found actual pool gid {0} does not match expected gid " "{1}".format(pool_info.pi_gid, gid))
def test_simple_query(self): """ Test querying a pool created on a single server. :avocado: tags=pool,poolquery,infotest """ # there is a presumption that this test lives in a specific spot # in the repo # create pool mode = self.params.get("mode", '/run/testparams/modes/*', 0731) uid = os.geteuid() gid = os.getegid() size = self.params.get("size", '/run/testparams/sizes/*', 0) tgt_list = None group = self.server_group self.pool.create(mode, uid, gid, size, group, tgt_list) PROGRESS_LOG.info("created pool") # connect to the pool flags = self.params.get("perms", '/run/testparams/connectperms/*', '') connect_flags = 1 << flags self.pool.connect(connect_flags) PROGRESS_LOG.info("connected to pool") # query the pool pool_info = self.pool.pool_query() PROGRESS_LOG.info("queried pool info") # check uuid uuid_str = c_uuid_to_str(pool_info.pi_uuid) PROGRESS_LOG.info("pool uuid pool_info.pi_uuid: {0}".format(uuid_str)) PROGRESS_LOG.info("pool uuid saved in api at create time: " "{0}".format(self.pool.get_uuid_str())) if uuid_str != self.pool.get_uuid_str(): self.fail("UUID str does not match expected string") # validate size of pool is what we expect PROGRESS_LOG.info("pool should be {0} bytes".format(size)) PROGRESS_LOG.info("pool actual space is {0} bytes".format( pool_info.pi_space)) ''' This check is currently disabled, as space is not implemented in DAOS C API yet. if size != pool_info.pi_space: self.fail("expected size {0} did not match actual size {1}" .format(size, pool_info.pi_space)) ''' # number of targets PROGRESS_LOG.info("number of targets in pool: %s", pool_info.pi_ntargets) if pool_info.pi_ntargets != len(self.hostlist): self.fail("found number of targets in pool did not match " "expected number, 1. num targets: {0}".format( pool_info.pi_ntargets)) # number of disabled targets PROGRESS_LOG.info("number of disabled targets in pool: %s", pool_info.pi_ndisabled) if pool_info.pi_ndisabled > 0: self.fail("found disabled targets, none expected to be disabled") # mode PROGRESS_LOG.info("pool mode: %s", pool_info.pi_mode) if pool_info.pi_mode != mode: self.fail("found different mode than expected. expected {0}, " "found {1}.".format(mode, pool_info.pi_mode)) # uid PROGRESS_LOG.info("expected uid is {0}".format(uid)) if pool_info.pi_uid != uid: self.fail("found actual pool uid {0} does not match expected uid " "{1}".format(pool_info.pi_uid, uid)) # gid PROGRESS_LOG.info("expected gid is {0}".format(gid)) if pool_info.pi_gid != gid: self.fail("found actual pool gid {0} does not match expected gid " "{1}".format(pool_info.pi_gid, gid))
def test_array_obj(self): """ Test ID: DAOS-961 Test Description: Writes an array to an object and then reads it back and verifies it. :avocado: tags=object,arrayobj,regression,vm,small """ try: # parameters used in pool create createmode = self.params.get("mode", '/run/pool_params/createmode/') createsetid = self.params.get("setname", '/run/pool_params/createset/') createsize = self.params.get("size", '/run/pool_params/createsize/') createuid = os.geteuid() creategid = os.getegid() # initialize a python pool object then create the underlying # daos storage pool = DaosPool(self.context) pool.create(createmode, createuid, creategid, createsize, createsetid, None) self.plog.info("Pool %s created.", pool.get_uuid_str()) # need a connection to create container pool.connect(1 << 1) # create a container container = DaosContainer(self.context) container.create(pool.handle) self.plog.info("Container %s created.", container.get_uuid_str()) # now open it container.open() # do a query and compare the UUID returned from create with # that returned by query container.query() if container.get_uuid_str() != c_uuid_to_str( container.info.ci_uuid): self.fail("Container UUID did not match the one in info\n") # create an object and write some data into it thedata = [] thedata.append("data string one") thedata.append("data string two") thedata.append("data string tre") dkey = "this is the dkey" akey = "this is the akey" self.plog.info("writing array to dkey >%s< akey >%s<.", dkey, akey) oid, epoch = container.write_an_array_value(thedata, dkey, akey, obj_cls=3) # read the data back and make sure its correct length = len(thedata[0]) thedata2 = container.read_an_array(len(thedata), length+1, dkey, akey, oid, epoch) if thedata[0][0:length-1] != thedata2[0][0:length-1]: self.plog.error("Data mismatch") self.plog.error("Wrote: >%s<", thedata[0]) self.plog.error("Read: >%s<", thedata2[0]) self.fail("Write data, read it back, didn't match\n") if thedata[2][0:length-1] != thedata2[2][0:length-1]: self.plog.error("Data mismatch") self.plog.error("Wrote: >%s<", thedata[2]) self.plog.error("Read: >%s<", thedata2[2]) self.fail("Write data, read it back, didn't match\n") container.close() # wait a few seconds and then destroy time.sleep(5) container.destroy() # cleanup the pool pool.disconnect() pool.destroy(1) self.plog.info("Test Complete") except DaosApiError as excep: self.plog.error("Test Failed, exception was thrown.") print(excep) print(traceback.format_exc()) self.fail("Test was expected to pass but it failed.\n")
def test_destroy_withdata(self): """ Test destroy and recreate one right after the other multiple times Should fail. :avocado: tags=pool,pooldestroy,destroydata """ try: # write out a hostfile and start the servers with it self.hostlist = self.params.get("test_machines1", '/run/hosts/') hostfile = write_host_file.write_host_file(self.hostlist, self.tmp) self.agent_sessions = AgentUtils.run_agent(self.basepath, self.hostlist) server_utils.run_server(hostfile, self.server_group, self.basepath) # parameters used in pool create createmode = self.params.get("mode", '/run/poolparams/createmode/') createuid = self.params.get("uid", '/run/poolparams/createuid/') creategid = self.params.get("gid", '/run/poolparams/creategid/') createsetid = self.params.get("setname", '/run/poolparams/createset/') createsize = self.params.get("size", '/run/poolparams/createsize/') # initialize a python pool object then create the underlying # daos storage pool = DaosPool(self.context) pool.create(createmode, createuid, creategid, createsize, createsetid, None) # need a connection to create container pool.connect(1 << 1) # create a container container = DaosContainer(self.context) container.create(pool.handle) pool.disconnect() daosctl = self.basepath + '/install/bin/daosctl' write_cmd = ('{0} write-pattern -i {1} -l 0 -c {2} -p sequential'. format(daosctl, c_uuid_to_str(pool.uuid), c_uuid_to_str(container.uuid))) process.system_output(write_cmd) # blow it away pool.destroy(1) except DaosApiError as excep: print(excep) print(traceback.format_exc()) self.fail("create/destroy/create/destroy test failed.\n") except Exception as excep: self.fail("Daos code segfaulted most likely. Error: %s" % excep) # no matter what happens cleanup finally: if self.agent_sessions: AgentUtils.stop_agent(self.hostlist, self.agent_sessions) server_utils.stop_server(hosts=self.hostlist) os.remove(hostfile)
def test_container_basics(self): """ Test basic container create/destroy/open/close/query. Nothing fancy just making sure they work at a rudimentary level :avocado: tags=container,containercreate,containerdestroy,basecont """ hostfile = None try: self.hostlist = self.params.get("test_machines",'/run/hosts/*') hostfile = WriteHostFile.WriteHostFile(self.hostlist, self.tmp) ServerUtils.runServer(hostfile, self.server_group, self.basepath) # give it time to start time.sleep(2) # parameters used in pool create createmode = self.params.get("mode",'/run/conttests/createmode/') createuid = self.params.get("uid",'/run/conttests/createuid/') creategid = self.params.get("gid",'/run/conttests/creategid/') createsetid = self.params.get("setname",'/run/conttests/createset/') createsize = self.params.get("size",'/run/conttests/createsize/') # initialize a python pool object then create the underlying # daos storage POOL = DaosPool(self.Context) POOL.create(createmode, createuid, creategid, createsize, createsetid, None) # need a connection to create container POOL.connect(1 << 1) # create a container CONTAINER = DaosContainer(self.Context) CONTAINER.create(POOL.handle) # now open it CONTAINER.open() # do a query and compare the UUID returned from create with # that returned by query CONTAINER.query() if CONTAINER.get_uuid_str() != c_uuid_to_str( CONTAINER.info.ci_uuid): self.fail("Container UUID did not match the one in info'n") CONTAINER.close() # wait a few seconds and then destroy time.sleep(5) CONTAINER.destroy() # cleanup the pool POOL.disconnect() POOL.destroy(1) except DaosApiError as e: print(e) print(traceback.format_exc()) self.fail("Test was expected to pass but it failed.\n") except Exception as e: self.fail("Daos code segfaulted most likely, error: %s" % e) finally: try: if hostfile is not None: os.remove(hostfile) finally: ServerUtils.stopServer(hosts=self.hostlist)
def test_epoch_basics(self): """ Perform I/O to an object in a container in 2 different epochs, verifying basic I/O and epochs in particular. :avocado: tags=container,epoch,basicepoch """ try: # parameters used in pool create createmode = self.params.get("mode",'/run/conttests/createmode/') createuid = self.params.get("uid",'/run/conttests/createuid/') creategid = self.params.get("gid",'/run/conttests/creategid/') createsetid = self.params.get("setname",'/run/conttests/createset/') createsize = self.params.get("size",'/run/conttests/createsize/') # initialize a python pool object then create the underlying # daos storage POOL = DaosPool(self.Context) POOL.create(createmode, createuid, creategid, createsize, createsetid, None) # need a connection to create container POOL.connect(1 << 1) # create a container CONTAINER = DaosContainer(self.Context) CONTAINER.create(POOL.handle) # now open it CONTAINER.open() # do a query and compare the UUID returned from create with # that returned by query CONTAINER.query() if CONTAINER.get_uuid_str() != c_uuid_to_str( CONTAINER.info.ci_uuid): self.fail("Container UUID did not match the one in info\n") # create an object and write some data into it thedata = "a string that I want to stuff into an object" thedatasize = 45 dkey = "this is the dkey" akey = "this is the akey" oid, epoch = CONTAINER.write_an_obj(thedata, thedatasize, dkey, akey) # read the data back and make sure its correct thedata2 = CONTAINER.read_an_obj(thedatasize, dkey, akey, oid, epoch) if thedata != thedata2.value: print("thedata>" + thedata) print("thedata2>" + thedata2.value) self.fail("Write data 1, read it back, didn't match\n") # repeat above, but know that the write_an_obj call is advancing # the epoch so the original copy remains and the new copy is in # a new epoch. thedata3 = "a different string" thedatasize2 = 19 # note using the same keys so writing to the same spot dkey = "this is the dkey" akey = "this is the akey" oid, epoch2 = CONTAINER.write_an_obj(thedata3, thedatasize2, dkey, akey, oid) # read the data back and make sure its correct thedata4 = CONTAINER.read_an_obj(thedatasize2, dkey, akey, oid, epoch2) if thedata3 != thedata4.value: self.fail("Write data 2, read it back, didn't match\n") # the original data should still be there too thedata5 = CONTAINER.read_an_obj(thedatasize, dkey, akey, oid, epoch) if thedata != thedata5.value: self.fail("Write data 3, read it back, didn't match\n") CONTAINER.close() # wait a few seconds and then destroy time.sleep(5) CONTAINER.destroy() # cleanup the pool POOL.disconnect() POOL.destroy(1) except DaosApiError as e: print(e) print(traceback.format_exc()) self.fail("Test was expected to pass but it failed.\n")
def test_tx_basics(self): """ Perform I/O to an object in a container in 2 different transactions, verifying basic I/O and transactions in particular. NOTE: this was an epoch test and all I did was get it working with tx Not a good test at this point, need to redesign when tx is fully working. :avocado: tags=container,tx,basictx """ pool = None try: # parameters used in pool create createmode = self.params.get("mode", '/run/poolparams/createmode/') createuid = os.geteuid() creategid = os.getegid() createsetid = self.params.get("setname", '/run/poolparams/createset/') createsize = self.params.get("size", '/run/poolparams/createsize/') # initialize a python pool object then create the underlying # daos storage pool = DaosPool(self.context) pool.create(createmode, createuid, creategid, createsize, createsetid, None) # need a connection to create container pool.connect(1 << 1) # create a container container = DaosContainer(self.context) container.create(pool.handle) # now open it container.open() # do a query and compare the UUID returned from create with # that returned by query container.query() if container.get_uuid_str() != c_uuid_to_str( container.info.ci_uuid): self.fail("Container UUID did not match the one in info\n") # create an object and write some data into it thedata = "a string that I want to stuff into an object" thedatasize = 45 dkey = "this is the dkey" akey = "this is the akey" oid, txn = container.write_an_obj(thedata, thedatasize, dkey, akey, None, None, 2) # read the data back and make sure its correct thedata2 = container.read_an_obj(thedatasize, dkey, akey, oid, txn) if thedata != thedata2.value: print("thedata>" + thedata) print("thedata2>" + thedata2.value) self.fail("Write data 1, read it back, didn't match\n") # repeat above, but know that the write_an_obj call is advancing # the epoch so the original copy remains and the new copy is in # a new epoch. thedata3 = "a different string" thedatasize2 = 19 # note using the same keys so writing to the same spot dkey = "this is the dkey" akey = "this is the akey" oid, tx2 = container.write_an_obj(thedata3, thedatasize2, dkey, akey, oid, None, 2) # read the data back and make sure its correct thedata4 = container.read_an_obj(thedatasize2, dkey, akey, oid, tx2) if thedata3 != thedata4.value: self.fail("Write data 2, read it back, didn't match\n") # transactions generally don't work this way but need to explore # an alternative to below code once model is complete, maybe # read from a snapshot or read from TX_NONE etc. # the original data should still be there too #thedata5 = container.read_an_obj(thedatasize, dkey, akey, # oid, transaction) #if thedata != thedata5.value: # self.fail("Write data 3, read it back, didn't match\n") container.close() # wait a few seconds and then destroy time.sleep(5) container.destroy() except DaosApiError as excep: print(excep) print(traceback.format_exc()) self.fail("Test was expected to pass but it failed.\n") finally: # cleanup the pool if pool is not None: pool.disconnect() pool.destroy(1)
def test_destroy_withdata(self): """ Test destroy and recreate one right after the other multiple times Should fail. :avocado: tags=pool,pooldestroy,destroydata """ try: # write out a hostfile and start the servers with it self.hostlist = self.params.get("test_machines1", '/run/hosts/') hostfile = WriteHostFile.WriteHostFile(self.hostlist, self.tmp) ServerUtils.runServer(hostfile, self.server_group, self.basepath) # parameters used in pool create createmode = self.params.get("mode", '/run/poolparams/createmode/') createuid = self.params.get("uid", '/run/poolparams/createuid/') creategid = self.params.get("gid", '/run/poolparams/creategid/') createsetid = self.params.get("setname", '/run/poolparams/createset/') createsize = self.params.get("size", '/run/poolparams/createsize/') # initialize a python pool object then create the underlying # daos storage POOL = DaosPool(self.Context) POOL.create(createmode, createuid, creategid, createsize, createsetid, None) # need a connection to create container POOL.connect(1 << 1) # create a container CONTAINER = DaosContainer(self.Context) CONTAINER.create(POOL.handle) POOL.disconnect() daosctl = self.basepath + '/install/bin/daosctl' write_cmd = ( '{0} write-pattern -i {1} -l 0 -c {2} -p sequential'.format( daosctl, c_uuid_to_str(POOL.uuid), c_uuid_to_str(CONTAINER.uuid))) process.system_output(write_cmd) # blow it away POOL.destroy(1) except DaosApiError as e: print(e) print(traceback.format_exc()) self.fail("create/destroy/create/destroy test failed.\n") except Exception as e: self.fail("Daos code segfaulted most likely. Error: %s" % e) # no matter what happens cleanup finally: ServerUtils.stopServer(hosts=self.hostlist) os.remove(hostfile)
def test_evict(self): """ Test evicting a client from a pool. Test creates 2 pools on 4 target (pool_tgt [0,1,2,3]) and 1 pool on 2 targets (pool_tgt_ut [0,1]). The pools are connected to and a container with data is created on all 3. The evict is done on connection to the pool with 2 targets. The handle is removed. The test verifies that the other two pools were not affected by the evict :avocado: tags=all,pool,pr,full_regression,small,poolevict """ pool = [] container = [] non_pool_servers = [] # Target list is configured so that the pools are across all servers # except the pool under test is created on half of the servers pool_tgt = [num for num in range(len(self.hostlist_servers))] pool_tgt_ut = [num for num in range(int(len(self.hostlist_servers)/2))] tlist = [pool_tgt, pool_tgt, pool_tgt_ut] pool_servers = [self.hostlist_servers[:len(tgt)] for tgt in tlist] non_pool_servers = [self.hostlist_servers[len(tgt):] for tgt in tlist] # Create Connected TestPool for count, target_list in enumerate(tlist): pool.append(self.connected_pool(pool_servers[count], target_list)) if len(non_pool_servers[count]) > 0: self.assertFalse( pool[count].check_files(non_pool_servers[count]), "Pool # {} data detected on non pool servers {} ".format( count+1, non_pool_servers[count])) self.log.info("Pool # %s is connected with handle %s", count+1, pool[count].pool.handle.value) # Create a container # container.append(get_container( # self.context, pool[count].pool, self.log)) # cont_uuid.append(container[count].get_uuid_str()) # self.log.info("Pool # %s has container %s", # count+1, cont_uuid[count]) container.append(TestContainer(pool[count])) container[count].get_params(self) container[count].create() container[count].write_objects(target_list[-1]) try: self.log.info( "Attempting to evict clients from pool with UUID: %s", pool[-1].uuid) # Evict the last pool in the list pool[-1].pool.evict() except DaosApiError as result: self.fail( "Detected exception while evicting a client {}".format( str(result))) for count in range(len(tlist)): # Check that all pool files still exist if pool[count].check_files(pool_servers[count]): self.log.info( "Pool # %s with UUID %s still exists", count+1, pool[count].uuid) else: self.fail( "Pool # {} with UUID {} does not exists".format( count+1, pool[count].uuid)) # Verify connection to pools with pool_query; pool that was evicted # should fail the pool query because the handle was removed try: # Call daos api directly to avoid connecting to pool pool_info = pool[count].pool.pool_query() except DaosApiError as error: # expected error for evicted pool if count == len(tlist) - 1 and "-1002" in str(error): self.log.info( "Pool # %s was unable to query pool info due to " "expected invalid handle error (-1002):\n\t%s", count+1, error) # unexpected error from pool_query else: self.fail( "Pool # {} failed pool query: {}".format( count+1, error)) pool_info = None # Check that UUID of valid pools still exists if pool_info: if c_uuid_to_str(pool_info.pi_uuid) == pool[count].uuid: self.log.info( "Pool # %s UUID matches pool_info.pi_uuid %s", count+1, pool[count].uuid) else: self.fail( "Pool # {} UUID does not matches pool_info.pi_uuid: " "{} != {}".format( count+1, pool[count].uuid, c_uuid_to_str( pool_info.pi_uuid)))