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)
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
def open_file(self, mds_fh, seqid=0, access=OPEN4_SHARE_ACCESS_BOTH, deny=OPEN4_SHARE_DENY_NONE, attrs={FATTR4_MODE: 0777}, owner="mds", mode=GUARDED4): verifier = self.sess.c.verifier openflag = openflag4(OPEN4_CREATE, createhow4(mode, attrs, verifier)) name = self.fh_to_name(mds_fh) while True: if mds_fh in self.filehandles: return open_op = op.open(seqid, access, deny, open_owner4(self.sess.client.clientid, owner), openflag, open_claim4(CLAIM_NULL, name)) res = self.execute(nfs4lib.use_obj(self.path_fh) + [open_op, op.getfh()], exceptions=[NFS4ERR_EXIST]) if res.status == NFS4_OK: ds_fh = res.resarray[-1].opgetfh.resok4.object ds_openstateid = stateid4(0, res.resarray[-2].stateid.other) self.filehandles[mds_fh] = (ds_fh, ds_openstateid) return elif res.status == NFS4ERR_EXIST: openflag = openflag4(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 _testDeleg(t, env, openaccess, want, breakaccess, sec = None, sec2 = None): recall = threading.Event() def pre_hook(arg, env): recall.stateid = arg.stateid # NOTE this must be done before set() recall.cred = env.cred.raw_cred env.notify = recall.set # This is called after compound sent to queue def post_hook(arg, env, res): return res sess1 = env.c1.new_client_session("%s_1" % env.testname(t), sec = sec) sess1.client.cb_pre_hook(OP_CB_RECALL, pre_hook) sess1.client.cb_post_hook(OP_CB_RECALL, post_hook) if sec2: sess1.compound([op.backchannel_ctl(env.c1.prog, sec2)]) fh = _create_file_with_deleg(sess1, env.testname(t), openaccess | want) sess2 = env.c1.new_client_session("%s_2" % env.testname(t)) 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, breakaccess, OPEN4_SHARE_DENY_NONE, owner, how, claim) slot = sess2.compound_async(env.home + [open_op]) # Wait for recall, and return delegation recall.wait() # STUB - deal with timeout # Getting here means CB_RECALL reply is in the send queue. # Give it a moment to actually be sent env.sleep(.1) res = sess1.compound([op.putfh(fh), op.delegreturn(recall.stateid)]) check(res) # Now get OPEN reply res = sess2.listen(slot) checklist(res, [NFS4_OK, NFS4ERR_DELAY]) return recall
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 # 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)
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() 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() 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 testDelegRevocation(t, env): """Allow a delegation to be revoked, check that TEST_STATEID and FREE_STATEID have the required effect. FLAGS: deleg all CODE: DELEG8 """ sess1 = env.c1.new_client_session("%s_1" % env.testname(t)) fh, deleg = __create_file_with_deleg( sess1, env.testname(t), OPEN4_SHARE_ACCESS_READ | OPEN4_SHARE_ACCESS_WANT_READ_DELEG) delegstateid = deleg.read.stateid sess2 = env.c1.new_client_session("%s_2" % env.testname(t)) 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_WRITE, OPEN4_SHARE_DENY_NONE, owner, how, claim) while 1: res = sess2.compound(env.home + [open_op]) if res.status == NFS4_OK: break checklist(res, [NFS4_OK, NFS4ERR_DELAY]) # just to keep sess1 renewed. This is a bit fragile, as we # depend on the above compound waiting no longer than the # server's lease period: res = sess1.compound([]) slot, seq_op = sess1._prepare_compound({}) res = sess1.c.compound([seq_op]) flags = res.resarray[0].sr_status_flags if not (flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED): fail("SEQ4_STATUS_RECALLABLE_STATE_REVOKED should be set after" " sucess of open conflicting with delegation") flags &= ~SEQ4_STATUS_RECALLABLE_STATE_REVOKED if flags: print("WARNING: unexpected status flag(s) 0x%x set" % flags) res = sess1.update_seq_state(res, slot) res = sess1.compound([op.test_stateid([delegstateid])]) stateid_stat = res.resarray[0].tsr_status_codes[0] if stateid_stat != NFS4ERR_DELEG_REVOKED: fail("TEST_STATEID on revoked stateid should report status" " NFS4ERR_DELEG_REVOKED, instead got %s" % nfsstat4[stateid_stat]) res = sess1.compound([op.free_stateid(delegstateid)]) check(res) slot, seq_op = sess1._prepare_compound({}) res = sess1.c.compound([seq_op]) flags = res.resarray[0].sr_status_flags if flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED: fail("SEQ4_STATUS_RECALLABLE_STATE_REVOKED should be cleared after" " FREE_STATEID") if flags & ~SEQ4_STATUS_RECALLABLE_STATE_REVOKED: print("WARNING: unexpected status flag(s) 0x%x set" % flags)
def testDelegRevocation(t, env): """Allow a delegation to be revoked, check that TEST_STATEID and FREE_STATEID have the required effect. FLAGS: deleg CODE: DELEG8 """ sess1 = env.c1.new_client_session("%s_1" % env.testname(t)) fh, deleg = __create_file_with_deleg(sess1, env.testname(t), OPEN4_SHARE_ACCESS_READ | OPEN4_SHARE_ACCESS_WANT_READ_DELEG) delegstateid = deleg.read.stateid sess2 = env.c1.new_client_session("%s_2" % env.testname(t)) 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_WRITE, OPEN4_SHARE_DENY_NONE, owner, how, claim) while 1: res = sess2.compound(env.home + [open_op]) if res.status == NFS4_OK: break; checklist(res, [NFS4_OK, NFS4ERR_DELAY]) # just to keep sess1 renewed. This is a bit fragile, as we # depend on the above compound waiting no longer than the # server's lease period: res = sess1.compound([]) slot, seq_op = sess1._prepare_compound({}) res = sess1.c.compound([seq_op]) flags = res.resarray[0].sr_status_flags; if not(flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED): fail("SEQ4_STATUS_RECALLABLE_STATE_REVOKED should be set after" " sucess of open conflicting with delegation") flags &= ~SEQ4_STATUS_RECALLABLE_STATE_REVOKED if flags: print("WARNING: unexpected status flag(s) 0x%x set" % flags); res = sess1.update_seq_state(res, slot) res = sess1.compound([op.test_stateid([delegstateid])]) stateid_stat = res.resarray[0].tsr_status_codes[0] if stateid_stat != NFS4ERR_DELEG_REVOKED: fail("TEST_STATEID on revoked stateid should report status" " NFS4ERR_DELEG_REVOKED, instead got %s" % nfsstat4[stateid_stat]); res = sess1.compound([op.free_stateid(delegstateid)]) check(res) slot, seq_op = sess1._prepare_compound({}) res = sess1.c.compound([seq_op]) flags = res.resarray[0].sr_status_flags if flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED: fail("SEQ4_STATUS_RECALLABLE_STATE_REVOKED should be cleared after" " FREE_STATEID") if flags & ~SEQ4_STATUS_RECALLABLE_STATE_REVOKED: print("WARNING: unexpected status flag(s) 0x%x set" % flags)
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() 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() 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 testReadDeleg(t, env): """Test read delgation handout and return FLAGS: open all CODE: OPEN20 """ recall = threading.Event() def pre_hook(arg, env): recall.stateid = arg.stateid # NOTE this must be done before set() env.notify = recall.set # This is called after compound sent to queue def post_hook(arg, env, res): return res # c1 - OPEN - READ c1 = env.c1.new_client("%s_1" % env.testname(t)) c1.cb_pre_hook(OP_CB_RECALL, pre_hook) c1.cb_post_hook(OP_CB_RECALL, post_hook) sess1 = c1.create_session() 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 if deleg.delegation_type == OPEN_DELEGATE_NONE: fail("Could not get delegation") # c2 - OPEN - WRITE c2 = env.c1.new_client("%s_2" % env.testname(t)) sess2 = c2.create_session() 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]) # Wait for recall, and return delegation recall.wait() # STUB - deal with timeout # Getting here means CB_RECALL reply is in the send queue. # Give it a moment to actually be sent env.sleep(1) res = sess1.compound([op.putfh(fh), op.delegreturn(recall.stateid)]) check(res) # Now get OPEN reply res = sess2.listen(slot) checklist(res, [NFS4_OK, NFS4ERR_DELAY])
def open_create_file_op(sess, owner, path=None, attrs={FATTR4_MODE: 0644}, access=OPEN4_SHARE_ACCESS_BOTH, deny=OPEN4_SHARE_DENY_NONE, mode=GUARDED4, verifier=None, claim_type=CLAIM_NULL, want_deleg=False, deleg_type=None, open_create=OPEN4_NOCREATE, seqid=0, clientid=0): # Set defaults if path is None: dir = sess.c.homedir name = owner else: dir = path[:-1] name = path[-1] if ((mode == EXCLUSIVE4) or (mode == EXCLUSIVE4_1)) and (verifier == None): verifier = sess.c.verifier if not want_deleg and access & OPEN4_SHARE_ACCESS_WANT_DELEG_MASK == 0: access |= OPEN4_SHARE_ACCESS_WANT_NO_DELEG # Open the file if claim_type == CLAIM_NULL: fh_op = use_obj(dir) elif claim_type == CLAIM_PREVIOUS: fh_op = [op.putfh(path)] name = None if open_create == OPEN4_CREATE: openflag = openflag4( OPEN4_CREATE, createhow4(mode, attrs, verifier, creatverfattr(verifier, attrs))) openclaim = open_claim4(CLAIM_NULL, name) else: openflag = openflag4(OPEN4_NOCREATE) openclaim = open_claim4(claim_type, name, deleg_type) open_op = op.open(seqid, access, deny, open_owner4(clientid, owner), openflag, openclaim) return fh_op + [open_op, op.getfh()]
def testWriteDeleg(t, env): """Test write delgation handout and return FLAGS: open deleg all CODE: DELEG2 """ recall = threading.Event() def pre_hook(arg, env): recall.stateid = arg.stateid # NOTE this must be done before set() env.notify = recall.set # This is called after compound sent to queue def post_hook(arg, env, res): return res # c1 - OPEN - WRITE c1 = env.c1.new_client("%s_1" % env.testname(t)) c1.cb_pre_hook(OP_CB_RECALL, pre_hook) c1.cb_post_hook(OP_CB_RECALL, post_hook) sess1 = c1.create_session() sess1.compound([op.reclaim_complete(FALSE)]) res = create_file(sess1, env.testname(t), access=OPEN4_SHARE_ACCESS_BOTH | OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG) check(res) fh = res.resarray[-1].object deleg = res.resarray[-2].delegation if deleg.delegation_type == OPEN_DELEGATE_NONE or deleg.delegation_type == OPEN_DELEGATE_NONE_EXT: fail("Could not get delegation") # c2 - OPEN - READ sess2 = env.c1.new_client_session("%s_2" % env.testname(t)) 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_READ, OPEN4_SHARE_DENY_NONE, owner, how, claim) slot = sess2.compound_async(env.home + [open_op]) # Wait for recall, and return delegation recall.wait() # STUB - deal with timeout # Getting here means CB_RECALL reply is in the send queue. # Give it a moment to actually be sent env.sleep(1) res = sess1.compound([op.putfh(fh), op.delegreturn(recall.stateid)]) check(res) # Now get OPEN reply res = sess2.listen(slot) checklist(res, [NFS4_OK, NFS4ERR_DELAY])
def open_create_file_op(sess, owner, path=None, attrs={FATTR4_MODE: 0644}, access=OPEN4_SHARE_ACCESS_BOTH, deny=OPEN4_SHARE_DENY_NONE, mode=GUARDED4, verifier=None, claim_type=CLAIM_NULL, want_deleg=False, deleg_type=None, open_create=OPEN4_NOCREATE, seqid=0, clientid=0): # Set defaults if path is None: dir = sess.c.homedir name = owner else: dir = path[:-1] name = path[-1] if ((mode==EXCLUSIVE4) or (mode==EXCLUSIVE4_1)) and (verifier==None): verifier = sess.c.verifier if not want_deleg and access & OPEN4_SHARE_ACCESS_WANT_DELEG_MASK == 0: access |= OPEN4_SHARE_ACCESS_WANT_NO_DELEG # Open the file if claim_type==CLAIM_NULL: fh_op = use_obj(dir) elif claim_type==CLAIM_PREVIOUS: fh_op = [op.putfh(path)] name = None if open_create==OPEN4_CREATE: openflag=openflag4(OPEN4_CREATE, createhow4(mode, attrs, verifier, creatverfattr(verifier, attrs))) openclaim=open_claim4(CLAIM_NULL, name) else: openflag=openflag4(OPEN4_NOCREATE) openclaim=open_claim4(claim_type, name, deleg_type) open_op = op.open(seqid, access, deny, open_owner4(clientid, owner), openflag, openclaim) return fh_op + [open_op, op.getfh()]
def create_file(sess, owner, path=None, attrs={FATTR4_MODE: 0644}, access=OPEN4_SHARE_ACCESS_BOTH, deny=OPEN4_SHARE_DENY_NONE, mode=GUARDED4, verifier=None, want_deleg=False): # Set defaults if path is None: dir = sess.c.homedir name = owner else: dir = path[:-1] name = path[-1] if (mode==EXCLUSIVE4) and (verifier==None): verifier = sess.c.verifier if not want_deleg and access & OPEN4_SHARE_ACCESS_WANT_DELEG_MASK == 0: access |= OPEN4_SHARE_ACCESS_WANT_NO_DELEG # Create the file open_op = op.open(0, access, deny, open_owner4(0, owner), openflag4(OPEN4_CREATE, createhow4(mode, attrs, verifier)), open_claim4(CLAIM_NULL, name)) return sess.compound(use_obj(dir) + [open_op, op.getfh()])
def open_file(self, mds_fh, seqid=0, access=OPEN4_SHARE_ACCESS_BOTH, deny=OPEN4_SHARE_DENY_NONE, attrs={FATTR4_MODE: 0777}, owner = "mds", mode=GUARDED4): verifier = self.sess.c.verifier openflag = openflag4(OPEN4_CREATE, createhow4(mode, attrs, verifier)) name = self.fh_to_name(mds_fh) while True: if mds_fh in self.filehandles: return open_op = op.open(seqid, access, deny, open_owner4(self.sess.client.clientid, owner), openflag, open_claim4(CLAIM_NULL, name)) res = self.execute(nfs4lib.use_obj(self.path_fh) + [open_op, op.getfh()], exceptions=[NFS4ERR_EXIST]) if res.status == NFS4_OK: ds_fh = res.resarray[-1].opgetfh.resok4.object ds_openstateid = stateid4(0, res.resarray[-2].stateid.other) self.filehandles[mds_fh] = (ds_fh, ds_openstateid) return elif res.status == NFS4ERR_EXIST: openflag = openflag4(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 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() 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() 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")