Tests: using LF line ending for test files.

This commit is contained in:
Andrey Zelenkov
2018-01-17 15:52:01 +03:00
parent 37a713c217
commit a949c2f088
6 changed files with 869 additions and 869 deletions

View File

@@ -1,146 +1,146 @@
import unittest import unittest
import unit import unit
class TestUnitConfiguration(unit.TestUnitControl): class TestUnitConfiguration(unit.TestUnitControl):
def setUpClass(): def setUpClass():
unit.TestUnit().check_modules('python') unit.TestUnit().check_modules('python')
def test_json(self): def test_json(self):
self.assertIn('error', self.put('/', '00'), 'leading zero') self.assertIn('error', self.put('/', '00'), 'leading zero')
def test_json_applications(self): def test_json_applications(self):
self.assertIn('error', self.put('/applications', '"{}"'), self.assertIn('error', self.put('/applications', '"{}"'),
'applications string') 'applications string')
self.assertIn('error', self.put('/applications', '{'), self.assertIn('error', self.put('/applications', '{'),
'applications miss brace') 'applications miss brace')
self.assertTry('assertIn', 'negative workers', 'error', self.assertTry('assertIn', 'negative workers', 'error',
self.put('/applications', """ self.put('/applications', """
{ {
"app": { "app": {
"type": "python", "type": "python",
"workers": -1, "workers": -1,
"path": "/app", "path": "/app",
"module": "wsgi" "module": "wsgi"
} }
} }
""")) """))
self.assertTry('assertIn', 'application type only', 'error', self.assertTry('assertIn', 'application type only', 'error',
self.put('/applications', """ self.put('/applications', """
{ {
"app": { "app": {
"type": "python" "type": "python"
} }
} }
""")) """))
self.assertIn('error', self.put('/applications', """ self.assertIn('error', self.put('/applications', """
{ {
app": { app": {
"type": "python", "type": "python",
"workers": 1, "workers": 1,
"path": "/app", "path": "/app",
"module": "wsgi" "module": "wsgi"
} }
} }
"""), 'applications miss quote') """), 'applications miss quote')
self.assertIn('error', self.put('/applications', """ self.assertIn('error', self.put('/applications', """
{ {
"app" { "app" {
"type": "python", "type": "python",
"workers": 1, "workers": 1,
"path": "/app", "path": "/app",
"module": "wsgi" "module": "wsgi"
} }
} }
"""), 'applications miss colon') """), 'applications miss colon')
self.assertIn('error', self.put('/applications', """ self.assertIn('error', self.put('/applications', """
{ {
"app": { "app": {
"type": "python" "type": "python"
"workers": 1, "workers": 1,
"path": "/app", "path": "/app",
"module": "wsgi" "module": "wsgi"
} }
} }
"""), 'applications miss comma') """), 'applications miss comma')
self.assertIn('success', self.put('/applications', b'{ \n\r\t}'), self.assertIn('success', self.put('/applications', b'{ \n\r\t}'),
'skip space') 'skip space')
self.assertIn('success', self.put('/applications', """ self.assertIn('success', self.put('/applications', """
{ {
"app": { "app": {
"type": "python", "type": "python",
"workers": 1, "workers": 1,
"path": "../app", "path": "../app",
"module": "wsgi" "module": "wsgi"
} }
} }
"""), 'relative path') """), 'relative path')
self.assertIn('success', self.put('/applications', b""" self.assertIn('success', self.put('/applications', b"""
{ {
"ap\u0070": { "ap\u0070": {
"type": "\u0070ython", "type": "\u0070ython",
"workers": 1, "workers": 1,
"path": "\u002Fapp", "path": "\u002Fapp",
"module": "wsgi" "module": "wsgi"
} }
} }
"""), 'unicode') """), 'unicode')
self.assertIn('success', self.put('/applications', """ self.assertIn('success', self.put('/applications', """
{ {
"приложение": { "приложение": {
"type": "python", "type": "python",
"workers": 1, "workers": 1,
"path": "/app", "path": "/app",
"module": "wsgi" "module": "wsgi"
} }
} }
"""), 'unicode 2') """), 'unicode 2')
self.assertIn('error', self.put('/applications', b""" self.assertIn('error', self.put('/applications', b"""
{ {
"app": { "app": {
"type": "python", "type": "python",
"workers": \u0031, "workers": \u0031,
"path": "/app", "path": "/app",
"module": "wsgi" "module": "wsgi"
} }
} }
"""), 'unicode number') """), 'unicode number')
def test_json_listeners(self): def test_json_listeners(self):
self.assertTry('assertIn', 'listener empty', 'error', self.assertTry('assertIn', 'listener empty', 'error',
self.put('/listeners', '{"*:7080":{}}')) self.put('/listeners', '{"*:7080":{}}'))
self.assertIn('error', self.put('/listeners', self.assertIn('error', self.put('/listeners',
'{"*:7080":{"application":"app"}}'), 'listeners no app') '{"*:7080":{"application":"app"}}'), 'listeners no app')
self.put('/applications', """ self.put('/applications', """
{ {
"app": { "app": {
"type": "python", "type": "python",
"workers": 1, "workers": 1,
"path": "/app", "path": "/app",
"module": "wsgi" "module": "wsgi"
} }
} }
""") """)
self.assertIn('success', self.put('/listeners', self.assertIn('success', self.put('/listeners',
'{"*:7080":{"application":"app"}}'), 'listeners wildcard') '{"*:7080":{"application":"app"}}'), 'listeners wildcard')
self.assertIn('success', self.put('/listeners', self.assertIn('success', self.put('/listeners',
'{"127.0.0.1:7081":{"application":"app"}}'), 'listeners explicit') '{"127.0.0.1:7081":{"application":"app"}}'), 'listeners explicit')
self.assertIn('success', self.put('/listeners', self.assertIn('success', self.put('/listeners',
'{"[::1]:7082":{"application":"app"}}'), 'listeners explicit ipv6') '{"[::1]:7082":{"application":"app"}}'), 'listeners explicit ipv6')
self.assertIn('error', self.put('/listeners', self.assertIn('error', self.put('/listeners',
'{"127.0.0.1":{"application":"app"}}'), 'listeners no port') '{"127.0.0.1":{"application":"app"}}'), 'listeners no port')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@@ -1,166 +1,166 @@
import unittest import unittest
import unit import unit
class TestUnitBasic(unit.TestUnitControl): class TestUnitBasic(unit.TestUnitControl):
def setUpClass(): def setUpClass():
unit.TestUnit().check_modules('php') unit.TestUnit().check_modules('php')
def test_php_get(self): def test_php_get(self):
resp = self.get() resp = self.get()
self.assertEqual(resp, {'listeners': {}, 'applications': {}}, 'empty') self.assertEqual(resp, {'listeners': {}, 'applications': {}}, 'empty')
self.assertEqual(self.get('/listeners'), {}, 'empty listeners prefix') self.assertEqual(self.get('/listeners'), {}, 'empty listeners prefix')
self.assertEqual(self.get('/applications'), {}, self.assertEqual(self.get('/applications'), {},
'empty applications prefix') 'empty applications prefix')
self.put('/applications', """ self.put('/applications', """
{ {
"app": { "app": {
"type": "php", "type": "php",
"workers": 1, "workers": 1,
"root": "/app", "root": "/app",
"index": "index.php" "index": "index.php"
} }
} }
""") """)
resp = self.get() resp = self.get()
self.assertEqual(resp['listeners'], {}, 'php empty listeners') self.assertEqual(resp['listeners'], {}, 'php empty listeners')
self.assertEqual(resp['applications'], self.assertEqual(resp['applications'],
{ {
"app": { "app": {
"type": "php", "type": "php",
"workers": 1, "workers": 1,
"root": "/app", "root": "/app",
"index": "index.php" "index": "index.php"
} }
}, },
'php applications') 'php applications')
self.assertEqual(self.get('/applications'), self.assertEqual(self.get('/applications'),
{ {
"app": { "app": {
"type": "php", "type": "php",
"workers": 1, "workers": 1,
"root": "/app", "root": "/app",
"index": "index.php" "index": "index.php"
} }
}, },
'php applications prefix') 'php applications prefix')
self.assertEqual(self.get('/applications/app'), self.assertEqual(self.get('/applications/app'),
{ {
"type": "php", "type": "php",
"workers": 1, "workers": 1,
"root": "/app", "root": "/app",
"index": "index.php" "index": "index.php"
}, },
'php applications prefix 2') 'php applications prefix 2')
self.assertEqual(self.get('/applications/app/type'), 'php', self.assertEqual(self.get('/applications/app/type'), 'php',
'php applications type') 'php applications type')
self.assertEqual(self.get('/applications/app/workers'), 1, self.assertEqual(self.get('/applications/app/workers'), 1,
'php applications workers') 'php applications workers')
self.put('/listeners', '{"*:7080":{"application":"app"}}') self.put('/listeners', '{"*:7080":{"application":"app"}}')
self.assertEqual(self.get()['listeners'], self.assertEqual(self.get()['listeners'],
{"*:7080":{"application":"app"}}, 'php listeners') {"*:7080":{"application":"app"}}, 'php listeners')
self.assertEqual(self.get('/listeners'), self.assertEqual(self.get('/listeners'),
{"*:7080":{"application":"app"}}, 'php listeners prefix') {"*:7080":{"application":"app"}}, 'php listeners prefix')
self.assertEqual(self.get('/listeners/*:7080'), self.assertEqual(self.get('/listeners/*:7080'),
{"application":"app"}, 'php listeners prefix 2') {"application":"app"}, 'php listeners prefix 2')
self.assertEqual(self.get('/listeners/*:7080/application'), 'app', self.assertEqual(self.get('/listeners/*:7080/application'), 'app',
'php listeners application') 'php listeners application')
def test_php_put(self): def test_php_put(self):
self.put('/', """ self.put('/', """
{ {
"listeners": { "listeners": {
"*:7080": { "*:7080": {
"application": "app" "application": "app"
} }
}, },
"applications": { "applications": {
"app": { "app": {
"type": "php", "type": "php",
"workers": 1, "workers": 1,
"root": "/app", "root": "/app",
"index": "index.php" "index": "index.php"
} }
} }
} }
""") """)
resp = self.get() resp = self.get()
self.assertEqual(resp['listeners'], {"*:7080":{"application":"app"}}, self.assertEqual(resp['listeners'], {"*:7080":{"application":"app"}},
'put listeners') 'put listeners')
self.assertEqual(resp['applications'], self.assertEqual(resp['applications'],
{ {
"app": { "app": {
"type": "php", "type": "php",
"workers": 1, "workers": 1,
"root": "/app", "root": "/app",
"index": "index.php" "index": "index.php"
} }
}, },
'put applications') 'put applications')
self.put('/listeners', '{"*:7081":{"application":"app"}}') self.put('/listeners', '{"*:7081":{"application":"app"}}')
self.assertEqual(self.get('/listeners'), self.assertEqual(self.get('/listeners'),
{"*:7081": {"application":"app"}}, 'put listeners prefix') {"*:7081": {"application":"app"}}, 'put listeners prefix')
self.put('/listeners/*:7082', '{"application":"app"}') self.put('/listeners/*:7082', '{"application":"app"}')
self.assertEqual(self.get('/listeners'), self.assertEqual(self.get('/listeners'),
{ {
"*:7081": { "*:7081": {
"application": "app" "application": "app"
}, },
"*:7082": { "*:7082": {
"application": "app" "application": "app"
} }
}, },
'put listeners prefix 3') 'put listeners prefix 3')
self.put('/applications/app/workers', '30') self.put('/applications/app/workers', '30')
self.assertEqual(self.get('/applications/app/workers'), 30, self.assertEqual(self.get('/applications/app/workers'), 30,
'put applications workers') 'put applications workers')
self.put('/applications/app/root', '"/www"') self.put('/applications/app/root', '"/www"')
self.assertEqual(self.get('/applications/app/root'), '/www', self.assertEqual(self.get('/applications/app/root'), '/www',
'put applications root') 'put applications root')
def test_php_delete(self): def test_php_delete(self):
self.put('/', """ self.put('/', """
{ {
"listeners": { "listeners": {
"*:7080": { "*:7080": {
"application": "app" "application": "app"
} }
}, },
"applications": { "applications": {
"app": { "app": {
"type": "php", "type": "php",
"workers": 1, "workers": 1,
"root": "/app", "root": "/app",
"index": "index.php" "index": "index.php"
} }
} }
} }
""") """)
self.assertIn('error', self.delete('/applications/app'), self.assertIn('error', self.delete('/applications/app'),
'delete app before listener') 'delete app before listener')
self.assertIn('success', self.delete('/listeners/*:7080'), self.assertIn('success', self.delete('/listeners/*:7080'),
'delete listener') 'delete listener')
self.assertIn('success', self.delete('/applications/app'), self.assertIn('success', self.delete('/applications/app'),
'delete app after listener') 'delete app after listener')
self.assertIn('error', self.delete('/applications/app'), self.assertIn('error', self.delete('/applications/app'),
'delete app again') 'delete app again')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@@ -1,90 +1,90 @@
import unittest import unittest
import unit import unit
class TestUnitApplication(unit.TestUnitControl): class TestUnitApplication(unit.TestUnitControl):
def setUpClass(): def setUpClass():
u = unit.TestUnit() u = unit.TestUnit()
u.check_modules('python') u.check_modules('python')
u.check_version('0.4') u.check_version('0.4')
def test_python_application(self): def test_python_application(self):
code, name = """ code, name = """
def application(environ, start_response): def application(environ, start_response):
content_length = int(environ.get('CONTENT_LENGTH', 0)) content_length = int(environ.get('CONTENT_LENGTH', 0))
body = bytes(environ['wsgi.input'].read(content_length)) body = bytes(environ['wsgi.input'].read(content_length))
start_response('200 OK', [ start_response('200 OK', [
('Content-Type', environ.get('CONTENT_TYPE')), ('Content-Type', environ.get('CONTENT_TYPE')),
('Content-Length', str(len(body))), ('Content-Length', str(len(body))),
('Request-Method', environ.get('REQUEST_METHOD')), ('Request-Method', environ.get('REQUEST_METHOD')),
('Request-Uri', environ.get('REQUEST_URI')), ('Request-Uri', environ.get('REQUEST_URI')),
('Path-Info', environ.get('PATH_INFO')), ('Path-Info', environ.get('PATH_INFO')),
('Http-Host', environ.get('HTTP_HOST')), ('Http-Host', environ.get('HTTP_HOST')),
('Remote-Addr', environ.get('REMOTE_ADDR')), ('Remote-Addr', environ.get('REMOTE_ADDR')),
('Server-Name', environ.get('SERVER_NAME')), ('Server-Name', environ.get('SERVER_NAME')),
('Server-Port', environ.get('SERVER_PORT')), ('Server-Port', environ.get('SERVER_PORT')),
('Server-Protocol', environ.get('SERVER_PROTOCOL')), ('Server-Protocol', environ.get('SERVER_PROTOCOL')),
('Custom-Header', environ.get('HTTP_CUSTOM_HEADER')) ('Custom-Header', environ.get('HTTP_CUSTOM_HEADER'))
]) ])
return [body] return [body]
""", 'py_app' """, 'py_app'
self.python_application(name, code) self.python_application(name, code)
self.put('/', """ self.put('/', """
{ {
"listeners": { "listeners": {
"*:7080": { "*:7080": {
"application": "app" "application": "app"
} }
}, },
"applications": { "applications": {
"app": { "app": {
"type": "python", "type": "python",
"workers": 1, "workers": 1,
"path": "%s", "path": "%s",
"module": "wsgi" "module": "wsgi"
} }
} }
} }
""" % (self.testdir + '/' + name)) """ % (self.testdir + '/' + name))
body = 'Test body string.' body = 'Test body string.'
r = unit.TestUnitHTTP.post(headers={ r = unit.TestUnitHTTP.post(headers={
'Host': 'localhost', 'Host': 'localhost',
'Content-Type': 'text/html', 'Content-Type': 'text/html',
'Custom-Header': 'blah' 'Custom-Header': 'blah'
}, data=body) }, data=body)
self.assertEqual(r.status_code, 200, 'status') self.assertEqual(r.status_code, 200, 'status')
self.assertEqual(r.headers['Content-Length'], str(len(body)), self.assertEqual(r.headers['Content-Length'], str(len(body)),
'header content length') 'header content length')
self.assertEqual(r.headers['Content-Type'], 'text/html', self.assertEqual(r.headers['Content-Type'], 'text/html',
'header content type') 'header content type')
self.assertEqual(r.headers['Request-Method'], 'POST', self.assertEqual(r.headers['Request-Method'], 'POST',
'header request method') 'header request method')
self.assertEqual(r.headers['Request-Uri'], '/', 'header request uri') self.assertEqual(r.headers['Request-Uri'], '/', 'header request uri')
self.assertEqual(r.headers['Path-Info'], '/', 'header path info') self.assertEqual(r.headers['Path-Info'], '/', 'header path info')
self.assertEqual(r.headers['Http-Host'], 'localhost', self.assertEqual(r.headers['Http-Host'], 'localhost',
'header http host') 'header http host')
self.assertEqual(r.headers['Remote-Addr'], '127.0.0.1', self.assertEqual(r.headers['Remote-Addr'], '127.0.0.1',
'header remote addr') 'header remote addr')
self.assertTry('assertEqual', 'header server port', self.assertTry('assertEqual', 'header server port',
r.headers['Server-Port'], '7080') r.headers['Server-Port'], '7080')
self.assertEqual(r.headers['Server-Protocol'], 'HTTP/1.1', self.assertEqual(r.headers['Server-Protocol'], 'HTTP/1.1',
'header server protocol') 'header server protocol')
self.assertEqual(r.headers['Custom-Header'], 'blah', self.assertEqual(r.headers['Custom-Header'], 'blah',
'header custom header') 'header custom header')
self.assertEqual(r.content, str.encode(body), 'body') self.assertEqual(r.content, str.encode(body), 'body')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@@ -1,65 +1,65 @@
import os import os
import time import time
import unittest import unittest
import unit import unit
class TestUnitApplication(unit.TestUnitControl): class TestUnitApplication(unit.TestUnitControl):
def setUpClass(): def setUpClass():
u = unit.TestUnit() u = unit.TestUnit()
u.check_modules('python') u.check_modules('python')
u.check_version('0.3') u.check_version('0.3')
def test_python_application(self): def test_python_application(self):
code, name = """ code, name = """
import atexit import atexit
def create_file(): def create_file():
open('%s', 'w') open('%s', 'w')
atexit.register(create_file) atexit.register(create_file)
def application(env, start_response): def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')]) start_response('200 OK', [('Content-Type','text/html')])
return [b'body'] return [b'body']
""" % (self.testdir + '/atexit'), 'py_app' """ % (self.testdir + '/atexit'), 'py_app'
self.python_application(name, code) self.python_application(name, code)
self.put('/', """ self.put('/', """
{ {
"listeners": { "listeners": {
"*:7080": { "*:7080": {
"application": "app" "application": "app"
} }
}, },
"applications": { "applications": {
"app": { "app": {
"type": "python", "type": "python",
"workers": 1, "workers": 1,
"path": "%s", "path": "%s",
"module": "wsgi" "module": "wsgi"
} }
} }
} }
""" % (self.testdir + '/' + name)) """ % (self.testdir + '/' + name))
unit.TestUnitHTTP.get() unit.TestUnitHTTP.get()
self.put('/', """ self.put('/', """
{ {
"listeners": {}, "listeners": {},
"applications": {} "applications": {}
} }
""") """)
time.sleep(0.2) time.sleep(0.2)
self.assertEqual(os.path.exists(self.testdir + '/atexit'), True, self.assertEqual(os.path.exists(self.testdir + '/atexit'), True,
'python atexit') 'python atexit')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@@ -1,166 +1,166 @@
import unittest import unittest
import unit import unit
class TestUnitBasic(unit.TestUnitControl): class TestUnitBasic(unit.TestUnitControl):
def setUpClass(): def setUpClass():
unit.TestUnit().check_modules('python') unit.TestUnit().check_modules('python')
def test_python_get(self): def test_python_get(self):
resp = self.get() resp = self.get()
self.assertEqual(resp, {'listeners': {}, 'applications': {}}, 'empty') self.assertEqual(resp, {'listeners': {}, 'applications': {}}, 'empty')
self.assertEqual(self.get('/listeners'), {}, 'empty listeners prefix') self.assertEqual(self.get('/listeners'), {}, 'empty listeners prefix')
self.assertEqual(self.get('/applications'), {}, self.assertEqual(self.get('/applications'), {},
'empty applications prefix') 'empty applications prefix')
self.put('/applications', """ self.put('/applications', """
{ {
"app": { "app": {
"type": "python", "type": "python",
"workers": 1, "workers": 1,
"path": "/app", "path": "/app",
"module": "wsgi" "module": "wsgi"
} }
} }
""") """)
resp = self.get() resp = self.get()
self.assertEqual(resp['listeners'], {}, 'python empty listeners') self.assertEqual(resp['listeners'], {}, 'python empty listeners')
self.assertEqual(resp['applications'], self.assertEqual(resp['applications'],
{ {
"app": { "app": {
"type": "python", "type": "python",
"workers": 1, "workers": 1,
"path": "/app", "path": "/app",
"module": "wsgi" "module": "wsgi"
} }
}, },
'python applications') 'python applications')
self.assertEqual(self.get('/applications'), self.assertEqual(self.get('/applications'),
{ {
"app": { "app": {
"type": "python", "type": "python",
"workers": 1, "workers": 1,
"path": "/app", "path": "/app",
"module":"wsgi" "module":"wsgi"
} }
}, },
'python applications prefix') 'python applications prefix')
self.assertEqual(self.get('/applications/app'), self.assertEqual(self.get('/applications/app'),
{ {
"type": "python", "type": "python",
"workers": 1, "workers": 1,
"path": "/app", "path": "/app",
"module": "wsgi" "module": "wsgi"
}, },
'python applications prefix 2') 'python applications prefix 2')
self.assertEqual(self.get('/applications/app/type'), 'python', self.assertEqual(self.get('/applications/app/type'), 'python',
'python applications type') 'python applications type')
self.assertEqual(self.get('/applications/app/workers'), 1, self.assertEqual(self.get('/applications/app/workers'), 1,
'python applications workers') 'python applications workers')
self.put('/listeners', '{"*:7080":{"application":"app"}}') self.put('/listeners', '{"*:7080":{"application":"app"}}')
self.assertEqual(self.get()['listeners'], self.assertEqual(self.get()['listeners'],
{"*:7080":{"application":"app"}}, 'python listeners') {"*:7080":{"application":"app"}}, 'python listeners')
self.assertEqual(self.get('/listeners'), self.assertEqual(self.get('/listeners'),
{"*:7080":{"application":"app"}}, 'python listeners prefix') {"*:7080":{"application":"app"}}, 'python listeners prefix')
self.assertEqual(self.get('/listeners/*:7080'), self.assertEqual(self.get('/listeners/*:7080'),
{"application":"app"}, 'python listeners prefix 2') {"application":"app"}, 'python listeners prefix 2')
self.assertEqual(self.get('/listeners/*:7080/application'), 'app', self.assertEqual(self.get('/listeners/*:7080/application'), 'app',
'python listeners application') 'python listeners application')
def test_python_put(self): def test_python_put(self):
self.put('/', """ self.put('/', """
{ {
"listeners": { "listeners": {
"*:7080": { "*:7080": {
"application": "app" "application": "app"
} }
}, },
"applications": { "applications": {
"app": { "app": {
"type": "python", "type": "python",
"workers": 1, "workers": 1,
"path": "/app", "path": "/app",
"module": "wsgi" "module": "wsgi"
} }
} }
} }
""") """)
resp = self.get() resp = self.get()
self.assertEqual(resp['listeners'], {"*:7080":{"application":"app"}}, self.assertEqual(resp['listeners'], {"*:7080":{"application":"app"}},
'put listeners') 'put listeners')
self.assertEqual(resp['applications'], self.assertEqual(resp['applications'],
{ {
"app": { "app": {
"type": "python", "type": "python",
"workers": 1, "workers": 1,
"path": "/app", "path": "/app",
"module": "wsgi" "module": "wsgi"
} }
}, },
'put applications') 'put applications')
self.put('/listeners', '{"*:7081":{"application":"app"}}') self.put('/listeners', '{"*:7081":{"application":"app"}}')
self.assertEqual(self.get('/listeners'), self.assertEqual(self.get('/listeners'),
{"*:7081": {"application":"app"}}, 'put listeners prefix') {"*:7081": {"application":"app"}}, 'put listeners prefix')
self.put('/listeners/*:7082', '{"application":"app"}') self.put('/listeners/*:7082', '{"application":"app"}')
self.assertEqual(self.get('/listeners'), self.assertEqual(self.get('/listeners'),
{ {
"*:7081": { "*:7081": {
"application": "app" "application": "app"
}, },
"*:7082": { "*:7082": {
"application": "app" "application": "app"
} }
}, },
'put listeners prefix 3') 'put listeners prefix 3')
self.put('/applications/app/workers', '30') self.put('/applications/app/workers', '30')
self.assertEqual(self.get('/applications/app/workers'), 30, self.assertEqual(self.get('/applications/app/workers'), 30,
'put applications workers') 'put applications workers')
self.put('/applications/app/path', '"/www"') self.put('/applications/app/path', '"/www"')
self.assertEqual(self.get('/applications/app/path'), '/www', self.assertEqual(self.get('/applications/app/path'), '/www',
'put applications path') 'put applications path')
def test_python_delete(self): def test_python_delete(self):
self.put('/', """ self.put('/', """
{ {
"listeners": { "listeners": {
"*:7080": { "*:7080": {
"application": "app" "application": "app"
} }
}, },
"applications": { "applications": {
"app": { "app": {
"type": "python", "type": "python",
"workers": 1, "workers": 1,
"path": "/app", "path": "/app",
"module": "wsgi" "module": "wsgi"
} }
} }
} }
""") """)
self.assertIn('error', self.delete('/applications/app'), self.assertIn('error', self.delete('/applications/app'),
'delete app before listener') 'delete app before listener')
self.assertIn('success', self.delete('/listeners/*:7080'), self.assertIn('success', self.delete('/listeners/*:7080'),
'delete listener') 'delete listener')
self.assertIn('success', self.delete('/applications/app'), self.assertIn('success', self.delete('/applications/app'),
'delete app after listener') 'delete app after listener')
self.assertIn('error', self.delete('/applications/app'), self.assertIn('error', self.delete('/applications/app'),
'delete app again') 'delete app again')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@@ -1,236 +1,236 @@
import os import os
import re import re
import sys import sys
import json import json
import time import time
import shutil import shutil
import socket import socket
import tempfile import tempfile
import unittest import unittest
from requests import Request, Session from requests import Request, Session
from subprocess import call from subprocess import call
from multiprocessing import Process from multiprocessing import Process
class TestUnit(unittest.TestCase): class TestUnit(unittest.TestCase):
pardir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) pardir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
def setUp(self): def setUp(self):
self._run() self._run()
def tearDown(self): def tearDown(self):
self._stop() self._stop()
if '--log' in sys.argv: if '--log' in sys.argv:
with open(self.testdir + '/unit.log', 'r') as f: with open(self.testdir + '/unit.log', 'r') as f:
print(f.read()) print(f.read())
if '--leave' not in sys.argv: if '--leave' not in sys.argv:
shutil.rmtree(self.testdir) shutil.rmtree(self.testdir)
def assertTry(self, assert_method, description, *args): def assertTry(self, assert_method, description, *args):
try: getattr(self, assert_method)(*args, msg=description) try: getattr(self, assert_method)(*args, msg=description)
except AssertionError: print('not yet: ' + description) except AssertionError: print('not yet: ' + description)
def check_modules(self, *modules): def check_modules(self, *modules):
self._run() self._run()
for i in range(50): for i in range(50):
with open(self.testdir + '/unit.log', 'r') as f: with open(self.testdir + '/unit.log', 'r') as f:
log = f.read() log = f.read()
m = re.search('controller started', log, re.M | re.S) m = re.search('controller started', log, re.M | re.S)
if m is None: if m is None:
time.sleep(0.1) time.sleep(0.1)
else: else:
break break
if m is None: if m is None:
exit("Unit is writing log too long") exit("Unit is writing log too long")
missed_module = '' missed_module = ''
for module in modules: for module in modules:
m = re.search('module: ' + module, log, re.M | re.S) m = re.search('module: ' + module, log, re.M | re.S)
if m is None: if m is None:
missed_module = module missed_module = module
break break
self._stop() self._stop()
shutil.rmtree(self.testdir) shutil.rmtree(self.testdir)
if missed_module: if missed_module:
raise unittest.SkipTest('Unit has no ' + missed_module + ' module') raise unittest.SkipTest('Unit has no ' + missed_module + ' module')
def check_version(self, version): def check_version(self, version):
with open(self.pardir + '/src/nxt_main.h' , 'r') as f: with open(self.pardir + '/src/nxt_main.h' , 'r') as f:
m = re.search('NXT_VERSION\s+"(\d+\.\d+)"', f.read(), re.M | re.S) m = re.search('NXT_VERSION\s+"(\d+\.\d+)"', f.read(), re.M | re.S)
current = m.group(1).split('.') current = m.group(1).split('.')
need = version.split('.') need = version.split('.')
for i in range(len(need)): for i in range(len(need)):
if need[i] > current[i]: if need[i] > current[i]:
raise unittest.SkipTest('Unit too old') raise unittest.SkipTest('Unit too old')
def _run(self): def _run(self):
self.testdir = tempfile.mkdtemp(prefix='unit-test-') self.testdir = tempfile.mkdtemp(prefix='unit-test-')
os.mkdir(self.testdir + '/state') os.mkdir(self.testdir + '/state')
print() print()
def _run_unit(): def _run_unit():
call([self.pardir + '/build/unitd', call([self.pardir + '/build/unitd',
'--no-daemon', '--no-daemon',
'--modules', self.pardir + '/build', '--modules', self.pardir + '/build',
'--state', self.testdir + '/state', '--state', self.testdir + '/state',
'--pid', self.testdir + '/unit.pid', '--pid', self.testdir + '/unit.pid',
'--log', self.testdir + '/unit.log', '--log', self.testdir + '/unit.log',
'--control', 'unix:' + self.testdir + '/control.unit.sock']) '--control', 'unix:' + self.testdir + '/control.unit.sock'])
self._p = Process(target=_run_unit) self._p = Process(target=_run_unit)
self._p.start() self._p.start()
if not self._waitforfiles(self.testdir + '/unit.pid', if not self._waitforfiles(self.testdir + '/unit.pid',
self.testdir + '/unit.log', self.testdir + '/control.unit.sock'): self.testdir + '/unit.log', self.testdir + '/control.unit.sock'):
exit("Could not start unit") exit("Could not start unit")
def python_application(self, name, code): def python_application(self, name, code):
os.mkdir(self.testdir + '/' + name) os.mkdir(self.testdir + '/' + name)
with open(self.testdir + '/' + name + '/wsgi.py', 'w') as f: with open(self.testdir + '/' + name + '/wsgi.py', 'w') as f:
f.write(code) f.write(code)
def _stop(self): def _stop(self):
with open(self.testdir + '/unit.pid', 'r') as f: with open(self.testdir + '/unit.pid', 'r') as f:
pid = f.read().rstrip() pid = f.read().rstrip()
call(['kill', pid]) call(['kill', pid])
for i in range(50): for i in range(50):
if not os.path.exists(self.testdir + '/unit.pid'): if not os.path.exists(self.testdir + '/unit.pid'):
break break
time.sleep(0.1) time.sleep(0.1)
if os.path.exists(self.testdir + '/unit.pid'): if os.path.exists(self.testdir + '/unit.pid'):
exit("Could not terminate unit") exit("Could not terminate unit")
self._p.join(timeout=1) self._p.join(timeout=1)
self._terminate_process(self._p) self._terminate_process(self._p)
def _terminate_process(self, process): def _terminate_process(self, process):
if process.is_alive(): if process.is_alive():
process.terminate() process.terminate()
process.join(timeout=5) process.join(timeout=5)
if process.is_alive(): if process.is_alive():
exit("Could not terminate process " + process.pid) exit("Could not terminate process " + process.pid)
if process.exitcode: if process.exitcode:
exit("Child process terminated with code " + str(process.exitcode)) exit("Child process terminated with code " + str(process.exitcode))
def _waitforfiles(self, *files): def _waitforfiles(self, *files):
for i in range(50): for i in range(50):
wait = False wait = False
ret = 0 ret = 0
for f in files: for f in files:
if not os.path.exists(f): if not os.path.exists(f):
wait = True wait = True
break break
if wait: if wait:
time.sleep(0.1) time.sleep(0.1)
else: else:
ret = 1 ret = 1
break break
return ret return ret
class TestUnitControl(TestUnit): class TestUnitControl(TestUnit):
# TODO socket reuse # TODO socket reuse
# TODO http client # TODO http client
def http(self, req): def http(self, req):
with self._control_sock() as sock: with self._control_sock() as sock:
sock.sendall(req) sock.sendall(req)
if '--verbose' in sys.argv: if '--verbose' in sys.argv:
print('>>>', req, sep='\n') print('>>>', req, sep='\n')
resp = self._recvall(sock) resp = self._recvall(sock)
if '--verbose' in sys.argv: if '--verbose' in sys.argv:
print('<<<', resp, sep='\n') print('<<<', resp, sep='\n')
return resp return resp
def get(self, path='/'): def get(self, path='/'):
resp = self.http(('GET ' + path resp = self.http(('GET ' + path
+ ' HTTP/1.1\r\nHost: localhost\r\n\r\n').encode()) + ' HTTP/1.1\r\nHost: localhost\r\n\r\n').encode())
return self._body_json(resp) return self._body_json(resp)
def delete(self, path='/'): def delete(self, path='/'):
resp = self.http(('DELETE ' + path resp = self.http(('DELETE ' + path
+ ' HTTP/1.1\r\nHost: localhost\r\n\r\n').encode()) + ' HTTP/1.1\r\nHost: localhost\r\n\r\n').encode())
return self._body_json(resp) return self._body_json(resp)
def put(self, path='/', data=''): def put(self, path='/', data=''):
if isinstance(data, str): if isinstance(data, str):
data = data.encode() data = data.encode()
resp = self.http(('PUT ' + path + ' HTTP/1.1\nHost: localhost\n' resp = self.http(('PUT ' + path + ' HTTP/1.1\nHost: localhost\n'
+ 'Content-Length: ' + str(len(data)) + 'Content-Length: ' + str(len(data))
+ '\r\n\r\n').encode() + data) + '\r\n\r\n').encode() + data)
return self._body_json(resp) return self._body_json(resp)
def _control_sock(self): def _control_sock(self):
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(self.testdir + '/control.unit.sock') sock.connect(self.testdir + '/control.unit.sock')
return sock return sock
def _recvall(self, sock, buff_size=4096): def _recvall(self, sock, buff_size=4096):
data = '' data = ''
while True: while True:
part = sock.recv(buff_size).decode() part = sock.recv(buff_size).decode()
data += part data += part
if len(part) < buff_size: if len(part) < buff_size:
break break
return data return data
def _body_json(self, resp): def _body_json(self, resp):
m = re.search('.*?\x0d\x0a?\x0d\x0a?(.*)', resp, re.M | re.S) m = re.search('.*?\x0d\x0a?\x0d\x0a?(.*)', resp, re.M | re.S)
return json.loads(m.group(1)) return json.loads(m.group(1))
class TestUnitHTTP(): class TestUnitHTTP():
@classmethod @classmethod
def http(self, method, **kwargs): def http(self, method, **kwargs):
host = '127.0.0.1:7080' if 'host' not in kwargs else kwargs['host'] host = '127.0.0.1:7080' if 'host' not in kwargs else kwargs['host']
uri = '/' if 'uri' not in kwargs else kwargs['uri'] uri = '/' if 'uri' not in kwargs else kwargs['uri']
sess = Session() if 'sess' not in kwargs else kwargs['sess'] sess = Session() if 'sess' not in kwargs else kwargs['sess']
data = None if 'data' not in kwargs else kwargs['data'] data = None if 'data' not in kwargs else kwargs['data']
headers = None if 'headers' not in kwargs else kwargs['headers'] headers = None if 'headers' not in kwargs else kwargs['headers']
req = Request(method, 'http://' + host + uri, data=data, req = Request(method, 'http://' + host + uri, data=data,
headers=headers) headers=headers)
r = sess.send(req.prepare()) r = sess.send(req.prepare())
if 'keep' not in kwargs: if 'keep' not in kwargs:
sess.close() sess.close()
return r return r
return (r, sess) return (r, sess)
def get(**kwargs): def get(**kwargs):
return TestUnitHTTP.http('GET', **kwargs) return TestUnitHTTP.http('GET', **kwargs)
def post(**kwargs): def post(**kwargs):
return TestUnitHTTP.http('POST', **kwargs) return TestUnitHTTP.http('POST', **kwargs)