1#!/usr/bin/env python3 2# 3# Copyright (C) 2008 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import os 18import shutil 19import tempfile 20import unittest 21 22import nsjail 23 24 25class TestMountPt(unittest.TestCase): 26 def test_requires_kwargs(self): 27 self.assertRaises(AssertionError, nsjail.MountPt, 0) 28 29 def test_args(self): 30 """Test arguments.""" 31 # Test string values. src and dst must be absolute paths. 32 for name in "src", "dst": 33 with self.subTest(arg=name): 34 path = os.path.abspath(name) 35 mnt = nsjail.MountPt(**{name: path}) 36 self.assertEqual(str(mnt), 37 f'mount {{\n {name}: "{path}"\n}}\n\n') 38 39 # The rest of the string arguments do not care as much. 40 for name in ("prefix_src_env", "src_content", "prefix_dst_env", 41 "fstype", "options"): 42 with self.subTest(arg=name): 43 mnt = nsjail.MountPt(**{name: name}) 44 self.assertEqual(str(mnt), 45 f'mount {{\n {name}: "{name}"\n}}\n\n') 46 47 # Test the booleans with both True and False. 48 for name in ("is_bind", "rw", "is_dir", "mandatory", "is_symlink", 49 "nosuid", "nodev", "noexec"): 50 with self.subTest(arg=name, value=True): 51 mnt = nsjail.MountPt(**{name: True}) 52 self.assertEqual(str(mnt), f'mount {{\n {name}: true\n}}\n\n') 53 with self.subTest(arg=name, value=False): 54 mnt = nsjail.MountPt(**{name: False}) 55 self.assertEqual(str(mnt), 56 f'mount {{\n {name}: false\n}}\n\n') 57 58 def test_absolute_paths(self): 59 """Test that src and dst must be absolute paths.""" 60 with self.assertRaises(AssertionError): 61 nsjail.MountPt(src="src") 62 with self.assertRaises(AssertionError): 63 nsjail.MountPt(dst="dst") 64 65 66class TestNsjail(unittest.TestCase): 67 def setUp(self): 68 self.test_dir = tempfile.mkdtemp() 69 self.cfg = nsjail.Nsjail(self.test_dir) 70 self.cfg_name = os.path.join(self.test_dir, 'nsjail.cfg') 71 72 def tearDown(self): 73 shutil.rmtree(self.test_dir) 74 75 @property 76 def config(self): 77 return self.cfg.generate_config(fn=None) 78 79 def test_WriteConfig(self): 80 self.cfg.generate_config(fn=self.cfg_name) 81 self.assertTrue(os.path.exists(self.cfg_name)) 82 with open(self.cfg_name, encoding="iso-8859-1") as f: 83 config = f.read() 84 self.assertEqual(self.config, config) 85 86 def testDefault(self): 87 # Verify that a default entry is present. 88 self.assertIn( 89 '\nmount {\n dst: "/dev/shm"\n fstype: "tmpfs"\n' 90 ' is_bind: false\n rw: true\n}\n\n', self.config) 91 # Verify that proc is mounted correctly. 92 self.assertNotIn('\nmount_proc: true\n', self.config) 93 self.assertIn('\nmount_proc: false\n', self.config) 94 self.assertIn( 95 ('\nmount {\n src: "/proc"\n dst: "/proc"\n is_bind: true\n ' 96 'rw: true\n mandatory: true\n}\n'), self.config) 97 98 def testCwd(self): 99 self.cfg = nsjail.Nsjail(cwd="/cwd") 100 self.assertIn('\ncwd: "/cwd"\n', self.config) 101 102 def testMountPt(self): 103 val = nsjail.MountPt(dst="/test") 104 self.cfg.add_mountpt(dst="/test") 105 self.assertEqual(val, self.cfg.mounts[-1]) 106 config = self.config 107 # Verify that both a default entry and the one we added are present. 108 self.assertIn( 109 '\nmount {\n dst: "/dev/shm"\n fstype: "tmpfs"\n' 110 ' is_bind: false\n rw: true\n}\n\n', self.config) 111 self.assertIn('\nmount {\n dst: "/test"\n}\n\n', config) 112 113 114if __name__ == "__main__": 115 unittest.main() 116 117# vim: sts=4:ts=4:sw=4 118