예제 #1
0
    def setUp(self):
        self.sess = helpers.make_session_from_config()

        # Create test collection
        self.test_coll = self.sess.collections.create(self.test_coll_path)

        # Create test object
        helpers.make_object(self.sess, self.test_obj_path, self.content_str)
예제 #2
0
 def test_query_with_in_condition(self):
     collection = self.coll_path
     filename = 'test_query_id_in_list.txt'
     file_path = '{collection}/{filename}'.format(**locals())
     obj1 = helpers.make_object(self.sess, file_path+'-1')
     obj2 = helpers.make_object(self.sess, file_path+'-2')
     ids = [x.id for x in (obj1,obj2)]
     for number in range(3):  # slice for empty(:0), first(:1) or both(:2)
         search_tuple = (ids[:number] if number >= 1 else [0] + ids[:number])
         q = self.sess.query(DataObject.name).filter(In( DataObject.id, search_tuple ))
         self.assertEqual (number, rows_returned(q))
예제 #3
0
 def test_copy_existing_obj_to_relative_dest_fails_irods4796(self):
     if self.sess.server_version <= (4, 2, 7):
         self.skipTest('iRODS servers <= 4.2.7 will give nondescriptive error')
     obj_name = 'this_object_will_exist_once_made'
     exists_path = '{}/{}'.format(self.coll_path, obj_name)
     helpers.make_object(self.sess, exists_path)
     self.assertTrue(self.sess.data_objects.exists(exists_path))
     non_existing_zone = 'this_zone_absent'
     relative_dst_path = '{non_existing_zone}/{obj_name}'.format(**locals())
     options = {}
     with self.assertRaises(ex.USER_INPUT_PATH_ERR):
         self.sess.data_objects.copy(exists_path, relative_dst_path, **options)
예제 #4
0
    def test_multiple_reads(self):
        collection = self.coll_path

        # make files
        filenames = []
        for filename in ['foo', 'bar', 'baz']:
            path = '{collection}/{filename}'.format(**locals())
            helpers.make_object(self.sess, path=path, content=path)
            filenames.append(path)

        # read files
        for filename in filenames:
            obj = self.sess.data_objects.get(filename)
            with obj.open('r') as f:
                self.assertEqual(f.read().decode(), obj.path)
예제 #5
0
    def test_multiple_reads(self):
        collection = self.coll_path

        # make files
        filenames = []
        for filename in ['foo', 'bar', 'baz']:
            path = '{collection}/{filename}'.format(**locals())
            helpers.make_object(self.sess, path=path, content=path)
            filenames.append(path)

        # read files
        for filename in filenames:
            obj = self.sess.data_objects.get(filename)
            with obj.open('r') as f:
                self.assertEqual(f.read().decode(), obj.path)
예제 #6
0
    def test_coll_read_ticket_between_rodsusers(self):
        t = None
        data_objs = []
        tmpfiles = []
        try:
            # Create ticket for read access to alice's home collection.
            alice = self.login(self.alice)
            tc = Ticket(alice)
            home = self.irods_homedir(alice)
            tc.issue('read', home.path)

            # Create 'x' and 'y' in alice's home collection
            data_objs = [
                helpers.make_object(alice,
                                    home.path + "/" + name,
                                    content='abcxyz') for name in ('x', 'y')
            ]

            with self.login(self.bob) as bob:
                ts = Ticket(bob, tc.string)
                ts.supply()
                # Check collection access ticket allows bob to list both subobjects
                self.assertEqual(len(self.list_objects(bob)), 2)
                # and that we can get (and read) them properly.
                for name in ('x', 'y'):
                    with tempfile.NamedTemporaryFile(delete=False) as tmpf:
                        tmpfiles += [tmpf]
                    bob.data_objects.get(home.path + "/" + name, tmpf.name,
                                         **{kw.FORCE_FLAG_KW: ''})
                    with open(tmpf.name, 'r') as tmpread:
                        self.assertEqual(tmpread.read(), 'abcxyz')

            td = Ticket(alice)
            td.issue('read', home.path + "/x")

            with self.login(self.bob) as bob:
                ts = Ticket(bob, td.string)
                ts.supply()

                # Check data access ticket allows bob to list only one data object
                self.assertEqual(len(self.list_objects(bob)), 1)

                # ... and fetch that object (verifying content)
                with tempfile.NamedTemporaryFile(delete=False) as tmpf:
                    tmpfiles += [tmpf]
                bob.data_objects.get(home.path + "/x", tmpf.name,
                                     **{kw.FORCE_FLAG_KW: ''})
                with open(tmpf.name, 'r') as tmpread:
                    self.assertEqual(tmpread.read(), 'abcxyz')

                # ... but not fetch the other data object owned by alice.
                with self.assertRaises(ex.DataObjectDoesNotExist):
                    bob.data_objects.get(home.path + "/y")
        finally:
            if t: t.delete()
            for d in data_objs:
                d.unlink(force=True)
            for file_ in tmpfiles:
                os.unlink(file_.name)
            alice.cleanup()
예제 #7
0
    def test_list_acl(self):
        # test args
        collection = self.coll_path
        filename = 'foo'

        # get current user info
        user = self.sess.users.get(
            config.IRODS_USER_USERNAME, config.IRODS_SERVER_ZONE)

        # make object in test collection
        path = "{collection}/{filename}".format(**locals())
        obj = helpers.make_object(self.sess, path)

        # get object
        obj = self.sess.data_objects.get(path)

        # test exception
        with self.assertRaises(TypeError):
            self.sess.permissions.get(filename)

        # get object's ACLs
        # only one for now, the owner's own access
        acl = self.sess.permissions.get(obj)[0]

        # check values
        self.assertEqual(acl.access_name, 'own')
        self.assertEqual(acl.user_zone, user.zone)
        self.assertEqual(acl.user_name, user.name)

        # check repr()
        self.assertEqual(
            repr(acl), "<iRODSAccess {0} {1} {2} {3}>".format('own', path, user.name, user.zone))

        # remove object
        self.sess.data_objects.unlink(path)
