# Copyright 2014 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unittests for the parseelf.py module."""

from __future__ import print_function

import os

from chromite.lib import cros_test_lib
from chromite.lib import osutils
from chromite.lib import parseelf
from chromite.lib import unittest_lib


class ELFParsingTest(cros_test_lib.TempDirTestCase):
  """Test the ELF parsing functions."""

  _ldpaths = {'interp': [], 'env': [], 'conf': []}

  def testIsLib(self):
    """Tests the 'is_lib' attribute is inferred correctly for libs."""
    unittest_lib.BuildELF(os.path.join(self.tempdir, 'liba.so'), ['func_a'])
    elf = parseelf.ParseELF(self.tempdir, 'liba.so', self._ldpaths)
    self.assertTrue('is_lib' in elf)
    self.assertTrue(elf['is_lib'])

  def testNotIsLib(self):
    """Tests the 'is_lib' attribute is inferred correctly for executables."""
    unittest_lib.BuildELF(os.path.join(self.tempdir, 'abc_main'),
                          executable=True)
    elf = parseelf.ParseELF(self.tempdir, 'abc_main', self._ldpaths)
    self.assertTrue('is_lib' in elf)
    self.assertFalse(elf['is_lib'])

  def testUnsupportedFiles(self):
    """Tests unsupported files are ignored."""
    osutils.WriteFile(os.path.join(self.tempdir, 'foo.so'), 'foo')
    self.assertEquals(None,
                      parseelf.ParseELF(self.tempdir, 'foo.so', self._ldpaths))

    osutils.WriteFile(os.path.join(self.tempdir, 'foo.so'), '\x7fELF-foo')
    self.assertEquals(None,
                      parseelf.ParseELF(self.tempdir, 'foo.so', self._ldpaths))

  def testParsedSymbols(self):
    """Tests the list of imported/exported symbols."""
    unittest_lib.BuildELF(os.path.join(self.tempdir, 'libabc.so'),
                          defined_symbols=['fa', 'fb', 'fc'])
    unittest_lib.BuildELF(os.path.join(self.tempdir, 'libxyz.so'),
                          defined_symbols=['fx', 'fy', 'fz'],
                          undefined_symbols=['fa', 'fb', 'fc'],
                          used_libs=['abc'])

    # Test without symbols.
    elf = parseelf.ParseELF(self.tempdir, 'libxyz.so', self._ldpaths,
                            parse_symbols=False)
    self.assertFalse('imp_sym' in elf)
    self.assertFalse('exp_sym' in elf)

    # Test with symbols by default.
    elf = parseelf.ParseELF(self.tempdir, 'libxyz.so', self._ldpaths)
    self.assertTrue('imp_sym' in elf)
    self.assertTrue('exp_sym' in elf)
    self.assertEquals(elf['imp_sym'], set(['fa', 'fb', 'fc']))
    self.assertEquals(set(k for k, (_, _, st_shndx)
                          in elf['exp_sym'].iteritems()
                          if st_shndx == 'SHT_DYNSYM'),
                      set(['fx', 'fy', 'fz']))
    for sym in ['fx', 'fy', 'fz']:
      self.assertEquals('STB_GLOBAL', elf['exp_sym'][sym][0])

  def testLibDependencies(self):
    """Tests the list direct dependencies."""
    # Dependencies:
    #   u -> abc
    #   v -> abc
    #   prog -> u,v
    unittest_lib.BuildELF(os.path.join(self.tempdir, 'libabc.so'),
                          defined_symbols=['fa', 'fb', 'fc'])
    unittest_lib.BuildELF(os.path.join(self.tempdir, 'libu.so'),
                          defined_symbols=['fu'],
                          undefined_symbols=['fa'],
                          used_libs=['abc'])
    unittest_lib.BuildELF(os.path.join(self.tempdir, 'libv.so'),
                          defined_symbols=['fv'],
                          undefined_symbols=['fb'],
                          used_libs=['abc'])
    unittest_lib.BuildELF(os.path.join(self.tempdir, 'prog'),
                          undefined_symbols=['fu', 'fv'],
                          used_libs=['u', 'v'],
                          executable=True)

    elf_prog = parseelf.ParseELF(self.tempdir, 'prog', self._ldpaths)
    # Check the direct dependencies.
    self.assertTrue('libu.so' in elf_prog['needed'])
    self.assertTrue('libv.so' in elf_prog['needed'])
    self.assertFalse('libabc.so' in elf_prog['needed'])

  def testRelativeLibPaths(self):
    """Test that the paths reported by ParseELF are relative to root."""
    unittest_lib.BuildELF(os.path.join(self.tempdir, 'liba.so'), ['fa'])
    unittest_lib.BuildELF(os.path.join(self.tempdir, 'prog'),
                          undefined_symbols=['fa'], used_libs=['a'],
                          executable=True)
    elf = parseelf.ParseELF(self.tempdir, 'prog', self._ldpaths)
    for lib in elf['libs'].values():
      for path in ('realpath', 'path'):
        if lib[path] is None:
          continue
        self.assertFalse(lib[path].startswith('/'))
        self.assertFalse(lib[path].startswith(self.tempdir))
        # Linked lib paths should be relative to the working directory or is the
        # ld dynamic loader.
        self.assertTrue(lib[path] == elf['interp'] or
                        os.path.exists(os.path.join(self.tempdir, lib[path])))
