Skip to content

Commit 9c0c6cb

Browse files
committed
[_120,_801] ticket attributes and ticket_iterator
1 parent b9895ab commit 9c0c6cb

3 files changed

Lines changed: 81 additions & 10 deletions

File tree

irods/models.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,8 @@ class Ticket(Model):
243243
write_byte_count = Column(Integer, "TICKET_WRITE_BYTE_COUNT", 2213)
244244
write_byte_limit = Column(Integer, "TICKET_WRITE_BYTE_LIMIT", 2214)
245245

246-
## For now, use of these columns raises CAT_SQL_ERR in both PRC and iquest: (irods/irods#5929)
247-
# create_time = Column(String, 'TICKET_CREATE_TIME', 2209)
248-
# modify_time = Column(String, 'TICKET_MODIFY_TIME', 2210)
246+
create_time = Column(DateTime, 'TICKET_CREATE_TIME', 2209, min_version = (4,3,0))
247+
modify_time = Column(DateTime, 'TICKET_MODIFY_TIME', 2210, min_version = (4,3,0))
249248

250249
class DataObject(Model):
251250
"""For queries of R_DATA_MAIN when joining to R_TICKET_MAIN.

irods/test/ticket_test.py

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
#! /usr/bin/env python
22

3+
import calendar
4+
import datetime
35
import os
46
import sys
5-
import unittest
67
import time
7-
import calendar
8+
import unittest
89

910
import irods.test.helpers as helpers
1011
import tempfile
1112
from irods.session import iRODSSession
1213
import irods.exception as ex
1314
import irods.keywords as kw
14-
from irods.ticket import Ticket
15+
from irods.ticket import ticket_iterator, Ticket
1516
from irods.models import TicketQuery, DataObject, Collection
1617

1718

@@ -48,7 +49,6 @@ def login(self, user):
4849
user=user.name,
4950
password=self.users[user.name],
5051
)
51-
5252
@staticmethod
5353
def irods_homedir(sess, path_only=False):
5454
path = f"/{sess.zone}/home/{sess.username}"
@@ -73,6 +73,8 @@ def setUp(self):
7373
u = ses.users.get(ses.username)
7474
if u.type != "rodsadmin":
7575
self.skipTest("""Test runnable only by rodsadmin.""")
76+
self.rods_admin_name = ses.username
77+
7678
self.host = ses.host
7779
self.port = ses.port
7880
self.zone = ses.zone
@@ -358,6 +360,29 @@ def test_coll_read_ticket_between_rodsusers(self):
358360
os.unlink(file_.name)
359361
alice.cleanup()
360362

363+
def test_new_attributes_in_tickets__issue_801(self):
364+
# Specifically we are testing that 'modify_time' and 'create_time' attributes function as expected,
365+
# and that other attributes such as 'id' are also present.
366+
367+
bobs_ticket = None
368+
369+
try:
370+
with self.login(self.bob) as bob:
371+
bobs_ticket = Ticket(bob).issue('write', helpers.home_collection(bob))
372+
time.sleep(2)
373+
bobs_ticket.modify('add', 'user', self.rods_admin_name)
374+
375+
# Reload the ticket, this time with the full complement of attributes present.
376+
bobs_ticket = next(ticket_iterator(bob, filter_args=[TicketQuery.Ticket.string == bobs_ticket.string]))
377+
378+
self.assertGreaterEqual(
379+
bobs_ticket.modify_time,
380+
bobs_ticket.create_time + datetime.timedelta(seconds=1)
381+
)
382+
finally:
383+
if bobs_ticket:
384+
bobs_ticket.delete()
385+
361386

362387
class TestTicketOps(unittest.TestCase):
363388

@@ -456,6 +481,28 @@ def test_coll_ticket_write(self):
456481
self._ticket_write_helper(obj_type="coll")
457482

458483

484+
def test_ticket_iterator__issue_120(self):
485+
486+
ses = self.sess
487+
t = None
488+
489+
try:
490+
# t first assigned as a "utility" Ticket object
491+
t = Ticket(ses).issue('read', helpers.home_collection(ses))
492+
493+
# This time, t receives attributes from a query result: notably the id, which we use for the next test.
494+
t = Ticket(
495+
ses,
496+
result=ses.query(TicketQuery.Ticket).filter(TicketQuery.Ticket.string == t.string).one()
497+
)
498+
499+
# Check an id attribute is present and listed in the results from list_tickets
500+
self.assertIn(t.id, (_.id for _ in ticket_iterator(ses)))
501+
finally:
502+
if t:
503+
t.delete()
504+
505+
459506
if __name__ == "__main__":
460507
# let the tests find the parent irods lib
461508
sys.path.insert(0, os.path.abspath("../.."))

irods/ticket.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,42 @@ def get_epoch_seconds(utc_timestamp):
2727
except ValueError:
2828
raise # final try at conversion, so a failure is an error
2929

30+
def ticket_iterator(session, filter_args=()):
31+
return (
32+
Ticket(session, result=row)
33+
for row in session.query(TicketQuery.Ticket).filter(*filter_args)
34+
)
3035

3136
class Ticket:
37+
3238
def __init__(self, session, ticket="", result=None, allow_punctuation=False):
3339
self._session = session
40+
41+
# Do an initial error and sanity check on result.
3442
try:
3543
if result is not None:
36-
ticket = result[TicketQuery.Ticket.string]
37-
except TypeError:
44+
_ticket = result[TicketQuery.Ticket.string]
45+
except (TypeError, KeyError):
3846
raise RuntimeError(
39-
"If specified, 'result' parameter must be a TicketQuery.Ticket search result"
47+
"If specified, 'result' parameter must be a TicketQuery.Ticket query result"
4048
)
49+
50+
# Process query result if given, and set object attributes from it.
51+
if result is not None:
52+
if _ticket != ticket != "":
53+
raise RuntimeError(
54+
"A ticket name was specified but does not match the query result."
55+
)
56+
ticket = _ticket
57+
for attr, value in TicketQuery.Ticket.__dict__.items():
58+
if value is TicketQuery.Ticket.string: continue
59+
if not attr.startswith("_"):
60+
try:
61+
setattr(self, attr, result[value])
62+
except KeyError:
63+
# backward compatibility with older schema versions
64+
pass
65+
4166
self._ticket = (
4267
ticket if ticket else self._generate(allow_punctuation=allow_punctuation)
4368
)

0 commit comments

Comments
 (0)