예제 #8
0
    def test_move_obj_to_coll(self):
        # test args
        collection = self.coll_path
        new_coll_name = 'my_coll'
        file_name = 'foo'

        # make object in test collection
        path = "{collection}/{file_name}".format(**locals())
        obj = helpers.make_object(self.sess, path)

        # get object id
        saved_id = obj.id

        # make new collection and move object to it
        new_coll_path = "{collection}/{new_coll_name}".format(**locals())
        new_coll = helpers.make_collection(self.sess, new_coll_path)
        self.sess.data_objects.move(path, new_coll_path)

        # get new object id
        new_path = "{collection}/{new_coll_name}/{file_name}".format(
            **locals())
        obj = self.sess.data_objects.get(new_path)

        # compare ids
        self.assertEqual(obj.id, saved_id)

        # remove new collection
        new_coll.remove(recurse=True, force=True)
예제 #9
0
    def setUp(self):
        self.sess = helpers.make_session()

        # Create test collection
        self.coll_path = '/{}/home/{}/test_dir'.format(self.sess.zone, self.sess.username)
        self.collection = self.sess.collections.create(self.coll_path)

        self.obj_name = 'test1'
        self.content_str = u'blah'
        self.write_str = u'0123456789'
        self.write_str1 = u'INTERRUPT'

        self.test_obj_path = '{coll_path}/{obj_name}'.format(**vars(self))

        # Create test object
        helpers.make_object(self.sess, self.test_obj_path, self.content_str)
예제 #10
0
    def test_obj_create_to_default_resource(self):
        if self.sess.server_version < (4, 0, 0):
            self.skipTest('For iRODS 4+')

        # make another UFS resource
        session = self.sess
        resource_name = 'ufs'
        resource_type = 'unixfilesystem'
        resource_host = session.host
        resource_path = '/tmp/' + resource_name
        session.resources.create(resource_name, resource_type, resource_host,
                                 resource_path)

        # set default resource to new UFS resource
        session.default_resource = resource_name

        # test object
        collection = self.coll_path
        filename = 'create_def_resc_test_file'
        obj_path = "{collection}/{filename}".format(**locals())
        content = ''.join(random.choice(string.printable) for _ in range(1024))

        # make object in test collection
        obj = helpers.make_object(session, obj_path, content=content)

        # get object and confirm resource
        self.assertEqual(obj.replicas[0].resource_name, resource_name)

        # delete obj and second resource
        obj.unlink(force=True)
        session.resources.remove(resource_name)
예제 #11
0
    def test_rename_obj(self):
        # test args
        collection = self.coll_path
        old_name = 'foo'
        new_name = 'bar'

        # make object in test collection
        path = "{collection}/{old_name}".format(**locals())
        obj = helpers.make_object(self.sess, path)

        # for coverage
        repr(obj)
        for replica in obj.replicas:
            repr(replica)

        # get object id
        saved_id = obj.id

        # rename object
        new_path = "{collection}/{new_name}".format(**locals())
        self.sess.data_objects.move(path, new_path)

        # get updated object
        obj = self.sess.data_objects.get(new_path)

        # compare ids
        self.assertEqual(obj.id, saved_id)

        # remove object
        self.sess.data_objects.unlink(new_path)
예제 #12
0
    def test_set_data_acl(self):
        # test args
        collection = self.coll_path
        filename = 'foo'

        # get current user info
        user = self.sess.users.get(self.sess.username, self.sess.zone)

        # make object in test collection
        path = "{collection}/{filename}".format(**locals())
        obj = helpers.make_object(self.sess, path)

        # get object
        obj = self.sess.data_objects.get(path)

        # set permission to write
        acl1 = iRODSAccess('write', path, user.name, user.zone)
        self.sess.permissions.set(acl1)

        # get object's ACLs
        acl = self.sess.permissions.get(obj)[0]  # owner's write access

        # check values
        self.assertEqual(acl.access_name, 'modify object')
        self.assertEqual(acl.user_zone, user.zone)
        self.assertEqual(acl.user_name, user.name)

        # reset permission to own
        acl1 = iRODSAccess('own', path, user.name, user.zone)
        self.sess.permissions.set(acl1)

        # remove object
        self.sess.data_objects.unlink(path)
예제 #13
0
    def test_obj_create_to_default_resource(self):
        if self.sess.server_version < (4, 0, 0):
            self.skipTest('For iRODS 4+')

        # make another UFS resource
        session = self.sess
        resource_name = 'ufs'
        resource_type = 'unixfilesystem'
        resource_host = session.host
        resource_path = '/tmp/' + resource_name
        session.resources.create(resource_name, resource_type, resource_host, resource_path)

        # set default resource to new UFS resource
        session.default_resource = resource_name

        # test object
        collection = self.coll_path
        filename = 'create_def_resc_test_file'
        obj_path = "{collection}/{filename}".format(**locals())
        content = ''.join(random.choice(string.printable) for _ in range(1024))

        # make object in test collection
        obj = helpers.make_object(session, obj_path, content=content)

        # get object and confirm resource
        self.assertEqual(obj.replicas[0].resource_name, resource_name)

        # delete obj and second resource
        obj.unlink(force=True)
        session.resources.remove(resource_name)
예제 #14
0
    def test_set_data_acl(self):
        # test args
        collection = self.coll_path
        filename = 'foo'

        # get current user info
        user = self.sess.users.get(
            config.IRODS_USER_USERNAME, config.IRODS_SERVER_ZONE)

        # make object in test collection
        path = "{collection}/{filename}".format(**locals())
        obj = helpers.make_object(self.sess, path)

        # get object
        obj = self.sess.data_objects.get(path)

        # set permission to write
        acl1 = iRODSAccess('write', path, user.name, user.zone)
        self.sess.permissions.set(acl1)

        # get object's ACLs
        acl = self.sess.permissions.get(obj)[0]  # owner's write access

        # check values
        self.assertEqual(acl.access_name, 'modify object')
        self.assertEqual(acl.user_zone, user.zone)
        self.assertEqual(acl.user_name, user.name)

        # reset permission to own
        acl1 = iRODSAccess('own', path, user.name, user.zone)
        self.sess.permissions.set(acl1)

        # remove object
        self.sess.data_objects.unlink(path)
