blob: d94b3f22271155c1bd99a0a7273300e7f981fe70 [file] [log] [blame]
Clint Byrum5870cca2017-04-04 16:20:00 -07001# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13import fixtures
14import logging
15import subprocess
16import tempfile
17import testtools
James E. Blairaa4199c2017-07-06 08:51:19 -070018import time
Tristan Cacqueray24388602017-06-11 23:40:57 +000019import os
Clint Byrum5870cca2017-04-04 16:20:00 -070020
21from zuul.driver import bubblewrap
22from zuul.executor.server import SshAgent
James E. Blairaa4199c2017-07-06 08:51:19 -070023from tests.base import iterate_timeout
Clint Byrum5870cca2017-04-04 16:20:00 -070024
25
26class TestBubblewrap(testtools.TestCase):
27 def setUp(self):
28 super(TestBubblewrap, self).setUp()
29 self.log_fixture = self.useFixture(
30 fixtures.FakeLogger(level=logging.DEBUG))
31 self.useFixture(fixtures.NestedTempfile())
32
33 def test_bubblewrap_wraps(self):
34 bwrap = bubblewrap.BubblewrapDriver()
35 work_dir = tempfile.mkdtemp()
Clint Byrum5870cca2017-04-04 16:20:00 -070036 ssh_agent = SshAgent()
37 self.addCleanup(ssh_agent.stop)
38 ssh_agent.start()
39 po = bwrap.getPopen(work_dir=work_dir,
Clint Byrum5870cca2017-04-04 16:20:00 -070040 ssh_auth_sock=ssh_agent.env['SSH_AUTH_SOCK'])
41 self.assertTrue(po.passwd_r > 2)
42 self.assertTrue(po.group_r > 2)
43 self.assertTrue(work_dir in po.command)
Clint Byrum5870cca2017-04-04 16:20:00 -070044 # Now run /usr/bin/id to verify passwd/group entries made it in
45 true_proc = po(['/usr/bin/id'], stdout=subprocess.PIPE,
46 stderr=subprocess.PIPE)
47 (output, errs) = true_proc.communicate()
48 # Make sure it printed things on stdout
49 self.assertTrue(len(output.strip()))
50 # And that it did not print things on stderr
51 self.assertEqual(0, len(errs.strip()))
52 # Make sure the _r's are closed
53 self.assertIsNone(po.passwd_r)
54 self.assertIsNone(po.group_r)
Tristan Cacqueray24388602017-06-11 23:40:57 +000055
56 def test_bubblewrap_leak(self):
57 bwrap = bubblewrap.BubblewrapDriver()
58 work_dir = tempfile.mkdtemp()
59 ansible_dir = tempfile.mkdtemp()
60 ssh_agent = SshAgent()
61 self.addCleanup(ssh_agent.stop)
62 ssh_agent.start()
63 po = bwrap.getPopen(work_dir=work_dir,
64 ansible_dir=ansible_dir,
65 ssh_auth_sock=ssh_agent.env['SSH_AUTH_SOCK'])
James E. Blairaa4199c2017-07-06 08:51:19 -070066 leak_time = 60
Tristan Cacqueray24388602017-06-11 23:40:57 +000067 # Use hexadecimal notation to avoid false-positive
68 true_proc = po(['bash', '-c', 'sleep 0x%X & disown' % leak_time])
69 self.assertEqual(0, true_proc.wait())
70 cmdline = "sleep\x000x%X\x00" % leak_time
James E. Blairaa4199c2017-07-06 08:51:19 -070071 for x in iterate_timeout(30, "process to exit"):
72 sleep_proc = [pid for pid in os.listdir("/proc") if
73 os.path.isfile("/proc/%s/cmdline" % pid) and
74 open("/proc/%s/cmdline" % pid).read() == cmdline]
75 if not sleep_proc:
76 break
77 time.sleep(1)