@@ -80,12 +80,28 @@ def cleanup_travis_junk(stdout=sys.stdout, stderr=sys.stderr, proc=proc):
8080# -----------------
8181
8282def _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
8893def 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
114154def 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
120168def 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
134190class 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
173241def 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'
@@ -180,10 +250,34 @@ def get_docker_hostname():
180250
181251
182252def image_for_distro (distro ):
183- return 'mitogen/%s-test' % (distro .partition ('-' )[0 ],)
253+ """Return the container image name or path for a test distro name.
254+
255+ 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'
261+ """
262+ return 'public.ecr.aws/n5z0e8q9/%s-test' % (distro .partition ('-' )[0 ],)
184263
185264
186265def 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+ """
187281 docker_hostname = get_docker_hostname ()
188282 firstbit = lambda s : (s + '-' ).split ('-' )[0 ]
189283 secondbit = lambda s : (s + '-' ).split ('-' )[1 ]
@@ -256,6 +350,14 @@ def get_interesting_procs(container_name=None):
256350
257351
258352def 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+ """
259361 if os .environ .get ('KEEP' ):
260362 return
261363
0 commit comments