moved and renamed fuel-cli

added tests, modified run_tests.sh

fixed some mode redundancy

fixed run_tests.sh

removed old code

Change-Id: I7660e550d40a4c77df2179a947b87a492984c682
This commit is contained in:
Alexandr Notchenko
2013-11-21 17:58:57 +04:00
commit 4c91d20a91
6 changed files with 1978 additions and 0 deletions

13
__init__.py Normal file
View File

@@ -0,0 +1,13 @@
# Copyright 2013 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.

1723
fuel Executable file

File diff suppressed because it is too large Load Diff

28
setup.py Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env python
# Copyright 2013 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 setuptools import setup
setup(
name='python-fuelclient',
version='0.1',
description='Command line interface for Nailgun',
long_description="""Command line interface for Nailgun""",
author='Mirantis Inc.',
author_email='product@mirantis.com',
url='http://mirantis.com',
install_requires=['PyYAML==3.10'],
scripts=['fuel']
)

13
tests/__init__.py Normal file
View File

@@ -0,0 +1,13 @@
# Copyright 2013 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.

133
tests/base.py Normal file
View File

@@ -0,0 +1,133 @@
# -*- coding: utf-8 -*-
# Copyright 2013 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.
try:
from unittest.case import TestCase
except ImportError:
# Runing unit-tests in production environment
from unittest2.case import TestCase
import logging
import os
import subprocess
import sys
logging.basicConfig(stream=sys.stderr)
logging.getLogger("SomeTest.testSomething").setLevel(logging.DEBUG)
class CliExectutionResult:
def __init__(self, process_handle):
self.return_code = process_handle.returncode
self.stdout = process_handle.stdout.read()
self.stderr = process_handle.stderr.read()
@property
def has_errors(self):
return bool(len(self.stderr))
@property
def is_return_code_zero(self):
return self.return_code == 0
class BaseTestCase(TestCase):
root_path = os.path.abspath(
os.path.join(
os.curdir,
os.path.pardir
)
)
clean_cmd = os.path.join(
root_path,
"run_tests.sh"
) + " -c"
manage_path = os.path.join(
root_path,
"nailgun/manage.py"
)
fuel_path = os.path.join(
root_path,
"fuelclient/fuel"
)
@classmethod
def setUpClass(cls):
cls.reload_nailgun_server()
@classmethod
def reload_nailgun_server(cls):
for action in ("dropdb", "syncdb", "loaddefault"):
cls.run_command(cls.manage_path, action)
@classmethod
def load_data_to_nailgun_server(cls):
cls.run_command(cls.manage_path, "loaddata {0}".format(
os.path.join(
cls.root_path,
"nailgun/nailgun/fixtures/sample_environment.json"
)
))
@staticmethod
def run_command(*args):
handle = subprocess.Popen(
[" ".join(args + (">/dev/null", "2>&1"))],
shell=True
)
print("Running " + " ".join(args))
handle.wait()
def run_cli_command(self, command_line=None, with_erros=False):
modified_env = os.environ.copy()
modified_env["LISTEN_PORT"] = "8003"
command_args = [" ".join((self.fuel_path, command_line))]
log = logging.getLogger("SomeTest.testSomething")
process_handle = subprocess.Popen(
command_args,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True,
env=modified_env
)
process_handle.wait()
result = CliExectutionResult(process_handle)
log.debug("command_args: '%s',stdout: '%s', stderr: '%s'",
command_args[0], result.stdout, result.stderr)
if not with_erros:
if not result.is_return_code_zero or result.has_errors:
self.fail()
return result
def check_if_required(self, command):
call = self.run_cli_command(command_line=command, with_erros=True)
#should not work without env id
self.assertIn("required", call.stderr)
def check_for_stdout(self, command, msg):
call = self.run_cli_command(command_line=command)
self.assertEqual(call.stdout, msg)
def check_all_in_msg(self, command, substrs):
output = self.run_cli_command(command_line=command)
for substr in substrs:
self.assertIn(substr, output.stdout)
def check_for_rows_in_table(self, command):
output = self.run_cli_command(command_line=command)
message = output.stdout.split("\n")
#no env
self.assertEqual(message[2], '')

68
tests/test_client.py Normal file
View File

@@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
# Copyright 2013 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.base import BaseTestCase
class TestHandlers(BaseTestCase):
def test_env_action(self):
#check env help
help_msgs = ["usage: fuel [global optional args]",
"environment [-h] [-l] [-s] [--delete]",
"optional arguments:", "--help", "--list", "--set",
"--delete", "--rel", "--release", "--env-create,",
"--create", "--name", "--env-name", "--mode", "--net",
"--network-mode", "--nst", "--net-segment-type",
"--deployment-mode"]
self.check_all_in_msg("env --help", help_msgs)
#no clusters
self.check_for_rows_in_table("env")
for action in ("set", "create", "delete"):
self.check_if_required("env {0}".format(action))
#list of tuples (<fuel CLI command>, <expected output of a command>)
expected_stdout = \
[(
"env create --name=TestEnv --release=1",
"Environment 'TestEnv' with id=1, mode=multinode and "
"network-mode=nova_network was created!\n"
), (
"--env-id=1 env set --name=NewEnv",
"Environment with id=1 was renamed to 'NewEnv'.\n"
), (
"--env-id=1 env set --mode=ha",
"Mode of environment with id=1 was set to 'ha'.\n"
)]
for cmd, msg in expected_stdout:
self.check_for_stdout(cmd, msg)
def test_node_action(self):
help_msg = ["usage: fuel [global optional args] node [-h] ",
"[-l] [-s] [--delete] [--default]", "-h", "--help", "-l",
"--list", "-s", "--set", "--delete", "--default", "-d",
"--download", "-u", "--upload", "--dir", "--node",
"--node-id", "-r", "--role", "--net", "--network",
"--disk", "-f", "--force"]
self.check_all_in_msg("node --help", help_msg)
self.check_for_rows_in_table("node")
for action in ("set", "remove", "--network", "--disk"):
self.check_if_required("node {0}".format(action))