예제 #15
0
    def test_list_acl(self):
        # test args
        collection = self.coll_path
        filename = 'foo'

        # get current user info
        user = self.sess.users.get(self.sess.username, self.sess.zone)

        # make object in test collection
        path = "{collection}/{filename}".format(**locals())
        obj = helpers.make_object(self.sess, path)

        # get object
        obj = self.sess.data_objects.get(path)

        # test exception
        with self.assertRaises(TypeError):
            self.sess.permissions.get(filename)

        # get object's ACLs
        # only one for now, the owner's own access
        acl = self.sess.permissions.get(obj)[0]

        # check values
        self.assertEqual(acl.access_name, 'own')
        self.assertEqual(acl.user_zone, user.zone)
        self.assertEqual(acl.user_name, user.name)

        # check repr()
        self.assertEqual(
            repr(acl), "<iRODSAccess own {path} {name} {zone}>".format(path=path, **vars(user)))

        # remove object
        self.sess.data_objects.unlink(path)
예제 #16
0
    def test_rename_obj(self):
        # test args
        collection = self.coll_path
        old_name = 'foo'
        new_name = 'bar'

        # make object in test collection
        path = "{collection}/{old_name}".format(**locals())
        obj = helpers.make_object(self.sess, path)

        # for coverage
        repr(obj)
        for replica in obj.replicas:
            repr(replica)

        # get object id
        saved_id = obj.id

        # rename object
        new_path = "{collection}/{new_name}".format(**locals())
        self.sess.data_objects.move(path, new_path)

        # get updated object
        obj = self.sess.data_objects.get(new_path)

        # compare ids
        self.assertEqual(obj.id, saved_id)

        # remove object
        self.sess.data_objects.unlink(new_path)
예제 #17
0
 def test_raw_acls__207(self):
     data = helpers.make_object(self.sess,"/".join((self.coll_path,"test_obj")))
     eg = eu = fg = fu = None
     try:
         eg = self.sess.user_groups.create ('egrp')
         eu = self.sess.users.create ('edith','rodsuser')
         eg.addmember(eu.name,eu.zone)
         fg = self.sess.user_groups.create ('fgrp')
         fu = self.sess.users.create ('frank','rodsuser')
         fg.addmember(fu.name,fu.zone)
         my_ownership = set([('own', self.sess.username, self.sess.zone)])
         #--collection--
         perms1data = [ iRODSAccess ('write',self.coll_path, eg.name, self.sess.zone),
                        iRODSAccess ('read', self.coll_path, fu.name, self.sess.zone)
                      ]
         for perm in perms1data: self.sess.permissions.set ( perm )
         p1 = self.sess.permissions.get ( self.coll, report_raw_acls = True)
         self.assertEqual(self.perms_lists_symm_diff( perms1data, p1 ), my_ownership)
         #--data object--
         perms2data = [ iRODSAccess ('write',data.path, fg.name, self.sess.zone),
                        iRODSAccess ('read', data.path, eu.name, self.sess.zone)
                      ]
         for perm in perms2data: self.sess.permissions.set ( perm )
         p2 = self.sess.permissions.get ( data, report_raw_acls = True)
         self.assertEqual(self.perms_lists_symm_diff( perms2data, p2 ), my_ownership)
     finally:
         ids_for_delete = [ u.id for u in (fu,fg,eu,eg) if u is not None ]
         for u in [ iRODSUser(self.sess.users,row)
                    for row in self.sess.query(User).filter(In(User.id, ids_for_delete)) ]:
             u.remove()
예제 #18
0
    def test_move_obj_to_coll(self):
        # test args
        collection = self.coll_path
        new_coll_name = 'my_coll'
        file_name = 'foo'

        # make object in test collection
        path = "{collection}/{file_name}".format(**locals())
        obj = helpers.make_object(self.sess, path)

        # get object id
        saved_id = obj.id

        # make new collection and move object to it
        new_coll_path = "{collection}/{new_coll_name}".format(**locals())
        new_coll = helpers.make_collection(self.sess, new_coll_path)
        self.sess.data_objects.move(path, new_coll_path)

        # get new object id
        new_path = "{collection}/{new_coll_name}/{file_name}".format(
            **locals())
        obj = self.sess.data_objects.get(new_path)

        # compare ids
        self.assertEqual(obj.id, saved_id)

        # remove new collection
        new_coll.remove(recurse=True, force=True)
예제 #19
0
    def test_meta_repr(self):
        # test obj
        collection = self.coll_path
        filename = 'test_meta_repr.txt'
        test_obj_path = '{collection}/{filename}'.format(**locals())

        # make object
        obj = helpers.make_object(self.sess, test_obj_path)

        # test AVU
        attribute, value, units = ('test_attr', 'test_value', 'test_units')

        # add metadata to test object
        meta = self.sess.metadata.add(DataObject, test_obj_path,
                               iRODSMeta(attribute, value, units))

        # get metadata
        meta = self.sess.metadata.get(DataObject, test_obj_path)
        id = meta[0].id

        # assert
        self.assertEqual(
            repr(meta[0]), "<iRODSMeta {id} {attribute} {value} {units}>".format(**locals()))

        # remove test object
        obj.unlink(force=True)
예제 #20
0
    def setUp(self):
        self.sess = helpers.make_session()

        # Create test collection
        self.coll_path = '/{}/home/{}/test_dir'.format(self.sess.zone,
                                                       self.sess.username)
        self.collection = self.sess.collections.create(self.coll_path)

        self.obj_name = 'test1'
        self.content_str = u'blah'
        self.write_str = u'0123456789'
        self.write_str1 = u'INTERRUPT'

        self.test_obj_path = '{coll_path}/{obj_name}'.format(**vars(self))

        # Create test object
        helpers.make_object(self.sess, self.test_obj_path, self.content_str)
