Home | History | Annotate | Download | only in framework
      1 #!/usr/bin/env python3.4
      2 #
      3 # Copyright 2017 - The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #     http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 
     17 from distutils import cmd
     18 from distutils import log
     19 import os
     20 import shutil
     21 import setuptools
     22 from setuptools.command import test
     23 import sys
     24 
     25 install_requires = [
     26     # Future needs to have a newer version that contains urllib.
     27     'future>=0.16.0',
     28     # mock-1.0.1 is the last version compatible with setuptools <17.1,
     29     # which is what comes with Ubuntu 14.04 LTS.
     30     'mock<=1.0.1',
     31     'numpy',
     32     'pyserial',
     33     'shellescape',
     34     'protobuf',
     35     'roman',
     36     'scapy-python3',
     37     'pylibftdi',
     38     'xlsxwriter'
     39 ]
     40 
     41 if sys.version_info < (3, ):
     42     install_requires.append('enum34')
     43     install_requires.append('statistics')
     44     # "futures" is needed for py2 compatibility and it only works in 2.7
     45     install_requires.append('futures')
     46     install_requires.append('py2-ipaddress')
     47     install_requires.append('subprocess32')
     48 
     49 
     50 class PyTest(test.test):
     51     """Class used to execute unit tests using PyTest. This allows us to execute
     52     unit tests without having to install the package.
     53     """
     54 
     55     def finalize_options(self):
     56         test.test.finalize_options(self)
     57         self.test_args = ['-x', "tests"]
     58         self.test_suite = True
     59 
     60     def run_tests(self):
     61         import pytest
     62         errno = pytest.main(self.test_args)
     63         sys.exit(errno)
     64 
     65 
     66 class ActsInstallDependencies(cmd.Command):
     67     """Installs only required packages
     68 
     69     Installs all required packages for acts to work. Rather than using the
     70     normal install system which creates links with the python egg, pip is
     71     used to install the packages.
     72     """
     73 
     74     description = 'Install dependencies needed for acts to run on this machine.'
     75     user_options = []
     76 
     77     def initialize_options(self):
     78         pass
     79 
     80     def finalize_options(self):
     81         pass
     82 
     83     def run(self):
     84         import pip
     85         pip.main(['install', '--upgrade', 'pip'])
     86         required_packages = self.distribution.install_requires
     87 
     88         for package in required_packages:
     89             self.announce('Installing %s...' % package, log.INFO)
     90             pip.main(['install', '-v', '--no-cache-dir', package])
     91 
     92         self.announce('Dependencies installed.')
     93 
     94 
     95 class ActsUninstall(cmd.Command):
     96     """Acts uninstaller.
     97 
     98     Uninstalls acts from the current version of python. This will attempt to
     99     import acts from any of the python egg locations. If it finds an import
    100     it will use the modules file location to delete it. This is repeated until
    101     acts can no longer be imported and thus is uninstalled.
    102     """
    103 
    104     description = 'Uninstall acts from the local machine.'
    105     user_options = []
    106 
    107     def initialize_options(self):
    108         pass
    109 
    110     def finalize_options(self):
    111         pass
    112 
    113     def uninstall_acts_module(self, acts_module):
    114         """Uninstalls acts from a module.
    115 
    116         Args:
    117             acts_module: The acts module to uninstall.
    118         """
    119         for acts_install_dir in acts_module.__path__:
    120             self.announce('Deleting acts from: %s' % acts_install_dir,
    121                           log.INFO)
    122             shutil.rmtree(acts_install_dir)
    123 
    124     def run(self):
    125         """Entry point for the uninstaller."""
    126         # Remove the working directory from the python path. This ensures that
    127         # Source code is not accidentally targeted.
    128         our_dir = os.path.abspath(os.path.dirname(__file__))
    129         if our_dir in sys.path:
    130             sys.path.remove(our_dir)
    131 
    132         if os.getcwd() in sys.path:
    133             sys.path.remove(os.getcwd())
    134 
    135         try:
    136             import acts as acts_module
    137         except ImportError:
    138             self.announce(
    139                 'Acts is not installed, nothing to uninstall.',
    140                 level=log.ERROR)
    141             return
    142 
    143         while acts_module:
    144             self.uninstall_acts_module(acts_module)
    145             try:
    146                 del sys.modules['acts']
    147                 import acts as acts_module
    148             except ImportError:
    149                 acts_module = None
    150 
    151         self.announce('Finished uninstalling acts.')
    152 
    153 
    154 def main():
    155     setuptools.setup(
    156         name='acts',
    157         version='0.9',
    158         description='Android Comms Test Suite',
    159         license='Apache2.0',
    160         packages=setuptools.find_packages(),
    161         include_package_data=False,
    162         tests_require=['pytest'],
    163         install_requires=install_requires,
    164         scripts=['acts/bin/act.py', 'acts/bin/monsoon.py'],
    165         cmdclass={
    166             'test': PyTest,
    167             'install_deps': ActsInstallDependencies,
    168             'uninstall': ActsUninstall
    169         },
    170         url="http://www.android.com/")
    171 
    172     if {'-u', '--uninstall', 'uninstall'}.intersection(sys.argv):
    173         act_path = '/usr/local/bin/act.py'
    174         if os.path.islink(act_path):
    175             os.unlink(act_path)
    176         elif os.path.exists(act_path):
    177             os.remove(act_path)
    178 
    179 
    180 if __name__ == '__main__':
    181     main()
    182