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:
13
__init__.py
Normal file
13
__init__.py
Normal 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.
|
||||
28
setup.py
Normal file
28
setup.py
Normal 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
13
tests/__init__.py
Normal 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
133
tests/base.py
Normal 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
68
tests/test_client.py
Normal 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))
|
||||
Reference in New Issue
Block a user