예제 #21
0
    def test_create_with_checksum(self):
        # skip if server is older than 4.2
        if self.server_version < (4, 2, 0):
            self.skipTest('Expects iRODS 4.2 server-side configuration')

        # server config
        server_config_dir = '/etc/irods'
        test_re_file = os.path.join(server_config_dir, 'test.re')
        server_config_file = os.path.join(
            server_config_dir, 'server_config.json')

        try:
            with helpers.file_backed_up(server_config_file):
                # make pep rule
                test_rule = "acPostProcForPut { msiDataObjChksum ($objPath, 'forceChksum=', *out )}"

                # write pep rule into test_re
                with open(test_re_file, 'w') as f:
                    f.write(test_rule)

                # make new server configuration with additional re file
                new_server_config = self.make_new_server_config_json(
                    server_config_file)

                # repave the existing server_config.json to add test_re
                with open(server_config_file, 'w') as f:
                    f.write(new_server_config)

                # must make a new connection for the agent to pick up the
                # updated configuration
                self.sess.cleanup()

                # test object
                collection = self.coll_path
                filename = 'checksum_test_file'
                obj_path = "{collection}/{filename}".format(**locals())
                contents = 'blah' * 100
                checksum = base64.b64encode(
                    hashlib.sha256(contents).digest()).decode()

                # make object in test collection
                options = {kw.OPR_TYPE_KW: 1}   # PUT_OPR
                obj = helpers.make_object(self.sess, obj_path, content=contents, options=options)

                # verify object's checksum
                self.assertEqual(
                    obj.checksum, "sha2:{checksum}".format(**locals()))

                # cleanup
                os.unlink(test_re_file)

        except IOError as e:
            # a likely fail scenario
            if e.errno == 13:
                self.skipTest("No permission to modify server configuration")
            raise
        except:
            raise
예제 #22
0
    def test_create_with_checksum(self):
        # skip if server is older than 4.2
        if self.server_version < (4, 2, 0):
            self.skipTest('Expects iRODS 4.2 server-side configuration')

        # server config
        server_config_dir = '/etc/irods'
        test_re_file = os.path.join(server_config_dir, 'test.re')
        server_config_file = os.path.join(server_config_dir,
                                          'server_config.json')

        try:
            with helpers.file_backed_up(server_config_file):
                # make pep rule
                test_rule = "acPostProcForPut { msiDataObjChksum ($objPath, 'forceChksum=', *out )}"

                # write pep rule into test_re
                with open(test_re_file, 'w') as f:
                    f.write(test_rule)

                # make new server configuration with additional re file
                new_server_config = self.make_new_server_config_json(
                    server_config_file)

                # repave the existing server_config.json to add test_re
                with open(server_config_file, 'w') as f:
                    f.write(new_server_config)

                # must make a new connection for the agent to pick up the
                # updated configuration
                self.sess.cleanup()

                # test object
                collection = self.coll_path
                filename = 'checksum_test_file'
                obj_path = "{collection}/{filename}".format(**locals())
                contents = 'blah' * 100
                checksum = base64.b64encode(
                    hashlib.sha256(contents).digest()).decode()

                # make object in test collection
                obj = helpers.make_object(self.sess, obj_path, contents)

                # verify object's checksum
                self.assertEqual(obj.checksum,
                                 "sha2:{checksum}".format(**locals()))

                # cleanup
                os.unlink(test_re_file)

        except IOError as e:
            # a likely fail scenario
            if e.errno == 13:
                self.fail("No permission to modify server configuration")
            raise
        except:
            raise
예제 #23
0
    def setUp(self):
        """Create objects for test"""
        self.sess = helpers.make_session()
        user = self.sess.users.get(self.sess.username)
        if user.type != 'rodsadmin':
            self.skipTest('''Test runnable only by rodsadmin.''')

        admin = self.sess
        delete_my_tickets(admin)

        # Create test collection

        self.coll_path = '/{}/home/{}/ticket_test_dir'.format(
            admin.zone, admin.username)
        self.coll = helpers.make_collection(admin, self.coll_path)

        # Create anonymous test user
        self.user = admin.users.create('anonymous', 'rodsuser')
        self.rodsuser_params = {
            'host': admin.host,
            'port': admin.port,
            'user': '******',
            'password': '',
            'zone': admin.zone
        }

        # make new data object in the test collection with some initialized content

        self.INITIALIZED_DATA = b'1' * 16
        self.data_path = '{self.coll_path}/ticketed_data'.format(**locals())
        helpers.make_object(admin,
                            self.data_path,
                            content=self.INITIALIZED_DATA)

        self.MODIFIED_DATA = b'2' * 16

        # make new tickets for the various combinations

        self.tickets = {'coll': {}, 'data': {}}
        for obj_type in ('coll', 'data'):
            for access in ('read', 'write'):
                ticket = Ticket(admin)
                self.tickets[obj_type][access] = ticket.string
                ticket.issue(access, getattr(self, obj_type + '_path'))
