summaryrefslogtreecommitdiffhomepage
path: root/test/unit
diff options
context:
space:
mode:
Diffstat (limited to 'test/unit')
-rw-r--r--test/unit/applications/lang/go.py7
-rw-r--r--test/unit/applications/lang/java.py5
-rw-r--r--test/unit/applications/lang/node.py11
-rw-r--r--test/unit/applications/lang/perl.py5
-rw-r--r--test/unit/applications/lang/php.py5
-rw-r--r--test/unit/applications/lang/python.py5
-rw-r--r--test/unit/applications/lang/ruby.py5
-rw-r--r--test/unit/applications/proto.py14
-rw-r--r--test/unit/feature/isolation.py3
-rw-r--r--test/unit/http.py82
-rw-r--r--test/unit/main.py21
11 files changed, 135 insertions, 28 deletions
diff --git a/test/unit/applications/lang/go.py b/test/unit/applications/lang/go.py
index 18345828..7212a95c 100644
--- a/test/unit/applications/lang/go.py
+++ b/test/unit/applications/lang/go.py
@@ -23,7 +23,7 @@ class TestApplicationGo(TestApplicationProto):
os.mkdir(self.testdir + '/go')
env = os.environ.copy()
- env['GOPATH'] = self.pardir + '/go'
+ env['GOPATH'] = self.pardir + '/build/go'
try:
process = Popen(
@@ -44,7 +44,7 @@ class TestApplicationGo(TestApplicationProto):
return process
- def load(self, script, name='app'):
+ def load(self, script, name='app', **kwargs):
self.prepare_env(script, name)
self._load_conf(
@@ -60,5 +60,6 @@ class TestApplicationGo(TestApplicationProto):
"executable": self.testdir + "/go/" + name,
}
},
- }
+ },
+ **kwargs
)
diff --git a/test/unit/applications/lang/java.py b/test/unit/applications/lang/java.py
index bcf87f59..a370d96b 100644
--- a/test/unit/applications/lang/java.py
+++ b/test/unit/applications/lang/java.py
@@ -6,7 +6,7 @@ from unit.applications.proto import TestApplicationProto
class TestApplicationJava(TestApplicationProto):
- def load(self, script, name='app'):
+ def load(self, script, name='app', **kwargs):
app_path = self.testdir + '/java'
web_inf_path = app_path + '/WEB-INF/'
classes_path = web_inf_path + 'classes/'
@@ -82,5 +82,6 @@ class TestApplicationJava(TestApplicationProto):
"webapp": app_path,
}
},
- }
+ },
+ **kwargs
)
diff --git a/test/unit/applications/lang/node.py b/test/unit/applications/lang/node.py
index 3cc72669..d818298f 100644
--- a/test/unit/applications/lang/node.py
+++ b/test/unit/applications/lang/node.py
@@ -15,20 +15,22 @@ class TestApplicationNode(TestApplicationProto):
return unit if not complete_check else unit.complete()
- def load(self, script, name='app.js'):
+ def load(self, script, name='app.js', **kwargs):
# copy application
shutil.copytree(
self.current_dir + '/node/' + script, self.testdir + '/node'
)
- # link modules
+ # copy modules
- os.symlink(
+ shutil.copytree(
self.pardir + '/node/node_modules',
self.testdir + '/node/node_modules',
)
+ self.public_dir(self.testdir + '/node')
+
self._load_conf(
{
"listeners": {"*:7080": {"pass": "applications/" + script}},
@@ -40,5 +42,6 @@ class TestApplicationNode(TestApplicationProto):
"executable": name,
}
},
- }
+ },
+ **kwargs
)
diff --git a/test/unit/applications/lang/perl.py b/test/unit/applications/lang/perl.py
index 79df2cfa..d32aca33 100644
--- a/test/unit/applications/lang/perl.py
+++ b/test/unit/applications/lang/perl.py
@@ -4,7 +4,7 @@ from unit.applications.proto import TestApplicationProto
class TestApplicationPerl(TestApplicationProto):
application_type = "perl"
- def load(self, script, name='psgi.pl'):
+ def load(self, script, name='psgi.pl', **kwargs):
script_path = self.current_dir + '/perl/' + script
self._load_conf(
@@ -18,5 +18,6 @@ class TestApplicationPerl(TestApplicationProto):
"script": script_path + '/' + name,
}
},
- }
+ },
+ **kwargs
)
diff --git a/test/unit/applications/lang/php.py b/test/unit/applications/lang/php.py
index 9c54368d..6b1677e6 100644
--- a/test/unit/applications/lang/php.py
+++ b/test/unit/applications/lang/php.py
@@ -4,7 +4,7 @@ from unit.applications.proto import TestApplicationProto
class TestApplicationPHP(TestApplicationProto):
application_type = "php"
- def load(self, script, name='index.php'):
+ def load(self, script, name='index.php', **kwargs):
script_path = self.current_dir + '/php/' + script
self._load_conf(
@@ -19,5 +19,6 @@ class TestApplicationPHP(TestApplicationProto):
"index": name,
}
},
- }
+ },
+ **kwargs
)
diff --git a/test/unit/applications/lang/python.py b/test/unit/applications/lang/python.py
index ded76cb6..fdda024a 100644
--- a/test/unit/applications/lang/python.py
+++ b/test/unit/applications/lang/python.py
@@ -4,7 +4,7 @@ from unit.applications.proto import TestApplicationProto
class TestApplicationPython(TestApplicationProto):
application_type = "python"
- def load(self, script, name=None):
+ def load(self, script, name=None, **kwargs):
if name is None:
name = script
@@ -22,5 +22,6 @@ class TestApplicationPython(TestApplicationProto):
"module": "wsgi",
}
},
- }
+ },
+ **kwargs
)
diff --git a/test/unit/applications/lang/ruby.py b/test/unit/applications/lang/ruby.py
index d30735ad..8c8acecc 100644
--- a/test/unit/applications/lang/ruby.py
+++ b/test/unit/applications/lang/ruby.py
@@ -4,7 +4,7 @@ from unit.applications.proto import TestApplicationProto
class TestApplicationRuby(TestApplicationProto):
application_type = "ruby"
- def load(self, script, name='config.ru'):
+ def load(self, script, name='config.ru', **kwargs):
script_path = self.current_dir + '/ruby/' + script
self._load_conf(
@@ -18,5 +18,6 @@ class TestApplicationRuby(TestApplicationProto):
"script": script_path + '/' + name,
}
},
- }
+ },
+ **kwargs
)
diff --git a/test/unit/applications/proto.py b/test/unit/applications/proto.py
index 4105473f..ae1af354 100644
--- a/test/unit/applications/proto.py
+++ b/test/unit/applications/proto.py
@@ -25,7 +25,19 @@ class TestApplicationProto(TestControl):
return found
- def _load_conf(self, conf):
+ def _load_conf(self, conf, **kwargs):
+ if 'applications' in conf:
+ for app in conf['applications'].keys():
+ app_conf = conf['applications'][app]
+ if 'user' in kwargs:
+ app_conf['user'] = kwargs['user']
+
+ if 'group' in kwargs:
+ app_conf['group'] = kwargs['group']
+
+ if 'isolation' in kwargs:
+ app_conf['isolation'] = kwargs['isolation']
+
self.assertIn(
'success', self.conf(conf), 'load application configuration'
)
diff --git a/test/unit/feature/isolation.py b/test/unit/feature/isolation.py
index 9b06ab3c..3f474993 100644
--- a/test/unit/feature/isolation.py
+++ b/test/unit/feature/isolation.py
@@ -82,6 +82,3 @@ class TestFeatureIsolation(TestApplicationProto):
data = int(os.readlink(nspath)[len(nstype) + 2 : -1])
return data
-
- def parsejson(self, data):
- return json.loads(data.split('\n')[1])
diff --git a/test/unit/http.py b/test/unit/http.py
index c7e3e36d..839e91a2 100644
--- a/test/unit/http.py
+++ b/test/unit/http.py
@@ -1,5 +1,6 @@
import re
import time
+import json
import socket
import select
from unit.main import TestUnit
@@ -86,23 +87,24 @@ class TestHTTP(TestUnit):
sock.sendall(req)
+ encoding = 'utf-8' if 'encoding' not in kwargs else kwargs['encoding']
+
if TestUnit.detailed:
print('>>>')
try:
- print(req.decode('utf-8', 'ignore'))
+ print(req.decode(encoding, 'ignore'))
except UnicodeEncodeError:
print(req)
resp = ''
if 'no_recv' not in kwargs:
- enc = 'utf-8' if 'encoding' not in kwargs else kwargs['encoding']
read_timeout = (
30 if 'read_timeout' not in kwargs else kwargs['read_timeout']
)
resp = self.recvall(
sock, read_timeout=read_timeout, buff_size=read_buffer_size
- ).decode(enc)
+ ).decode(encoding)
if TestUnit.detailed:
print('<<<')
@@ -114,6 +116,15 @@ class TestHTTP(TestUnit):
if 'raw_resp' not in kwargs:
resp = self._resp_to_dict(resp)
+ headers = resp.get('headers')
+ if headers and headers.get('Transfer-Encoding') == 'chunked':
+ resp['body'] = self._parse_chunked_body(resp['body']).decode(
+ encoding
+ )
+
+ if 'json' in kwargs:
+ resp = self._parse_json(resp)
+
if 'start' not in kwargs:
sock.close()
return resp
@@ -151,7 +162,7 @@ class TestHTTP(TestUnit):
return data
def _resp_to_dict(self, resp):
- m = re.search('(.*?\x0d\x0a?)\x0d\x0a?(.*)', resp, re.M | re.S)
+ m = re.search(r'(.*?\x0d\x0a?)\x0d\x0a?(.*)', resp, re.M | re.S)
if not m:
return {}
@@ -162,12 +173,12 @@ class TestHTTP(TestUnit):
headers_lines = p.findall(headers_text)
status = re.search(
- '^HTTP\/\d\.\d\s(\d+)|$', headers_lines.pop(0)
+ r'^HTTP\/\d\.\d\s(\d+)|$', headers_lines.pop(0)
).group(1)
headers = {}
for line in headers_lines:
- m = re.search('(.*)\:\s(.*)', line)
+ m = re.search(r'(.*)\:\s(.*)', line)
if m.group(1) not in headers:
headers[m.group(1)] = m.group(2)
@@ -180,6 +191,65 @@ class TestHTTP(TestUnit):
return {'status': int(status), 'headers': headers, 'body': body}
+ def _parse_chunked_body(self, raw_body):
+ if isinstance(raw_body, str):
+ raw_body = bytes(raw_body.encode())
+
+ crlf = b'\r\n'
+ chunks = raw_body.split(crlf)
+
+ if len(chunks) < 3:
+ self.fail('Invalid chunked body')
+
+ if chunks.pop() != b'':
+ self.fail('No CRLF at the end of the body')
+
+ try:
+ last_size = int(chunks[-2], 16)
+ except:
+ self.fail('Invalid zero size chunk')
+
+ if last_size != 0 or chunks[-1] != b'':
+ self.fail('Incomplete body')
+
+ body = b''
+ while len(chunks) >= 2:
+ try:
+ size = int(chunks.pop(0), 16)
+ except:
+ self.fail('Invalid chunk size %s' % str(size))
+
+ if size == 0:
+ self.assertEqual(len(chunks), 1, 'last zero size')
+ break
+
+ temp_body = crlf.join(chunks)
+
+ body += temp_body[:size]
+
+ temp_body = temp_body[size + len(crlf) :]
+
+ chunks = temp_body.split(crlf)
+
+ return body
+
+ def _parse_json(self, resp):
+ headers = resp['headers']
+
+ self.assertIn('Content-Type', headers, 'Content-Type header set')
+ self.assertEqual(
+ headers['Content-Type'],
+ 'application/json',
+ 'Content-Type header is application/json',
+ )
+
+ resp['body'] = json.loads(resp['body'])
+
+ return resp
+
+ def getjson(self, **kwargs):
+ return self.get(json=True, **kwargs)
+
def waitforsocket(self, port):
ret = False
diff --git a/test/unit/main.py b/test/unit/main.py
index 094fdb0e..ea6afd7f 100644
--- a/test/unit/main.py
+++ b/test/unit/main.py
@@ -1,6 +1,7 @@
import os
import re
import sys
+import stat
import time
import fcntl
import shutil
@@ -20,6 +21,9 @@ class TestUnit(unittest.TestCase):
pardir = os.path.abspath(
os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)
)
+ is_su = os.geteuid() == 0
+ uid = os.geteuid()
+ gid = os.getegid()
architecture = platform.architecture()[0]
system = platform.system()
maxDiff = None
@@ -188,13 +192,19 @@ class TestUnit(unittest.TestCase):
self.stop_processes()
def _run(self):
- self.unitd = self.pardir + '/build/unitd'
+ build_dir = self.pardir + '/build'
+ self.unitd = build_dir + '/unitd'
if not os.path.isfile(self.unitd):
exit("Could not find unit")
self.testdir = tempfile.mkdtemp(prefix='unit-test-')
+ self.public_dir(self.testdir)
+
+ if oct(stat.S_IMODE(os.stat(build_dir).st_mode)) != '0o777':
+ self.public_dir(build_dir)
+
os.mkdir(self.testdir + '/state')
print()
@@ -328,6 +338,15 @@ class TestUnit(unittest.TestCase):
return ret
+ def public_dir(self, path):
+ os.chmod(path, 0o777)
+
+ for root, dirs, files in os.walk(path):
+ for d in dirs:
+ os.chmod(os.path.join(root, d), 0o777)
+ for f in files:
+ os.chmod(os.path.join(root, f), 0o777)
+
@staticmethod
def _parse_args():
parser = argparse.ArgumentParser(add_help=False)