Merge "Introduced command 'env redeploy' in v2 version of fuelclient"

This commit is contained in:
Jenkins 2016-04-04 10:07:37 +00:00 committed by Gerrit Code Review
commit a54da335f1
9 changed files with 213 additions and 30 deletions

View File

@ -201,14 +201,35 @@ class EnvDeploy(EnvMixIn, base.BaseCommand):
parser.add_argument('id',
type=int,
help='Id of the nailgun entity to be processed.')
help='Id of the environment to be deployed.')
return parser
def take_action(self, parsed_args):
task_id = self.client.deploy_changes(parsed_args.id)
msg = 'Deploy task with id {t} for the environment {e} '\
msg = 'Deployment task with id {t} for the environment {e} '\
'has been started.\n'.format(t=task_id, e=parsed_args.id)
self.app.stdout.write(msg)
class EnvRedeploy(EnvMixIn, base.BaseCommand):
"""Redeploys changes on the specified environment."""
def get_parser(self, prog_name):
parser = super(EnvRedeploy, self).get_parser(prog_name)
parser.add_argument('id',
type=int,
help='Id of the environment to be redeployed.')
return parser
def take_action(self, parsed_args):
task_id = self.client.redeploy_changes(parsed_args.id)
msg = 'Deployment task with id {t} for the environment {e} '\
'has been started.\n'.format(t=task_id, e=parsed_args.id)
self.app.stdout.write(msg)

View File

@ -14,4 +14,21 @@
# License for the specific language governing permissions and limitations
# under the License.
from collections import namedtuple
def Enum(*values, **kwargs):
names = kwargs.get('names')
if names:
return namedtuple('Enum', names)(*values)
return namedtuple('Enum', values)(*values)
SERIALIZATION_FORMAT_FLAG = 'serialization_format'
TASK_STATUSES = Enum(
'error',
'pending',
'ready',
'running'
)

View File

@ -12,24 +12,27 @@
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import os
import re
import shutil
import subprocess
import sys
import tempfile
import time
from oslotest import base as oslo_base
from fuelclient import consts
from fuelclient.objects import Release
from oslotest import base as oslo_base
logging.basicConfig(stream=sys.stderr)
log = logging.getLogger("CliTest.ExecutionLog")
log.setLevel(logging.DEBUG)
class CliExectutionResult(object):
class CliExecutionResult(object):
def __init__(self, process_handle, out, err):
self.return_code = process_handle.returncode
self.stdout = out
@ -45,6 +48,8 @@ class CliExectutionResult(object):
class BaseTestCase(oslo_base.BaseTestCase):
handler = ''
nailgun_root = os.environ.get('NAILGUN_ROOT', '/tmp/fuel_web/nailgun')
def setUp(self):
@ -91,7 +96,7 @@ class BaseTestCase(oslo_base.BaseTestCase):
def run_cli_command(self, command_line,
check_errors=True, env=os.environ.copy()):
command_args = [" ".join(('fuel', command_line))]
command_args = [" ".join((self.handler, command_line))]
process_handle = subprocess.Popen(
command_args,
stdout=subprocess.PIPE,
@ -100,7 +105,7 @@ class BaseTestCase(oslo_base.BaseTestCase):
env=env
)
out, err = process_handle.communicate()
result = CliExectutionResult(process_handle, out, err)
result = CliExecutionResult(process_handle, out, err)
log.debug("command_args: '%s',stdout: '%s', stderr: '%s'",
command_args[0], out, err)
if check_errors:
@ -129,6 +134,12 @@ class BaseTestCase(oslo_base.BaseTestCase):
call = self.run_cli_command(command, check_errors=check_errors)
self.assertEqual(call.stdout, msg)
def check_for_stdout_by_regexp(self, command, pattern, check_errors=True):
call = self.run_cli_command(command, check_errors=check_errors)
result = re.search(pattern, call.stdout)
self.assertIsNotNone(result)
return result
def check_for_stderr(self, command, msg, check_errors=True):
call = self.run_cli_command(command, check_errors=check_errors)
self.assertIn(msg, call.stderr)
@ -147,3 +158,59 @@ class BaseTestCase(oslo_base.BaseTestCase):
def check_number_of_rows_in_table(self, command, number_of_rows):
output = self.run_cli_command(command)
self.assertEqual(len(output.stdout.split("\n")), number_of_rows + 3)
def _get_task_info(self, task_id):
"""Get info about task with given ID.
:param task_id: Task ID
:type task_id: str or int
:return: Task info
:rtype: dict
"""
return {}
def wait_task_ready(self, task_id, timeout=60, interval=3):
"""Wait for changing task status to 'ready'.
:param task_id: Task ID
:type task_id: str or int
:param timeout: Max time of waiting, in seconds
:type timeout: int
:param interval: Interval of getting task info, in seconds
:type interval: int
"""
wait_until_in_statuses = (consts.TASK_STATUSES.running,
consts.TASK_STATUSES.pending)
timer = time.time()
while True:
task = self._get_task_info(task_id)
status = task.get('status', '')
if status not in wait_until_in_statuses:
self.assertEqual(status, consts.TASK_STATUSES.ready)
break
if time.time() - timer > timeout:
raise Exception(
"Task '{0}' seems to be hanged".format(task['name'])
)
time.sleep(interval)
class CLIv1TestCase(BaseTestCase):
handler = 'fuel'
def _get_task_info(self, task_id):
command = "task --task {0} --json".format(str(task_id))
call = self.run_cli_command(command)
return json.loads(call.stdout)[0]
class CLIv2TestCase(BaseTestCase):
handler = 'fuel2'
def _get_task_info(self, task_id):
command = "task show -f json {0}".format(str(task_id))
call = self.run_cli_command(command)
return json.loads(call.stdout)

