diff options
author | Steve Fung <stevefung@google.com> | 2016-04-19 01:46:29 -0700 |
---|---|---|
committer | Steve Fung <stevefung@google.com> | 2016-04-19 20:13:49 +0000 |
commit | 868d93486cf3d558132b2d08f76d9ffb1f1cfbbb (patch) | |
tree | aa2e217fc3c7364c72e8acb0bb0abff9e072d398 | |
parent | c357ad7a2fa25390e25497a199028bd118075004 (diff) | |
download | bdk-868d93486cf3d558132b2d08f76d9ffb1f1cfbbb.tar.gz |
Convert environment/ to 4 space indent
Convert all files in the environment/ folder to a 4 space indent
to comply with PEP8 style rules.
Bug: 28007659
Test: `python test_runner.py` passes.
Test: pylint passes.
Change-Id: Ib079be15e5ecc2cb705b5270e0dd730f490080dc
-rw-r--r-- | cli/lib/environment/sysroot.py | 466 | ||||
-rw-r--r-- | cli/lib/environment/sysroot_stub.py | 211 | ||||
-rw-r--r-- | cli/lib/environment/sysroot_unittest.py | 722 | ||||
-rw-r--r-- | cli/lib/environment/sysroot_util.py | 592 | ||||
-rw-r--r-- | cli/lib/environment/sysroot_util_unittest.py | 290 | ||||
-rw-r--r-- | cli/lib/environment/toolchain_util.py | 132 | ||||
-rw-r--r-- | cli/lib/environment/toolchain_util_unittest.py | 95 |
7 files changed, 1269 insertions, 1239 deletions
diff --git a/cli/lib/environment/sysroot.py b/cli/lib/environment/sysroot.py index ce25612..a07fd28 100644 --- a/cli/lib/environment/sysroot.py +++ b/cli/lib/environment/sysroot.py @@ -24,236 +24,244 @@ import shutil class Sysroot(object): - """A wrapper around basic os/file system operations as pertains to a sysroot. + """A wrapper around basic os/file system operations as pertains to a + sysroot. - Provides access to copying in files to a sysroot, making directories, or - writing new files without needing to know exactly where the sysroot is based. + Provides access to copying in files to a sysroot, making directories, or + writing new files without needing to know exactly where the sysroot is + based. - Attributes: - path - The path at which the sysroot is based. - copy_newer_only - only copy files if the src is newer. - """ - - def __init__(self, path, copy_newer_only=False): - self.path = path - if not os.path.isdir(path): - os.makedirs(path) - self._copy_newer_only = copy_newer_only - - def Destroy(self): - """Remove the sysroot and all subdirs.""" - shutil.rmtree(self.path) - - def __str__(self): - return self.path - - def Path(self, *args): - """Get an absolute path given a path relative to the sysroot.""" - return os.path.join(self.path, *args) - - def Makedirs(self, *path): - """Make directories under the sysroot. - - Only creates directories if they don't already exist. - """ - if not self.HasDir(*path): - os.makedirs(self.Path(*path)) - - def HasDir(self, *path): - """Checks if the sysroot has a given directory.""" - return os.path.isdir(self.Path(*path)) - - def _src_is_newer(self, src, real_dest): - """Returns True is the src should replace the dest.""" - if self._copy_newer_only == False: - return True - # If the src doesn't exist, we force the copy such that - # the caller can raise the appropriate exception. - if not os.path.exists(src): - return True - if not os.path.exists(real_dest): - return True - src_st = os.stat(src) - return src_st.st_mtime - os.stat(real_dest).st_mtime > 0 - - def _copy_times(self, src, real_dest): - """Nearly synchronizes the atime and mtime of the src and dest. - - To enable reliable copy_newer_only behavior, we always set - the mtime to 1 second later than the original to offset - precision issues. Because of those issues, it is beneficial - to call _copy_times even after copy2 or copystat. - """ - if os.path.islink(src): - # Until os.futime/os.lutime, symlink times cannot be changed. - return - src_st = os.lstat(src) - os.utime(real_dest, (src_st.st_atime, src_st.st_mtime + 1)) - - def AddFile(self, src, dest=''): - """Copies a file from src to dest. - - Args: - src - the file to copy. - dest - where to copy to. If a directory, uses the filename from src. - The dest directory must already exist. - Raises: - IOError if the copy fails. + Attributes: + path - The path at which the sysroot is based. + copy_newer_only - only copy files if the src is newer. """ - try: - tgt = self.Path(dest) - if self._src_is_newer(src, tgt): - shutil.copy2(src, tgt) - self._copy_times(src, tgt) - except (IOError, OSError) as e: - raise IOError(('Failed to add file {0} to ' - 'sysroot {1} dest {2}: {3}').format( - src, self, dest, e)) - - def AddSymlink(self, src, dest=''): - """Creates a symlink at dest using src. - - Args: - src - the symlink to copy. - dest - where to create a symlink. If a directory, uses the filename from - src. The dest directory must already exist. - - Raises: - IOError if the symlink fails. - """ - try: - tgt = self.Path(dest) - if self._src_is_newer(src, tgt): - linkto = os.readlink(src) - os.symlink(linkto, tgt) - except (IOError, OSError) as e: - raise IOError(('Failed to add symlink {0} to ' - 'sysroot {1} dest {2}: {3}').format( - src, self, dest, e)) - - def AddDir(self, src, dest='', recurse=True, filter_func=None, - symlinks=False): - """Copies all folders and files from external src to dest in sysroot. - - This function does not use shutil.copytree since that function - does not support copying (and merging) into existing folders, but - the implementation is based on the copytree implementation provided - in the python documentation. - - Does not require dest dir to exist. - - Args: - src - dir to copy files from (absolute path) - dest - (optional) dir to copy files to (relative to self.path). - Default ''. - recurse - (optional) True to recursively add subdirs. Default True. - filter - (optional) a function for filenames that returns true if - the file should be copied, false otherwise. Default identity function. - symlinks - (optional) True to copy symlinks as symlinks. Default False. - - Returns: - List of added files - - Raises: - IOError if any part of the copy fails. - """ - # Default filter is to not filter anything. - filter_func = filter_func or bool - - # Copy the dir. - self.Makedirs(dest) - shutil.copystat(src, self.Path(dest)) - - # Copy the files. - names = os.listdir(src) - errors = [] - added = [] - for name in names: - srcname = os.path.join(src, name) - destname = os.path.join(dest, name) - try: - if symlinks and os.path.islink(srcname): - self.AddSymlink(srcname, destname) - added.append(destname) - elif os.path.isdir(srcname): - if recurse: - added += self.AddDir(srcname, destname, recurse, filter_func, - symlinks) - elif filter_func(name): - added.append(destname) - self.AddFile(srcname, destname) - except IOError as e: - errors.append('Failed to copy {0} to {1}: {2}'.format(srcname, - destname, e)) - - if errors: - raise IOError(str(errors)) - return added - - def AddGlob(self, src, dest='', recurse=False, filter_func=None, - symlinks=False): - """Copies matching folders and files from external src to dest in sysroot. - - This function uses AddDir and AddFile above. - - Does not require dest dir to exist. - - Args: - src - glob to copy files from (absolute glob path) - dest - (optional) dir to copy files to (relative to self.path). - Default ''. - recurse - (optional) True to recursively add subdirs. Default False. - filter - (optional) a function for filenames that returns true if - the file should be copied, false otherwise. Default identity function. - symlinks - (optional) True to copy symlinks as symlinks. Default False. - - Returns: - List of added files - - Raises: - IOError if any part of the copy fails. - """ - # Default filter is to not filter anything. - filter_func = filter_func or bool - - added = [] - for srcname in glob.glob(src): - name = os.path.basename(srcname) - destname = os.path.join(dest, name) - if symlinks and os.path.islink(srcname): - if filter_func(name): - self.AddSymlink(srcname, destname) - added.append(destname) - elif os.path.isdir(srcname): - if recurse: - added += self.AddDir(srcname, destname, recurse=True, - symlinks=symlinks) - elif filter_func(name): - added.append(destname) - self.Makedirs(os.path.dirname(destname)) - self.AddFile(srcname, destname) - - if len(added) == 0: - raise IOError(('Failed to add glob {0} to ' - 'sysroot {1} dest {2}: no matching files').format( - src, self, dest)) - - return added - - def WriteFile(self, dest, contents): - """Write a new file in the sysroot. - - Args: - dest - the path (relative to the sysroot) to add the file to. - contents - the desired contents of the file. - Raises: - IOError if the write fails. - """ - try: - self.Makedirs(os.path.dirname(dest)) - with open(self.Path(dest), 'w') as f: - f.write(contents) - except IOError as e: - raise IOError('Failed to write file {1} in sysroot {2}: {3}'.format( - dest, self, e)) + def __init__(self, path, copy_newer_only=False): + self.path = path + if not os.path.isdir(path): + os.makedirs(path) + self._copy_newer_only = copy_newer_only + + def Destroy(self): + """Remove the sysroot and all subdirs.""" + shutil.rmtree(self.path) + + def __str__(self): + return self.path + + def Path(self, *args): + """Get an absolute path given a path relative to the sysroot.""" + return os.path.join(self.path, *args) + + def Makedirs(self, *path): + """Make directories under the sysroot. + + Only creates directories if they don't already exist. + """ + if not self.HasDir(*path): + os.makedirs(self.Path(*path)) + + def HasDir(self, *path): + """Checks if the sysroot has a given directory.""" + return os.path.isdir(self.Path(*path)) + + def _src_is_newer(self, src, real_dest): + """Returns True is the src should replace the dest.""" + if self._copy_newer_only == False: + return True + # If the src doesn't exist, we force the copy such that + # the caller can raise the appropriate exception. + if not os.path.exists(src): + return True + if not os.path.exists(real_dest): + return True + src_st = os.stat(src) + return src_st.st_mtime - os.stat(real_dest).st_mtime > 0 + + def _copy_times(self, src, real_dest): + """Nearly synchronizes the atime and mtime of the src and dest. + + To enable reliable copy_newer_only behavior, we always set + the mtime to 1 second later than the original to offset + precision issues. Because of those issues, it is beneficial + to call _copy_times even after copy2 or copystat. + """ + if os.path.islink(src): + # Until os.futime/os.lutime, symlink times cannot be changed. + return + src_st = os.lstat(src) + os.utime(real_dest, (src_st.st_atime, src_st.st_mtime + 1)) + + def AddFile(self, src, dest=''): + """Copies a file from src to dest. + + Args: + src - the file to copy. + dest - where to copy to. If a directory, uses the filename from src. + The dest directory must already exist. + Raises: + IOError if the copy fails. + """ + + try: + tgt = self.Path(dest) + if self._src_is_newer(src, tgt): + shutil.copy2(src, tgt) + self._copy_times(src, tgt) + except (IOError, OSError) as e: + raise IOError(('Failed to add file {0} to ' + 'sysroot {1} dest {2}: {3}').format( + src, self, dest, e)) + + def AddSymlink(self, src, dest=''): + """Creates a symlink at dest using src. + + Args: + src - the symlink to copy. + dest - where to create a symlink. If a directory, uses the filename + from src. The dest directory must already exist. + + Raises: + IOError if the symlink fails. + """ + try: + tgt = self.Path(dest) + if self._src_is_newer(src, tgt): + linkto = os.readlink(src) + os.symlink(linkto, tgt) + except (IOError, OSError) as e: + raise IOError(('Failed to add symlink {0} to ' + 'sysroot {1} dest {2}: {3}').format( + src, self, dest, e)) + + def AddDir(self, src, dest='', recurse=True, filter_func=None, + symlinks=False): + """Copies all folders and files from external src to dest in sysroot. + + This function does not use shutil.copytree since that function + does not support copying (and merging) into existing folders, but + the implementation is based on the copytree implementation provided + in the python documentation. + + Does not require dest dir to exist. + + Args: + src - dir to copy files from (absolute path) + dest - (optional) dir to copy files to (relative to self.path). + Default ''. + recurse - (optional) True to recursively add subdirs. Default True. + filter - (optional) a function for filenames that returns true if + the file should be copied, false otherwise. Default identity + function. + symlinks - (optional) True to copy symlinks as symlinks. Default + False. + + Returns: + List of added files + + Raises: + IOError if any part of the copy fails. + """ + # Default filter is to not filter anything. + filter_func = filter_func or bool + + # Copy the dir. + self.Makedirs(dest) + shutil.copystat(src, self.Path(dest)) + + # Copy the files. + names = os.listdir(src) + errors = [] + added = [] + for name in names: + srcname = os.path.join(src, name) + destname = os.path.join(dest, name) + try: + if symlinks and os.path.islink(srcname): + self.AddSymlink(srcname, destname) + added.append(destname) + elif os.path.isdir(srcname): + if recurse: + added += self.AddDir(srcname, destname, recurse, + filter_func, symlinks) + elif filter_func(name): + added.append(destname) + self.AddFile(srcname, destname) + except IOError as e: + errors.append('Failed to copy {0} to {1}: {2}'.format(srcname, + destname, + e)) + + if errors: + raise IOError(str(errors)) + return added + + def AddGlob(self, src, dest='', recurse=False, filter_func=None, + symlinks=False): + """Copies matching folders and files from external src to dest in + sysroot. + + This function uses AddDir and AddFile above. + + Does not require dest dir to exist. + + Args: + src - glob to copy files from (absolute glob path) + dest - (optional) dir to copy files to (relative to self.path). + Default ''. + recurse - (optional) True to recursively add subdirs. Default False. + filter - (optional) a function for filenames that returns true if + the file should be copied, false otherwise. Default identity + function. + symlinks - (optional) True to copy symlinks as symlinks. Default + False. + + Returns: + List of added files + + Raises: + IOError if any part of the copy fails. + """ + # Default filter is to not filter anything. + filter_func = filter_func or bool + + added = [] + for srcname in glob.glob(src): + name = os.path.basename(srcname) + destname = os.path.join(dest, name) + if symlinks and os.path.islink(srcname): + if filter_func(name): + self.AddSymlink(srcname, destname) + added.append(destname) + elif os.path.isdir(srcname): + if recurse: + added += self.AddDir(srcname, destname, recurse=True, + symlinks=symlinks) + elif filter_func(name): + added.append(destname) + self.Makedirs(os.path.dirname(destname)) + self.AddFile(srcname, destname) + + if len(added) == 0: + raise IOError(('Failed to add glob {0} to ' + 'sysroot {1} dest {2}: no matching files').format( + src, self, dest)) + + return added + + def WriteFile(self, dest, contents): + """Write a new file in the sysroot. + + Args: + dest - the path (relative to the sysroot) to add the file to. + contents - the desired contents of the file. + Raises: + IOError if the write fails. + """ + try: + self.Makedirs(os.path.dirname(dest)) + with open(self.Path(dest), 'w') as f: + f.write(contents) + except IOError as e: + raise IOError('Failed to write file {1} in sysroot {2}: {3}'.format( + dest, self, e)) diff --git a/cli/lib/environment/sysroot_stub.py b/cli/lib/environment/sysroot_stub.py index e7ebc10..17048fb 100644 --- a/cli/lib/environment/sysroot_stub.py +++ b/cli/lib/environment/sysroot_stub.py @@ -24,113 +24,114 @@ import error class Error(error.Error): - pass + pass class StubSysroot(object): - """Replacement for Sysroots.""" - - def __init__(self, path): - self.path = path - self.should_write = [] - self.last_written = '' - self.written = [] - self.should_add_file = [] - self.should_add_dir = [] - self.should_add_glob = [] - self.should_pass_filter = [] - self.should_fail_filter = [] - self.should_makedirs = [] - - def Path(self, *path): - return os.path.join(self.path, *path) - - def WriteFile(self, path, contents): - if path in self.should_write: - self.last_written = contents - self.written.append(contents) - self.should_write.remove(path) - else: - raise IOError('not supposed to write {0}'.format(path)) - - def AddFile(self, src, dest=''): - if not (src, dest) in self.should_add_file: - raise IOError('Not supposed to add file {0} to {1}'.format(src, dest)) - self.should_add_file.remove((src, dest)) - - # pylint: disable=unused-argument - def AddDir(self, src, dest=None, recurse=True, filter_func=None, - symlinks=None): - dest = dest or '' - proper_filter = True - if filter_func: - proper_filter = ( - [f for f in self.should_pass_filter - if filter_func(f)] == self.should_pass_filter and - [f for f in self.should_fail_filter if filter_func(f)] == []) - - if not proper_filter: - raise Error('AddDir called with improper filter') - if not (src, dest, recurse) in self.should_add_dir: - raise IOError(('Not supposed to add dir "{}" to "{}", ' - 'recursive: {}').format(src, dest, recurse)) - - self.should_add_dir.remove((src, dest, recurse)) - # This should walk path.should_exist if recurse - return [dest] - - # pylint: disable=unused-argument - def AddGlob(self, src, dest=None, recurse=True, filter_func=None, - symlinks=None): - dest = dest or '' - proper_filter = True - if filter_func: - proper_filter = ( - [f for f in self.should_pass_filter - if filter_func(f)] == self.should_pass_filter and - [f for f in self.should_fail_filter if filter_func(f)] == []) - - if not proper_filter: - raise Error('AddGlob called with improper filter') - if not (src, dest, recurse) in self.should_add_glob: - raise IOError(('Not supposed to add glob "{}" to "{}", ' - 'recursive: {}').format(src, dest, recurse)) - - self.should_add_glob.remove((src, dest, recurse)) - # This should walk path.should_exist if recurse - return [dest] - - def Makedirs(self, dirs): - if not dirs in self.should_makedirs: - raise IOError('Could not make dirs {0}'.format(dirs)) - - def Destroy(self): - pass + """Replacement for Sysroots.""" + + def __init__(self, path): + self.path = path + self.should_write = [] + self.last_written = '' + self.written = [] + self.should_add_file = [] + self.should_add_dir = [] + self.should_add_glob = [] + self.should_pass_filter = [] + self.should_fail_filter = [] + self.should_makedirs = [] + + def Path(self, *path): + return os.path.join(self.path, *path) + + def WriteFile(self, path, contents): + if path in self.should_write: + self.last_written = contents + self.written.append(contents) + self.should_write.remove(path) + else: + raise IOError('not supposed to write {0}'.format(path)) + + def AddFile(self, src, dest=''): + if not (src, dest) in self.should_add_file: + raise IOError('Not supposed to add file {0} to {1}'.format(src, + dest)) + self.should_add_file.remove((src, dest)) + + # pylint: disable=unused-argument + def AddDir(self, src, dest=None, recurse=True, filter_func=None, + symlinks=None): + dest = dest or '' + proper_filter = True + if filter_func: + proper_filter = ( + [f for f in self.should_pass_filter + if filter_func(f)] == self.should_pass_filter and + [f for f in self.should_fail_filter if filter_func(f)] == []) + + if not proper_filter: + raise Error('AddDir called with improper filter') + if not (src, dest, recurse) in self.should_add_dir: + raise IOError(('Not supposed to add dir "{}" to "{}", ' + 'recursive: {}').format(src, dest, recurse)) + + self.should_add_dir.remove((src, dest, recurse)) + # This should walk path.should_exist if recurse. + return [dest] + + # pylint: disable=unused-argument + def AddGlob(self, src, dest=None, recurse=True, filter_func=None, + symlinks=None): + dest = dest or '' + proper_filter = True + if filter_func: + proper_filter = ( + [f for f in self.should_pass_filter + if filter_func(f)] == self.should_pass_filter and + [f for f in self.should_fail_filter if filter_func(f)] == []) + + if not proper_filter: + raise Error('AddGlob called with improper filter') + if not (src, dest, recurse) in self.should_add_glob: + raise IOError(('Not supposed to add glob "{}" to "{}", ' + 'recursive: {}').format(src, dest, recurse)) + + self.should_add_glob.remove((src, dest, recurse)) + # This should walk path.should_exist if recurse. + return [dest] + + def Makedirs(self, dirs): + if not dirs in self.should_makedirs: + raise IOError('Could not make dirs {0}'.format(dirs)) + + def Destroy(self): + pass class StubSysrootGenerator(object): - """Generates stub sysroots.""" - - def __init__(self): - self.should_write = [] - self.last_written = '' - self.should_add_file = [] - self.should_add_dir = [] - self.should_add_glob = [] - self.should_pass_filter = [] - self.should_fail_filter = [] - self.should_makedirs = [] - self.sysroots = [] - - # pylint: disable=unused-argument - def Sysroot(self, path, copy_newer_only=False): - gen = StubSysroot(path) - self.sysroots.append(gen) - gen.should_write = self.should_write - gen.last_written = self.last_written - gen.should_add_file = self.should_add_file - gen.should_add_dir = self.should_add_dir - gen.should_add_glob = self.should_add_glob - gen.should_pass_filter = self.should_pass_filter - gen.should_fail_filter = self.should_fail_filter - gen.should_makedirs = self.should_makedirs - return gen + """Generates stub sysroots.""" + + def __init__(self): + self.should_write = [] + self.last_written = '' + self.should_add_file = [] + self.should_add_dir = [] + self.should_add_glob = [] + self.should_pass_filter = [] + self.should_fail_filter = [] + self.should_makedirs = [] + self.sysroots = [] + + # pylint: disable=unused-argument + def Sysroot(self, path, copy_newer_only=False): + gen = StubSysroot(path) + self.sysroots.append(gen) + gen.should_write = self.should_write + gen.last_written = self.last_written + gen.should_add_file = self.should_add_file + gen.should_add_dir = self.should_add_dir + gen.should_add_glob = self.should_add_glob + gen.should_pass_filter = self.should_pass_filter + gen.should_fail_filter = self.should_fail_filter + gen.should_makedirs = self.should_makedirs + return gen diff --git a/cli/lib/environment/sysroot_unittest.py b/cli/lib/environment/sysroot_unittest.py index 7438354..dc8bf02 100644 --- a/cli/lib/environment/sysroot_unittest.py +++ b/cli/lib/environment/sysroot_unittest.py @@ -24,361 +24,367 @@ from test import stubs class SysrootTest(unittest.TestCase): - def setUp(self): - self.stub_os = stubs.StubOs() - self.stub_glob = stubs.StubGlob(self.stub_os) - self.stub_shutil = stubs.StubShutil(self.stub_os) - self.stub_open = stubs.StubOpen(self.stub_os) - - sysroot.os = self.stub_os - sysroot.glob = self.stub_glob - sysroot.shutil = self.stub_shutil - sysroot.open = self.stub_open.open - - def gen_sysroot(self, copy_newer_only=False): - """Helper - Generates a sysroot and returns it and its path.""" - path = 'path/subdir' - self.stub_os.should_makedirs = ['path/subdir'] - return (sysroot.Sysroot(path, copy_newer_only=copy_newer_only), path) - - def test_init_destroy(self): - self.stub_os.path.should_be_dir = [] - # Check that necessary dirs are created for a sysroot on init. - (sysrt, _) = self.gen_sysroot() - self.assertTrue(self.stub_os.path.isdir('path')) - self.assertTrue(self.stub_os.path.isdir('path/subdir')) - sysrt.Destroy() - # 'path' will actually remain, but this is WAI because it may - # have had non-sysroot files added between creation and destruction. - self.assertTrue(self.stub_os.path.isdir('path')) - self.assertFalse(self.stub_os.path.isdir('path/subdir')) - - def test_path(self): - self.stub_os.path.should_be_dir = [] - (sysrt, path) = self.gen_sysroot() - self.assertEqual(path, sysrt.Path()) - self.assertEqual(self.stub_os.path.join(path, 'boogie', 'woogie', 'woo'), - sysrt.Path('boogie', 'woogie', 'woo')) - - def test_makedirs_hasdir(self): - self.stub_os.path.should_be_dir = [] - (sysrt, path) = self.gen_sysroot() - - self.stub_os.should_makedirs = [sysrt.Path('deeper/deeperer/deepest')] - # Makedirs - sysrt.Makedirs('deeper/deeperer/deepest') - self.assertTrue(self.stub_os.path.isdir(self.stub_os.path.join(path, - 'deeper'))) - self.assertTrue( - self.stub_os.path.isdir(self.stub_os.path.join(path, - 'deeper/deeperer'))) - self.assertTrue(self.stub_os.path.isdir( - self.stub_os.path.join(path, 'deeper/deeperer/deepest'))) - # Trying to make existing dirs doesn't cause a problem - sysrt.Makedirs('deeper/deeperer') - - # HasDir - self.assertTrue(sysrt.HasDir('deeper')) - self.assertTrue(sysrt.HasDir('deeper/deeperer')) - self.assertTrue(sysrt.HasDir('deeper/deeperer/deepest')) - - def test_add_file(self): - self.stub_os.path.should_be_dir = [] - (sysrt, _) = self.gen_sysroot() - self.stub_shutil.should_copy = [('a/b/c', sysrt.Path('d'))] - self.stub_os.path.should_exist += ['a/b/c'] - sysrt.AddFile('a/b/c', 'd') - self.assertEqual(self.stub_shutil.should_copy, []) - # If we fail, should raise IOError - self.assertRaisesRegexp(IOError, 'does/not/exist', sysrt.AddFile, - 'does/not/exist', 'e') - - def test_add_file_cond_new(self): - self.stub_os.path.should_be_dir = [] - (sysrt, _) = self.gen_sysroot(copy_newer_only=True) - self.stub_shutil.should_copy = [('a/b/c', sysrt.Path('d'))] - self.stub_os.path.should_exist += ['a/b/c'] - # There is no destination, so this is just a normal copy. - sysrt.AddFile('a/b/c', 'd') - self.assertEqual(self.stub_shutil.should_copy, []) - # If we fail, should raise IOError - self.assertRaisesRegexp(IOError, 'does/not/exist', sysrt.AddFile, - 'does/not/exist', 'e') - - def test_add_file_cond_exists_but_newer(self): - self.stub_os.path.should_be_dir = [] - (sysrt, _) = self.gen_sysroot(copy_newer_only=True) - self.stub_os.path.should_exist = [sysrt.Path('d'), 'a/b/c'] - # No copy should occur. - self.stub_os.should_stat = {sysrt.Path('d'): {'st_mtime': 100}, - 'a/b/c': {'st_mtime': 100}} - sysrt.AddFile('a/b/c', 'd') - self.assertEqual(self.stub_shutil.should_copy, []) - # If we fail, should raise IOError - self.assertRaisesRegexp(IOError, 'does/not/exist', sysrt.AddFile, - 'does/not/exist', 'e') - - def test_add_file_cond_exists_and_older(self): - self.stub_os.path.should_be_dir = [] - (sysrt, _) = self.gen_sysroot(copy_newer_only=True) - self.stub_shutil.should_copy = [('a/b/c', sysrt.Path('d'))] - self.stub_os.path.should_exist = [sysrt.Path('d'), 'a/b/c'] - # 'd' will be copied over. - self.stub_os.should_stat = {sysrt.Path('d'): {'st_mtime': 99}, - 'a/b/c': {'st_mtime': 100}} - sysrt.AddFile('a/b/c', 'd') - self.assertEqual(self.stub_shutil.should_copy, []) - # If we fail, should raise IOError - self.assertRaisesRegexp(IOError, 'does/not/exist', sysrt.AddFile, - 'does/not/exist', 'e') - - def test_add_symlink(self): - self.stub_os.path.should_be_dir = [] - (sysrt, _) = self.gen_sysroot() - self.stub_shutil.should_copy = [('a/b/c', sysrt.Path('d'))] - self.stub_os.path.should_exist += ['a/b/c'] - sysrt.AddFile('a/b/c', 'd') - self.assertEqual(self.stub_shutil.should_copy, []) - self.stub_os.path.should_be_dir += ['root'] - self.stub_os.path.should_exist += ['root', 'root/link'] - self.stub_os.path.should_link['root/link'] = '../a_link_dest' - - # Should copy not_a_link, and create a link for link. - self.stub_os.should_create_link = [ - ('../a_link_dest', sysrt.Path('newlink')), - ('../../relative_link_dest', sysrt.Path('subdir/link')), - ] - sysrt.AddSymlink('root/link', 'newlink') - # Make sure the one file was copied, and the link was created. - self.assertEqual('../a_link_dest', - self.stub_os.readlink(sysrt.Path('newlink'))) - # If we fail, should raise IOError - self.assertRaisesRegexp(IOError, 'does/not/exist', sysrt.AddSymlink, - 'does/not/exist', 'e') - - def test_add_glob(self): - self.stub_os.path.should_be_dir = [] - self.stub_os.path.should_exist = [] - (sysrt, _) = self.gen_sysroot() - directories = ['root', 'root/sub1', 'root/sub2', 'root/sub1/supersub'] - files = ['root/sub1/copy1', 'root/sub2/copy2', 'root/sub1/supersub/copy3', - 'root/copy0', 'root/copy1'] - for directory in directories: - self.stub_os.path.should_be_dir.append(directory) - self.stub_os.path.should_exist.append(directory) - for f in files: - self.stub_os.path.should_exist.append(f) - # Should only copy from top level of root matching copy*. - self.stub_shutil.should_copy.append(('root/copy0', sysrt.Path('copy0'))) - self.stub_shutil.should_copy.append(('root/copy1', sysrt.Path('copy1'))) - sysrt.AddGlob('root/copy*', recurse=False) - # Make sure the two files were copied. - self.assertEqual(self.stub_shutil.should_copy, []) - - def test_add_glob_no_match(self): - self.stub_os.path.should_be_dir = [] - self.stub_os.path.should_exist = [] - (sysrt, _) = self.gen_sysroot() - directories = ['root', 'root/sub1', 'root/sub2', 'root/sub1/supersub'] - files = ['root/sub1/copy1', 'root/sub2/copy2', 'root/sub1/supersub/copy3'] - for directory in directories: - self.stub_os.path.should_be_dir.append(directory) - self.stub_os.path.should_exist.append(directory) - for f in files: - self.stub_os.path.should_exist.append(f) - with self.assertRaises(IOError): - sysrt.AddGlob('root/copy*', recurse=False) - - def test_add_glob_recurse(self): - self.stub_os.path.should_exist = [] - self.stub_os.path.should_be_dir = [] - (sysrt, _) = self.gen_sysroot() - directories = ['root', 'root/sub1', 'root/sub2', 'root/sub1/supersub'] - files = ['root/sub1/copy1', 'root/sub2/copy2', 'root/sub1/supersub/copy3', - 'root/copy0'] - for directory in directories: - self.stub_os.path.should_be_dir.append(directory) - self.stub_os.path.should_exist.append(directory) - self.stub_os.should_makedirs.append(sysrt.Path(directory.replace('root', - 'dest'))) - for f in files: - self.stub_os.path.should_exist.append(f) - self.stub_shutil.should_copy.append((f, sysrt.Path(f.replace('root', - 'dest')))) - # Add some files to the mock filesystem that shouldn't be copied. - self.stub_os.path.should_exist.append('root/donotcopy') - self.stub_os.path.should_exist.append('other') - self.stub_os.path.should_be_dir.append('other') - self.stub_os.path.should_exist.append('other/copy0') - self.stub_os.path.should_exist.append('other/unfilteredcopy') - # A filter that should only collect the copy files. - def copy_filter(name): - return name.startswith('copy') - - sysrt.AddGlob('root/*', 'dest', recurse=True, filter_func=copy_filter) - # Make sure everything was copied. - self.assertEqual(self.stub_shutil.should_copy, []) - # Note: shutil copy2 stub is not implemented such that it checks for dirs - # existing. This will test that dirs were created, but not necessarily - # that they were created before they were copied to. - for directory in directories: - self.assertTrue( - sysrt.HasDir(self.stub_os.path.join(directory.replace('root', - 'dest')))) - - # Test with no filter. - # Also should be no issue copying into a now-populated destination. - self.stub_shutil.should_copy.append(('other/copy0', sysrt.Path('dest', - 'copy0'))) - sysrt.AddGlob('other/c*', 'dest') - # Make sure everything was copied. - self.assertEqual(self.stub_shutil.should_copy, []) - - def test_add_glob_symlinks(self): - (sysrt, _) = self.gen_sysroot() - self.stub_os.path.should_be_dir += ['root', 'root/subdir'] - self.stub_os.should_makedirs += [sysrt.Path('subdir')] - self.stub_os.path.should_exist += [ - 'root', 'root/subdir', 'root/subdir/not_a_link', 'root/link', - 'root/subdir/link'] - self.stub_os.path.should_link['root/link'] = '../relative_link_dest' - self.stub_os.path.should_link['root/subdir/link'] = ( - '../../relative_link_dest') - - # Should copy not_a_link, and create a link for link. - self.stub_os.should_create_link = [ - ('../relative_link_dest', sysrt.Path('link')), - ('../../relative_link_dest', sysrt.Path('subdir/link')), - ] - self.stub_shutil.should_copy = [ - ('root/subdir/not_a_link', sysrt.Path('subdir/not_a_link'))] - sysrt.AddGlob('root/*', recurse=True, symlinks=True) - # Make sure the one file was copied, and the link was created. - self.assertEqual(self.stub_shutil.should_copy, []) - self.assertEqual('../relative_link_dest', - self.stub_os.readlink(sysrt.Path('link'))) - self.assertEqual('../../relative_link_dest', - self.stub_os.readlink(sysrt.Path('subdir/link'))) - - def test_add_glob_ignore_symlinks(self): - (sysrt, _) = self.gen_sysroot() - self.stub_os.path.should_be_dir += ['root', 'root/subdir'] - self.stub_os.should_makedirs += [sysrt.Path('subdir')] - self.stub_os.path.should_exist += [ - 'root', 'root/subdir', 'root/not_a_link', 'root/subdir/link'] - self.stub_os.path.should_link['root/subdir/link'] = '../relative_link_dest' - - # Should copy both not_a_link and link. - self.stub_shutil.should_copy = [ - ('root/not_a_link', sysrt.Path('not_a_link')), - ('root/subdir/link', sysrt.Path('subdir/link'))] - sysrt.AddGlob('root/*', recurse=True, symlinks=False) - # Make sure the two files were copied. - self.assertEqual(self.stub_shutil.should_copy, []) - - def test_add_dir_recurse_and_unfiltered(self): - self.stub_os.path.should_exist = [] - self.stub_os.path.should_be_dir = [] - (sysrt, _) = self.gen_sysroot() - directories = ['root', 'root/sub1', 'root/sub2', 'root/sub1/supersub'] - files = ['root/sub1/copy1', 'root/sub2/copy2', 'root/sub1/supersub/copy3', - 'root/copy0'] - for directory in directories: - self.stub_os.path.should_be_dir.append(directory) - self.stub_os.path.should_exist.append(directory) - self.stub_os.should_makedirs.append(sysrt.Path(directory.replace('root', - 'dest'))) - for f in files: - self.stub_os.path.should_exist.append(f) - self.stub_shutil.should_copy.append((f, sysrt.Path(f.replace('root', - 'dest')))) - # Add some files to the mock filesystem that shouldn't be copied. - self.stub_os.path.should_exist.append('root/donotcopy') - self.stub_os.path.should_exist.append('other') - self.stub_os.path.should_be_dir.append('other') - self.stub_os.path.should_exist.append('other/copy0') - self.stub_os.path.should_exist.append('other/unfilteredcopy') - # A filter that should only collect the copy files. - def copy_filter(name): - return name.startswith('copy') - - sysrt.AddDir('root', 'dest', recurse=True, filter_func=copy_filter) - # Make sure everything was copied. - self.assertEqual(self.stub_shutil.should_copy, []) - # Note: shutil copy2 stub is not implemented such that it checks for dirs - # existing. This will test that dirs were created, but not necessarily that - # they were created before they were copied to. - for directory in directories: - self.assertTrue( - sysrt.HasDir( - self.stub_os.path.join(directory.replace('root', 'dest')))) - - # Test with no filter. - # Also should be no issue copying into a now-populated destination. - self.stub_shutil.should_copy.append( - ('other/copy0', sysrt.Path('dest', 'copy0'))) - self.stub_shutil.should_copy.append(('other/unfilteredcopy', - sysrt.Path('dest', 'unfilteredcopy'))) - sysrt.AddDir('other', 'dest') - # Make sure everything was copied. - self.assertEqual(self.stub_shutil.should_copy, []) - - def test_add_dir_top_level_no_recurse(self): - (sysrt, _) = self.gen_sysroot() - directories = ['root', 'root/sub1', 'root/sub2', 'root/sub1/supersub'] - files = ['root/sub1/copy1', 'root/sub2/copy2', 'root/sub1/supersub/copy3', - 'root/copy0'] - for directory in directories: - self.stub_os.path.should_be_dir.append(directory) - self.stub_os.path.should_exist.append(directory) - for f in files: - self.stub_os.path.should_exist.append(f) - # Should only copy from top level of root, - # and with no dest provided should copy to top level of the sysroot. - self.stub_shutil.should_copy.append(('root/copy0', sysrt.Path('copy0'))) - sysrt.AddDir('root', recurse=False) - # Make sure the one file was copied. - self.assertEqual(self.stub_shutil.should_copy, []) - - def test_add_dir_symlinks(self): - (sysrt, _) = self.gen_sysroot() - self.stub_os.path.should_be_dir += ['root', 'root/subdir'] - self.stub_os.should_makedirs += [sysrt.Path('subdir')] - self.stub_os.path.should_exist += [ - 'root', 'root/subdir', 'root/not_a_link', 'root/subdir/link'] - self.stub_os.path.should_link['root/subdir/link'] = '../relative_link_dest' - - # Should copy not_a_link, and create a link for link. - self.stub_os.should_create_link = [('../relative_link_dest', - sysrt.Path('subdir/link'))] - self.stub_shutil.should_copy = [ - ('root/not_a_link', sysrt.Path('not_a_link'))] - sysrt.AddDir('root', symlinks=True) - # Make sure the one file was copied, and the link was created. - self.assertEqual(self.stub_shutil.should_copy, []) - self.assertEqual('../relative_link_dest', - self.stub_os.readlink(sysrt.Path('subdir/link'))) - - def test_add_dir_ignore_symlinks(self): - (sysrt, _) = self.gen_sysroot() - self.stub_os.path.should_be_dir += ['root', 'root/subdir'] - self.stub_os.should_makedirs += [sysrt.Path('subdir')] - self.stub_os.path.should_exist += [ - 'root', 'root/subdir', 'root/not_a_link', 'root/subdir/link'] - self.stub_os.path.should_link['root/subdir/link'] = '../relative_link_dest' - - # Should copy both not_a_link and link. - self.stub_shutil.should_copy += [ - ('root/not_a_link', sysrt.Path('not_a_link')), - ('root/subdir/link', sysrt.Path('subdir/link'))] - sysrt.AddDir('root', symlinks=False) - # Make sure the two files were copied. - self.assertEqual(self.stub_shutil.should_copy, []) - - def test_write_file(self): - self.stub_os.path.should_be_dir = [] - (sysrt, _) = self.gen_sysroot() - self.stub_os.should_makedirs = [sysrt.Path('dir')] - sysrt.WriteFile('dir/file', 'contents') - self.assertTrue( - 'contents' in self.stub_open.files[sysrt.Path('dir/file')].contents) + def setUp(self): + self.stub_os = stubs.StubOs() + self.stub_glob = stubs.StubGlob(self.stub_os) + self.stub_shutil = stubs.StubShutil(self.stub_os) + self.stub_open = stubs.StubOpen(self.stub_os) + + sysroot.os = self.stub_os + sysroot.glob = self.stub_glob + sysroot.shutil = self.stub_shutil + sysroot.open = self.stub_open.open + + def gen_sysroot(self, copy_newer_only=False): + """Helper - Generates a sysroot and returns it and its path.""" + path = 'path/subdir' + self.stub_os.should_makedirs = ['path/subdir'] + return (sysroot.Sysroot(path, copy_newer_only=copy_newer_only), path) + + def test_init_destroy(self): + self.stub_os.path.should_be_dir = [] + # Check that necessary dirs are created for a sysroot on init. + (sysrt, _) = self.gen_sysroot() + self.assertTrue(self.stub_os.path.isdir('path')) + self.assertTrue(self.stub_os.path.isdir('path/subdir')) + sysrt.Destroy() + # 'path' will actually remain, but this is WAI because it may + # have had non-sysroot files added between creation and destruction. + self.assertTrue(self.stub_os.path.isdir('path')) + self.assertFalse(self.stub_os.path.isdir('path/subdir')) + + def test_path(self): + self.stub_os.path.should_be_dir = [] + (sysrt, path) = self.gen_sysroot() + self.assertEqual(path, sysrt.Path()) + self.assertEqual(self.stub_os.path.join(path, 'boogie', 'woogie', + 'woo'), + sysrt.Path('boogie', 'woogie', 'woo')) + + def test_makedirs_hasdir(self): + self.stub_os.path.should_be_dir = [] + (sysrt, path) = self.gen_sysroot() + + self.stub_os.should_makedirs = [sysrt.Path('deeper/deeperer/deepest')] + # Makedirs + sysrt.Makedirs('deeper/deeperer/deepest') + self.assertTrue(self.stub_os.path.isdir( + self.stub_os.path.join(path, 'deeper'))) + self.assertTrue( + self.stub_os.path.isdir(self.stub_os.path.join(path, + 'deeper/deeperer'))) + self.assertTrue(self.stub_os.path.isdir( + self.stub_os.path.join(path, 'deeper/deeperer/deepest'))) + # Trying to make existing dirs doesn't cause a problem + sysrt.Makedirs('deeper/deeperer') + + # HasDir + self.assertTrue(sysrt.HasDir('deeper')) + self.assertTrue(sysrt.HasDir('deeper/deeperer')) + self.assertTrue(sysrt.HasDir('deeper/deeperer/deepest')) + + def test_add_file(self): + self.stub_os.path.should_be_dir = [] + (sysrt, _) = self.gen_sysroot() + self.stub_shutil.should_copy = [('a/b/c', sysrt.Path('d'))] + self.stub_os.path.should_exist += ['a/b/c'] + sysrt.AddFile('a/b/c', 'd') + self.assertEqual(self.stub_shutil.should_copy, []) + # If we fail, should raise IOError + self.assertRaisesRegexp(IOError, 'does/not/exist', sysrt.AddFile, + 'does/not/exist', 'e') + + def test_add_file_cond_new(self): + self.stub_os.path.should_be_dir = [] + (sysrt, _) = self.gen_sysroot(copy_newer_only=True) + self.stub_shutil.should_copy = [('a/b/c', sysrt.Path('d'))] + self.stub_os.path.should_exist += ['a/b/c'] + # There is no destination, so this is just a normal copy. + sysrt.AddFile('a/b/c', 'd') + self.assertEqual(self.stub_shutil.should_copy, []) + # If we fail, should raise IOError + self.assertRaisesRegexp(IOError, 'does/not/exist', sysrt.AddFile, + 'does/not/exist', 'e') + + def test_add_file_cond_exists_but_newer(self): + self.stub_os.path.should_be_dir = [] + (sysrt, _) = self.gen_sysroot(copy_newer_only=True) + self.stub_os.path.should_exist = [sysrt.Path('d'), 'a/b/c'] + # No copy should occur. + self.stub_os.should_stat = {sysrt.Path('d'): {'st_mtime': 100}, + 'a/b/c': {'st_mtime': 100}} + sysrt.AddFile('a/b/c', 'd') + self.assertEqual(self.stub_shutil.should_copy, []) + # If we fail, should raise IOError + self.assertRaisesRegexp(IOError, 'does/not/exist', sysrt.AddFile, + 'does/not/exist', 'e') + + def test_add_file_cond_exists_and_older(self): + self.stub_os.path.should_be_dir = [] + (sysrt, _) = self.gen_sysroot(copy_newer_only=True) + self.stub_shutil.should_copy = [('a/b/c', sysrt.Path('d'))] + self.stub_os.path.should_exist = [sysrt.Path('d'), 'a/b/c'] + # 'd' will be copied over. + self.stub_os.should_stat = {sysrt.Path('d'): {'st_mtime': 99}, + 'a/b/c': {'st_mtime': 100}} + sysrt.AddFile('a/b/c', 'd') + self.assertEqual(self.stub_shutil.should_copy, []) + # If we fail, should raise IOError + self.assertRaisesRegexp(IOError, 'does/not/exist', sysrt.AddFile, + 'does/not/exist', 'e') + + def test_add_symlink(self): + self.stub_os.path.should_be_dir = [] + (sysrt, _) = self.gen_sysroot() + self.stub_shutil.should_copy = [('a/b/c', sysrt.Path('d'))] + self.stub_os.path.should_exist += ['a/b/c'] + sysrt.AddFile('a/b/c', 'd') + self.assertEqual(self.stub_shutil.should_copy, []) + self.stub_os.path.should_be_dir += ['root'] + self.stub_os.path.should_exist += ['root', 'root/link'] + self.stub_os.path.should_link['root/link'] = '../a_link_dest' + + # Should copy not_a_link, and create a link for link. + self.stub_os.should_create_link = [ + ('../a_link_dest', sysrt.Path('newlink')), + ('../../relative_link_dest', sysrt.Path('subdir/link')), + ] + sysrt.AddSymlink('root/link', 'newlink') + # Make sure the one file was copied, and the link was created. + self.assertEqual('../a_link_dest', + self.stub_os.readlink(sysrt.Path('newlink'))) + # If we fail, should raise IOError + self.assertRaisesRegexp(IOError, 'does/not/exist', sysrt.AddSymlink, + 'does/not/exist', 'e') + + def test_add_glob(self): + self.stub_os.path.should_be_dir = [] + self.stub_os.path.should_exist = [] + (sysrt, _) = self.gen_sysroot() + directories = ['root', 'root/sub1', 'root/sub2', 'root/sub1/supersub'] + files = ['root/sub1/copy1', 'root/sub2/copy2', + 'root/sub1/supersub/copy3', 'root/copy0', 'root/copy1'] + for directory in directories: + self.stub_os.path.should_be_dir.append(directory) + self.stub_os.path.should_exist.append(directory) + for f in files: + self.stub_os.path.should_exist.append(f) + # Should only copy from top level of root matching copy*. + self.stub_shutil.should_copy.append(('root/copy0', sysrt.Path('copy0'))) + self.stub_shutil.should_copy.append(('root/copy1', sysrt.Path('copy1'))) + sysrt.AddGlob('root/copy*', recurse=False) + # Make sure the two files were copied. + self.assertEqual(self.stub_shutil.should_copy, []) + + def test_add_glob_no_match(self): + self.stub_os.path.should_be_dir = [] + self.stub_os.path.should_exist = [] + (sysrt, _) = self.gen_sysroot() + directories = ['root', 'root/sub1', 'root/sub2', 'root/sub1/supersub'] + files = ['root/sub1/copy1', 'root/sub2/copy2', + 'root/sub1/supersub/copy3'] + for directory in directories: + self.stub_os.path.should_be_dir.append(directory) + self.stub_os.path.should_exist.append(directory) + for f in files: + self.stub_os.path.should_exist.append(f) + with self.assertRaises(IOError): + sysrt.AddGlob('root/copy*', recurse=False) + + def test_add_glob_recurse(self): + self.stub_os.path.should_exist = [] + self.stub_os.path.should_be_dir = [] + (sysrt, _) = self.gen_sysroot() + directories = ['root', 'root/sub1', 'root/sub2', 'root/sub1/supersub'] + files = ['root/sub1/copy1', 'root/sub2/copy2', + 'root/sub1/supersub/copy3', 'root/copy0'] + for directory in directories: + self.stub_os.path.should_be_dir.append(directory) + self.stub_os.path.should_exist.append(directory) + self.stub_os.should_makedirs.append( + sysrt.Path(directory.replace('root', 'dest'))) + for f in files: + self.stub_os.path.should_exist.append(f) + self.stub_shutil.should_copy.append( + (f, sysrt.Path(f.replace('root', 'dest')))) + # Add some files to the mock filesystem that shouldn't be copied. + self.stub_os.path.should_exist.append('root/donotcopy') + self.stub_os.path.should_exist.append('other') + self.stub_os.path.should_be_dir.append('other') + self.stub_os.path.should_exist.append('other/copy0') + self.stub_os.path.should_exist.append('other/unfilteredcopy') + # A filter that should only collect the copy files. + def copy_filter(name): + return name.startswith('copy') + + sysrt.AddGlob('root/*', 'dest', recurse=True, filter_func=copy_filter) + # Make sure everything was copied. + self.assertEqual(self.stub_shutil.should_copy, []) + # Note: shutil copy2 stub is not implemented such that it checks for + # dirs existing. This will test that dirs were created, but not + # necessarily that they were created before they were copied to. + for directory in directories: + self.assertTrue( + sysrt.HasDir(self.stub_os.path.join(directory.replace('root', + 'dest')))) + + # Test with no filter. + # Also should be no issue copying into a now-populated destination. + self.stub_shutil.should_copy.append(('other/copy0', + sysrt.Path('dest', 'copy0'))) + sysrt.AddGlob('other/c*', 'dest') + # Make sure everything was copied. + self.assertEqual(self.stub_shutil.should_copy, []) + + def test_add_glob_symlinks(self): + (sysrt, _) = self.gen_sysroot() + self.stub_os.path.should_be_dir += ['root', 'root/subdir'] + self.stub_os.should_makedirs += [sysrt.Path('subdir')] + self.stub_os.path.should_exist += [ + 'root', 'root/subdir', 'root/subdir/not_a_link', 'root/link', + 'root/subdir/link'] + self.stub_os.path.should_link['root/link'] = '../relative_link_dest' + self.stub_os.path.should_link['root/subdir/link'] = ( + '../../relative_link_dest') + + # Should copy not_a_link, and create a link for link. + self.stub_os.should_create_link = [ + ('../relative_link_dest', sysrt.Path('link')), + ('../../relative_link_dest', sysrt.Path('subdir/link')), + ] + self.stub_shutil.should_copy = [ + ('root/subdir/not_a_link', sysrt.Path('subdir/not_a_link'))] + sysrt.AddGlob('root/*', recurse=True, symlinks=True) + # Make sure the one file was copied, and the link was created. + self.assertEqual(self.stub_shutil.should_copy, []) + self.assertEqual('../relative_link_dest', + self.stub_os.readlink(sysrt.Path('link'))) + self.assertEqual('../../relative_link_dest', + self.stub_os.readlink(sysrt.Path('subdir/link'))) + + def test_add_glob_ignore_symlinks(self): + (sysrt, _) = self.gen_sysroot() + self.stub_os.path.should_be_dir += ['root', 'root/subdir'] + self.stub_os.should_makedirs += [sysrt.Path('subdir')] + self.stub_os.path.should_exist += [ + 'root', 'root/subdir', 'root/not_a_link', 'root/subdir/link'] + self.stub_os.path.should_link['root/subdir/link'] = ( + '../relative_link_dest') + + # Should copy both not_a_link and link. + self.stub_shutil.should_copy = [ + ('root/not_a_link', sysrt.Path('not_a_link')), + ('root/subdir/link', sysrt.Path('subdir/link'))] + sysrt.AddGlob('root/*', recurse=True, symlinks=False) + # Make sure the two files were copied. + self.assertEqual(self.stub_shutil.should_copy, []) + + def test_add_dir_recurse_and_unfiltered(self): + self.stub_os.path.should_exist = [] + self.stub_os.path.should_be_dir = [] + (sysrt, _) = self.gen_sysroot() + directories = ['root', 'root/sub1', 'root/sub2', 'root/sub1/supersub'] + files = ['root/sub1/copy1', 'root/sub2/copy2', + 'root/sub1/supersub/copy3', 'root/copy0'] + for directory in directories: + self.stub_os.path.should_be_dir.append(directory) + self.stub_os.path.should_exist.append(directory) + self.stub_os.should_makedirs.append( + sysrt.Path(directory.replace('root', 'dest'))) + for f in files: + self.stub_os.path.should_exist.append(f) + self.stub_shutil.should_copy.append( + (f, sysrt.Path(f.replace('root', 'dest')))) + # Add some files to the mock filesystem that shouldn't be copied. + self.stub_os.path.should_exist.append('root/donotcopy') + self.stub_os.path.should_exist.append('other') + self.stub_os.path.should_be_dir.append('other') + self.stub_os.path.should_exist.append('other/copy0') + self.stub_os.path.should_exist.append('other/unfilteredcopy') + # A filter that should only collect the copy files. + def copy_filter(name): + return name.startswith('copy') + + sysrt.AddDir('root', 'dest', recurse=True, filter_func=copy_filter) + # Make sure everything was copied. + self.assertEqual(self.stub_shutil.should_copy, []) + # Note: shutil copy2 stub is not implemented such that it checks for + # dirs existing. This will test that dirs were created, but not + # necessarily that they were created before they were copied to. + for directory in directories: + self.assertTrue( + sysrt.HasDir( + self.stub_os.path.join(directory.replace('root', 'dest')))) + + # Test with no filter. + # Also should be no issue copying into a now-populated destination. + self.stub_shutil.should_copy.append( + ('other/copy0', sysrt.Path('dest', 'copy0'))) + self.stub_shutil.should_copy.append(('other/unfilteredcopy', + sysrt.Path('dest', + 'unfilteredcopy'))) + sysrt.AddDir('other', 'dest') + # Make sure everything was copied. + self.assertEqual(self.stub_shutil.should_copy, []) + + def test_add_dir_top_level_no_recurse(self): + (sysrt, _) = self.gen_sysroot() + directories = ['root', 'root/sub1', 'root/sub2', 'root/sub1/supersub'] + files = ['root/sub1/copy1', 'root/sub2/copy2', + 'root/sub1/supersub/copy3', 'root/copy0'] + for directory in directories: + self.stub_os.path.should_be_dir.append(directory) + self.stub_os.path.should_exist.append(directory) + for f in files: + self.stub_os.path.should_exist.append(f) + # Should only copy from top level of root, + # and with no dest provided should copy to top level of the sysroot. + self.stub_shutil.should_copy.append(('root/copy0', sysrt.Path('copy0'))) + sysrt.AddDir('root', recurse=False) + # Make sure the one file was copied. + self.assertEqual(self.stub_shutil.should_copy, []) + + def test_add_dir_symlinks(self): + (sysrt, _) = self.gen_sysroot() + self.stub_os.path.should_be_dir += ['root', 'root/subdir'] + self.stub_os.should_makedirs += [sysrt.Path('subdir')] + self.stub_os.path.should_exist += [ + 'root', 'root/subdir', 'root/not_a_link', 'root/subdir/link'] + self.stub_os.path.should_link['root/subdir/link'] = ( + '../relative_link_dest') + + # Should copy not_a_link, and create a link for link. + self.stub_os.should_create_link = [('../relative_link_dest', + sysrt.Path('subdir/link'))] + self.stub_shutil.should_copy = [ + ('root/not_a_link', sysrt.Path('not_a_link'))] + sysrt.AddDir('root', symlinks=True) + # Make sure the one file was copied, and the link was created. + self.assertEqual(self.stub_shutil.should_copy, []) + self.assertEqual('../relative_link_dest', + self.stub_os.readlink(sysrt.Path('subdir/link'))) + + def test_add_dir_ignore_symlinks(self): + (sysrt, _) = self.gen_sysroot() + self.stub_os.path.should_be_dir += ['root', 'root/subdir'] + self.stub_os.should_makedirs += [sysrt.Path('subdir')] + self.stub_os.path.should_exist += [ + 'root', 'root/subdir', 'root/not_a_link', 'root/subdir/link'] + self.stub_os.path.should_link['root/subdir/link'] = ( + '../relative_link_dest') + + # Should copy both not_a_link and link. + self.stub_shutil.should_copy += [ + ('root/not_a_link', sysrt.Path('not_a_link')), + ('root/subdir/link', sysrt.Path('subdir/link'))] + sysrt.AddDir('root', symlinks=False) + # Make sure the two files were copied. + self.assertEqual(self.stub_shutil.should_copy, []) + + def test_write_file(self): + self.stub_os.path.should_be_dir = [] + (sysrt, _) = self.gen_sysroot() + self.stub_os.should_makedirs = [sysrt.Path('dir')] + sysrt.WriteFile('dir/file', 'contents') + self.assertTrue( + 'contents' in self.stub_open.files[sysrt.Path('dir/file')].contents) diff --git a/cli/lib/environment/sysroot_util.py b/cli/lib/environment/sysroot_util.py index 6d8302e..c599ffb 100644 --- a/cli/lib/environment/sysroot_util.py +++ b/cli/lib/environment/sysroot_util.py @@ -24,298 +24,308 @@ from core import util def _FilterHeaders(filename): - return filename.endswith('.h') + return filename.endswith('.h') class SysrootUtil(object): - """A class to assist with setting up sysroots. - - Attributes: - sysroot - the sysroot this instance helps with. - """ - - # Includes to provide in the sysroot. - # (lib, recurse, filter) - DEFAULT_INCLUDES = [ - ('bionic/libc/include', True, _FilterHeaders), - ('bionic/libc/kernel/uapi/asm-generic/..', True, _FilterHeaders), - ('bionic/libc/kernel/uapi/linux/..', True, _FilterHeaders), - ('external/zlib', False, _FilterHeaders), - ('system/core/include', True, _FilterHeaders) - ] - DEFAULT_ARCH_INCLUDES = { - 'arm': [('bionic/libc/kernel/uapi/asm-arm', True, _FilterHeaders), - ('bionic/libc/arch-arm/include', True, _FilterHeaders)], - 'mips': [('bionic/libc/kernel/uapi/asm-mips', True, _FilterHeaders), - ('bionic/libc/arch-mips/include', True, _FilterHeaders)], - 'x86': [('bionic/libc/kernel/uapi/asm-x86', True, _FilterHeaders), - ('bionic/libc/arch-x86/include', True, _FilterHeaders)], - } - - # Libs to provide in the sysroot. - STATIC_PATH_FORMAT = '{0}_intermediates/{0}.a' - DEFAULT_STATIC_LIBS = ['libc', 'libc++_static', 'libm', 'libz'] - DEFAULT_SHARED_LIBS = ['crtbegin_so.o', - 'crtbegin_dynamic.o', - 'crtbegin_static.o', - 'crtend_android.o', - 'crtend_so.o', - 'libc.so', - 'libc++.so', - 'libdl.so', - 'libm.so', - 'libz.so'] - - DEFAULT_LIB_RENAMES = { - 'libc++.so': 'libstdc++.so', - 'libc++_static.a': 'libstdc++.a' - } - - # Some defaults for where things go. - DEFAULT_INCLUDE_DIR = os.path.join('usr', 'include') - DEFAULT_LIB_DIR = os.path.join('usr', 'lib') - ADDITIONAL_INCLUDE_EXTENSION = 'brillo' - - # Libcxx gets special treatment. - LIBCXX_HEADERS = 'external/libcxx/include' - LIBCXX_INCLUDE_DIR = os.path.join(DEFAULT_INCLUDE_DIR, 'c++') - - # pkg-config constants. - PC_DIR = os.path.join('usr', 'share', 'pkgconfig') - # For this format: - # {0} - lib name - # {1} - version - # {2} - dependencies - # {3} - normalized lib name ('lib' prefix removed) - # Note that if this format changes where to expect things, - # also change the AddProvidedLib function. - PC_FILE_FORMAT = ('prefix=/usr\n' - 'exec_prefix=${{prefix}}\n' - 'libdir=${{exec_prefix}}/lib\n' - 'includedir=${{exec_prefix}}/include/' + - ADDITIONAL_INCLUDE_EXTENSION + '/{0}\n' - '\n' - 'Name: {0}\n' - 'Description: {0} for Brillo\n' - 'Version: {1}\n' - 'Requires: {2}\n' - 'Libs: -L${{libdir}} -l{3}\n' - 'Cflags: -I${{includedir}}\n') - - def __init__(self, sysroot, os_version): - self.sysroot = sysroot - self.os_version = os_version - - def _FormatForCopy(self, src, dest): - """Helper to account for special formatting signals. - - Given a path to copy from and path to copy to, returns a pair suitable - to input into sysroot.AddDir. - - Special format A/B/.. designates wanting only B when A has several subdirs. - - Args: - src: the path to copy from. Relative to the OS. - dest: the path to copy to. Relative to the sysroot. - - Returns: - (result_src, result_dest), src and dest transformed and ready - to be passed into sysroot.AddDir. - """ - result_src = util.GetOSPath(self.os_version, src) - result_dest = dest - if src.endswith('/..'): - basename = os.path.basename(src[:-3]) - result_src = os.path.join(result_src, basename) - result_dest = os.path.join(result_dest, basename) - return (result_src, result_dest) - - def _AddPkgConfigFile(self, lib, deps, version): - """Writes a .pc file for a lib in the sysroot. - - Args: - lib: the name of the library for this .pc file. - deps: a space separated string of library names this library depends on. - version: the version of this library. - - Raises: - IOError if the file write fails. - """ - dest_dir = self.PC_DIR - - normalized_lib = lib - if lib.startswith('lib'): - normalized_lib = lib[3:] - self.sysroot.WriteFile( - os.path.join(dest_dir, lib + '.pc'), - self.PC_FILE_FORMAT.format(lib, version, deps, normalized_lib)) - - def AddSharedLib(self, lib_src, name, deps, includes, suffix=None): - """Adds a library to the sysroot. - - Copies in the .so file, copies in includes, and generates a pkg-config file. - - Args: - lib_src: path where prebuilt shared libs can be found. - name: the name of the library to add. - deps: a space-separated string of library names lib is dependent on. - includes: a list of directories with headers for lib. - suffix: (optional) a suffix to append to the lib name when added - to the sysroot. - - Raises: - IOError: If there are any issues adding the necessary files - to the sysroot. - """ - suffixed_name = name - if suffix: - suffixed_name += '-' + suffix - - # Set up destinations. - # NOTE: if these change, also update the PC_FILE_FORMAT. - lib_dest = self.DEFAULT_LIB_DIR - include_dest = os.path.join(self.DEFAULT_INCLUDE_DIR, - self.ADDITIONAL_INCLUDE_EXTENSION, - suffixed_name) - self.sysroot.Makedirs(lib_dest) - self.sysroot.Makedirs(include_dest) - - errors = [] - - # Get the .so file. - try: - self.sysroot.AddFile(os.path.join(lib_src, name + '.so'), - os.path.join(lib_dest, suffixed_name + '.so')) - except IOError as e: - errors.append('.so file: {}'.format(e)) - - # Copy includes (.h files only) over to sysroot. - for include in includes: - (src, dest) = self._FormatForCopy(include, include_dest) - try: - self.sysroot.AddDir(src, dest, filter_func=_FilterHeaders) - except IOError as e: - errors.append('include {}: {}'.format(include, e)) - - # Write the .pc file. - try: - self._AddPkgConfigFile(suffixed_name, deps, util.GetOSVersion()) - except IOError as e: - errors.append('.pc file: {}'.format(e)) - - if errors: - raise IOError('Failed to add components for {}: {}'.format( - suffixed_name, errors)) - - def AddSharedLibsFromCSV(self, lib_src, csv_file, suffix=None): - """Add libraries read from a csv file to the sysroot. - - CSV file format is one line header, followed by lines of the form - libname, deps, include_dirs - - Args: - lib_src: path where prebuilt shared libs can be found. - csv_file: path to the file to add libs from. - suffix: (optional) a suffix to append to all the lib names when added to - the sysroot. - - Raises: - IOError: if file can't be found or adding any lib fails. - ValueError: if any line in the file doesn't meet format expectations. - """ - libs = [] - try: - with open(csv_file) as pkg_list: - # Skip the header line - pkg_list.readline() - # Read in all the remaining lines - for line in pkg_list: - lib_details = [pkg.strip() for pkg in line.split(',')] - if len(lib_details) != 3: - raise ValueError(('Line in package csv file "{0}" ' - 'has the incorrect number of items (expected 3): ' - '{1}').format(csv_file, line)) - libs.append(lib_details) - except IOError as e: - raise IOError('Failed to open lib list: {0}'.format(e)) - - errors = [] - for (name, deps, include_str) in libs: - try: - self.AddSharedLib(lib_src, name, deps, include_str.split(), suffix) - except IOError as e: - errors.append(e) - - if errors: - raise IOError('Failed to add libs from csv {0}: {1}'.format( - csv_file, errors)) - - def SetupBaseSysroot(self, arch, shared_libs, static_libs, base_sysroot=None): - """Sets up a sysroot dir from defaults. - - Standard includes and lib files are added to <sysroot>/usr/{include, lib}. - - Args: - arch: the architecture to setup a sysroot for. - shared_libs: path where prebuilt shared libs can be found. - static_libs: path where prebuilt static libs can be found. - base_sysroot: (optional). If provided, copies all files of the sysroot - found at this path, with priority over other files. - - Raises: - IOError: if anything fails, specifying which things failed. + """A class to assist with setting up sysroots. + + Attributes: + sysroot - the sysroot this instance helps with. """ - errors = [] - - # Copy in includes. - self.sysroot.Makedirs(self.DEFAULT_INCLUDE_DIR) - for (include, recurse, filter_func) in (self.DEFAULT_INCLUDES + - self.DEFAULT_ARCH_INCLUDES[arch]): - (src, dest) = self._FormatForCopy(include, self.DEFAULT_INCLUDE_DIR) - try: - self.sysroot.AddDir(src, dest, recurse, filter_func) - except IOError as e: - errors.append('{}: {}'.format(include, e)) - - # Handle libcxx. - (src, dest) = self._FormatForCopy(self.LIBCXX_HEADERS, - self.LIBCXX_INCLUDE_DIR) - try: - self.sysroot.AddDir(src, dest) - except IOError as e: - errors.append(self.LIBCXX_HEADERS) - - # Copy in libs. - self.sysroot.Makedirs(self.DEFAULT_LIB_DIR) - for lib in self.DEFAULT_SHARED_LIBS: - try: - self.sysroot.AddFile(os.path.join(shared_libs, lib), - self.DEFAULT_LIB_DIR) - except IOError as e: - errors.append(lib) - for lib in self.DEFAULT_STATIC_LIBS: - try: - self.sysroot.AddFile(os.path.join(static_libs, - self.STATIC_PATH_FORMAT.format(lib)), - self.DEFAULT_LIB_DIR) - except IOError as e: - errors.append(lib) - - # Do some renaming. - for (src, dest) in self.DEFAULT_LIB_RENAMES.iteritems(): - try: - shutil.move(self.sysroot.Path(self.DEFAULT_LIB_DIR, src), - self.sysroot.Path(self.DEFAULT_LIB_DIR, dest)) - except IOError as e: - errors.append('rename {0} --> {1}'.format(src, dest)) - - # Base our sysroot on another. - # We do this after copying in defaults to give this base priority. - if base_sysroot: - try: - self.sysroot.AddDir(base_sysroot) - except IOError as e: - errors.append(base_sysroot) - - if errors: - raise IOError('Failed to add {0} during sysroot setup.'.format(errors)) + + # Includes to provide in the sysroot. + # (lib, recurse, filter) + DEFAULT_INCLUDES = [ + ('bionic/libc/include', True, _FilterHeaders), + ('bionic/libc/kernel/uapi/asm-generic/..', True, _FilterHeaders), + ('bionic/libc/kernel/uapi/linux/..', True, _FilterHeaders), + ('external/zlib', False, _FilterHeaders), + ('system/core/include', True, _FilterHeaders) + ] + DEFAULT_ARCH_INCLUDES = { + 'arm': [('bionic/libc/kernel/uapi/asm-arm', True, _FilterHeaders), + ('bionic/libc/arch-arm/include', True, _FilterHeaders)], + 'mips': [('bionic/libc/kernel/uapi/asm-mips', True, _FilterHeaders), + ('bionic/libc/arch-mips/include', True, _FilterHeaders)], + 'x86': [('bionic/libc/kernel/uapi/asm-x86', True, _FilterHeaders), + ('bionic/libc/arch-x86/include', True, _FilterHeaders)], + } + + # Libs to provide in the sysroot. + STATIC_PATH_FORMAT = '{0}_intermediates/{0}.a' + DEFAULT_STATIC_LIBS = ['libc', 'libc++_static', 'libm', 'libz'] + DEFAULT_SHARED_LIBS = ['crtbegin_so.o', + 'crtbegin_dynamic.o', + 'crtbegin_static.o', + 'crtend_android.o', + 'crtend_so.o', + 'libc.so', + 'libc++.so', + 'libdl.so', + 'libm.so', + 'libz.so'] + + DEFAULT_LIB_RENAMES = { + 'libc++.so': 'libstdc++.so', + 'libc++_static.a': 'libstdc++.a' + } + + # Some defaults for where things go. + DEFAULT_INCLUDE_DIR = os.path.join('usr', 'include') + DEFAULT_LIB_DIR = os.path.join('usr', 'lib') + ADDITIONAL_INCLUDE_EXTENSION = 'brillo' + + # Libcxx gets special treatment. + LIBCXX_HEADERS = 'external/libcxx/include' + LIBCXX_INCLUDE_DIR = os.path.join(DEFAULT_INCLUDE_DIR, 'c++') + + # pkg-config constants. + PC_DIR = os.path.join('usr', 'share', 'pkgconfig') + # For this format: + # {0} - lib name + # {1} - version + # {2} - dependencies + # {3} - normalized lib name ('lib' prefix removed) + # Note that if this format changes where to expect things, + # also change the AddProvidedLib function. + PC_FILE_FORMAT = ('prefix=/usr\n' + 'exec_prefix=${{prefix}}\n' + 'libdir=${{exec_prefix}}/lib\n' + 'includedir=${{exec_prefix}}/include/' + + ADDITIONAL_INCLUDE_EXTENSION + '/{0}\n' + '\n' + 'Name: {0}\n' + 'Description: {0} for Brillo\n' + 'Version: {1}\n' + 'Requires: {2}\n' + 'Libs: -L${{libdir}} -l{3}\n' + 'Cflags: -I${{includedir}}\n') + + def __init__(self, sysroot, os_version): + self.sysroot = sysroot + self.os_version = os_version + + def _FormatForCopy(self, src, dest): + """Helper to account for special formatting signals. + + Given a path to copy from and path to copy to, returns a pair suitable + to input into sysroot.AddDir. + + Special format A/B/.. designates wanting only B when A has several + subdirs. + + Args: + src: the path to copy from. Relative to the OS. + dest: the path to copy to. Relative to the sysroot. + + Returns: + (result_src, result_dest), src and dest transformed and ready + to be passed into sysroot.AddDir. + """ + result_src = util.GetOSPath(self.os_version, src) + result_dest = dest + if src.endswith('/..'): + basename = os.path.basename(src[:-3]) + result_src = os.path.join(result_src, basename) + result_dest = os.path.join(result_dest, basename) + return (result_src, result_dest) + + def _AddPkgConfigFile(self, lib, deps, version): + """Writes a .pc file for a lib in the sysroot. + + Args: + lib: the name of the library for this .pc file. + deps: a space separated string of library names this library + depends on. + version: the version of this library. + + Raises: + IOError if the file write fails. + """ + dest_dir = self.PC_DIR + + normalized_lib = lib + if lib.startswith('lib'): + normalized_lib = lib[3:] + self.sysroot.WriteFile( + os.path.join(dest_dir, lib + '.pc'), + self.PC_FILE_FORMAT.format(lib, version, deps, normalized_lib)) + + def AddSharedLib(self, lib_src, name, deps, includes, suffix=None): + """Adds a library to the sysroot. + + Copies in the .so file, copies in includes, and generates a pkg-config + file. + + Args: + lib_src: path where prebuilt shared libs can be found. + name: the name of the library to add. + deps: a space-separated string of library names lib is dependent on. + includes: a list of directories with headers for lib. + suffix: (optional) a suffix to append to the lib name when added + to the sysroot. + + Raises: + IOError: If there are any issues adding the necessary files + to the sysroot. + """ + suffixed_name = name + if suffix: + suffixed_name += '-' + suffix + + # Set up destinations. + # NOTE: if these change, also update the PC_FILE_FORMAT. + lib_dest = self.DEFAULT_LIB_DIR + include_dest = os.path.join(self.DEFAULT_INCLUDE_DIR, + self.ADDITIONAL_INCLUDE_EXTENSION, + suffixed_name) + self.sysroot.Makedirs(lib_dest) + self.sysroot.Makedirs(include_dest) + + errors = [] + + # Get the .so file. + try: + self.sysroot.AddFile(os.path.join(lib_src, name + '.so'), + os.path.join(lib_dest, suffixed_name + '.so')) + except IOError as e: + errors.append('.so file: {}'.format(e)) + + # Copy includes (.h files only) over to sysroot. + for include in includes: + (src, dest) = self._FormatForCopy(include, include_dest) + try: + self.sysroot.AddDir(src, dest, filter_func=_FilterHeaders) + except IOError as e: + errors.append('include {}: {}'.format(include, e)) + + # Write the .pc file. + try: + self._AddPkgConfigFile(suffixed_name, deps, util.GetOSVersion()) + except IOError as e: + errors.append('.pc file: {}'.format(e)) + + if errors: + raise IOError('Failed to add components for {}: {}'.format( + suffixed_name, errors)) + + def AddSharedLibsFromCSV(self, lib_src, csv_file, suffix=None): + """Add libraries read from a csv file to the sysroot. + + CSV file format is one line header, followed by lines of the form + libname, deps, include_dirs + + Args: + lib_src: path where prebuilt shared libs can be found. + csv_file: path to the file to add libs from. + suffix: (optional) a suffix to append to all the lib names when + added to the sysroot. + + Raises: + IOError: if file can't be found or adding any lib fails. + ValueError: if any line in the file doesn't meet format + expectations. + """ + libs = [] + try: + with open(csv_file) as pkg_list: + # Skip the header line + pkg_list.readline() + # Read in all the remaining lines + for line in pkg_list: + lib_details = [pkg.strip() for pkg in line.split(',')] + if len(lib_details) != 3: + raise ValueError(('Line in package csv file "{0}" has ' + 'the incorrect number of items ' + '(expected 3): {1}').format(csv_file, + line)) + libs.append(lib_details) + except IOError as e: + raise IOError('Failed to open lib list: {0}'.format(e)) + + errors = [] + for (name, deps, include_str) in libs: + try: + self.AddSharedLib(lib_src, name, deps, include_str.split(), + suffix) + except IOError as e: + errors.append(e) + + if errors: + raise IOError('Failed to add libs from csv {0}: {1}'.format( + csv_file, errors)) + + def SetupBaseSysroot(self, arch, shared_libs, static_libs, + base_sysroot=None): + """Sets up a sysroot dir from defaults. + + Standard includes and lib files are added to + <sysroot>/usr/{include, lib}. + + Args: + arch: the architecture to setup a sysroot for. + shared_libs: path where prebuilt shared libs can be found. + static_libs: path where prebuilt static libs can be found. + base_sysroot: (optional). If provided, copies all files of the + sysroot found at this path, with priority over other files. + + Raises: + IOError: if anything fails, specifying which things failed. + """ + errors = [] + + # Copy in includes. + self.sysroot.Makedirs(self.DEFAULT_INCLUDE_DIR) + for (include, recurse, filter_func) in ( + self.DEFAULT_INCLUDES + self.DEFAULT_ARCH_INCLUDES[arch]): + (src, dest) = self._FormatForCopy(include, self.DEFAULT_INCLUDE_DIR) + try: + self.sysroot.AddDir(src, dest, recurse, filter_func) + except IOError as e: + errors.append('{}: {}'.format(include, e)) + + # Handle libcxx. + (src, dest) = self._FormatForCopy(self.LIBCXX_HEADERS, + self.LIBCXX_INCLUDE_DIR) + try: + self.sysroot.AddDir(src, dest) + except IOError as e: + errors.append(self.LIBCXX_HEADERS) + + # Copy in libs. + self.sysroot.Makedirs(self.DEFAULT_LIB_DIR) + for lib in self.DEFAULT_SHARED_LIBS: + try: + self.sysroot.AddFile(os.path.join(shared_libs, lib), + self.DEFAULT_LIB_DIR) + except IOError as e: + errors.append(lib) + for lib in self.DEFAULT_STATIC_LIBS: + try: + self.sysroot.AddFile( + os.path.join(static_libs, + self.STATIC_PATH_FORMAT.format(lib)), + self.DEFAULT_LIB_DIR) + except IOError as e: + errors.append(lib) + + # Do some renaming. + for (src, dest) in self.DEFAULT_LIB_RENAMES.iteritems(): + try: + shutil.move(self.sysroot.Path(self.DEFAULT_LIB_DIR, src), + self.sysroot.Path(self.DEFAULT_LIB_DIR, dest)) + except IOError as e: + errors.append('rename {0} --> {1}'.format(src, dest)) + + # Base our sysroot on another. + # We do this after copying in defaults to give this base priority. + if base_sysroot: + try: + self.sysroot.AddDir(base_sysroot) + except IOError as e: + errors.append(base_sysroot) + + if errors: + raise IOError( + 'Failed to add {0} during sysroot setup.'.format(errors)) diff --git a/cli/lib/environment/sysroot_util_unittest.py b/cli/lib/environment/sysroot_util_unittest.py index a97f5a8..3139c27 100644 --- a/cli/lib/environment/sysroot_util_unittest.py +++ b/cli/lib/environment/sysroot_util_unittest.py @@ -26,146 +26,150 @@ from test import stubs class SysrootUtilTest(unittest.TestCase): - def setUp(self): - self.stub_os = stubs.StubOs() - self.stub_open = stubs.StubOpen(self.stub_os) - self.stub_shutil = stubs.StubShutil(self.stub_os) - self.stub_util = util_stub.StubUtil() - - sysroot_util.os = self.stub_os - sysroot_util.open = self.stub_open.open - sysroot_util.shutil = self.stub_shutil - sysroot_util.util = self.stub_util - - self.sysroot = sysroot_stub.StubSysroot('sysroot/path') - self.sysrt_util = sysroot_util.SysrootUtil(self.sysroot, - self.stub_util.GetOSVersion()) - - def test_add_pc_file(self): - self.sysroot.should_write = [self.stub_os.path.join(self.sysrt_util.PC_DIR, - 'libtest.pc')] - # pylint: disable=protected-access - self.sysrt_util._AddPkgConfigFile('libtest', 'liba libb', '1.0') - self.assertTrue('liba libb' in self.sysroot.last_written) - self.assertTrue('1.0' in self.sysroot.last_written) - self.assertTrue('-ltest' in self.sysroot.last_written) - self.assertTrue('libtest' in self.sysroot.last_written) - - def test_add_shared_lib(self): - self.sysroot.should_write = [self.stub_os.path.join(self.sysrt_util.PC_DIR, - 'libtest-suffix.pc')] - lib_dir = self.sysrt_util.DEFAULT_LIB_DIR - include_dir = self.stub_os.path.join( - self.sysrt_util.DEFAULT_INCLUDE_DIR, - self.sysrt_util.ADDITIONAL_INCLUDE_EXTENSION, 'libtest-suffix') - self.sysroot.should_makedirs = [lib_dir, include_dir] - self.sysroot.should_add_file = [ - (self.stub_os.path.join('libsrc', 'libtest.so'), - self.stub_os.path.join(lib_dir, 'libtest-suffix.so'))] - self.sysroot.should_add_dir = [ - (self.stub_util.GetOSPath(self.stub_util.GetOSVersion(), 'headers/1'), - include_dir, True), - (self.stub_util.GetOSPath(self.stub_util.GetOSVersion(), - 'headers/deeper/2/../2'), - self.stub_os.path.join(include_dir, '2'), True)] - self.sysroot.should_pass_filter = ['file.h', 'h.h', '.h.h', - 'longer/path/to/thing.h'] - self.sysroot.should_fail_filter = ['h.cpp', 'h', 'file.h.tar'] - self.sysrt_util.AddSharedLib('libsrc', - 'libtest', - 'liba libb', - ['headers/1', 'headers/deeper/2/..'], - 'suffix') - # Make sure everything got done. - self.assertEqual(self.sysroot.should_add_file, []) - self.assertEqual(self.sysroot.should_add_dir, []) - self.assertEqual(self.sysroot.should_write, []) - - def test_add_libs_from_csv(self): - self.sysroot.should_write = [self.stub_os.path.join(self.sysrt_util.PC_DIR, - 'libtest-suffix.pc'), - self.stub_os.path.join(self.sysrt_util.PC_DIR, - 'libtest2-suffix.pc')] - lib_dir = self.sysrt_util.DEFAULT_LIB_DIR - include_dir = self.stub_os.path.join( - self.sysrt_util.DEFAULT_INCLUDE_DIR, - self.sysrt_util.ADDITIONAL_INCLUDE_EXTENSION, 'libtest-suffix') - include_dir2 = self.stub_os.path.join( - self.sysrt_util.DEFAULT_INCLUDE_DIR, - self.sysrt_util.ADDITIONAL_INCLUDE_EXTENSION, 'libtest2-suffix') - self.sysroot.should_makedirs = [lib_dir, include_dir, include_dir2] - self.sysroot.should_add_file = [ - (self.stub_os.path.join('libsrc', 'libtest.so'), - self.stub_os.path.join(lib_dir, 'libtest-suffix.so')), - (self.stub_os.path.join('libsrc', 'libtest2.so'), - self.stub_os.path.join(lib_dir, 'libtest2-suffix.so'))] - self.sysroot.should_add_dir = [ - (self.stub_util.GetOSPath(self.stub_util.GetOSVersion(), 'headers/1'), - include_dir, True), - (self.stub_util.GetOSPath(self.stub_util.GetOSVersion(), 'headers/2'), - include_dir, True)] - self.sysroot.should_pass_filter = ['file.h', 'h.h', '.h.h', - 'longer/path/to/thing.h'] - self.sysroot.should_fail_filter = ['h.cpp', 'h', 'file.h.tar'] - f = stubs.StubFile('header line\n' - 'libtest, liba libb, headers/1 headers/2\n' - 'libtest2, , ') - self.stub_open.files['csv_path'] = f - self.stub_os.path.should_exist = ['csv_path'] - - self.sysrt_util.AddSharedLibsFromCSV('libsrc', 'csv_path', 'suffix') - # Make sure everything got done. - self.assertEqual(self.sysroot.should_add_file, []) - self.assertEqual(self.sysroot.should_add_dir, []) - self.assertEqual(self.sysroot.should_write, []) - - - def test_add_libs_bad_csv(self): - f = stubs.StubFile('header line\n' - 'has, enough, items\n' - 'not, enough items') - self.stub_open.files['csv_path'] = f - self.stub_os.path.should_exist = ['csv_path'] - # Error should indicate which line was problematic. - self.assertRaisesRegexp(ValueError, 'not, enough items', - self.sysrt_util.AddSharedLibsFromCSV, - 'libsrc', 'csv_path', 'suffix') - - def test_setup_base(self): - self.sysroot.should_makedirs = [self.sysrt_util.DEFAULT_INCLUDE_DIR, - self.sysrt_util.DEFAULT_LIB_DIR] - def copyformat(src): - # pylint: disable=protected-access - return self.sysrt_util._FormatForCopy( - src, self.sysrt_util.DEFAULT_INCLUDE_DIR) - - # pylint: disable=protected-access - (libcxx_src, libcxx_dest) = self.sysrt_util._FormatForCopy( - self.sysrt_util.LIBCXX_HEADERS, self.sysrt_util.LIBCXX_INCLUDE_DIR) - - self.sysroot.should_add_dir = [(libcxx_src, libcxx_dest, True)] - for (src, recurse, _) in (self.sysrt_util.DEFAULT_INCLUDES + - self.sysrt_util.DEFAULT_ARCH_INCLUDES['x86']): - (copysrc, copydest) = copyformat(src) - self.sysroot.should_add_dir.append((copysrc, copydest, recurse)) - self.sysroot.should_add_file = [('lib_src/' + default, - self.sysrt_util.DEFAULT_LIB_DIR) - for default in - self.sysrt_util.DEFAULT_SHARED_LIBS] - self.sysroot.should_add_file += [ - ('static_src/' + self.sysrt_util.STATIC_PATH_FORMAT.format(default), - self.sysrt_util.DEFAULT_LIB_DIR) - for default in self.sysrt_util.DEFAULT_STATIC_LIBS] - self.sysroot.should_add_dir.append(('base', '', True)) - self.stub_shutil.should_move = [ - (self.sysroot.Path(self.sysrt_util.DEFAULT_LIB_DIR, src), - self.sysroot.Path(self.sysrt_util.DEFAULT_LIB_DIR, dest)) - for (src, dest) in - self.sysrt_util.DEFAULT_LIB_RENAMES.iteritems()] - - self.sysrt_util.SetupBaseSysroot('x86', 'lib_src', 'static_src', 'base') - # Make sure everything got done. - self.assertEqual(self.sysroot.should_add_file, []) - self.assertEqual(self.sysroot.should_add_dir, []) - self.assertEqual(self.sysroot.should_write, []) - self.assertEqual(self.stub_shutil.should_move, []) + def setUp(self): + self.stub_os = stubs.StubOs() + self.stub_open = stubs.StubOpen(self.stub_os) + self.stub_shutil = stubs.StubShutil(self.stub_os) + self.stub_util = util_stub.StubUtil() + + sysroot_util.os = self.stub_os + sysroot_util.open = self.stub_open.open + sysroot_util.shutil = self.stub_shutil + sysroot_util.util = self.stub_util + + self.sysroot = sysroot_stub.StubSysroot('sysroot/path') + self.sysrt_util = sysroot_util.SysrootUtil( + self.sysroot, self.stub_util.GetOSVersion()) + + def test_add_pc_file(self): + self.sysroot.should_write = [ + self.stub_os.path.join(self.sysrt_util.PC_DIR, 'libtest.pc')] + # pylint: disable=protected-access + self.sysrt_util._AddPkgConfigFile('libtest', 'liba libb', '1.0') + self.assertTrue('liba libb' in self.sysroot.last_written) + self.assertTrue('1.0' in self.sysroot.last_written) + self.assertTrue('-ltest' in self.sysroot.last_written) + self.assertTrue('libtest' in self.sysroot.last_written) + + def test_add_shared_lib(self): + self.sysroot.should_write = [ + self.stub_os.path.join(self.sysrt_util.PC_DIR, + 'libtest-suffix.pc')] + lib_dir = self.sysrt_util.DEFAULT_LIB_DIR + include_dir = self.stub_os.path.join( + self.sysrt_util.DEFAULT_INCLUDE_DIR, + self.sysrt_util.ADDITIONAL_INCLUDE_EXTENSION, 'libtest-suffix') + self.sysroot.should_makedirs = [lib_dir, include_dir] + self.sysroot.should_add_file = [ + (self.stub_os.path.join('libsrc', 'libtest.so'), + self.stub_os.path.join(lib_dir, 'libtest-suffix.so'))] + self.sysroot.should_add_dir = [ + (self.stub_util.GetOSPath(self.stub_util.GetOSVersion(), + 'headers/1'), + include_dir, True), + (self.stub_util.GetOSPath(self.stub_util.GetOSVersion(), + 'headers/deeper/2/../2'), + self.stub_os.path.join(include_dir, '2'), True)] + self.sysroot.should_pass_filter = ['file.h', 'h.h', '.h.h', + 'longer/path/to/thing.h'] + self.sysroot.should_fail_filter = ['h.cpp', 'h', 'file.h.tar'] + self.sysrt_util.AddSharedLib('libsrc', + 'libtest', + 'liba libb', + ['headers/1', 'headers/deeper/2/..'], + 'suffix') + # Make sure everything got done. + self.assertEqual(self.sysroot.should_add_file, []) + self.assertEqual(self.sysroot.should_add_dir, []) + self.assertEqual(self.sysroot.should_write, []) + + def test_add_libs_from_csv(self): + self.sysroot.should_write = [ + self.stub_os.path.join(self.sysrt_util.PC_DIR, 'libtest-suffix.pc'), + self.stub_os.path.join(self.sysrt_util.PC_DIR, + 'libtest2-suffix.pc')] + lib_dir = self.sysrt_util.DEFAULT_LIB_DIR + include_dir = self.stub_os.path.join( + self.sysrt_util.DEFAULT_INCLUDE_DIR, + self.sysrt_util.ADDITIONAL_INCLUDE_EXTENSION, 'libtest-suffix') + include_dir2 = self.stub_os.path.join( + self.sysrt_util.DEFAULT_INCLUDE_DIR, + self.sysrt_util.ADDITIONAL_INCLUDE_EXTENSION, 'libtest2-suffix') + self.sysroot.should_makedirs = [lib_dir, include_dir, include_dir2] + self.sysroot.should_add_file = [ + (self.stub_os.path.join('libsrc', 'libtest.so'), + self.stub_os.path.join(lib_dir, 'libtest-suffix.so')), + (self.stub_os.path.join('libsrc', 'libtest2.so'), + self.stub_os.path.join(lib_dir, 'libtest2-suffix.so'))] + self.sysroot.should_add_dir = [ + (self.stub_util.GetOSPath(self.stub_util.GetOSVersion(), + 'headers/1'), + include_dir, True), + (self.stub_util.GetOSPath(self.stub_util.GetOSVersion(), + 'headers/2'), + include_dir, True)] + self.sysroot.should_pass_filter = ['file.h', 'h.h', '.h.h', + 'longer/path/to/thing.h'] + self.sysroot.should_fail_filter = ['h.cpp', 'h', 'file.h.tar'] + f = stubs.StubFile('header line\n' + 'libtest, liba libb, headers/1 headers/2\n' + 'libtest2, , ') + self.stub_open.files['csv_path'] = f + self.stub_os.path.should_exist = ['csv_path'] + + self.sysrt_util.AddSharedLibsFromCSV('libsrc', 'csv_path', 'suffix') + # Make sure everything got done. + self.assertEqual(self.sysroot.should_add_file, []) + self.assertEqual(self.sysroot.should_add_dir, []) + self.assertEqual(self.sysroot.should_write, []) + + + def test_add_libs_bad_csv(self): + f = stubs.StubFile('header line\n' + 'has, enough, items\n' + 'not, enough items') + self.stub_open.files['csv_path'] = f + self.stub_os.path.should_exist = ['csv_path'] + # Error should indicate which line was problematic. + self.assertRaisesRegexp(ValueError, 'not, enough items', + self.sysrt_util.AddSharedLibsFromCSV, + 'libsrc', 'csv_path', 'suffix') + + def test_setup_base(self): + self.sysroot.should_makedirs = [self.sysrt_util.DEFAULT_INCLUDE_DIR, + self.sysrt_util.DEFAULT_LIB_DIR] + def copyformat(src): + # pylint: disable=protected-access + return self.sysrt_util._FormatForCopy( + src, self.sysrt_util.DEFAULT_INCLUDE_DIR) + + # pylint: disable=protected-access + (libcxx_src, libcxx_dest) = self.sysrt_util._FormatForCopy( + self.sysrt_util.LIBCXX_HEADERS, self.sysrt_util.LIBCXX_INCLUDE_DIR) + + self.sysroot.should_add_dir = [(libcxx_src, libcxx_dest, True)] + for (src, recurse, _) in (self.sysrt_util.DEFAULT_INCLUDES + + self.sysrt_util.DEFAULT_ARCH_INCLUDES['x86']): + (copysrc, copydest) = copyformat(src) + self.sysroot.should_add_dir.append((copysrc, copydest, recurse)) + self.sysroot.should_add_file = [('lib_src/' + default, + self.sysrt_util.DEFAULT_LIB_DIR) + for default + in self.sysrt_util.DEFAULT_SHARED_LIBS] + self.sysroot.should_add_file += [ + ('static_src/' + self.sysrt_util.STATIC_PATH_FORMAT.format(default), + self.sysrt_util.DEFAULT_LIB_DIR) + for default in self.sysrt_util.DEFAULT_STATIC_LIBS] + self.sysroot.should_add_dir.append(('base', '', True)) + self.stub_shutil.should_move = [ + (self.sysroot.Path(self.sysrt_util.DEFAULT_LIB_DIR, src), + self.sysroot.Path(self.sysrt_util.DEFAULT_LIB_DIR, dest)) + for (src, dest) in + self.sysrt_util.DEFAULT_LIB_RENAMES.iteritems()] + + self.sysrt_util.SetupBaseSysroot('x86', 'lib_src', 'static_src', 'base') + # Make sure everything got done. + self.assertEqual(self.sysroot.should_add_file, []) + self.assertEqual(self.sysroot.should_add_dir, []) + self.assertEqual(self.sysroot.should_write, []) + self.assertEqual(self.stub_shutil.should_move, []) diff --git a/cli/lib/environment/toolchain_util.py b/cli/lib/environment/toolchain_util.py index 1a8e4c2..9f1c81a 100644 --- a/cli/lib/environment/toolchain_util.py +++ b/cli/lib/environment/toolchain_util.py @@ -61,83 +61,83 @@ ARCH_TOOL_FLAGS = { class Error(error.Error): - pass + pass class GenerationError(Error): - """Raised when the toolchain fails to generate correctly.""" - description = 'Failed to generate all tools' + """Raised when the toolchain fails to generate correctly.""" + description = 'Failed to generate all tools' def _ToolFlags(tool, arch): - """Helper to combine general and arch-specific tool flags.""" - result = [] - if tool in TOOL_FLAGS: - result += TOOL_FLAGS[tool] - if arch in ARCH_TOOL_FLAGS and tool in ARCH_TOOL_FLAGS[arch]: - result += ARCH_TOOL_FLAGS[arch][tool] - return result + """Helper to combine general and arch-specific tool flags.""" + result = [] + if tool in TOOL_FLAGS: + result += TOOL_FLAGS[tool] + if arch in ARCH_TOOL_FLAGS and tool in ARCH_TOOL_FLAGS[arch]: + result += ARCH_TOOL_FLAGS[arch][tool] + return result def _GenerateWrapper(src, dest, flags=None): - """Write a simple wrapper for a tool. + """Write a simple wrapper for a tool. - dest will call src with flags. dest will be an executable file. + dest will call src with flags. dest will be an executable file. - Args: - src: The original tool to wrap. - dest: The place to put the wrapper. - flags: (optional) Flags to include in the wrapper. Default empty list. + Args: + src: The original tool to wrap. + dest: The place to put the wrapper. + flags: (optional) Flags to include in the wrapper. Default empty list. - Raises: - OSError: There is an error opening or otherwise accessing dest. - IOError: There is an error writing the wrapper file. - """ - flags = flags or [] - with open(dest, 'w') as f: - f.write('#!/bin/sh\n{0} {1} "$@"\n'.format(src, ' '.join(flags))) - # Make sure the file is executable. - st = os.stat(dest) - os.chmod(dest, st.st_mode | stat.S_IEXEC) + Raises: + OSError: There is an error opening or otherwise accessing dest. + IOError: There is an error writing the wrapper file. + """ + flags = flags or [] + with open(dest, 'w') as f: + f.write('#!/bin/sh\n{0} {1} "$@"\n'.format(src, ' '.join(flags))) + # Make sure the file is executable. + st = os.stat(dest) + os.chmod(dest, st.st_mode | stat.S_IEXEC) def GenerateToolchain(os_version, host, target, output_dir): - """Generate a toolchain. - - Args: - os_version: OS version to generate toolchain for. - host: Host architecture to generate toolchain for. - target: Target architecture to generate toolchain for. - output_dir: Where to put generated tools. - - Raises: - Error: Not all tools generated properly. - """ - # Make sure output dir exists. - if not os.path.isdir(output_dir): - os.makedirs(output_dir) - - # Put together some variables based on host and target. - existing_tools = util.GetOSPath(os_version, - EXISTING_TOOLS_FORMAT.format(host_arch=host)) - tool_prefix = os.path.join(existing_tools, ARCH_TOOL_PREFIX[target]) - prefix_len = len(tool_prefix) - - # Walk the existing tools, wrapping them all. - errors = [] - for path in glob.iglob(tool_prefix + '*'): - # Skip dirs, not that there should be any. - if not os.path.isfile(path): - continue - - # Otherwise, assume it's a tool and wrap it. - tool = path[prefix_len:] - try: - output_tool = os.path.join(output_dir, tool) - tool_flags = _ToolFlags(tool, target) - # Write a simple wrapper. - _GenerateWrapper(path, output_tool, tool_flags) - except (IOError, OSError) as e: - errors.append((tool, e)) - - if errors: - raise GenerationError('Failed: {}'.format(errors)) + """Generate a toolchain. + + Args: + os_version: OS version to generate toolchain for. + host: Host architecture to generate toolchain for. + target: Target architecture to generate toolchain for. + output_dir: Where to put generated tools. + + Raises: + Error: Not all tools generated properly. + """ + # Make sure output dir exists. + if not os.path.isdir(output_dir): + os.makedirs(output_dir) + + # Put together some variables based on host and target. + existing_tools = util.GetOSPath( + os_version, EXISTING_TOOLS_FORMAT.format(host_arch=host)) + tool_prefix = os.path.join(existing_tools, ARCH_TOOL_PREFIX[target]) + prefix_len = len(tool_prefix) + + # Walk the existing tools, wrapping them all. + errors = [] + for path in glob.iglob(tool_prefix + '*'): + # Skip dirs, not that there should be any. + if not os.path.isfile(path): + continue + + # Otherwise, assume it's a tool and wrap it. + tool = path[prefix_len:] + try: + output_tool = os.path.join(output_dir, tool) + tool_flags = _ToolFlags(tool, target) + # Write a simple wrapper. + _GenerateWrapper(path, output_tool, tool_flags) + except (IOError, OSError) as e: + errors.append((tool, e)) + + if errors: + raise GenerationError('Failed: {}'.format(errors)) diff --git a/cli/lib/environment/toolchain_util_unittest.py b/cli/lib/environment/toolchain_util_unittest.py index 1ea1c75..cd1d703 100644 --- a/cli/lib/environment/toolchain_util_unittest.py +++ b/cli/lib/environment/toolchain_util_unittest.py @@ -26,56 +26,57 @@ from test import stubs class ToolchainUtilTest(unittest.TestCase): - def setUp(self): - self.stub_os = stubs.StubOs() - self.stub_open = stubs.StubOpen(self.stub_os) - self.stub_glob = stubs.StubGlob(self.stub_os) - self.stub_util = util_stub.StubUtil() + def setUp(self): + self.stub_os = stubs.StubOs() + self.stub_open = stubs.StubOpen(self.stub_os) + self.stub_glob = stubs.StubGlob(self.stub_os) + self.stub_util = util_stub.StubUtil() - toolchain_util.os = self.stub_os - toolchain_util.open = self.stub_open.open - toolchain_util.glob = self.stub_glob - toolchain_util.util = self.stub_util + toolchain_util.os = self.stub_os + toolchain_util.open = self.stub_open.open + toolchain_util.glob = self.stub_glob + toolchain_util.util = self.stub_util - def test_generate_toolchain(self): - stub_tools = ['no_flags', 'g++'] - tool_paths = {} - tool_dests = {} - for tool in stub_tools: - tool_paths[tool] = self.stub_util.GetOSPath( - self.stub_util.GetOSVersion(), - toolchain_util.EXISTING_TOOLS_FORMAT.format(host_arch='host_arch'), - toolchain_util.ARCH_TOOL_PREFIX['x86'] + tool) - self.stub_os.path.should_exist.append(tool_paths[tool]) + def test_generate_toolchain(self): + stub_tools = ['no_flags', 'g++'] + tool_paths = {} + tool_dests = {} + for tool in stub_tools: + tool_paths[tool] = self.stub_util.GetOSPath( + self.stub_util.GetOSVersion(), + toolchain_util.EXISTING_TOOLS_FORMAT.format( + host_arch='host_arch'), + toolchain_util.ARCH_TOOL_PREFIX['x86'] + tool) + self.stub_os.path.should_exist.append(tool_paths[tool]) - tool_dests[tool] = self.stub_os.path.join('dest', tool) - self.stub_os.should_chmod.append((tool_dests[tool], stat.S_IEXEC)) + tool_dests[tool] = self.stub_os.path.join('dest', tool) + self.stub_os.should_chmod.append((tool_dests[tool], stat.S_IEXEC)) - self.stub_os.should_makedirs = ['dest'] - toolchain_util.GenerateToolchain(self.stub_util.GetOSVersion(), - 'host_arch', 'x86', 'dest') - # Should have created dest dir. - self.assertTrue(self.stub_os.path.isdir('dest')) - for tool in stub_tools: - # Should have generated the tool file. - self.assertTrue(self.stub_os.path.isfile(tool_dests[tool])) - # Should have correctly generated the tool file. - tool_file = self.stub_open.files[tool_dests[tool]] - self.assertEqual(len(tool_file.contents), 3) - # Should invoke sh. - self.assertEqual(tool_file.contents[0], '#!/bin/sh') - # Should be a nice file with a trailing newline. - self.assertEqual(tool_file.contents[2], '') - # Should point to the original tool. - self.assertTrue(tool_paths[tool] in tool_file.contents[1]) + self.stub_os.should_makedirs = ['dest'] + toolchain_util.GenerateToolchain(self.stub_util.GetOSVersion(), + 'host_arch', 'x86', 'dest') + # Should have created dest dir. + self.assertTrue(self.stub_os.path.isdir('dest')) + for tool in stub_tools: + # Should have generated the tool file. + self.assertTrue(self.stub_os.path.isfile(tool_dests[tool])) + # Should have correctly generated the tool file. + tool_file = self.stub_open.files[tool_dests[tool]] + self.assertEqual(len(tool_file.contents), 3) + # Should invoke sh. + self.assertEqual(tool_file.contents[0], '#!/bin/sh') + # Should be a nice file with a trailing newline. + self.assertEqual(tool_file.contents[2], '') + # Should point to the original tool. + self.assertTrue(tool_paths[tool] in tool_file.contents[1]) - if tool == 'g++': - # g++ is supposed to get some flags. Make sure those appeared. - # Note: this is not comprehensive testing of all the flags. - # Non arch-specific: - self.assertTrue('-Wformat' in tool_file.contents[1]) - # Arch-specific: - self.assertTrue('-m32' in tool_file.contents[1]) + if tool == 'g++': + # g++ is supposed to get some flags. Make sure those appeared. + # Note: this is not comprehensive testing of all the flags. + # Non arch-specific: + self.assertTrue('-Wformat' in tool_file.contents[1]) + # Arch-specific: + self.assertTrue('-m32' in tool_file.contents[1]) - # All chmods should have happened. - self.assertEqual(self.stub_os.should_chmod, []) + # All chmods should have happened. + self.assertEqual(self.stub_os.should_chmod, []) |