Tests: fixed tests to run as root.

- The mode of testdir was changed to allow reading from other users/groups.
- The java multipart test now uploads the file into an app writable dir.
- The build directory was made readable for other users.
- The python environment test now uses the HOME env var instead of PWD
  because the latter is not set by the root shell (/bin/sh) by default.
- The node `node_modules` directory now is copied into the `testdir` instead
  of using symlinks.
This commit is contained in:
Tiago Natel
2019-11-09 20:14:52 +00:00
parent 94a9162baa
commit 19b974674c
5 changed files with 72 additions and 25 deletions

View File

@@ -1,4 +1,5 @@
import os import pwd
import grp
import json import json
import unittest import unittest
from unit.applications.lang.go import TestApplicationGo from unit.applications.lang.go import TestApplicationGo
@@ -45,38 +46,50 @@ class TestGoIsolation(TestApplicationGo):
raise unittest.SkipTest() raise unittest.SkipTest()
self.load('ns_inspect') self.load('ns_inspect')
user_id = pwd.getpwnam('nobody').pw_uid
try:
group_id = grp.getgrnam('nogroup').gr_gid
except:
group_id = grp.getgrnam('nobody').gr_gid
obj = self.isolation.parsejson(self.get()['body']) obj = self.isolation.parsejson(self.get()['body'])
self.assertTrue(obj['UID'] != 0, 'uid not zero') self.assertTrue(obj['UID'] != 0, 'uid not zero')
self.assertTrue(obj['GID'] != 0, 'gid not zero') self.assertTrue(obj['GID'] != 0, 'gid not zero')
self.assertEqual(obj['UID'], os.getuid(), 'uid match')
self.assertEqual(obj['GID'], os.getgid(), 'gid match') if self.is_su:
self.assertEqual(obj['UID'], user_id, 'uid match')
self.assertEqual(obj['GID'], group_id, 'gid match')
else:
self.assertEqual(obj['UID'], self.uid, 'uid match')
self.assertEqual(obj['GID'], self.gid, 'gid match')
self.conf_isolation({"namespaces": {"credential": True}}) self.conf_isolation({"namespaces": {"credential": True}})
obj = self.isolation.parsejson(self.get()['body']) obj = self.isolation.parsejson(self.get()['body'])
# default uid and gid maps current user to nobody # default uid and gid maps current user to nobody
self.assertEqual(obj['UID'], 65534, 'uid nobody') self.assertEqual(obj['UID'], user_id, 'uid nobody')
self.assertEqual(obj['GID'], 65534, 'gid nobody') self.assertEqual(obj['GID'], group_id, 'gid nobody')
self.conf_isolation( self.conf_isolation(
{ {
"namespaces": {"credential": True}, "namespaces": {"credential": True},
"uidmap": [ "uidmap": [
{"container": 1000, "host": os.geteuid(), "size": 1} {"container": user_id, "host": self.uid, "size": 1}
], ],
"gidmap": [ "gidmap": [
{"container": 1000, "host": os.getegid(), "size": 1} {"container": group_id, "host": self.gid, "size": 1}
], ],
} }
) )
obj = self.isolation.parsejson(self.get()['body']) obj = self.isolation.parsejson(self.get()['body'])
# default uid and gid maps current user to root self.assertEqual(obj['UID'], user_id, 'uid match')
self.assertEqual(obj['UID'], 1000, 'uid root') self.assertEqual(obj['GID'], group_id, 'gid match')
self.assertEqual(obj['GID'], 1000, 'gid root')
def test_isolation_mnt(self): def test_isolation_mnt(self):
if not self.isolation_key('mnt'): if not self.isolation_key('mnt'):

View File

