1# Copyright 2020 Google LLC
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Test nsjail."""
16
17import os
18import subprocess
19import tempfile
20import unittest
21from . import nsjail
22
23
24class NsjailTest(unittest.TestCase):
25
26  def setUp(self):
27    nsjail.__file__ = '/'
28
29  def testMinimalParameters(self):
30    commands = nsjail.run(
31        nsjail_bin='/bin/true',
32        chroot='/chroot',
33        source_dir='/source_dir',
34        command=['/bin/bash'],
35        android_target='target_name',
36        dry_run=True)
37    self.assertEqual(
38        commands,
39        [
40            '/bin/true',
41            '--env', 'USER=nobody',
42            '--config', '/nsjail.cfg',
43            '--bindmount', '/source_dir:/src',
44            '--', '/bin/bash'
45        ]
46    )
47
48  def testSetBadMetaAndroidDir(self):
49    os.chdir('/')
50    with self.assertRaises(ValueError):
51      commands = nsjail.run(
52        nsjail_bin='/bin/true',
53        chroot='/chroot',
54        source_dir='/source_dir',
55        command=['/bin/bash'],
56        android_target='target_name',
57        dry_run=True,
58        meta_root_dir='/meta/dir',
59        meta_android_dir='/android/dir')
60
61  def testRedirectStdout(self):
62    with tempfile.TemporaryFile('w+t') as out:
63      nsjail.run(
64          nsjail_bin='/bin/echo',
65          chroot='/chroot',
66          source_dir='/source_dir',
67          command=['/bin/bash'],
68          android_target='target_name',
69          stdout=out)
70      out.seek(0)
71      stdout = out.read()
72      args = ('--env USER=nobody --config /nsjail.cfg '
73              '--bindmount /source_dir:/src -- /bin/bash')
74      expected = '\n'.join([args, 'NsJail command:', '/bin/echo '+args])+'\n'
75      self.assertEqual(stdout, expected)
76
77  def testFailingJailedCommand(self):
78    with self.assertRaises(subprocess.CalledProcessError):
79      nsjail.run(
80          nsjail_bin='/bin/false',
81          chroot='/chroot',
82          source_dir='/source_dir',
83          command=['/bin/bash'],
84          android_target='target_name')
85
86  def testDist(self):
87    commands = nsjail.run(
88        nsjail_bin='/bin/true',
89        chroot='/chroot',
90        source_dir='/source_dir',
91        command=['/bin/bash'],
92        android_target='target_name',
93        dist_dir='/dist_dir',
94        dry_run=True)
95    self.assertEqual(
96        commands,
97        [
98            '/bin/true',
99            '--env', 'USER=nobody',
100            '--config', '/nsjail.cfg',
101            '--env', 'DIST_DIR=/dist',
102            '--bindmount', '/source_dir:/src',
103            '--bindmount', '/dist_dir:/dist',
104            '--', '/bin/bash'
105        ]
106    )
107
108  def testBuildID(self):
109    commands = nsjail.run(
110        nsjail_bin='/bin/true',
111        chroot='/chroot',
112        source_dir='/source_dir',
113        command=['/bin/bash'],
114        android_target='target_name',
115        build_id='0',
116        dry_run=True)
117    self.assertEqual(
118        commands,
119        [
120            '/bin/true',
121            '--env', 'USER=nobody',
122            '--config', '/nsjail.cfg',
123            '--env', 'BUILD_NUMBER=0',
124            '--bindmount', '/source_dir:/src',
125            '--', '/bin/bash'
126        ]
127    )
128
129  def testMaxCPU(self):
130    commands = nsjail.run(
131        nsjail_bin='/bin/true',
132        chroot='/chroot',
133        source_dir='/source_dir',
134        command=['/bin/bash'],
135        android_target='target_name',
136        max_cpus=1,
137        dry_run=True)
138    self.assertEqual(
139        commands,
140        [
141            '/bin/true',
142            '--env', 'USER=nobody',
143            '--config', '/nsjail.cfg',
144            '--max_cpus=1',
145            '--bindmount', '/source_dir:/src',
146            '--', '/bin/bash'
147        ]
148    )
149
150  def testEnv(self):
151    commands = nsjail.run(
152        nsjail_bin='/bin/true',
153        chroot='/chroot',
154        source_dir='/source_dir',
155        command=['/bin/bash'],
156        android_target='target_name',
157        max_cpus=1,
158        dry_run=True,
159        env=['foo=bar', 'spam=eggs'])
160    self.assertEqual(
161        commands,
162        [
163            '/bin/true',
164            '--env', 'USER=nobody',
165            '--config', '/nsjail.cfg',
166            '--max_cpus=1',
167            '--bindmount', '/source_dir:/src',
168            '--env', 'foo=bar', '--env', 'spam=eggs',
169            '--', '/bin/bash'
170        ]
171    )
172
173
174if __name__ == '__main__':
175  unittest.main()
176