Skip to content

Commit

Permalink
Merge pull request #32 from ChannelFinder/pyprojecttoml
Browse files Browse the repository at this point in the history
Clean up package and tests
  • Loading branch information
jacomago authored Jun 19, 2024
2 parents e03429f + ce51f03 commit c7f426a
Show file tree
Hide file tree
Showing 17 changed files with 397 additions and 279 deletions.
37 changes: 37 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python

name: Python package

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

jobs:
test:

runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install '.[test]'
python -m pip install .
- name: Clear existing docker image cache
shell: bash
run: docker image prune -af
- name: Test with pytest
run: |
python -m unittest discover -v -s test -p "test*.py"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
*.pyc
build/
*.egg-info/
.vscode
17 changes: 0 additions & 17 deletions .project

This file was deleted.

11 changes: 0 additions & 11 deletions .pydevproject

This file was deleted.

9 changes: 0 additions & 9 deletions MANIFEST

This file was deleted.

24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# pyCFClient
A python client library

A python client library for ChannelFinder.

### configuration for pyCFClient
## Configuration

The python channelfinder client library can be configured by setting up a `channelfinderapi.conf` file in the following locations

Expand All @@ -11,6 +11,7 @@ The python channelfinder client library can be configured by setting up a `chann
`channelfinderapi.conf`

The example preferences:

```
cat ~/channelfinderapi.conf
[DEFAULT]
Expand All @@ -19,3 +20,22 @@ username=MyUserName
password=MyPassword
```

## Development

To install with dependancies for testing.

```bash
python -m pip install --upgrade pip
python -m pip install '.[test]'
python -m pip install .
```

### Testing

Some of the tests use docker to run a test ChannelFinderService, so a working docker installation needs to available for tests to be successful.

To run all tests:

```bash
python -m unittest discover -v -s test -p "test*.py"
```
3 changes: 0 additions & 3 deletions cf-update-ioc

This file was deleted.

262 changes: 131 additions & 131 deletions cf-monitor-test → channelfinder/cfMonitorTest.py
Original file line number Diff line number Diff line change
@@ -1,131 +1,131 @@
#!/usr/bin/python
'''
Created on Mar 19, 2012
A python script to ensure that the cf-update-ioc is working correctly.
The script requires the setup of two files
e.g.
>cat nagios01.host01.dbl
>test:cf-update-daemon{test}
>cat nagios02.host02.dbl
>test:cf-update-daemon{test}
The script will touch each file, with a short delay and will check that
Channelfinder has been appropriately updated.
python cf-monitor-test /complete/path/to/daemon/dir -i initialFile -f finalFile
@author: shroffk
'''
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 "
parser = OptionParser(usage=usage)
parser.add_option('-i', '--initial-file', \
action='store', type='string', dest='initialFile', \
help='the initial-file')
parser.add_option('-f', '--final-file', \
action='store', type='string', dest='finalFile', \
help='the --final-file')
opts, args = parser.parse_args()
if args == None or len(args) == 0 :
parser.error('Please specify a directory')
if not opts.initialFile:
parser.error('Please specify a initial test files')
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)
iHostName, iIocName = getArgsFromFilename(initialFile)
finalFile = os.path.normpath(directory + '/' + opts.finalFile)
fHostName, fIocName = getArgsFromFilename(finalFile)
if getPVNames(initialFile) != getPVNames(finalFile):
sys.exit(1)
pvNames = getPVNames(initialFile)
if len(pvNames) == 0:
sys.exit(1)
'''
Touch the initial file and check channelfinder
'''
touch(initialFile)
sleep(2)
check(pvNames, iHostName, iIocName)
'''
Touch the final file and check channelfinder
'''
touch(finalFile)
sleep(2)
check(pvNames, fHostName, fIocName)
sys.exit


def check(pvNames, hostName, iocName):
try:
client = ChannelFinderClient()
except:
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:
sys.exit(2)
else:
sys.exit(2)


def touch(fname, times=None):
with open(fname, 'a'):
os.utime(fname, times)


def getArgsFromFilename(completeFilePath):
fileName = os.path.split(os.path.normpath(completeFilePath))[1]
pattern4Hostname = '(\S+?)\.\S+'
match = re.search(pattern4Hostname, fileName)
if match:
hostName = match.group(1)
else:
hostName = None
pattern4Iocname = '\S+?\.(\S+?)\.\S+'
match = re.search(pattern4Iocname, fileName)
if match:
iocName = match.group(1)
else:
iocName = None
return hostName, iocName

def getPVNames(completeFilePath, pattern=None):
try:
f = open(completeFilePath)
pvNames = f.read().splitlines()
pvNames = map(lambda x: x.strip(), pvNames)
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
except IOError:
return None
finally:
f.close()

if __name__ == '__main__':
main()
pass
#!/usr/bin/python
'''
Created on Mar 19, 2012
A python script to ensure that the cf-update-ioc is working correctly.
The script requires the setup of two files
e.g.
>cat nagios01.host01.dbl
>test:cf-update-daemon{test}
>cat nagios02.host02.dbl
>test:cf-update-daemon{test}
The script will touch each file, with a short delay and will check that
Channelfinder has been appropriately updated.
python cf-monitor-test /complete/path/to/daemon/dir -i initialFile -f finalFile
@author: shroffk
'''
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 "
parser = OptionParser(usage=usage)
parser.add_option('-i', '--initial-file', \
action='store', type='string', dest='initialFile', \
help='the initial-file')
parser.add_option('-f', '--final-file', \
action='store', type='string', dest='finalFile', \
help='the --final-file')
opts, args = parser.parse_args()
if args == None or len(args) == 0 :
parser.error('Please specify a directory')
if not opts.initialFile:
parser.error('Please specify a initial test files')
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)
iHostName, iIocName = getArgsFromFilename(initialFile)
finalFile = os.path.normpath(directory + '/' + opts.finalFile)
fHostName, fIocName = getArgsFromFilename(finalFile)
if getPVNames(initialFile) != getPVNames(finalFile):
sys.exit(1)
pvNames = getPVNames(initialFile)
if len(pvNames) == 0:
sys.exit(1)
'''
Touch the initial file and check channelfinder
'''
touch(initialFile)
sleep(2)
check(pvNames, iHostName, iIocName)
'''
Touch the final file and check channelfinder
'''
touch(finalFile)
sleep(2)
check(pvNames, fHostName, fIocName)
sys.exit


def check(pvNames, hostName, iocName):
try:
client = ChannelFinderClient()
except:
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:
sys.exit(2)
else:
sys.exit(2)


def touch(fname, times=None):
with open(fname, 'a'):
os.utime(fname, times)


def getArgsFromFilename(completeFilePath):
fileName = os.path.split(os.path.normpath(completeFilePath))[1]
pattern4Hostname = '(\S+?)\.\S+'
match = re.search(pattern4Hostname, fileName)
if match:
hostName = match.group(1)
else:
hostName = None
pattern4Iocname = '\S+?\.(\S+?)\.\S+'
match = re.search(pattern4Iocname, fileName)
if match:
iocName = match.group(1)
else:
iocName = None
return hostName, iocName

def getPVNames(completeFilePath, pattern=None):
try:
f = open(completeFilePath)
pvNames = f.read().splitlines()
pvNames = map(lambda x: x.strip(), pvNames)
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
except IOError:
return None
finally:
f.close()

if __name__ == '__main__':
main()
pass
Loading

0 comments on commit c7f426a

Please sign in to comment.