add some test case for pynfs41
Subsystems (2)
cover add some test case for pynfs41
Add some test case for pynfs41 which according to rfc5661.
thanks,
Mi Jinlong
PATCH 1/17 CLNT: check NFS4ERR_NOT_ONLY_OP for CREATE_SESSION
--- nfs4.1/server41tests/st_create_session.py | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_create_session.py +14 -0
@@ -382,3 +382,17 @@ def testMaxreqs(t, env): if nfs4lib.test_equal(sess1.fore_channel.maxrequests, chan_attrs.ca_maxrequests, "count4"): fail("Server allows surprisingly large fore_channel maxreqs") + +def testNotOnlyOp(t, env): + """Check for NFS4ERR_NOT_ONLY_OP + + FLAGS: create_session all + CODE: CSESS23 + """ + c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION with PUT_ROOTFH + chan_attrs = channel_attrs4(0,8192,8192,8192,128,8,[]) + res = c.c.compound([op.create_session(c.clientid, c.seqid, 0, + chan_attrs, chan_attrs, + 123, []), op.putrootfh()], None) + check(res, NFS4ERR_NOT_ONLY_OP)
Signature · 1 line
1.7.4.1
Re: [PATCH 01/17] CLNT: check NFS4ERR_NOT_ONLY_OP for CREATE_SESSION
Quoted 2 lines · Mi Jinlong
Signed-off-by Mi Jinlong <[email protected]>
Looks fine, thanks.--b.
Quoted 31 lines
--- nfs4.1/server41tests/st_create_session.py | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-)nfs4.1/server41tests/st_create_session.py +14
-0@@ -382,3 +382,17 @@ def testMaxreqs(t, env): if nfs4lib.test_equal(sess1.fore_channel.maxrequests, chan_attrs.ca_maxrequests, "count4"): fail("Server allows surprisingly large fore_channel maxreqs") + +def testNotOnlyOp(t, env): + """Check for NFS4ERR_NOT_ONLY_OP + + FLAGS: create_session all + CODE: CSESS23 + """ + c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION with PUT_ROOTFH + chan_attrs = channel_attrs4(0,8192,8192,8192,128,8,[]) + res = c.c.compound([op.create_session(c.clientid, c.seqid, 0, + chan_attrs, chan_attrs, + 123, []), op.putrootfh()], None) + check(res, NFS4ERR_NOT_ONLY_OP)Signature · 1 line
1.7.4.1
PATCH 2/17 CLNT: test lease period of unconfirmed record
In reply to Mi Jinlong--- nfs4.1/server41tests/st_exchange_id.py | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_exchange_id.py +26 -0
@@ -1,5 +1,6 @@ from nfs4_const import * import nfs4_ops as op +import time from environment import check, fail from nfs4_type import * from rpc import RPCAcceptError, GARBAGE_ARGS, RPCTimeout
@@ -436,3 +437,28 @@ def testNotOnlyOp(t, env): res = c.compound([op.exchange_id(owner, 0, protect, [c.impl_id]), op.putrootfh()]) # per draft 21 18.35.3, server MUST return NFS4ERR_NOT_ONLY_OP check(res, NFS4ERR_NOT_ONLY_OP) + +def testLeasePeriod(t, env): + """Any unconfirmed record that is not confirmed within + a lease period SHOULD be removed. + + FLAGS: exchange_id all + CODE: EID9 + """ + c1 = env.c1.new_client("%s_1" % env.testname(t)) + c2 = env.c1.new_client("%s_2" % env.testname(t)) + # CREATE_SESSION + chan_attrs = channel_attrs4(0,8192,8192,8192,128,8,[]) + time.sleep(80) + # Inside lease period, create_session will success. + res1 = c1.c.compound([op.create_session(c1.clientid, c1.seqid, 0, + chan_attrs, chan_attrs, + 123, [])], None) + check(res1) + + time.sleep(20) + # After lease period, create_session will get error NFS4ERR_STALE_CLIENTID + res2 = c2.c.compound([op.create_session(c2.clientid, c2.seqid, 0, + chan_attrs, chan_attrs, + 123, [])], None) + check(res2, NFS4ERR_STALE_CLIENTID)
Signature · 1 line
1.7.4.1
PATCH 3/17 CLNT: check the csr_sequence at CREATE_SESSION
--- nfs4.1/nfs4client.py | 1 + nfs4.1/server41tests/st_create_session.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 0 deletions(-)
nfs4.1/nfs4client.py +1 -0
@@ -404,6 +404,7 @@ class SendChannel(object): class SessionRecord(object): def __init__(self, csr, client): self.sessionid = csr.csr_sessionid + self.seqid = csr.csr_sequence self.client = client self.c = client.c self.cred = client.cred
nfs4.1/server41tests/st_create_session.py +15 -0
@@ -396,3 +396,18 @@ def testNotOnlyOp(t, env): chan_attrs, chan_attrs, 123, []), op.putrootfh()], None) check(res, NFS4ERR_NOT_ONLY_OP) + +def testCsr_sequence(t, env): + """The corresponding result of csa_sequence is csr_sequence, + which MUST be equal to csa_sequence. + + FLAGS: create_session all + CODE: CSESS24 + """ + c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION + chan_attrs = channel_attrs4(0,8192,8192,8192,128,8,[]) + csa_sequence = c.seqid + sess1 = c.create_session(fore_attrs=chan_attrs) + if not nfs4lib.test_equal(sess1.seqid, csa_sequence, "int"): + fail("Server returns bad csr_sequence which not equal to csa_sequence")
Signature · 1 line
1.7.4.1
Re: [PATCH 02/17] CLNT: test lease period of unconfirmed record
In reply to Mi JinlongQuoted 24 lines · Mi Jinlong
Signed-off-by Mi Jinlong <[email protected]>--- nfs4.1/server41tests/st_exchange_id.py | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-)nfs4.1/server41tests/st_exchange_id.py +4
-0@@ -1,5 +1,6 @@ from nfs4_const import * import nfs4_ops as op +import time from environment import check, fail from nfs4_type import * from rpc import RPCAcceptError, GARBAGE_ARGS, RPCTimeout@@ -436,3 +437,28 @@ def testNotOnlyOp(t, env): res = c.compound([op.exchange_id(owner, 0, protect, [c.impl_id]), op.putrootfh()]) # per draft 21 18.35.3, server MUST return NFS4ERR_NOT_ONLY_OP check(res, NFS4ERR_NOT_ONLY_OP) + +def testLeasePeriod(t, env): + """Any unconfirmed record that is not confirmed within
nfs4.1/server41tests/st_exchange_id.py def testNotOnlyOp(t, env): · line 452
Quoted 10 lines
nfs4.1/server41tests/st_exchange_id.py +10
-0+ a lease period SHOULD be removed. + + FLAGS: exchange_id all + CODE: EID9 + """ + c1 = env.c1.new_client("%s_1" % env.testname(t)) + c2 = env.c1.new_client("%s_2" % env.testname(t)) + # CREATE_SESSION + chan_attrs = channel_attrs4(0,8192,8192,8192,128,8,[]) + time.sleep(80)
Let's not hard-code any lease time. pynfs should do a getattr to find the server's lease time, and use that as the basis for calculations (we need something like the getLeaseTime in the 4.0 pynfs.)
I actually usually set the server lease time to 15 seconds for testing, just to make the tests go faster....
nfs4.1/server41tests/st_exchange_id.py def testNotOnlyOp(t, env): · line 459
Quoted 7 lines
nfs4.1/server41tests/st_exchange_id.py +7
-0+ # Inside lease period, create_session will success. + res1 = c1.c.compound([op.create_session(c1.clientid, c1.seqid, 0, + chan_attrs, chan_attrs, + 123, [])], None) + check(res1) + + time.sleep(20)
Ditto.
--b.
Quoted 9 lines
nfs4.1/server41tests/st_exchange_id.py +5
-0+ # After lease period, create_session will get error NFS4ERR_STALE_CLIENTID + res2 = c2.c.compound([op.create_session(c2.clientid, c2.seqid, 0, + chan_attrs, chan_attrs, + 123, [])], None) + check(res2, NFS4ERR_STALE_CLIENTID)Signature · 1 line
1.7.4.1
Re: [PATCH 02/17] CLNT: test lease period of unconfirmed record
J. Bruce Fields :
Quoted 39 lines · Mi Jinlong
Quoted 23 lines
Signed-off-by Mi Jinlong <[email protected]>--- nfs4.1/server41tests/st_exchange_id.py | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-)nfs4.1/server41tests/st_exchange_id.py +4
-0@@ -1,5 +1,6 @@ from nfs4_const import * import nfs4_ops as op +import time from environment import check, fail from nfs4_type import * from rpc import RPCAcceptError, GARBAGE_ARGS, RPCTimeout@@ -436,3 +437,28 @@ def testNotOnlyOp(t, env): res = c.compound([op.exchange_id(owner, 0, protect, [c.impl_id]), op.putrootfh()]) # per draft 21 18.35.3, server MUST return NFS4ERR_NOT_ONLY_OP check(res, NFS4ERR_NOT_ONLY_OP) + +def testLeasePeriod(t, env): + """Any unconfirmed record that is not confirmed withinnfs4.1/server41tests/st_exchange_id.py def testNotOnlyOp(t, env): · line 452
Quoted 10 lines
nfs4.1/server41tests/st_exchange_id.py +10
-0+ a lease period SHOULD be removed. + + FLAGS: exchange_id all + CODE: EID9 + """ + c1 = env.c1.new_client("%s_1" % env.testname(t)) + c2 = env.c1.new_client("%s_2" % env.testname(t)) + # CREATE_SESSION + chan_attrs = channel_attrs4(0,8192,8192,8192,128,8,[]) + time.sleep(80)Let's not hard-code any lease time. pynfs should do a getattr to find the server's lease time, and use that as the basis for calculations (we need something like the getLeaseTime in the 4.0 pynfs.)
Quoted 2 lines
I actually usually set the server lease time to 15 seconds for testing, just to make the tests go faster....
Agree with you!
What about the following one?
---
thanks,
Mi Jinlong
=================================
Re: [PATCH 02/17] CLNT: test lease period of unconfirmed record
Quoted 42 lines · Mi Jinlong
J. Bruce Fields :
Quoted 39 lines · Mi Jinlong
Quoted 23 lines
Signed-off-by Mi Jinlong <[email protected]>--- nfs4.1/server41tests/st_exchange_id.py | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-)nfs4.1/server41tests/st_exchange_id.py +4
-0@@ -1,5 +1,6 @@ from nfs4_const import * import nfs4_ops as op +import time from environment import check, fail from nfs4_type import * from rpc import RPCAcceptError, GARBAGE_ARGS, RPCTimeout@@ -436,3 +437,28 @@ def testNotOnlyOp(t, env): res = c.compound([op.exchange_id(owner, 0, protect, [c.impl_id]), op.putrootfh()]) # per draft 21 18.35.3, server MUST return NFS4ERR_NOT_ONLY_OP check(res, NFS4ERR_NOT_ONLY_OP) + +def testLeasePeriod(t, env): + """Any unconfirmed record that is not confirmed withinnfs4.1/server41tests/st_exchange_id.py def testNotOnlyOp(t, env): · line 452
Quoted 10 lines
nfs4.1/server41tests/st_exchange_id.py +10
-0+ a lease period SHOULD be removed. + + FLAGS: exchange_id all + CODE: EID9 + """ + c1 = env.c1.new_client("%s_1" % env.testname(t)) + c2 = env.c1.new_client("%s_2" % env.testname(t)) + # CREATE_SESSION + chan_attrs = channel_attrs4(0,8192,8192,8192,128,8,[]) + time.sleep(80)Let's not hard-code any lease time. pynfs should do a getattr to find the server's lease time, and use that as the basis for calculations (we need something like the getLeaseTime in the 4.0 pynfs.)
Quoted 5 lines
Quoted 2 lines
I actually usually set the server lease time to 15 seconds for testing, just to make the tests go faster....
Agree with you!
What about the following one?
Looks fine to me.
Review
Quoted 2 lines
(quoted diff) +2
-0+ chan_attrs = channel_attrs4(0,8192,8192,8192,128,8,[]) + time.sleep(lease - 10)
I changed this to
time.sleep(min(lease-10, 1))
so it'll sill work with single-digit lease, and left it the same otherwise.
Thanks!
--b.
Quoted 17 lines
nfs4.1/server41tests/st_exchange_id.py +12
-0+ # Inside lease period, create_session will success. + res1 = c1.c.compound([op.create_session(c1.clientid, c1.seqid, 0, + chan_attrs, chan_attrs, + 123, [])], None) + check(res1) + + time.sleep(lease + 10) + # After lease period, create_session will get error NFS4ERR_STALE_CLIENTID + res2 = c2.c.compound([op.create_session(c2.clientid, c2.seqid, 0, + chan_attrs, chan_attrs, + 123, [])], None) + check(res2, NFS4ERR_STALE_CLIENTID)Signature · 1 line
1.7.4.1
Re: [PATCH 02/17] CLNT: test lease period of unconfirmed record
J. Bruce Fields :
Quoted 51 lines · Mi Jinlong
Quoted 40 lines
J. Bruce Fields :
Quoted 38 lines · Mi Jinlong
Quoted 23 lines
Signed-off-by Mi Jinlong <[email protected]>--- nfs4.1/server41tests/st_exchange_id.py | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-)nfs4.1/server41tests/st_exchange_id.py +4
-0@@ -1,5 +1,6 @@ from nfs4_const import * import nfs4_ops as op +import time from environment import check, fail from nfs4_type import * from rpc import RPCAcceptError, GARBAGE_ARGS, RPCTimeout@@ -436,3 +437,28 @@ def testNotOnlyOp(t, env): res = c.compound([op.exchange_id(owner, 0, protect, [c.impl_id]), op.putrootfh()]) # per draft 21 18.35.3, server MUST return NFS4ERR_NOT_ONLY_OP check(res, NFS4ERR_NOT_ONLY_OP) + +def testLeasePeriod(t, env): + """Any unconfirmed record that is not confirmed withinnfs4.1/server41tests/st_exchange_id.py def testNotOnlyOp(t, env): · line 452
Quoted 10 lines
nfs4.1/server41tests/st_exchange_id.py +10
-0+ a lease period SHOULD be removed. + + FLAGS: exchange_id all + CODE: EID9 + """ + c1 = env.c1.new_client("%s_1" % env.testname(t)) + c2 = env.c1.new_client("%s_2" % env.testname(t)) + # CREATE_SESSION + chan_attrs = channel_attrs4(0,8192,8192,8192,128,8,[]) + time.sleep(80)Let's not hard-code any lease time. pynfs should do a getattr to find the server's lease time, and use that as the basis for calculations (we need something like the getLeaseTime in the 4.0 pynfs.)
Quoted 4 lines
Quoted 2 lines
I actually usually set the server lease time to 15 seconds for testing, just to make the tests go faster....
Agree with you!
What about the following one?Looks fine to me.
Review
Quoted 2 lines
(quoted diff) +2
-0+ chan_attrs = channel_attrs4(0,8192,8192,8192,128,8,[]) + time.sleep(lease - 10)
Quoted 6 lines
I changed this to
time.sleep(min(lease-10, 1))so it'll sill work with single-digit lease, and left it the same otherwise.
After testing, that's OK.
--
thanks,
Mi Jinlong
PATCH 4/17 CLNT: test with ca_maxresponsesize is too small
In reply to Mi Jinlong--- nfs4.1/server41tests/st_create_session.py | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_create_session.py +16 -0
@@ -411,3 +411,19 @@ def testCsr_sequence(t, env): sess1 = c.create_session(fore_attrs=chan_attrs) if not nfs4lib.test_equal(sess1.seqid, csa_sequence, "int"): fail("Server returns bad csr_sequence which not equal to csa_sequence") + +def testTooSmallMaxRS(t, env): + """If client selects a value for ca_maxresponsesize such that + a replier on a channel could never send a response, + server SHOULD return NFS4ERR_TOOSMALL + + FLAGS: create_session all + CODE: CSESS25 + """ + c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION with too small ca_maxresponsesize + chan_attrs = channel_attrs4(0,8192,0,8192,128,8,[]) + res = c.c.compound([op.create_session(c.clientid, c.seqid, 0, + chan_attrs, chan_attrs, + 123, [])], None) + check(res, NFS4ERR_TOOSMALL)
Signature · 1 line
1.7.4.1
PATCH 5/17 CLNT: test reply too big
In reply to Mi Jinlong--- nfs4.1/server41tests/st_create_session.py | 30 ++++++++++++++++++++++++++++- 1 files changed, 29 insertions(+), 1 deletions(-)
nfs4.1/server41tests/st_create_session.py +29 -1
@@ -1,6 +1,6 @@ from nfs4_const import * import nfs4_ops as op -from environment import check, fail +from environment import check, fail, create_file, open_file from nfs4_type import * import random import nfs4lib
@@ -427,3 +427,31 @@ def testTooSmallMaxRS(t, env): chan_attrs, chan_attrs, 123, [])], None) check(res, NFS4ERR_TOOSMALL) + +def testRepTooBig(t, env): + """If requester sends a request for which the size of the reply + would exceed ca_maxresponsesize, the replier will return + NFS4ERR_REP_TOO_BIG + + FLAGS: create_session all + CODE: CSESS26 + """ + name = env.testname(t) + c1 = env.c1.new_client(name) + # create session with a small ca_maxresponsesize + chan_attrs = channel_attrs4(0,8192,50,8192,128,8,[]) + sess1 = c1.create_session(fore_attrs=chan_attrs) + owner = "owner_%s" % name + path = sess1.c.homedir + [name] + res = create_file(sess1, owner, path, access=OPEN4_SHARE_ACCESS_BOTH) + check(res) + + # write some data to file + fh = res.resarray[-1].object + stateid = res.resarray[-2].stateid + res = sess1.compound([op.putfh(fh), op.write(stateid, 5, FILE_SYNC4, "write test data " * 10)]) + check(res) + + # read data rather than ca_maxresponsesize + res = sess1.compound([op.putfh(fh), op.read(stateid, 0, 500)]) + check(res, NFS4ERR_REP_TOO_BIG)
Signature · 1 line
1.7.4.1
PATCH 6/17 CLNT: test reply too big to cache
In reply to Mi Jinlong--- nfs4.1/server41tests/st_create_session.py | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_create_session.py +21 -0
@@ -455,3 +455,24 @@ def testRepTooBig(t, env): # read data rather than ca_maxresponsesize res = sess1.compound([op.putfh(fh), op.read(stateid, 0, 500)]) check(res, NFS4ERR_REP_TOO_BIG) + +def testRepTooBigToCache(t, env): + """If requester sends a request for which the size of the reply + would exceed ca_maxresponsesize_cached, the replier will return + NFS4ERR_REP_TOO_BIG_TO_CACHE + + FLAGS: create_session all + CODE: CSESS27 + """ + c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION with a small ca_maxresponsesize_cached + chan_attrs = channel_attrs4(0,8192,8192,10,128,8,[]) + res = c.c.compound([op.create_session(c.clientid, c.seqid, 0, + chan_attrs, chan_attrs, + 123, [])], None) + check(res) + + # SEQUENCE with cache this + sid = res.resarray[0].csr_sessionid + res = c.c.compound([op.sequence(sid, 1, 0, 0, True)]) + check(res, NFS4ERR_REP_TOO_BIG_TO_CACHE)
Signature · 1 line
1.7.4.1
PATCH 7/17 CLNT: test operation not in session
In reply to Mi Jinlong--- nfs4.1/server41tests/st_sequence.py | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_sequence.py +13 -0
@@ -301,3 +301,16 @@ def testReplayCache007(t, env): res2 = sess1.compound(ops, seq_delta=0, cache_this=False) check(res2, NFS4ERR_RETRY_UNCACHED_REP) +def testOpNotInSession(t, env): + """Operations other than SEQUENCE, BIND_CONN_TO_SESSION, EXCHANGE_ID, + CREATE_SESSION, and DESTROY_SESSION, MUST NOT appear as the + first operation in a COMPOUND. rfc5661 18.46.3 + + FLAGS: sequence all + CODE: SEQ11 + """ + c = env.c1.new_client(env.testname(t)) + + # putrootfh with out session + res = c.c.compound([op.putrootfh()]) + check(res, NFS4ERR_OP_NOT_IN_SESSION)
Signature · 1 line
1.7.4.1
PATCH 8/17 CLNT: test the sessionid, slotid and sequenceid for SEQUENCE
In reply to Mi Jinlong--- nfs4.1/server41tests/st_sequence.py | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_sequence.py +24 -0
@@ -314,3 +314,27 @@ def testOpNotInSession(t, env): # putrootfh with out session res = c.c.compound([op.putrootfh()]) check(res, NFS4ERR_OP_NOT_IN_SESSION) + +def testSessionidSequenceidSlotid(t, env): + """ The sr_sessionid result MUST equal sa_sessionid. + The sr_slotid result MUST equal sa_slotid. + The sr_sequenceid result MUST equal sa_sequenceid. + rfc5661 18.46.3 + + FLAGS: sequence all + CODE: SEQ12 + """ + c = env.c1.new_client(env.testname(t)) + sess1 = c.create_session() + + # SEQUENCE + sid = sess1.sessionid + res = c.c.compound([op.sequence(sid, 1, 2, 3, True)]) + if not nfs4lib.test_equal(res.resarray[0].sr_sessionid, sid, "opaque"): + fail("server return bad sessionid") + + if not nfs4lib.test_equal(res.resarray[0].sr_sequenceid, 1, "int"): + fail("server return bad sequenceid") + + if not nfs4lib.test_equal(res.resarray[0].sr_slotid, 2, "int"): + fail("server return bad slotid")
Signature · 1 line
1.7.4.1
PATCH 9/17 CLNT: test Bad Sequenceid At Slot
In reply to Mi Jinlong--- nfs4.1/server41tests/st_sequence.py | 25 +++++++++++++++++++++++++ 1 files changed, 25 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_sequence.py +25 -0
@@ -338,3 +338,28 @@ def testSessionidSequenceidSlotid(t, env): if not nfs4lib.test_equal(res.resarray[0].sr_slotid, 2, "int"): fail("server return bad slotid") + +def testBadSequenceidAtSlot(t, env): + """ If the difference between sa_sequenceid and the server's cached + sequence ID at the slot ID is two (2) or more, or if sa_sequenceid + is less than the cached sequence ID , server MUST return + NFS4ERR_SEQ_MISORDERED. rfc5661 18.46.3 + + FLAGS: sequence all + CODE: SEQ13 + """ + c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION + sess1 = c.create_session() + + sid = sess1.sessionid + res = c.c.compound([op.sequence(sid, 1, 2, 3, True)]) + check(res) + + seqid = res.resarray[0].sr_sequenceid + # SEQUENCE with bad sr_sequenceid + res = c.c.compound([op.sequence(sid, seqid + 2, 2, 3, True)]) + check(res, NFS4ERR_SEQ_MISORDERED) + + res = c.c.compound([op.sequence(sid, nfs4lib.dec_u32(seqid), 2, 3, True)]) + check(res, NFS4ERR_SEQ_MISORDERED)
Signature · 1 line
1.7.4.1
PATCH 10/17 CLNT: test resues slot ID
In reply to Mi Jinlong--- nfs4.1/server41tests/st_sequence.py | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_sequence.py +18 -0
@@ -363,3 +363,21 @@ def testBadSequenceidAtSlot(t, env): res = c.c.compound([op.sequence(sid, nfs4lib.dec_u32(seqid), 2, 3, True)]) check(res, NFS4ERR_SEQ_MISORDERED) + +def testReuseSlotID(t, env): + """ + + FLAGS: sequence all + CODE: SEQ14 + """ + c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION + sess1 = c.create_session() + + sid = sess1.sessionid + res = c.c.compound([op.sequence(sid, 1, 2, 3, True), op.putrootfh()]) + check(res) + + res = c.c.compound([op.sequence(sid, 1, 2, 3, True)]) + # should we also check the ERROR of NFS4ERR_SEQ_FALSE_RETRY ?? + check(res)
Signature · 1 line
1.7.4.1
Re: [PATCH 10/17] CLNT: test resues slot ID
Quoted 10 lines · Mi Jinlong
Signed-off-by Mi Jinlong <[email protected]>--- nfs4.1/server41tests/st_sequence.py | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)nfs4.1/server41tests/st_sequence.py +0
-0
nfs4.1/server41tests/st_sequence.py def testBadSequenceidAtSlot(t, env): · line 372
Quoted 10 lines
nfs4.1/server41tests/st_sequence.py +7
-0@@ -363,3 +363,21 @@ def testBadSequenceidAtSlot(t, env): res = c.c.compound([op.sequence(sid, nfs4lib.dec_u32(seqid), 2, 3, True)]) check(res, NFS4ERR_SEQ_MISORDERED) + +def testReuseSlotID(t, env): + """ + + FLAGS: sequence all + CODE: SEQ14 + """
Missing description?
nfs4.1/server41tests/st_sequence.py def testBadSequenceidAtSlot(t, env): · line 382
Quoted 10 lines
nfs4.1/server41tests/st_sequence.py +10
-0+ c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION + sess1 = c.create_session() + + sid = sess1.sessionid + res = c.c.compound([op.sequence(sid, 1, 2, 3, True), op.putrootfh()]) + check(res) + + res = c.c.compound([op.sequence(sid, 1, 2, 3, True)]) + # should we also check the ERROR of NFS4ERR_SEQ_FALSE_RETRY ??
As I understand it, the server isn't required to recognize false retries, so I don't think we can check for that.
The only useful thing to check for, I think, is just to send the same request twice and make sure the requests match.
Actually, best would be to do this with a non-idempotent operation. For example, send SEQ+RENAME twice and make sure that both renames succeed. (Whereas if the server reply cache is broken and the server attempts to rename the file again, the second rename will fail with NOENT.)
--b.
Quoted 6 lines
nfs4.1/server41tests/st_sequence.py +1
-0+ check(res)Signature · 1 line
1.7.4.1
Re: [PATCH 10/17] CLNT: test resues slot ID
J. Bruce Fields:
Quoted 12 lines · Mi Jinlong
Quoted 11 lines
Signed-off-by Mi Jinlong <[email protected]>--- nfs4.1/server41tests/st_sequence.py | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)nfs4.1/server41tests/st_sequence.py +0
-0@@ -363,3 +363,21 @@ def testBadSequenceidAtSlot(t, env):
Quoted 11 lines
nfs4.1/server41tests/st_sequence.py def testBadSequenceidAtSlot(t, env): · line 372
Quoted 9 lines
nfs4.1/server41tests/st_sequence.py +7
-0res = c.c.compound([op.sequence(sid, nfs4lib.dec_u32(seqid), 2, 3, True)]) check(res, NFS4ERR_SEQ_MISORDERED) + +def testReuseSlotID(t, env): + """ + + FLAGS: sequence all + CODE: SEQ14 + """Missing description?
Sorry! I will add it at next version.
Quoted 15 lines
nfs4.1/server41tests/st_sequence.py def testBadSequenceidAtSlot(t, env): · line 382
Quoted 11 lines
nfs4.1/server41tests/st_sequence.py +10
-0+ c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION + sess1 = c.create_session() + + sid = sess1.sessionid + res = c.c.compound([op.sequence(sid, 1, 2, 3, True), op.putrootfh()]) + check(res) + + res = c.c.compound([op.sequence(sid, 1, 2, 3, True)]) + # should we also check the ERROR of NFS4ERR_SEQ_FALSE_RETRY ??As I understand it, the server isn't required to recognize false retries, so I don't think we can check for that.
Quoted 7 lines
The only useful thing to check for, I think, is just to send the same request twice and make sure the requests match.
Actually, best would be to do this with a non-idempotent operation. For example, send SEQ+RENAME twice and make sure that both renames succeed. (Whereas if the server reply cache is broken and the server attempts to rename the file again, the second rename will fail with NOENT.)
Yes, thanks for you advice.
I will send a new patch tomorrow.
Signature · 3 lines
---- thanks Mi Jinlong
Re: [PATCH 10/17] CLNT: test resues slot ID
Quoted 47 lines · Mi Jinlong
J. Bruce Fields:
Quoted 12 lines · Mi Jinlong
Quoted 11 lines
Signed-off-by Mi Jinlong <[email protected]>--- nfs4.1/server41tests/st_sequence.py | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)nfs4.1/server41tests/st_sequence.py +0
-0@@ -363,3 +363,21 @@ def testBadSequenceidAtSlot(t, env):Quoted 11 lines
nfs4.1/server41tests/st_sequence.py def testBadSequenceidAtSlot(t, env): · line 372
Quoted 9 lines
nfs4.1/server41tests/st_sequence.py +7
-0res = c.c.compound([op.sequence(sid, nfs4lib.dec_u32(seqid), 2, 3, True)]) check(res, NFS4ERR_SEQ_MISORDERED) + +def testReuseSlotID(t, env): + """ + + FLAGS: sequence all + CODE: SEQ14 + """Missing description?
Sorry! I will add it at next version.
Quoted 18 lines
nfs4.1/server41tests/st_sequence.py def testBadSequenceidAtSlot(t, env): · line 382
Quoted 11 lines
nfs4.1/server41tests/st_sequence.py +10
-0+ c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION + sess1 = c.create_session() + + sid = sess1.sessionid + res = c.c.compound([op.sequence(sid, 1, 2, 3, True), op.putrootfh()]) + check(res) + + res = c.c.compound([op.sequence(sid, 1, 2, 3, True)]) + # should we also check the ERROR of NFS4ERR_SEQ_FALSE_RETRY ??As I understand it, the server isn't required to recognize false retries, so I don't think we can check for that.
The only useful thing to check for, I think, is just to send the same request twice and make sure the requests match.
Quoted 7 lines
Quoted 4 lines
Actually, best would be to do this with a non-idempotent operation. For example, send SEQ+RENAME twice and make sure that both renames succeed. (Whereas if the server reply cache is broken and the server attempts to rename the file again, the second rename will fail with NOENT.)
Yes, thanks for you advice.
I will send a new patch tomorrow.
OK, thanks. The patches I didn't comment on look mostly fine to me; I'll push them out to my git tree as I apply them.
--b.
Re: [PATCH 10/17] CLNT: test resues slot ID
In reply to Mi JinlongMi Jinlong :
Quoted 43 lines
J. Bruce Fields:
Quoted 12 lines · Mi Jinlong
Quoted 11 lines
Signed-off-by Mi Jinlong <[email protected]>--- nfs4.1/server41tests/st_sequence.py | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)nfs4.1/server41tests/st_sequence.py +0
-0@@ -363,3 +363,21 @@ def testBadSequenceidAtSlot(t, env):Quoted 10 lines
nfs4.1/server41tests/st_sequence.py def testBadSequenceidAtSlot(t, env): · line 372
Quoted 9 lines
nfs4.1/server41tests/st_sequence.py +7
-0res = c.c.compound([op.sequence(sid, nfs4lib.dec_u32(seqid), 2, 3, True)]) check(res, NFS4ERR_SEQ_MISORDERED) + +def testReuseSlotID(t, env): + """ + + FLAGS: sequence all + CODE: SEQ14 + """Missing description?
Sorry! I will add it at next version.
Quoted 16 lines
nfs4.1/server41tests/st_sequence.py def testBadSequenceidAtSlot(t, env): · line 382
Quoted 10 lines
nfs4.1/server41tests/st_sequence.py +10
-0+ c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION + sess1 = c.create_session() + + sid = sess1.sessionid + res = c.c.compound([op.sequence(sid, 1, 2, 3, True), op.putrootfh()]) + check(res) + + res = c.c.compound([op.sequence(sid, 1, 2, 3, True)]) + # should we also check the ERROR of NFS4ERR_SEQ_FALSE_RETRY ??As I understand it, the server isn't required to recognize false retries, so I don't think we can check for that.
The only useful thing to check for, I think, is just to send the same request twice and make sure the requests match.
Quoted 7 lines
Quoted 4 lines
Actually, best would be to do this with a non-idempotent operation. For example, send SEQ+RENAME twice and make sure that both renames succeed. (Whereas if the server reply cache is broken and the server attempts to rename the file again, the second rename will fail with NOENT.)
Yes, thanks for you advice.
I will send a new patch tomorrow.
Maybe the following one is better than before.
Signature · 4 lines
thanks, Mi Jinlong =========================================================
Re: [PATCH 10/17] CLNT: test resues slot ID
Quoted 1 line · Mi Jinlong
Maybe the following one is better than before.
Looks good to me, thanks!
Very minor nit:
Quoted 4 lines
nfs4.1/server41tests/st_sequence.py +4
-0+def testReuseSlotID(t, env): + """ If client reuses a slot ID and sequence ID for a completely + different request, server MAY treat the request as if it is + a retry of what it has already executed. rfc5661 18.46.3
nfs4.1/server41tests/st_sequence.py def testBadSequenceidAtSlot(t, env):
Quoted 10 lines
nfs4.1/server41tests/st_sequence.py +10
-0+ + FLAGS: sequence all + CODE: SEQ14 + """ + c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION + sess1 = c.create_session() + + name = "%s_1" % env.testname(t) + res = create_file(sess1, name)
Could you check your patches for trailing whitespace? (There's an extra space at the end of that line.)
(No need to resend anything.)
--b.
Quoted 19 lines
(quoted diff) +15
-0+ check(res) + + sid = sess1.sessionid + seqid = nfs4lib.inc_u32(sess1.seqid) + fh = res.resarray[3].object + homedir = sess1.c.homedir[0] + + res = c.c.compound([op.sequence(sid, seqid, 0, 0, TRUE), op.putrootfh(), + op.lookup(homedir), op.remove(name)]) + check(res) + + # Reuses slot ID and sequence ID for different request + res = c.c.compound([op.sequence(sid, seqid, 0, 0, TRUE), op.putrootfh(), + op.lookup(homedir), op.rename(name, "test")]) + check(res)Signature · 1 line
1.7.4.1
Re: [PATCH 10/17] CLNT: test resues slot ID
Quoted 4 lines · J. Bruce Fields
Quoted 1 line · Mi Jinlong
Maybe the following one is better than before.
Looks good to me, thanks!
But on testing I get a failure:
SEQ14 st_sequence.testReuseSlotID : FAILURE
AttributeError: LOOKUP4res instance has no attribute 'object'
I haven't tried to figure out what's going on there.
--b.
Quoted 44 lines
Very minor nit:
Quoted 4 lines
nfs4.1/server41tests/st_sequence.py +4
-0+def testReuseSlotID(t, env): + """ If client reuses a slot ID and sequence ID for a completely + different request, server MAY treat the request as if it is + a retry of what it has already executed. rfc5661 18.46.3nfs4.1/server41tests/st_sequence.py def testBadSequenceidAtSlot(t, env):
Quoted 10 lines
nfs4.1/server41tests/st_sequence.py +10
-0+ + FLAGS: sequence all + CODE: SEQ14 + """ + c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION + sess1 = c.create_session() + + name = "%s_1" % env.testname(t) + res = create_file(sess1, name)Could you check your patches for trailing whitespace? (There's an extra space at the end of that line.)
(No need to resend anything.)
--b.
Quoted 19 lines
(quoted diff) +15
-0+ check(res) + + sid = sess1.sessionid + seqid = nfs4lib.inc_u32(sess1.seqid) + fh = res.resarray[3].object + homedir = sess1.c.homedir[0] + + res = c.c.compound([op.sequence(sid, seqid, 0, 0, TRUE), op.putrootfh(), + op.lookup(homedir), op.remove(name)]) + check(res) + + # Reuses slot ID and sequence ID for different request + res = c.c.compound([op.sequence(sid, seqid, 0, 0, TRUE), op.putrootfh(), + op.lookup(homedir), op.rename(name, "test")]) + check(res)Signature · 1 line
1.7.4.1
Re: [PATCH 10/17] CLNT: test resues slot ID
J. Bruce Fields:
Quoted 10 lines · J. Bruce Fields
Quoted 3 lines · Mi Jinlong
Quoted 1 line
Maybe the following one is better than before.
Looks good to me, thanks!
But on testing I get a failure:
SEQ14 st_sequence.testReuseSlotID : FAILURE
AttributeError: LOOKUP4res instance has no attribute 'object'
See below.
Quoted 23 lines
I haven't tried to figure out what's going on there.
--b.
Quoted 18 lines
Very minor nit:
Quoted 4 lines
nfs4.1/server41tests/st_sequence.py +4
-0+def testReuseSlotID(t, env): + """ If client reuses a slot ID and sequence ID for a completely + different request, server MAY treat the request as if it is + a retry of what it has already executed. rfc5661 18.46.3nfs4.1/server41tests/st_sequence.py def testBadSequenceidAtSlot(t, env):
Quoted 10 lines
nfs4.1/server41tests/st_sequence.py +10
-0+ + FLAGS: sequence all + CODE: SEQ14 + """ + c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION + sess1 = c.create_session() + + name = "%s_1" % env.testname(t) + res = create_file(sess1, name)Could you check your patches for trailing whitespace? (There's an extra space at the end of that line.)
I will pay attention to that in the future.
Quoted 10 lines
Quoted 10 lines
(No need to resend anything.)
--b.
Quoted 5 lines
(quoted diff) +5
-0+ check(res) + + sid = sess1.sessionid + seqid = nfs4lib.inc_u32(sess1.seqid) + fh = res.resarray[3].object
The error only appears here.
At my machine, the res.resarray[3] is GETFHres.
As the above error message shown res.resarray[3] is LOOKUP4res. Is it the nfs4lib's problem?
--
thanks,
Mi Jinlong
Quoted 19 lines
Quoted 6 lines
Quoted 6 lines
nfs4.1/server41tests/st_sequence.py +6
-0+ homedir = sess1.c.homedir[0] + + res = c.c.compound([op.sequence(sid, seqid, 0, 0, TRUE), op.putrootfh(), + op.lookup(homedir), op.remove(name)]) + check(res) +Quoted 8 lines
Quoted 8 lines
(quoted diff) +4
-0+ # Reuses slot ID and sequence ID for different request + res = c.c.compound([op.sequence(sid, seqid, 0, 0, TRUE), op.putrootfh(), + op.lookup(homedir), op.rename(name, "test")]) + check(res)Signature · 1 line
1.7.4.1--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 10/17] CLNT: test resues slot ID
Quoted 53 lines · Mi Jinlong
J. Bruce Fields:
Quoted 10 lines · J. Bruce Fields
Quoted 3 lines · Mi Jinlong
Quoted 1 line
Maybe the following one is better than before.
Looks good to me, thanks!
But on testing I get a failure:
SEQ14 st_sequence.testReuseSlotID : FAILURE
AttributeError: LOOKUP4res instance has no attribute 'object'See below.
Quoted 23 lines
I haven't tried to figure out what's going on there.
--b.
Quoted 18 lines
Very minor nit:
Quoted 4 lines
(quoted diff) +4
-0+def testReuseSlotID(t, env): + """ If client reuses a slot ID and sequence ID for a completely + different request, server MAY treat the request as if it is + a retry of what it has already executed. rfc5661 18.46.3Review
Quoted 10 lines
(quoted diff) +10
-0+ + FLAGS: sequence all + CODE: SEQ14 + """ + c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION + sess1 = c.create_session() + + name = "%s_1" % env.testname(t) + res = create_file(sess1, name)Could you check your patches for trailing whitespace? (There's an extra space at the end of that line.)
I will pay attention to that in the future.
Quoted 10 lines
Quoted 10 lines
(No need to resend anything.)
--b.
Quoted 5 lines
(quoted diff) +5
-0+ check(res) + + sid = sess1.sessionid + seqid = nfs4lib.inc_u32(sess1.seqid) + fh = res.resarray[3].object
Quoted 5 lines
The error only appears here.
At my machine, the res.resarray[3] is GETFHres.
As the above error message shown res.resarray[3] is LOOKUP4res. Is it the nfs4lib's problem?
Oh, are you assuming that the GETFH op is always at the same position in the compound?
You can't do that--the number of LOOKUPS required to get to the file depends on how deep in the server's pseudofs the file is.
Note the following "homedir = " line also assumes that the pynfs tests are being run on /, but that's not necessarily true.
--b.
Quoted 25 lines
--
thanks,
Mi JinlongQuoted 19 lines
Quoted 6 lines
Quoted 6 lines
(quoted diff) +6
-0+ homedir = sess1.c.homedir[0] + + res = c.c.compound([op.sequence(sid, seqid, 0, 0, TRUE), op.putrootfh(), + op.lookup(homedir), op.remove(name)]) + check(res) +Quoted 8 lines
Quoted 8 lines
(quoted diff) +4
-0+ # Reuses slot ID and sequence ID for different request + res = c.c.compound([op.sequence(sid, seqid, 0, 0, TRUE), op.putrootfh(), + op.lookup(homedir), op.rename(name, "test")]) + check(res)Signature · 1 line
1.7.4.1--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 10/17] CLNT: test resues slot ID
J. Bruce Fields:
Quoted 53 lines · Mi Jinlong
Quoted 46 lines
J. Bruce Fields:
Quoted 9 lines · J. Bruce Fields
Quoted 3 lines · Mi Jinlong
Quoted 1 line
Maybe the following one is better than before.
Looks good to me, thanks!
But on testing I get a failure:
SEQ14 st_sequence.testReuseSlotID : FAILURE
AttributeError: LOOKUP4res instance has no attribute 'object'See below.
Quoted 22 lines
I haven't tried to figure out what's going on there.
--b.
Quoted 18 lines
Very minor nit:
Quoted 4 lines
(quoted diff) +4
-0+def testReuseSlotID(t, env): + """ If client reuses a slot ID and sequence ID for a completely + different request, server MAY treat the request as if it is + a retry of what it has already executed. rfc5661 18.46.3Review
Quoted 10 lines
(quoted diff) +10
-0+ + FLAGS: sequence all + CODE: SEQ14 + """ + c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION + sess1 = c.create_session() + + name = "%s_1" % env.testname(t) + res = create_file(sess1, name)Could you check your patches for trailing whitespace? (There's an extra space at the end of that line.)
I will pay attention to that in the future.
Quoted 9 lines
Quoted 9 lines
(No need to resend anything.)
--b.
Quoted 5 lines
(quoted diff) +5
-0+ check(res) + + sid = sess1.sessionid + seqid = nfs4lib.inc_u32(sess1.seqid) + fh = res.resarray[3].objectQuoted 5 lines
The error only appears here.
At my machine, the res.resarray[3] is GETFHres.
As the above error message shown res.resarray[3] is LOOKUP4res. Is it the nfs4lib's problem?
Quoted 8 lines
Oh, are you assuming that the GETFH op is always at the same position in the compound?
You can't do that--the number of LOOKUPS required to get to the file depends on how deep in the server's pseudofs the file is.
Note the following "homedir = " line also assumes that the pynfs tests are being run on /, but that's not necessarily true.
I have made a mistake about this case, we don't need the filehandle from GETFHres, that is just unnecessary.
Thanks for your point about the homedir,
I found a function named use_obj at nfs4lib which can solve our problem.
After fixed, maybe the following patch is OK now.
---
thanks,
Mi Jinlong
Quoted 1 line
From
e9faf0c2e86421012296f95ce5cd9cd3338f98a2Mon Sep 17 00:00:00 2001
From: Mi Jinlong <[email protected]>
Date: Mon, 22 Mar 2011 19:25:23 +0800
Subject: [PATCH] CLNT: test resues slot ID
--- nfs4.1/server41tests/st_sequence.py | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_sequence.py +29 -0
@@ -363,3 +363,32 @@ def testBadSequenceidAtSlot(t, env): res = c.c.compound([op.sequence(sid, nfs4lib.dec_u32(seqid), 2, 3, True)]) check(res, NFS4ERR_SEQ_MISORDERED) + +def testReuseSlotID(t, env): + """ If client reuses a slot ID and sequence ID for a completely + different request, server MAY treat the request as if it is + a retry of what it has already executed. rfc5661 18.46.3 + + FLAGS: sequence all + CODE: SEQ14 + """ + c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION + sess1 = c.create_session() + + name = "%s_1" % env.testname(t) + res = create_file(sess1, name) + check(res) + + sid = sess1.sessionid + seqid = nfs4lib.inc_u32(sess1.seqid) + dir = sess1.c.homedir + + res = c.c.compound([op.sequence(sid, seqid, 0, 0, TRUE)] + + nfs4lib.use_obj(dir) + [op.remove(name)]) + check(res) + + # Reuses slot ID and sequence ID for different request + res = c.c.compound([op.sequence(sid, seqid, 0, 0, TRUE)] + + nfs4lib.use_obj(dir) + [op.rename(name, "test")]) + check(res)
Signature · 1 line
1.7.4.1
Re: [PATCH 10/17] CLNT: test resues slot ID
Quoted 7 lines · Mi Jinlong
I have made a mistake about this case, we don't need the filehandle from GETFHres, that is just unnecessary.
Thanks for your point about the homedir,
I found a function nameduse_objat nfs4lib which can solve our problem.After fixed, maybe the following patch is OK now.
Great, thanks--applied.
At this point I've applied and pushed out everything I've taken from you.
So let me know what else you still have that's not in my git repo. I know there are the reclaim_complete tests that you're still looking at, but there might also be a few other odd tests that I still had questions about?
--b.
Quoted 58 lines
---
thanks,
Mi JinlongQuoted 1 line
From
e9faf0c2e86421012296f95ce5cd9cd3338f98a2Mon Sep 17 00:00:00 2001From: Mi Jinlong <[email protected]>
Date: Mon, 22 Mar 2011 19:25:23 +0800
Subject: [PATCH] CLNT: test resues slot IDSigned-off-by Mi Jinlong <[email protected]>--- nfs4.1/server41tests/st_sequence.py | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-)nfs4.1/server41tests/st_sequence.py +29
-0@@ -363,3 +363,32 @@ def testBadSequenceidAtSlot(t, env): res = c.c.compound([op.sequence(sid, nfs4lib.dec_u32(seqid), 2, 3, True)]) check(res, NFS4ERR_SEQ_MISORDERED) + +def testReuseSlotID(t, env): + """ If client reuses a slot ID and sequence ID for a completely + different request, server MAY treat the request as if it is + a retry of what it has already executed. rfc5661 18.46.3 + + FLAGS: sequence all + CODE: SEQ14 + """ + c = env.c1.new_client(env.testname(t)) + # CREATE_SESSION + sess1 = c.create_session() + + name = "%s_1" % env.testname(t) + res = create_file(sess1, name) + check(res) + + sid = sess1.sessionid + seqid = nfs4lib.inc_u32(sess1.seqid) + dir = sess1.c.homedir + + res = c.c.compound([op.sequence(sid, seqid, 0, 0, TRUE)] + + nfs4lib.use_obj(dir) + [op.remove(name)]) + check(res) + + # Reuses slot ID and sequence ID for different request + res = c.c.compound([op.sequence(sid, seqid, 0, 0, TRUE)] + + nfs4lib.use_obj(dir) + [op.rename(name, "test")]) + check(res)Signature · 1 line
1.7.4.1
Re: [PATCH 10/17] CLNT: test resues slot ID
J. Bruce Fields:
Quoted 7 lines · Mi Jinlong
Quoted 6 lines
I have made a mistake about this case, we don't need the filehandle from GETFHres, that is just unnecessary.
Thanks for your point about the homedir,
I found a function nameduse_objat nfs4lib which can solve our problem.
Quoted 6 lines
Quoted 1 line
After fixed, maybe the following patch is OK now.
Great, thanks--applied.
At this point I've applied and pushed out everything I've taken from you.
Thanks.
Quoted 5 lines
So let me know what else you still have that's not in my git repo. I know there are the
reclaim_completetests that you're still looking at, but there might also be a few other odd tests that I still had questions about?
No. Just those tests about reclaim_complete.
Maybe I have meet some other problem about pynfs41 tests, I will send the fixing out after I check out.
Signature · 3 lines
---- thanks Mi Jinlong
PATCH 11/17 CLNT: DESTROY_SESSION not the fianl operation
In reply to Mi Jinlong--- nfs4.1/server41tests/st_destroy_session.py | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_destroy_session.py +16 -0
@@ -133,3 +133,19 @@ def testDestroy3(t, env): if not recall.happened: fail("Did not get callback") +def testDestoryNotFinalOps(t, env): + """ If the COMPOUND request starts with SEQUENCE, DESTROY_SESSION + MUST be the final operation in the COMPOUND request. + rfc5661 18.37.3 + + FLAGS: destroy_session + CODE: DSESS9004 + """ + c = env.c1.new_client(env.testname(t)) + sess1 = c.create_session() + + sid = sess1.sessionid + res = c.c.compound([op.sequence(sid, 1, 2, 3, False), + op.destroy_session(sess1.sessionid), + op.putrootfh()]) + check(res, NFS4ERR_NOT_ONLY_OP)
Signature · 1 line
1.7.4.1
PATCH 12/17 CLNT: test DESTROY_SESSION not the sole operation
In reply to Mi Jinlong--- nfs4.1/server41tests/st_destroy_session.py | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_destroy_session.py +18 -0
@@ -149,3 +149,21 @@ def testDestoryNotFinalOps(t, env): op.destroy_session(sess1.sessionid), op.putrootfh()]) check(res, NFS4ERR_NOT_ONLY_OP) + +def testDestoryNotSoleOps(t, env): + """ If the COMPOUND request does not start with SEQUENCE, + and DESTROY_SESSION is not the sole operation, + then server MUST return NFS4ERR_NOT_ONLY_OP. rfc5661 18.37.3 + + FLAGS: destroy_session + CODE: DSESS9005 + """ + c = env.c1.new_client(env.testname(t)) + sess1 = c.create_session() + + sid = sess1.sessionid + res = c.c.compound([op.destroy_session(sess1.sessionid), op.putrootfh()]) + check(res, NFS4ERR_NOT_ONLY_OP) + + res = c.c.compound([op.putrootfh(), op.destroy_session(sess1.sessionid)]) + check(res, NFS4ERR_NOT_ONLY_OP)
Signature · 1 line
1.7.4.1
PATCH 13/17 CLNT: add a simple test about RECLAIM_COMPLETE
In reply to Mi Jinlong--- nfs4.1/server41tests/__init__.py | 1 + nfs4.1/server41tests/st_reclaim_complete.py | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 0 deletions(-) create mode 100644 nfs4.1/server41tests/st_reclaim_complete.py
nfs4.1/server41tests/__init__.py +1 -0
@@ -2,6 +2,7 @@ __all__ = ["st_exchange_id.py", # draft 21 "st_compound.py", "st_create_session.py", "st_destroy_session.py", + "st_reclaim_complete.py", "st_secinfo_no_name.py", "st_secinfo.py", "st_sequence.py",
nfs4.1/server41tests/st_reclaim_complete.py new file +21 -0
@@ -0,0 +1,21 @@ +from st_create_session import create_session +from nfs4_const import * +from environment import check, fail, use_obj, create_file +import nfs4_ops as op +import nfs4lib + +def testSupported(t, env): + """Do a simple RECLAIM_COMPLETE + + FLAGS: all + CODE: RECC1 + """ + c = env.c1.new_client(env.testname(t)) + sess = c.create_session() + + # RECLAIM_COMPLETE + res = sess.compound([op.reclaim_complete(FALSE)]) + check(res) + + res = sess.compound([op.putrootfh(), op.reclaim_complete(TRUE)]) + check(res)
Signature · 1 line
1.7.4.1
PATCH 14/17 CLNT: test reclaim after RECLAIM_COMPLETE
In reply to Mi Jinlong--- nfs4.1/server41tests/st_reclaim_complete.py | 31 +++++++++++++++++++++++++++ 1 files changed, 31 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_reclaim_complete.py +31 -0
@@ -1,6 +1,7 @@ from st_create_session import create_session from nfs4_const import * from environment import check, fail, use_obj, create_file +from nfs4_type import open_owner4, locker4, open_to_lock_owner4 import nfs4_ops as op import nfs4lib
@@ -19,3 +20,33 @@ def testSupported(t, env): res = sess.compound([op.putrootfh(), op.reclaim_complete(TRUE)]) check(res) + +def testReclaimAfterRECC(t, env): + """If client does subsequent reclaims of locking state after + RECLAIM_COMPLETE is done, server will return NFS4ERR_NO_GRACE. + rfc5661 18.51.3 + + FLAGS: all + CODE: RECC2 + """ + name = env.testname(t) + c = env.c1.new_client(name) + sess = c.create_session() + + # RECLAIM_COMPLETE + res = sess.compound([op.reclaim_complete(FALSE)]) + check(res) + + fname = "owner_%s" % name + path = sess.c.homedir + [name] + res = create_file(sess, fname, path, access=OPEN4_SHARE_ACCESS_BOTH) + check(res) + + oseqid = res.resarray[2].stateid + cfh = res.resarray[3].object + owner = open_owner4(0, "My Open Owner") + otlowner = open_to_lock_owner4(0, oseqid, 0, owner) + lowner = locker4(TRUE, otlowner) + + res = sess.compound([op.putfh(cfh), op.lock(READ_LT, TRUE, 0, 1, lowner)]) + check(res, NFS4ERR_NO_GRACE)
Signature · 1 line
1.7.4.1
PATCH 15/17 CLNT: test lock before RECLAIM_COMPLETE
In reply to Mi Jinlong--- nfs4.1/server41tests/st_reclaim_complete.py | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_reclaim_complete.py +26 -0
@@ -50,3 +50,29 @@ def testReclaimAfterRECC(t, env): res = sess.compound([op.putfh(cfh), op.lock(READ_LT, TRUE, 0, 1, lowner)]) check(res, NFS4ERR_NO_GRACE) + +def testLockBeforeRECC(t, env): + """After a client establishes a new client ID, if non-reclaim + locking operations are done before the RECLAIM_COMPLETE, + error NFS4ERR_GRACE will be returned. rfc5661 18.51.3 + + FLAGS: all + CODE: RECC3 + """ + name = env.testname(t) + c = env.c1.new_client(name) + sess = c.create_session() + + fname = "owner_%s" % name + path = sess.c.homedir + [name] + res = create_file(sess, fname, path, access=OPEN4_SHARE_ACCESS_BOTH) + check(res) + + oseqid = res.resarray[2].stateid + cfh = res.resarray[3].object + owner = open_owner4(0, "My Open Owner") + otlowner = open_to_lock_owner4(0, oseqid, 0, owner) + lowner = locker4(TRUE, otlowner) + + res = sess.compound([op.putfh(cfh), op.lock(READ_LT, FALSE, 0, 1, lowner)]) + check(res, NFS4ERR_NO_GRACE)
Signature · 1 line
1.7.4.1
Re: [PATCH 15/17] CLNT: test lock before RECLAIM_COMPLETE
Quoted 1 line · Mi Jinlong
Signed-off-by Mi Jinlong <[email protected]>
I'm getting failures I don't understand on these reclaim complete tests too.
--b.
Quoted 43 lines
--- nfs4.1/server41tests/st_reclaim_complete.py | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-)nfs4.1/server41tests/st_reclaim_complete.py +26
-0@@ -50,3 +50,29 @@ def testReclaimAfterRECC(t, env): res = sess.compound([op.putfh(cfh), op.lock(READ_LT, TRUE, 0, 1, lowner)]) check(res, NFS4ERR_NO_GRACE) + +def testLockBeforeRECC(t, env): + """After a client establishes a new client ID, if non-reclaim + locking operations are done before the RECLAIM_COMPLETE, + error NFS4ERR_GRACE will be returned. rfc5661 18.51.3 + + FLAGS: all + CODE: RECC3 + """ + name = env.testname(t) + c = env.c1.new_client(name) + sess = c.create_session() + + fname = "owner_%s" % name + path = sess.c.homedir + [name] + res = create_file(sess, fname, path, access=OPEN4_SHARE_ACCESS_BOTH) + check(res) + + oseqid = res.resarray[2].stateid + cfh = res.resarray[3].object + owner = open_owner4(0, "My Open Owner") + otlowner = open_to_lock_owner4(0, oseqid, 0, owner) + lowner = locker4(TRUE, otlowner) + + res = sess.compound([op.putfh(cfh), op.lock(READ_LT, FALSE, 0, 1, lowner)]) + check(res, NFS4ERR_NO_GRACE)Signature · 1 line
1.7.4.1
Re: [PATCH 15/17] CLNT: test lock before RECLAIM_COMPLETE
J. Bruce Fields:
Quoted 5 lines · Mi Jinlong
Quoted 1 line
Signed-off-by Mi Jinlong <[email protected]>I'm getting failures I don't understand on these reclaim complete tests too.
Maybe there are some problem I have missing.
If testing reclaim-complete, we should restart server's NFS service. I think those tests about reclaim-complete need some fix.
After fixed, I will send those patch again.
--
thanks,
Mi Jinlong
Quoted 47 lines
--b.
Quoted 43 lines
--- nfs4.1/server41tests/st_reclaim_complete.py | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-)nfs4.1/server41tests/st_reclaim_complete.py +26
-0@@ -50,3 +50,29 @@ def testReclaimAfterRECC(t, env): res = sess.compound([op.putfh(cfh), op.lock(READ_LT, TRUE, 0, 1, lowner)]) check(res, NFS4ERR_NO_GRACE) + +def testLockBeforeRECC(t, env): + """After a client establishes a new client ID, if non-reclaim + locking operations are done before the RECLAIM_COMPLETE, + error NFS4ERR_GRACE will be returned. rfc5661 18.51.3 + + FLAGS: all + CODE: RECC3 + """ + name = env.testname(t) + c = env.c1.new_client(name) + sess = c.create_session() + + fname = "owner_%s" % name + path = sess.c.homedir + [name] + res = create_file(sess, fname, path, access=OPEN4_SHARE_ACCESS_BOTH) + check(res) + + oseqid = res.resarray[2].stateid + cfh = res.resarray[3].object + owner = open_owner4(0, "My Open Owner") + otlowner = open_to_lock_owner4(0, oseqid, 0, owner) + lowner = locker4(TRUE, otlowner) + + res = sess.compound([op.putfh(cfh), op.lock(READ_LT, FALSE, 0, 1, lowner)]) + check(res, NFS4ERR_NO_GRACE)Signature · 1 line
1.7.4.1
Re: [PATCH 15/17] CLNT: test lock before RECLAIM_COMPLETE
Quoted 6 lines · Mi Jinlong
J. Bruce Fields:
Quoted 3 lines · Mi Jinlong
Quoted 1 line
Signed-off-by Mi Jinlong <[email protected]>
Quoted 7 lines
Quoted 2 lines
I'm getting failures I don't understand on these reclaim complete tests too.
Maybe there are some problem I have missing.
If testing reclaim-complete, we should restart server's NFS service. I think those tests about reclaim-complete need some fix.
Probably so.
Also:
Quoted 2 lines
Quoted 2 lines
nfs4.1/server41tests/st_reclaim_complete.py def testReclaimAfterRECC(t, env): · line 72
Quoted 2 lines
nfs4.1/server41tests/st_reclaim_complete.py +2
-0+ oseqid = res.resarray[2].stateid + cfh = res.resarray[3].object
This has the same problem as SEQ14, I suspect.
In general I'm nervous about grabbing results directly out of the resarray. We shouldn't have to know so much about the structure of a compound that some other part of the code constructed.
--b.
Quoted 13 lines
Quoted 12 lines
Quoted 11 lines
nfs4.1/server41tests/st_reclaim_complete.py +6
-0+ owner = open_owner4(0, "My Open Owner") + otlowner = open_to_lock_owner4(0, oseqid, 0, owner) + lowner = locker4(TRUE, otlowner) + + res = sess.compound([op.putfh(cfh), op.lock(READ_LT, FALSE, 0, 1, lowner)]) + check(res, NFS4ERR_NO_GRACE)Signature · 1 line
1.7.4.1
PATCH 16/17 CLNT: test double RECLAIM_COMPLETE after create session
In reply to Mi Jinlong--- nfs4.1/server41tests/st_reclaim_complete.py | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_reclaim_complete.py +19 -0
@@ -76,3 +76,22 @@ def testLockBeforeRECC(t, env): res = sess.compound([op.putfh(cfh), op.lock(READ_LT, FALSE, 0, 1, lowner)]) check(res, NFS4ERR_NO_GRACE) + +def testDoubleRECC(t, env): + """If RECLAIM_COMPLETE is done a second time, error + NFS4ERR_COMPLETE_ALREADY will be returned. rfc5661 18.51.4 + + FLAGS: all + CODE: RECC4 + """ + name = env.testname(t) + c = env.c1.new_client(name) + sess = c.create_session() + + # RECLAIM_COMPLETE + res = sess.compound([op.reclaim_complete(FALSE)]) + check(res) + + # RECLAIM_COMPLETE again + res = sess.compound([op.reclaim_complete(FALSE)]) + check(res, NFS4ERR_COMPLETE_ALREADY)
Signature · 1 line
1.7.4.1
PATCH 17/17 CLNT: test EXCLUSIVE4_1 for different verifier
In reply to Mi Jinlong--- nfs4.1/server41tests/environment.py | 5 +++-- nfs4.1/server41tests/st_open.py | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-)
nfs4.1/server41tests/environment.py +3 -2
@@ -458,13 +458,14 @@ def create_file(sess, owner, path=None, attrs={FATTR4_MODE: 0644}, else: dir = path[:-1] name = path[-1] - if (mode==EXCLUSIVE4) and (verifier==None): + 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 # Create the file open_op = op.open(seqid, access, deny, open_owner4(clientid, owner), - openflag4(OPEN4_CREATE, createhow4(mode, attrs, verifier)), + openflag4(OPEN4_CREATE, createhow4(mode, attrs, verifier, + creatverfattr(verifier, attrs))), open_claim4(CLAIM_NULL, name)) return sess.compound(use_obj(dir) + [open_op, op.getfh()])
nfs4.1/server41tests/st_open.py +18 -0
@@ -2,6 +2,7 @@ from st_create_session import create_session from nfs4_const import * from environment import check, checklist, fail, create_file, open_file from nfs4_type import open_owner4, openflag4, createhow4, open_claim4 +from nfs4_type import creatverfattr, fattr4 import nfs4_ops as op import threading
@@ -201,3 +202,20 @@ def testReadWrite(t, env): if res.resarray[-1].data != desired: fail("Expected %r, got %r" % (desired, res.resarray[-1].data)) +def testEXCLUSIVE4AtNameAttribute(t, env): + """If the file does exist,but the stored verifier does not match, + then an error of NFS4ERR_EXIST is returned from server. + rfc5661 18.16.3 + + FLAGS: open all + CODE: OPEN6 + """ + c1 = env.c1.new_client(env.testname(t)) + sess1 = c1.create_session() + + res = create_file(sess1, env.testname(t), mode=EXCLUSIVE4_1) + check(res) + + res = create_file(sess1, env.testname(t), mode=EXCLUSIVE4_1, + verifier = "Justtest") + check(res, NFS4ERR_EXIST)
Signature · 1 line
1.7.4.1
Quoted 1 line · Mi Jinlong
Add some test case for pynfs41 which according to rfc5661.
This is great, thanks!
It'll take me a little time to work through them....
--b.
cover a pynfs41 problem and some tests about RECLAIM_COMPLETE
In reply to Mi JinlongFix a pynfs41 problem and some tests about RECLAIM_COMPLETE.
Signature · 3 lines
---- thanks Mi Jinlong
PATCH 1/5 CLNT: try to destroy session after test complete
When testing pynfs41, I got NFS4ERR_DELAY at some tests. At a test case, we don't destroy the session after create. So, this patch try to destroy session test complete.
--- nfs4.1/nfs4client.py | 4 +++ nfs4.1/server41tests/environment.py | 1 + nfs4.1/server41tests/st_block.py | 4 +++ nfs4.1/server41tests/st_create_session.py | 20 +++++++++++++++ nfs4.1/server41tests/st_debug.py | 6 ++++ nfs4.1/server41tests/st_destroy_session.py | 9 +++++++ nfs4.1/server41tests/st_exchange_id.py | 12 ++++++++- nfs4.1/server41tests/st_getdevicelist.py | 11 ++++++++ nfs4.1/server41tests/st_lookup.py | 5 ++++ nfs4.1/server41tests/st_lookupp.py | 11 ++++++++ nfs4.1/server41tests/st_open.py | 10 +++++++ nfs4.1/server41tests/st_putfh.py | 8 ++++++ nfs4.1/server41tests/st_reboot.py | 1 + nfs4.1/server41tests/st_rename.py | 36 ++++++++++++++++++++++++++++ nfs4.1/server41tests/st_secinfo.py | 2 + nfs4.1/server41tests/st_secinfo_no_name.py | 2 + nfs4.1/server41tests/st_sequence.py | 18 ++++++++++++++ nfs4.1/server41tests/st_trunking.py | 4 +++ nfs4.1/server41tests/st_verify.py | 1 + 19 files changed, 164 insertions(+), 1 deletions(-)
nfs4.1/nfs4client.py +4 -0
@@ -495,6 +495,10 @@ class SessionRecord(object): res.resarray = res.resarray[1:] return res + def destroy(self): + res = self.c.compound([op.destroy_session(self.sessionid)]) + nfs4lib.check(res) + ## def open(self, owner, name=None, type=OPEN4_NOCREATE, ## mode=UNCHECKED4, attrs={FATTR4_MODE:0644}, verf=None, ## access=OPEN4_SHARE_ACCESS_READ,
nfs4.1/server41tests/environment.py +1 -0
@@ -153,6 +153,7 @@ class Environment(testmod.Environment): # Make sure it is empty clean_dir(sess, self.opts.home) sess.c.null() + sess.destroy() def _maketree(self, sess): """Make test tree"""
nfs4.1/server41tests/st_block.py +4 -0
@@ -49,6 +49,7 @@ def testStateid1(t, env): # the server increments by one the value of the "seqid" in each # subsequent LAYOUTGET and LAYOUTRETURN response, fail("Expected stateid.seqid==%i, got %i" % (i+2, lo_stateid.seqid)) + sess.destroy_session() def testStateid2(t, env): """Check for proper sequence handling in layout stateids.
@@ -109,6 +110,7 @@ def testStateid2(t, env): layoutupdate4(LAYOUT4_BLOCK_VOLUME, p.get_buffer()))] res = sess.compound(ops) check(res) + sess.destroy_session() def testEmptyCommit(t, env): """Check for proper handling of empty LAYOUTCOMMIT.
@@ -171,6 +173,7 @@ def testEmptyCommit(t, env): layoutupdate4(LAYOUT4_BLOCK_VOLUME, ""))] res = sess.compound(ops) check(res) + sess.destroy_session() def testSplitCommit(t, env): """Check for proper handling of disjoint LAYOUTCOMMIT.opaque
@@ -218,3 +221,4 @@ def testSplitCommit(t, env): layoutupdate4(LAYOUT4_BLOCK_VOLUME, p.get_buffer()))] res = sess.compound(ops) check(res) + sess.destroy_session()
nfs4.1/server41tests/st_create_session.py +20 -0
@@ -25,6 +25,7 @@ def testSupported1(t, env): """ c = env.c1.new_client(env.testname(t)) sess = c.create_session() + sess.destroy(); def testSupported2(t, env): """Do a CREATE_SESSION after a SEQUENCE (for same client)
@@ -44,6 +45,8 @@ def testSupported2(t, env): # Now make sure sess2 works res = sess2.compound([op.putrootfh()]) check(res) + sess1.destroy(); + sess2.destroy(); def testSupported2b(t, env): """Do a CREATE_SESSION after a SEQUENCE (for different client)
@@ -64,6 +67,8 @@ def testSupported2b(t, env): # Now make sure sess2 works res = sess2.compound([op.putrootfh()]) check(res) + sess1.destroy(); + sess2.destroy(); def testNoExchange(t, env): """Send CREATE_SESSION when server has no record of clientid
@@ -132,6 +137,8 @@ def testReplay1a(t, env): if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") + sess1.destroy(); + def testReplay1b(t, env): """Replay a successful SEQUENCE:CREATE_SESSION without a preceeding SEQUENCE
@@ -156,6 +163,8 @@ def testReplay1b(t, env): if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") + sess1.destroy(); + def testReplay2(t, env): """Replay a unsuccessful CREATE_SESSION
@@ -251,6 +260,7 @@ def testCbSecParms(t, env): c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session(sec=sec) + sess1.destroy(); def testCbSecParmsDec(t, env): """A decode problem was found at NFS server
@@ -267,6 +277,7 @@ def testCbSecParmsDec(t, env): c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session(sec=sec) + sess1.destroy(); def testRdmaArray0(t, env): """Test 0 length rdma arrays
@@ -278,6 +289,7 @@ def testRdmaArray0(t, env): chan_attrs = channel_attrs4(0, 8192,8192,8192,128,8,[]) sess1 = c1.create_session(fore_attrs=chan_attrs, back_attrs=chan_attrs) + sess1.destroy(); def testRdmaArray1(t, env): """Test length 1 rdma arrays
@@ -289,6 +301,7 @@ def testRdmaArray1(t, env): chan_attrs = channel_attrs4(0,8192,8192,8192,128,8,[57]) sess1 = c1.create_session(fore_attrs=chan_attrs, back_attrs=chan_attrs) + sess1.destroy(); def testRdmaArray2(t, env): """Test length 2 rdma arrays
@@ -351,6 +364,8 @@ def testCallbackProgram(t, env): finally: env.c1._check_program = orig + sess.destroy(); + def testCallbackVersion(t, env): """Check server sends callback program with a version listed in nfs4client.py
@@ -380,6 +395,8 @@ def testCallbackVersion(t, env): finally: env.c1._check_version = orig + sess.destroy() + def testMaxreqs(t, env): """A CREATE_SESSION with maxreqs too large should return a modified value
@@ -428,6 +445,8 @@ def testCsr_sequence(t, env): if not nfs4lib.test_equal(sess1.seqid, csa_sequence, "int"): fail("Server returns bad csr_sequence which not equal to csa_sequence") + sess1.destroy() + def testTooSmallMaxRS(t, env): """If client selects a value for ca_maxresponsesize such that a replier on a channel could never send a response,
@@ -471,6 +490,7 @@ def testRepTooBig(t, env): # read data rather than ca_maxresponsesize res = sess1.compound([op.putfh(fh), op.read(stateid, 0, 500)]) check(res, NFS4ERR_REP_TOO_BIG) + sess1.destroy() def testRepTooBigToCache(t, env): """If requester sends a request for which the size of the reply
nfs4.1/server41tests/st_debug.py +6 -0
@@ -30,6 +30,8 @@ def testSupported2(t, env): # STUB - since we are not handling callback, deleg_return never gets done print res check(res) + sess1.destroy() + sess2.destroy() def testReadWrite(t, env): """Do a simple READ and WRITE
@@ -57,6 +59,7 @@ def testReadWrite(t, env): res = sess1.compound([op.putfh(fh), op.read(stateid, 0, 1000)]) print res check(res) + sess1.destroy() def testDeadlock(t, env):
@@ -86,6 +89,7 @@ def testDeadlock(t, env): res = sess1.listen(xid) check(res) print res + sess1.destroy() def testLayout(t, env): """Verify layout handling
@@ -118,6 +122,7 @@ def testLayout(t, env): 0, 0xffffffff, 0, 0xffff)] res = sess.compound(ops) check(res) + sess.destroy() def testGetDevList(t, env): """Check devlist
@@ -142,3 +147,4 @@ def testGetDevList(t, env): ops = use_obj(env.opts.path) + [op.getdevicelist(LAYOUT4_BLOCK_VOLUME, 0, 0, "")] res = sess.compound(ops) check(res) + sess.destroy()
nfs4.1/server41tests/st_destroy_session.py +9 -0
@@ -27,6 +27,7 @@ def testDestroy(t, env): env.c1.compound([sess.seq_op()], pipe=rogue) res = c.c.compound([op.destroy_session(sess.sessionid)], pipe=rogue) check(res) + sess.destroy() def testDestroy2(t, env): """
@@ -74,6 +75,9 @@ def testDestroy2(t, env): recall.wait(100) # STUB - deal with timeout if not recall.happened: fail("Did not get callback") + sess1.destroy() + sess2.destroy() + sess3.destroy() def testDestroy3(t, env): """
@@ -132,6 +136,9 @@ def testDestroy3(t, env): recall.wait(100) # STUB - deal with timeout if not recall.happened: fail("Did not get callback") + sess1.destroy() + sess2.destroy() + sess3.destroy() def testDestoryNotFinalOps(t, env): """ If the COMPOUND request starts with SEQUENCE, DESTROY_SESSION
@@ -149,6 +156,7 @@ def testDestoryNotFinalOps(t, env): op.destroy_session(sess1.sessionid), op.putrootfh()]) check(res, NFS4ERR_NOT_ONLY_OP) + sess1.destroy() def testDestoryNotSoleOps(t, env): """ If the COMPOUND request does not start with SEQUENCE,
@@ -167,3 +175,4 @@ def testDestoryNotSoleOps(t, env): res = c.c.compound([op.putrootfh(), op.destroy_session(sess1.sessionid)]) check(res, NFS4ERR_NOT_ONLY_OP) + sess1.destroy()
nfs4.1/server41tests/st_exchange_id.py +11 -1
@@ -56,7 +56,7 @@ def testSupported2(t, env): # per draft 21 13.1, server MUST set one of these bits if not (res.resarray[0].eir_flags & EXCHGID4_FLAG_MASK_PNFS): fail("server did not set any EXCHGID4_FLAG_USE_* bits") - + sess1.destroy() def testSSV(t, env): """Do a simple EXCHANGE_ID
@@ -84,6 +84,7 @@ def testSSV(t, env): # SET_SSV res = sess.set_ssv('\x5a' * c.protect.context.ssv_len) print res + sess.destroy() def testNoImplId(t, env): """Do a simple EXCHANGE_ID w/o setting client impl_id
@@ -213,6 +214,7 @@ def testNoUpdate100(t, env): # Check that cred1 state is destroyed res = sess1.compound([]) check(res, NFS4ERR_BADSESSION) + sess1.destroy() # Need similar tests of 100 for expired lease, existing state (IN_USE)
@@ -237,6 +239,7 @@ def testNoUpdate101(t, env): res = sess1.compound([]) check(res, NFS4ERR_BADSESSION) # FIXME - more checks here + sess1.destroy() def testNoUpdate110(t, env): """
@@ -255,6 +258,7 @@ def testNoUpdate110(t, env): # Check that cred1 state is destroyed res = sess1.compound([]) check(res, NFS4ERR_BADSESSION) + sess1.destroy() # Need similar tests of 110 for expired lease, existing state (IN_USE)
@@ -272,6 +276,7 @@ def testNoUpdate111(t, env): if c1.clientid != c2.clientid: fail("Expected clientid %i, got %i" % (c1.clientid, c2.clientid)) # STUB - really want to check to see if E_ID results are the same + sess1.destroy() def testUpdateNonexistant(t, env): """Do an EXCHANGE_ID update of a non-existant record
@@ -357,6 +362,7 @@ def testUpdate100(t, env): cred=env.cred2, flags=EXCHGID4_FLAG_UPD_CONFIRMED_REC_A, expect=NFS4ERR_NOT_SAME) + sess1.destroy() def testUpdate101(t, env): """
@@ -372,6 +378,7 @@ def testUpdate101(t, env): cred=env.cred1, flags=EXCHGID4_FLAG_UPD_CONFIRMED_REC_A, expect=NFS4ERR_NOT_SAME) + sess1.destroy() def testUpdate110(t, env): """
@@ -387,6 +394,7 @@ def testUpdate110(t, env): cred=env.cred2, flags=EXCHGID4_FLAG_UPD_CONFIRMED_REC_A, expect=NFS4ERR_PERM) + sess1.destroy() def testUpdate111(t, env):
@@ -406,6 +414,7 @@ def testUpdate111(t, env): fail("Record update changed clientid from %r to %r\n" % (c1.clientid, c2.clientid)) # STUB - want to check update occurred + sess1.destroy() # Want test similar to testUpdate111, that tries to update qqc that cant update
@@ -472,3 +481,4 @@ def testLeasePeriod(t, env): chan_attrs, chan_attrs, 123, [])], None) check(res2, NFS4ERR_STALE_CLIENTID) + sess.destroy()
nfs4.1/server41tests/st_getdevicelist.py +11 -0
@@ -32,6 +32,7 @@ def testGetDevList(t, env): # STUB - check block stuff dev_list = res.resarray[-1].gdlr_deviceid_list print dev_list + sess.destroy() def testGetDevInfo(t, env): """Check devlist
@@ -69,6 +70,8 @@ def testGetDevInfo(t, env): p.done() print decode + sess.destroy() + ## def xxxtestLayout(t, env): ## """Verify layout handling
@@ -140,6 +143,8 @@ def testGetLayout(t, env): p.done() print opaque + sess.destroy() + def testEMCGetLayout(t, env): """Verify layout handling
@@ -183,6 +188,8 @@ def testEMCGetLayout(t, env): p.done() print opaque + sess.destroy() + def testLayoutReturnFile(t, env): """ Return a file's layout
@@ -215,6 +222,7 @@ def testLayoutReturnFile(t, env): layoutreturn_file4(0, 0xffffffffffffffff, layout_stateid, "")))] res = sess.compound(ops) check(res) + sess.destroy() def testLayoutReturnFsid(t, env): """
@@ -247,6 +255,7 @@ def testLayoutReturnFsid(t, env): layoutreturn4(LAYOUTRETURN4_FSID))] res = sess.compound(ops) check(res) + sess.destroy() def testLayoutReturnAll(t, env): """
@@ -278,6 +287,7 @@ def testLayoutReturnAll(t, env): layoutreturn4(LAYOUTRETURN4_ALL))] res = sess.compound(ops) check(res) + sess.destroy() def testLayoutCommit(t, env): """
@@ -341,5 +351,6 @@ def testLayoutCommit(t, env): res = sess.compound(ops) check(res) print res + sess.destroy()
nfs4.1/server41tests/st_lookup.py +5 -0
@@ -12,6 +12,7 @@ def testHome(t, env): sess1 = c1.create_session() res = sess1.compound(env.home + [op.getfh()]) check(res) + sess1.destroy() def testNoFh(t, env): """LOOKUP should fail with NFS4ERR_NOFILEHANDLE if no (cfh)
@@ -23,6 +24,7 @@ def testNoFh(t, env): sess1 = c1.create_session() res = sess1.compound([op.lookup(env.testname(t))]) check(res, NFS4ERR_NOFILEHANDLE, "LOOKUP with no <cfh>") + sess1.destroy() def testNonExistent(t, env): """LOOKUP with non-existent components should return NFS4ERR_NOENT
@@ -36,6 +38,7 @@ def testNonExistent(t, env): res = sess1.compound(env.home + [op.lookup(name)]) check(res, NFS4ERR_NOENT, "LOOKUP with non-existant component '%s'" % name) + sess1.destroy() def testZeroLength(t, env): """LOOKUP with zero length name should return NFS4ERR_INVAL
@@ -47,6 +50,7 @@ def testZeroLength(t, env): sess1 = c1.create_session() res = sess1.compound([op.putrootfh(), op.lookup('')]) check(res, NFS4ERR_INVAL, "LOOKUP with no zero-length component") + sess1.destroy() def testLongName(t, env): """LOOKUP should fail with NFS4ERR_NAMETOOLONG with long filenames
@@ -58,6 +62,7 @@ def testLongName(t, env): sess1 = c1.create_session() res = sess1.compound([op.putrootfh(), op.lookup('abc' * 512)]) check(res, NFS4ERR_NAMETOOLONG, "LOOKUP with very long component") + sess1.destroy() # STUB - if get NOENT, check fattr4_maxname # NOTE there is NO limit on component4 length
nfs4.1/server41tests/st_lookupp.py +11 -0
@@ -22,6 +22,7 @@ def testLookupp(t, env): if res.resarray[2*i+1].object != res.resarray[-(2*i+1)].object: t.fail('LOOKUPP returned %r, expected %r' % (res.resarray[-(2*i+1)].object, res.resarray[2*i+1].object)) + sess1.destroy() def testFile(t, env): """LOOKUPP with non-dir (cfh)
@@ -34,6 +35,7 @@ def testFile(t, env): ops = use_obj(env.opts.usefile) + [op.lookupp()] res = sess1.compound(ops) check(res, NFS4ERR_NOTDIR, "LOOKUPP with non-dir <cfh>") + sess1.destroy() def testFifo(t, env): """LOOKUPP with non-dir (cfh)
@@ -46,6 +48,7 @@ def testFifo(t, env): ops = use_obj(env.opts.usefifo) + [op.lookupp()] res = sess1.compound(ops) check(res, NFS4ERR_NOTDIR, "LOOKUPP with non-dir <cfh>") + sess1.destroy() def testLink(t, env): """LOOKUPP with non-dir (cfh)
@@ -58,6 +61,7 @@ def testLink(t, env): ops = use_obj(env.opts.uselink) + [op.lookupp()] res = sess1.compound(ops) check(res, NFS4ERR_SYMLINK, "LOOKUPP with non-dir <cfh>") + sess1.destroy() def testBlock(t, env): """LOOKUPP with non-dir (cfh)
@@ -70,6 +74,7 @@ def testBlock(t, env): ops = use_obj(env.opts.useblock) + [op.lookupp()] res = sess1.compound(ops) check(res, NFS4ERR_NOTDIR, "LOOKUPP with non-dir <cfh>") + sess1.destroy() def testChar(t, env): """LOOKUPP with non-dir (cfh)
@@ -82,6 +87,7 @@ def testChar(t, env): ops = use_obj(env.opts.usechar) + [op.lookupp()] res = sess1.compound(ops) check(res, NFS4ERR_NOTDIR, "LOOKUPP with non-dir <cfh>") + sess1.destroy() def testSock(t, env): """LOOKUPP with non-dir (cfh)
@@ -94,6 +100,7 @@ def testSock(t, env): ops = use_obj(env.opts.usesocket) + [op.lookupp()] res = sess1.compound(ops) check(res, NFS4ERR_NOTDIR, "LOOKUPP with non-dir <cfh>") + sess1.destroy() def testLookuppRoot(t, env): """Lookupp from root should return NFS4ERR_NOENT
@@ -108,6 +115,7 @@ def testLookuppRoot(t, env): fh = res.resarray[-1].object res = sess1.compound([op.putfh(fh), op.lookupp()]) check(res, NFS4ERR_NOENT) + sess1.destroy() def testNoFH(t, env): """Lookup without a cfh should return NFS4ERR_NOFILEHANDLE
@@ -119,6 +127,7 @@ def testNoFH(t, env): sess1 = c1.create_session() res = sess1.compound([op.lookupp()]) check(res, NFS4ERR_NOFILEHANDLE) + sess1.destroy() def testXdev(t, env): """LOOKUPP with dir on different fs
@@ -138,3 +147,5 @@ def testXdev(t, env): fh2 = res.resarray[-1].object if fh1 != fh2: t.fail("file handles not equal") + + sess1.destroy()
nfs4.1/server41tests/st_open.py +10 -0
@@ -30,6 +30,7 @@ def testSupported(t, env): # see draft-10 line 19445 # QUESTION - what does "If the server supports the new _WANT_ flags" mean? # will the server return INVAL? NOTSUPP? or just silently ignore? + sess1.destroy() def testServerStateSeqid(t, env): """Do multiple OPENs of a file, check that server bumps stateid.seqid
@@ -49,6 +50,7 @@ def testServerStateSeqid(t, env): check(res) expect(res, seqid=2) # STUB - need to check no delegation return + sess1.destroy() # Test outdate, see draft22 8.2.2 def xtestClientStateSeqid(t, env):
@@ -73,6 +75,7 @@ def xtestClientStateSeqid(t, env): stateid = res.resarray[-2].stateid res = sess1.compound([op.putfh(fh), op.write(stateid, 5, FILE_SYNC4, "write test data")]) check(res, NFS4ERR_BAD_STATEID, "Using an open_stateid w/o zeroing the seqid") + sess1.destroy() # Test outdated by draft15 8.8
@@ -96,6 +99,7 @@ def xtestOpenSeqid(t, env): res = open_file(sess1, owner, path, access=OPEN4_SHARE_ACCESS_READ, seqid=1) check(res, NFS4ERR_INVAL, msg="Using non-zero seqid in OPEN") + sess1.destroy() # Test outdated by draft15 8.8
@@ -116,6 +120,7 @@ def xtestOpenClientid(t, env): sess1 = c1.create_session() res = create_file(sess1, env.testname(t), clientid=c1.clientid) check(res, NFS4ERR_INVAL, msg="Using non-zero clientid in open_owner") + sess1.destroy() def testReadDeleg(t, env): """Test read delgation handout and return
@@ -173,6 +178,9 @@ def testReadDeleg(t, env): print res checklist(res, [NFS4_OK, NFS4ERR_DELAY]) print "FRED - done" + + sess1.destroy() + sess2.destroy()
@@ -201,6 +209,7 @@ def testReadWrite(t, env): desired = "\0"*5 + data if res.resarray[-1].data != desired: fail("Expected %r, got %r" % (desired, res.resarray[-1].data)) + sess1.destroy() def testEXCLUSIVE4AtNameAttribute(t, env): """If the file does exist,but the stored verifier does not match,
@@ -219,3 +228,4 @@ def testEXCLUSIVE4AtNameAttribute(t, env): res = create_file(sess1, env.testname(t), mode=EXCLUSIVE4_1, verifier = "Justtest") check(res, NFS4ERR_EXIST) + sess1.destroy()
nfs4.1/server41tests/st_putfh.py +8 -0
@@ -23,6 +23,7 @@ def testFile(t, env): c = env.c1.new_client(env.testname(t)) sess = c.create_session() _try_put(t, sess, env.opts.usefile) + sess.destroy() def testLink(t, env): """PUTFH followed by GETFH should end up with original fh
@@ -33,6 +34,7 @@ def testLink(t, env): c = env.c1.new_client(env.testname(t)) sess = c.create_session() _try_put(t, sess, env.opts.uselink) + sess.destroy() def testBlock(t, env): """PUTFH followed by GETFH should end up with original fh
@@ -43,6 +45,7 @@ def testBlock(t, env): c = env.c1.new_client(env.testname(t)) sess = c.create_session() _try_put(t, sess, env.opts.useblock) + sess.destroy() def testChar(t, env): """PUTFH followed by GETFH should end up with original fh
@@ -53,6 +56,7 @@ def testChar(t, env): c = env.c1.new_client(env.testname(t)) sess = c.create_session() _try_put(t, sess, env.opts.usechar) + sess.destroy() def testDir(t, env): """PUTFH followed by GETFH should end up with original fh
@@ -63,6 +67,7 @@ def testDir(t, env): c = env.c1.new_client(env.testname(t)) sess = c.create_session() _try_put(t, sess, env.opts.usedir) + sess.destroy() def testFifo(t, env): """PUTFH followed by GETFH should end up with original fh
@@ -73,6 +78,7 @@ def testFifo(t, env): c = env.c1.new_client(env.testname(t)) sess = c.create_session() _try_put(t, sess, env.opts.usefifo) + sess.destroy() def testSocket(t, env): """PUTFH followed by GETFH should end up with original fh
@@ -83,6 +89,7 @@ def testSocket(t, env): c = env.c1.new_client(env.testname(t)) sess = c.create_session() _try_put(t, sess, env.opts.usesocket) + sess.destroy() def testBadHandle(t, env): """PUTFH with bad filehandle should return NFS4ERR_BADHANDLE
@@ -94,3 +101,4 @@ def testBadHandle(t, env): sess = c.create_session() res = sess.compound([op.putfh('abc')]) check(res, NFS4ERR_BADHANDLE, "PUTFH with bad filehandle='abc'") + sess.destroy()
nfs4.1/server41tests/st_reboot.py +1 -0
@@ -74,3 +74,4 @@ def testRebootValid(t, env): reclaim_complete(sess) finally: env.sleep(sleeptime, "Waiting for grace period to end") + sess.destroy()
nfs4.1/server41tests/st_rename.py +36 -0
@@ -17,6 +17,7 @@ def testValidDir(t, env): res = rename_obj(sess, basedir + ['dir1', 'foo'], basedir + ['dir2', 'bar']) check(res, msg="RENAME of directory %s/dir1/foo to %s/dir2/bar" % (name, name)) + sess.destroy() def testValidFile(t, env): """RENAME : normal operation
@@ -32,6 +33,7 @@ def testValidFile(t, env): res = rename_obj(sess, basedir + ['dir1', 'foo'], basedir + ['dir2', 'bar']) check(res, msg="RENAME of file %s/dir1/foo to %s/dir2/bar" % (name, name)) + sess.destroy() def testValidLink(t, env): """RENAME : normal operation
@@ -49,6 +51,7 @@ def testValidLink(t, env): res = rename_obj(sess, basedir + ['dir1', 'foo'], basedir + ['dir2', 'bar']) check(res, msg="RENAME of symlink %s/dir1/foo to %s/dir2/bar" % (name, name)) + sess.destroy() def testValidBlock(t, env): """RENAME : normal operation
@@ -66,6 +69,7 @@ def testValidBlock(t, env): res = rename_obj(sess, basedir + ['dir1', 'foo'], basedir + ['dir2', 'bar']) check(res, msg="RENAME of block device %s/dir1/foo to %s/dir2/bar" % (name, name)) + sess.destroy() def testValidChar(t, env): """RENAME : normal operation
@@ -83,6 +87,7 @@ def testValidChar(t, env): res = rename_obj(sess, basedir + ['dir1', 'foo'], basedir + ['dir2', 'bar']) check(res, msg="RENAME of character device %s/dir1/foo to %s/dir2/bar" % (name, name)) + sess.destroy() def testValidFifo(t, env): """RENAME : normal operation
@@ -100,6 +105,7 @@ def testValidFifo(t, env): res = rename_obj(sess, basedir + ['dir1', 'foo'], basedir + ['dir2', 'bar']) check(res, msg="RENAME of fifo %s/dir1/foo to %s/dir2/bar" % (name, name)) + sess.destroy() def testValidSocket(t, env): """RENAME : normal operation
@@ -117,6 +123,7 @@ def testValidSocket(t, env): res = rename_obj(sess, basedir + ['dir1', 'foo'], basedir + ['dir2', 'bar']) check(res, msg="RENAME of socket %s/dir1/foo to %s/dir2/bar" % (name, name)) + sess.destroy() def testSfhFile(t, env): """RENAME with non-dir (sfh) should return NFS4ERR_NOTDIR
@@ -129,6 +136,7 @@ def testSfhFile(t, env): sess = c.create_session() res = rename_obj(sess, env.opts.usefile + [name], env.c1.homedir + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <sfh>") + sess.destroy() def testSfhLink(t, env): """RENAME with non-dir (sfh) should return NFS4ERR_NOTDIR
@@ -141,6 +149,7 @@ def testSfhLink(t, env): sess = c.create_session() res = rename_obj(sess, env.opts.uselink + [name], env.c1.homedir + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <sfh>") + sess.destroy() def testSfhBlock(t, env): """RENAME with non-dir (sfh) should return NFS4ERR_NOTDIR
@@ -153,6 +162,7 @@ def testSfhBlock(t, env): sess = c.create_session() res = rename_obj(sess, env.opts.useblock + [name], env.c1.homedir + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <sfh>") + sess.destroy() def testSfhChar(t, env): """RENAME with non-dir (sfh) should return NFS4ERR_NOTDIR
@@ -165,6 +175,7 @@ def testSfhChar(t, env): sess = c.create_session() res = rename_obj(sess, env.opts.usechar + [name], env.c1.homedir + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <sfh>") + sess.destroy() def testSfhFifo(t, env): """RENAME with non-dir (sfh) should return NFS4ERR_NOTDIR
@@ -177,6 +188,7 @@ def testSfhFifo(t, env): sess = c.create_session() res = rename_obj(sess, env.opts.usefifo + [name], env.c1.homedir + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <sfh>") + sess.destroy() def testSfhSocket(t, env): """RENAME with non-dir (sfh) should return NFS4ERR_NOTDIR
@@ -189,6 +201,7 @@ def testSfhSocket(t, env): sess = c.create_session() res = rename_obj(sess, env.opts.usesocket + [name], env.c1.homedir + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <sfh>") + sess.destroy() def testCfhFile(t, env): """RENAME with non-dir (cfh) should return NFS4ERR_NOTDIR
@@ -203,6 +216,7 @@ def testCfhFile(t, env): check(res) res = rename_obj(sess, env.c1.homedir + [name], env.opts.usefile + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <cfh>") + sess.destroy() def testCfhLink(t, env): """RENAME with non-dir (cfh) should return NFS4ERR_NOTDIR
@@ -217,6 +231,7 @@ def testCfhLink(t, env): check(res) res = rename_obj(sess, env.c1.homedir + [name], env.opts.uselink + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <cfh>") + sess.destroy() def testCfhBlock(t, env): """RENAME with non-dir (cfh) should return NFS4ERR_NOTDIR
@@ -231,6 +246,7 @@ def testCfhBlock(t, env): check(res) res = rename_obj(sess, env.c1.homedir + [name], env.opts.useblock + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <cfh>") + sess.destroy() def testCfhChar(t, env): """RENAME with non-dir (cfh) should return NFS4ERR_NOTDIR
@@ -245,6 +261,7 @@ def testCfhChar(t, env): check(res) res = rename_obj(sess, env.c1.homedir + [name], env.opts.usechar + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <cfh>") + sess.destroy() def testCfhFifo(t, env): """RENAME with non-dir (cfh) should return NFS4ERR_NOTDIR
@@ -259,6 +276,7 @@ def testCfhFifo(t, env): check(res) res = rename_obj(sess, env.c1.homedir + [name], env.opts.usefifo + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <cfh>") + sess.destroy() def testCfhSocket(t, env): """RENAME with non-dir (cfh) should return NFS4ERR_NOTDIR
@@ -273,6 +291,7 @@ def testCfhSocket(t, env): check(res) res = rename_obj(sess, env.c1.homedir + [name], env.opts.usesocket + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <cfh>") + sess.destroy() def testNoSfh(t, env): """RENAME without (sfh) should return NFS4ERR_NOFILEHANDLE
@@ -286,6 +305,7 @@ def testNoSfh(t, env): ops = env.home + [op.rename(name, name)] res = sess.compound(ops) check(res, NFS4ERR_NOFILEHANDLE, "RENAME with no <sfh>") + sess.destroy() # FRED - can't test No Cfh, with a Sfh
@@ -303,6 +323,7 @@ def testNonExistent(t, env): check(res) res = rename_obj(sess, basedir + ['foo'], basedir + ['bar']) check(res, NFS4ERR_NOENT, "RENAME on non-existing object %s/foo" % name) + sess.destroy() def testZeroLengthOldname(t, env): """RENAME with zero length oldname should return NFS4ERR_INVAL
@@ -318,6 +339,7 @@ def testZeroLengthOldname(t, env): check(res) res = rename_obj(sess, basedir + [''], basedir + ['bar']) check(res, NFS4ERR_INVAL, "RENAME with zero length oldname") + sess.destroy() def testZeroLengthNewname(t, env): """RENAME with zero length newname should return NFS4ERR_INVAL
@@ -333,6 +355,7 @@ def testZeroLengthNewname(t, env): check(res) res = rename_obj(sess, basedir + ['foo'], basedir + ['']) check(res, NFS4ERR_INVAL, "RENAME with zero length newname") + sess.destroy() def testBadutf8Oldname(t, env): """RENAME with non-UTF8 oldname should return NFS4ERR_INVAL
@@ -350,6 +373,7 @@ def testBadutf8Oldname(t, env): res = rename_obj(sess, basedir + [bad_utf8], basedir + [name]) check(res, NFS4ERR_INVAL, "RENAME with non-UTF8 oldname %s/%s" % (name, repr(bad_utf8)[1:-1])) + sess.destroy() def testBadutf8Newname(t, env): """RENAME with non-UTF8 newname should return NFS4ERR_INVAL
@@ -366,6 +390,7 @@ def testBadutf8Newname(t, env): res = rename_obj(sess, basedir + [name], basedir + [bad_utf8]) check(res, NFS4ERR_INVAL, "RENAME with non-UTF8 newname %s/%s" % (name, repr(bad_utf8)[1:-1])) + sess.destroy() def testDotsOldname(t, env): """RENAME from nonexistant . or .. should return _NOENT/_BADNAME
@@ -384,6 +409,7 @@ def testDotsOldname(t, env): res = rename_obj(sess, basedir + ['..'], basedir + [name]) check(res, NFS4ERR_BADNAME, "RENAME from nonexistant '..'", [NFS4ERR_NOENT]) + sess.destroy() def testDotsNewname(t, env): """RENAME into . or .. should return _BADNAME or NFS4_OK
@@ -402,6 +428,7 @@ def testDotsNewname(t, env): res = rename_obj(sess, basedir + [name], basedir + ['..']) check(res, NFS4ERR_BADNAME, "RENAME into '..'", [NFS4_OK]) + sess.destroy() def testDirToObj(t, env): """RENAME dir into existing nondir should return NFS4ERR_EXIST
@@ -416,6 +443,7 @@ def testDirToObj(t, env): maketree(sess, [name, ['dir'], 'file']) res = rename_obj(sess, basedir + ['dir'], basedir + ['file']) check(res, NFS4ERR_EXIST, "RENAME dir into existing file") + sess.destroy() def testDirToDir(t, env): """RENAME dir into existing, empty dir should retrun NFS4_OK
@@ -430,6 +458,7 @@ def testDirToDir(t, env): maketree(sess, [name, ['dir1', ['foo']], ['dir2']]) res = rename_obj(sess, basedir + ['dir1'], basedir + ['dir2']) check(res, msg="RENAME dir1 into existing, empty dir2") + sess.destroy() def testFileToDir(t, env): """RENAME file into existing dir should return NFS4ERR_EXIST
@@ -444,6 +473,7 @@ def testFileToDir(t, env): maketree(sess, [name, ['dir'], 'file']) res = rename_obj(sess, basedir + ['file'], basedir + ['dir']) check(res, NFS4ERR_EXIST, "RENAME file into existing dir") + sess.destroy() def testFileToFile(t, env): """RENAME file into existing file should return NFS4_OK
@@ -458,6 +488,7 @@ def testFileToFile(t, env): maketree(sess, [name, 'file1', 'file2']) res = rename_obj(sess, basedir + ['file1'], basedir + ['file2']) check(res, msg="RENAME file1 into existing file2") + sess.destroy() def testDirToFullDir(t, env): """RENAME dir into existing, nonempty dir should return NFS4ERR_EXIST
@@ -472,6 +503,7 @@ def testDirToFullDir(t, env): maketree(sess, [name, ['dir1'], ['dir2', ['foo']]]) res = rename_obj(sess, basedir + ['dir1'], basedir + ['dir2']) check(res, NFS4ERR_EXIST, "RENAME dir1 into existing, nonempty dir2") + sess.destroy() def testFileToFullDir(t, env): """RENAME file into existing, nonempty dir should return NFS4ERR_EXIST
@@ -486,6 +518,7 @@ def testFileToFullDir(t, env): maketree(sess, [name, 'file', ['dir', ['foo']]]) res = rename_obj(sess, basedir + ['file'], basedir + ['dir']) check(res, NFS4ERR_EXIST, "RENAME file into existing, nonempty dir") + sess.destroy() def testSelfRenameDir(t, env): """RENAME that does nothing
@@ -505,6 +538,7 @@ def testSelfRenameDir(t, env): if scinfo.before != scinfo.after or tcinfo.before != tcinfo.after: t.fail("RENAME of dir %s into itself should do nothing, " "but cinfo was changed" % name) + sess.destroy() def testSelfRenameFile(t, env): """RENAME that does nothing
@@ -524,6 +558,7 @@ def testSelfRenameFile(t, env): if scinfo.before != scinfo.after or tcinfo.before != tcinfo.after: t.fail("RENAME of file %s into itself should do nothing, " "but cinfo was changed" % name) + sess.destroy() def testLinkRename(t, env): """RENAME of file into its hard link should do nothing
@@ -545,3 +580,4 @@ def testLinkRename(t, env): if scinfo.before != scinfo.after or tcinfo.before != tcinfo.after: t.fail("RENAME of file into its hard link should do nothing, " "but cinfo was changed") + sess.destroy()
nfs4.1/server41tests/st_secinfo.py +2 -0
@@ -29,6 +29,7 @@ def testSupported(t, env): # Just do a simple SECINFO res = sess.compound([op.putfh(fh), op.secinfo(name)]) check(res) + sess.destroy() def testSupported2(t, env): """GETFH after do a SECINFO_NO_NAME or SECINFO
@@ -55,3 +56,4 @@ def testSupported2(t, env): # GETFH after do a SECINFO should get error NFS4ERR_NOFILEHANDLE res = sess.compound([op.putfh(fh), op.secinfo(name), op.getfh()]) check(res, NFS4ERR_NOFILEHANDLE) + sess.destroy()
nfs4.1/server41tests/st_secinfo_no_name.py +2 -0
@@ -18,6 +18,7 @@ def testSupported(t, env): # Do a simple SECINFO_NO_NAME res = sess.compound([op.putrootfh(), op.secinfo_no_name(0)]) check(res) + sess.destroy() def testSupported2(t, env): """GETFH after do a SECINFO_NO_NAME or SECINFO
@@ -33,3 +34,4 @@ def testSupported2(t, env): res = sess.compound([op.putrootfh(), op.secinfo_no_name(0), op.getfh()]) print res check(res, NFS4ERR_NOFILEHANDLE) + sess.destroy()
nfs4.1/server41tests/st_sequence.py +18 -0
@@ -15,6 +15,7 @@ def testSupported(t, env): sess = c.create_session() res = sess.compound([]) check(res) + sess.destroy() def testNotFirst(t, env): """SEQUENCE must be first
@@ -26,6 +27,7 @@ def testNotFirst(t, env): sess = c.create_session() res = sess.compound([sess.seq_op()]) check(res, NFS4ERR_SEQUENCE_POS) + sess.destroy() def testNotBound(t, env): """SEQUENCE sent on unbound connection
@@ -70,6 +72,7 @@ def testImplicitBind(t, env): res = env.c1.compound([sess.seq_op()], pipe=rogue) check(res) env.c1.close(rogue) + sess.destroy() def testImplicitBind4a(t, env): """SEQUENCE sent on unbound connection will bind it if no enforcing done
@@ -93,6 +96,7 @@ def testImplicitBind4a(t, env): print "B4" env.c1.close(rogue) print "B5" + sess.destroy() def xtestImplicitBind(t, env): """SEQUENCE sent on unbound connection will bind it if no enforcing done
@@ -122,6 +126,7 @@ def xtestImplicitBind(t, env): res = c.compound([op.sequence(sid, seqid, 0, 0, True)], pipe=rogue) check(res) c.close(rogue) + sess.destroy() def testBadSession(t, env): """SEQUENCE sent on unknown session
@@ -148,6 +153,7 @@ def testRequestTooBig(t, env): res = sess1.compound([op.putrootfh(), op.lookup("12345"*100)]) # FIXME - NAME_TOO_BIG is valid, don't want it to be check(res, NFS4ERR_REQ_TOO_BIG) + sess1.destroy() def testTooManyOps(t, env): """Send a request with more ops than the session can handle
@@ -168,6 +174,7 @@ def testTooManyOps(t, env): lots_of_ops += [op.getattr(0)] res = sess1.compound(lots_of_ops) check(res, NFS4ERR_TOO_MANY_OPS) + sess1.destroy() def testBadSlot(t, env): """Send a request with a bad slot
@@ -182,6 +189,7 @@ def testBadSlot(t, env): # Send sequence on (non-existant) slot number 8 res = env.c1.compound([op.sequence(sess1.sessionid, 1, 8, 8, True)]) check(res, NFS4ERR_BADSLOT) + sess1.destroy() def testReplayCache001(t, env): """Send two successful idempotent compounds with same seqid
@@ -198,6 +206,7 @@ def testReplayCache001(t, env): res1.tag = res2.tag = "" if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") + sess1.destroy() def testReplayCache002(t, env): """Send two successful non-idempotent compounds with same seqid
@@ -218,6 +227,7 @@ def testReplayCache002(t, env): res1.tag = res2.tag = "" if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") + sess1.destroy() def testReplayCache003(t, env): """Send two unsuccessful idempotent compounds with same seqid
@@ -234,6 +244,7 @@ def testReplayCache003(t, env): res1.tag = res2.tag = "" if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") + sess1.destroy() def testReplayCache004(t, env): """Send two unsuccessful non-idempotent compounds with same seqid
@@ -251,6 +262,7 @@ def testReplayCache004(t, env): res1.tag = res2.tag = "" if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") + sess1.destroy() def testReplayCache005(t, env): """Send two unsupported compounds with same seqid
@@ -267,6 +279,7 @@ def testReplayCache005(t, env): res1.tag = res2.tag = "" if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") + sess1.destroy() def testReplayCache006(t, env): """Send two solo sequence compounds with same seqid
@@ -283,6 +296,7 @@ def testReplayCache006(t, env): res1.tag = res2.tag = "" if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") + sess1.destroy() def testReplayCache007(t, env): """Send two successful non-idempotent compounds with same seqid and False cache_this
@@ -300,6 +314,7 @@ def testReplayCache007(t, env): check(res1, NFS4_OK) res2 = sess1.compound(ops, seq_delta=0, cache_this=False) check(res2, NFS4ERR_RETRY_UNCACHED_REP) + sess1.destroy() def testOpNotInSession(t, env): """Operations other than SEQUENCE, BIND_CONN_TO_SESSION, EXCHANGE_ID,
@@ -338,6 +353,7 @@ def testSessionidSequenceidSlotid(t, env): if not nfs4lib.test_equal(res.resarray[0].sr_slotid, 2, "int"): fail("server return bad slotid") + sess1.destroy() def testBadSequenceidAtSlot(t, env): """ If the difference between sa_sequenceid and the server's cached
@@ -363,6 +379,7 @@ def testBadSequenceidAtSlot(t, env): res = c.c.compound([op.sequence(sid, nfs4lib.dec_u32(seqid), 2, 3, True)]) check(res, NFS4ERR_SEQ_MISORDERED) + sess1.destroy() def testReuseSlotID(t, env): """ If client reuses a slot ID and sequence ID for a completely
@@ -392,3 +409,4 @@ def testReuseSlotID(t, env): res = c.c.compound([op.sequence(sid, seqid, 0, 0, TRUE)] + nfs4lib.use_obj(dir) + [op.rename(name, "test")]) check(res) + sess1.destroy()
nfs4.1/server41tests/st_trunking.py +4 -0
@@ -23,6 +23,8 @@ def testTwoSessions(t, env): c = env.c1.new_client(env.testname(t)) sess = c.create_session() sess2 = c.create_session() + sess.destroy() + sess2.destroy() def testUseTwoSessions(t, env):
@@ -42,6 +44,8 @@ def testUseTwoSessions(t, env): check(res) res = sess2.compound([]) check(res) + sess.destroy() + sess2.destroy() # create client # create session
nfs4.1/server41tests/st_verify.py +1 -0
@@ -12,6 +12,7 @@ def _try_mand(t, env, path): ops = use_obj(path) + [op.verify(dict)] + use_obj(path) res = sess1.compound(ops) check(res, msg="Verifying mandatory attributes against getattr") + sess1.destroy() def _try_type(env, path, type): c = env.c1
Signature · 1 line
1.7.4.1
Re: [PATCH 1/5] CLNT: try to destroy session after test complete
Quoted 3 lines · Mi Jinlong
When testing pynfs41, I got
NFS4ERR_DELAYat some tests. At a test case, we don't destroy the session after create. So, this patch try to destroy session test complete.
Sounds like a good idea.
It seems a little tedious to have to do this by hand every time; could we do some automatic cleanup at the end of the test when the variable goes out of scope, or something like that?
--b.
Quoted 1,220 lines
Signed-off-by Mi Jinlong <[email protected]>--- nfs4.1/nfs4client.py | 4 +++ nfs4.1/server41tests/environment.py | 1 + nfs4.1/server41tests/st_block.py | 4 +++ nfs4.1/server41tests/st_create_session.py | 20 +++++++++++++++ nfs4.1/server41tests/st_debug.py | 6 ++++ nfs4.1/server41tests/st_destroy_session.py | 9 +++++++ nfs4.1/server41tests/st_exchange_id.py | 12 ++++++++- nfs4.1/server41tests/st_getdevicelist.py | 11 ++++++++ nfs4.1/server41tests/st_lookup.py | 5 ++++ nfs4.1/server41tests/st_lookupp.py | 11 ++++++++ nfs4.1/server41tests/st_open.py | 10 +++++++ nfs4.1/server41tests/st_putfh.py | 8 ++++++ nfs4.1/server41tests/st_reboot.py | 1 + nfs4.1/server41tests/st_rename.py | 36 ++++++++++++++++++++++++++++ nfs4.1/server41tests/st_secinfo.py | 2 + nfs4.1/server41tests/st_secinfo_no_name.py | 2 + nfs4.1/server41tests/st_sequence.py | 18 ++++++++++++++ nfs4.1/server41tests/st_trunking.py | 4 +++ nfs4.1/server41tests/st_verify.py | 1 + 19 files changed, 164 insertions(+), 1 deletions(-)nfs4.1/nfs4client.py +4
-0@@ -495,6 +495,10 @@ class SessionRecord(object): res.resarray = res.resarray[1:] return res + def destroy(self): + res = self.c.compound([op.destroy_session(self.sessionid)]) + nfs4lib.check(res) + ## def open(self, owner, name=None, type=OPEN4_NOCREATE, ## mode=UNCHECKED4, attrs={FATTR4_MODE:0644}, verf=None, ## access=OPEN4_SHARE_ACCESS_READ,nfs4.1/server41tests/environment.py +1
-0@@ -153,6 +153,7 @@ class Environment(testmod.Environment): # Make sure it is empty clean_dir(sess, self.opts.home) sess.c.null() + sess.destroy() def _maketree(self, sess): """Make test tree"""nfs4.1/server41tests/st_block.py +4
-0@@ -49,6 +49,7 @@ def testStateid1(t, env): # the server increments by one the value of the "seqid" in each # subsequent LAYOUTGET and LAYOUTRETURN response, fail("Expected stateid.seqid==%i, got %i" % (i+2, lo_stateid.seqid)) + sess.destroy_session() def testStateid2(t, env): """Check for proper sequence handling in layout stateids.@@ -109,6 +110,7 @@ def testStateid2(t, env): layoutupdate4(LAYOUT4_BLOCK_VOLUME, p.get_buffer()))] res = sess.compound(ops) check(res) + sess.destroy_session() def testEmptyCommit(t, env): """Check for proper handling of empty LAYOUTCOMMIT.@@ -171,6 +173,7 @@ def testEmptyCommit(t, env): layoutupdate4(LAYOUT4_BLOCK_VOLUME, ""))] res = sess.compound(ops) check(res) + sess.destroy_session() def testSplitCommit(t, env): """Check for proper handling of disjoint LAYOUTCOMMIT.opaque@@ -218,3 +221,4 @@ def testSplitCommit(t, env): layoutupdate4(LAYOUT4_BLOCK_VOLUME, p.get_buffer()))] res = sess.compound(ops) check(res) + sess.destroy_session()nfs4.1/server41tests/st_create_session.py +20
-0@@ -25,6 +25,7 @@ def testSupported1(t, env): """ c = env.c1.new_client(env.testname(t)) sess = c.create_session() + sess.destroy(); def testSupported2(t, env): """Do a CREATE_SESSION after a SEQUENCE (for same client)@@ -44,6 +45,8 @@ def testSupported2(t, env): # Now make sure sess2 works res = sess2.compound([op.putrootfh()]) check(res) + sess1.destroy(); + sess2.destroy(); def testSupported2b(t, env): """Do a CREATE_SESSION after a SEQUENCE (for different client)@@ -64,6 +67,8 @@ def testSupported2b(t, env): # Now make sure sess2 works res = sess2.compound([op.putrootfh()]) check(res) + sess1.destroy(); + sess2.destroy(); def testNoExchange(t, env): """Send CREATE_SESSION when server has no record of clientid@@ -132,6 +137,8 @@ def testReplay1a(t, env): if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") + sess1.destroy(); + def testReplay1b(t, env): """Replay a successful SEQUENCE:CREATE_SESSION without a preceeding SEQUENCE@@ -156,6 +163,8 @@ def testReplay1b(t, env): if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") + sess1.destroy(); + def testReplay2(t, env): """Replay a unsuccessful CREATE_SESSION@@ -251,6 +260,7 @@ def testCbSecParms(t, env): c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session(sec=sec) + sess1.destroy(); def testCbSecParmsDec(t, env): """A decode problem was found at NFS server@@ -267,6 +277,7 @@ def testCbSecParmsDec(t, env): c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session(sec=sec) + sess1.destroy(); def testRdmaArray0(t, env): """Test 0 length rdma arrays@@ -278,6 +289,7 @@ def testRdmaArray0(t, env): chan_attrs = channel_attrs4(0, 8192,8192,8192,128,8,[]) sess1 = c1.create_session(fore_attrs=chan_attrs, back_attrs=chan_attrs) + sess1.destroy(); def testRdmaArray1(t, env): """Test length 1 rdma arrays@@ -289,6 +301,7 @@ def testRdmaArray1(t, env): chan_attrs = channel_attrs4(0,8192,8192,8192,128,8,[57]) sess1 = c1.create_session(fore_attrs=chan_attrs, back_attrs=chan_attrs) + sess1.destroy(); def testRdmaArray2(t, env): """Test length 2 rdma arrays@@ -351,6 +364,8 @@ def testCallbackProgram(t, env): finally: env.c1._check_program = orig + sess.destroy(); + def testCallbackVersion(t, env): """Check server sends callback program with a version listed in nfs4client.py@@ -380,6 +395,8 @@ def testCallbackVersion(t, env): finally: env.c1._check_version = orig + sess.destroy() + def testMaxreqs(t, env): """A CREATE_SESSION with maxreqs too large should return a modified value@@ -428,6 +445,8 @@ def testCsr_sequence(t, env): if not nfs4lib.test_equal(sess1.seqid, csa_sequence, "int"): fail("Server returns bad csr_sequence which not equal to csa_sequence") + sess1.destroy() + def testTooSmallMaxRS(t, env): """If client selects a value for ca_maxresponsesize such that a replier on a channel could never send a response,@@ -471,6 +490,7 @@ def testRepTooBig(t, env): # read data rather than ca_maxresponsesize res = sess1.compound([op.putfh(fh), op.read(stateid, 0, 500)]) check(res, NFS4ERR_REP_TOO_BIG) + sess1.destroy() def testRepTooBigToCache(t, env): """If requester sends a request for which the size of the replynfs4.1/server41tests/st_debug.py +6
-0@@ -30,6 +30,8 @@ def testSupported2(t, env): # STUB - since we are not handling callback, deleg_return never gets done print res check(res) + sess1.destroy() + sess2.destroy() def testReadWrite(t, env): """Do a simple READ and WRITE@@ -57,6 +59,7 @@ def testReadWrite(t, env): res = sess1.compound([op.putfh(fh), op.read(stateid, 0, 1000)]) print res check(res) + sess1.destroy() def testDeadlock(t, env):@@ -86,6 +89,7 @@ def testDeadlock(t, env): res = sess1.listen(xid) check(res) print res + sess1.destroy() def testLayout(t, env): """Verify layout handling@@ -118,6 +122,7 @@ def testLayout(t, env): 0, 0xffffffff, 0, 0xffff)] res = sess.compound(ops) check(res) + sess.destroy() def testGetDevList(t, env): """Check devlist@@ -142,3 +147,4 @@ def testGetDevList(t, env): ops = use_obj(env.opts.path) + [op.getdevicelist(LAYOUT4_BLOCK_VOLUME, 0, 0, "")] res = sess.compound(ops) check(res) + sess.destroy()nfs4.1/server41tests/st_destroy_session.py +9
-0@@ -27,6 +27,7 @@ def testDestroy(t, env): env.c1.compound([sess.seq_op()], pipe=rogue) res = c.c.compound([op.destroy_session(sess.sessionid)], pipe=rogue) check(res) + sess.destroy() def testDestroy2(t, env): """@@ -74,6 +75,9 @@ def testDestroy2(t, env): recall.wait(100) # STUB - deal with timeout if not recall.happened: fail("Did not get callback") + sess1.destroy() + sess2.destroy() + sess3.destroy() def testDestroy3(t, env): """@@ -132,6 +136,9 @@ def testDestroy3(t, env): recall.wait(100) # STUB - deal with timeout if not recall.happened: fail("Did not get callback") + sess1.destroy() + sess2.destroy() + sess3.destroy() def testDestoryNotFinalOps(t, env): """ If the COMPOUND request starts with SEQUENCE, DESTROY_SESSION@@ -149,6 +156,7 @@ def testDestoryNotFinalOps(t, env): op.destroy_session(sess1.sessionid), op.putrootfh()]) check(res, NFS4ERR_NOT_ONLY_OP) + sess1.destroy() def testDestoryNotSoleOps(t, env): """ If the COMPOUND request does not start with SEQUENCE,@@ -167,3 +175,4 @@ def testDestoryNotSoleOps(t, env): res = c.c.compound([op.putrootfh(), op.destroy_session(sess1.sessionid)]) check(res, NFS4ERR_NOT_ONLY_OP) + sess1.destroy()nfs4.1/server41tests/st_exchange_id.py +11
-1@@ -56,7 +56,7 @@ def testSupported2(t, env): # per draft 21 13.1, server MUST set one of these bits if not (res.resarray[0].eir_flags & EXCHGID4_FLAG_MASK_PNFS): fail("server did not set any EXCHGID4_FLAG_USE_* bits") - + sess1.destroy() def testSSV(t, env): """Do a simple EXCHANGE_ID@@ -84,6 +84,7 @@ def testSSV(t, env): # SET_SSV res = sess.set_ssv('\x5a' * c.protect.context.ssv_len) print res + sess.destroy() def testNoImplId(t, env): """Do a simple EXCHANGE_ID w/o setting client impl_id@@ -213,6 +214,7 @@ def testNoUpdate100(t, env): # Check that cred1 state is destroyed res = sess1.compound([]) check(res, NFS4ERR_BADSESSION) + sess1.destroy() # Need similar tests of 100 for expired lease, existing state (IN_USE)@@ -237,6 +239,7 @@ def testNoUpdate101(t, env): res = sess1.compound([]) check(res, NFS4ERR_BADSESSION) # FIXME - more checks here + sess1.destroy() def testNoUpdate110(t, env): """@@ -255,6 +258,7 @@ def testNoUpdate110(t, env): # Check that cred1 state is destroyed res = sess1.compound([]) check(res, NFS4ERR_BADSESSION) + sess1.destroy() # Need similar tests of 110 for expired lease, existing state (IN_USE)@@ -272,6 +276,7 @@ def testNoUpdate111(t, env): if c1.clientid != c2.clientid: fail("Expected clientid %i, got %i" % (c1.clientid, c2.clientid)) # STUB - really want to check to see if E_ID results are the same + sess1.destroy() def testUpdateNonexistant(t, env): """Do an EXCHANGE_ID update of a non-existant record@@ -357,6 +362,7 @@ def testUpdate100(t, env): cred=env.cred2, flags=EXCHGID4_FLAG_UPD_CONFIRMED_REC_A, expect=NFS4ERR_NOT_SAME) + sess1.destroy() def testUpdate101(t, env): """@@ -372,6 +378,7 @@ def testUpdate101(t, env): cred=env.cred1, flags=EXCHGID4_FLAG_UPD_CONFIRMED_REC_A, expect=NFS4ERR_NOT_SAME) + sess1.destroy() def testUpdate110(t, env): """@@ -387,6 +394,7 @@ def testUpdate110(t, env): cred=env.cred2, flags=EXCHGID4_FLAG_UPD_CONFIRMED_REC_A, expect=NFS4ERR_PERM) + sess1.destroy() def testUpdate111(t, env):@@ -406,6 +414,7 @@ def testUpdate111(t, env): fail("Record update changed clientid from %r to %r\n" % (c1.clientid, c2.clientid)) # STUB - want to check update occurred + sess1.destroy() # Want test similar to testUpdate111, that tries to update qqc that cant update@@ -472,3 +481,4 @@ def testLeasePeriod(t, env): chan_attrs, chan_attrs, 123, [])], None) check(res2, NFS4ERR_STALE_CLIENTID) + sess.destroy()nfs4.1/server41tests/st_getdevicelist.py +11
-0@@ -32,6 +32,7 @@ def testGetDevList(t, env): # STUB - check block stuff dev_list = res.resarray[-1].gdlr_deviceid_list print dev_list + sess.destroy() def testGetDevInfo(t, env): """Check devlist@@ -69,6 +70,8 @@ def testGetDevInfo(t, env): p.done() print decode + sess.destroy() + ## def xxxtestLayout(t, env): ## """Verify layout handling@@ -140,6 +143,8 @@ def testGetLayout(t, env): p.done() print opaque + sess.destroy() + def testEMCGetLayout(t, env): """Verify layout handling@@ -183,6 +188,8 @@ def testEMCGetLayout(t, env): p.done() print opaque + sess.destroy() + def testLayoutReturnFile(t, env): """ Return a file's layout@@ -215,6 +222,7 @@ def testLayoutReturnFile(t, env): layoutreturn_file4(0, 0xffffffffffffffff, layout_stateid, "")))] res = sess.compound(ops) check(res) + sess.destroy() def testLayoutReturnFsid(t, env): """@@ -247,6 +255,7 @@ def testLayoutReturnFsid(t, env): layoutreturn4(LAYOUTRETURN4_FSID))] res = sess.compound(ops) check(res) + sess.destroy() def testLayoutReturnAll(t, env): """@@ -278,6 +287,7 @@ def testLayoutReturnAll(t, env): layoutreturn4(LAYOUTRETURN4_ALL))] res = sess.compound(ops) check(res) + sess.destroy() def testLayoutCommit(t, env): """@@ -341,5 +351,6 @@ def testLayoutCommit(t, env): res = sess.compound(ops) check(res) print res + sess.destroy()nfs4.1/server41tests/st_lookup.py +5
-0@@ -12,6 +12,7 @@ def testHome(t, env): sess1 = c1.create_session() res = sess1.compound(env.home + [op.getfh()]) check(res) + sess1.destroy() def testNoFh(t, env): """LOOKUP should fail with NFS4ERR_NOFILEHANDLE if no (cfh)@@ -23,6 +24,7 @@ def testNoFh(t, env): sess1 = c1.create_session() res = sess1.compound([op.lookup(env.testname(t))]) check(res, NFS4ERR_NOFILEHANDLE, "LOOKUP with no <cfh>") + sess1.destroy() def testNonExistent(t, env): """LOOKUP with non-existent components should return NFS4ERR_NOENT@@ -36,6 +38,7 @@ def testNonExistent(t, env): res = sess1.compound(env.home + [op.lookup(name)]) check(res, NFS4ERR_NOENT, "LOOKUP with non-existant component '%s'" % name) + sess1.destroy() def testZeroLength(t, env): """LOOKUP with zero length name should return NFS4ERR_INVAL@@ -47,6 +50,7 @@ def testZeroLength(t, env): sess1 = c1.create_session() res = sess1.compound([op.putrootfh(), op.lookup('')]) check(res, NFS4ERR_INVAL, "LOOKUP with no zero-length component") + sess1.destroy() def testLongName(t, env): """LOOKUP should fail with NFS4ERR_NAMETOOLONG with long filenames@@ -58,6 +62,7 @@ def testLongName(t, env): sess1 = c1.create_session() res = sess1.compound([op.putrootfh(), op.lookup('abc' * 512)]) check(res, NFS4ERR_NAMETOOLONG, "LOOKUP with very long component") + sess1.destroy() # STUB - if get NOENT, check fattr4_maxname # NOTE there is NO limit on component4 lengthnfs4.1/server41tests/st_lookupp.py +11
-0@@ -22,6 +22,7 @@ def testLookupp(t, env): if res.resarray[2*i+1].object != res.resarray[-(2*i+1)].object: t.fail('LOOKUPP returned %r, expected %r' % (res.resarray[-(2*i+1)].object, res.resarray[2*i+1].object)) + sess1.destroy() def testFile(t, env): """LOOKUPP with non-dir (cfh)@@ -34,6 +35,7 @@ def testFile(t, env): ops = use_obj(env.opts.usefile) + [op.lookupp()] res = sess1.compound(ops) check(res, NFS4ERR_NOTDIR, "LOOKUPP with non-dir <cfh>") + sess1.destroy() def testFifo(t, env): """LOOKUPP with non-dir (cfh)@@ -46,6 +48,7 @@ def testFifo(t, env): ops = use_obj(env.opts.usefifo) + [op.lookupp()] res = sess1.compound(ops) check(res, NFS4ERR_NOTDIR, "LOOKUPP with non-dir <cfh>") + sess1.destroy() def testLink(t, env): """LOOKUPP with non-dir (cfh)@@ -58,6 +61,7 @@ def testLink(t, env): ops = use_obj(env.opts.uselink) + [op.lookupp()] res = sess1.compound(ops) check(res, NFS4ERR_SYMLINK, "LOOKUPP with non-dir <cfh>") + sess1.destroy() def testBlock(t, env): """LOOKUPP with non-dir (cfh)@@ -70,6 +74,7 @@ def testBlock(t, env): ops = use_obj(env.opts.useblock) + [op.lookupp()] res = sess1.compound(ops) check(res, NFS4ERR_NOTDIR, "LOOKUPP with non-dir <cfh>") + sess1.destroy() def testChar(t, env): """LOOKUPP with non-dir (cfh)@@ -82,6 +87,7 @@ def testChar(t, env): ops = use_obj(env.opts.usechar) + [op.lookupp()] res = sess1.compound(ops) check(res, NFS4ERR_NOTDIR, "LOOKUPP with non-dir <cfh>") + sess1.destroy() def testSock(t, env): """LOOKUPP with non-dir (cfh)@@ -94,6 +100,7 @@ def testSock(t, env): ops = use_obj(env.opts.usesocket) + [op.lookupp()] res = sess1.compound(ops) check(res, NFS4ERR_NOTDIR, "LOOKUPP with non-dir <cfh>") + sess1.destroy() def testLookuppRoot(t, env): """Lookupp from root should return NFS4ERR_NOENT@@ -108,6 +115,7 @@ def testLookuppRoot(t, env): fh = res.resarray[-1].object res = sess1.compound([op.putfh(fh), op.lookupp()]) check(res, NFS4ERR_NOENT) + sess1.destroy() def testNoFH(t, env): """Lookup without a cfh should return NFS4ERR_NOFILEHANDLE@@ -119,6 +127,7 @@ def testNoFH(t, env): sess1 = c1.create_session() res = sess1.compound([op.lookupp()]) check(res, NFS4ERR_NOFILEHANDLE) + sess1.destroy() def testXdev(t, env): """LOOKUPP with dir on different fs@@ -138,3 +147,5 @@ def testXdev(t, env): fh2 = res.resarray[-1].object if fh1 != fh2: t.fail("file handles not equal") + + sess1.destroy()nfs4.1/server41tests/st_open.py +10
-0@@ -30,6 +30,7 @@ def testSupported(t, env): # see draft-10 line 19445 # QUESTION - what does "If the server supports the new _WANT_ flags" mean? # will the server return INVAL? NOTSUPP? or just silently ignore? + sess1.destroy() def testServerStateSeqid(t, env): """Do multiple OPENs of a file, check that server bumps stateid.seqid@@ -49,6 +50,7 @@ def testServerStateSeqid(t, env): check(res) expect(res, seqid=2) # STUB - need to check no delegation return + sess1.destroy() # Test outdate, see draft22 8.2.2 def xtestClientStateSeqid(t, env):@@ -73,6 +75,7 @@ def xtestClientStateSeqid(t, env): stateid = res.resarray[-2].stateid res = sess1.compound([op.putfh(fh), op.write(stateid, 5, FILE_SYNC4, "write test data")]) check(res, NFS4ERR_BAD_STATEID, "Using an open_stateid w/o zeroing the seqid") + sess1.destroy() # Test outdated by draft15 8.8@@ -96,6 +99,7 @@ def xtestOpenSeqid(t, env): res = open_file(sess1, owner, path, access=OPEN4_SHARE_ACCESS_READ, seqid=1) check(res, NFS4ERR_INVAL, msg="Using non-zero seqid in OPEN") + sess1.destroy() # Test outdated by draft15 8.8@@ -116,6 +120,7 @@ def xtestOpenClientid(t, env): sess1 = c1.create_session() res = create_file(sess1, env.testname(t), clientid=c1.clientid) check(res, NFS4ERR_INVAL, msg="Using non-zero clientid in open_owner") + sess1.destroy() def testReadDeleg(t, env): """Test read delgation handout and return@@ -173,6 +178,9 @@ def testReadDeleg(t, env): print res checklist(res, [NFS4_OK, NFS4ERR_DELAY]) print "FRED - done" + + sess1.destroy() + sess2.destroy()@@ -201,6 +209,7 @@ def testReadWrite(t, env): desired = "\0"*5 + data if res.resarray[-1].data != desired: fail("Expected %r, got %r" % (desired, res.resarray[-1].data)) + sess1.destroy() def testEXCLUSIVE4AtNameAttribute(t, env): """If the file does exist,but the stored verifier does not match,@@ -219,3 +228,4 @@ def testEXCLUSIVE4AtNameAttribute(t, env): res = create_file(sess1, env.testname(t), mode=EXCLUSIVE4_1, verifier = "Justtest") check(res, NFS4ERR_EXIST) + sess1.destroy()nfs4.1/server41tests/st_putfh.py +8
-0@@ -23,6 +23,7 @@ def testFile(t, env): c = env.c1.new_client(env.testname(t)) sess = c.create_session() _try_put(t, sess, env.opts.usefile) + sess.destroy() def testLink(t, env): """PUTFH followed by GETFH should end up with original fh@@ -33,6 +34,7 @@ def testLink(t, env): c = env.c1.new_client(env.testname(t)) sess = c.create_session() _try_put(t, sess, env.opts.uselink) + sess.destroy() def testBlock(t, env): """PUTFH followed by GETFH should end up with original fh@@ -43,6 +45,7 @@ def testBlock(t, env): c = env.c1.new_client(env.testname(t)) sess = c.create_session() _try_put(t, sess, env.opts.useblock) + sess.destroy() def testChar(t, env): """PUTFH followed by GETFH should end up with original fh@@ -53,6 +56,7 @@ def testChar(t, env): c = env.c1.new_client(env.testname(t)) sess = c.create_session() _try_put(t, sess, env.opts.usechar) + sess.destroy() def testDir(t, env): """PUTFH followed by GETFH should end up with original fh@@ -63,6 +67,7 @@ def testDir(t, env): c = env.c1.new_client(env.testname(t)) sess = c.create_session() _try_put(t, sess, env.opts.usedir) + sess.destroy() def testFifo(t, env): """PUTFH followed by GETFH should end up with original fh@@ -73,6 +78,7 @@ def testFifo(t, env): c = env.c1.new_client(env.testname(t)) sess = c.create_session() _try_put(t, sess, env.opts.usefifo) + sess.destroy() def testSocket(t, env): """PUTFH followed by GETFH should end up with original fh@@ -83,6 +89,7 @@ def testSocket(t, env): c = env.c1.new_client(env.testname(t)) sess = c.create_session() _try_put(t, sess, env.opts.usesocket) + sess.destroy() def testBadHandle(t, env): """PUTFH with bad filehandle should return NFS4ERR_BADHANDLE@@ -94,3 +101,4 @@ def testBadHandle(t, env): sess = c.create_session() res = sess.compound([op.putfh('abc')]) check(res, NFS4ERR_BADHANDLE, "PUTFH with bad filehandle='abc'") + sess.destroy()nfs4.1/server41tests/st_reboot.py +1
-0@@ -74,3 +74,4 @@ def testRebootValid(t, env): reclaim_complete(sess) finally: env.sleep(sleeptime, "Waiting for grace period to end") + sess.destroy()nfs4.1/server41tests/st_rename.py +36
-0@@ -17,6 +17,7 @@ def testValidDir(t, env): res = rename_obj(sess, basedir + ['dir1', 'foo'], basedir + ['dir2', 'bar']) check(res, msg="RENAME of directory %s/dir1/foo to %s/dir2/bar" % (name, name)) + sess.destroy() def testValidFile(t, env): """RENAME : normal operation@@ -32,6 +33,7 @@ def testValidFile(t, env): res = rename_obj(sess, basedir + ['dir1', 'foo'], basedir + ['dir2', 'bar']) check(res, msg="RENAME of file %s/dir1/foo to %s/dir2/bar" % (name, name)) + sess.destroy() def testValidLink(t, env): """RENAME : normal operation@@ -49,6 +51,7 @@ def testValidLink(t, env): res = rename_obj(sess, basedir + ['dir1', 'foo'], basedir + ['dir2', 'bar']) check(res, msg="RENAME of symlink %s/dir1/foo to %s/dir2/bar" % (name, name)) + sess.destroy() def testValidBlock(t, env): """RENAME : normal operation@@ -66,6 +69,7 @@ def testValidBlock(t, env): res = rename_obj(sess, basedir + ['dir1', 'foo'], basedir + ['dir2', 'bar']) check(res, msg="RENAME of block device %s/dir1/foo to %s/dir2/bar" % (name, name)) + sess.destroy() def testValidChar(t, env): """RENAME : normal operation@@ -83,6 +87,7 @@ def testValidChar(t, env): res = rename_obj(sess, basedir + ['dir1', 'foo'], basedir + ['dir2', 'bar']) check(res, msg="RENAME of character device %s/dir1/foo to %s/dir2/bar" % (name, name)) + sess.destroy() def testValidFifo(t, env): """RENAME : normal operation@@ -100,6 +105,7 @@ def testValidFifo(t, env): res = rename_obj(sess, basedir + ['dir1', 'foo'], basedir + ['dir2', 'bar']) check(res, msg="RENAME of fifo %s/dir1/foo to %s/dir2/bar" % (name, name)) + sess.destroy() def testValidSocket(t, env): """RENAME : normal operation@@ -117,6 +123,7 @@ def testValidSocket(t, env): res = rename_obj(sess, basedir + ['dir1', 'foo'], basedir + ['dir2', 'bar']) check(res, msg="RENAME of socket %s/dir1/foo to %s/dir2/bar" % (name, name)) + sess.destroy() def testSfhFile(t, env): """RENAME with non-dir (sfh) should return NFS4ERR_NOTDIR@@ -129,6 +136,7 @@ def testSfhFile(t, env): sess = c.create_session() res = rename_obj(sess, env.opts.usefile + [name], env.c1.homedir + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <sfh>") + sess.destroy() def testSfhLink(t, env): """RENAME with non-dir (sfh) should return NFS4ERR_NOTDIR@@ -141,6 +149,7 @@ def testSfhLink(t, env): sess = c.create_session() res = rename_obj(sess, env.opts.uselink + [name], env.c1.homedir + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <sfh>") + sess.destroy() def testSfhBlock(t, env): """RENAME with non-dir (sfh) should return NFS4ERR_NOTDIR@@ -153,6 +162,7 @@ def testSfhBlock(t, env): sess = c.create_session() res = rename_obj(sess, env.opts.useblock + [name], env.c1.homedir + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <sfh>") + sess.destroy() def testSfhChar(t, env): """RENAME with non-dir (sfh) should return NFS4ERR_NOTDIR@@ -165,6 +175,7 @@ def testSfhChar(t, env): sess = c.create_session() res = rename_obj(sess, env.opts.usechar + [name], env.c1.homedir + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <sfh>") + sess.destroy() def testSfhFifo(t, env): """RENAME with non-dir (sfh) should return NFS4ERR_NOTDIR@@ -177,6 +188,7 @@ def testSfhFifo(t, env): sess = c.create_session() res = rename_obj(sess, env.opts.usefifo + [name], env.c1.homedir + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <sfh>") + sess.destroy() def testSfhSocket(t, env): """RENAME with non-dir (sfh) should return NFS4ERR_NOTDIR@@ -189,6 +201,7 @@ def testSfhSocket(t, env): sess = c.create_session() res = rename_obj(sess, env.opts.usesocket + [name], env.c1.homedir + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <sfh>") + sess.destroy() def testCfhFile(t, env): """RENAME with non-dir (cfh) should return NFS4ERR_NOTDIR@@ -203,6 +216,7 @@ def testCfhFile(t, env): check(res) res = rename_obj(sess, env.c1.homedir + [name], env.opts.usefile + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <cfh>") + sess.destroy() def testCfhLink(t, env): """RENAME with non-dir (cfh) should return NFS4ERR_NOTDIR@@ -217,6 +231,7 @@ def testCfhLink(t, env): check(res) res = rename_obj(sess, env.c1.homedir + [name], env.opts.uselink + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <cfh>") + sess.destroy() def testCfhBlock(t, env): """RENAME with non-dir (cfh) should return NFS4ERR_NOTDIR@@ -231,6 +246,7 @@ def testCfhBlock(t, env): check(res) res = rename_obj(sess, env.c1.homedir + [name], env.opts.useblock + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <cfh>") + sess.destroy() def testCfhChar(t, env): """RENAME with non-dir (cfh) should return NFS4ERR_NOTDIR@@ -245,6 +261,7 @@ def testCfhChar(t, env): check(res) res = rename_obj(sess, env.c1.homedir + [name], env.opts.usechar + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <cfh>") + sess.destroy() def testCfhFifo(t, env): """RENAME with non-dir (cfh) should return NFS4ERR_NOTDIR@@ -259,6 +276,7 @@ def testCfhFifo(t, env): check(res) res = rename_obj(sess, env.c1.homedir + [name], env.opts.usefifo + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <cfh>") + sess.destroy() def testCfhSocket(t, env): """RENAME with non-dir (cfh) should return NFS4ERR_NOTDIR@@ -273,6 +291,7 @@ def testCfhSocket(t, env): check(res) res = rename_obj(sess, env.c1.homedir + [name], env.opts.usesocket + [name]) check(res, NFS4ERR_NOTDIR, "RENAME with non-dir <cfh>") + sess.destroy() def testNoSfh(t, env): """RENAME without (sfh) should return NFS4ERR_NOFILEHANDLE@@ -286,6 +305,7 @@ def testNoSfh(t, env): ops = env.home + [op.rename(name, name)] res = sess.compound(ops) check(res, NFS4ERR_NOFILEHANDLE, "RENAME with no <sfh>") + sess.destroy() # FRED - can't test No Cfh, with a Sfh@@ -303,6 +323,7 @@ def testNonExistent(t, env): check(res) res = rename_obj(sess, basedir + ['foo'], basedir + ['bar']) check(res, NFS4ERR_NOENT, "RENAME on non-existing object %s/foo" % name) + sess.destroy() def testZeroLengthOldname(t, env): """RENAME with zero length oldname should return NFS4ERR_INVAL@@ -318,6 +339,7 @@ def testZeroLengthOldname(t, env): check(res) res = rename_obj(sess, basedir + [''], basedir + ['bar']) check(res, NFS4ERR_INVAL, "RENAME with zero length oldname") + sess.destroy() def testZeroLengthNewname(t, env): """RENAME with zero length newname should return NFS4ERR_INVAL@@ -333,6 +355,7 @@ def testZeroLengthNewname(t, env): check(res) res = rename_obj(sess, basedir + ['foo'], basedir + ['']) check(res, NFS4ERR_INVAL, "RENAME with zero length newname") + sess.destroy() def testBadutf8Oldname(t, env): """RENAME with non-UTF8 oldname should return NFS4ERR_INVAL@@ -350,6 +373,7 @@ def testBadutf8Oldname(t, env): res = rename_obj(sess, basedir + [bad_utf8], basedir + [name]) check(res, NFS4ERR_INVAL, "RENAME with non-UTF8 oldname %s/%s" % (name, repr(bad_utf8)[1:-1])) + sess.destroy() def testBadutf8Newname(t, env): """RENAME with non-UTF8 newname should return NFS4ERR_INVAL@@ -366,6 +390,7 @@ def testBadutf8Newname(t, env): res = rename_obj(sess, basedir + [name], basedir + [bad_utf8]) check(res, NFS4ERR_INVAL, "RENAME with non-UTF8 newname %s/%s" % (name, repr(bad_utf8)[1:-1])) + sess.destroy() def testDotsOldname(t, env): """RENAME from nonexistant . or .. should return _NOENT/_BADNAME@@ -384,6 +409,7 @@ def testDotsOldname(t, env): res = rename_obj(sess, basedir + ['..'], basedir + [name]) check(res, NFS4ERR_BADNAME, "RENAME from nonexistant '..'", [NFS4ERR_NOENT]) + sess.destroy() def testDotsNewname(t, env): """RENAME into . or .. should return _BADNAME or NFS4_OK@@ -402,6 +428,7 @@ def testDotsNewname(t, env): res = rename_obj(sess, basedir + [name], basedir + ['..']) check(res, NFS4ERR_BADNAME, "RENAME into '..'", [NFS4_OK]) + sess.destroy() def testDirToObj(t, env): """RENAME dir into existing nondir should return NFS4ERR_EXIST@@ -416,6 +443,7 @@ def testDirToObj(t, env): maketree(sess, [name, ['dir'], 'file']) res = rename_obj(sess, basedir + ['dir'], basedir + ['file']) check(res, NFS4ERR_EXIST, "RENAME dir into existing file") + sess.destroy() def testDirToDir(t, env): """RENAME dir into existing, empty dir should retrun NFS4_OK@@ -430,6 +458,7 @@ def testDirToDir(t, env): maketree(sess, [name, ['dir1', ['foo']], ['dir2']]) res = rename_obj(sess, basedir + ['dir1'], basedir + ['dir2']) check(res, msg="RENAME dir1 into existing, empty dir2") + sess.destroy() def testFileToDir(t, env): """RENAME file into existing dir should return NFS4ERR_EXIST@@ -444,6 +473,7 @@ def testFileToDir(t, env): maketree(sess, [name, ['dir'], 'file']) res = rename_obj(sess, basedir + ['file'], basedir + ['dir']) check(res, NFS4ERR_EXIST, "RENAME file into existing dir") + sess.destroy() def testFileToFile(t, env): """RENAME file into existing file should return NFS4_OK@@ -458,6 +488,7 @@ def testFileToFile(t, env): maketree(sess, [name, 'file1', 'file2']) res = rename_obj(sess, basedir + ['file1'], basedir + ['file2']) check(res, msg="RENAME file1 into existing file2") + sess.destroy() def testDirToFullDir(t, env): """RENAME dir into existing, nonempty dir should return NFS4ERR_EXIST@@ -472,6 +503,7 @@ def testDirToFullDir(t, env): maketree(sess, [name, ['dir1'], ['dir2', ['foo']]]) res = rename_obj(sess, basedir + ['dir1'], basedir + ['dir2']) check(res, NFS4ERR_EXIST, "RENAME dir1 into existing, nonempty dir2") + sess.destroy() def testFileToFullDir(t, env): """RENAME file into existing, nonempty dir should return NFS4ERR_EXIST@@ -486,6 +518,7 @@ def testFileToFullDir(t, env): maketree(sess, [name, 'file', ['dir', ['foo']]]) res = rename_obj(sess, basedir + ['file'], basedir + ['dir']) check(res, NFS4ERR_EXIST, "RENAME file into existing, nonempty dir") + sess.destroy() def testSelfRenameDir(t, env): """RENAME that does nothing@@ -505,6 +538,7 @@ def testSelfRenameDir(t, env): if scinfo.before != scinfo.after or tcinfo.before != tcinfo.after: t.fail("RENAME of dir %s into itself should do nothing, " "but cinfo was changed" % name) + sess.destroy() def testSelfRenameFile(t, env): """RENAME that does nothing@@ -524,6 +558,7 @@ def testSelfRenameFile(t, env): if scinfo.before != scinfo.after or tcinfo.before != tcinfo.after: t.fail("RENAME of file %s into itself should do nothing, " "but cinfo was changed" % name) + sess.destroy() def testLinkRename(t, env): """RENAME of file into its hard link should do nothing@@ -545,3 +580,4 @@ def testLinkRename(t, env): if scinfo.before != scinfo.after or tcinfo.before != tcinfo.after: t.fail("RENAME of file into its hard link should do nothing, " "but cinfo was changed") + sess.destroy()nfs4.1/server41tests/st_secinfo.py +2
-0@@ -29,6 +29,7 @@ def testSupported(t, env): # Just do a simple SECINFO res = sess.compound([op.putfh(fh), op.secinfo(name)]) check(res) + sess.destroy() def testSupported2(t, env): """GETFH after do a SECINFO_NO_NAME or SECINFO@@ -55,3 +56,4 @@ def testSupported2(t, env): # GETFH after do a SECINFO should get error NFS4ERR_NOFILEHANDLE res = sess.compound([op.putfh(fh), op.secinfo(name), op.getfh()]) check(res, NFS4ERR_NOFILEHANDLE) + sess.destroy()nfs4.1/server41tests/st_secinfo_no_name.py +2
-0@@ -18,6 +18,7 @@ def testSupported(t, env): # Do a simple SECINFO_NO_NAME res = sess.compound([op.putrootfh(), op.secinfo_no_name(0)]) check(res) + sess.destroy() def testSupported2(t, env): """GETFH after do a SECINFO_NO_NAME or SECINFO@@ -33,3 +34,4 @@ def testSupported2(t, env): res = sess.compound([op.putrootfh(), op.secinfo_no_name(0), op.getfh()]) print res check(res, NFS4ERR_NOFILEHANDLE) + sess.destroy()nfs4.1/server41tests/st_sequence.py +18
-0@@ -15,6 +15,7 @@ def testSupported(t, env): sess = c.create_session() res = sess.compound([]) check(res) + sess.destroy() def testNotFirst(t, env): """SEQUENCE must be first@@ -26,6 +27,7 @@ def testNotFirst(t, env): sess = c.create_session() res = sess.compound([sess.seq_op()]) check(res, NFS4ERR_SEQUENCE_POS) + sess.destroy() def testNotBound(t, env): """SEQUENCE sent on unbound connection@@ -70,6 +72,7 @@ def testImplicitBind(t, env): res = env.c1.compound([sess.seq_op()], pipe=rogue) check(res) env.c1.close(rogue) + sess.destroy() def testImplicitBind4a(t, env): """SEQUENCE sent on unbound connection will bind it if no enforcing done@@ -93,6 +96,7 @@ def testImplicitBind4a(t, env): print "B4" env.c1.close(rogue) print "B5" + sess.destroy() def xtestImplicitBind(t, env): """SEQUENCE sent on unbound connection will bind it if no enforcing done@@ -122,6 +126,7 @@ def xtestImplicitBind(t, env): res = c.compound([op.sequence(sid, seqid, 0, 0, True)], pipe=rogue) check(res) c.close(rogue) + sess.destroy() def testBadSession(t, env): """SEQUENCE sent on unknown session@@ -148,6 +153,7 @@ def testRequestTooBig(t, env): res = sess1.compound([op.putrootfh(), op.lookup("12345"*100)]) # FIXME - NAME_TOO_BIG is valid, don't want it to be check(res, NFS4ERR_REQ_TOO_BIG) + sess1.destroy() def testTooManyOps(t, env): """Send a request with more ops than the session can handle@@ -168,6 +174,7 @@ def testTooManyOps(t, env): lots_of_ops += [op.getattr(0)] res = sess1.compound(lots_of_ops) check(res, NFS4ERR_TOO_MANY_OPS) + sess1.destroy() def testBadSlot(t, env): """Send a request with a bad slot@@ -182,6 +189,7 @@ def testBadSlot(t, env): # Send sequence on (non-existant) slot number 8 res = env.c1.compound([op.sequence(sess1.sessionid, 1, 8, 8, True)]) check(res, NFS4ERR_BADSLOT) + sess1.destroy() def testReplayCache001(t, env): """Send two successful idempotent compounds with same seqid@@ -198,6 +206,7 @@ def testReplayCache001(t, env): res1.tag = res2.tag = "" if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") + sess1.destroy() def testReplayCache002(t, env): """Send two successful non-idempotent compounds with same seqid@@ -218,6 +227,7 @@ def testReplayCache002(t, env): res1.tag = res2.tag = "" if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") + sess1.destroy() def testReplayCache003(t, env): """Send two unsuccessful idempotent compounds with same seqid@@ -234,6 +244,7 @@ def testReplayCache003(t, env): res1.tag = res2.tag = "" if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") + sess1.destroy() def testReplayCache004(t, env): """Send two unsuccessful non-idempotent compounds with same seqid@@ -251,6 +262,7 @@ def testReplayCache004(t, env): res1.tag = res2.tag = "" if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") + sess1.destroy() def testReplayCache005(t, env): """Send two unsupported compounds with same seqid@@ -267,6 +279,7 @@ def testReplayCache005(t, env): res1.tag = res2.tag = "" if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") + sess1.destroy() def testReplayCache006(t, env): """Send two solo sequence compounds with same seqid@@ -283,6 +296,7 @@ def testReplayCache006(t, env): res1.tag = res2.tag = "" if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") + sess1.destroy() def testReplayCache007(t, env): """Send two successful non-idempotent compounds with same seqid and False cache_this@@ -300,6 +314,7 @@ def testReplayCache007(t, env): check(res1, NFS4_OK) res2 = sess1.compound(ops, seq_delta=0, cache_this=False) check(res2, NFS4ERR_RETRY_UNCACHED_REP) + sess1.destroy() def testOpNotInSession(t, env): """Operations other than SEQUENCE, BIND_CONN_TO_SESSION, EXCHANGE_ID,@@ -338,6 +353,7 @@ def testSessionidSequenceidSlotid(t, env): if not nfs4lib.test_equal(res.resarray[0].sr_slotid, 2, "int"): fail("server return bad slotid") + sess1.destroy() def testBadSequenceidAtSlot(t, env): """ If the difference between sa_sequenceid and the server's cached@@ -363,6 +379,7 @@ def testBadSequenceidAtSlot(t, env): res = c.c.compound([op.sequence(sid, nfs4lib.dec_u32(seqid), 2, 3, True)]) check(res, NFS4ERR_SEQ_MISORDERED) + sess1.destroy() def testReuseSlotID(t, env): """ If client reuses a slot ID and sequence ID for a completely@@ -392,3 +409,4 @@ def testReuseSlotID(t, env): res = c.c.compound([op.sequence(sid, seqid, 0, 0, TRUE)] + nfs4lib.use_obj(dir) + [op.rename(name, "test")]) check(res) + sess1.destroy()nfs4.1/server41tests/st_trunking.py +4
-0@@ -23,6 +23,8 @@ def testTwoSessions(t, env): c = env.c1.new_client(env.testname(t)) sess = c.create_session() sess2 = c.create_session() + sess.destroy() + sess2.destroy() def testUseTwoSessions(t, env):@@ -42,6 +44,8 @@ def testUseTwoSessions(t, env): check(res) res = sess2.compound([]) check(res) + sess.destroy() + sess2.destroy() # create client # create sessionnfs4.1/server41tests/st_verify.py +1
-0@@ -12,6 +12,7 @@ def _try_mand(t, env, path): ops = use_obj(path) + [op.verify(dict)] + use_obj(path) res = sess1.compound(ops) check(res, msg="Verifying mandatory attributes against getattr") + sess1.destroy() def _try_type(env, path, type): c = env.c1Signature · 1 line
1.7.4.1
Re: [PATCH 1/5] CLNT: try to destroy session after test complete
J. Bruce Fields:
Quoted 10 lines · Mi Jinlong
Quoted 3 lines
When testing pynfs41, I got
NFS4ERR_DELAYat some tests. At a test case, we don't destroy the session after create. So, this patch try to destroy session test complete.Sounds like a good idea.
It seems a little tedious to have to do this by hand every time; could we do some automatic cleanup at the end of the test when the variable goes out of scope, or something like that?
I have try my best to find a automatic method to cleanup it, but I can't get.
Maybe Fred can help us?
Signature · 3 lines
---- thanks Mi Jinlong
PATCH v2 2/5 CLNT: add a simple test about RECLAIM_COMPLETE
In reply to Mi Jinlong--- nfs4.1/server41tests/__init__.py | 1 + nfs4.1/server41tests/st_reclaim_complete.py | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 0 deletions(-) create mode 100644 nfs4.1/server41tests/st_reclaim_complete.py
nfs4.1/server41tests/__init__.py +1 -0
@@ -2,6 +2,7 @@ __all__ = ["st_exchange_id.py", # draft 21 "st_compound.py", "st_create_session.py", "st_destroy_session.py", + "st_reclaim_complete.py", "st_secinfo_no_name.py", "st_secinfo.py", "st_sequence.py",
nfs4.1/server41tests/st_reclaim_complete.py new file +22 -0
@@ -0,0 +1,22 @@ +from st_create_session import create_session +from nfs4_const import * +from environment import check, fail, use_obj, create_file +import nfs4_ops as op +import nfs4lib + +def testSupported(t, env): + """Do a simple RECLAIM_COMPLETE + + FLAGS: reclaim_complete all + CODE: RECC1 + """ + c = env.c1.new_client(env.testname(t)) + sess = c.create_session() + + # RECLAIM_COMPLETE + res = sess.compound([op.putrootfh(), op.reclaim_complete(TRUE)]) + check(res) + + res = sess.compound([op.reclaim_complete(FALSE)]) + check(res) + sess.destroy()
Signature · 1 line
1.7.4.1
PATCH v2 3/5 CLNT: test reclaim after RECLAIM_COMPLETE
In reply to Mi Jinlong--- nfs4.1/server41tests/st_reclaim_complete.py | 50 +++++++++++++++++++++++++++ 1 files changed, 50 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_reclaim_complete.py +50 -0
@@ -1,9 +1,18 @@ from st_create_session import create_session from nfs4_const import * from environment import check, fail, use_obj, create_file +from nfs4_type import open_owner4, locker4, open_to_lock_owner4 import nfs4_ops as op import nfs4lib +def opt_result(res, opt=None): + """Get the corresponding result at res.resarray[]""" + if opt == None: + return + for resa in res.resarray: + if resa.resop == opt: + return resa + def testSupported(t, env): """Do a simple RECLAIM_COMPLETE
@@ -20,3 +29,44 @@ def testSupported(t, env): res = sess.compound([op.reclaim_complete(FALSE)]) check(res) sess.destroy() + +def testReclaimAfterRECC(t, env): + """If client does subsequent reclaims of locking state after + RECLAIM_COMPLETE is done, server will return NFS4ERR_NO_GRACE. + rfc5661 18.51.3 + + FLAGS: reclaim_complete all + CODE: RECC2 + """ + name = env.testname(t) + c = env.c1.new_client(name) + sess = c.create_session() + + # RECLAIM_COMPLETE + res = sess.compound([op.reclaim_complete(FALSE)]) + check(res) + + fname = "owner_%s" % name + path = sess.c.homedir + [name] + res = create_file(sess, fname, path, access=OPEN4_SHARE_ACCESS_BOTH) + check(res) + + # Get stateid from OPEN4resok for making a lockowner + nres = opt_result(res, OP_OPEN) + if nres == None: + fail("Can not get OPEN4resok!") + oseqid = nres.stateid + + owner = open_owner4(0, "My Open Owner") + otlowner = open_to_lock_owner4(0, oseqid, 0, owner) + lowner = locker4(TRUE, otlowner) + + # Get filehandle from GETFHresok for locking + nres = opt_result(res, OP_GETFH) + if nres == None: + fail("Can not get GETFHresok!") + cfh = nres.object + + res = sess.compound([op.putfh(cfh), op.lock(READ_LT, TRUE, 0, 1, lowner)]) + check(res, NFS4ERR_NO_GRACE) + sess.destroy()
Signature · 1 line
1.7.4.1
Re: [PATCH v2 3/5] CLNT: test reclaim after RECLAIM_COMPLETE
Quoted 1 line · Mi Jinlong
Signed-off-by Mi Jinlong <[email protected]>
Looks fine but note you shouldn't need to go to the trouble of doing a lock if you want to test reclaims--opens can also be reclaimed.
--b.
Quoted 77 lines
--- nfs4.1/server41tests/st_reclaim_complete.py | 50 +++++++++++++++++++++++++++ 1 files changed, 50 insertions(+), 0 deletions(-)nfs4.1/server41tests/st_reclaim_complete.py +50
-0@@ -1,9 +1,18 @@ from st_create_session import create_session from nfs4_const import * from environment import check, fail, use_obj, create_file +from nfs4_type import open_owner4, locker4, open_to_lock_owner4 import nfs4_ops as op import nfs4lib +def opt_result(res, opt=None): + """Get the corresponding result at res.resarray[]""" + if opt == None: + return + for resa in res.resarray: + if resa.resop == opt: + return resa + def testSupported(t, env): """Do a simple RECLAIM_COMPLETE@@ -20,3 +29,44 @@ def testSupported(t, env): res = sess.compound([op.reclaim_complete(FALSE)]) check(res) sess.destroy() + +def testReclaimAfterRECC(t, env): + """If client does subsequent reclaims of locking state after + RECLAIM_COMPLETE is done, server will return NFS4ERR_NO_GRACE. + rfc5661 18.51.3 + + FLAGS: reclaim_complete all + CODE: RECC2 + """ + name = env.testname(t) + c = env.c1.new_client(name) + sess = c.create_session() + + # RECLAIM_COMPLETE + res = sess.compound([op.reclaim_complete(FALSE)]) + check(res) + + fname = "owner_%s" % name + path = sess.c.homedir + [name] + res = create_file(sess, fname, path, access=OPEN4_SHARE_ACCESS_BOTH) + check(res) + + # Get stateid from OPEN4resok for making a lockowner + nres = opt_result(res, OP_OPEN) + if nres == None: + fail("Can not get OPEN4resok!") + oseqid = nres.stateid + + owner = open_owner4(0, "My Open Owner") + otlowner = open_to_lock_owner4(0, oseqid, 0, owner) + lowner = locker4(TRUE, otlowner) + + # Get filehandle from GETFHresok for locking + nres = opt_result(res, OP_GETFH) + if nres == None: + fail("Can not get GETFHresok!") + cfh = nres.object + + res = sess.compound([op.putfh(cfh), op.lock(READ_LT, TRUE, 0, 1, lowner)]) + check(res, NFS4ERR_NO_GRACE) + sess.destroy()Signature · 1 line
1.7.4.1
PATCH v2 4/5 CLNT: test lock before RECLAIM_COMPLETE
In reply to Mi Jinlong--- nfs4.1/server41tests/st_reclaim_complete.py | 37 +++++++++++++++++++++++++++ 1 files changed, 37 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_reclaim_complete.py +37 -0
@@ -70,3 +70,40 @@ def testReclaimAfterRECC(t, env): res = sess.compound([op.putfh(cfh), op.lock(READ_LT, TRUE, 0, 1, lowner)]) check(res, NFS4ERR_NO_GRACE) sess.destroy() + +def testLockBeforeRECC(t, env): + """After a client establishes a new client ID, if non-reclaim + locking operations are done before the RECLAIM_COMPLETE, + error NFS4ERR_GRACE will be returned. rfc5661 18.51.3 + + FLAGS: reclaim_complete all + CODE: RECC3 + """ + name = env.testname(t) + c = env.c1.new_client(name) + sess = c.create_session() + + fname = "owner_%s" % name + path = sess.c.homedir + [name] + res = create_file(sess, fname, path, access=OPEN4_SHARE_ACCESS_BOTH) + check(res) + + # Get stateid from OPEN4resok for making a lockowner + nres = opt_result(res, OP_OPEN) + if nres == None: + fail("Can not get OPEN4resok!") + oseqid = nres.stateid + + owner = open_owner4(0, "My Open Owner") + otlowner = open_to_lock_owner4(0, oseqid, 0, owner) + lowner = locker4(TRUE, otlowner) + + # Get filehandle from GETFHresok for locking + nres = opt_result(res, OP_GETFH) + if nres == None: + fail("Can not get GETFHresok!") + cfh = nres.object + + res = sess.compound([op.putfh(cfh), op.lock(READ_LT, FALSE, 0, 1, lowner)]) + check(res, NFS4ERR_NO_GRACE) + sess.destroy()
Signature · 1 line
1.7.4.1
PATCH v2 5/5 CLNT: test double RECLAIM_COMPLETE after create session
In reply to Mi Jinlong--- nfs4.1/server41tests/st_reclaim_complete.py | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-)
nfs4.1/server41tests/st_reclaim_complete.py +20 -0
@@ -107,3 +107,23 @@ def testLockBeforeRECC(t, env): res = sess.compound([op.putfh(cfh), op.lock(READ_LT, FALSE, 0, 1, lowner)]) check(res, NFS4ERR_NO_GRACE) sess.destroy() + +def testDoubleRECC(t, env): + """If RECLAIM_COMPLETE is done a second time, error + NFS4ERR_COMPLETE_ALREADY will be returned. rfc5661 18.51.4 + + FLAGS: reclaim_complete all + CODE: RECC4 + """ + name = env.testname(t) + c = env.c1.new_client(name) + sess = c.create_session() + + # RECLAIM_COMPLETE + res = sess.compound([op.reclaim_complete(FALSE)]) + check(res) + + # RECLAIM_COMPLETE again + res = sess.compound([op.reclaim_complete(FALSE)]) + check(res, NFS4ERR_COMPLETE_ALREADY) + sess.destroy()
Signature · 1 line
1.7.4.1
Re: [PATCH 0/5] a pynfs41 problem and some tests about RECLAIM_COMPLETE
In reply to Mi JinlongOn a quick skim these look reasonable to me. Fred, are you catching up with this stuff or should I continue queueing it up in my tree?
--b.
Quoted 8 lines · Mi Jinlong
Fix a pynfs41 problem and some tests about
RECLAIM_COMPLETE.Signature · 3 lines
---- thanks Mi Jinlong