@@ -1,3 +1,4 @@
import os
import time import time
import unittest import unittest
from unit.applications.lang.java import TestApplicationJava from unit.applications.lang.java import TestApplicationJava
@@ -1217,7 +1218,13 @@ class TestJavaApplication(TestApplicationJava):
def test_java_application_multipart(self): def test_java_application_multipart(self):
self.load('multipart') self.load('multipart')
body = """Preamble. Should be ignored.\r reldst = '/uploads'
fulldst = self.testdir + reldst
os.mkdir(fulldst)
self.public_dir(fulldst)
body = (
"""Preamble. Should be ignored.\r
\r \r
--12345\r --12345\r
Content-Disposition: form-data; name="file"; filename="sample.txt"\r Content-Disposition: form-data; name="file"; filename="sample.txt"\r
@@ -1234,7 +1241,9 @@ Content-Disposition: form-data; name="upload"\r
Upload\r Upload\r
--12345--\r --12345--\r
\r \r
Epilogue. Should be ignored.""" % self.testdir Epilogue. Should be ignored."""
% fulldst
)
resp = self.post( resp = self.post(
headers={ headers={
@@ -1246,9 +1255,13 @@ Epilogue. Should be ignored.""" % self.testdir
) )
self.assertEqual(resp['status'], 200, 'multipart status') self.assertEqual(resp['status'], 200, 'multipart status')
self.assertRegex(resp['body'], r'sample\.txt created', 'multipart body') self.assertRegex(
resp['body'], r'sample\.txt created', 'multipart body'
)
self.assertIsNotNone( self.assertIsNotNone(
self.search_in_log(r'^Data from sample file$', name='sample.txt'), self.search_in_log(
r'^Data from sample file$', name=reldst + '/sample.txt'
),
'file created', 'file created',
) )

View File

@@ -136,27 +136,27 @@ class TestPythonEnvironment(TestApplicationPython):
def test_python_environment_replace_default(self): def test_python_environment_replace_default(self):
self.load('environment') self.load('environment')
pwd_default = self.get( home_default = self.get(
headers={ headers={
'Host': 'localhost', 'Host': 'localhost',
'X-Variables': 'PWD', 'X-Variables': 'HOME',
'Connection': 'close', 'Connection': 'close',
} }
)['body'] )['body']
self.assertGreater(len(pwd_default), 1, 'get default') self.assertGreater(len(home_default), 1, 'get default')
self.conf({"PWD": "new/pwd"}, 'applications/environment/environment') self.conf({"HOME": "/"}, 'applications/environment/environment')
self.assertEqual( self.assertEqual(
self.get( self.get(
headers={ headers={
'Host': 'localhost', 'Host': 'localhost',
'X-Variables': 'PWD', 'X-Variables': 'HOME',
'Connection': 'close', 'Connection': 'close',
} }
)['body'], )['body'],
'new/pwd,', '/,',
'replace default', 'replace default',
) )
@@ -166,11 +166,11 @@ class TestPythonEnvironment(TestApplicationPython):
self.get( self.get(
headers={ headers={
'Host': 'localhost', 'Host': 'localhost',
'X-Variables': 'PWD', 'X-Variables': 'HOME',
'Connection': 'close', 'Connection': 'close',
} }
)['body'], )['body'],
pwd_default, home_default,
'restore default', 'restore default',
) )

View File

@@ -22,13 +22,15 @@ class TestApplicationNode(TestApplicationProto):
self.current_dir + '/node/' + script, self.testdir + '/node' self.current_dir + '/node/' + script, self.testdir + '/node'
) )
# link modules # copy modules
os.symlink( shutil.copytree(
self.pardir + '/node/node_modules', self.pardir + '/node/node_modules',
self.testdir + '/node/node_modules', self.testdir + '/node/node_modules',
) )
self.public_dir(self.testdir + '/node')
self._load_conf( self._load_conf(
{ {
"listeners": {"*:7080": {"pass": "applications/" + script}}, "listeners": {"*:7080": {"pass": "applications/" + script}},

View File

@@ -1,6 +1,7 @@
import os import os
import re import re
import sys import sys
import stat
import time import time
import fcntl import fcntl
import shutil import shutil
@@ -20,6 +21,9 @@ class TestUnit(unittest.TestCase):
pardir = os.path.abspath( pardir = os.path.abspath(
os.path.join(os.path.dirname(__file__), os.pardir, os.pardir) 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] architecture = platform.architecture()[0]
system = platform.system() system = platform.system()
maxDiff = None maxDiff = None
@@ -188,13 +192,19 @@ class TestUnit(unittest.TestCase):
self.stop_processes() self.stop_processes()
def _run(self): 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): if not os.path.isfile(self.unitd):
exit("Could not find unit") exit("Could not find unit")
self.testdir = tempfile.mkdtemp(prefix='unit-test-') 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') os.mkdir(self.testdir + '/state')
print() print()
@@ -328,6 +338,15 @@ class TestUnit(unittest.TestCase):
return ret 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 @staticmethod
def _parse_args(): def _parse_args():
parser = argparse.ArgumentParser(add_help=False) parser = argparse.ArgumentParser(add_help=False)