Skip to content

Commit

Permalink
Add inject option for ipa testing.
Browse files Browse the repository at this point in the history
Provides the following options for injection:

:inject_packages: an rpm path or list of rpm paths which will be
                  copied and installed on instance.
:inject_archives: an archive or list of archives which will
                  be copied and extracted on instance.
:inject_files: a file path or list of file paths which
               will be copied to instance.
:execute: a command or list of commands to run.
:install: a package name or list of package names to
         install from an existing repo.

The injection happens in that order.
  • Loading branch information
smarlowucf committed May 10, 2018
1 parent f733781 commit b6155f4
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 0 deletions.
2 changes: 2 additions & 0 deletions ipa/ipa_azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def __init__(self,
early_exit=None,
history_log=None,
image_id=None,
inject=None,
instance_type=None,
log_level=30,
no_default_test_dirs=False,
Expand All @@ -72,6 +73,7 @@ def __init__(self,
early_exit,
history_log,
image_id,
inject,
instance_type,
log_level,
no_default_test_dirs,
Expand Down
2 changes: 2 additions & 0 deletions ipa/ipa_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def test_image(provider_name,
early_exit=None,
history_log=None,
image_id=None,
inject=None,
instance_type=None,
log_level=None,
no_default_test_dirs=None,
Expand Down Expand Up @@ -83,6 +84,7 @@ def test_image(provider_name,
early_exit=early_exit,
history_log=history_log,
image_id=image_id,
inject=inject,
instance_type=instance_type,
log_level=log_level,
no_default_test_dirs=no_default_test_dirs,
Expand Down
2 changes: 2 additions & 0 deletions ipa/ipa_ec2.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def __init__(self,
early_exit=None,
history_log=None,
image_id=None,
inject=None,
instance_type=None,
log_level=30,
no_default_test_dirs=False,
Expand Down Expand Up @@ -75,6 +76,7 @@ def __init__(self,
early_exit,
history_log,
image_id,
inject,
instance_type,
log_level,
no_default_test_dirs,
Expand Down
2 changes: 2 additions & 0 deletions ipa/ipa_gce.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def __init__(self,
early_exit=None,
history_log=None,
image_id=None,
inject=None,
instance_type=None,
log_level=30,
no_default_test_dirs=False,
Expand All @@ -75,6 +76,7 @@ def __init__(self,
early_exit,
history_log,
image_id,
inject,
instance_type,
log_level,
no_default_test_dirs,
Expand Down
70 changes: 70 additions & 0 deletions ipa/ipa_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ def __init__(self,
early_exit=None,
history_log=None,
image_id=None,
inject=None,
instance_type=None,
log_level=None,
no_default_test_dirs=False,
Expand Down Expand Up @@ -102,6 +103,7 @@ def __init__(self,
self.distro_name = self._get_value(distro_name)
self.early_exit = self._get_value(early_exit)
self.image_id = self._get_value(image_id)
self.inject = self._get_value(inject)
self.instance_type = self._get_value(instance_type)
self.running_instance_id = self._get_value(running_instance_id)
self.test_files = list(self._get_value(test_files, default=[]))
Expand Down Expand Up @@ -447,6 +449,71 @@ def install_package(self, client, package):
log_file.write('\n')
log_file.write(out)

def process_injection_file(self, client):
"""
Load yaml file and process injection configuration.
There are 5 injection options:
:inject_packages: an rpm path or list of rpm paths which will be
copied and installed on instance.
:inject_archives: an archive or list of archives which will
be copied and extracted on instance.
:inject_files: a file path or list of file paths which
will be copied to instance.
:execute: a command or list of commands to run.
:install: a package name or list of package names to
install from an existing repo.
"""
configuration = ipa_utils.get_yaml_config(self.inject)

if configuration.get('inject_packages'):
inject_packages = configuration['inject_packages']

if not isinstance(inject_packages, list):
inject_packages = [inject_packages]

for package in inject_packages:
package_path = self.put_file(client, package)
self.install_package(client, package_path)

if configuration.get('inject_archives'):
inject_archives = configuration['inject_archives']

if not isinstance(inject_archives, list):
inject_archives = [inject_archives]

for archive in inject_archives:
archive_path = self.put_file(client, archive)
self.extract_archive(client, archive_path)

if configuration.get('inject_files'):
inject_files = configuration['inject_files']

if not isinstance(inject_files, list):
inject_files = [inject_files]

for file_path in inject_files:
self.put_file(client, file_path)

if configuration.get('execute'):
execute = configuration['execute']

if not isinstance(execute, list):
execute = [execute]

for command in execute:
self.execute_ssh_command(client, command)

if configuration.get('install'):
install = configuration['install']

if not isinstance(install, list):
install = [install]

for package in install:
self.install_package(client, package)

def put_file(self, client, source_file):
"""
Put file on instance in default SSH directory.
Expand Down Expand Up @@ -507,6 +574,9 @@ def test_image(self):
self._set_distro()
self._log_info()

if self.inject:
self.process_injection_file(self._get_ssh_client())

status = 0
with ipa_utils.ssh_config(self.ssh_user, self.ssh_private_key)\
as ssh_config:
Expand Down
7 changes: 7 additions & 0 deletions ipa/scripts/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ def main(context, no_color):
'--image-id',
help='The ID of the image used for instance.'
)
@click.option(
'--inject',
help='Path to an injection yaml config file.',
type=click.Path(exists=True)
)
@click.option(
'-t',
'--instance-type',
Expand Down Expand Up @@ -228,6 +233,7 @@ def test(context,
early_exit,
history_log,
image_id,
inject,
instance_type,
log_level,
no_default_test_dirs,
Expand Down Expand Up @@ -260,6 +266,7 @@ def test(context,
early_exit,
history_log,
image_id,
inject,
instance_type,
log_level,
no_default_test_dirs,
Expand Down
5 changes: 5 additions & 0 deletions tests/data/injection/test_injection.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
inject_packages: /home/user/test.noarch.rpm
inject_archives: /home/user/test.tar.xz
install: python3
inject_files: /home/user/test.py
execute: python test.py
38 changes: 38 additions & 0 deletions tests/test_ipa_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,44 @@ def test_provider_install_package(self):
call('package install successful!')
])

@patch.object(IpaProvider, 'execute_ssh_command')
@patch.object(IpaProvider, 'extract_archive')
@patch.object(IpaProvider, 'install_package')
@patch.object(IpaProvider, 'put_file')
def test_process_injection_file(self,
mock_put_file,
mock_install_package,
mock_extract_archive,
mock_execute_command):
client = MagicMock()
mock_put_file.side_effect = [
'test.noarch.rpm', 'test.tar.xz', 'test.py'
]

provider = IpaProvider(*args, **self.kwargs)
provider.inject = 'tests/data/injection/test_injection.yaml'

provider.process_injection_file(client)

mock_put_file.assert_has_calls([
call(client, '/home/user/test.noarch.rpm'),
call(client, '/home/user/test.tar.xz'),
call(client, '/home/user/test.py')
])

mock_install_package.assert_has_calls([
call(client, 'test.noarch.rpm'),
call(client, 'python3')
])

mock_extract_archive.assert_called_once_with(
client, 'test.tar.xz'
)

mock_execute_command.assert_called_once_with(
client, 'python test.py'
)

@patch.object(IpaProvider, '_set_instance_ip')
@patch.object(IpaProvider, '_set_image_id')
@patch.object(IpaProvider, '_start_instance_if_stopped')
Expand Down

0 comments on commit b6155f4

Please sign in to comment.