Add support for multiple images

This patch adds support for running tests on multiple images. Instead of
parsing just 1 image, it attempts to always parse multiple images from
config files and/or CLI.

To run dox on multiple images from the CLI, you'll have to:

    $ dox -i infra/trusty,infra/f20

The tox.ini `docker:images` option is now a comma-separated list of
images, whereas the dox.yml one is an array of images.

Change-Id: I124c299b208be5c31c63187af754705c48de5693
This commit is contained in:
Flavio Percoco 2014-09-08 09:16:35 +02:00 committed by Flavio Percoco
parent 2ea441b29d
commit de82bcdf77
7 changed files with 49 additions and 41 deletions

View File

@ -1,4 +1,5 @@
image: infra/trusty
images:
- infra/trusty
add:
- requirements.txt
- test-requirements.txt

View File

@ -14,6 +14,7 @@
# limitations under the License.
import argparse
import functools
import logging
import dox.commands
@ -46,8 +47,8 @@ def parse_args():
parser.add_argument(dest='extra_args', nargs='*',
help='args to append to command, or command to run'
' if -c is given')
parser.add_argument('-i', '--image', dest='image',
help='Base image to use')
parser.add_argument('-i', '--images', dest='images',
help='Base images to use')
parser.add_argument('-c', '--command', dest='command', default=False,
action='store_true',
help='Treat arguments as the entire command to run')
@ -77,9 +78,10 @@ def main():
def run_dox(args):
# Get Image
image = args.image
if args.image is None:
image = dox.images.get_image()
if args.images is None:
images = dox.images.get_images()
else:
images = args.images.split(',')
# Get Command
if args.command:
@ -89,7 +91,9 @@ def run_dox(args):
# Run
try:
return dox.runner.Runner(args).run(image, command)
run = functools.partial(dox.runner.Runner(args).run,
command=command)
map(run, images)
except Exception:
logger.error(
"Operation failed, aborting dox.", exc_info=args.debug)

View File

@ -43,8 +43,8 @@ class DoxYaml(object):
def exists(self):
return os.path.exists('dox.yml')
def get_image(self, image):
return self._open_dox_yaml().get('image', image)
def get_images(self):
return self._open_dox_yaml().get('images', [])
def get_commands(self, extra_args):
return " ".join([self._open_dox_yaml().get('commands')] + extra_args)

View File

@ -43,11 +43,10 @@ class ToxIni(object):
def exists(self):
return os.path.exists('tox.ini')
def get_image(self, image):
def get_images(self):
ini = self._open_tox_ini()
if ini.has_option('docker', 'image'):
image = ini.get('docker', 'image')
return image
if ini.has_option('docker', 'images'):
return ini.get('docker', 'images', '').split(',')
def get_commands(self, extra_args):
ini = self._open_tox_ini()

View File

@ -14,7 +14,7 @@
# limitations under the License.
__all__ = [
'get_image',
'get_images',
]
import dox.config.dockerfile
@ -22,21 +22,24 @@ import dox.config.dox_yaml
import dox.config.tox_ini
def get_image():
def get_images():
'''Examine the local environment and figure out where we should run.'''
dockerfile = dox.config.dockerfile.get_dockerfile()
dox_yaml = dox.config.dox_yaml.get_dox_yaml()
tox_ini = dox.config.tox_ini.get_tox_ini()
# Set default image value
if dockerfile.exists():
image = None
default_images = []
else:
image = 'ubuntu'
# NOTE(flaper87): We should probably raise
# `RuntimeError` if no image was specified
default_images = ['ubuntu']
images = []
if dox_yaml.exists():
image = dox_yaml.get_image(image)
images = dox_yaml.get_images()
elif tox_ini.exists():
image = tox_ini.get_image(image)
return image
images = tox_ini.get_images()
return images or default_images

View File

@ -29,12 +29,12 @@ from dox.tests import base
def get_fake_image(value):
if value:
def fake_value(self, image):
if value is not None:
def fake_value(self):
return value
else:
def fake_value(self, image):
return image
def fake_value(self):
return ['ubuntu']
return fake_value
@ -43,37 +43,38 @@ class TestImages(base.TestCase):
scenarios = [
('have_dockerfile', dict(
dockerfile=True, tox_ini=False, dox_yaml=False,
tox_value=None, dox_value=None, image=None)),
tox_value=[], dox_value=[], images=[])),
('no_dockerfile', dict(
dockerfile=False, tox_ini=False, dox_yaml=False,
tox_value=None, dox_value=None, image='ubuntu')),
tox_value=[], dox_value=[], images=['ubuntu'])),
('tox_no_docker', dict(
dockerfile=False, tox_ini=True, dox_yaml=False,
tox_value=None, dox_value=None, image='ubuntu')),
tox_value=[], dox_value=[], images=['ubuntu'])),
('tox_docker', dict(
dockerfile=False, tox_ini=True, dox_yaml=False,
tox_value='tox_docker', dox_value=None, image='tox_docker')),
tox_value=['tox_docker'], dox_value=[], images=['tox_docker'])),
('dox_image', dict(
dockerfile=False, tox_ini=False, dox_yaml=True,
tox_value=None, dox_value=None, image='ubuntu')),
tox_value=[], dox_value=[], images=['ubuntu'])),
('dox_no_image', dict(
dockerfile=False, tox_ini=False, dox_yaml=True,
tox_value=None, dox_value='dox_value', image='dox_value')),
tox_value=[], dox_value=['dox_value'], images=['dox_value'])),
('both_dox_wins', dict(
dockerfile=False, tox_ini=True, dox_yaml=True,
tox_value='tox_wins', dox_value='dox_wins', image='dox_wins')),
tox_value=['tox_wins'], dox_value=['dox_wins'],
images=['dox_wins'])),
('both_no_dox', dict(
dockerfile=False, tox_ini=True, dox_yaml=True,
tox_value='tox_wins', dox_value=None, image='ubuntu')),
tox_value=['tox_wins'], dox_value=[], images=['ubuntu'])),
('both_dockerfile_passthru', dict(
dockerfile=True, tox_ini=True, dox_yaml=True,
tox_value=None, dox_value=None, image=None)),
tox_value=[], dox_value=[], images=[])),
('all_dockerfile_dox_override', dict(
dockerfile=True, tox_ini=True, dox_yaml=True,
tox_value=None, dox_value='dox_wins', image='dox_wins')),
tox_value=[], dox_value=['dox_wins'], images=['dox_wins'])),
('all_dockerfile_tox_loses', dict(
dockerfile=True, tox_ini=True, dox_yaml=True,
tox_value='tox_wins', dox_value=None, image=None)),
tox_value=['tox_wins'], dox_value=[], images=[])),
]
def setUp(self):
@ -88,15 +89,15 @@ class TestImages(base.TestCase):
'dox.config.tox_ini.ToxIni.exists',
base.bool_to_fake(self.tox_ini)))
self.useFixture(fixtures.MonkeyPatch(
'dox.config.dox_yaml.DoxYaml.get_image',
'dox.config.dox_yaml.DoxYaml.get_images',
get_fake_image(self.dox_value)))
self.useFixture(fixtures.MonkeyPatch(
'dox.config.tox_ini.ToxIni.get_image',
'dox.config.tox_ini.ToxIni.get_images',
get_fake_image(self.tox_value)))
def test_images(self):
image = images.get_image()
self.assertEqual(image, self.image)
image = images.get_images()
self.assertEqual(image, self.images)
def load_tests(loader, in_tests, pattern):

View File

@ -30,4 +30,4 @@ builtins = _
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build
[docker]
image = infra/trusty
images = infra/trusty