| # |
| # Copyright (C) 2016 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # |
| |
| """Unit tests for stubs.py.""" |
| |
| |
| from __future__ import print_function |
| import unittest |
| |
| from test import stubs |
| |
| |
| class StubOsTest(unittest.TestCase): |
| |
| def test_isolated_environ_1(self): |
| """Make sure changes to os.environ won't bleed between tests. |
| |
| If os.environ is shared, this or test_isolated_environ_2() will fail. |
| """ |
| os = stubs.StubOs() |
| os.environ['foo'] = 'bar' |
| self.assertEqual({'foo': 'bar'}, os.environ) |
| |
| def test_isolated_environ_2(self): |
| os = stubs.StubOs() |
| os.environ['abc'] = 'def' |
| self.assertEqual({'abc': 'def'}, os.environ) |
| |
| |
| class StubSubprocessTest(unittest.TestCase): |
| |
| def setUp(self): |
| self.stub_subprocess = stubs.StubSubprocess() |
| |
| def test_call(self): |
| """Tests a basic call() subprocess.""" |
| command = self.stub_subprocess.AddCommand() |
| self.stub_subprocess.call(['echo', 'foo']) |
| command.AssertCallWas(['echo', 'foo']) |
| |
| def test_popen(self): |
| """Tests a basic Popen + communicate() subprocess.""" |
| command = self.stub_subprocess.AddCommand() |
| self.stub_subprocess.Popen(['echo', 'foo']).communicate() |
| command.AssertCallWas(['echo', 'foo']) |
| |
| def test_exit_code(self): |
| """Tests returning a non-zero exit code.""" |
| self.stub_subprocess.AddCommand(ret_code=1) |
| self.assertEqual(1, self.stub_subprocess.call(['echo', 'foo'])) |
| |
| def test_output(self): |
| """Tests returning stdout, stderr, and and exit code.""" |
| self.stub_subprocess.AddCommand(ret_out='foo', ret_err='bar', |
| ret_code=5) |
| popen = self.stub_subprocess.Popen(['echo', 'foo']) |
| # Not piped, shouldn't return the string values. |
| self.assertEqual((None, None), popen.communicate()) |
| self.assertEqual(5, popen.returncode) |
| |
| self.stub_subprocess.AddCommand(ret_out='baz', ret_err='bip', |
| ret_code=6) |
| popen = self.stub_subprocess.Popen( |
| ['a command'], stdout=self.stub_subprocess.PIPE, |
| stderr=self.stub_subprocess.PIPE) |
| # Piped, should return the string values. |
| self.assertEqual(('baz', 'bip'), popen.communicate()) |
| self.assertEqual(6, popen.returncode) |
| |
| |
| def test_specified_command(self): |
| """Tests specifying the command args at creation.""" |
| self.stub_subprocess.AddCommand(['echo', 'foo']) |
| self.stub_subprocess.call(['echo', 'foo']) |
| |
| def test_underspecified_command(self): |
| """Tests underspecifying the command args at creation.""" |
| full_command = ['repo', 'sync', '-c', '-j20', '--prune', '-q'] |
| |
| # Any command subset should pass even in the wrong order. This lets a |
| # test check only that the args it cares about are present. |
| for partial in (['repo', 'sync'], ['repo', '-j20'], ['-q', 'sync'], []): |
| command = self.stub_subprocess.AddCommand(partial) |
| self.stub_subprocess.Popen(full_command).communicate() |
| |
| command.AssertCallWas(full_command) |
| command.AssertCallContained(partial) |
| |
| def test_kwargs(self): |
| """Tests additional kwargs passed to a subprocess.""" |
| command = self.stub_subprocess.AddCommand() |
| self.stub_subprocess.call(['echo', 'foo'], |
| stdout=self.stub_subprocess.PIPE, |
| cwd='/path/to/foo', env={'bar': 'baz'}) |
| |
| command.AssertCallWas(['echo', 'foo'], stdout=self.stub_subprocess.PIPE, |
| cwd='/path/to/foo', env={'bar': 'baz'}) |
| command.AssertCallContained(['echo', 'foo'], cwd='/path/to/foo') |
| command.AssertCallContained(env={'bar': 'baz'}) |
| |
| # Try a few assert failures to make sure we check kwargs properly. |
| with self.assertRaises(stubs.CommandError): |
| command.AssertCallWas(['echo', 'foo']) |
| with self.assertRaises(stubs.CommandError): |
| command.AssertCallContained(stderr=self.stub_subprocess.PIPE) |
| with self.assertRaises(stubs.CommandError): |
| command.AssertCallContained(env={'not_bar': 'baz'}) |
| |
| def test_unexpected_subprocess_failure(self): |
| """Tests failure when an unexpected subprocess is run.""" |
| with self.assertRaises(stubs.CommandError): |
| self.stub_subprocess.call(['echo', 'foo']) |
| |
| def test_wrong_command_failure(self): |
| """Tests failure when command args don't match.""" |
| self.stub_subprocess.AddCommand(['echo', 'foo']) |
| |
| with self.assertRaises(stubs.CommandError): |
| self.stub_subprocess.call(['echo', 'bar']) |
| |
| def test_not_run_failure(self): |
| """Tests failure when a command was created but not run.""" |
| command = self.stub_subprocess.AddCommand() |
| self.stub_subprocess.Popen(['echo', 'foo']) |
| with self.assertRaises(stubs.CommandError): |
| command.AssertCallWas(['echo', 'foo']) |
| |
| |
| class StubSubprocessFileTest(unittest.TestCase): |
| |
| def setUp(self): |
| self.stub_os = stubs.StubOs() |
| self.stub_open = stubs.StubOpen(self.stub_os) |
| self.stub_subprocess = stubs.StubSubprocess(self.stub_os, |
| self.stub_open) |
| |
| def test_input_name(self): |
| """Tests requiring an input file by argument name.""" |
| self.stub_subprocess.AddFileCommand(['my_command'], in_args=['--in']) |
| with self.assertRaises(stubs.CommandError): |
| self.stub_subprocess.call(['my_command', '--in', 'foo.txt']) |
| |
| self.stub_subprocess.AddFileCommand(['my_command'], in_args=['--in']) |
| self.stub_open.open('foo.txt', 'w') |
| self.stub_subprocess.call(['my_command', '--in', 'foo.txt']) |
| |
| def test_output_name(self): |
| """Tests creating an output file by argument name.""" |
| self.stub_subprocess.AddFileCommand(['my_command'], out_args=['--out']) |
| self.assertFalse(self.stub_os.path.exists('foo.txt')) |
| |
| self.stub_subprocess.call(['my_command', '--out', 'foo.txt']) |
| self.assertTrue(self.stub_os.path.exists('foo.txt')) |
| |
| def test_input_position(self): |
| """Tests requiring an input file by argument position.""" |
| self.stub_subprocess.AddFileCommand(['cat'], pos_in=[1, 2]) |
| with self.assertRaises(stubs.CommandError): |
| self.stub_subprocess.call(['cat', 'foo.txt', 'bar.txt']) |
| |
| self.stub_subprocess.AddFileCommand(['cat'], pos_in=[1, 2]) |
| self.stub_open.open('foo.txt', 'w') |
| self.stub_open.open('bar.txt', 'w') |
| self.stub_subprocess.call(['cat', 'foo.txt', 'bar.txt']) |
| |
| def test_output_position(self): |
| """Tests creating an output file by argument position.""" |
| self.stub_subprocess.AddFileCommand(['touch'], pos_out=[1, 2]) |
| self.assertFalse(self.stub_os.path.exists('foo.txt')) |
| self.assertFalse(self.stub_os.path.exists('bar.txt')) |
| |
| self.stub_subprocess.call(['touch', 'foo.txt', 'bar.txt']) |
| self.assertTrue(self.stub_os.path.exists('foo.txt')) |
| self.assertTrue(self.stub_os.path.exists('bar.txt')) |