예제 #24
0
    def test_simultaneous_multiple_AVU_joins(self):
        objects = []
        decoys = []
        try:
            collection = self.coll_path
            filename = 'test_multiple_AVU_joins'
            file_path = '{collection}/{filename}'.format(**locals())
            for x in range(3, 9):
                obj = helpers.make_object(self.sess, file_path +
                                          '-{}'.format(x))  # with metadata
                objects.append(obj)
                obj.metadata.add('A_meta', '1{}'.format(x))
                obj.metadata.add('B_meta', '2{}'.format(x))
                decoys.append(
                    helpers.make_object(
                        self.sess,
                        file_path + '-dummy{}'.format(x)))  # without metadata
            self.assertTrue(len(objects) > 0)

            # -- test simple repeat of same column --
            q = self.sess.query(DataObject,DataObjectMeta).\
                                            filter(DataObjectMeta.name == 'A_meta', DataObjectMeta.value <  '20').\
                                            filter(DataObjectMeta.name == 'B_meta', DataObjectMeta.value >= '20')
            self.assertTrue(rows_returned(q) == len(objects))

            # -- test no-stomp of previous filter --
            self.assertTrue(('B_meta',
                             '28') in [(x.name, x.value)
                                       for x in objects[-1].metadata.items()])
            q = self.sess.query(DataObject,DataObjectMeta).\
                                            filter(DataObjectMeta.name == 'B_meta').filter(DataObjectMeta.value < '28').\
                                            filter(DataObjectMeta.name == 'B_meta').filter(Like(DataObjectMeta.value, '2_'))
            self.assertTrue(rows_returned(q) == len(objects) - 1)

            # -- test multiple AVU's by same attribute name --
            objects[-1].metadata.add('B_meta', '29')
            q = self.sess.query(DataObject,DataObjectMeta).\
                                            filter(DataObjectMeta.name == 'B_meta').filter(DataObjectMeta.value == '28').\
                                            filter(DataObjectMeta.name == 'B_meta').filter(DataObjectMeta.value == '29')
            self.assertTrue(rows_returned(q) == 1)
        finally:
            for x in (objects + decoys):
                x.unlink(force=True)
            helpers.remove_unused_metadata(self.sess)
예제 #25
0
 def test_multiple_criteria_on_one_column_name(self):
     collection = self.coll_path
     filename = 'test_multiple_AVU_joins'
     file_path = '{collection}/{filename}'.format(**locals())
     objects = []
     nobj = 0
     for x in range(3,9):
         nobj += 2
         obj1 = helpers.make_object(self.sess, file_path+'-{}'.format(x))
         obj2 = helpers.make_object(self.sess, file_path+'-dummy{}'.format(x))
         objects.extend([obj1,obj2])
     self.assertTrue( nobj > 0 and len(objects) == nobj )
     q = self.sess.query(Collection,DataObject)
     dummy_test = [d for d in q if d[DataObject.name][-1:] != '8'
                               and d[DataObject.name][-7:-1] == '-dummy' ]
     self.assertTrue( len(dummy_test) > 0 )
     q = q. filter(Like(DataObject.name, '%-dummy_')).\
            filter(Collection.name == collection) .\
            filter(DataObject.name != (filename + '-dummy8'))
     results = [r[DataObject.name] for r in q]
     self.assertTrue(len(results) == len(dummy_test))
예제 #26
0
    def test_add_metadata_from_rule(self):
        '''
        Runs a rule whose body and input parameters are created in our script.
        The rule adds metadata attributes to an iRODS object
        and we check for the presence of said attributes.
        '''
        session = self.sess

        # test metadata
        attr_name = "test_attr"
        attr_value = "test_value"

        # make test object
        ts = time.time()
        zone = session.zone
        username = session.username
        object_name = 'foo_{ts}.txt'.format(**locals())

        object_path = "/{zone}/home/{username}/{object_name}".format(
            **locals())
        obj = helpers.make_object(session, object_path)

        # rule body
        rule_body = textwrap.dedent('''\
                                test {{
                                    # add metadata
                                    *attribute.*name = *value;
                                    msiAssociateKeyValuePairsToObj(*attribute, *object, "-d")
                                }}''')

        # rule parameters
        input_params = {  # extra quotes for string literals
            '*object': '"{object_path}"'.format(**locals()),
            '*name': '"{attr_name}"'.format(**locals()),
            '*value': '"{attr_value}"'.format(**locals())
        }
        output = 'ruleExecOut'

        # run test rule
        myrule = Rule(session,
                      body=rule_body,
                      irods_3_literal_style=True,
                      params=input_params,
                      output=output)
        myrule.execute()

        # check that metadata is there
        meta = session.metadata.get(DataObject, object_path)
        assert meta[0].name == attr_name
        assert meta[0].value == attr_value

        # remove test object
        obj.unlink(force=True)
예제 #27
0
    def test_add_metadata_from_rule(self):
        '''
        Runs a rule whose body and input parameters are created in our script.
        The rule adds metadata attributes to an iRODS object
        and we check for the presence of said attributes.
        '''
        session = self.sess

        # test metadata
        attr_name = "test_attr"
        attr_value = "test_value"

        # make test object
        ts = time.time()
        zone = session.zone
        username = session.username
        object_name = 'foo_{ts}.txt'.format(**locals())

        object_path = "/{zone}/home/{username}/{object_name}".format(
            **locals())
        obj = helpers.make_object(session, object_path)

        # rule body
        rule_body = textwrap.dedent('''\
                                test {{
                                    # add metadata
                                    *attribute.*name = *value;
                                    msiAssociateKeyValuePairsToObj(*attribute, *object, "-d")
                                }}''')

        # rule parameters
        input_params = {  # extra quotes for string literals
            '*object': '"{object_path}"'.format(**locals()),
            '*name': '"{attr_name}"'.format(**locals()),
            '*value': '"{attr_value}"'.format(**locals())
        }
        output = 'ruleExecOut'

        # run test rule
        myrule = Rule(session, body=rule_body,
                      params=input_params, output=output)
        myrule.execute()

        # check that metadata is there
        meta = session.metadata.get(DataObject, object_path)
        assert meta[0].name == attr_name
        assert meta[0].value == attr_value

        # remove test object
        obj.unlink(force=True)
