blob: 654ba5fcfbaafd9f9fb367225063cf10a2689ff0 [file] [log] [blame]
tturney1bdf77d2015-12-28 17:46:13 -08001#!/usr/bin/env python3.4
Ang Lieb5e5052016-06-24 18:07:11 -07002#
Daniel Barros1cefafd2017-08-04 15:36:40 -07003# Copyright 2017 - The Android Open Source Project
Ang Lieb5e5052016-06-24 18:07:11 -07004#
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
Benny Peake914ce732016-09-26 12:53:03 -070017from distutils import cmd
18from distutils import log
19import os
20import shutil
21import setuptools
22from setuptools.command import test
Alexander Dorokhine5eb366e2016-03-14 12:04:40 -070023import sys
24
Alexander Dorokhine5eb366e2016-03-14 12:04:40 -070025install_requires = [
markdr81044bc2017-04-26 12:12:39 -070026 # Future needs to have a newer version that contains urllib.
27 'future>=0.16.0',
Alexander Dorokhine5eb366e2016-03-14 12:04:40 -070028 # 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',
tturney91191de2017-11-16 15:07:17 -080031 'numpy',
Alexander Dorokhine5eb366e2016-03-14 12:04:40 -070032 'pyserial',
Christopher Wileyfe382762016-11-07 09:58:32 -080033 'shellescape',
Jack Hee4787832017-01-24 22:31:18 -080034 'protobuf',
markdr78faf622017-09-12 11:37:16 -070035 'roman',
Daniel Barros1cefafd2017-08-04 15:36:40 -070036 'scapy-python3',
globaledgee7706752018-01-22 17:07:22 +053037 'pylibftdi',
Alexander Dorokhine5eb366e2016-03-14 12:04:40 -070038]
Ang Lieb5e5052016-06-24 18:07:11 -070039
40if sys.version_info < (3, ):
Alexander Dorokhine5eb366e2016-03-14 12:04:40 -070041 install_requires.append('enum34')
Etan Cohen10200962016-10-06 10:56:52 -070042 install_requires.append('statistics')
Ang Lia7a30692016-09-21 13:25:53 -070043 # "futures" is needed for py2 compatibility and it only works in 2.7
44 install_requires.append('futures')
Benny Peakea5deae42016-10-07 19:40:12 -070045 install_requires.append('py2-ipaddress')
Christopher Wileyfe382762016-11-07 09:58:32 -080046 install_requires.append('subprocess32')
Ang Li73697b32015-12-03 00:41:53 +000047
Ang Lieb5e5052016-06-24 18:07:11 -070048
Benny Peake914ce732016-09-26 12:53:03 -070049class PyTest(test.test):
Ang Lieb5e5052016-06-24 18:07:11 -070050 """Class used to execute unit tests using PyTest. This allows us to execute
51 unit tests without having to install the package.
52 """
Benny Peake914ce732016-09-26 12:53:03 -070053
Ang Lieb5e5052016-06-24 18:07:11 -070054 def finalize_options(self):
Benny Peake914ce732016-09-26 12:53:03 -070055 test.test.finalize_options(self)
Ang Lieb5e5052016-06-24 18:07:11 -070056 self.test_args = ['-x', "tests"]
57 self.test_suite = True
58
59 def run_tests(self):
60 import pytest
61 errno = pytest.main(self.test_args)
62 sys.exit(errno)
63
64
Benny Peakee7fd9292016-09-28 14:26:36 -070065class ActsInstallDependencies(cmd.Command):
66 """Installs only required packages
67
68 Installs all required packages for acts to work. Rather than using the
69 normal install system which creates links with the python egg, pip is
70 used to install the packages.
71 """
72
73 description = 'Install dependencies needed for acts to run on this machine.'
74 user_options = []
75
76 def initialize_options(self):
77 pass
78
79 def finalize_options(self):
80 pass
81
82 def run(self):
Kris Rambish4bc048b2017-05-31 14:14:24 -070083 import pip
84 pip.main(['install', '--upgrade', 'pip'])
Benny Peakee7fd9292016-09-28 14:26:36 -070085 required_packages = self.distribution.install_requires
86
87 for package in required_packages:
88 self.announce('Installing %s...' % package, log.INFO)
89 pip.main(['install', package])
90
91 self.announce('Dependencies installed.')
92
93
Benny Peake914ce732016-09-26 12:53:03 -070094class ActsUninstall(cmd.Command):
95 """Acts uninstaller.
96
97 Uninstalls acts from the current version of python. This will attempt to
98 import acts from any of the python egg locations. If it finds an import
99 it will use the modules file location to delete it. This is repeated until
100 acts can no longer be imported and thus is uninstalled.
101 """
102
103 description = 'Uninstall acts from the local machine.'
104 user_options = []
105
106 def initialize_options(self):
107 pass
108
109 def finalize_options(self):
110 pass
111
112 def uninstall_acts_module(self, acts_module):
113 """Uninstalls acts from a module.
114
115 Args:
116 acts_module: The acts module to uninstall.
117 """
Benny Peakec973e292016-11-09 13:43:39 -0800118 for acts_install_dir in acts_module.__path__:
Jack Hee4787832017-01-24 22:31:18 -0800119 self.announce('Deleting acts from: %s' % acts_install_dir,
120 log.INFO)
Benny Peakec973e292016-11-09 13:43:39 -0800121 shutil.rmtree(acts_install_dir)
Benny Peake914ce732016-09-26 12:53:03 -0700122
123 def run(self):
124 """Entry point for the uninstaller."""
125 # Remove the working directory from the python path. This ensures that
markdrb2e826a2017-08-04 21:42:08 -0700126 # Source code is not accidentally targeted.
Benny Peakefe6113c2016-10-13 19:47:16 -0700127 our_dir = os.path.abspath(os.path.dirname(__file__))
128 if our_dir in sys.path:
129 sys.path.remove(our_dir)
130
Benny Peake914ce732016-09-26 12:53:03 -0700131 if os.getcwd() in sys.path:
132 sys.path.remove(os.getcwd())
133
134 try:
135 import acts as acts_module
136 except ImportError:
Jack Hee4787832017-01-24 22:31:18 -0800137 self.announce(
138 'Acts is not installed, nothing to uninstall.',
139 level=log.ERROR)
Benny Peake914ce732016-09-26 12:53:03 -0700140 return
141
142 while acts_module:
143 self.uninstall_acts_module(acts_module)
144 try:
145 del sys.modules['acts']
146 import acts as acts_module
147 except ImportError:
148 acts_module = None
149
150 self.announce('Finished uninstalling acts.')
151
152
Benny Peakee7fd9292016-09-28 14:26:36 -0700153def main():
Jack Hee4787832017-01-24 22:31:18 -0800154 setuptools.setup(
155 name='acts',
156 version='0.9',
157 description='Android Comms Test Suite',
158 license='Apache2.0',
159 packages=setuptools.find_packages(),
160 include_package_data=False,
161 tests_require=['pytest'],
162 install_requires=install_requires,
163 scripts=['acts/bin/act.py', 'acts/bin/monsoon.py'],
164 cmdclass={
165 'test': PyTest,
166 'install_deps': ActsInstallDependencies,
167 'uninstall': ActsUninstall
168 },
169 url="http://www.android.com/")
Benny Peakee7fd9292016-09-28 14:26:36 -0700170
markdr98ec2c62017-10-03 12:40:47 -0700171 if {'-u', '--uninstall', 'uninstall'}.intersection(sys.argv):
172 act_path = '/usr/local/bin/act.py'
173 if os.path.islink(act_path):
174 os.unlink(act_path)
175 elif os.path.exists(act_path):
176 os.remove(act_path)
177
Benny Peakee7fd9292016-09-28 14:26:36 -0700178
179if __name__ == '__main__':
180 main()