def testAnonReadWrite(t, env): """Do a simple READ and WRITE using anonymous stateid FLAGS: open all CODE: OPEN31 """ sess1 = env.c1.new_client_session(env.testname(t)) owner = open_owner4(0, b"My Open Owner") res = create_file(sess1, env.testname(t)) check(res) expect(res, seqid=1) fh = res.resarray[-1].object data = b"write test data" stateid = res.resarray[-2].stateid res = close_file(sess1, fh, stateid=stateid) check(res) res = write_file(sess1, fh, data, 5, nfs4lib.state00) check(res) res = read_file(sess1, fh, 0, 1000, nfs4lib.state00) check(res) if not res.eof: fail("EOF not set on read") desired = b"\0" * 5 + data if res.data != desired: fail("Expected %r, got %r" % (desired, res.data))
def open_file(self, mds_fh): seqid=0 access = const4.OPEN4_SHARE_ACCESS_BOTH deny = const4.OPEN4_SHARE_DENY_NONE attrs = {const4.FATTR4_MODE: 0777} owner = "mds" mode = const4.GUARDED4 verifier = self.sess.c.verifier openflag = type4.openflag4(const4.OPEN4_CREATE, type4.createhow4(mode, attrs, verifier)) name = self.fh_to_name(mds_fh) while True: if mds_fh in self.filehandles: return open_op = op4.open(seqid, access, deny, type4.open_owner4(self.sess.client.clientid, owner), openflag, type4.open_claim4(const4.CLAIM_NULL, name)) res = self._execute(nfs4lib.use_obj(self.path_fh) + [open_op, op4.getfh()], exceptions=[const4.NFS4ERR_EXIST]) if res.status == const4.NFS4_OK: ds_fh = res.resarray[-1].opgetfh.resok4.object ds_openstateid = type4.stateid4(0, res.resarray[-2].stateid.other) self.filehandles[mds_fh] = (ds_fh, ds_openstateid) return elif res.status == const4.NFS4ERR_EXIST: openflag = type4.openflag4(const4.OPEN4_NOCREATE) else: raise RuntimeError
def testOPENClaimFH(t, env): """OPEN file with claim_type is CLAIM_FH FLAGS: open all CODE: OPEN7 """ sess1 = env.c1.new_client_session(env.testname(t)) res = create_file(sess1, env.testname(t)) check(res) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid res = close_file(sess1, fh, stateid=stateid) check(res) claim = open_claim4(CLAIM_FH) how = openflag4(OPEN4_NOCREATE) oowner = open_owner4(0, "My Open Owner 2") open_op = op.open(0, OPEN4_SHARE_ACCESS_BOTH, OPEN4_SHARE_DENY_NONE, oowner, how, claim) res = sess1.compound([op.putfh(fh), open_op]) check(res) stateid = res.resarray[-1].stateid stateid.seqid = 0 data = "write test data" res = sess1.compound([op.putfh(fh), op.write(stateid, 5, FILE_SYNC4, data)]) check(res) res = sess1.compound([op.putfh(fh), op.read(stateid, 0, 1000)]) check(res) if not res.resarray[-1].eof: fail("EOF not set on read") desired = "\0"*5 + data if res.resarray[-1].data != desired: fail("Expected %r, got %r" % (desired, res.resarray[-1].data))
def testDeadlock(t, env): """Trigger deadlock bug FLAGS: debug all CODE: DEBUG1 """ c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session() owner = open_owner4(0, "My Open Owner") how = openflag4(OPEN4_CREATE, createhow4(GUARDED4, {FATTR4_SIZE:0})) claim = open_claim4(CLAIM_NULL, env.testname(t)) open_op = op.open(0, OPEN4_SHARE_ACCESS_BOTH , OPEN4_SHARE_DENY_NONE, owner, how, claim) res = sess1.compound(env.home + [open_op, op.getfh()]) # OPEN fh = res.resarray[-1].object stateid = res.resarray[-2].stateid #### def ops(i): return [op.putfh(fh), op.write(stateid, i*1000, UNSTABLE4, chr(97+i)*100), op.getattr(42950721818L) ] xids = [sess1.compound_async(ops(i), slot=i) for i in range(4)] for xid in xids: res = sess1.listen(xid) check(res) print res res = close_file(sess1, fh, stateid=stateid) check(res)
def testSupported2(t, env): """Check OPEN delegation handling FLAGS: open all CODE: OPEN200 """ # c1 - OPEN - READ with delegation c1 = env.c1.new_client("%s_1" % env.testname(t)) sess1 = c1.create_session() res = create_file(sess1, env.testname(t), access=OPEN4_SHARE_ACCESS_READ | OPEN4_SHARE_ACCESS_WANT_READ_DELEG) check(res) # STUB Should check delegation was granted fh1 = res.resarray[-1].object stateid1 = res.resarray[-2].stateid # c2 - OPEN - WRITE c2 = env.c1.new_client("%s_2" % env.testname(t)) sess2 = c2.create_session() owner = open_owner4(0, "My Open Owner 2") claim = open_claim4(CLAIM_NULL, env.testname(t)) how = openflag4(OPEN4_NOCREATE) open_op = op.open(0, OPEN4_SHARE_ACCESS_BOTH, OPEN4_SHARE_DENY_NONE, owner, how, claim) res = sess2.compound(env.home + [open_op]) # STUB - since we are not handling callback, deleg_return never gets done print res check(res) fh2 = res.resarray[-1].object stateid2 = res.resarray[-2].stateid res = close_file(sess1, fh1, stateid=stateid1) check(res) res = close_file(sess2, fh2, stateid=stateid2) check(res)
def testReadWrite(t, env): """Do a simple READ and WRITE FLAGS: open all CODE: OPEN400 """ c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session() owner = open_owner4(0, "My Open Owner") how = openflag4(OPEN4_CREATE, createhow4(GUARDED4, {FATTR4_SIZE:0})) claim = open_claim4(CLAIM_NULL, env.testname(t)) open_op = op.open(0, OPEN4_SHARE_ACCESS_BOTH , OPEN4_SHARE_DENY_NONE, owner, how, claim) fh_op = op.putrootfh() res = sess1.compound([fh_op, open_op, op.getfh()]) # OPEN print res check(res) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid stateid.seqid = 0 res = sess1.compound([op.putfh(fh), op.write(stateid, 5, FILE_SYNC4, "write test data")]) print res check(res) res = sess1.compound([op.putfh(fh), op.read(stateid, 0, 1000)]) print res check(res) res = close_file(sess1, fh, stateid=stateid) check(res)
def testAnonReadWrite(t, env): """Do a simple READ and WRITE using anonymous stateid FLAGS: open all CODE: OPEN31 """ sess1 = env.c1.new_client_session(env.testname(t)) owner = open_owner4(0, "My Open Owner") res = create_file(sess1, env.testname(t)) check(res) expect(res, seqid=1) fh = res.resarray[-1].object data = "write test data" stateid = res.resarray[-2].stateid res = close_file(sess1, fh, stateid=stateid) check(res) res = sess1.compound([op.putfh(fh), op.write(nfs4lib.state00, 5, FILE_SYNC4, data)]) check(res) res = sess1.compound([op.putfh(fh), op.read(nfs4lib.state00, 0, 1000)]) check(res) if not res.resarray[-1].eof: fail("EOF not set on read") desired = "\0"*5 + data if res.resarray[-1].data != desired: fail("Expected %r, got %r" % (desired, res.resarray[-1].data))
def testReadWrite(t, env): """Do a simple READ and WRITE FLAGS: open all CODE: OPEN30 """ sess1 = env.c1.new_client_session(env.testname(t)) owner = open_owner4(0, "My Open Owner") res = create_file(sess1, env.testname(t)) check(res) expect(res, seqid=1) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid stateid.seqid = 0 data = "write test data" res = sess1.compound( [op.putfh(fh), op.write(stateid, 5, FILE_SYNC4, data)]) check(res) res = sess1.compound([op.putfh(fh), op.read(stateid, 0, 1000)]) check(res) if not res.resarray[-1].eof: fail("EOF not set on read") desired = "\0" * 5 + data if res.resarray[-1].data != desired: fail("Expected %r, got %r" % (desired, res.resarray[-1].data)) res = close_file(sess1, fh, stateid=stateid) check(res)
def testShareReservation00(t, env): """Test OPEN file with OPEN4_SHARE_DENY_WRITE 1st client opens file with OPEN4_SHARE_DENY_WRITE 1st client opens same file with OPEN4_SHARE_ACCESS_BOTH and OPEN4_SHARE_DENY_NONE expected reply is NFS4ERR_SHARE_DENIED 2nd client opens file with OPEN4_SHARE_ACCESS_WRITE expected reply is NFS4ERR_SHARE_DENIED sleep to force lease of client 1 to expire 3rd client opens file with OPEN4_SHARE_ACCESS_WRITE expected reply is NFS4_OK FLAGS: courteous all CODE: COUR3 """ sess1 = env.c1.new_client_session(env.testname(t)) res = create_file(sess1, env.testname(t), want_deleg=False, deny=OPEN4_SHARE_DENY_WRITE) check(res) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid claim = open_claim4(CLAIM_FH) how = openflag4(OPEN4_NOCREATE) oowner = open_owner4(0, b"My Open Owner 2") access = OPEN4_SHARE_ACCESS_BOTH | OPEN4_SHARE_ACCESS_WANT_NO_DELEG open_op = op.open(0, access, OPEN4_SHARE_DENY_NONE, oowner, how, claim) res = sess1.compound([op.putfh(fh), open_op]) check(res, NFS4ERR_SHARE_DENIED) log.info("local open conflict detected - PASSED\n") """ 2nd client """ sess2 = env.c1.new_client_session(b"%s_2" % env.testname(t)) name = env.testname(t) owner = b"owner_%s" % name path = sess1.c.homedir + [name] res = open_file(sess2, owner, path, access=OPEN4_SHARE_ACCESS_WRITE) check(res, NFS4ERR_SHARE_DENIED) log.info("2nd client open conflict detected - PASSED\n") """ force lease of both c1 to expire """ log.info("force lease to expire...\n") lease_time = _getleasetime(sess1) env.sleep(lease_time + 10, "the lease period + 10 secs") """ 3rd client """ sess3 = env.c1.new_client_session(b"%s_3" % env.testname(t)) """ should succeed """ name = env.testname(t) owner = b"owner_%s" % name path = sess3.c.homedir + [name] res = open_file(sess3, owner, path, access=OPEN4_SHARE_ACCESS_WRITE) check(res) log.info("3nd client opened OK - no conflict detected - PASSED\n") fh = res.resarray[-1].object stateid = res.resarray[-2].stateid res = close_file(sess3, fh, stateid=stateid) check(res)
def testDeadlock(t, env): """Trigger deadlock bug FLAGS: debug all CODE: DEBUG1 """ c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session() owner = open_owner4(0, "My Open Owner") how = openflag4(OPEN4_CREATE, createhow4(GUARDED4, {FATTR4_SIZE: 0})) claim = open_claim4(CLAIM_NULL, env.testname(t)) open_op = op.open(0, OPEN4_SHARE_ACCESS_BOTH, OPEN4_SHARE_DENY_NONE, owner, how, claim) res = sess1.compound(env.home + [open_op, op.getfh()]) # OPEN fh = res.resarray[-1].object stateid = res.resarray[-2].stateid #### def ops(i): return [ op.putfh(fh), op.write(stateid, i * 1000, UNSTABLE4, chr(97 + i) * 100), op.getattr(42950721818L) ] xids = [sess1.compound_async(ops(i), slot=i) for i in range(4)] for xid in xids: res = sess1.listen(xid) check(res) print res res = close_file(sess1, fh, stateid=stateid) check(res)
def testReadWrite(t, env): """Do a simple READ and WRITE FLAGS: open all CODE: OPEN400 """ c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session() owner = open_owner4(0, "My Open Owner") how = openflag4(OPEN4_CREATE, createhow4(GUARDED4, {FATTR4_SIZE: 0})) claim = open_claim4(CLAIM_NULL, env.testname(t)) open_op = op.open(0, OPEN4_SHARE_ACCESS_BOTH, OPEN4_SHARE_DENY_NONE, owner, how, claim) fh_op = op.putrootfh() res = sess1.compound([fh_op, open_op, op.getfh()]) # OPEN print res check(res) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid stateid.seqid = 0 res = sess1.compound( [op.putfh(fh), op.write(stateid, 5, FILE_SYNC4, "write test data")]) print res check(res) res = sess1.compound([op.putfh(fh), op.read(stateid, 0, 1000)]) print res check(res) res = close_file(sess1, fh, stateid=stateid) check(res)
def open_file(self, mds_fh): seqid = 0 access = const4.OPEN4_SHARE_ACCESS_BOTH deny = const4.OPEN4_SHARE_DENY_NONE attrs = {const4.FATTR4_MODE: 0777} owner = "mds" mode = const4.GUARDED4 verifier = self.sess.c.verifier openflag = type4.openflag4(const4.OPEN4_CREATE, type4.createhow4(mode, attrs, verifier)) name = self.fh_to_name(mds_fh) while True: if mds_fh in self.filehandles: return open_op = op4.open( seqid, access, deny, type4.open_owner4(self.sess.client.clientid, owner), openflag, type4.open_claim4(const4.CLAIM_NULL, name)) res = self._execute(nfs4lib.use_obj(self.path_fh) + [open_op, op4.getfh()], exceptions=[const4.NFS4ERR_EXIST]) if res.status == const4.NFS4_OK: ds_fh = res.resarray[-1].opgetfh.resok4.object ds_openstateid = type4.stateid4(0, res.resarray[-2].stateid.other) self.filehandles[mds_fh] = (ds_fh, ds_openstateid) return elif res.status == const4.NFS4ERR_EXIST: openflag = type4.openflag4(const4.OPEN4_NOCREATE) else: raise RuntimeError
def testDestroy3(t, env): """ - create client (exchangeid) - create session - trigger callback; check that it arrives, but don't answer it. - destroy session - create new session - check that a new callback is sent over the new session. Some servers will do this very quickly, some might take longer. FLAGS: destroy_session CODE: DSESS9003 """ recall = threading.Event() def pre_hook(arg, env): recall.stateid = arg.stateid # NOTE this must be done before set() recall.happened = True env.notify = recall.set # This is called after compound sent to queue def bad_post_hook(arg, env, res): return None; def good_post_hook(arg, env, res): return res c = env.c1.new_client(env.testname(t)) sess1 = c.create_session() sess1.compound([op.reclaim_complete(FALSE)]) res = create_file(sess1, env.testname(t), access=OPEN4_SHARE_ACCESS_READ | OPEN4_SHARE_ACCESS_WANT_READ_DELEG) check(res) fh = res.resarray[-1].object deleg = res.resarray[-2].delegation print("OPEN fh =", repr(fh)) if deleg.delegation_type == OPEN_DELEGATE_NONE: fail("Could not get delegation") recall.happened = False c2 = env.c1.new_client("%s_2" % env.testname(t)) sess2 = c2.create_session() sess2.compound([op.reclaim_complete(FALSE)]) claim = open_claim4(CLAIM_NULL, env.testname(t)) owner = open_owner4(0, "My Open Owner 2") how = openflag4(OPEN4_NOCREATE) open_op = op.open(0, OPEN4_SHARE_ACCESS_BOTH, OPEN4_SHARE_DENY_NONE, owner, how, claim) slot = sess2.compound_async(env.home + [open_op]) c.cb_pre_hook(OP_CB_RECALL, pre_hook) c.cb_post_hook(OP_CB_RECALL, bad_post_hook) recall.wait(1) # STUB - deal with timeout if not recall.happened: fail("Did not get callback") recall.happened = False # since we did not reply to callback, robust server should retry when # we give it a new backchannel to use: res = c.c.compound([op.destroy_session(sess1.sessionid)]) c.cb_pre_hook(OP_CB_RECALL, pre_hook) c.cb_post_hook(OP_CB_RECALL, good_post_hook) sess3 = c.create_session() recall.wait(100) # STUB - deal with timeout if not recall.happened: fail("Did not get callback")
def testDestroy2(t, env): """ - create client (exchangeid) - create session - destroy session - create a new session for the same client - do something that triggers a callback (look at the delegation tests for example) - check that we get the callback FLAGS: destroy_session CODE: DSESS9002 """ recall = threading.Event() def pre_hook(arg, env): recall.stateid = arg.stateid # NOTE this must be done before set() recall.happened = True env.notify = recall.set # This is called after compound sent to queue def post_hook(arg, env, res): return res c = env.c1.new_client(env.testname(t)) sess1 = c.create_session() sess1.compound([op.reclaim_complete(FALSE)]) res = c.c.compound([op.destroy_session(sess1.sessionid)]) sess2 = c.create_session() res = create_file(sess2, env.testname(t), access=OPEN4_SHARE_ACCESS_READ | OPEN4_SHARE_ACCESS_WANT_READ_DELEG) check(res) fh = res.resarray[-1].object deleg = res.resarray[-2].delegation if deleg.delegation_type == OPEN_DELEGATE_NONE: fail("Could not get delegation") c2 = env.c1.new_client("%s_2" % env.testname(t)) sess3 = c2.create_session() sess3.compound([op.reclaim_complete(FALSE)]) claim = open_claim4(CLAIM_NULL, env.testname(t)) owner = open_owner4(0, "My Open Owner 2") how = openflag4(OPEN4_NOCREATE) open_op = op.open(0, OPEN4_SHARE_ACCESS_BOTH, OPEN4_SHARE_DENY_NONE, owner, how, claim) c.cb_pre_hook(OP_CB_RECALL, pre_hook) c.cb_post_hook(OP_CB_RECALL, post_hook) slot = sess3.compound_async(env.home + [open_op]) recall.happened = False recall.wait(100) # STUB - deal with timeout if not recall.happened: fail("Did not get callback")
def test_async_read(): sess1 = env.c1.new_client_session(env.testname(t)) owner = open_owner4(0, "My Open Owner") res = create_file(sess1, env.testname(t)) check(res) expect(res, seqid=1) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid stateid.seqid = 0 data = "write test data" res = sess1.compound([op.putfh(fh), op.write(stateid, 5, FILE_SYNC4, data)]) check(res) res = sess1.compound([op.putfh(fh), op.async_read(1, 0, 5)]) check(res)