예제 #28
0
    def test_add_metadata_from_rule_file(self):
        '''
        Tests running a rule from a client-side .r file.
        The rule adds metadata attributes to an iRODS object
        and we check for the presence of said attributes.
        '''
        session = self.sess

        # test metadata
        attr_name = "test_attr"
        attr_value = "test_value"

        # make test object
        ts = time.time()
        zone = session.zone
        username = session.username
        object_name = 'foo_{ts}.txt'.format(**locals())

        object_path = "/{zone}/home/{username}/{object_name}".format(
            **locals())
        obj = helpers.make_object(session, object_path)

        # make rule file
        rule_file_path = "/tmp/test_{ts}.r".format(**locals())
        rule = textwrap.dedent('''\
                                test {{
                                    # add metadata
                                    *attribute.*name = *value;
                                    msiAssociateKeyValuePairsToObj(*attribute, *object, "-d")
                                }}
                                INPUT *object="{object_path}",*name="{attr_name}",*value="{attr_value}"
                                OUTPUT ruleExecOut'''.format(**locals()))

        with open(rule_file_path, "w") as rule_file:
            rule_file.write(rule)

        # run test rule
        myrule = Rule(session, rule_file_path)
        myrule.execute()

        # check that metadata is there
        meta = session.metadata.get(DataObject, object_path)
        assert meta[0].name == attr_name
        assert meta[0].value == attr_value

        # remove test object
        obj.unlink(force=True)

        # remove rule file
        os.remove(rule_file_path)
예제 #29
0
    def test_add_metadata_from_rule_file(self):
        '''
        Tests running a rule from a client-side .r file.
        The rule adds metadata attributes to an iRODS object
        and we check for the presence of said attributes.
        '''
        session = self.sess

        # test metadata
        attr_name = "test_attr"
        attr_value = "test_value"

        # make test object
        ts = time.time()
        zone = session.zone
        username = session.username
        object_name = 'foo_{ts}.txt'.format(**locals())

        object_path = "/{zone}/home/{username}/{object_name}".format(
            **locals())
        obj = helpers.make_object(session, object_path)

        # make rule file
        rule_file_path = "/tmp/test_{ts}.r".format(**locals())
        rule = textwrap.dedent('''\
                                test {{
                                    # add metadata
                                    *attribute.*name = *value;
                                    msiAssociateKeyValuePairsToObj(*attribute, *object, "-d")
                                }}
                                INPUT *object="{object_path}",*name="{attr_name}",*value="{attr_value}"
                                OUTPUT ruleExecOut'''.format(**locals()))

        with open(rule_file_path, "w") as rule_file:
            rule_file.write(rule)

        # run test rule
        myrule = Rule(session, rule_file_path)
        myrule.execute()

        # check that metadata is there
        meta = session.metadata.get(DataObject, object_path)
        assert meta[0].name == attr_name
        assert meta[0].value == attr_value

        # remove test object
        obj.unlink(force=True)

        # remove rule file
        os.remove(rule_file_path)
예제 #30
0
    def test_copy_obj_to_obj(self):
        # test args
        collection = self.coll_path
        src_file_name = 'foo'
        dest_file_name = 'bar'

        # make object in test collection
        src_path = "{collection}/{src_file_name}".format(**locals())
        src_obj = helpers.make_object(self.sess, src_path, options={kw.REG_CHKSUM_KW: ''})

        # copy object
        options = {kw.VERIFY_CHKSUM_KW: ''}
        dest_path = "{collection}/{dest_file_name}".format(**locals())
        self.sess.data_objects.copy(src_path, dest_path, options)

        # compare checksums
        dest_obj = self.sess.data_objects.get(dest_path)
        self.assertEqual(src_obj.checksum, dest_obj.checksum)
예제 #31
0
    def test_obj_truncate(self):
        collection = self.coll_path
        filename = 'test_obj_truncate.txt'
        file_path = '{collection}/{filename}'.format(**locals())
        # random long content
        content = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
        truncated_content = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

        # make object
        obj = helpers.make_object(self.sess, file_path, content=content)

        # truncate object
        obj.truncate(len(truncated_content))

        # read file
        obj = self.sess.data_objects.get(file_path)
        with obj.open('r') as f:
            self.assertEqual(f.read().decode(), truncated_content)
예제 #32
0
    def test_obj_truncate(self):
        collection = self.coll_path
        filename = 'test_obj_truncate.txt'
        file_path = '{collection}/{filename}'.format(**locals())
        # random long content
        content = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
        truncated_content = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

        # make object
        obj = helpers.make_object(self.sess, file_path, content=content)

        # truncate object
        obj.truncate(len(truncated_content))

        # read file
        obj = self.sess.data_objects.get(file_path)
        with obj.open('r') as f:
            self.assertEqual(f.read().decode(), truncated_content)
예제 #33
0
    def test_copy_obj_to_obj(self):
        # test args
        collection = self.coll_path
        src_file_name = 'foo'
        dest_file_name = 'bar'

        # make object in test collection
        options = {kw.REG_CHKSUM_KW: ''}
        src_path = "{collection}/{src_file_name}".format(**locals())
        src_obj = helpers.make_object(self.sess, src_path, **options)

        # copy object
        options = {kw.VERIFY_CHKSUM_KW: ''}
        dest_path = "{collection}/{dest_file_name}".format(**locals())
        self.sess.data_objects.copy(src_path, dest_path, **options)

        # compare checksums
        dest_obj = self.sess.data_objects.get(dest_path)
        self.assertEqual(src_obj.checksum, dest_obj.checksum)
예제 #34
0
    def test_obj_replicate(self):
        # test data
        resc_name = 'temporary_test_resource'
        if self.sess.server_version < (4, 0, 0):
            resc_type = 'unix file system'
            resc_class = 'cache'
        else:
            resc_type = 'unixfilesystem'
            resc_class = ''
        resc_host = self.sess.host  # use remote host when available in CI
        resc_path = '/tmp/' + resc_name

        # make second resource
        self.sess.resources.create(resc_name,
                                   resc_type,
                                   resc_host,
                                   resc_path,
                                   resource_class=resc_class)

        # make test object on default resource
        collection = self.coll_path
        filename = 'test_replicate.txt'
        file_path = '{collection}/{filename}'.format(**locals())
        obj = helpers.make_object(self.sess, file_path)

        # replicate object to 2nd resource
        obj.replicate(resc_name)

        # refresh object
        obj = self.sess.data_objects.get(obj.path)

        # check that object is on both resources
        resources = [replica.resource_name for replica in obj.replicas]
        self.assertEqual(len(resources), 2)
        self.assertIn(resc_name, resources)

        # force remove object
        obj.unlink(force=True)

        # delete second resource
        self.sess.resources.remove(resc_name)
