blob: c999b63f0199b65bc1ff8fb8c4bd30f9750bf8f6 [file] [log] [blame]
#
# 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'))