View File

@ -20,7 +20,7 @@ import tempfile
from fuelclient.tests.functional import base
class TestHandlers(base.BaseTestCase):
class TestHandlers(base.CLIv1TestCase):
def test_env_action(self):
# check env help
@ -289,7 +289,7 @@ class TestHandlers(base.BaseTestCase):
)
class TestCharset(base.BaseTestCase):
class TestCharset(base.CLIv1TestCase):
def test_charset_problem(self):
self.load_data_to_nailgun_server()
@ -301,7 +301,7 @@ class TestCharset(base.BaseTestCase):
))
class TestFiles(base.BaseTestCase):
class TestFiles(base.CLIv1TestCase):
def test_file_creation(self):
self.load_data_to_nailgun_server()
@ -393,7 +393,7 @@ class TestFiles(base.BaseTestCase):
))
class TestDownloadUploadNodeAttributes(base.BaseTestCase):
class TestDownloadUploadNodeAttributes(base.CLIv1TestCase):
def test_upload_download_interfaces(self):
self.load_data_to_nailgun_server()
@ -415,35 +415,43 @@ class TestDownloadUploadNodeAttributes(base.BaseTestCase):
self.upload_command(cmd)))
class TestDeployChanges(base.BaseTestCase):
class TestDeployChanges(base.CLIv1TestCase):
create_env = "env create --name=test --release={0}"
add_node = "--env-id=1 node set --node 1 --role=controller"
deploy_changes = "deploy-changes --env 1"
redeploy_changes = "redeploy-changes --env 1"
cmd_create_env = "env create --name=test --release={0}"
cmd_add_node = "--env-id=1 node set --node 1 --role=controller"
cmd_deploy_changes = "deploy-changes --env 1"
cmd_redeploy_changes = "redeploy-changes --env 1"
messages_success = [
"Deploying changes to environment with id=1\n",
"Finished deployment!\n"
]
message_error = "(No changes to deploy)\n"
def setUp(self):
super(TestDeployChanges, self).setUp()
self.load_data_to_nailgun_server()
release_id = self.get_first_deployable_release_id()
self.create_env = self.create_env.format(release_id)
self.run_cli_commands((self.create_env, self.add_node))
self.cmd_create_env = self.cmd_create_env.format(release_id)
self.run_cli_commands((
self.cmd_create_env,
self.cmd_add_node
))
def test_deploy_changes(self):
self.run_cli_commands((self.deploy_changes,))
def test_no_changes_to_deploy(self):
self.run_cli_commands((self.deploy_changes,))
self.check_for_stderr(self.deploy_changes,
"(No changes to deploy)\n",
check_errors=False)
self.check_all_in_msg(self.cmd_deploy_changes,
self.messages_success)
def test_redeploy_changes(self):
self.run_cli_commands((self.deploy_changes,
self.redeploy_changes))
self.run_cli_command(self.cmd_deploy_changes)
self.check_for_stderr(self.cmd_deploy_changes,
self.message_error,
check_errors=False)
self.check_all_in_msg(self.cmd_redeploy_changes,
self.messages_success)
class TestDirectoryDoesntExistErrorMessages(base.BaseTestCase):
class TestDirectoryDoesntExistErrorMessages(base.CLIv1TestCase):
def test_settings_upload(self):
self.check_for_stderr(
@ -520,7 +528,7 @@ class TestDirectoryDoesntExistErrorMessages(base.BaseTestCase):
)
class TestUploadSettings(base.BaseTestCase):
class TestUploadSettings(base.CLIv1TestCase):
create_env = "env create --name=test --release={0}"
add_node = "--env-id=1 node set --node 1 --role=controller"

