summaryrefslogtreecommitdiffstats
path: root/test/unit/__init__.py
diff options
context:
space:
mode:
authorLuis Pabon <lpabon@redhat.com>2013-05-29 21:19:43 -0400
committerPeter Portante <pportant@redhat.com>2013-06-03 16:52:15 -0700
commit40c313378e5fffb846f1fd143573a687e2774b28 (patch)
treedc6dd6e05c8a4abe1eba31bc25f849c86df8be96 /test/unit/__init__.py
parent31a2ef1935133f224169a1315a91a2d9e9775d9a (diff)
Copy proxy unit test from OpenStack Swift
This is a copy of the proxy unit test from OpenStack Swift. The file has minor changes to make it compatible with Gluster For Swift. Change-Id: I64a0f8d274461eb2a2c38524c6282e0d3d3d1457 Signed-off-by: Luis Pabon <lpabon@redhat.com> Reviewed-on: http://review.gluster.org/5113 Reviewed-by: Peter Portante <pportant@redhat.com> Tested-by: Peter Portante <pportant@redhat.com>
Diffstat (limited to 'test/unit/__init__.py')
-rw-r--r--test/unit/__init__.py309
1 files changed, 306 insertions, 3 deletions
diff --git a/test/unit/__init__.py b/test/unit/__init__.py
index cb24764..e90553f 100644
--- a/test/unit/__init__.py
+++ b/test/unit/__init__.py
@@ -1,9 +1,110 @@
-""" Gluster Swift Unit Tests """
+""" Swift tests """
+import sys
+import os
+import copy
import logging
+import errno
+from sys import exc_info
+from contextlib import contextmanager
from collections import defaultdict
+from tempfile import NamedTemporaryFile
+from eventlet.green import socket
+from tempfile import mkdtemp
+from shutil import rmtree
from test import get_config
-from swift.common.utils import TRUE_VALUES
+from ConfigParser import MissingSectionHeaderError
+from StringIO import StringIO
+from swift.common.utils import readconf, config_true_value
+from logging import Handler
+from hashlib import md5
+from eventlet import sleep, spawn, Timeout
+import logging.handlers
+
+
+def readuntil2crlfs(fd):
+ rv = ''
+ lc = ''
+ crlfs = 0
+ while crlfs < 2:
+ c = fd.read(1)
+ rv = rv + c
+ if c == '\r' and lc != '\n':
+ crlfs = 0
+ if lc == '\r' and c == '\n':
+ crlfs += 1
+ lc = c
+ return rv
+
+
+def connect_tcp(hostport):
+ rv = socket.socket()
+ rv.connect(hostport)
+ return rv
+
+
+@contextmanager
+def tmpfile(content):
+ with NamedTemporaryFile('w', delete=False) as f:
+ file_name = f.name
+ f.write(str(content))
+ try:
+ yield file_name
+ finally:
+ os.unlink(file_name)
+
+xattr_data = {}
+
+
+def _get_inode(fd):
+ if not isinstance(fd, int):
+ try:
+ fd = fd.fileno()
+ except AttributeError:
+ return os.stat(fd).st_ino
+ return os.fstat(fd).st_ino
+
+
+def _setxattr(fd, k, v):
+ inode = _get_inode(fd)
+ data = xattr_data.get(inode, {})
+ data[k] = v
+ xattr_data[inode] = data
+
+
+def _getxattr(fd, k):
+ inode = _get_inode(fd)
+ data = xattr_data.get(inode, {}).get(k)
+ if not data:
+ e = IOError("Fake IOError")
+ e.errno = errno.ENODATA
+ raise e
+ return data
+
+import xattr
+xattr.setxattr = _setxattr
+xattr.getxattr = _getxattr
+
+
+@contextmanager
+def temptree(files, contents=''):
+ # generate enough contents to fill the files
+ c = len(files)
+ contents = (list(contents) + [''] * c)[:c]
+ tempdir = mkdtemp()
+ for path, content in zip(files, contents):
+ if os.path.isabs(path):
+ path = '.' + path
+ new_path = os.path.join(tempdir, path)
+ subdir = os.path.dirname(new_path)
+ if not os.path.exists(subdir):
+ os.makedirs(subdir)
+ with open(new_path, 'w') as f:
+ f.write(str(content))
+ try:
+ yield tempdir
+ finally:
+ rmtree(tempdir)
class NullLoggingHandler(logging.Handler):
@@ -45,6 +146,17 @@ class FakeLogger(object):
update_stats = _store_in('update_stats')
set_statsd_prefix = _store_in('set_statsd_prefix')
+ def get_increments(self):
+ return [call[0][0] for call in self.log_dict['increment']]
+
+ def get_increment_counts(self):
+ counts = {}
+ for metric in self.get_increments():
+ if metric not in counts:
+ counts[metric] = 0
+ counts[metric] += 1
+ return counts
+
def setFormatter(self, obj):
self.formatter = obj
@@ -91,5 +203,196 @@ def fake_syslog_handler():
logging.handlers.SysLogHandler = FakeLogger
-if get_config('unit_test').get('fake_syslog', 'False').lower() in TRUE_VALUES:
+if config_true_value(get_config('unit_test').get('fake_syslog', 'False')):
fake_syslog_handler()
+
+
+class MockTrue(object):
+ """
+ Instances of MockTrue evaluate like True
+ Any attr accessed on an instance of MockTrue will return a MockTrue
+ instance. Any method called on an instance of MockTrue will return
+ a MockTrue instance.
+
+ >>> thing = MockTrue()
+ >>> thing
+ True
+ >>> thing == True # True == True
+ True
+ >>> thing == False # True == False
+ False
+ >>> thing != True # True != True
+ False
+ >>> thing != False # True != False
+ True
+ >>> thing.attribute
+ True
+ >>> thing.method()
+ True
+ >>> thing.attribute.method()
+ True
+ >>> thing.method().attribute
+ True
+
+ """
+
+ def __getattribute__(self, *args, **kwargs):
+ return self
+
+ def __call__(self, *args, **kwargs):
+ return self
+
+ def __repr__(*args, **kwargs):
+ return repr(True)
+
+ def __eq__(self, other):
+ return other is True
+
+ def __ne__(self, other):
+ return other is not True
+
+
+@contextmanager
+def mock(update):
+ returns = []
+ deletes = []
+ for key, value in update.items():
+ imports = key.split('.')
+ attr = imports.pop(-1)
+ module = __import__(imports[0], fromlist=imports[1:])
+ for modname in imports[1:]:
+ module = getattr(module, modname)
+ if hasattr(module, attr):
+ returns.append((module, attr, getattr(module, attr)))
+ else:
+ deletes.append((module, attr))
+ setattr(module, attr, value)
+ yield True
+ for module, attr, value in returns:
+ setattr(module, attr, value)
+ for module, attr in deletes:
+ delattr(module, attr)
+
+
+def fake_http_connect(*code_iter, **kwargs):
+
+ class FakeConn(object):
+
+ def __init__(self, status, etag=None, body='', timestamp='1',
+ expect_status=None):
+ self.status = status
+ if expect_status is None:
+ self.expect_status = self.status
+ else:
+ self.expect_status = expect_status
+ self.reason = 'Fake'
+ self.host = '1.2.3.4'
+ self.port = '1234'
+ self.sent = 0
+ self.received = 0
+ self.etag = etag
+ self.body = body
+ self.timestamp = timestamp
+
+ def getresponse(self):
+ if kwargs.get('raise_exc'):
+ raise Exception('test')
+ if kwargs.get('raise_timeout_exc'):
+ raise Timeout()
+ return self
+
+ def getexpect(self):
+ if self.expect_status == -2:
+ raise HTTPException()
+ if self.expect_status == -3:
+ return FakeConn(507)
+ if self.expect_status == -4:
+ return FakeConn(201)
+ return FakeConn(100)
+
+ def getheaders(self):
+ etag = self.etag
+ if not etag:
+ if isinstance(self.body, str):
+ etag = '"' + md5(self.body).hexdigest() + '"'
+ else:
+ etag = '"68b329da9893e34099c7d8ad5cb9c940"'
+
+ headers = {'content-length': len(self.body),
+ 'content-type': 'x-application/test',
+ 'x-timestamp': self.timestamp,
+ 'last-modified': self.timestamp,
+ 'x-object-meta-test': 'testing',
+ 'etag': etag,
+ 'x-works': 'yes',
+ 'x-account-container-count': kwargs.get('count', 12345)}
+ if not self.timestamp:
+ del headers['x-timestamp']
+ try:
+ if container_ts_iter.next() is False:
+ headers['x-container-timestamp'] = '1'
+ except StopIteration:
+ pass
+ if 'slow' in kwargs:
+ headers['content-length'] = '4'
+ if 'headers' in kwargs:
+ headers.update(kwargs['headers'])
+ return headers.items()
+
+ def read(self, amt=None):
+ if 'slow' in kwargs:
+ if self.sent < 4:
+ self.sent += 1
+ sleep(0.1)
+ return ' '
+ rv = self.body[:amt]
+ self.body = self.body[amt:]
+ return rv
+
+ def send(self, amt=None):
+ if 'slow' in kwargs:
+ if self.received < 4:
+ self.received += 1
+ sleep(0.1)
+
+ def getheader(self, name, default=None):
+ return dict(self.getheaders()).get(name.lower(), default)
+
+ timestamps_iter = iter(kwargs.get('timestamps') or ['1'] * len(code_iter))
+ etag_iter = iter(kwargs.get('etags') or [None] * len(code_iter))
+ x = kwargs.get('missing_container', [False] * len(code_iter))
+ if not isinstance(x, (tuple, list)):
+ x = [x] * len(code_iter)
+ container_ts_iter = iter(x)
+ code_iter = iter(code_iter)
+ static_body = kwargs.get('body', None)
+ body_iter = kwargs.get('body_iter', None)
+ if body_iter:
+ body_iter = iter(body_iter)
+
+ def connect(*args, **ckwargs):
+ if 'give_content_type' in kwargs:
+ if len(args) >= 7 and 'Content-Type' in args[6]:
+ kwargs['give_content_type'](args[6]['Content-Type'])
+ else:
+ kwargs['give_content_type']('')
+ if 'give_connect' in kwargs:
+ kwargs['give_connect'](*args, **ckwargs)
+ status = code_iter.next()
+ if isinstance(status, tuple):
+ status, expect_status = status
+ else:
+ expect_status = status
+ etag = etag_iter.next()
+ timestamp = timestamps_iter.next()
+
+ if status <= 0:
+ raise HTTPException()
+ if body_iter is None:
+ body = static_body or ''
+ else:
+ body = body_iter.next()
+ return FakeConn(status, etag, body=body, timestamp=timestamp,
+ expect_status=expect_status)
+
+ return connect