# tests/test_shell.py -------------------------------------------*- python -*- # # This source file is part of the Swift.org open source project # # Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors # Licensed under Apache License v2.0 with Runtime Library Exception # # See https://swift.org/LICENSE.txt for license information # See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors # ---------------------------------------------------------------------------- import os import os.path import platform import shutil import sys import tempfile import unittest from io import StringIO from swift_build_support import shell class ShellTestCase(unittest.TestCase): def setUp(self): self.tmpdir = os.path.realpath(tempfile.mkdtemp()) self._orig_stdout = sys.stdout self._orig_stderr = sys.stderr self.stdout = StringIO() self.stderr = StringIO() sys.stdout = self.stdout sys.stderr = self.stderr def tearDown(self): sys.stdout = self._orig_stdout sys.stderr = self._orig_stderr if os.path.exists(self.tmpdir): shutil.rmtree(self.tmpdir) def test_quote_command(self): self.assertEqual(shell.quote_command(["a b", "", "c"]), "'a b' '' c") def test_call(self): shell.dry_run = False foo_file = os.path.join(self.tmpdir, 'foo.txt') bar_file = os.path.join(self.tmpdir, 'bar.txt') with open(foo_file, 'w') as f: f.write("Hello Swift") shell.call(['cp', foo_file, bar_file]) with open(bar_file, 'r') as f: self.assertEqual(f.read(), "Hello Swift") self.assertEqual(self.stdout.getvalue(), "") self.assertEqual(self.stderr.getvalue(), '''\ + cp {foo_file} {bar_file} '''.format(foo_file=self._platform_quote(foo_file), bar_file=self._platform_quote(bar_file))) def test_capture(self): self.assertEqual(shell.capture(["echo", "hi"]), "hi\n") with self.assertRaises(SystemExit): shell.capture(["false"]) self.assertIsNone(shell.capture(["false"], optional=True)) self.assertEqual( shell.capture(["sh", "-c", "echo foo && false"], allow_non_zero_exit=True), "foo\n") with self.assertRaises(SystemExit): shell.capture(["**not-a-command**"], optional=False) self.assertIsNone(shell.capture(["**not-a-command**"], optional=True)) def test_rmtree(self): shell.dry_run = False path = os.path.join(self.tmpdir, 'foo', 'bar') shell.makedirs(path) self.assertTrue(os.path.isdir(path)) shell.rmtree(os.path.join(path)) self.assertFalse( os.path.exists(os.path.join(path))) self.assertTrue( os.path.exists(os.path.join(self.tmpdir, 'foo'))) self.assertEqual(self.stdout.getvalue(), "") self.assertEqual(self.stderr.getvalue(), '''\ + mkdir -p {path} + rm -rf {path} '''.format(path=self._platform_quote(path))) def test_pushd(self): shell.dry_run = False basedir = os.getcwd() with shell.pushd(self.tmpdir): self.assertEqual(os.getcwd(), self.tmpdir) self.assertEqual(os.getcwd(), basedir) # pushd inside pushd with shell.pushd(self.tmpdir): self.assertEqual(os.getcwd(), self.tmpdir) shell.makedirs('foo') with shell.pushd('foo'): self.assertEqual(os.getcwd(), os.path.join(self.tmpdir, 'foo')) self.assertEqual(os.getcwd(), self.tmpdir) self.assertEqual(os.getcwd(), basedir) # cd inside pushd with shell.pushd(self.tmpdir): os.chdir('foo') self.assertEqual(os.getcwd(), os.path.join(self.tmpdir, 'foo')) os.chdir('..') self.assertEqual(os.getcwd(), self.tmpdir) shell.rmtree('foo') self.assertEqual(os.getcwd(), basedir) self.assertEqual(self.stdout.getvalue(), "") self.assertEqual(self.stderr.getvalue(), '''\ + pushd {tmpdir} + popd + pushd {tmpdir} + mkdir -p foo + pushd foo + popd + popd + pushd {tmpdir} + rm -rf foo + popd '''.format(tmpdir=self._platform_quote(self.tmpdir))) def test_dry_run(self): shell.dry_run = True basedir = os.getcwd() foobar_dir = os.path.join(self.tmpdir, 'foo', 'bar') shell.makedirs(foobar_dir) self.assertFalse(os.path.exists(os.path.join(self.tmpdir, 'foo'))) self.assertFalse(os.path.exists(foobar_dir)) with shell.pushd(foobar_dir): self.assertEqual(os.getcwd(), basedir) shell.call(['touch', 'testfile']) self.assertFalse(os.path.exists( os.path.join(foobar_dir, 'testfile'))) self.assertEqual(os.getcwd(), basedir) shell.rmtree(self.tmpdir) self.assertTrue(os.path.exists(self.tmpdir)) self.assertEqual(self.stdout.getvalue(), '''\ + mkdir -p {foobar_dir} + pushd {foobar_dir} + touch testfile + popd + rm -rf {tmpdir} '''.format(foobar_dir=self._platform_quote(foobar_dir), tmpdir=self._platform_quote(self.tmpdir))) self.assertEqual(self.stderr.getvalue(), "") self.dry_run = False def _platform_quote(self, path): if platform.system() == 'Windows': return "'{}'".format(path) else: return path