View File

@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
#
# Copyright 2013-2014 Mirantis, Inc.
#
# 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.
from fuelclient.tests.functional import base
class TestDeployChanges(base.CLIv2TestCase):
cmd_create_env = "env create -r {0} cluster-test"
cmd_add_node = "env add nodes -e 1 -n 1 -r controller"
cmd_deploy_changes = "env deploy 1"
cmd_redeploy_changes = "env redeploy 1"
pattern_success = (r"^Deployment task with id (\d{1,}) "
r"for the environment 1 has been started.\n$")
message_error = "(No changes to deploy)\n"
def setUp(self):
super(TestDeployChanges, self).setUp()
self.load_data_to_nailgun_server()
release_id = self.get_first_deployable_release_id()
self.cmd_create_env = self.cmd_create_env.format(release_id)
self.run_cli_commands((
self.cmd_create_env,
self.cmd_add_node
))
def test_deploy_changes(self):
self.check_for_stdout_by_regexp(self.cmd_deploy_changes,
self.pattern_success)
def test_redeploy_changes(self):
result = self.check_for_stdout_by_regexp(self.cmd_deploy_changes,
self.pattern_success)
task_id = result.group(1)
self.wait_task_ready(task_id)
self.check_for_stderr(self.cmd_deploy_changes,
self.message_error,
check_errors=False)
self.check_for_stdout_by_regexp(self.cmd_redeploy_changes,
self.pattern_success)

View File

@ -95,6 +95,13 @@ class TestEnvCommand(test_engine.BaseCLITest):
self.m_get_client.assert_called_once_with('environment', mock.ANY)
self.m_client.deploy_changes.assert_called_once_with(42)
def test_env_redeploy(self):
args = 'env redeploy 42'
self.exec_command(args)
self.m_get_client.assert_called_once_with('environment', mock.ANY)
self.m_client.redeploy_changes.assert_called_once_with(42)
def test_env_add_nodes(self):
args = 'env add nodes -e 42 -n 24 25 -r compute cinder'
self.exec_command(args)

View File

@ -71,6 +71,12 @@ class EnvironmentClient(base_v1.BaseV1Client):
return deploy_task.id
def redeploy_changes(self, environment_id):
env = self._entity_wrapper(obj_id=environment_id)
redeploy_task = env.redeploy_changes()
return redeploy_task.id
def spawn_vms(self, environment_id):
env = self._entity_wrapper(obj_id=environment_id)
return env.spawn_vms()

View File

@ -34,6 +34,7 @@ fuelclient =
env_delete=fuelclient.commands.environment:EnvDelete
env_deploy=fuelclient.commands.environment:EnvDeploy
env_list=fuelclient.commands.environment:EnvList
env_redeploy=fuelclient.commands.environment:EnvRedeploy
env_show=fuelclient.commands.environment:EnvShow
env_spawn-vms=fuelclient.commands.environment:EnvSpawnVms
env_update=fuelclient.commands.environment:EnvUpdate

View File

@ -14,7 +14,7 @@ setenv = VIRTUAL_ENV={envdir}
# Functional env settings
FUEL_WEB_CLONE={env:FUEL_WEB_CLONE:yes}
FUEL_WEB_REPO={env:FUEL_WEB_REPO:https://github.com/stackforge/fuel-web.git}
FUEL_WEB_REPO={env:FUEL_WEB_REPO:https://github.com/openstack/fuel-web.git}
FUEL_WEB_ROOT={env:FUEL_WEB_ROOT:/tmp/fuel_web}
FETCH_REPO={env:FETCH_REPO:}
FETCH_REFSPEC={env:FETCH_REFSPEC:}