Updated rsync_url and tests
Change-Id: I652a72713ab82661232db20b9643d3340e016af0
diff --git a/rsync_url.py b/rsync_url.py
index 38836ac..4f45859 100644
--- a/rsync_url.py
+++ b/rsync_url.py
@@ -11,7 +11,7 @@
def __init__(self, remote_url):
- self.url = remote_url
+ self._url = remote_url
self._url_type = False
self.regexps = {
@@ -30,7 +30,8 @@
r'(?P<user>[-\w]+@)?'
r'(?P<host>[-\.\w]+){1}'
r'::'
- r'(?P<path>[\w/-]*){1}'
+ r'(?P<module>[\w-]+){1}'
+ r'(?P<path>[\w/-]*)?'
r'$'
),
# rsync://[USER@]HOST[:PORT]/SRC
@@ -39,7 +40,8 @@
r'(?P<user>[-\w]+@)?'
r'(?P<host>[-\.\w]+){1}'
r'(?P<port>:[\d]+)?'
- r'(?P<path>[\w/-]*){1}'
+ r'(?P<module>/[\w-]*)?'
+ r'(?P<path>[\w/-]*)?'
r'$'
),
# local/path/to/directory
@@ -50,9 +52,10 @@
),
}
- self.match = self._get_matching_regexp()
+ self._match = self._get_matching_regexp()
if self.match is None:
- self.user, self.host, self.port, self.path = None, None, None, None
+ self.user, self.host, self.module, self.port, self.path = \
+ None, None, None, None, None
else:
self._parse_rsync_url(self.match)
@@ -83,17 +86,16 @@
if self.url_type is False:
self._url_type = url_type
regexps.append(regexp)
- #print match, regexp.pattern
return regexps
def _parse_rsync_url(self, regexp):
# parse remote url
- for match in re.finditer(regexp, self.url):
+ for match in re.finditer(regexp, self._url):
self.path = match.group('path')
- if not self.path:
- self.path = '/'
+ if self.path is None:
+ self.path = ''
try:
self.host = match.group('host')
@@ -116,6 +118,38 @@
if self.port is not None:
self.port = int(self.port.strip(':'))
+ try:
+ self.module = match.group('module')
+ except IndexError:
+ self.module = None
+ else:
+ if self.module is not None:
+ self.module = self.module.strip('/')
+ if not self.module:
+ self.module = None
+
+ @property
+ def match(self):
+ return self._match
+
@property
def url_type(self):
return self._url_type
+
+ @property
+ def is_valid(self):
+ if self.match is None:
+ return False
+ if self.path in (None, False):
+ return False
+ if self.url_type != 'path':
+ if self.host in ('', None, False):
+ return False
+ if self.url_type.startswith('rsync'):
+ if self.module is None:
+ return False
+ return True
+
+ @property
+ def url(self):
+ return self._url
diff --git a/test_rsync_url.py b/test_rsync_url.py
index 5166b6c..cb6c350 100644
--- a/test_rsync_url.py
+++ b/test_rsync_url.py
@@ -1,28 +1,67 @@
#-*- coding: utf-8 -*-
-import rsync_url
+import logging
import unittest
import yaml
+import rsync_url
+
+
+logging.basicConfig(level='INFO')
+logger = logging.getLogger('TestRsyncUrl')
+
class TestRsyncUrl(unittest.TestCase):
+ def log_locals(self, url):
+ if url.match:
+ logger.info('RE: "{}"'.format(url.match.pattern))
+ logger.info('user "{}", host "{}", port "{}", module "{}", '
+ 'path "{}"'.format(url.user, url.host, url.port,
+ url.module, url.path))
+
def exact_match_num(self, remote, expected_result):
+ logger.info('"{}" - {}'.format(remote, expected_result))
url = rsync_url.RsyncUrl(remote)
+ self.log_locals(url)
matching_regexps = url._get_all_matching_regexps()
self.assertEqual(len(matching_regexps), expected_result)
def classed(self, remote, expected_result):
+ logger.info('"{}" - {}'.format(remote, expected_result))
url = rsync_url.RsyncUrl(remote)
+ self.log_locals(url)
self.assertEqual(url.url_type, expected_result)
def parsed(self, remote, expected_result):
+ logger.info('"{}" - {}'.format(remote, expected_result))
url = rsync_url.RsyncUrl(remote)
+ self.log_locals(url)
self.assertEqual(
- [url.user, url.host, url.port, url.path],
+ [url.user, url.host, url.path],
expected_result
)
+ def parsed_rsync(self, remote, expected_result):
+ logger.info('"{}" - {}'.format(remote, expected_result))
+ url = rsync_url.RsyncUrl(remote)
+ self.log_locals(url)
+ self.assertEqual(
+ [url.user, url.host, url.port, url.module, url.path],
+ expected_result
+ )
+
+ def valid(self, remote, expected_result):
+ logger.info('"{}" - {}'.format(remote, expected_result))
+ url = rsync_url.RsyncUrl(remote)
+ self.log_locals(url)
+ self.assertEqual(url.is_valid, expected_result)
+
+ def url(self, remote, expected_result):
+ logger.info('"{}" - {}'.format(remote, expected_result))
+ url = rsync_url.RsyncUrl(remote)
+ self.log_locals(url)
+ self.assertEqual(url.url, expected_result)
testdata = yaml.load(open('test_rsync_url.yaml'))
@@ -38,7 +77,7 @@
getattr(self, test)(remote, expected_result)
test_function.__name__ = \
- 'test_{}_{}_{}'.format(index, tests['classed'], test)
+ 'test_rsync_url_{}_{}_{}'.format(index, tests['classed'], test)
test_function.__doc__ = test_function.__name__
setattr(TestRsyncUrl, test_function.__name__, test_function)
del test_function
diff --git a/test_rsync_url.yaml b/test_rsync_url.yaml
index d784da3..eaac8dd 100644
--- a/test_rsync_url.yaml
+++ b/test_rsync_url.yaml
@@ -6,154 +6,191 @@
# - expected
# - results
'ubuntu@172.18.66.89:~':
+ url: 'ubuntu@172.18.66.89:~'
exact_match_num: 1
classed: 'ssh'
parsed:
- 'ubuntu'
- '172.18.66.89'
- - null
- '~'
+ valid: True
'johnivanov@172.18.66.89:/mirror-sync/otlichniy/reg/exp':
+ url: 'johnivanov@172.18.66.89:/mirror-sync/otlichniy/reg/exp'
exact_match_num: 1
classed: 'ssh'
parsed:
- 'johnivanov'
- '172.18.66.89'
- - null
- '/mirror-sync/otlichniy/reg/exp'
+ valid: True
'172.18.66.89:/mirror-sync/otlichniy/reg/exp':
+ url: '172.18.66.89:/mirror-sync/otlichniy/reg/exp'
exact_match_num: 1
classed: 'ssh'
parsed:
- null
- '172.18.66.89'
- - null
- '/mirror-sync/otlichniy/reg/exp'
+ valid: True
'172.18.66.89:/':
+ url: '172.18.66.89:/'
exact_match_num: 1
classed: 'ssh'
parsed:
- null
- '172.18.66.89'
- - null
- '/'
+ valid: True
'172.18.66.89:':
+ url: '172.18.66.89:'
exact_match_num: 1
classed: 'ssh'
parsed:
- null
- '172.18.66.89'
- - null
- - '/'
-'johnivanov@172.18.66.89::/mirror-sync/otlichniy/reg/exp':
+ - ''
+ valid: True
+'johnivanov@172.18.66.89::mirror-sync/otlichniy/reg/exp':
+ url: 'johnivanov@172.18.66.89::mirror-sync/otlichniy/reg/exp'
exact_match_num: 1
classed: 'rsync1'
- parsed:
+ parsed_rsync:
- 'johnivanov'
- '172.18.66.89'
- null
- - '/mirror-sync/otlichniy/reg/exp'
+ - 'mirror-sync'
+ - '/otlichniy/reg/exp'
+ valid: True
+'172.18.66.89::mirror-sync/otlichniy/reg/exp':
+ url: '172.18.66.89::mirror-sync/otlichniy/reg/exp'
+ exact_match_num: 1
+ classed: 'rsync1'
+ parsed_rsync:
+ - null
+ - '172.18.66.89'
+ - null
+ - 'mirror-sync'
+ - '/otlichniy/reg/exp'
+ valid: True
+'johnivanov@172.18.66.89::/mirror-sync/otlichniy/reg/exp':
+ url: 'johnivanov@172.18.66.89::/mirror-sync/otlichniy/reg/exp'
+ exact_match_num: 0
+ classed: null
+ valid: False
'172.18.66.89::/mirror-sync/otlichniy/reg/exp':
- exact_match_num: 1
- classed: 'rsync1'
- parsed:
- - null
- - '172.18.66.89'
- - null
- - '/mirror-sync/otlichniy/reg/exp'
+ url: '172.18.66.89::/mirror-sync/otlichniy/reg/exp'
+ exact_match_num: 0
+ classed: null
+ valid: False
'172.18.66.89::/':
- exact_match_num: 1
- classed: 'rsync1'
- parsed:
- - null
- - '172.18.66.89'
- - null
- - '/'
+ url: '172.18.66.89::/'
+ exact_match_num: 0
+ classed: null
+ valid: False
'172.18.66.89::':
+ url: '172.18.66.89::'
exact_match_num: 1
classed: 'rsync1'
- parsed:
+ parsed_rsync:
- null
- '172.18.66.89'
- null
- - '/'
+ - null
+ - ''
+ valid: False
'rsync://mirror-sync@172.18.66.89:7327/otlichniy/reg/exp':
+ url: 'rsync://mirror-sync@172.18.66.89:7327/otlichniy/reg/exp'
exact_match_num: 1
classed: 'rsync2'
- parsed:
+ parsed_rsync:
- 'mirror-sync'
- '172.18.66.89'
- 7327
- - '/otlichniy/reg/exp'
+ - 'otlichniy'
+ - '/reg/exp'
+ valid: True
'rsync://172.18.66.89:7327/mirror-sync/otlichniy/reg/exp':
+ url: 'rsync://172.18.66.89:7327/mirror-sync/otlichniy/reg/exp'
exact_match_num: 1
classed: 'rsync2'
- parsed:
+ parsed_rsync:
- null
- '172.18.66.89'
- 7327
- - '/mirror-sync/otlichniy/reg/exp'
+ - 'mirror-sync'
+ - '/otlichniy/reg/exp'
+ valid: True
'rsync://172.18.66.89/mirror-sync/otlichniy/reg/exp':
+ url: 'rsync://172.18.66.89/mirror-sync/otlichniy/reg/exp'
exact_match_num: 1
classed: 'rsync2'
- parsed:
+ parsed_rsync:
- null
- '172.18.66.89'
- null
- - '/mirror-sync/otlichniy/reg/exp'
+ - 'mirror-sync'
+ - '/otlichniy/reg/exp'
+ valid: True
'rsync://172.18.66.89/':
+ url: 'rsync://172.18.66.89/'
exact_match_num: 1
classed: 'rsync2'
- parsed:
+ parsed_rsync:
- null
- '172.18.66.89'
- null
- - '/'
+ - null
+ - ''
+ valid: False
'rsync://172.18.66.89':
+ url: 'rsync://172.18.66.89'
exact_match_num: 1
classed: 'rsync2'
- parsed:
+ parsed_rsync:
- null
- '172.18.66.89'
- null
- - '/'
+ - null
+ - ''
+ valid: False
'/':
+ url: '/'
exact_match_num: 1
classed: 'path'
parsed:
- null
- null
- - null
- '/'
+ valid: True
'dir':
+ url: 'dir'
exact_match_num: 1
classed: 'path'
parsed:
- null
- null
- - null
- 'dir'
+ valid: True
'/dir':
+ url: '/dir'
exact_match_num: 1
classed: 'path'
parsed:
- null
- null
- - null
- '/dir'
+ valid: True
'/dir/subdir/':
+ url: '/dir/subdir/'
exact_match_num: 1
classed: 'path'
parsed:
- null
- null
- - null
- '/dir/subdir/'
+ valid: True
'':
+ url: ''
exact_match_num: 0
classed: null
- parsed:
- - null
- - null
- - null
- - null
+ valid: False