def setUpClass(cls): if config_get_bool('common', 'multi_vo', raise_exception=False, default=False): cls.vo = {'vo': config_get('client', 'vo', raise_exception=False, default='tst')} cls.new_vo = {'vo': 'new'} cls.multi_vo = True if not vo_exists(**cls.new_vo): add_vo(description='Test', email='*****@*****.**', **cls.new_vo) else: cls.vo = {} cls.new_vo = {} cls.multi_vo = False # Add test account cls.account_name = ''.join(random.choice(string.ascii_lowercase) for x in range(10)) add_account(account=cls.account_name, type='user', email='*****@*****.**', issuer='root', **cls.vo) cls.account = InternalAccount(cls.account_name, **cls.vo) # Add test scope cls.scope_name = ''.join(random.choice(string.ascii_lowercase) for x in range(10)) add_scope(scope=cls.scope_name, account=cls.account_name, issuer='root', **cls.vo) cls.scope = InternalScope(cls.scope_name, **cls.vo) # Get test RSEs cls.rse_name = 'MOCK' cls.rse_id = get_rse_id(rse=cls.rse_name, **cls.vo) cls.rse2_name = 'MOCK2' cls.rse2_id = get_rse_id(rse=cls.rse2_name, **cls.vo) cls.rse3_name = rse_name_generator() cls.rse3_id = api_rse.add_rse(cls.rse3_name, 'root', **cls.new_vo) cls.rse4_name = rse_name_generator() cls.rse4_id = api_rse.add_rse(cls.rse4_name, 'root', **cls.new_vo) api_rse.add_distance(cls.rse3_name, cls.rse4_name, issuer='root', distance=3, **cls.new_vo)
def post(self, rse): """ Create RSE with given name. .. :quickref: RSE; create a new RSE. :param rse: The RSE name. :<json bool deterministic: Boolean to know if the pfn is generated deterministically. :<json bool volatile: Boolean for RSE cache. :<json string city: City for the RSE. :<json bool staging_area: Staging area. :<json string region_code: The region code for the RSE. :<json string country_name: The country. :<json string continent: The continent. :<json string time_zone: Timezone. :<json string ISP: Internet Service Provider. :<json string rse_type: RSE type. :<json number latitude: Latitude coordinate of RSE. :<json number longitude: Longitude coordinate of RSE. :<json string ASN: Access service network. :<json integer availability: Availability. :status 201: RSE created successfully. :status 400: Cannot decode json parameter dictionary. :status 401: Invalid Auth Token. :status 409: RSE already exists. :status 409: RSE not found. """ kwargs = { 'deterministic': True, 'volatile': False, 'city': None, 'staging_area': False, 'region_code': None, 'country_name': None, 'continent': None, 'time_zone': None, 'ISP': None, 'rse_type': None, 'latitude': None, 'longitude': None, 'ASN': None, 'availability': None, } if request.get_data(as_text=True): parameters = json_parameters() for keyword in kwargs.keys(): kwargs[keyword] = param_get(parameters, keyword, default=kwargs[keyword]) kwargs['issuer'] = request.environ.get('issuer') kwargs['vo'] = request.environ.get('vo') try: add_rse(rse, **kwargs) except InvalidObject as error: return generate_http_error_flask(400, error) except AccessDenied as error: return generate_http_error_flask(401, error) except RSENotFound as error: return generate_http_error_flask(404, error) except Duplicate as error: return generate_http_error_flask(409, error) return 'Created', 201
def POST(self, rse): """ Create RSE with given name. HTTP Success: 201 Created HTTP Error: 400 Bad request 401 Unauthorized 404 Resource not Found 409 Conflict 500 Internal Error """ json_data = data() kwargs = { 'deterministic': True, 'volatile': False, 'city': None, 'staging_area': False, 'region_code': None, 'country_name': None, 'continent': None, 'time_zone': None, 'ISP': None, 'rse_type': None, 'latitude': None, 'longitude': None, 'ASN': None, 'availability': None } try: parameters = json_data and loads(json_data) if parameters: for param in kwargs: if param in parameters: kwargs[param] = parameters[param] except ValueError: raise generate_http_error( 400, 'ValueError', 'Cannot decode json parameter dictionary') kwargs['issuer'] = ctx.env.get('issuer') try: add_rse(rse, **kwargs) except InvalidObject as error: raise generate_http_error(400, 'InvalidObject', error.args[0]) except AccessDenied as error: raise generate_http_error(401, 'AccessDenied', error.args[0]) except RSENotFound as error: raise generate_http_error(404, 'RSENotFound', error.args[0]) except Duplicate as error: raise generate_http_error(409, 'Duplicate', error.args[0]) except RucioException as error: raise generate_http_error(500, error.__class__.__name__, error.args[0]) except Exception as error: print(error) print(format_exc()) raise InternalError(error) raise Created()
def POST(self, rse): """ Create RSE with given name. HTTP Success: 201 Created HTTP Error: 400 Bad request 401 Unauthorized 500 Internal Error """ json_data = data() kwargs = {'deterministic': True, 'volatile': False, 'city': None, 'staging_area': False, 'region_code': None, 'country_name': None, 'continent': None, 'time_zone': None, 'ISP': None} try: parameters = json_data and loads(json_data) if parameters: for param in kwargs: if param in parameters: kwargs[param] = parameters[param] except ValueError: raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter dictionary') kwargs['issuer'] = ctx.env.get('issuer') try: add_rse(rse, **kwargs) except AccessDenied, e: raise generate_http_error(401, 'AccessDenied', e.args[0][0])
def create_rse_psdm(): prefix = "/reg/d/psdm" if not os.path.exists(prefix): os.makedirs(prefix) params = { 'scheme': 'file', 'prefix': prefix, 'impl': 'rucio.rse.protocols.posix.Default', 'domains': { "lan": { "read": 1, "write": 1, "delete": 1 }, "wan": { "read": 1, "write": 1, "delete": 1 } } } add_rse('PSDM_DISK', 'root', deterministic=False) add_protocol('PSDM_DISK', params) add_rse_attribute(rse='PSDM_DISK', key='istape', value='False')
def POST(self, rse): """ Create RSE with given name. HTTP Success: 201 Created HTTP Error: 400 Bad request 401 Unauthorized 404 Resource not Found 409 Conflict 500 Internal Error """ json_data = data() kwargs = {'deterministic': True, 'volatile': False, 'city': None, 'staging_area': False, 'region_code': None, 'country_name': None, 'continent': None, 'time_zone': None, 'ISP': None} try: parameters = json_data and loads(json_data) if parameters: for param in kwargs: if param in parameters: kwargs[param] = parameters[param] except ValueError: raise generate_http_error(400, 'ValueError', 'Cannot decode json parameter dictionary') kwargs['issuer'] = ctx.env.get('issuer') try: add_rse(rse, **kwargs) except InvalidObject, error: raise generate_http_error(400, 'InvalidObject', error[0][0])
def post(self, rse): """ Create RSE with given name. .. :quickref: RSE; create a new RSE. :param rse: The RSE name. :<json bool deterministic: Boolean to know if the pfn is generated deterministically. :<json bool volatile: Boolean for RSE cache. :<json string city: City for the RSE. :<json bool staging_area: Staging area. :<json string region_code: The region code for the RSE. :<json string country_name: The country. :<json string continent: The continent. :<json string time_zone: Timezone. :<json string ISP: Internet Service Provider. :status 201: RSE created successfully. :status 400: Cannot decode json parameter dictionary. :status 401: Invalid Auth Token. :status 409: RSE already exists. :status 409: RSE not found. :status 500: Internal Error. """ json_data = request.data kwargs = {'deterministic': True, 'volatile': False, 'city': None, 'staging_area': False, 'region_code': None, 'country_name': None, 'continent': None, 'time_zone': None, 'ISP': None} try: parameters = json_data and loads(json_data) if parameters: for param in kwargs: if param in parameters: kwargs[param] = parameters[param] except ValueError: return generate_http_error_flask(400, 'ValueError', 'Cannot decode json parameter dictionary') kwargs['issuer'] = request.environ.get('issuer') try: add_rse(rse, **kwargs) except InvalidObject as error: return generate_http_error_flask(400, 'InvalidObject', error.args[0]) except AccessDenied as error: return generate_http_error_flask(401, 'AccessDenied', error.args[0]) except RSENotFound as error: return generate_http_error_flask(404, 'RSENotFound', error.args[0]) except Duplicate as error: return generate_http_error_flask(409, 'Duplicate', error.args[0]) except RucioException as error: return generate_http_error_flask(500, error.__class__.__name__, error.args[0]) except Exception as error: print(error) print(format_exc()) return error, 500 return "Created", 201
def test_rses_at_different_vos(self): """ MULTI VO (CLIENT): Test that RSEs from 2nd vo don't interfere """ # Set up RSEs at two VOs rse_client = RSEClient() rse_str = ''.join(choice(ascii_uppercase) for x in range(10)) tst = 'TST_%s' % rse_str new = 'NEW_%s' % rse_str shr = 'SHR_%s' % rse_str rse_client.add_rse(tst) rse_client.add_rse(shr) add_rse(new, 'root', **self.new_vo) shr_id_new_original = add_rse(shr, 'root', **self.new_vo) # Accurate rse_id for shared RSE at 'new' # Check the cached rse-id from each VO does not interfere shr_id_tst = get_rse_id(shr, **self.vo) shr_id_new = get_rse_id(shr, **self.new_vo) assert_equal(shr_id_new, shr_id_new_original) assert_not_equal(shr_id_new, shr_id_tst) # Check that when listing RSEs we only get RSEs for our VO rse_list_tst = [r['rse'] for r in rse_client.list_rses()] rse_list_new = [r['rse'] for r in list_rses(filters={}, **self.new_vo)] assert_true(tst in rse_list_tst) assert_false(new in rse_list_tst) assert_true(shr in rse_list_tst) assert_false(tst in rse_list_new) assert_true(new in rse_list_new) assert_true(shr in rse_list_new) # Check the cached attribute-value results do not interfere and only give results from the appropriate VO attribute_value = generate_uuid() add_rse_attribute(new, 'test', attribute_value, 'root', **self.new_vo) rses_tst_1 = list(get_rses_with_attribute_value('test', attribute_value, 'test', **self.vo)) rses_new_1 = list(get_rses_with_attribute_value('test', attribute_value, 'test', **self.new_vo)) rses_tst_2 = list(get_rses_with_attribute_value('test', attribute_value, 'test', **self.vo)) rses_new_2 = list(get_rses_with_attribute_value('test', attribute_value, 'test', **self.new_vo)) assert_equal(len(rses_tst_1), 0) assert_not_equal(len(rses_new_1), 0) assert_equal(len(rses_tst_2), 0) assert_not_equal(len(rses_new_2), 0) # check parse_expression rses_tst_3 = parse_expression(shr, filter={'vo': self.vo['vo']}) rses_tst_4 = parse_expression(tst, filter={'vo': self.vo['vo']}) rses_new_3 = parse_expression(shr, filter={'vo': self.new_vo['vo']}) with assert_raises(InvalidRSEExpression): parse_expression(tst, filter={'vo': self.new_vo['vo']}) assert_equal(len(rses_tst_3), 1) assert_equal(shr_id_tst, rses_tst_3[0]['id']) assert_equal(len(rses_tst_4), 1) assert_equal(tst, rses_tst_4[0]['rse']) assert_equal(len(rses_new_3), 1) assert_equal(shr_id_new, rses_new_3[0]['id'])
def test_super_root_permissions(self): """ MULTI VO (CORE): Test super_root cannot access root/user functions """ rse_str = ''.join(choice(ascii_uppercase) for x in range(10)) rse_name = 'MOCK_%s' % rse_str scope_uuid = str(generate_uuid()).lower()[:16] scope = 'mock_%s' % scope_uuid # Test super_root@def with functions at vo='def' with assert_raises(AccessDenied): add_rse(rse_name, 'super_root', vo='def') with assert_raises(AccessDenied): add_scope(scope, 'root', 'super_root', vo='def') add_scope(scope, 'super_root', 'super_root', vo='def') assert_in(scope, [s for s in list_scopes(filter={}, vo='def')])
def test_account_counters_at_different_vos(self): """ MULTI VO (CLIENT): Test that account counters from 2nd vo don't interfere """ session = db_session.get_session() # add some RSEs to test create_counters_for_new_account rse_client = RSEClient() rse_str = ''.join(choice(ascii_uppercase) for x in range(10)) tst_rse1 = 'TST1_%s' % rse_str new_rse1 = 'NEW1_%s' % rse_str rse_client.add_rse(tst_rse1) add_rse(new_rse1, 'root', **self.new_vo) # add an account - should have counters created for RSEs on the same VO usr_uuid = str(generate_uuid()).lower()[:16] new_acc_str = 'shr-%s' % usr_uuid new_acc = InternalAccount(new_acc_str, **self.new_vo) add_account(new_acc_str, 'USER', '*****@*****.**', 'root', **self.new_vo) query = session.query(models.AccountUsage.account, models.AccountUsage.rse_id).\ distinct(models.AccountUsage.account, models.AccountUsage.rse_id).\ filter_by(account=new_acc) acc_counters = list(query.all()) assert_not_equal(0, len(acc_counters)) for counter in acc_counters: rse_id = counter[1] vo = get_rse_vo(rse_id) assert_equal(vo, self.new_vo['vo']) # add an RSE - should have counters created for accounts on the same VO new_rse2 = 'NEW2_' + rse_str new_rse2_id = add_rse(new_rse2, 'root', **self.new_vo) query = session.query(models.AccountUsage.account, models.AccountUsage.rse_id).\ distinct(models.AccountUsage.account, models.AccountUsage.rse_id).\ filter_by(rse_id=new_rse2_id) rse_counters = list(query.all()) assert_not_equal(0, len(rse_counters)) for counter in rse_counters: account = counter[0] assert_equal(account.vo, self.new_vo['vo']) session.commit()
def test_automatix(self): """ MULTI VO (DAEMON): Test that automatix runs on a single VO """ scope_client = ScopeClient() scope_uuid = str(generate_uuid()).lower()[:16] shr_scope = 'shr_%s' % scope_uuid scope_client.add_scope('root', shr_scope) add_scope(shr_scope, 'root', 'root', **self.new_vo) rse_client = RSEClient() rse_str = ''.join(choice(ascii_uppercase) for x in range(10)) shr_rse = 'SHR_%s' % rse_str mock_protocol = {'scheme': 'MOCK', 'hostname': 'localhost', 'port': 123, 'prefix': '/test/automatix', 'impl': 'rucio.rse.protocols.mock.Default', 'domains': { 'lan': {'read': 1, 'write': 1, 'delete': 1}, 'wan': {'read': 1, 'write': 1, 'delete': 1}}} rse_client.add_rse(shr_rse) rse_client.add_rse_attribute(rse=shr_rse, key='verify_checksum', value=False) rse_client.add_protocol(shr_rse, mock_protocol) add_rse(shr_rse, 'root', **self.new_vo) add_rse_attribute(rse=shr_rse, key='verify_checksum', value=False, issuer='root', **self.new_vo) add_protocol(rse=shr_rse, data=mock_protocol, issuer='root', **self.new_vo) automatix(sites=[shr_rse], inputfile='/opt/rucio/etc/automatix.json', sleep_time=30, account='root', once=True, scope=shr_scope) did_list_tst = list(DIDClient().list_dids(shr_scope, {})) did_list_new = list(list_dids(shr_scope, {}, **self.new_vo)) assert_not_equal(len(did_list_tst), 0) assert_equal(len(did_list_new), 0) did_dicts = [{'scope': shr_scope, 'name': n} for n in did_list_tst] replicas_tst = list(ReplicaClient().list_replicas(did_dicts, rse_expression=shr_rse)) replicas_new = list(list_replicas(did_dicts, rse_expression=shr_rse, **self.new_vo)) assert_not_equal(len(replicas_tst), 0) assert_equal(len(replicas_new), 0)
def setup(self): """RucioCache (Func): Find necessary rse and dids """ self.id = int(random.random() * 10000) self.rse_exist_volatile = 'RUCIO_CACHE_VOLATILE' + str(self.id) try: rse.add_rse(self.rse_exist_volatile, 'root', deterministic=True, volatile=True) except exception.Duplicate: logging.warning("rse RUCIO_CACHE_VOLATILE already there") self.rse_exist_novolatile = 'RUCIO_CACHE_NOVOLATILE' + str(self.id) try: rse.add_rse(self.rse_exist_novolatile, 'root', deterministic=True, volatile=False) except exception.Duplicate: logging.warning("rse RUCIO_CACHE_NOVOLATILE already there") self.rse_noExist = 'RUCIO_CACHE_NOEXIST' + str(self.id) dids = did.list_dids(scope='mock', filters={}, type='file') i = 0 self.files_exist = [] self.files_exist_wrong_meta = [] self.file_replica_on_novolatile = [] for _did in dids: if i < 2: i += 1 meta = did.get_metadata(scope='mock', name=_did[0]) self.files_exist.append({'scope': meta['scope'], 'name': meta['name'], 'bytes': meta['bytes'], "adler32": meta["adler32"]}) self.files_exist_wrong_meta.append({'scope': meta['scope'], 'name': meta['name'], 'bytes': 12345678, "adler32": '12345678'}) elif i < 3: meta = did.get_metadata(scope='mock', name=_did[0]) file = {'scope': meta['scope'], 'name': meta['name'], 'bytes': meta['bytes'], "adler32": meta["adler32"]} self.file_replica_on_novolatile.append(file) replica.add_replicas(self.rse_exist_novolatile, [file], account='root') logging.debug("File Exists: %s " % self.files_exist) logging.debug("File Exists with wrong metadata: %s " % self.files_exist_wrong_meta) logging.debug("File Exists on volatie rses: " % self.file_replica_on_novolatile) self.files_noExist = [{'scope': 'mock', 'name': 'file_notexist', "bytes": 1, "adler32": "0cc737eb"}] logging.debug("File not Exists: %s " % self.files_noExist) self.account = 'root' self.lifetime = 2
def createRSEs(): # Add test RSEs for i in xrange(0, 3): rse1 = str(uuid()) rse2 = str(uuid()) add_rse(rse1, issuer='root') add_rse(rse2, issuer='root') add_rse_attribute(rse1, "T1", True, issuer='root') add_rse_attribute(rse2, "T1", True, issuer='root') add_rse_attribute(rse1, "DISK", True, issuer='root') add_rse_attribute(rse2, "TAPE", True, issuer='root') for i in xrange(0, 10): rse1 = str(uuid()) add_rse(rse1, issuer='root') add_rse_attribute(rse1, "T2", True, issuer='root') add_rse_attribute(rse1, "DISK", True, issuer='root') source_rse = str(uuid()) add_rse(source_rse, issuer='root') add_rse_attribute(source_rse, "T0", True, issuer='root')
def test_access_rule_vo(self): """ MULTI VO (CORE): Test accessing rules from a different VO """ scope = InternalScope('mock', **self.vo) dataset = 'dataset_' + str(generate_uuid()) account = InternalAccount('root', **self.vo) rse_str = ''.join(choice(ascii_uppercase) for x in range(10)) rse_name = 'MOCK_%s' % rse_str rse_id = add_rse(rse_name, 'root', **self.vo) add_replica(rse_id=rse_id, scope=scope, name=dataset, bytes=10, account=account) rule_id = add_rule(dids=[{'scope': scope, 'name': dataset}], account=account, copies=1, rse_expression='MOCK', grouping='NONE', weight='fakeweight', lifetime=None, locked=False, subscription_id=None)[0] with assert_raises(AccessDenied): delete_replication_rule(rule_id=rule_id, purge_replicas=False, issuer='root', **self.new_vo) # check locks are not accessible from other VO locks = list(get_replica_locks_for_rule_id(rule_id, **self.vo)) assert_equal(len(locks), 1) locks = list(get_replica_locks_for_rule_id(rule_id, **self.new_vo)) assert_equal(len(locks), 0) delete_replication_rule(rule_id=rule_id, purge_replicas=False, issuer='root', **self.vo) rule_dict = get_replication_rule(rule_id=rule_id, issuer='root', **self.vo) assert_is_not_none(rule_dict['expires_at'])
def setup(self): """RucioCache (Func): Find necessary rse and dids """ self.id = int(random.random() * 10000) self.rse_exist_volatile = 'RUCIO_CACHE_VOLATILE' + str(self.id) try: rse.add_rse(self.rse_exist_volatile, 'root', deterministic=True, volatile=True) except exception.Duplicate: logging.warning("rse RUCIO_CACHE_VOLATILE already there") self.rse_exist_novolatile = 'RUCIO_CACHE_NOVOLATILE' + str(self.id) try: rse.add_rse(self.rse_exist_novolatile, 'root', deterministic=True, volatile=False) except exception.Duplicate: logging.warning("rse RUCIO_CACHE_NOVOLATILE already there") self.rse_noExist = 'RUCIO_CACHE_NOEXIST' + str(self.id) dids = did.list_dids(scope='mock', filters={}, type='file') i = 0 self.files_exist = [] self.files_exist_wrong_meta = [] self.file_replica_on_novolatile = [] for _did in dids: if i < 2: i += 1 meta = did.get_metadata(scope='mock', name=_did[0]) self.files_exist.append({ 'scope': meta['scope'], 'name': meta['name'], 'bytes': meta['bytes'], "adler32": meta["adler32"] }) self.files_exist_wrong_meta.append({ 'scope': meta['scope'], 'name': meta['name'], 'bytes': 12345678, "adler32": '12345678' }) elif i < 3: meta = did.get_metadata(scope='mock', name=_did[0]) file = { 'scope': meta['scope'], 'name': meta['name'], 'bytes': meta['bytes'], "adler32": meta["adler32"] } self.file_replica_on_novolatile.append(file) replica.add_replicas(self.rse_exist_novolatile, [file], account='root') logging.debug("File Exists: %s " % self.files_exist) logging.debug("File Exists with wrong metadata: %s " % self.files_exist_wrong_meta) logging.debug("File Exists on volatie rses: " % self.file_replica_on_novolatile) self.files_noExist = [{ 'scope': 'mock', 'name': 'file_notexist', "bytes": 1, "adler32": "0cc737eb" }] logging.debug("File not Exists: %s " % self.files_noExist) self.account = 'root' self.lifetime = 2
'impl': 'rucio.rse.protocols.posix.Default', 'domains': { "lan": { "read": 1, "write": 1, "delete": 1 }, "wan": { "read": 1, "write": 1, "delete": 1 } } } add_rse('SITE1_DISK', 'root') add_protocol('SITE1_DISK', params) add_rse_attribute(rse='SITE1_DISK', key='istape', value='False') params = { 'scheme': 'file', 'prefix': '/tmp/SITE2_DISK/', 'impl': 'rucio.rse.protocols.posix.Default', 'domains': { "lan": { "read": 1, "write": 1, "delete": 1 }, "wan": { "read": 1,
def test_subscriptions_at_different_vos(self): """ MULTI VO (CLIENT): Test that subscriptions from 2nd vo don't interfere """ account_client = AccountClient() usr_uuid = str(generate_uuid()).lower()[:16] shr_acc = 'shr-%s' % usr_uuid account_client.add_account(shr_acc, 'USER', '*****@*****.**') add_account(shr_acc, 'USER', '*****@*****.**', 'root', **self.new_vo) scope_client = ScopeClient() scope_uuid = str(generate_uuid()).lower()[:16] tst_scope = 'tst_%s' % scope_uuid new_scope = 'new_%s' % scope_uuid scope_client.add_scope('root', tst_scope) add_scope(new_scope, 'root', 'root', **self.new_vo) did_client = DIDClient() did_uuid = str(generate_uuid()).lower()[:16] tst_did = 'tstset_%s' % did_uuid new_did = 'newset_%s' % did_uuid rse_client = RSEClient() rse_str = ''.join(choice(ascii_uppercase) for x in range(10)) tst_rse1 = 'TST1_%s' % rse_str tst_rse2 = 'TST2_%s' % rse_str new_rse1 = 'NEW1_%s' % rse_str new_rse2 = 'NEW2_%s' % rse_str rse_client.add_rse(tst_rse1) rse_client.add_rse(tst_rse2) add_rse(new_rse1, 'root', **self.new_vo) add_rse(new_rse2, 'root', **self.new_vo) acc_lim_client = AccountLimitClient() acc_lim_client.set_local_account_limit(shr_acc, tst_rse1, 10) acc_lim_client.set_local_account_limit(shr_acc, tst_rse2, 10) set_local_account_limit(shr_acc, new_rse1, 10, 'root', **self.new_vo) set_local_account_limit(shr_acc, new_rse2, 10, 'root', **self.new_vo) did_client.add_did(tst_scope, tst_did, 'DATASET', rse=tst_rse1) add_did(new_scope, new_did, 'DATASET', 'root', rse=new_rse1, **self.new_vo) sub_client = SubscriptionClient() sub_str = generate_uuid() tst_sub = 'tstsub_' + sub_str new_sub = 'newsub_' + sub_str shr_sub = 'shrsub_' + sub_str tst_sub_id = sub_client.add_subscription(tst_sub, shr_acc, {'scope': [tst_scope]}, [{'copies': 1, 'rse_expression': tst_rse2, 'weight': 0, 'activity': 'User Subscriptions'}], '', None, 0, 0) shr_tst_sub_id = sub_client.add_subscription(shr_sub, shr_acc, {'scope': [tst_scope]}, [{'copies': 1, 'rse_expression': tst_rse2, 'weight': 0, 'activity': 'User Subscriptions'}], '', None, 0, 0) new_sub_id = add_subscription(new_sub, shr_acc, {'scope': [new_scope]}, [{'copies': 1, 'rse_expression': new_rse2, 'weight': 0, 'activity': 'User Subscriptions'}], '', False, 0, 0, 3, 'root', **self.new_vo) shr_new_sub_id = add_subscription(shr_sub, shr_acc, {'scope': [new_scope]}, [{'copies': 1, 'rse_expression': new_rse2, 'weight': 0, 'activity': 'User Subscriptions'}], '', False, 0, 0, 3, 'root', **self.new_vo) tst_subs = [s['id'] for s in sub_client.list_subscriptions()] assert_in(tst_sub_id, tst_subs) assert_in(shr_tst_sub_id, tst_subs) assert_not_in(new_sub_id, tst_subs) assert_not_in(shr_new_sub_id, tst_subs) new_subs = [s['id'] for s in list_subscriptions(**self.new_vo)] assert_in(new_sub_id, new_subs) assert_in(shr_new_sub_id, new_subs) assert_not_in(tst_sub_id, new_subs) assert_not_in(shr_tst_sub_id, new_subs) shr_tst_subs = [s['id'] for s in sub_client.list_subscriptions(name=shr_sub)] assert_in(shr_tst_sub_id, shr_tst_subs) assert_not_in(shr_new_sub_id, shr_tst_subs) shr_new_subs = [s['id'] for s in list_subscriptions(name=shr_sub, **self.new_vo)] assert_in(shr_new_sub_id, shr_new_subs) assert_not_in(shr_tst_sub_id, shr_new_subs) acc_tst_subs = [s['id'] for s in sub_client.list_subscriptions(account=shr_acc)] assert_in(tst_sub_id, acc_tst_subs) assert_in(shr_tst_sub_id, acc_tst_subs) assert_not_in(new_sub_id, acc_tst_subs) assert_not_in(shr_new_sub_id, acc_tst_subs) acc_new_subs = [s['id'] for s in list_subscriptions(account=shr_acc, **self.new_vo)] assert_in(new_sub_id, acc_new_subs) assert_in(shr_new_sub_id, acc_new_subs) assert_not_in(tst_sub_id, acc_new_subs) assert_not_in(shr_tst_sub_id, acc_new_subs)