예제 #35
0
    def test_force_unlink(self):
        collection = self.coll_path
        filename = 'test_force_unlink.txt'
        file_path = '{collection}/{filename}'.format(**locals())
        
        # make object
        obj = helpers.make_object(self.sess, file_path)
        
        # force remove object
        obj.unlink(force=True)

        # should be gone
        with self.assertRaises(DataObjectDoesNotExist):
            obj = self.sess.data_objects.get(file_path)

        # make sure it's not in the trash either
        conditions = [DataObject.name == filename, 
                      Criterion('like', Collection.name, "/dev/trash/%%")]
        query = self.sess.query(DataObject.id, DataObject.name, Collection.name).filter(*conditions)
        results = query.all()
        self.assertEqual(len(results), 0)
예제 #36
0
    def test_copy_obj_to_coll(self):
        # test args
        collection = self.coll_path
        file_name = 'foo'
        dest_coll_name = 'copy_dest_coll'
        dest_coll_path = "{collection}/{dest_coll_name}".format(**locals())
        dest_obj_path = "{collection}/{dest_coll_name}/{file_name}".format(
            **locals())

        # make object in test collection
        path = "{collection}/{file_name}".format(**locals())
        src_obj = helpers.make_object(self.sess, path, options={kw.REG_CHKSUM_KW: ''})

        # make new collection and copy object into it
        options = {kw.VERIFY_CHKSUM_KW: ''}
        helpers.make_collection(self.sess, dest_coll_path)
        self.sess.data_objects.copy(path, dest_coll_path, options)

        # compare checksums
        dest_obj = self.sess.data_objects.get(dest_obj_path)
        self.assertEqual(src_obj.checksum, dest_obj.checksum)
예제 #37
0
    def test_copy_obj_to_coll(self):
        # test args
        collection = self.coll_path
        file_name = 'foo'
        dest_coll_name = 'copy_dest_coll'
        dest_coll_path = "{collection}/{dest_coll_name}".format(**locals())
        dest_obj_path = "{collection}/{dest_coll_name}/{file_name}".format(
            **locals())

        # make object in test collection
        path = "{collection}/{file_name}".format(**locals())
        options = {kw.REG_CHKSUM_KW: ''}
        src_obj = helpers.make_object(self.sess, path, **options)

        # make new collection and copy object into it
        options = {kw.VERIFY_CHKSUM_KW: ''}
        helpers.make_collection(self.sess, dest_coll_path)
        self.sess.data_objects.copy(path, dest_coll_path, **options)

        # compare checksums
        dest_obj = self.sess.data_objects.get(dest_obj_path)
        self.assertEqual(src_obj.checksum, dest_obj.checksum)
예제 #38
0
    def test_obj_replicate(self):
        # test data
        resc_name = 'temporary_test_resource'
        if self.sess.server_version < (4, 0, 0):
            resc_type = 'unix file system'
            resc_class = 'cache'
        else:
            resc_type = 'unixfilesystem'
            resc_class = ''
        resc_host = self.sess.host  # use remote host when available in CI
        resc_path = '/tmp/' + resc_name

        # make second resource
        self.sess.resources.create(
            resc_name, resc_type, resc_host, resc_path, resource_class=resc_class)

        # make test object on default resource
        collection = self.coll_path
        filename = 'test_replicate.txt'
        file_path = '{collection}/{filename}'.format(**locals())
        obj = helpers.make_object(self.sess, file_path)

        # replicate object to 2nd resource
        obj.replicate(resc_name)

        # refresh object
        obj = self.sess.data_objects.get(obj.path)

        # check that object is on both resources
        resources = [replica.resource_name for replica in obj.replicas]
        self.assertEqual(len(resources), 2)
        self.assertIn(resc_name, resources)

        # force remove object
        obj.unlink(force=True)

        # delete second resource
        self.sess.resources.remove(resc_name)
예제 #39
0
    def test_ticket_expiry(self):
        with helpers.make_session() as ses:
            t1 = t2 = dobj = None
            try:
                gm_now = time.gmtime()
                gm_later = time.gmtime(calendar.timegm(gm_now) + 10)
                home = self.irods_homedir(ses)
                dobj = helpers.make_object(ses,
                                           home.path + '/dummy',
                                           content='abcxyz')

                later_ts = gmtime_to_timestamp(gm_later)
                later_epoch = calendar.timegm(gm_later)

                t1 = Ticket(ses)
                t2 = Ticket(ses)

                tickets = [
                    _.issue('read', dobj.path).string for _ in (
                        t1,
                        t2,
                    )
                ]
                t1.modify(
                    'expire', later_ts
                )  # - Specify expiry with the human readable timestamp.
                t2.modify('expire', later_epoch
                          )  # - Specify expiry formatted as epoch seconds.

                # Check normal access succeeds prior to expiration
                for ticket_string in tickets:
                    with self.login(self.alice) as alice:
                        Ticket(alice, ticket_string).supply()
                        alice.data_objects.get(dobj.path)

                # Check that both time formats have effected the same expiry time (The catalog returns epoch secs.)
                timestamps = []
                for ticket_string in tickets:
                    t = ses.query(TicketQuery.Ticket).filter(
                        TicketQuery.Ticket.string == ticket_string).one()
                    timestamps.append(t[TicketQuery.Ticket.expiry_ts])
                self.assertEqual(len(timestamps), 2)
                self.assertEqual(timestamps[0], timestamps[1])

                # Wait for tickets to expire.
                epoch = int(time.time())
                while epoch <= later_epoch:
                    time.sleep(later_epoch - epoch + 1)
                    epoch = int(time.time())

                Expected_Exception = ex.CAT_TICKET_EXPIRED if ses.server_version >= (4,2,9) \
                        else ex.SYS_FILE_DESC_OUT_OF_RANGE

                # Check tickets no longer allow access.
                for ticket_string in tickets:
                    with self.login(
                            self.alice) as alice, tempfile.NamedTemporaryFile(
                            ) as f:
                        Ticket(alice, ticket_string).supply()
                        with self.assertRaises(Expected_Exception):
                            alice.data_objects.get(dobj.path, f.name,
                                                   **{kw.FORCE_FLAG_KW: ''})

            finally:
                if t1: t1.delete()
                if t2: t2.delete()
                if dobj: dobj.unlink(force=True)
