Start of docker hook unit tests

Other hooks process json then execute commands. The docker hook
makes socket API calls via the docker-py module. For this reason
a different approach has been taken with testing this hook:
- symlink hook-docker.py to the tests package as hook_docker.py
- in the test, mock out the docker import and run main() directly

Change-Id: Ia069b2cc0db71952732dea310a8986b73981b656
This commit is contained in:
Steve Baker 2014-11-21 11:06:50 +13:00 committed by Rabi Mishra
parent 67301b6ff4
commit 08d00b0c41
3 changed files with 78 additions and 10 deletions

View File

@ -18,7 +18,11 @@ import logging
import os import os
import sys import sys
import docker try:
import docker
except ImportError:
docker = None
import yaml import yaml
@ -142,7 +146,7 @@ def update_pod_state(pod_state, is_container_running):
def configure_logging(): def configure_logging():
log = logging.getLogger('heat-config') log = logging.getLogger('heat-config')
log.setLevel('DEBUG') log.setLevel(logging.DEBUG)
formatter = logging.Formatter( formatter = logging.Formatter(
'[%(asctime)s] (%(name)s) [%(levelname)s] %(message)s') '[%(asctime)s] (%(name)s) [%(levelname)s] %(message)s')
@ -154,23 +158,23 @@ def configure_logging():
deploy_stdout = cStringIO.StringIO() deploy_stdout = cStringIO.StringIO()
handler = logging.StreamHandler(deploy_stdout) handler = logging.StreamHandler(deploy_stdout)
handler.setFormatter(formatter) handler.setFormatter(formatter)
handler.setLevel('DEBUG') handler.setLevel(logging.DEBUG)
log.addHandler(handler) log.addHandler(handler)
deploy_stderr = cStringIO.StringIO() deploy_stderr = cStringIO.StringIO()
handler = logging.StreamHandler(deploy_stderr) handler = logging.StreamHandler(deploy_stderr)
handler.setFormatter(formatter) handler.setFormatter(formatter)
handler.setLevel('DEBUG') handler.setLevel(logging.WARN)
log.addHandler(handler) log.addHandler(handler)
return log, deploy_stdout, deploy_stderr return log, deploy_stdout, deploy_stderr
def main(argv=sys.argv): def main(argv=sys.argv, sys_stdin=sys.stdin, sys_stdout=sys.stdout):
(log, deploy_stdout, deploy_stderr) = configure_logging() (log, deploy_stdout, deploy_stderr) = configure_logging()
client = get_client(log) client = get_client(log)
c = json.load(sys.stdin) c = json.load(sys_stdin)
pod_name = c.get('name') pod_name = c.get('name')
input_values = dict((i['name'], i['value']) for i in c['inputs']) input_values = dict((i['name'], i['value']) for i in c['inputs'])
@ -182,8 +186,8 @@ def main(argv=sys.argv):
else: else:
yaml_config = yaml.load(config) yaml_config = yaml.load(config)
containers = yaml_config.get('containers') containers = yaml_config.get('containers', [])
volumes = yaml_config.get('volumes') volumes = yaml_config.get('volumes', [])
remove_all_containers_for_pod(client, log, pod_name) remove_all_containers_for_pod(client, log, pod_name)
@ -196,7 +200,7 @@ def main(argv=sys.argv):
'deploy_stderr': deploy_stderr.getvalue(), 'deploy_stderr': deploy_stderr.getvalue(),
'deploy_status_code': 0, 'deploy_status_code': 0,
} }
json.dump(response, sys.stdout) json.dump(response, sys_stdout)
return return
mount_external_volumes(log, volumes) mount_external_volumes(log, volumes)
@ -260,7 +264,7 @@ def main(argv=sys.argv):
'deploy_stderr': deploy_stderr.getvalue(), 'deploy_stderr': deploy_stderr.getvalue(),
'deploy_status_code': pod_state, 'deploy_status_code': pod_state,
} }
json.dump(response, sys.stdout) json.dump(response, sys_stdout)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -0,0 +1 @@
../../hot/software-config/elements/heat-config-docker/install.d/hook-docker.py

View File

@ -0,0 +1,63 @@
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import cStringIO
import json
import mock
import testtools
from testtools import matchers
from tests.software_config import hook_docker
class HookDockerTest(testtools.TestCase):
def setUp(self):
super(HookDockerTest, self).setUp()
docker = mock.MagicMock()
self.docker_client = mock.MagicMock()
docker.Client.return_value = self.docker_client
self.docker_client.version.return_value = {
'ApiVersion': '1.3.0'
}
hook_docker.docker = docker
def assertLogEntries(self, entries, log):
for (entry, line) in zip(entries, log.split('\n')):
self.assertThat(line, matchers.EndsWith(entry))
def test_empty_input(self):
config = {
'name': 'deployment_name',
'options': {},
'inputs': [],
'outputs': [],
'config': {}
}
sys_stdin = cStringIO.StringIO(json.dumps(config))
sys_stdout = cStringIO.StringIO()
hook_docker.main([], sys_stdin, sys_stdout)
response = json.loads(sys_stdout.getvalue())
self.assertLogEntries([
'Connecting to unix:///var/run/docker.sock',
'Connected to version 1.3.0',
'Removing all containers from deployment_name'
], response.pop('deploy_stdout'))
self.assertLogEntries([], response.pop('deploy_stderr'))
self.assertEqual(
{"deploy_status_code": 0}, response)