forked from ionelmc/setupext-janitor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tests.py
315 lines (255 loc) · 10.7 KB
/
tests.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
from distutils import core, dist
from distutils.command import clean
import atexit
import os.path
import shutil
import sys
import tempfile
import uuid
if sys.version_info >= (2, 7):
import unittest
else: # noinspection PyPackageRequirements,PyUnresolvedReferences
import unittest2 as unittest
from setupext_janitor import janitor
def run_setup(*command_line):
"""
Run the setup command with `command_line`.
:param command_line: the command line arguments to pass
as the simulated command line
This function runs :func:`distutils.core.setup` after it
configures an environment that mimics passing the specified
command line arguments. The ``distutils`` internals are
replaced with a :class:`~distutils.dist.Distribution`
instance that will only execute the clean command. Other
commands can be passed freely to simulate command line usage
patterns.
"""
class FakeDistribution(dist.Distribution):
def __init__(self, *args, **kwargs):
"""Enable verbose output to make tests easier to debug."""
dist.Distribution.__init__(self, *args, **kwargs)
self.verbose = 3
def run_command(self, command):
"""Only run the clean command."""
if command == 'clean':
dist.Distribution.run_command(self, command)
def parse_config_files(self, filenames=None):
"""Skip processing of configuration files."""
pass
core.setup(
distclass=FakeDistribution,
script_name='testsetup.py',
script_args=command_line,
cmdclass={'clean': janitor.CleanCommand},
)
class CommandOptionTests(unittest.TestCase):
def test_that_distutils_options_are_present(self):
defined_options = set(t[0] for t in janitor.CleanCommand.user_options)
superclass_options = set(t[0] for t in clean.clean.user_options)
self.assertTrue(defined_options.issuperset(superclass_options))
def test_that_janitor_user_options_are_not_clean_options(self):
self.assertIsNot(
janitor.CleanCommand.user_options, clean.clean.user_options)
def test_that_janitor_defines_dist_command(self):
self.assertIn(
('dist', 'd', 'remove distribution directory'),
janitor.CleanCommand.user_options)
class DirectoryCleanupMixin(object):
@classmethod
def setUpClass(cls):
super(DirectoryCleanupMixin, cls).setUpClass()
cls.temp_dir = tempfile.mkdtemp()
atexit.register(shutil.rmtree, cls.temp_dir)
@classmethod
def create_directory(cls, dir_name):
return tempfile.mkdtemp(dir=cls.temp_dir, prefix=dir_name)
@staticmethod
def mkdirs(*dirs):
for d in dirs:
os.makedirs(d)
return dirs[:]
def assert_path_does_not_exist(self, *trailing_segments):
full_path = os.path.join(*trailing_segments)
if os.path.exists(full_path):
raise AssertionError('{0} should not exist'.format(full_path))
def assert_path_exists(self, *trailing_segments):
full_path = os.path.join(*trailing_segments)
if not os.path.exists(full_path):
raise AssertionError('{0} should exist'.format(full_path))
class DistDirectoryCleanupTests(DirectoryCleanupMixin, unittest.TestCase):
def test_that_dist_directory_is_removed_for_sdist(self):
dist_dir = self.create_directory('dist-dir')
run_setup(
'sdist', '--dist-dir={0}'.format(dist_dir),
'clean', '--dist',
)
self.assert_path_does_not_exist(dist_dir)
def test_that_dist_directory_is_removed_for_bdist_dumb(self):
dist_dir = self.create_directory('dist-dir')
run_setup(
'bdist_dumb', '--dist-dir={0}'.format(dist_dir),
'clean', '--dist',
)
self.assert_path_does_not_exist(dist_dir)
def test_that_multiple_dist_directories_with_be_removed(self):
sdist_dir = self.create_directory('sdist-dir')
bdist_dir = self.create_directory('bdist_dumb')
run_setup(
'sdist', '--dist-dir={0}'.format(sdist_dir),
'bdist_dumb', '--dist-dir={0}'.format(bdist_dir),
'clean', '--dist',
)
self.assert_path_does_not_exist(sdist_dir)
self.assert_path_does_not_exist(bdist_dir)
def test_that_directories_are_not_removed_without_parameter(self):
sdist_dir = self.create_directory('sdist-dir')
bdist_dir = self.create_directory('bdist_dumb')
run_setup(
'sdist', '--dist-dir={0}'.format(sdist_dir),
'bdist_dumb', '--dist-dir={0}'.format(bdist_dir),
'clean',
)
self.assert_path_exists(sdist_dir)
self.assert_path_exists(bdist_dir)
def test_that_directories_are_not_removed_in_dry_run_mode(self):
sdist_dir = self.create_directory('sdist-dir')
run_setup(
'sdist', '--dist-dir={0}'.format(sdist_dir),
'clean', '--dist', '--dry-run'
)
self.assert_path_exists(sdist_dir)
class EggDirectoryCleanupTests(DirectoryCleanupMixin, unittest.TestCase):
def test_that_egg_info_directories_are_removed(self):
egg_root = self.create_directory('egg-info-root')
os.mkdir(os.path.join(egg_root, 'bah.egg-info'))
os.mkdir(os.path.join(egg_root, 'foo.egg-info'))
run_setup('clean', '--egg-base={0}'.format(egg_root), '--eggs')
self.assert_path_exists(egg_root)
self.assert_path_does_not_exist(egg_root, 'bah.egg-info')
self.assert_path_does_not_exist(egg_root, 'foo.egg-info')
def test_that_egg_directories_are_removed(self):
dir_name = uuid.uuid4().hex + '.egg'
os.mkdir(dir_name)
try:
run_setup('clean', '--eggs')
self.assert_path_does_not_exist(dir_name)
except:
os.rmdir(dir_name)
raise
def test_that_eggs_directories_are_removed(self):
dir_name = uuid.uuid4().hex + '.eggs'
os.mkdir(dir_name)
try:
run_setup('clean', '--eggs')
self.assert_path_does_not_exist(dir_name)
except:
os.rmdir(dir_name)
raise
def test_that_directories_are_not_removed_in_dry_run_mode(self):
egg_root = self.create_directory('egg-info-root')
os.mkdir(os.path.join(egg_root, 'package.egg-info'))
installed_egg = uuid.uuid4().hex + '.egg'
os.mkdir(installed_egg)
try:
run_setup(
'clean', '--egg-base={0}'.format(egg_root), '--eggs',
'--dry-run',
)
self.assert_path_exists(installed_egg)
self.assert_path_exists(egg_root, 'package.egg-info')
except:
os.rmdir(installed_egg)
raise
os.rmdir(installed_egg)
class VirtualEnvironmentCleanupTests(DirectoryCleanupMixin, unittest.TestCase):
def setUp(self):
super(VirtualEnvironmentCleanupTests, self).setUp()
self._saved_venv = os.environ.get('VIRTUAL_ENV', None)
def tearDown(self):
super(VirtualEnvironmentCleanupTests, self).tearDown()
if self._saved_venv is not None:
os.environ['VIRTUAL_ENV'] = self._saved_venv
else:
os.environ.pop('VIRTUAL_ENV', None)
def test_that_virtualenv_is_removed_when_dir_is_specified(self):
venv_dir = self.create_directory('venv')
run_setup(
'clean', '--environment', '--virtualenv-dir={0}'.format(venv_dir))
self.assert_path_does_not_exist(venv_dir)
def test_that_virtualenv_is_removed_based_on_envvar(self):
venv_dir = self.create_directory('venv')
os.environ['VIRTUAL_ENV'] = venv_dir
run_setup('clean', '--environment')
self.assert_path_does_not_exist(venv_dir)
def test_that_janitor_does_not_fail_when_envdir_is_missing(self):
venv_dir = self.create_directory('venv')
os.environ['VIRTUAL_ENV'] = venv_dir
os.rmdir(venv_dir)
run_setup('clean', '--environment')
def test_that_janitor_does_not_fail_when_no_dir_specified(self):
os.environ.pop('VIRTUAL_ENV', None)
run_setup('clean', '--environment')
class PycacheCleanupTests(DirectoryCleanupMixin, unittest.TestCase):
def setUp(self):
super(PycacheCleanupTests, self).setUp()
self.test_root = self.create_directory('test-root')
starting_dir = os.curdir
self.addCleanup(os.chdir, starting_dir)
os.chdir(self.test_root)
def test_that_pycache_directories_are_removed(self):
all_dirs = self.mkdirs(
os.path.join(self.test_root, '__pycache__'),
os.path.join(self.test_root, 'a', '__pycache__'),
os.path.join(self.test_root, 'a', 'b', '__pycache__'),
os.path.join(self.test_root, 'b', '__pycache__'),
)
run_setup('clean', '--pycache')
for cache_dir in all_dirs:
self.assert_path_does_not_exist(cache_dir)
def test_that_janitor_does_not_fail_when_cache_parent_is_removed(self):
all_dirs = self.mkdirs(
os.path.join(self.test_root, 'dist'),
os.path.join(self.test_root, 'dist', '__pycache__', '__pycache__'),
os.path.join(self.test_root, 'dist', 'foo', '__pycache__'),
)
run_setup('clean', '--dist', '--pycache')
for cache_dir in all_dirs:
self.assert_path_does_not_exist(cache_dir)
class RemoveAllTests(DirectoryCleanupMixin, unittest.TestCase):
@classmethod
def setUpClass(cls):
super(RemoveAllTests, cls).setUpClass()
test_root = cls.create_directory('test-root')
starting_dir = os.curdir
saved_env_dir = os.environ.get('VIRTUAL_ENV', None)
def restore():
os.chdir(starting_dir)
os.environ.pop('VIRTUAL_ENV', None)
if saved_env_dir is not None:
os.environ['VIRTUAL_ENV'] = saved_env_dir
os.chdir(test_root)
try:
all_dirs = cls.mkdirs(
'__pycache__',
'dist',
'foo.egg-info',
'env',
)
cls.pycache_dir = all_dirs[0]
cls.dist_dir = all_dirs[1]
cls.egg_dir = all_dirs[2]
cls.env_dir = all_dirs[3]
os.environ['VIRTUAL_ENV'] = cls.env_dir
run_setup('clean', '--all')
restore()
except:
restore()
raise
def test_that_pycache_is_removed(self):
self.assert_path_does_not_exist(self.pycache_dir)
def test_that_distdir_is_removed(self):
self.assert_path_does_not_exist(self.dist_dir)
def test_that_eggdir_is_removed(self):
self.assert_path_does_not_exist(self.egg_dir)
def test_that_envdir_is_removed(self):
self.assert_path_does_not_exist(self.env_dir)