blob: 66e705253c13b183e805a2885c4628a579c3cdaf [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',
globaledgeda43e8e2018-02-06 12:21:04 +053038 'xlsxwriter'
Alexander Dorokhine5eb366e2016-03-14 12:04:40 -070039]
Ang Lieb5e5052016-06-24 18:07:11 -070040
41if sys.version_info < (3, ):
Alexander Dorokhine5eb366e2016-03-14 12:04:40 -070042 install_requires.append('enum34')
Etan Cohen10200962016-10-06 10:56:52 -070043 install_requires.append('statistics')
Ang Lia7a30692016-09-21 13:25:53 -070044 # "futures" is needed for py2 compatibility and it only works in 2.7
45 install_requires.append('futures')
Benny Peakea5deae42016-10-07 19:40:12 -070046 install_requires.append('py2-ipaddress')
Christopher Wileyfe382762016-11-07 09:58:32 -080047 install_requires.append('subprocess32')
Ang Li73697b32015-12-03 00:41:53 +000048
Ang Lieb5e5052016-06-24 18:07:11 -070049
Benny Peake914ce732016-09-26 12:53:03 -070050class PyTest(test.test):
Ang Lieb5e5052016-06-24 18:07:11 -070051 """Class used to execute unit tests using PyTest. This allows us to execute
52 unit tests without having to install the package.
53 """
Benny Peake914ce732016-09-26 12:53:03 -070054
Ang Lieb5e5052016-06-24 18:07:11 -070055 def finalize_options(self):
Benny Peake914ce732016-09-26 12:53:03 -070056 test.test.finalize_options(self)
Ang Lieb5e5052016-06-24 18:07:11 -070057 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
Benny Peakee7fd9292016-09-28 14:26:36 -070066class 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):
Kris Rambish4bc048b2017-05-31 14:14:24 -070084 import pip
85 pip.main(['install', '--upgrade', 'pip'])
Benny Peakee7fd9292016-09-28 14:26:36 -070086 required_packages = self.distribution.install_requires
87
88 for package in required_packages:
89 self.announce('Installing %s...' % package, log.INFO)
Girish Moturu39e811c2018-04-12 14:37:19 -070090 pip.main(['install', '-v', '--no-cache-dir', package])
Benny Peakee7fd9292016-09-28 14:26:36 -070091
92 self.announce('Dependencies installed.')
93
94
Benny Peake914ce732016-09-26 12:53:03 -070095class 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 """
Benny Peakec973e292016-11-09 13:43:39 -0800119 for acts_install_dir in acts_module.__path__:
Jack Hee4787832017-01-24 22:31:18 -0800120 self.announce('Deleting acts from: %s' % acts_install_dir,
121 log.INFO)
Benny Peakec973e292016-11-09 13:43:39 -0800122 shutil.rmtree(acts_install_dir)
Benny Peake914ce732016-09-26 12:53:03 -0700123
124 def run(self):
125 """Entry point for the uninstaller."""
126 # Remove the working directory from the python path. This ensures that
markdrb2e826a2017-08-04 21:42:08 -0700127 # Source code is not accidentally targeted.
Benny Peakefe6113c2016-10-13 19:47:16 -0700128 our_dir = os.path.abspath(os.path.dirname(__file__))
129 if our_dir in sys.path:
130 sys.path.remove(our_dir)
131
Benny Peake914ce732016-09-26 12:53:03 -0700132 if os.getcwd() in sys.path:
133 sys.path.remove(os.getcwd())
134
135 try:
136 import acts as acts_module
137 except ImportError:
Jack Hee4787832017-01-24 22:31:18 -0800138 self.announce(
139 'Acts is not installed, nothing to uninstall.',
140 level=log.ERROR)
Benny Peake914ce732016-09-26 12:53:03 -0700141 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
Benny Peakee7fd9292016-09-28 14:26:36 -0700154def main():
Jack Hee4787832017-01-24 22:31:18 -0800155 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/")
Benny Peakee7fd9292016-09-28 14:26:36 -0700171
markdr98ec2c62017-10-03 12:40:47 -0700172 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
Benny Peakee7fd9292016-09-28 14:26:36 -0700179
180if __name__ == '__main__':
181 main()