예제 #40
0
    def test_object_read_and_write_tickets(self):
        if self.alice is None or self.bob is None:
            self.skipTest(
                "A rodsuser (alice and/or bob) could not be created.")
        t = None
        data_objs = []
        tmpfiles = []
        try:
            # Create ticket for read access to alice's home collection.
            alice = self.login(self.alice)
            home = self.irods_homedir(alice)

            # Create 'R' and 'W' in alice's home collection.
            data_objs = [
                helpers.make_object(alice,
                                    home.path + "/" + name,
                                    content='abcxyz') for name in ('R', 'W')
            ]
            tickets = {
                'R': Ticket(alice).issue('read', home.path + "/R").string,
                'W': Ticket(alice).issue('write', home.path + "/W").string
            }
            # Test only write ticket allows upload.
            with self.login(self.bob) as bob:
                rw_names = {}
                for name in ('R', 'W'):
                    Ticket(bob, tickets[name]).supply()
                    with tempfile.NamedTemporaryFile(delete=False) as tmpf:
                        tmpfiles += [tmpf]
                        rw_names[name] = tmpf.name
                        tmpf.write(b'hello')
                    if name == 'W':
                        bob.data_objects.put(tmpf.name, home.path + "/" + name)
                    else:
                        try:
                            bob.data_objects.put(tmpf.name,
                                                 home.path + "/" + name)
                        except ex.CAT_NO_ACCESS_PERMISSION:
                            pass
                        else:
                            raise AssertionError(
                                "A read ticket allowed a data object write operation to happen without error."
                            )

            # Test upload was successful, by getting and confirming contents.

            with self.login(
                    self.bob
            ) as bob:  # This check must be in a new session or we get CollectionDoesNotExist. - Possibly a new issue [ ]
                for name in ('R', 'W'):
                    Ticket(bob, tickets[name]).supply()
                    bob.data_objects.get(home.path + "/" + name,
                                         rw_names[name],
                                         **{kw.FORCE_FLAG_KW: ''})
                    with open(rw_names[name], 'r') as tmpread:
                        self.assertEqual(tmpread.read(),
                                         'abcxyz' if name == 'R' else 'hello')
        finally:
            if t: t.delete()
            for d in data_objs:
                d.unlink(force=True)
            for file_ in tmpfiles:
                os.unlink(file_.name)
            alice.cleanup()
예제 #41
0
 def test_obj_exists(self):
     obj_name = 'this_object_will_exist_once_made'
     exists_path = '{}/{}'.format(self.coll_path, obj_name)
     helpers.make_object(self.sess, exists_path)
     self.assertTrue(self.sess.data_objects.exists(exists_path))
예제 #42
0
    def test_irodsmetacollection_data_obj(self):
        '''
        Tested as data_object metadata
        '''
        # test settings
        avu_count = 5
        
        # make test object
        test_obj_path = self.coll_path + '/test_irodsmetacollection'
        test_obj = helpers.make_object(self.sess, test_obj_path)

        # test AVUs
        triplets = [('test_attr'+str(i), 'test_value', 'test_units') for i in range(avu_count)]

        # get coll meta
        imc = test_obj.metadata
        
        # try invalid key
        with self.assertRaises(KeyError):
            imc.get_one('bad_key')

        # invalid key type
        with self.assertRaises(TypeError):
            imc.get_one(list())

        # try empty update values
        with self.assertRaises(ValueError):
            imc.add()

        # add AVUs
        for triplet in triplets:
            imc.add(*triplet)
 
        # add another AVU with existing attribute name
        attr_name = triplets[0][0]
        duplicate_triplet = (attr_name, 'other_value', 'test_units')
        imc.add(*duplicate_triplet)
        
        # get_one should fail
        with self.assertRaises(KeyError):
            imc.get_one(attr_name)

        # remove triplet
        imc.remove(*duplicate_triplet)
        imc.get_one(attr_name)

        # get keys
        for key in imc.keys():
            self.assertIn(key, [triplet[0] for triplet in triplets])

        # get items
        for avu in imc.items():
            self.assertIsInstance(avu, iRODSMeta)
            self.assertIn(avu.name, [triplet[0] for triplet in triplets])
            self.assertIn(avu.value, [triplet[1] for triplet in triplets])
            self.assertIn(avu.units, [triplet[2] for triplet in triplets])

        # try contains
        self.assertIn(triplets[0][0], imc)

        # try contains with bad key type
        with self.assertRaises(TypeError):
            int() in imc

        # set item
        imc[attr_name] = iRODSMeta(attr_name, 'boo')

        # get item
        imc[attr_name]

        # del item with bad key type
        with self.assertRaises(TypeError):
            del imc[int()]

        # del item
        del imc[attr_name]
        
        with self.assertRaises(KeyError):
            imc[attr_name]

        # remove all metadta
        imc.remove_all()
        self.assertEqual(len(imc), 0)

        # remove test collection
        test_obj.unlink(force=True)
예제 #43
0
 def test_obj_exists(self):
     obj_name = 'this_object_will_exist_once_made'
     exists_path = '{}/{}'.format(self.coll_path, obj_name)
     helpers.make_object(self.sess, exists_path)
     self.assertTrue(self.sess.data_objects.exists(exists_path))