Skip to content

Commit dd3a6f1

Browse files
committed
tests: docstrings for ci_lib
(cherry picked from commit 9923507)
1 parent eabb7e3 commit dd3a6f1

File tree

1 file changed

+100
-2
lines changed

1 file changed

+100
-2
lines changed

.ci/ci_lib.py

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,28 @@ def cleanup_travis_junk(stdout=sys.stdout, stderr=sys.stderr, proc=proc):
8080
# -----------------
8181

8282
def _argv(s, *args):
83+
"""Interpolate a command line using *args, return an argv style list.
84+
85+
>>> _argv('git commit -m "Use frobnicate 2.0 (fixes #%d)"', 1234)
86+
['git', commit', '-m', 'Use frobnicate 2.0 (fixes #1234)']
87+
"""
8388
if args:
8489
s %= args
8590
return shlex.split(s)
8691

8792

8893
def run(s, *args, **kwargs):
94+
""" Run a command, with arguments, and print timing information
95+
96+
>>> rc = run('echo "%s %s"', 'foo', 'bar')
97+
Running: ['/usr/bin/time', '--', 'echo', 'foo bar']
98+
foo bar
99+
0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 1964maxresident)k
100+
0inputs+0outputs (0major+71minor)pagefaults 0swaps
101+
Finished running: ['/usr/bin/time', '--', 'echo', 'foo bar']
102+
>>> rc
103+
0
104+
"""
89105
argv = ['/usr/bin/time', '--'] + _argv(s, *args)
90106
print('Running: %s' % (argv,))
91107
try:
@@ -98,12 +114,36 @@ def run(s, *args, **kwargs):
98114
return ret
99115

100116

101-
def run_batches(batches):
102-
combine = lambda batch: 'set -x; ' + (' && '.join(
117+
def combine(batch):
118+
"""
119+
>>> combine(['ls -l', 'echo foo'])
120+
'set -x; ( ls -l; ) && ( echo foo; )'
121+
"""
122+
return 'set -x; ' + (' && '.join(
103123
'( %s; )' % (cmd,)
104124
for cmd in batch
105125
))
106126

127+
128+
def run_batches(batches):
129+
""" Run shell commands grouped into batches, showing an execution trace.
130+
131+
Raise AssertionError if any command has exits with a non-zero status.
132+
133+
>>> run_batches([['echo foo', 'true']])
134+
+ echo foo
135+
foo
136+
+ true
137+
>>> run_batches([['true', 'echo foo'], ['false']])
138+
+ true
139+
+ echo foo
140+
foo
141+
+ false
142+
Traceback (most recent call last):
143+
File "...", line ..., in <module>
144+
File "...", line ..., in run_batches
145+
AssertionError
146+
"""
107147
procs = [
108148
subprocess.Popen(combine(batch), shell=True)
109149
for batch in batches
@@ -112,12 +152,28 @@ def run_batches(batches):
112152

113153

114154
def get_output(s, *args, **kwargs):
155+
"""
156+
Print and run command line s, %-interopolated using *args. Return stdout.
157+
158+
>>> s = get_output('echo "%s %s"', 'foo', 'bar')
159+
Running: ['echo', 'foo bar']
160+
>>> s
161+
'foo bar\n'
162+
"""
115163
argv = _argv(s, *args)
116164
print('Running: %s' % (argv,))
117165
return subprocess.check_output(argv, **kwargs)
118166

119167

120168
def exists_in_path(progname):
169+
"""
170+
Return True if proganme exists in $PATH.
171+
172+
>>> exists_in_path('echo')
173+
True
174+
>>> exists_in_path('kwyjibo') # Only found in North American cartoons
175+
False
176+
"""
121177
return any(os.path.exists(os.path.join(dirname, progname))
122178
for dirname in os.environ['PATH'].split(os.pathsep))
123179

@@ -132,6 +188,18 @@ def destroy(self, rmtree=shutil.rmtree):
132188

133189

134190
class Fold(object):
191+
"""
192+
Bracket a section of stdout with travis_fold markers.
193+
194+
This allows the section to be collapsed or expanded in Travis CI web UI.
195+
196+
>>> with Fold('stage 1'):
197+
... print('Frobnicate the frobnitz')
198+
...
199+
travis_fold:start:stage 1
200+
Frobnicate the frobnitz
201+
travis_fold:end:stage 1
202+
"""
135203
def __init__(self, name):
136204
self.name = name
137205

@@ -171,6 +239,8 @@ def __exit__(self, _1, _2, _3):
171239
)
172240

173241
def get_docker_hostname():
242+
"""Return the hostname where the docker daemon is running.
243+
"""
174244
url = os.environ.get('DOCKER_HOST')
175245
if url in (None, 'http+docker://localunixsocket'):
176246
return 'localhost'
@@ -183,11 +253,31 @@ def image_for_distro(distro):
183253
"""Return the container image name or path for a test distro name.
184254
185255
The returned value is suitable for use with `docker pull`.
256+
257+
>>> image_for_distro('centos5')
258+
'public.ecr.aws/n5z0e8q9/centos5-test'
259+
>>> image_for_distro('centos5-something_custom')
260+
'public.ecr.aws/n5z0e8q9/centos5-test'
186261
"""
187262
return 'public.ecr.aws/n5z0e8q9/%s-test' % (distro.partition('-')[0],)
188263

189264

190265
def make_containers(name_prefix='', port_offset=0):
266+
"""
267+
>>> import pprint
268+
>>> BASE_PORT=2200; DISTROS=['debian', 'centos6']
269+
>>> pprint.pprint(make_containers())
270+
[{'distro': 'debian',
271+
'hostname': 'localhost',
272+
'name': 'target-debian-1',
273+
'port': 2201,
274+
'python_path': '/usr/bin/python'},
275+
{'distro': 'centos6',
276+
'hostname': 'localhost',
277+
'name': 'target-centos6-2',
278+
'port': 2202,
279+
'python_path': '/usr/bin/python'}]
280+
"""
191281
docker_hostname = get_docker_hostname()
192282
firstbit = lambda s: (s+'-').split('-')[0]
193283
secondbit = lambda s: (s+'-').split('-')[1]
@@ -260,6 +350,14 @@ def get_interesting_procs(container_name=None):
260350

261351

262352
def start_containers(containers):
353+
"""Run docker containers in the background, with sshd on specified ports.
354+
355+
>>> containers = start_containers([
356+
... {'distro': 'debian', 'hostname': 'localhost',
357+
... 'name': 'target-debian-1', 'port': 2201,
358+
... 'python_path': '/usr/bin/python'},
359+
... ])
360+
"""
263361
if os.environ.get('KEEP'):
264362
return
265363

0 commit comments

Comments
 (0)