diff --git a/cf-monitor-test b/cf-monitor-test index 6b6ada3..7326e7a 100644 --- a/cf-monitor-test +++ b/cf-monitor-test @@ -18,16 +18,19 @@ python cf-monitor-test /complete/path/to/daemon/dir -i initialFile -f finalFile @author: shroffk ''' -from channelfinder import ChannelFinderClient, Channel, Property -from optparse import OptionParser -from time import sleep +import sys import os import re +from optparse import OptionParser +from time import sleep + +from channelfinder import ChannelFinderClient SEVR = {0:'OK ', 1:'Minor ', 2:'Major '} + def main(): requiredOpts = ['initial-file', 'final-file'] usage = "usage: %prog -i initial-file -f final-file directory " @@ -46,7 +49,8 @@ def main(): if not opts.finalFile: parser.error('Please specify a final test files') mainRun(opts, args) - + + def mainRun(opts, args): for directory in args: initialFile = os.path.normpath(directory + '/' + opts.initialFile) @@ -54,11 +58,9 @@ def mainRun(opts, args): finalFile = os.path.normpath(directory + '/' + opts.finalFile) fHostName, fIocName = getArgsFromFilename(finalFile) if getPVNames(initialFile) != getPVNames(finalFile): -# raise Exception, 'initial and final file should have the same pvs' sys.exit(1) pvNames = getPVNames(initialFile) if len(pvNames) == 0: -# raise Exception, 'no pv\'s specified in the test file' sys.exit(1) ''' Touch the initial file and check channelfinder @@ -74,25 +76,26 @@ def mainRun(opts, args): check(pvNames, fHostName, fIocName) sys.exit + def check(pvNames, hostName, iocName): try: client = ChannelFinderClient() except: - raise Exception, 'Unable to create a valid webResourceClient' + raise RuntimeError('Unable to create a valid webResourceClient') channels = client.find(property=[('hostName', hostName), ('iocName', iocName)]) if channels and len(pvNames) == len(channels): for channel in channels: if channel.Name not in pvNames: -# raise Exception, 'Failed check for ' + channel.Name sys.exit(2) else: -# raise Exception, 'Failed check for ' + str(pvNames) + ' with: ' + hostName + ' & ' + iocName sys.exit(2) + def touch(fname, times=None): - with file(fname, 'a'): + with open(fname, 'a'): os.utime(fname, times) - + + def getArgsFromFilename(completeFilePath): fileName = os.path.split(os.path.normpath(completeFilePath))[1] pattern4Hostname = '(\S+?)\.\S+' diff --git a/channelfinder/CFDataTypes.py b/channelfinder/CFDataTypes.py index 0c96aaf..e663559 100644 --- a/channelfinder/CFDataTypes.py +++ b/channelfinder/CFDataTypes.py @@ -1,73 +1,85 @@ -''' +# -*- coding: utf-8 -*- + +""" Copyright (c) 2010 Brookhaven National Laboratory All rights reserved. Use is subject to license terms and conditions. Created on Feb 11, 2011 @author: shroffk -''' +""" + + +from ._conf import PYTHON3 + +if PYTHON3: + # cmp function is gone in Python 3. + # Define for backward compatibility + def cmp(a, b): + return (a > b) - (a < b) + class Channel(object): - ''' - A Channel object consists of a unique name, an owner and an optional list - of Tags and Properties - ''' # TODO - # updated the properties datastructure by splitting it into 2 dict - + # updated the properties data structure by splitting it into 2 dict + # All the attributes are private and read only in an attempt to make the channel object immutable + Name = property(lambda self: self.__Name) + Owner = property(lambda self: self.__Owner) + def __init__(self, name, owner, properties=None, tags=None): - ''' - Constructor - name = channel name - owner = channel owner - properties = list of properties of type Property - tags = list of tags of type Tag - ''' - self.__Name = str(name).strip(); - self.__Owner = str(owner).strip(); + """ + Channel object constructor. + A Channel object consists of a unique name, an owner and an optional list + of Tags and Properties + + :param name: channel name + :param owner: channel owner + :param properties: list of properties of type Property + :param tags: list of tags of type Tag + """ + self.__Name = str(name).strip() + self.__Owner = str(owner).strip() self.Properties = properties self.Tags = tags - ## All the attributes are private and read only in an attempt to make the channel object immutable - Name = property(lambda self:self.__Name) - Owner = property(lambda self:self.__Owner) -# Properties = property(lambda self:self.Properties) -# Tags = property(lambda self:self.Tags) - - ## TODO don't recreate the dictionary with every get, + ## TODO don't recreate the dictionary with every get def getProperties(self): - ''' - getProperties returns a dictionary containing all properties associated with calling channel. - the key= propertyName and the value=propertyValue - ''' + """ + Get all properties associated with calling channel. + It returns a dictionary with format: + {"property name": "property value", + ... + } + + :return: dictionary of properties, or None if property is empty + """ propDictionary = {} - if self.Properties == None: + if self.Properties is None: return None - for property in self.Properties: - propDictionary[property.Name] = property.Value + for prop in self.Properties: + propDictionary[prop.Name] = prop.Value return propDictionary -# properties = property(getProperties) - - ## TODO don't recreate the list with each get call def getTags(self): - ''' - get tags returns a list of tagNames for the tags associated with this channel - ''' - if self.Tags == None: + """ + Get all tags associated with calling channel. + All names in the results are unique, and duplicated name are removed. + It returns a list of tag names with format ['tag 1', 'tag 2', ...] + + :return: list of tags, or None if tag is empty + """ + if self.Tags is None: return None else: - return set([ tag.Name for tag in self.Tags]) - -# tags = property(getTags) + return set([tag.Name for tag in self.Tags]) + class Property(object): - ''' - Property consists of a name, an owner and a value - ''' - def __init__(self, name, owner, value=None): + """ + Property consists of a name, an owner and a value + """ self.Name = str(name).strip() self.Owner = str(owner).strip() self.Value = value @@ -75,20 +87,20 @@ def __init__(self, name, owner, value=None): str(value).strip() def __cmp__(self, *arg, **kwargs): - if arg[0] == None: + if arg[0] is None: return 1 return cmp((self.Name, self.Value), (arg[0].Name, arg[0].Value)) - + + class Tag(object): - ''' - Tag object consists on a name and an owner - ''' - def __init__(self, name, owner): + """ + Tag object consists on a name and an owner + """ self.Name = str(name).strip() self.Owner = str(owner).strip() def __cmp__(self, *arg, **kwargs): - if arg[0] == None: + if arg[0] is None: return 1 return cmp(self.Name, arg[0].Name) diff --git a/channelfinder/ChannelFinderClient.py b/channelfinder/ChannelFinderClient.py index 6f40b89..db58a85 100644 --- a/channelfinder/ChannelFinderClient.py +++ b/channelfinder/ChannelFinderClient.py @@ -1,4 +1,4 @@ -''' +""" Copyright (c) 2010 Brookhaven National Laboratory All rights reserved. Use is subject to license terms and conditions. @@ -6,41 +6,41 @@ @author: shroffk -''' -import re -import requests +""" + import ssl -from requests.adapters import HTTPAdapter -from requests.packages.urllib3.poolmanager import PoolManager +import requests from requests import auth +from requests.adapters import HTTPAdapter +from requests.exceptions import HTTPError +from urllib3.poolmanager import PoolManager from copy import copy -from _conf import _conf -try: +try: from json import JSONDecoder, JSONEncoder -except ImportError: +except ImportError: from simplejson import JSONDecoder, JSONEncoder -from collections import OrderedDict +from ._conf import basecfg, PYTHON3 class ChannelFinderClient(object): - ''' - The ChannelFinderClient provides a connection object to perform - set, update, delete and find operations. - - TODO: Fix pydocs - ''' - - __jsonheader = {'content-type':'application/json', 'accept':'application/json'} + __jsonheader = {'content-type': 'application/json', 'accept': 'application/json'} __channelsResource = '/resources/channels' __propertiesResource = '/resources/properties' __tagsResource = '/resources/tags' - + def __init__(self, BaseURL=None, username=None, password=None): - ''' - BaseURL = the url of the channelfinder service - username = - ''' - try: + """ + Channel finder client object. It provides a connection object to perform the following operations: + - find: find all channels satisfying given searching criteria + - set: add channel into service + - update: update channel information + - delete: delete channel from service + + :param BaseURL: the url of the channel finder service + :param username: user name authorized by channel finder service + :param password: password for the authorized user + """ + try: self.__baseURL = self.__getDefaultConfig('BaseURL', BaseURL) self.__userName = self.__getDefaultConfig('username', username) self.__password = self.__getDefaultConfig('password', password) @@ -50,21 +50,43 @@ def __init__(self, BaseURL=None, username=None, password=None): self.__auth = None self.__session = requests.Session() self.__session.mount(self.__baseURL, Ssl3HttpAdapter()) - #self.__session.get(self.__baseURL, verify=False, headers=copy(self.__jsonheader)).raise_for_status() - except: - raise Exception, 'Failed to create client to ' + self.__baseURL - - def __getDefaultConfig(self, arg, value): - if value == None and _conf.has_option('DEFAULT', arg): - return _conf.get('DEFAULT', arg) - else: - return value + raise RuntimeError('Failed to create client to ' + self.__baseURL) + + def __getDefaultConfig(self, key, ref): + """ + Get default configuration for given name and section. + + :param key: key word + :param ref: reference value + :return: result if key word is configured or ref is not None, otherwise None + """ + result = ref + if ref is None: + if PYTHON3: + result = basecfg['DEFAULT'].get(key, None) + elif basecfg.has_option('DEFAULT', key): + result = basecfg.get('DEFAULT', key) + return result def set(self, **kwds): - ''' + """ method to allow various types of set operations on one or many channels, tags or properties The operation creates a new entry if none exists and destructively replaces existing entries. + + It handles request to add data with one key as below: + - channel + - channels + - tag + - tags + - property + - properties + + or key combinations as: + - tag and channelName + - tag and channelNames + - property and channels + set(channel = Channel) >>> set(channel={'name':'channelName', 'owner':'channelOwner'}) >>> set(channel={'name':'channelName', @@ -108,108 +130,119 @@ def set(self, **kwds): # and add it to the channels with the names specified in channels # and delete it from all other channels - ''' + """ if len(kwds) == 1: self.__handleSingleAddParameter(**kwds) elif len(kwds) == 2: self.__handleMultipleAddParameters(**kwds) else: - raise Exception, 'incorrect usage: ' - + raise RuntimeError('incorrect usage: ') + def __handleSingleAddParameter(self, **kwds): - if 'channel' in kwds : + """ + Handle request to add parameter. The allowed keys are: + - channel + - channels + - tag + - tags + - property + - properties + + :param kwds: + """ + + if 'channel' in kwds: r = self.__session.put(self.__baseURL + self.__channelsResource + '/' + kwds['channel'][u'name'], - data=JSONEncoder().encode(kwds['channel']), - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth) + data=JSONEncoder().encode(kwds['channel']), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth) r.raise_for_status() - elif 'channels' in kwds : + elif 'channels' in kwds: r = self.__session.put(self.__baseURL + self.__channelsResource, - data=JSONEncoder().encode(kwds['channels']), - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth) + data=JSONEncoder().encode(kwds['channels']), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth) r.raise_for_status() elif 'tag' in kwds: r = self.__session.put(self.__baseURL + self.__tagsResource + '/' + kwds['tag'][u'name'], - data=JSONEncoder().encode(kwds['tag']), - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth) + data=JSONEncoder().encode(kwds['tag']), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth) r.raise_for_status() elif 'tags' in kwds: data = JSONEncoder().encode(kwds['tags']) r = self.__session.put(self.__baseURL + self.__tagsResource, - data=data, - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth) + data=data, + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth) r.raise_for_status() elif 'property' in kwds: r = self.__session.put(self.__baseURL + self.__propertiesResource + '/' + kwds['property'][u'name'], - data=JSONEncoder().encode(kwds['property']) , - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth) + data=JSONEncoder().encode(kwds['property']), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth) r.raise_for_status() - elif 'properties' in kwds: ############################ u'property' may be incorrect + elif 'properties' in kwds: + # u'property' may be incorrect data = JSONEncoder().encode(kwds['properties']) r = self.__session.put(self.__baseURL + self.__propertiesResource, - data=data, - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth) + data=data, + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth) r.raise_for_status() else: - raise Exception, 'Incorrect Usage: unknown key' + raise RuntimeError('Incorrect Usage: unknown key') def __handleMultipleAddParameters(self, **kwds): + """ + Handle request to add parameter. The allowed keys are: + - tag and channelName + - tag and channelNames + - property and channels + + :param kwds: + """ + # set a tag to a channel if 'tag' in kwds and 'channelName' in kwds: - channels = [{u'name':kwds['channelName'].strip(), u'owner':self.__userName}] + channels = [{u'name': kwds['channelName'].strip(), u'owner': self.__userName}] kwds['tag']['channels'] = channels data = kwds['tag'] self.__session.put(self.__baseURL + self.__tagsResource + '/' + kwds['tag'][u'name'], - data=JSONEncoder().encode(data), - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth).raise_for_status() + data=JSONEncoder().encode(data), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth).raise_for_status() elif 'tag' in kwds and 'channelNames' in kwds: channels = [] for eachChannel in kwds['channelNames']: - channels.append({u'name':eachChannel, u'owner':self.__userName}) + channels.append({u'name': eachChannel, u'owner': self.__userName}) kwds['tag']['channels'] = channels data = kwds['tag'] self.__session.put(self.__baseURL + self.__tagsResource + '/' + kwds['tag'][u'name'], - data=JSONEncoder().encode(data), - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth).raise_for_status() + data=JSONEncoder().encode(data), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth).raise_for_status() elif 'property' in kwds and 'channels' in kwds: data = kwds['property'] data['property']['channels'] = kwds['channels'] self.__session.put(self.__baseURL + self.__propertiesResource + '/' + kwds['property'][u'name'], - data=JSONEncoder().encode(data), - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth).raise_for_status() + data=JSONEncoder().encode(data), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth).raise_for_status() else: - raise Exception, 'Incorrect Usage: unknown keys' - - def __checkResponseState(self, r): - ''' - simply checks the return status of the http response - ''' - if not int(r[u'headers']['status']) <= 206: - match = re.search(r'description([\S\s]*?)
', r[u'body']) - msg = match.group(1) - raise Exception, 'HTTP Error status: ' + r[u'headers']['status'] + \ - ' Cause: ' + msg - return r + raise RuntimeError('Incorrect Usage: unknown keys') def find(self, **kwds): - ''' + """ Method allows you to query for a channel/s based on name, properties, tags find(name = channelNamePattern) >>> find(name='*') @@ -259,11 +292,11 @@ def find(self, **kwds): >>> assert find(size=n, ifrom=m) == find(size=n+m)[-n:] To query for the existance of a tag or property use findTag and findProperty. - ''' + """ if not self.__baseURL: - raise Exception, 'Connection not created' + raise RuntimeError('Connection not created') if not len(kwds) > 0: - raise Exception, 'Incorrect usage: atleast one parameter must be specified' + raise RuntimeError('Incorrect usage: at least one parameter must be specified') args = [] for key in kwds: if key == 'name': @@ -284,90 +317,100 @@ def find(self, **kwds): elif key == 'ifrom': args.append(('~from', '{0:d}'.format(int(kwds[key])))) else: - raise Exception, 'unknown find argument ' + key + raise RuntimeError('unknown find argument ' + key) return self.findByArgs(args) def findByArgs(self, args): url = self.__baseURL + self.__channelsResource r = self.__session.get(url, - params=args, - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth) + params=args, + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth) try: r.raise_for_status() return r.json() - except: + except HTTPError: if r.status_code == 404: return None else: r.raise_for_status() - def findTag(self, tagName): - ''' + def findTag(self, tagname): + """ Searches for the _exact_ tagName and returns a single Tag object if found - ''' - url = self.__baseURL + self.__tagsResource + '/' + tagName + + :param tagname: tag name of searching + :return: Tag object if found, otherwise None + """ + url = self.__baseURL + self.__tagsResource + '/' + tagname r = self.__session.get(url, - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth) + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth) try: r.raise_for_status() return r.json() - except: + except HTTPError: if r.status_code == 404: return None else: r.raise_for_status() - def findProperty(self, propertyName): - ''' + def findProperty(self, propertyname): + """ Searches for the _exact_ propertyName and return a single Property object if found - ''' - url = self.__baseURL + self.__propertiesResource + '/' + propertyName + + :param propertyname: property name for searching + :return: Property object if found, otherwise None + """ + url = self.__baseURL + self.__propertiesResource + '/' + propertyname r = self.__session.get(url, headers=copy(self.__jsonheader), verify=False) try: r.raise_for_status() return r.json() - except: + except HTTPError: if r.status_code == 404: return None else: r.raise_for_status() def getAllTags(self): - ''' - return a list of all the Tags present - even the ones not associated w/t any channel - ''' + """ + Search all tags present, even the ones not associated with any channel. + + :return: list of all the Tag objects present, otherwise None. + """ url = self.__baseURL + self.__tagsResource r = self.__session.get(url, headers=copy(self.__jsonheader), verify=False) try: r.raise_for_status() return r.json() - except: + except HTTPError: if r.status_code == 404: return None else: r.raise_for_status() def getAllProperties(self): - ''' - return a list of all the Properties present - even the ones not associated w/t any channel - ''' + """ + Search all the Properties present - even the ones not associated with any channel + + :return: list of the Property objects present, otherwise None + """ url = self.__baseURL + self.__propertiesResource r = self.__session.get(url, headers=copy(self.__jsonheader), verify=False) try: r.raise_for_status() return r.json() - except: + except HTTPError: if r.status_code == 404: return None else: r.raise_for_status() def delete(self, **kwds): - ''' + """ Method to delete a channel, property, tag delete(channelName = String) >>> delete(channelName = 'ch1') @@ -395,45 +438,61 @@ def delete(self, **kwds): delete(property = Property ,channelNames = [String]) >>> delete(property = {'name':'propName','owner':'propOwner'} ,channelNames = ['ch1','ch2','ch3']) # delete the property from all the channels in the channelNames list - ''' + """ if len(kwds) == 1: self.__handleSingleDeleteParameter(**kwds) elif len(kwds) == 2: self.__handleMultipleDeleteParameters(**kwds) else: - raise Exception, 'incorrect usage: Delete a single Channel/tag/property' + raise RuntimeError('incorrect usage: Delete a single Channel/tag/property') def __handleSingleDeleteParameter(self, **kwds): + """ + Handle request to delete parameter. The allowed keys are: + - channelName + - tagName + - propertyName + + :param kwds: + :return: + """ if 'channelName' in kwds: url = self.__baseURL + self.__channelsResource + '/' + kwds['channelName'].strip() self.__session.delete(url, - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth).raise_for_status() - pass + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth).raise_for_status() elif 'tagName' in kwds: url = self.__baseURL + self.__tagsResource + '/' + kwds['tagName'].strip() self.__session.delete(url, - verify=False, - headers=copy(self.__jsonheader), - auth=self.__auth).raise_for_status() - pass + verify=False, + headers=copy(self.__jsonheader), + auth=self.__auth).raise_for_status() elif 'propertyName' in kwds: url = self.__baseURL + self.__propertiesResource + '/' + kwds['propertyName'].strip() self.__session.delete(url, - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth).raise_for_status() - pass + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth).raise_for_status() else: - raise Exception, ' unkown key use channelName, tagName or proprtyName' + raise RuntimeError('Unknown key. Have to be channelName, tagName or proprtyName') def __handleMultipleDeleteParameters(self, **kwds): + """ + Handle request to delete parameter. The allowed keys are: + - tag and channelName + - tag and channelNames + - property and channelName + - property and channelNames + + :param kwds: + """ if 'tag' in kwds and 'channelName' in kwds: - self.__session.delete(self.__baseURL + self.__tagsResource + '/' + kwds['tag'][u'name'] + '/' + kwds['channelName'].strip(), - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth).raise_for_status() + self.__session.delete(self.__baseURL + self.__tagsResource + '/' + kwds['tag'][u'name'] + + '/' + kwds['channelName'].strip(), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth).raise_for_status() elif 'tag' in kwds and 'channelNames' in kwds: # find channels with the tag channelsWithTag = self.find(tagName=kwds['tag'][u'name']) @@ -442,28 +501,30 @@ def __handleMultipleDeleteParameters(self, **kwds): channelNames = [channel[u'name'] for channel in channelsWithTag if channel[u'name'] not in kwds['channelNames']] self.set(tag=kwds['tag'], channelNames=channelNames) elif 'property' in kwds and 'channelName' in kwds: - self.__session.delete(self.__baseURL + self.__propertiesResource + '/' + kwds['property'][u'name'] + '/' + kwds['channelName'], - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth).raise_for_status() + self.__session.delete(self.__baseURL + self.__propertiesResource + + '/' + kwds['property'][u'name'] + '/' + kwds['channelName'], + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth).raise_for_status() elif 'property' in kwds and 'channelNames' in kwds: channelsWithProp = self.find(property=[(kwds['property'][u'name'], '*')]) channels = [channel for channel in channelsWithProp if channel[u'name'] not in kwds['channelNames']] self.set(property=kwds['property'], channels=channels) else: - raise Exception, ' unkown keys' + raise RuntimeError('Unknown keys. Have to be ' + '(tag, channelName), ' + '(tag, channelNames), ' + '(property, channelName), ' + 'or (property and channelNames)') -#=============================================================================== -# Update methods -#=============================================================================== def update(self, **kwds): - ''' + """ update(channel = Channel) >>> update(channel = {'name':'existingCh', 'owner':'chOwner', 'properties':'[ - {'name':'newProp','owner':'propOwner','value':'Val'}, - {'name':'existingProp','owner':'propOwner','value':'newVal'}], + {'name':'newProp','owner':'propOwner','value':'Val'}, + {'name':'existingProp','owner':'propOwner','value':'newVal'}], tags=[{'name':'mytag','owner':'tagOwner'}]}) # updates the channel 'existingCh' with the new provided properties and tags # without affecting the other tags and properties of this channel @@ -508,33 +569,43 @@ def update(self, **kwds): >>> update(tab = {'name':'newTagName','owner':'tagOwner'}, originalTagName = 'oldTagName') # rename the tag 'oldTagName' to 'newTagName' # the channel with the old tag are also updated - ''' + """ if not self.__baseURL: - raise Exception, 'Olog client not configured correctly' + raise RuntimeError('Olog client not configured correctly') if len(kwds) == 1: self.__handleSingleUpdateParameter(**kwds) elif len(kwds) == 2: self.__handleMultipleUpdateParameters(**kwds) else: - raise Exception, 'incorrect usage: ' + raise RuntimeError('incorrect usage: ') def __handleSingleUpdateParameter(self, **kwds): + """ + Handle single update. It accepts key-value pair as parameters. + The keys could be one of the following: + - channel + - property + - tag + - tags + + :param kwds: + """ if 'channel' in kwds: ch = kwds['channel'] r = self.__session.post(self.__baseURL + self.__channelsResource + '/' + ch[u'name'], - data=JSONEncoder().encode(ch), - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth) + data=JSONEncoder().encode(ch), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth) r.raise_for_status() elif 'property' in kwds: property = kwds['property'] r = self.__session.post(self.__baseURL + self.__propertiesResource + '/' + property[u'name'], - data=JSONEncoder().encode(property), - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth) + data=JSONEncoder().encode(property), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth) r.raise_for_status() elif 'tag' in kwds: tag = kwds['tag'] @@ -552,9 +623,22 @@ def __handleSingleUpdateParameter(self, **kwds): auth=self.__auth) r.raise_for_status() else: - raise Exception, ' unkown key ' + raise RuntimeError('Unknown key. ') def __handleMultipleUpdateParameters(self, **kwds): + """ + handle update for multiple parameters. It accepts key-value pair as parameters. + The keys could be one of the following combinations: + - tag and channelName + - tag and channelNames + - property and channelName + - property and channelNames + - originalChannelName and channel + - originalPropertyName and property + - originalTagName and tag + + :param kwds: + """ if 'tag' in kwds and 'channelName' in kwds: # identity operation performed to prevent side-effects tag = dict(kwds['tag']) @@ -562,10 +646,10 @@ def __handleMultipleUpdateParameters(self, **kwds): tag = dict(tag) tag[u'channels'] = channels self.__session.post(self.__baseURL + self.__tagsResource + '/' + tag[u'name'], - data=JSONEncoder().encode(tag), - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth).raise_for_status() + data=JSONEncoder().encode(tag), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth).raise_for_status() elif 'tag' in kwds and 'channelNames' in kwds: # identity operation performed to prevent side-effects tag = dict(kwds['tag']) @@ -575,10 +659,10 @@ def __handleMultipleUpdateParameters(self, **kwds): tag = dict(tag) tag[u'channels'] = channels self.__session.post(self.__baseURL + self.__tagsResource + '/' + tag[u'name'], - data=JSONEncoder().encode(tag), - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth).raise_for_status() + data=JSONEncoder().encode(tag), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth).raise_for_status() elif 'property' in kwds and 'channelName' in kwds: # identity operation performed to prevent side-effects property = dict(kwds['property']) @@ -586,10 +670,10 @@ def __handleMultipleUpdateParameters(self, **kwds): property = dict(property) property[u'channels'] = channels self.__session.post(self.__baseURL + self.__propertiesResource + '/' + property[u'name'], - data=JSONEncoder().encode(property), - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth).raise_for_status() + data=JSONEncoder().encode(property), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth).raise_for_status() elif 'property' in kwds and 'channelNames' in kwds: # identity operation performed to prevent side-effects property = dict(kwds['property']) @@ -599,45 +683,52 @@ def __handleMultipleUpdateParameters(self, **kwds): property = dict(property) property[u'channels'] = channels self.__session.post(self.__baseURL + self.__propertiesResource + '/' + property[u'name'], - data=JSONEncoder().encode(property), - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth).raise_for_status() + data=JSONEncoder().encode(property), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth).raise_for_status() elif 'originalChannelName' in kwds and 'channel' in kwds: ch = kwds['channel'] channelName = kwds['originalChannelName'].strip() self.__session.post(self.__baseURL + self.__channelsResource + '/' + channelName, - data=JSONEncoder().encode(ch), - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth).raise_for_status() + data=JSONEncoder().encode(ch), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth).raise_for_status() elif 'originalPropertyName' in kwds and 'property' in kwds: prop = kwds['property'] propName = kwds['originalPropertyName'].strip() self.__session.post(self.__baseURL + self.__propertiesResource + '/' + propName, - data=JSONEncoder().encode(prop), - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth).raise_for_status() + data=JSONEncoder().encode(prop), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth).raise_for_status() elif 'originalTagName' in kwds and 'tag' in kwds: tag = kwds['tag'] tagName = kwds['originalTagName'].strip() self.__session.post(self.__baseURL + self.__tagsResource + '/' + tagName, - data=JSONEncoder().encode(tag), - headers=copy(self.__jsonheader), - verify=False, - auth=self.__auth).raise_for_status() + data=JSONEncoder().encode(tag), + headers=copy(self.__jsonheader), + verify=False, + auth=self.__auth).raise_for_status() else: - raise Exception, ' unknown keys' - + raise RuntimeError('unknown keys') class Ssl3HttpAdapter(HTTPAdapter): - """"Transport adapter" that allows us to use SSLv3.""" + def __init__(self): + """ + "Transport adapter" that allows us to use SSLv3. - def init_poolmanager(self, connections, maxsize, block=False): + """ + if PYTHON3: + super().__init__() + else: + super(Ssl3HttpAdapter, self).__init__() + self.poolmanager = None + + def init_poolmanager(self, connections, maxsize, block=False, **kwargs): self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize, block=block, ssl_version=ssl.PROTOCOL_SSLv23) - diff --git a/channelfinder/__init__.py b/channelfinder/__init__.py index d8912b5..cbb42a0 100644 --- a/channelfinder/__init__.py +++ b/channelfinder/__init__.py @@ -1,2 +1,2 @@ -from CFDataTypes import * -from ChannelFinderClient import * \ No newline at end of file +from .CFDataTypes import * +from .ChannelFinderClient import * \ No newline at end of file diff --git a/channelfinder/_conf.py b/channelfinder/_conf.py index e733b9b..9a4a9a6 100644 --- a/channelfinder/_conf.py +++ b/channelfinder/_conf.py @@ -12,17 +12,29 @@ password=MyPassword """ + +import sys +import os.path + + +if sys.version_info[0] < 3: + PYTHON3 = False + # Python 2 code in this block + from ConfigParser import SafeConfigParser as ConfigParser +else: + PYTHON3 = True + # Python 3 code in this block + from configparser import ConfigParser + def __loadConfig(): - import os.path - import ConfigParser dflt={'BaseURL':'http://localhost:8080/ChannelFinder' } - cf=ConfigParser.SafeConfigParser(defaults=dflt) + cf=ConfigParser(defaults=dflt) # print os.path.normpath(os.path.expanduser('~/channelfinderapi.conf')) cf.read([ '/etc/channelfinderapi.conf', - os.path.expanduser('~/channelfinderapi.conf'), + os.path.expanduser('~/.channelfinderapi.conf'), 'channelfinderapi.conf' ]) return cf -_conf=__loadConfig() \ No newline at end of file +basecfg=__loadConfig() \ No newline at end of file diff --git a/channelfinder/cfPropertyManager/CFPropertyManager.py b/channelfinder/cfPropertyManager/CFPropertyManager.py index dc3ab7d..689c5b4 100755 --- a/channelfinder/cfPropertyManager/CFPropertyManager.py +++ b/channelfinder/cfPropertyManager/CFPropertyManager.py @@ -1,11 +1,18 @@ +# -*- coding: utf-8 -*- + ''' SEE cf-property-manager.cfg for example configuration file ''' -from channelfinder import ChannelFinderClient + + +from __future__ import print_function +import sys +import re from optparse import OptionParser from getpass import getpass -import re -from channelfinder._conf import _conf + +from channelfinder import ChannelFinderClient +from channelfinder._conf import basecfg, PYTHON3 global username, client, exclusion_expression, password, SERVICE_URL, quiet, verbose @@ -57,9 +64,10 @@ def readConfiguration(path): global cfglines, expression_list, exclusion_expression cfglines = [line.strip().split("=",1) for line in open(path)] for properties in cfglines: - if(verbose): print properties[0] + " = " + properties[1] + if(verbose): + print(properties[0] + " = " + properties[1]) if properties[0] == "IGNORE": - print "IGNORE "+properties[1] + print("IGNORE "+properties[1]) exclusion_expression = re.compile(properties[1]) else: if client.findProperty(properties[0]) != None: @@ -67,8 +75,8 @@ def readConfiguration(path): expression = re.compile(properties[1]) expression_list.append([expression, properties[0]]) except Exception as e: - print 'Failed to find the property',properties[0] - print 'CAUSE:',e.message + print('Failed to find the property',properties[0]) + print('CAUSE:',e.message) return cfglines @@ -88,33 +96,41 @@ def applyExpression(): exclusion_expression="[^_]+" for channel_name in dbllines: prop_list = [] - if(exclusion_expression.search(channel_name)!=None): - if verbose: print "EXCLUDE: "+channel_name + if(exclusion_expression.search(channel_name) != None): + if verbose: + print("EXCLUDE: "+channel_name) else: + for expression in expression_list: + result = expression[0].search(channel_name) + if result != None: + value = clean(result.group()) + if(verbose): + print( "FOUND: "+value +" in "+ channel_name) + if value != "": + prop_list.append({u'name' : expression[1], u'owner' : username, u'value' : value}) + else: + if(verbose): + print("MISSING " + expression[1] + "IN " + channel_name) + if verbose: + print("UPDATE "+channel_name) + try: + client.update(channel = {u'name' : channel_name, u'owner':username,u'properties':prop_list }) + except Exception as e: + if PYTHON3: + # Python 3 code in this block + print('Failed to update: ' + channel_name + " \n--Cause:" + str(e).strip()) + else: + # Python 2 code in this block + print('Failed to update: ' + channel_name + " \n--Cause:" + e.message) - for expression in expression_list: - - result = expression[0].search(channel_name) - - if result != None: - value = clean(result.group()) - if(verbose): print "FOUND: "+value +" in "+ channel_name - if value != "": - prop_list.append({u'name' : expression[1], u'owner' : username, u'value' : value}) - else: - if(verbose): print "MISSING " + expression[1] + "IN " + channel_name - if verbose: print "UPDATE "+channel_name - try: - client.update(channel = {u'name' : channel_name, u'owner':username,u'properties':prop_list }) - except Exception as e: - print 'Failed to update: '+channel_name+" \n--Cause:"+ e.message def updateProperty(result, property_name,channel_name): ''' Creates or updates properties defined in configuration file for any channel object passed. ''' - if(verbose): print "ADD "+result+" TO "+property_name+ " IN " +channel_name + if(verbose): + print("ADD "+result+" TO "+property_name+ " IN " +channel_name) client.set(property={u'name':property_name, u'owner' : username, u'value':result},channelName=channel_name) @@ -123,7 +139,8 @@ def addChannel(result, property_name, channel_name): Presently not used method for building a list of channels to be batch-updated. ''' global channel_list - if (verbose):print "ADD "+result+" TO "+property_name+ " IN " +channel_name + if (verbose): + print("ADD "+result+" TO "+property_name+ " IN " +channel_name) #channel_list.append(Channel(name=channel_name, owner=username,properties=[Property(property_name,username,result)])) #ch = Channel(name=channel_name, owner=username,properties=[Property(property_name,username,result)]) #client.update(channel = ch) @@ -141,7 +158,7 @@ def __getDefaultConfig(arg, value): ''' if value == None: try: - return _conf.get('DEFAULT', arg) + return basecfg.get('DEFAULT', arg) except: return None else: @@ -194,7 +211,7 @@ def mainRun(opts, args): if password==None: password='1234' #CURRENT DEFAULT if SERVICE_URL==None: - SERVICE_URL='https://webdev.cs.nsls2.local:8181/ChannelFinder' #CURRENT DEFAULT + SERVICE_URL='https://localhost:8181/ChannelFinder' #CURRENT DEFAULT startClient() run(args[0], args[1]) @@ -204,7 +221,8 @@ def run(dbl_path,cfg_path): Core functionality sequence. ''' global DBL_PATH, CFG_PATH - if (verbose): print dbl_path, cfg_path + if (verbose): + print(dbl_path, cfg_path) DBL_PATH=dbl_path CFG_PATH=cfg_path @@ -220,7 +238,7 @@ def run(dbl_path,cfg_path): try: main() except IOError as e: - print "IOError: " + e.message + print("IOError: " + e.message) else: startClient() diff --git a/channelfinder/cfPropertyManager/__init__.py b/channelfinder/cfPropertyManager/__init__.py index 789b1f7..148e4da 100644 --- a/channelfinder/cfPropertyManager/__init__.py +++ b/channelfinder/cfPropertyManager/__init__.py @@ -1 +1 @@ -from CFPropertyManager import * \ No newline at end of file +from .CFPropertyManager import * \ No newline at end of file diff --git a/channelfinder/cfUpdate/CFUpdateIOC.py b/channelfinder/cfUpdate/CFUpdateIOC.py index 03c9d00..c389f93 100644 --- a/channelfinder/cfUpdate/CFUpdateIOC.py +++ b/channelfinder/cfUpdate/CFUpdateIOC.py @@ -9,13 +9,17 @@ CFUpdateIOC provides a command like client to update channelfinder with a list of process variables (usually the output of the dbl command). ''' + +from __future__ import print_function + import os import re from optparse import OptionParser from getpass import getpass -from channelfinder import ChannelFinderClient from glob import glob -from channelfinder._conf import _conf + +from channelfinder import ChannelFinderClient +from channelfinder._conf import basecfg def getArgsFromFilename(completeFilePath): fileName = os.path.split(os.path.normpath(completeFilePath))[1] @@ -41,7 +45,7 @@ def getPVNames(completeFilePath, pattern=None): pvNames = filter(lambda x: len(x)>0, pvNames) if pattern: pvNames = [re.match(pattern, pvName).group() for pvName in pvNames if re.match(pattern, pvName)] - return pvNames + return list(pvNames) except IOError: return None finally: @@ -65,12 +69,12 @@ def updateChannelFinder(pvNames, hostName, iocName, time, owner, password = channelfinder password ''' if hostName == None or iocName == None: - raise Exception, 'missing hostName or iocName' + raise RuntimeError('missing hostName or iocName') channels = [] try: client = ChannelFinderClient(BaseURL=service, username=username, password=password) except: - raise Exception, 'Unable to create a valid webResourceClient' + raise RuntimeError('Unable to create a valid webResourceClient') checkPropertiesExist(client, owner) previousChannelsList = client.findByArgs([(u'hostName', hostName), (u'iocName', iocName)]) if previousChannelsList != None: @@ -162,8 +166,8 @@ def checkPropertiesExist(client, propOwner): try: client.set(property={u'name' : propName, u'owner' : propOwner}) except Exception as e: - print 'Failed to create the property',propName - print 'CAUSE:',e.message + print('Failed to create the property',propName) + print('CAUSE:',e.message) def ifNoneReturnDefault(object, default): ''' @@ -209,9 +213,9 @@ def mainRun(opts, args): password=__getDefaultConfig('password',opts.password)) def __getDefaultConfig(arg, value): - if value == None: + if value is None: try: - return _conf.get('DEFAULT', arg) + return basecfg.get('DEFAULT', arg) except: return None else: diff --git a/channelfinder/util/ChannelUtil.py b/channelfinder/util/ChannelUtil.py index 787773b..0275e4e 100644 --- a/channelfinder/util/ChannelUtil.py +++ b/channelfinder/util/ChannelUtil.py @@ -1,62 +1,62 @@ -''' +""" Copyright (c) 2010 Brookhaven National Laboratory All rights reserved. Use is subject to license terms and conditions. Created on May 11, 2011 @author: shroffk -''' -from sets import Set -from Validators import PropertyValidator, TagValidator +""" + +from .Validators import PropertyValidator, TagValidator class ChannelUtil(object): - ''' + """ Utiltity class - ''' + """ def __init__(self): - ''' + """ Constructor - ''' + """ @classmethod def getAllTags(cls, channels): - ''' + """ getAllTags([Channel]) -> [String] returns a list of the tagNames of all the tags present on this set of channels - ''' + """ if isinstance(channels, list): allTags = [] for channel in channels: for tag in channel.getTags(): allTags.append(tag) - uniqueNames = Set(allTags) + uniqueNames = frozenset(allTags) return list(uniqueNames) else: return None @classmethod def getAllProperties(cls, channels): - ''' + """ getAllProperties([Channel]) -> [String] returns a list of the propertyNames of all the properties on the set of channels - ''' + """ if isinstance(channels, list): allProperties = [] for channel in channels: if channel.getProperties(): for propertyName in channel.getProperties().keys(): allProperties.append(propertyName) - uniqueNames = Set(allProperties) + uniqueNames = frozenset(allProperties) return list(uniqueNames) else: return None @classmethod def getAllPropValues(cls, channels, propertyName, key=None): - ''' + """ given the list of channels return a list of all values - ''' + """ ret = [] for ch in channels: if ch.Properties: @@ -66,37 +66,35 @@ def getAllPropValues(cls, channels, propertyName, key=None): @classmethod def validateChannelsWithTag(cls, channels, tag): - ''' + """ Utility method to validate a group of channel to ensure they all have the tag 'tag' e.g. ChannelUtil.validateChannelsWithTag(client.find(name=*), Tag('goldenOrbit','tagOwner')) this will return True is all channels with any name have the tag 'goldenOrbit' and false if anyone channel does not have that tag - ''' + """ return cls.channelsValidityCheck(channels, TagValidator(tag)) @classmethod def validateChannelWithProperty(cls, channels, prop): - ''' + """ Utility method to validate a group of channels to ensure they all have the property 'prop' e.g. ChannelUtil.validateChannelWithProperty(client.find(ElemName='The Magnet'), Property('length','propOwner','0.3')) This will return True if all channels with property ElemName with value 'The Magnet' also have the property length with value 0.3 - ''' + """ return cls.channelsValidityCheck(channels, PropertyValidator(prop)) @classmethod def channelsValidityCheck(cls, channels, validator): - ''' + """ A generic method to validate a set of channels based on a given validator. The validator needs to provide the logic on how to validate a channel in a validate method. - ''' + """ for ch in channels: if not validator.validate(ch): return False return True - - \ No newline at end of file diff --git a/channelfinder/util/Validators.py b/channelfinder/util/Validators.py index bd5d717..13e67f3 100644 --- a/channelfinder/util/Validators.py +++ b/channelfinder/util/Validators.py @@ -3,22 +3,22 @@ @author: shroffk ''' -from channelfinder import Channel, Property, Tag class TagValidator(object): ''' A simple Validator that ensures that a particular Tag is present on the channel ''' - + def __init__(self, tag): ''' Constructor ''' - self.tag = tag; - + self.tag = tag + def validate(self, channel): - return self.tag in channel.Tags + tags = [t.Name for t in channel.Tags] + return self.tag.Name in tags class PropertyValidator(object): ''' @@ -32,5 +32,7 @@ def __init__(self, prop): self.property = prop def validate(self, channel): - return self.property in channel.Properties - \ No newline at end of file + props = [p.Name for p in channel.Properties] + # for p in channel.Properties: + # props.append(p.Name) + return self.property.Name in props diff --git a/channelfinder/util/__init__.py b/channelfinder/util/__init__.py index 91efcfe..03e4db3 100644 --- a/channelfinder/util/__init__.py +++ b/channelfinder/util/__init__.py @@ -1 +1 @@ -from ChannelUtil import ChannelUtil \ No newline at end of file +from .ChannelUtil import ChannelUtil \ No newline at end of file diff --git a/example/demo.py b/example/demo.py index e53bdce..b648d64 100644 --- a/example/demo.py +++ b/example/demo.py @@ -23,45 +23,158 @@ @author: G. Shen """ -from channelfinder.ChannelFinderClient import ChannelFinderClient -from channelfinder.Channel import Tag +from channelfinder import ChannelFinderClient -if __name__ == '__main__': - cf = ChannelFinderClient(BaseURL = 'http://channelfinder.nsls2.bnl.gov:8080/ChannelFinder', username='boss', password='1234') - +import urllib3 +urllib3.disable_warnings() + + +def prop_demo(channel): + """ + Demo routine to operate property + + :param channel: + :return: + """ + # every property has to be added first before using it. + properties = [] + propDict = {'elem_type': 'cf-update', + 'elem_name': 'cf-update', + 'dev_name': 'cf-update', + 'length': 'cf-update', + 's_position': 'cf-update', + 'ordinal': 'cf-update', + 'system': 'cf-update', + 'cell': 'cf-update', + 'girder': 'cf-update', + 'handle': 'cf-update', + 'symmetry': 'cf-update', + 'hostName': 'cf-update', + 'iocName': 'cf-update', + 'pvStatus': 'cf-update', + 'time': 'cf-update', + 'ioctest': 'cf-update', + 'iocid': 'cf-update', + 'iocidtest': 'cf-update' + } + + properties1 = channel.getAllProperties() + for prop in properties1: + try: + del propDict[prop['name']] + except KeyError: + pass + if len(propDict) > 0: + for k, v in propDict.items(): + properties.append({u'name': k, u'owner': v}) + if len(propDict) == 1: + channel.set(property=properties[0]) + else: + channel.set(properties=properties) + print(channel.getAllProperties()) + else: + print('all properties are in database already.') + + +def channel_demo(channel): + """ + Demo routine to operate channel + + :param channel: + :return: + """ + try: + # the file has the following attributes: + # index, read back, set point, phys name, len[m], s[m], type + f = open('lat_conf_table.txt', 'r') + lines = f.readlines() + channels = [] + + for line in lines: + if not (line.startswith('#') or line.startswith('!') or not line.strip()): + results = line.split() + if len(results) < 7: + # input file format problem + raise + props = [{'name': u'elem_type', 'value': results[6]}, + {'name': u'elem_name', 'value': results[3]}, + {'name': u'length', 'value': results[4]}, + {'name': u's_position', 'value': results[5]}, + {'name': u'ordinal', 'value': results[0]}, + {'name': u'system', 'value': u'SR'} + ] + + if results[1] != 'NULL': + props.append({'name': u'handle', 'value': u'readback'}) + channels.append({u'name': results[1], u'owner': u'cf-update', u'properties': props}) + if results[2] != 'NULL': + props.append({'name': u'handle', 'value': u'setpoint'}) + channels.append({u'name': results[2], u'owner': u'cf-update', u'properties': props}) + channel.set(channels=channels) + finally: + f.close() + + +def tag_demo(channel): + """ + Demo routine to operate tag. + + :param channel: + :return: + """ # set one tag - tag = Tag('example1', 'vioc') - cf.set(tag=tag) + tag = {'name': 'example1', 'owner': 'cf-update'} + channel.set(tag=tag) # set a set of tags - tags = [Tag('example2', 'vioc'), Tag('example3', 'vioc'), Tag('example4', 'vioc'), Tag('example5', 'vioc')] - cf.set(tags=tags) - - channels = cf.find(name='SR*') - channelNames = [channel.Name for channel in channels] + tags = [{'name': 'example2', 'owner': 'cf-update'}, + {'name': 'example3', 'owner': 'cf-update'}, + {'name': 'example4', 'owner': 'cf-update'}, + {'name': 'example5', 'owner': 'cf-update'}] + channel.set(tags=tags) + + +def addtag2channel_demo(channel): + tag = {'name': 'example1', 'owner': 'cf-update'} + + # set a set of tags + tags = [{'name': 'example2', 'owner': 'cf-update'}, + {'name': 'example3', 'owner': 'cf-update'}, + {'name': 'example4', 'owner': 'cf-update'}, + {'name': 'example5', 'owner': 'cf-update'}] + + channels = channel.find(name='SR*') + channelNames = [ch['name'] for ch in channels] # set a tag to many channels - cf.set(tag=tag, channelNames=channelNames) + channel.set(tag=tag, channelNames=channelNames) # set tags to many channels for tag in tags: - cf.set(tag=tag, channelNames=channelNames) - - # retrieve channel, properties, and tags -# channels = cf.find(name='SR*') -# for channel in channels: -# print channel.Name -# # get tags for each channel -# tmp_tags = channel.getTags() -# if tmp_tags != None: -# for tmp_tag in tmp_tags: -# print tmp_tag - - # remove one tag -# cf.remove(tagName='example1') -# cf.remove(tagName='example2') -# cf.remove(tagName='example3') -# cf.remove(tagName='example4') -# cf.remove(tagName='example5') - -# print len(channels) + channel.set(tag=tag, channelNames=channelNames) + + +def searchchannel_demo(channel): + """ + Demo routine to search channel names in channel finder. + + :param channel: + :return: + """ + channels = channel.find(name='SR*') + print(len(channels)) + for channel in channels: + print(channel) + + +if __name__ == '__main__': + # cf = ChannelFinderClient(BaseURL='https://localhost:8181/ChannelFinder', username='channel', password='1234') + cf = ChannelFinderClient() + # you can use browser to view results + # http://localhost:8080/ChannelFinder/resources/channels?~name=SR* + + tag_demo(cf) + prop_demo(cf) + channel_demo(cf) + addtag2channel_demo(cf) + searchchannel_demo(cf) diff --git a/example/loadData.py b/example/loadData.py deleted file mode 100644 index 45a6ffb..0000000 --- a/example/loadData.py +++ /dev/null @@ -1,173 +0,0 @@ -""" -This module is a client which provides a interface to access channel finder service to get channel information. -The Channel Finder service uses a web service, and http protocol to provide EPICS channel name, and its related -properties, tags. The properties supported so far are, which is developed against NSLS II storage ring.: - 'elem_type': element type - 'elem_name': element name - 'length': element length - 's_position': s position along beam trajectory - 'ordinal': index in simulation code (for NSLS II storage ring, tracy) - 'system': system, for example, storage ring - 'cell': cell information - 'girder': girder information - 'handle': handle, either setpoint or readback - 'symmetry': symmetry (A or B for NSLS II storage ring, following the naming convention) - - - -Created on Mar 14, 2011 - National Synchrotron Radiation Facility II - Brookhaven National Laboratory - PO Box 5000, Upton, New York, 11973-5000 - -@author: G. Shen -""" - -import sys -import time -import re - -from channelfinder.ChannelFinderClient import ChannelFinderClient -from channelfinder.Channel import Channel -from channelfinder.Channel import Property - -def addProps(cf): - # every property has to be added first before using it. - properties = [] - - # connect to server is time-consuming - # A bad example to set multiple properties -# beg = time.time() -# if cf.findProperty('dev_type') == None: -# properties.append(Property('dev_type', 'vioc')) -# if cf.findProperty('elem_name') == None: -# properties.append(Property('elem_name', 'vioc')) -# if cf.findProperty('length') == None: -# properties.append(Property('length', 'vioc')) -# if cf.findProperty('s_position') == None: -# properties.append(Property('s_position', 'vioc')) -# if cf.findProperty('ordinal') == None: -# properties.append(Property('ordinal', 'vioc')) -# if cf.findProperty('system') == None: -# properties.append(Property('system', 'vioc')) -# if cf.findProperty('cell') == None: -# properties.append(Property('cell', 'vioc')) -# if cf.findProperty('girder') == None: -# properties.append(Property('girder', 'vioc')) -# if cf.findProperty('ch_type') == None: -# properties.append(Property('ch_type', 'vioc')) -# end = time.time() -# print ('%.6f' % (end - beg)) - - # This method works better -# beg1 = time.time() - propDict = {'elem_type': 'vioc', \ - 'elem_name': 'vioc', \ - 'dev_name': 'vioc', \ - 'length': 'vioc', \ - 's_position': 'vioc', \ - 'ordinal': 'vioc', \ - 'system': 'vioc', \ - 'cell': 'vioc', \ - 'girder': 'vioc', \ - 'handle': 'vioc', \ - 'symmetry': 'vioc' - } - - properties1 = cf.getAllProperties() - for prop in properties1: - try: - del propDict[prop.Name] - except KeyError: - pass - if len(propDict) > 0: - for key in propDict.iterkeys(): - properties.append(Property(key, propDict[key])) -# end1 = time.time() -# print ('%.6f' % (end1 - beg1)) - - if len(properties) > 0: - cf.set(properties=properties) - else: - print 'all properties are in database already.' - -def buildProps(results, channame, chtype): - properties = [Property('elem_type', 'vioc', results[6]), - Property('elem_name', 'vioc', results[3]), - Property('dev_name', 'vioc', results[7]), - Property('length', 'vioc', results[4]), - Property('s_position', 'vioc', results[5]), - Property('ordinal', 'vioc', results[0])] - - # SR stands for storage ring - if channame.startswith('SR'): - properties.append(Property('system', 'vioc', 'storage ring')) - - # C00 stands for global pv - if channame.find('C00') == -1: -# tmp = channame.split(':') -# properties.append(Property('cell', 'vioc', tmp[1][1:3])) -# properties.append(Property('girder', 'vioc', tmp[2][1:3])) -# properties.append(Property('symmetry', 'vioc', tmp[2][3:4])) -# print channame - try: - tmp = re.match(r'.*(C\d{1,2}).*(G\d{1,2})(.).*', channame) - properties.append(Property('cell', 'vioc', tmp.groups()[0])) - properties.append(Property('girder', 'vioc', tmp.groups()[1])) - properties.append(Property('symmetry', 'vioc', tmp.groups()[2])) -# properties.append(Property('cell', 'vioc', tmp.groups()[0])) -# properties.append(Property('girder', 'vioc', tmp.groups()[1])) -# properties.append(Property('symmetry', 'vioc', tmp.groups()[2])) - except: - raise - - properties.append(Property('handle', 'vioc', chtype)) - return properties - -if __name__ == '__main__': - baseurl = 'http://channelfinder.nsls2.bnl.gov:8080/ChannelFinder' - client = ChannelFinderClient(BaseURL=baseurl, username='boss', password='1234') - # you can use browser to view results - # http://channelfinder.nsls2.bnl.gov:8080/ChannelFinder/resources/channels?~name=SR* - - addProps(client) - - try: - # the file has the following attributes: - #index, read back, set point, phys name, len[m], s[m], type - f = open('lat_conf_table.txt', 'r') - lines = f.readlines() - channels = [] - for line in lines: - if not (line.startswith('#') or line.startswith('!') or not line.strip()): - results = line.split() - if len(results) < 7: - # input file format problem - raise - - if results[1] != 'NULL': - channels.append(Channel((u'%s' %results[1]), 'vioc', properties=buildProps(results, results[1], 'readback'))) - #name = u'%s' % result[1] - #channels.append(Channel(name, 'vioc', properties=buildProps(results, results[1], 'readback'))) - #client.set(channel = Channel((u'%s' %results[1]), 'vioc', properties=buildProps(results, results[1], 'readback'))) - if results[2] != 'NULL': - channels.append(Channel((u'%s' %results[2]), 'vioc', properties=buildProps(results, results[2], 'setpoint'))) - #name = u'%s' % result[2] - #channels.append(Channel(name, 'vioc', properties=buildProps(results, results[2], 'readback'))) - #client.set(channel = Channel((u'%s' %results[2]), 'vioc', properties=buildProps(results, results[2], 'setpoint'))) - beg = time.time() - client.set(channels=channels) - end = time.time() - print ('%.6f' % (end-beg)) - finally: - f.close() - -# channels = client.getAllChannels() - channels = client.find(name='SR*') - print len(channels) -# beg = time.time() - for channel in channels: - print channel.Name -# client.remove(channelName=(u'%s' % channel.Name)) - end = time.time() -# print ('%.6f' % (end-beg)) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..46bc311 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +requests>=2.15.0 +simplejson>=3.10.0 +urllib3>=1.22 \ No newline at end of file diff --git a/setup.py b/setup.py index 10d16f2..655aa94 100644 --- a/setup.py +++ b/setup.py @@ -6,6 +6,21 @@ from setuptools import setup +from os import path + +cur_dir = path.abspath(path.dirname(__file__)) + +with open(path.join(cur_dir, 'requirements.txt')) as f: + requirements = f.read().split() + +extras_require = { + 'PySide': ['PySide'], + 'pyepics': ['pyepics'], + 'perf': ['psutil'], + 'testing-ioc': ['pcaspy'], + 'test': ['codecov', 'pytest', 'pytest-cov', 'coverage', 'coveralls', 'pcaspy'] +} + setup( name='channelfinder', version='3.0.0', @@ -15,11 +30,9 @@ url='http://channelfinder.sourceforge.net/channelfinderpy', scripts=['cf-update-ioc', 'cf-monitor-test'], packages=['channelfinder', 'channelfinder/util', 'channelfinder/cfUpdate', 'test'], - long_description="""\ - Python ChannelFinder Client Lib - """, - license='GPL', - install_requires=[ - 'requests', - ], - ) + long_description="""\ + Python ChannelFinder Client Lib + """, + license='GPL', + install_requires=requirements, +) diff --git a/test/_testConf.py b/test/_testConf.py index 4424e1e..acb28b0 100644 --- a/test/_testConf.py +++ b/test/_testConf.py @@ -11,11 +11,19 @@ username=MyUserName password=MyPassword """ +import os.path + +import sys +if sys.version_info[0] < 3: + # Python 2 code in this block + from ConfigParser import SafeConfigParser as ConfigParser +else: + # Python 3 code in this block + from configparser import ConfigParser + def __loadConfig(): - import os.path - import ConfigParser - dflt={'BaseURL':'https://localhost:8181/ChannelFinder', + dflt={'BaseURL':'https://barkeria-vm:8181/ChannelFinder', 'username' : 'cf-update', 'password' : '1234', 'owner' : 'cf-update', @@ -29,11 +37,12 @@ def __loadConfig(): 'tagUsername' : 'tag', 'tagPassword' : '1234' } - cf=ConfigParser.SafeConfigParser(defaults=dflt) + cf=ConfigParser(defaults=dflt) cf.read([ '/etc/channelfinderapi.conf', os.path.expanduser('~/channelfinderapi.conf'), 'channelfinderapi.conf' ]) return cf + _testConf=__loadConfig() \ No newline at end of file diff --git a/test/cf-property-manager-unittest.py b/test/testCFPpropertyManager.py similarity index 82% rename from test/cf-property-manager-unittest.py rename to test/testCFPpropertyManager.py index ad46d83..a770e03 100644 --- a/test/cf-property-manager-unittest.py +++ b/test/testCFPpropertyManager.py @@ -1,15 +1,22 @@ +from __future__ import print_function + import unittest from channelfinder.cfPropertyManager import CFPropertyManager import re import os + from _testConf import _testConf +import urllib3 +urllib3.disable_warnings() + + class CFPropertyManagerTest(unittest.TestCase): cfglines = [] def setUp(self): - print "\n---------------------------------------------------------------\n" + print("\n---------------------------------------------------------------\n") def test_run(self): ''' @@ -28,7 +35,7 @@ def test_dbl_read(self): CFPropertyManager.password=_testConf.get('DEFAULT', 'password') CFPropertyManager.startClient() fo = open("cf-property-manager-test-dbl", "w+") - fo.write("UT:RF-Cu:1{LD}Time:ShtDwn-I"); + fo.write("UT:RF-Cu:1{LD}Time:ShtDwn-I") fo.close() dbllines = CFPropertyManager.readDBL("cf-property-manager-test-dbl") for line in dbllines: @@ -44,13 +51,13 @@ def test_regex_error(self): fo.close() cfglines=cfglines = CFPropertyManager.readConfiguration("cf-property-manager-test-bad-cfg") for properties in cfglines: - print properties[0] + " = " + properties[1] + print(properties[0] + " = " + properties[1]) try: self.assertRaises(Exception, re.compile, properties[1]) except Exception as e: - print 'Invalid regular expression: ',properties[1] - print 'CAUSE:',e.message + print('Invalid regular expression: ',properties[1]) + print('CAUSE:',e.message) os.remove("cf-property-manager-test-bad-cfg") return cfglines @@ -60,19 +67,19 @@ def test_regex(self): Tests validity of regular expression. ''' fo = open("cf-property-manager-test-cfg", "w+") - fo.write("devName=[{][^:}][^:}]*\ndevType=[:][^{]*?[:}](?!.*[{])\nIGNORE=.*WtrSkid.*"); + fo.write("devName=[{][^:}][^:}]*\ndevType=[:][^{]*?[:}](?!.*[{])\nIGNORE=.*WtrSkid.*") fo.close() cfglines = CFPropertyManager.readConfiguration("cf-property-manager-test-cfg") for properties in cfglines: expression=None - print properties[0] + " = " + properties[1] + print(properties[0] + " = " + properties[1]) try: expression = re.compile(properties[1]) self.assertTrue(expression!=None) except Exception as e: - print 'Invalid regular expression: ',properties[1] - print 'CAUSE:',e.message + print('Invalid regular expression: ',properties[1]) + print('CAUSE:',e.message) return cfglines def test_cfg_read(self): @@ -85,7 +92,7 @@ def test_cfg_read(self): CFPropertyManager.password=_testConf.get('DEFAULT', 'password') CFPropertyManager.startClient() fo = open("cf-property-manager-test-cfg", "w+") - fo.write("devName=[{][^:}][^:}]*\ndevType=[:][^{]*?[:}](?!.*[{])\nIGNORE=.*WtrSkid.*"); + fo.write("devName=[{][^:}][^:}]*\ndevType=[:][^{]*?[:}](?!.*[{])\nIGNORE=.*WtrSkid.*") fo.close() cfglines = CFPropertyManager.readConfiguration("cf-property-manager-test-cfg") for line in cfglines: @@ -94,4 +101,4 @@ def test_cfg_read(self): if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/test/CFUpdateIOCTest.py b/test/testCFUpdateIOC.py similarity index 99% rename from test/CFUpdateIOCTest.py rename to test/testCFUpdateIOC.py index 124ab10..13b8ce2 100644 --- a/test/CFUpdateIOCTest.py +++ b/test/testCFUpdateIOC.py @@ -9,14 +9,18 @@ import unittest import os from channelfinder import ChannelFinderClient -from _testConf import _testConf from channelfinder.cfUpdate.CFUpdateIOC import getPVNames, getArgsFromFilename, updateChannelFinder, ifNoneReturnDefault from time import time from tempfile import NamedTemporaryFile from copy import copy +from _testConf import _testConf + +import urllib3 +urllib3.disable_warnings() + + class Test(unittest.TestCase): - def setUp(self): if _testConf.has_option('DEFAULT', 'BaseURL'): self.baseURL = _testConf.get('DEFAULT', 'BaseURL') @@ -118,7 +122,7 @@ def testAddUpdateChannelsWithProperties(self): hostName1 = 'update-test-hostname' + t1 iocName1 = 'update-test-iocName' + t1 # New Channels added - client = ChannelFinderClient(BaseURL=self.baseURL, username=self.username, password=self.password); + client = ChannelFinderClient(BaseURL=self.baseURL, username=self.username, password=self.password) client.set(channel={u'name':u'cf-update-pv1', u'owner':u'cf-update', u'properties':[unaffectedProperty]}) updateChannelFinder(['cf-update-pv1', 'cf-update-pv2'], \ hostName1, \ @@ -391,11 +395,11 @@ def testRegularExperssion(self): tempFile = NamedTemporaryFile(delete=False) publicPVs = ['publicPV1', 'publicPV2', 'publicPV3'] privatePVS = ['_privatePV1', '_privatePV2'] - allPVs = copy(publicPVs); + allPVs = copy(publicPVs) allPVs.extend(privatePVS) for pv in allPVs: - tempFile.write(pv + '\n') - tempFile.close(); + tempFile.write(str.encode(pv + '\n')) + tempFile.close() try: pvNames = getPVNames(tempFile.name) self.assertEqual(len(pvNames), len(allPVs), \ diff --git a/test/ChannelFinderClientTest.py b/test/testChannelFinderClient.py similarity index 66% rename from test/ChannelFinderClientTest.py rename to test/testChannelFinderClient.py index 2d993fe..a1a6680 100644 --- a/test/ChannelFinderClientTest.py +++ b/test/testChannelFinderClient.py @@ -1,35 +1,39 @@ -''' +""" Copyright (c) 2010 Brookhaven National Laboratory All rights reserved. Use is subject to license terms and conditions. Created on Feb 15, 2011 @author: shroffk -''' +""" + import unittest from channelfinder import ChannelFinderClient -#from channelfinder import Channel, Property, Tag from channelfinder.util import ChannelUtil -from collections import Counter from _testConf import _testConf -#=============================================================================== -# -#=============================================================================== -class ConnectionTest(unittest.TestCase): +import urllib3 + +urllib3.disable_warnings() + + +class ConnectionTest(unittest.TestCase): def testConnection(self): - testUrl = getDefaultTestConfig("BaseURL") - self.assertNotEqual(ChannelFinderClient(BaseURL=testUrl, username=getDefaultTestConfig('username'), password=getDefaultTestConfig('password')), None, 'failed to create client') + self.assertNotEqual(ChannelFinderClient(BaseURL=testUrl, + username=getDefaultTestConfig('username'), + password=getDefaultTestConfig('password')), + None, 'failed to create client') badBaseurl = ['', 'noSuchURL'] for url in badBaseurl: self.assertRaises(Exception, ChannelFinderClient, BaseURL=url, msg='message') - -#=============================================================================== + + +# =============================================================================== # Test JSON Parsing -#=============================================================================== -''' +# =============================================================================== +""" class JSONparserTest(unittest.TestCase): multiChannels = {u'channels': {u'channel': [{u'@owner': u'shroffk', u'@name': u'Test_first:a<000>:0:0', u'properties': {u'property': [{u'@owner': u'shroffk', u'@name': u'Test_PropA', u'@value': u'0'}, {u'@owner': u'shroffk', u'@name': u'Test_PropB', u'@value': u'19'}, {u'@owner': u'shroffk', u'@name': u'Test_PropC', u'@value': u'ALL'}]}, u'tags': {u'tag': [{u'@owner': u'shroffk', u'@name': u'Test_TagA'}, {u'@owner': u'shroffk', u'@name': u'Test_TagB'}]}}, {u'@owner': u'shroffk', u'@name': u'Test_first:a<000>:0:1', u'properties': {u'property': [{u'@owner': u'shroffk', u'@name': u'Test_PropA', u'@value': u'1'}, {u'@owner': u'shroffk', u'@name': u'Test_PropB', u'@value': u'22'}, {u'@owner': u'shroffk', u'@name': u'Test_PropC', u'@value': u'ALL'}]}, u'tags': {u'tag': [{u'@owner': u'shroffk', u'@name': u'Test_TagA'}, {u'@owner': u'shroffk', u'@name': u'Test_TagB'}]}}, {u'@owner': u'shroffk', u'@name': u'Test_first:a<000>:0:2', u'properties': {u'property': [{u'@owner': u'shroffk', u'@name': u'Test_PropA', u'@value': u'2'}, {u'@owner': u'shroffk', u'@name': u'Test_PropB', u'@value': u'38'}, {u'@owner': u'shroffk', u'@name': u'Test_PropC', u'@value': u'ALL'}]}, u'tags': {u'tag': [{u'@owner': u'shroffk', u'@name': u'Test_TagA'}, {u'@owner': u'shroffk', u'@name': u'Test_TagB'}]}}, {u'@owner': u'shroffk', u'@name': u'Test_first:a<000>:0:3', u'properties': {u'property': [{u'@owner': u'shroffk', u'@name': u'Test_PropA', u'@value': u'3'}, {u'@owner': u'shroffk', u'@name': u'Test_PropB', u'@value': u'65'}, {u'@owner': u'shroffk', u'@name': u'Test_PropC', u'@value': u'ALL'}]}, u'tags': {u'tag': [{u'@owner': u'shroffk', u'@name': u'Test_TagA'}, {u'@owner': u'shroffk', u'@name': u'Test_TagB'}]}}, {u'@owner': u'shroffk', u'@name': u'Test_first:a<000>:0:4', u'properties': {u'property': [{u'@owner': u'shroffk', u'@name': u'Test_PropA', u'@value': u'4'}, {u'@owner': u'shroffk', u'@name': u'Test_PropB', u'@value': u'78'}, {u'@owner': u'shroffk', u'@name': u'Test_PropC', u'@value': u'ALL'}]}, u'tags': {u'tag': [{u'@owner': u'shroffk', u'@name': u'Test_TagA'}, {u'@owner': u'shroffk', u'@name': u'Test_TagB'}]}}, {u'@owner': u'shroffk', u'@name': u'Test_first:a<000>:0:5', u'properties': {u'property': [{u'@owner': u'shroffk', u'@name': u'Test_PropA', u'@value': u'5'}, {u'@owner': u'shroffk', u'@name': u'Test_PropB', u'@value': u'79'}, {u'@owner': u'shroffk', u'@name': u'Test_PropC', u'@value': u'ALL'}]}, u'tags': {u'tag': [{u'@owner': u'shroffk', u'@name': u'Test_TagA'}, {u'@owner': u'shroffk', u'@name': u'Test_TagB'}]}}, {u'@owner': u'shroffk', u'@name': u'Test_first:a<000>:0:6', u'properties': {u'property': [{u'@owner': u'shroffk', u'@name': u'Test_PropA', u'@value': u'6'}, {u'@owner': u'shroffk', u'@name': u'Test_PropB', u'@value': u'90'}, {u'@owner': u'shroffk', u'@name': u'Test_PropC', u'@value': u'ALL'}]}, u'tags': {u'tag': [{u'@owner': u'shroffk', u'@name': u'Test_TagA'}, {u'@owner': u'shroffk', u'@name': u'Test_TagB'}]}}, {u'@owner': u'shroffk', u'@name': u'Test_first:a<000>:0:7', u'properties': {u'property': [{u'@owner': u'shroffk', u'@name': u'Test_PropA', u'@value': u'7'}, {u'@owner': u'shroffk', u'@name': u'Test_PropB', u'@value': u'5'}, {u'@owner': u'shroffk', u'@name': u'Test_PropC', u'@value': u'ALL'}]}, u'tags': {u'tag': [{u'@owner': u'shroffk', u'@name': u'Test_TagA'}, {u'@owner': u'shroffk', u'@name': u'Test_TagB'}]}}, {u'@owner': u'shroffk', u'@name': u'Test_first:a<000>:0:8', u'properties': {u'property': [{u'@owner': u'shroffk', u'@name': u'Test_PropA', u'@value': u'8'}, {u'@owner': u'shroffk', u'@name': u'Test_PropB', u'@value': u'64'}, {u'@owner': u'shroffk', u'@name': u'Test_PropC', u'@value': u'ALL'}]}, u'tags': {u'tag': [{u'@owner': u'shroffk', u'@name': u'Test_TagA'}, {u'@owner': u'shroffk', u'@name': u'Test_TagB'}]}}, {u'@owner': u'shroffk', u'@name': u'Test_first:a<000>:0:9', u'properties': {u'property': [{u'@owner': u'shroffk', u'@name': u'Test_PropA', u'@value': u'9'}, {u'@owner': u'shroffk', u'@name': u'Test_PropB', u'@value': u'85'}, {u'@owner': u'shroffk', u'@name': u'Test_PropC', u'@value': u'ALL'}]}, u'tags': {u'tag': [{u'@owner': u'shroffk', u'@name': u'Test_TagA'}, {u'@owner': u'shroffk', u'@name': u'Test_TagB'}]}}]}} @@ -68,54 +72,52 @@ def testChannel(self): def testEncodeChannel(self): encodedChannel = ChannelFinderClient()._ChannelFinderClient__encodeChannels(\ - [{u'name':u'Test_first:a<000>:0:0', u'owner':u'shroffk', \ - u'properties':[{u'name':u'Test_PropA', u'owner':u'shroffk', u'value':u'0'}, \ - {u'name':u'Test_PropB', u'owner':u'shroffk', u'value':u'19'}, \ - {u'name':u'Test_PropC', u'owner':u'shroffk', u'value':u'ALL'}], \ - u'tags':[{u'name':u'Test_TagA', u'owner':u'shroffk'}, \ + [{u'name':u'Test_first:a<000>:0:0', u'owner':u'shroffk', + u'properties':[{u'name':u'Test_PropA', u'owner':u'shroffk', u'value':u'0'}, + {u'name':u'Test_PropB', u'owner':u'shroffk', u'value':u'19'}, + {u'name':u'Test_PropC', u'owner':u'shroffk', u'value':u'ALL'}], + u'tags':[{u'name':u'Test_TagA', u'owner':u'shroffk'}, {u'name':u'Test_TagB', u'owner':u'shroffk'}]}]) # print encodedChannel[u'channels'][u'channel'] print "TEST "+ str(encodedChannel[u'channels'][u'channel']) + " == " + str(self.channel) self.assertTrue(encodedChannel[u'channels'][u'channel'] == self.channel) def testEncodeChannels(self): - self.assertTrue(self.multiChannels == \ + self.assertTrue(self.multiChannels == ChannelFinderClient()._ChannelFinderClient__encodeChannels(ChannelFinderClient()._ChannelFinderClient__decodeChannels(self.multiChannels))) -''' +""" -#=============================================================================== + +# =============================================================================== # Test all the tag operations -#=============================================================================== +# =============================================================================== class OperationTagTest(unittest.TestCase): - def setUp(self): - '''Default Owners''' + """Default Owners""" self.channelOwner = _testConf.get('DEFAULT', 'channelOwner') self.tagOwner = _testConf.get('DEFAULT', 'tagOwner') - '''Default Clients''' - self.client = ChannelFinderClient(BaseURL=_testConf.get('DEFAULT', 'BaseURL'), \ - username=_testConf.get('DEFAULT', 'username'), \ + """Default Clients""" + self.client = ChannelFinderClient(BaseURL=_testConf.get('DEFAULT', 'BaseURL'), + username=_testConf.get('DEFAULT', 'username'), password=_testConf.get('DEFAULT', 'password')) - self.clientTag = ChannelFinderClient(BaseURL=_testConf.get('DEFAULT', 'BaseURL'), \ - username=_testConf.get('DEFAULT', 'tagUsername'), \ - password=_testConf.get('DEFAULT', 'tagPassword')) - self.testChannels = [{u'name':u'pyTestChannel1', u'owner':self.channelOwner}, \ - {u'name':u'pyTestChannel2', u'owner':self.channelOwner}, \ - {u'name':u'pyTestChannel3', u'owner':self.channelOwner}] + self.clientTag = ChannelFinderClient(BaseURL=_testConf.get('DEFAULT', 'BaseURL'), + username=_testConf.get('DEFAULT', 'tagUsername'), + password=_testConf.get('DEFAULT', 'tagPassword')) + self.testChannels = [{u'name': u'pyTestChannel1', u'owner': self.channelOwner}, + {u'name': u'pyTestChannel2', u'owner': self.channelOwner}, + {u'name': u'pyTestChannel3', u'owner': self.channelOwner}] self.client.set(channels=self.testChannels) - self.assertTrue(len(self.client.find(name=u'pyTestChannel*')) == 3, \ + self.assertTrue(len(self.client.find(name=u'pyTestChannel*')) == 3, 'Error: Failed to set channel') - pass def tearDown(self): for ch in self.testChannels: self.client.delete(channelName=ch[u'name']) - pass def testCreateAndDeleteTag(self): - testTag = {'name':'setTestTag', 'owner':self.tagOwner} + testTag = {'name': 'setTestTag', 'owner': self.tagOwner} try: - result = self.clientTag.set(tag=testTag) + self.clientTag.set(tag=testTag) foundtag = self.client.findTag(testTag['name']) self.assertIsNotNone(foundtag, 'failed to create a test tag') self.assertTrue(checkTagInList([foundtag], [testTag]), 'tag not created correctly') @@ -125,14 +127,14 @@ def testCreateAndDeleteTag(self): self.assertIsNone(foundtag, 'failed to delete the test tag') def testCreateAndDeleteTagWithChannel(self): - testTag = {'name':'setTestTag', 'owner':self.tagOwner, 'channels':[self.testChannels[0]]} + testTag = {'name': 'setTestTag', 'owner': self.tagOwner, 'channels': [self.testChannels[0]]} try: result = self.clientTag.set(tag=testTag) foundtag = self.client.findTag(testTag['name']) self.assertIsNotNone(foundtag, 'failed to create a test tag') self.assertTrue(checkTagInList([foundtag], [testTag]), 'tag not created correctly') - '''check the created tag was added to the channel''' - self.assertTrue(checkTagOnChannel(self.client, self.testChannels[0]['name'], foundtag), \ + """check the created tag was added to the channel""" + self.assertTrue(checkTagOnChannel(self.client, self.testChannels[0]['name'], foundtag), 'Failed to correctly set the created tag to the appropriate channel') finally: self.clientTag.delete(tagName=testTag['name']) @@ -140,130 +142,125 @@ def testCreateAndDeleteTagWithChannel(self): self.assertIsNone(foundtag, 'failed to delete the test tag') def testCreateAndDeleteTags(self): - testTags = [] - testTags.append({u'name':u'pyTag1', u'owner':self.tagOwner}) - testTags.append({u'name':u'pyTag2', u'owner':self.tagOwner}) - testTags.append({u'name':u'pyTag3', u'owner':self.tagOwner}) + testTags = [{u'name': u'pyTag1', u'owner': self.tagOwner}, + {u'name': u'pyTag2', u'owner': self.tagOwner}, + {u'name': u'pyTag3', u'owner': self.tagOwner}] try: self.clientTag.set(tags=testTags) - '''Check if all the tags were correctly Added ''' + """Check if all the tags were correctly Added """ for tag in testTags: - self.assertTrue(self.client.findTag(tagName=tag[u'name']), \ + self.assertTrue(self.client.findTag(tagname=tag[u'name']), 'Error: tag ' + tag[u'name'] + ' was not added') finally: - '''delete the Tags ''' + """delete the Tags """ for tag in testTags: self.clientTag.delete(tagName=tag[u'name']) - '''Check all the tags were correctly removed ''' + """Check all the tags were correctly removed """ for tag in testTags: - self.assertEqual(self.client.findTag(tagName='pyTag1'), None, \ + self.assertEqual(self.client.findTag(tagname='pyTag1'), None, 'Error: tag ' + tag[u'name'] + ' was not removed') def testSetRemoveTag2Channel(self): - ''' + """ Set Tag to channel removing it from all other channels for non destructive operation check TestUpdateAppend - ''' - testTag = {u'name':u'pySetTag', u'owner':self.tagOwner} + """ + testTag = {u'name': u'pySetTag', u'owner': self.tagOwner} try: self.client.set(tag=testTag) self.client.set(tag=testTag, channelName=self.testChannels[0][u'name']) - self.assertTrue(checkTagOnChannel(self.client, 'pyTestChannel1', testTag) , \ + self.assertTrue(checkTagOnChannel(self.client, 'pyTestChannel1', testTag), 'Error: Tag-pySetTag not added to the channel-pyTestChannel1') self.client.set(tag=testTag, channelName=self.testChannels[1][u'name']) # check if the tag has been added to the new channel and removed from the old channel self.assertTrue(checkTagOnChannel(self.client, self.testChannels[1][u'name'], testTag) and - not checkTagOnChannel(self.client, self.testChannels[0][u'name'], testTag), \ + not checkTagOnChannel(self.client, self.testChannels[0][u'name'], testTag), 'Error: Tag-pySetTag not added to the channel-pyTestChannel2') self.client.delete(tag=testTag, channelName=self.testChannels[1][u'name']) - self.assertTrue(not checkTagOnChannel(self.client, self.testChannels[1][u'name'], testTag), \ - 'Error: Failed to delete the tag-pySetTag from channel-pyTestChannel1') + self.assertTrue(not checkTagOnChannel(self.client, self.testChannels[1][u'name'], testTag), + 'Error: Failed to delete the tag-pySetTag from channel-pyTestChannel1') finally: self.client.delete(tagName=testTag[u'name']) # TODO set a check for removing the tag from a subset of channels which have that tag def testSetRemoveTag2Channels(self): - ''' + """ Set tags to a set of channels and remove it from all other channels - ''' - testTag = {u'name':u'pySetTag', u'owner':self.tagOwner} + """ + testTag = {u'name': u'pySetTag', u'owner': self.tagOwner} # the list comprehension is used to construct a list of all the channel names channelNames = [channel[u'name'] for channel in self.testChannels] try: self.client.set(tag=testTag, channelNames=channelNames) responseChannelNames = [channel[u'name'] for channel in self.client.find(tagName=testTag[u'name'])] - for ch in channelNames : + for ch in channelNames: self.assertTrue(ch in responseChannelNames, 'Error: tag-pySetTag not added to channel ' + ch) self.client.delete(tag=testTag, channelNames=channelNames) response = self.client.find(tagName=testTag[u'name']) if response: responseChannelNames = [channel[u'name'] for channel in response] - for ch in channelNames : + for ch in channelNames: self.assertFalse(ch in responseChannelNames, 'Error: tag-pySetTag not removed from channel ' + ch) finally: self.client.delete(tagName=testTag[u'name']) def testUpdateTag(self): - ''' + """ Add a tag to a group of channels without removing it from existing channels - ''' - tag = {'name':'initialTestTag', 'owner':self.tagOwner} - tag['channels'] = [self.testChannels[0]] + """ + tag = {'name': 'initialTestTag', 'owner': self.tagOwner, 'channels': [self.testChannels[0]]} try: - '''Create initial tag''' + """Create initial tag""" self.clientTag.set(tag=tag) self.assertIsNotNone(self.client.findTag(tag['name']), 'failed to create a test tag') - '''Update tag with new channels''' + """Update tag with new channels""" tag['channels'] = [self.testChannels[1], self.testChannels[2]] self.clientTag.update(tag=tag) for channel in self.testChannels: self.assertTrue(checkTagOnChannel(self.client, channel['name'], tag), 'Failed to updated tag') finally: - '''cleanup''' + """cleanup""" self.client.delete(tagName=tag['name']) - self.assertIsNone(self.client.findTag(tag['name']), 'failed to delete the test tag:'+tag['name']) + self.assertIsNone(self.client.findTag(tag['name']), 'failed to delete the test tag:' + tag['name']) def testUpdateTags(self): - ''' + """ Add tags to a group of channels without removing it from existing channels - ''' - tag1 = {'name':'pyTestTag1', 'owner':self.tagOwner} - tag1['channels'] = [self.testChannels[0]] - tag2 = {'name':'pyTestTag2', 'owner':self.tagOwner} - tag2['channels'] = [self.testChannels[0]] + """ + tag1 = {'name': 'pyTestTag1', 'owner': self.tagOwner, 'channels': [self.testChannels[0]]} + tag2 = {'name': 'pyTestTag2', 'owner': self.tagOwner, 'channels': [self.testChannels[0]]} try: - '''Create initial tags which are set on the pyTestChannel1''' - self.clientTag.set(tags=[tag1,tag2]) + """Create initial tags which are set on the pyTestChannel1""" + self.clientTag.set(tags=[tag1, tag2]) self.assertIsNotNone(self.client.findTag(tag1['name']), 'failed to create a test tag: pyTestTag1') self.assertIsNotNone(self.client.findTag(tag1['name']), 'failed to create a test tag: pyTestTag2') - '''Update tags with new channels''' + """Update tags with new channels""" tag1['channels'] = [self.testChannels[1], self.testChannels[2]] tag2['channels'] = [self.testChannels[1], self.testChannels[2]] - self.clientTag.update(tags = [tag1, tag2]) - '''Check that the all channels have been updated with the tags''' + self.clientTag.update(tags=[tag1, tag2]) + """Check that the all channels have been updated with the tags""" for channel in self.testChannels: - self.assertTrue(checkTagOnChannel(self.client, channel['name'], tag1) and \ - checkTagOnChannel(self.client, channel['name'], tag2), \ + self.assertTrue(checkTagOnChannel(self.client, channel['name'], tag1) and + checkTagOnChannel(self.client, channel['name'], tag2), 'Failed to updated tags') finally: - '''cleanup''' + """cleanup""" self.client.delete(tagName=tag1['name']) self.client.delete(tagName=tag2['name']) - self.assertIsNone(self.client.findTag(tag1['name']), 'failed to delete the test tag:'+tag1['name']) - self.assertIsNone(self.client.findTag(tag2['name']), 'failed to delete the test tag:'+tag2['name']) + self.assertIsNone(self.client.findTag(tag1['name']), 'failed to delete the test tag:' + tag1['name']) + self.assertIsNone(self.client.findTag(tag2['name']), 'failed to delete the test tag:' + tag2['name']) def testGetAllTags(self): - '''Test setting multiple tags and listing all tags''' - testTags = [] - testTags.append({'name':'testTag1', 'owner':self.tagOwner}) - testTags.append({'name':'testTag2', 'owner':self.tagOwner}) - testTags.append({'name':'testTag3', 'owner':self.tagOwner}) + """Test setting multiple tags and listing all tags""" + testTags = [{'name': 'testTag1', 'owner': self.tagOwner}, + {'name': 'testTag2', 'owner': self.tagOwner}, + {'name': 'testTag3', 'owner': self.tagOwner}] try: self.client.set(tags=testTags) allTags = self.client.getAllTags() @@ -274,31 +271,31 @@ def testGetAllTags(self): self.client.delete(tagName=tag['name']) # Check all the tags were correctly removed for tag in testTags: - self.assertEqual(self.client.findTag(tagName=tag[u'name']), None, \ + self.assertEqual(self.client.findTag(tagname=tag[u'name']), None, 'Error: property ' + tag[u'name'] + ' was not removed') -#=============================================================================== + +# =============================================================================== # Test all the property operations -#=============================================================================== +# =============================================================================== class OperationPropertyTest(unittest.TestCase): - def setUp(self): - '''Default Owners''' + """Default Owners""" self.channelOwner = _testConf.get('DEFAULT', 'channelOwner') self.propOwner = _testConf.get('DEFAULT', 'propOwner') - '''Default Clients''' - self.client = ChannelFinderClient(BaseURL=_testConf.get('DEFAULT', 'BaseURL'), \ - username=_testConf.get('DEFAULT', 'username'), \ + """Default Clients""" + self.client = ChannelFinderClient(BaseURL=_testConf.get('DEFAULT', 'BaseURL'), + username=_testConf.get('DEFAULT', 'username'), password=_testConf.get('DEFAULT', 'password')) - self.clientProp = ChannelFinderClient(BaseURL=_testConf.get('DEFAULT', 'BaseURL'), \ - username=_testConf.get('DEFAULT', 'propUsername'), \ - password=_testConf.get('DEFAULT', 'propPassword')) - self.testChannels = [{u'name':u'pyTestChannel1', u'owner':self.channelOwner}, \ - {u'name':u'pyTestChannel2', u'owner':self.channelOwner}, \ - {u'name':u'pyTestChannel3', u'owner':self.channelOwner}] + self.clientProp = ChannelFinderClient(BaseURL=_testConf.get('DEFAULT', 'BaseURL'), + username=_testConf.get('DEFAULT', 'propUsername'), + password=_testConf.get('DEFAULT', 'propPassword')) + self.testChannels = [{u'name': u'pyTestChannel1', u'owner': self.channelOwner}, + {u'name': u'pyTestChannel2', u'owner': self.channelOwner}, + {u'name': u'pyTestChannel3', u'owner': self.channelOwner}] self.client.set(channels=self.testChannels) - self.assertTrue(len(self.client.find(name=u'pyTestChannel*')) == 3, \ + self.assertTrue(len(self.client.find(name=u'pyTestChannel*')) == 3, 'Error: Failed to set channel') pass @@ -308,10 +305,10 @@ def tearDown(self): pass def testCreateAndDeleteProperty(self): - ''' + """ Create and delete a single property - ''' - testProperty = {'name':'setTestProp', 'owner':self.propOwner} + """ + testProperty = {'name': 'setTestProp', 'owner': self.propOwner} try: result = self.clientProp.set(property=testProperty) foundProperty = self.client.findProperty(testProperty['name']) @@ -323,19 +320,19 @@ def testCreateAndDeleteProperty(self): self.assertIsNone(foundProperty, 'failed to delete the test property') def testCreateAndDeletePropertyWithChannel(self): - ''' + """ Create and delete a single property - ''' + """ ch = self.testChannels[0] - ch['properties'] = [ {'name':'setTestProp', 'owner':self.propOwner, 'value':'testValue1'} ] - testProperty = {'name':'setTestProp', 'owner':self.propOwner, 'channels':[ch]} + ch['properties'] = [{'name': 'setTestProp', 'owner': self.propOwner, 'value': 'testValue1'}] + testProperty = {'name': 'setTestProp', 'owner': self.propOwner, 'channels': [ch]} try: result = self.clientProp.set(property=testProperty) foundProperty = self.client.findProperty(testProperty['name']) self.assertIsNotNone(foundProperty, 'failed to create a test property') self.assertTrue(checkPropInList([foundProperty], [testProperty]), 'property not created correctly') - '''check the created property was added to the channel''' - self.assertTrue(checkPropertyOnChannel(self.client, self.testChannels[0]['name'], foundProperty), \ + """check the created property was added to the channel""" + self.assertTrue(checkPropertyOnChannel(self.client, self.testChannels[0]['name'], foundProperty), 'Failed to correctly set the created property to the appropriate channel') finally: self.client.delete(propertyName=testProperty['name']) @@ -343,23 +340,23 @@ def testCreateAndDeletePropertyWithChannel(self): self.assertIsNone(foundProperty, 'failed to delete the test property') def testCreateAndDeletePropertyWithChannels(self): - ''' + """ Create and delete a single property - ''' + """ ch1 = self.testChannels[0] - ch1['properties'] = [ {'name':'setTestProp', 'owner':self.propOwner, 'value':'testValue1'} ] + ch1['properties'] = [{'name': 'setTestProp', 'owner': self.propOwner, 'value': 'testValue1'}] ch2 = self.testChannels[1] - ch2['properties'] = [ {'name':'setTestProp', 'owner':self.propOwner, 'value':'testValue2'} ] - testProperty = {'name':'setTestProp', 'owner':self.propOwner, 'channels':[ch1, ch2]} + ch2['properties'] = [{'name': 'setTestProp', 'owner': self.propOwner, 'value': 'testValue2'}] + testProperty = {'name': 'setTestProp', 'owner': self.propOwner, 'channels': [ch1, ch2]} try: - result = self.clientProp.set(property=testProperty) + self.clientProp.set(property=testProperty) foundProperty = self.client.findProperty(testProperty['name']) self.assertIsNotNone(foundProperty, 'failed to create a test property') self.assertTrue(checkPropInList([foundProperty], [testProperty]), 'property not created correctly') - '''check the created property was added to the channel''' - self.assertTrue(checkPropertyOnChannel(self.client, self.testChannels[0]['name'], foundProperty), \ + """check the created property was added to the channel""" + self.assertTrue(checkPropertyOnChannel(self.client, self.testChannels[0]['name'], foundProperty), 'Failed to correctly set the created property to the appropriate channel') - self.assertTrue(checkPropertyOnChannel(self.client, self.testChannels[1]['name'], foundProperty), \ + self.assertTrue(checkPropertyOnChannel(self.client, self.testChannels[1]['name'], foundProperty), 'Failed to correctly set the created property to the appropriate channel') finally: self.client.delete(propertyName=testProperty['name']) @@ -367,14 +364,15 @@ def testCreateAndDeletePropertyWithChannels(self): self.assertIsNone(foundProperty, 'failed to delete the test property') def testCreateAndDeleteProperties(self): - ''' + """ Create and delete a set of properties - ''' - testProperty1 = {'name':'pyTestProp1', 'owner':self.propOwner} - testProperty2 = {'name':'pyTestProp2', 'owner':self.propOwner} + """ + testProperty1 = {'name': 'pyTestProp1', 'owner': self.propOwner} + testProperty2 = {'name': 'pyTestProp2', 'owner': self.propOwner} try: - result = self.clientProp.set(properties=[testProperty1, testProperty2]) - self.assertTrue(checkPropInList(self.clientProp.getAllProperties(), [testProperty1, testProperty2]), 'property not created correctly') + self.clientProp.set(properties=[testProperty1, testProperty2]) + self.assertTrue(checkPropInList(self.clientProp.getAllProperties(), [testProperty1, testProperty2]), + 'property not created correctly') finally: self.client.delete(propertyName=testProperty1['name']) self.client.delete(propertyName=testProperty2['name']) @@ -382,41 +380,40 @@ def testCreateAndDeleteProperties(self): self.assertIsNone(self.client.findProperty(testProperty2['name']), 'failed to delete the test property1') def testSetRemoveProperty2Channel(self): - ''' + """ Set Property to channel removing it from all other channels for non destructive operation check TestUpdateAppend - ''' - testProperty = {'name':'setTestProp', 'owner':self.propOwner} + """ + testProperty = {'name': 'setTestProp', 'owner': self.propOwner} try: - result = self.clientProp.set(property=testProperty) + self.clientProp.set(property=testProperty) ch0 = self.testChannels[0] - ch0['properties'] = [ {'name':'setTestProp', 'owner':self.propOwner, 'value':'testValue1'} ] + ch0['properties'] = [{'name': 'setTestProp', 'owner': self.propOwner, 'value': 'testValue1'}] testProperty['channels'] = [ch0] self.client.set(property=testProperty) - self.assertTrue(checkPropertyOnChannel(self.client, ch0[u'name'], testProperty) , \ + self.assertTrue(checkPropertyOnChannel(self.client, ch0[u'name'], testProperty), 'Error: Property - setTestProp not added to the channel-pyTestChannel1') ch1 = self.testChannels[1] - ch1['properties'] = [ {'name':'setTestProp', 'owner':self.propOwner, 'value':'testValue2'} ] + ch1['properties'] = [{'name': 'setTestProp', 'owner': self.propOwner, 'value': 'testValue2'}] testProperty['channels'] = [ch1] self.client.set(property=testProperty) - '''check if the property has been added to the new channel and removed from the old channel''' + """check if the property has been added to the new channel and removed from the old channel""" self.assertTrue(checkPropertyOnChannel(self.client, ch1[u'name'], testProperty) and - not checkPropertyOnChannel(self.client, ch0[u'name'], testProperty), \ + not checkPropertyOnChannel(self.client, ch0[u'name'], testProperty), 'Error: Tag-pySetTag not added to the channel-pyTestChannel2') finally: # Delete operation causes an error if performed twice, IE: the first delete succeeded - '''delete the property and ensure it is removed from the associated channel''' + """delete the property and ensure it is removed from the associated channel""" self.client.delete(propertyName=testProperty[u'name']) - self.assertTrue(not checkPropertyOnChannel(self.client, ch0[u'name'], testProperty) and \ - not checkPropertyOnChannel(self.client, ch1[u'name'], testProperty), \ + self.assertTrue(not checkPropertyOnChannel(self.client, ch0[u'name'], testProperty) and + not checkPropertyOnChannel(self.client, ch1[u'name'], testProperty), 'Error: Failed to delete the tag-pySetTag from channel-pyTestChannel1') def testGetAllPropperties(self): - '''Test setting multiple properties and listing all tags''' - testProps = [] - testProps.append({u'name':u'pyTestProp1', u'owner':self.propOwner}) - testProps.append({u'name':u'pyTestProp2', u'owner':self.propOwner}) - testProps.append({u'name':u'pyTestProp3', u'owner':self.propOwner}) + """Test setting multiple properties and listing all tags""" + testProps = [{u'name': u'pyTestProp1', u'owner': self.propOwner}, + {u'name': u'pyTestProp2', u'owner': self.propOwner}, + {u'name': u'pyTestProp3', u'owner': self.propOwner}] try: self.client.set(properties=testProps) allProperties = self.client.getAllProperties() @@ -427,38 +424,39 @@ def testGetAllPropperties(self): self.client.delete(propertyName=prop[u'name']) # Check all the tags were correctly removed for prop in testProps: - self.assertEqual(self.client.findProperty(propertyName=prop[u'name']), None, \ + self.assertEqual(self.client.findProperty(propertyname=prop[u'name']), None, 'Error: property ' + prop[u'name'] + ' was not removed') -#=============================================================================== + + +# =============================================================================== # -#=============================================================================== +# =============================================================================== class OperationChannelTest(unittest.TestCase): - def setUp(self): - '''Default Owners''' + """Default Owners""" self.channelOwner = _testConf.get('DEFAULT', 'channelOwner') self.propOwner = _testConf.get('DEFAULT', 'propOwner') self.tagOwner = _testConf.get('DEFAULT', 'tagOwner') - '''Default Clients''' - self.client = ChannelFinderClient(BaseURL=_testConf.get('DEFAULT', 'BaseURL'), \ - username=_testConf.get('DEFAULT', 'username'), \ + """Default Clients""" + self.client = ChannelFinderClient(BaseURL=_testConf.get('DEFAULT', 'BaseURL'), + username=_testConf.get('DEFAULT', 'username'), password=_testConf.get('DEFAULT', 'password')) - self.clientCh = ChannelFinderClient(BaseURL=_testConf.get('DEFAULT', 'BaseURL'), \ - username=_testConf.get('DEFAULT', 'channelUsername'), \ - password=_testConf.get('DEFAULT', 'channelPassword')) - self.clientProp = ChannelFinderClient(BaseURL=_testConf.get('DEFAULT', 'BaseURL'), \ - username=_testConf.get('DEFAULT', 'propUsername'), \ - password=_testConf.get('DEFAULT', 'propPassword')) - self.clientTag = ChannelFinderClient(BaseURL=_testConf.get('DEFAULT', 'BaseURL'), \ - username=_testConf.get('DEFAULT', 'tagUsername'), \ - password=_testConf.get('DEFAULT', 'tagPassword')) + self.clientCh = ChannelFinderClient(BaseURL=_testConf.get('DEFAULT', 'BaseURL'), + username=_testConf.get('DEFAULT', 'channelUsername'), + password=_testConf.get('DEFAULT', 'channelPassword')) + self.clientProp = ChannelFinderClient(BaseURL=_testConf.get('DEFAULT', 'BaseURL'), + username=_testConf.get('DEFAULT', 'propUsername'), + password=_testConf.get('DEFAULT', 'propPassword')) + self.clientTag = ChannelFinderClient(BaseURL=_testConf.get('DEFAULT', 'BaseURL'), + username=_testConf.get('DEFAULT', 'tagUsername'), + password=_testConf.get('DEFAULT', 'tagPassword')) def testSetDeleteChannel(self): - ''' + """ Set and Delete a simple channel with no properties or tags - ''' + """ try: - testChannel = {u'name':u'pyTestChannelName', u'owner': self.channelOwner} + testChannel = {u'name': u'pyTestChannelName', u'owner': self.channelOwner} self.clientCh.set(channel=testChannel) result = self.client.find(name=u'pyTestChannelName') self.assertTrue(len(result) == 1, 'incorrect number of channels returned') @@ -469,23 +467,24 @@ def testSetDeleteChannel(self): self.assertFalse(result, 'incorrect number of channels returned') def testSetDeleteChannelWithPropertiesAndTags(self): - ''' + """ Set and Delete a simple channel with properties or tags - ''' + """ try: - testProp = {u'name':u'pyTestProp', u'owner':self.propOwner, u'value':u'testVal'} + testProp = {u'name': u'pyTestProp', u'owner': self.propOwner, u'value': u'testVal'} self.client.set(property=testProp) - testTag = {u'name':u'pyTestTag', u'owner':self.tagOwner} + testTag = {u'name': u'pyTestTag', u'owner': self.tagOwner} self.client.set(tag=testTag) - testChannel = {u'name':u'pyTestChannelName', u'owner': self.channelOwner, u'properties':[testProp], u'tags':[testTag]} + testChannel = {u'name': u'pyTestChannelName', u'owner': self.channelOwner, u'properties': [testProp], + u'tags': [testTag]} self.clientCh.set(channel=testChannel) result = self.client.find(name=u'pyTestChannelName') self.assertTrue(len(result) == 1, 'incorrect number of channels returned') self.assertTrue(result[0][u'name'] == u'pyTestChannelName', 'incorrect channel returned') finally: - '''Cleanup''' + """Cleanup""" self.clientCh.delete(channelName=testChannel[u'name']) self.client.delete(tagName=testTag[u'name']) self.client.delete(propertyName=testProp[u'name']) @@ -493,16 +492,16 @@ def testSetDeleteChannelWithPropertiesAndTags(self): self.assertFalse(result, 'incorrect number of channels returned') def testSetRemoveChannels(self): - ''' + """ Test Set and Delete on a list of channels with no propties or tags - ''' - testChannels = [{u'name' : u'pyTestChannel1', u'owner' : self.channelOwner}, \ - {u'name' : u'pyTestChannel2', u'owner' : self.channelOwner}, \ - {u'name' : u'pyTestChannel3', u'owner' : self.channelOwner}] + """ + testChannels = [{u'name': u'pyTestChannel1', u'owner': self.channelOwner}, + {u'name': u'pyTestChannel2', u'owner': self.channelOwner}, + {u'name': u'pyTestChannel3', u'owner': self.channelOwner}] try: self.clientCh.set(channels=testChannels) r = self.client.find(name='pyTestChannel*') - self.assertTrue(len(r) == 3, \ + self.assertTrue(len(r) == 3, 'ERROR: # of channels returned expected ' + str(len(r)) + ' expected 3') finally: # delete each individually @@ -510,31 +509,31 @@ def testSetRemoveChannels(self): self.clientCh.delete(channelName=str(ch[u'name'])) def testSetChannelsWithProperties(self): - ''' + """ This method creates a set of channels and then updates the property values using the set method with the channels parameter. - ''' - prop1 = {u'name':u'originalProp1', u'owner':self.propOwner, u'value':u'originalVal'} - prop2 = {u'name':u'originalProp2', u'owner':self.propOwner, u'value':u'originalVal'} - ch1 = {u'name':u'orgChannel1', u'owner':self.channelOwner, u'properties':[prop1, prop2]} - ch2 = {u'name':u'orgChannel2', u'owner':self.channelOwner, u'properties':[prop1, prop2]} - ch3 = {u'name':u'orgChannel3', u'owner':self.channelOwner, u'properties':[prop1]} + """ + prop1 = {u'name': u'originalProp1', u'owner': self.propOwner, u'value': u'originalVal'} + prop2 = {u'name': u'originalProp2', u'owner': self.propOwner, u'value': u'originalVal'} + ch1 = {u'name': u'orgChannel1', u'owner': self.channelOwner, u'properties': [prop1, prop2]} + ch2 = {u'name': u'orgChannel2', u'owner': self.channelOwner, u'properties': [prop1, prop2]} + ch3 = {u'name': u'orgChannel3', u'owner': self.channelOwner, u'properties': [prop1]} channels = [ch1, ch2, ch3] self.client.set(property=prop1) self.client.set(property=prop2) self.client.set(channels=channels) - chs = self.client.find(property=[(u'originalProp1', u'originalVal'), \ + chs = self.client.find(property=[(u'originalProp1', u'originalVal'), (u'originalProp2', u'originalVal')]) self.assertTrue(len(chs) == 2) for ch in chs: if (ch[u'properties'][0])[u'name'] == 'originalProp1': (ch[u'properties'][0])[u'value'] = 'newVal' self.client.set(channels=chs) - self.assertTrue(len(self.client.find(property=[('originalProp1', 'newVal')])) == 2, \ + self.assertTrue(len(self.client.find(property=[('originalProp1', 'newVal')])) == 2, 'failed to update prop value') - ''' clean up ''' + """ clean up """ for ch in channels: self.client.delete(channelName=ch[u'name']) self.client.delete(propertyName=prop1[u'name']) @@ -542,29 +541,29 @@ def testSetChannelsWithProperties(self): pass def testDestructiveSetRemoveChannels(self): - ''' + """ This test will check that a POST in the channels resources is destructive - ''' - testProp = {u'name':u'testProp', u'owner' : self.propOwner} + """ + testProp = {u'name': u'testProp', u'owner': self.propOwner} try: self.clientProp.set(property=testProp) testProp[u'value'] = 'original' - testChannels = [{u'name':u'pyChannel1', u'owner':self.channelOwner, u'properties':[testProp]}, \ - {u'name':u'pyChannel2', u'owner':self.channelOwner}, \ - {u'name':u'pyChannel3', u'owner':self.channelOwner}] + testChannels = [{u'name': u'pyChannel1', u'owner': self.channelOwner, u'properties': [testProp]}, + {u'name': u'pyChannel2', u'owner': self.channelOwner}, + {u'name': u'pyChannel3', u'owner': self.channelOwner}] self.clientCh.set(channel=testChannels[0]) - self.assertEqual(len(self.client.find(name=u'pyChannel*')), 1, \ + self.assertEqual(len(self.client.find(name=u'pyChannel*')), 1, 'Failed to set a single channel correctly') result = self.client.find(name=u'pyChannel1')[0] - self.assertTrue(checkPropWithValueInList( result['properties'], [testProp] ), \ + self.assertTrue(checkPropWithValueInList(result['properties'], [testProp]), 'Failed to add pychannel1 correctly') - testChannels[0] = {u'name':u'pyChannel1', u'owner':self.channelOwner} + testChannels[0] = {u'name': u'pyChannel1', u'owner': self.channelOwner} self.clientCh.set(channels=testChannels) - self.assertEqual(len(self.client.find(name=u'pyChannel*')), 3, \ + self.assertEqual(len(self.client.find(name=u'pyChannel*')), 3, 'Failed to set a list of channels correctly') - self.assertTrue(not self.client.find(name=u'pyChannel1')[0][u'properties'] or \ - testProp not in self.client.find(name=u'pyChannel1')[0][u'properties'], \ + self.assertTrue(not self.client.find(name=u'pyChannel1')[0][u'properties'] or + testProp not in self.client.find(name=u'pyChannel1')[0][u'properties'], 'Failed to set pychannel1 correctly') finally: for ch in testChannels: @@ -572,9 +571,9 @@ def testDestructiveSetRemoveChannels(self): self.clientProp.delete(propertyName=testProp[u'name']) def testSetRemoveSpecialChar(self): - spChannel = {u'name':u'special{}