blob: 661d868c4f9e5a962300beac07dbb5187752d84e [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()
James E. Blairce56ff92017-08-18 14:39:06 -070035 context = bwrap.getExecutionContext()
Clint Byrum5870cca2017-04-04 16:20:00 -070036 work_dir = tempfile.mkdtemp()
Clint Byrum5870cca2017-04-04 16:20:00 -070037 ssh_agent = SshAgent()
38 self.addCleanup(ssh_agent.stop)
39 ssh_agent.start()
James E. Blairce56ff92017-08-18 14:39:06 -070040 po = context.getPopen(work_dir=work_dir,
41 ssh_auth_sock=ssh_agent.env['SSH_AUTH_SOCK'])
James E. Blaird6a71ca2017-08-18 14:15:05 -070042 self.assertTrue(po.fds[0] > 2)
43 self.assertTrue(po.fds[1] > 2)
Clint Byrum5870cca2017-04-04 16:20:00 -070044 self.assertTrue(work_dir in po.command)
Clint Byrum5870cca2017-04-04 16:20:00 -070045 # Now run /usr/bin/id to verify passwd/group entries made it in
46 true_proc = po(['/usr/bin/id'], stdout=subprocess.PIPE,
47 stderr=subprocess.PIPE)
48 (output, errs) = true_proc.communicate()
49 # Make sure it printed things on stdout
50 self.assertTrue(len(output.strip()))
51 # And that it did not print things on stderr
52 self.assertEqual(0, len(errs.strip()))
53 # Make sure the _r's are closed
James E. Blaird6a71ca2017-08-18 14:15:05 -070054 self.assertEqual([], po.fds)
Tristan Cacqueray24388602017-06-11 23:40:57 +000055
56 def test_bubblewrap_leak(self):
57 bwrap = bubblewrap.BubblewrapDriver()
James E. Blairce56ff92017-08-18 14:39:06 -070058 context = bwrap.getExecutionContext()
Tristan Cacqueray24388602017-06-11 23:40:57 +000059 work_dir = tempfile.mkdtemp()
60 ansible_dir = tempfile.mkdtemp()
61 ssh_agent = SshAgent()
62 self.addCleanup(ssh_agent.stop)
63 ssh_agent.start()
James E. Blairce56ff92017-08-18 14:39:06 -070064 po = context.getPopen(work_dir=work_dir,
65 ansible_dir=ansible_dir,
66 ssh_auth_sock=ssh_agent.env['SSH_AUTH_SOCK'])
James E. Blairaa4199c2017-07-06 08:51:19 -070067 leak_time = 60
Tristan Cacqueray24388602017-06-11 23:40:57 +000068 # Use hexadecimal notation to avoid false-positive
69 true_proc = po(['bash', '-c', 'sleep 0x%X & disown' % leak_time])
70 self.assertEqual(0, true_proc.wait())
71 cmdline = "sleep\x000x%X\x00" % leak_time
James E. Blairaa4199c2017-07-06 08:51:19 -070072 for x in iterate_timeout(30, "process to exit"):
73 sleep_proc = [pid for pid in os.listdir("/proc") if
74 os.path.isfile("/proc/%s/cmdline" % pid) and
75 open("/proc/%s/cmdline" % pid).read() == cmdline]
76 if not sleep_proc:
77 break
78 time.sleep(1)