Enabled python3 unit tests in tox and zuul

Replaces the unittest2 base module with testtools.
Adds py36 unit test target in tox.ini, called from zuul.
Updates unit tests to pass when run in both py27 and py36.

Add sample CLI unit tests for fw update strategy based on
a mixin for update strategy.

Story: 2007875
Task: 40674
Change-Id: Ia1b94110a53d48249aed76c94b07f8ffc2946bb3
Signed-off-by: albailey <Al.Bailey@windriver.com>
This commit is contained in:
albailey 2020-08-13 07:59:54 -05:00
parent 7036f1fd11
commit f10e0455f0
8 changed files with 156 additions and 13 deletions

View File

@ -9,12 +9,14 @@
- openstack-tox-linters
- stx-distcloud-client-tox-pep8
- stx-distcloud-client-tox-py27
- stx-distcloud-client-tox-py36
- stx-distcloud-client-tox-pylint
gate:
jobs:
- openstack-tox-linters
- stx-distcloud-client-tox-pep8
- stx-distcloud-client-tox-py27
- stx-distcloud-client-tox-py36
- stx-distcloud-client-tox-pylint
post:
jobs:
@ -28,6 +30,14 @@
tox_envlist: py27
tox_extra_args: -c distributedcloud-client/tox.ini
- job:
name: stx-distcloud-client-tox-py36
parent: tox
description: Run py36 for distcloud-client
vars:
tox_envlist: py36
tox_extra_args: -c distributedcloud-client/tox.ini
- job:
name: stx-distcloud-client-tox-pylint
parent: tox

View File

@ -21,9 +21,8 @@
#
import json
import mock
import unittest2
import testtools
class FakeResponse(object):
@ -39,9 +38,12 @@ class FakeResponse(object):
return json.loads(self.content)
class BaseClientTest(unittest2.TestCase):
class BaseClientTest(testtools.TestCase):
_client = None
def setUp(self):
super(BaseClientTest, self).setUp()
def mock_http_get(self, content, status_code=200):
if isinstance(content, dict):
content = json.dumps(content)
@ -76,8 +78,9 @@ class BaseClientTest(unittest2.TestCase):
return self._client.http_client.delete
class BaseCommandTest(unittest2.TestCase):
class BaseCommandTest(testtools.TestCase):
def setUp(self):
super(BaseCommandTest, self).setUp()
self.app = mock.Mock()
self.client = self.app.client_manager.subcloud_manager

View File

@ -0,0 +1,72 @@
#
# Copyright (c) 2020 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
from dcmanagerclient.tests.v1 import utils
class UpdateStrategyMixin(object):
"""Mixin for testing the different types of dcmanager update strategies.
Used by concrete testsuites of strategy types such as patch, upgrade, etc..
Subclasses must:
- mix with BaseCommandTest
- provide: self.sw_update_manager
- provide: self.show_command
"""
def setUp(self):
super(UpdateStrategyMixin, self).setUp()
def test_create_strategy(self):
"""Test that if no strategy exists, one can be created."""
# prepare mixin attributes
manager_to_test = self.sw_update_manager
expected_strategy_type = manager_to_test.update_type
# mock the result of the API call
strategy = utils.make_strategy(strategy_type=expected_strategy_type)
# mock that there is no pre-existing strategy
manager_to_test.create_sw_update_strategy.return_value = strategy
# invoke the backend method for the CLI.
# Returns a tuple of field descriptions, and a second tuple of values
fields, results = self.call(self.create_command)
# results is a tuple of expected length 7
self.assertEqual(len(results), 7)
# result tuple values are
# - strategy_type
# - subcloud_apply_type
# - max_parallel_subclouds
# - stop_on_failure
# - state
# - created_at
# - updated_at
self.assertEqual(results[0], expected_strategy_type)
def test_get_strategy(self):
# prepare mocked results
manager_to_test = self.sw_update_manager
expected_strategy_type = manager_to_test.update_type
expected_apply_type = 'parallel'
strategy = utils.make_strategy(strategy_type=expected_strategy_type,
subcloud_apply_type=expected_apply_type)
manager_to_test.update_sw_strategy_detail.return_value = strategy
# invoke the backend method for the CLI.
# Returns a tuple of field descriptions, and a second tuple of values
fields, results = self.call(self.show_command)
# results is a tuple of expected length 7
self.assertEqual(len(results), 7)
# result tuple values are
# - strategy_type
# - subcloud_apply_type
# - max_parallel_subclouds
# - stop_on_failure
# - state
# - created_at
# - updated_at
self.assertEqual(results[0], expected_strategy_type)
self.assertEqual(results[1], expected_apply_type)

View File

@ -0,0 +1,19 @@
#
# Copyright (c) 2020 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
from dcmanagerclient.commands.v1 import fw_update_manager as cli_cmd
from dcmanagerclient.tests import base
from dcmanagerclient.tests.v1.mixins import UpdateStrategyMixin
class TestFwUpdateStrategy(UpdateStrategyMixin, base.BaseCommandTest):
def setUp(self):
super(TestFwUpdateStrategy, self).setUp()
self.sw_update_manager = \
self.app.client_manager.fw_update_manager.fw_update_manager
self.create_command = cli_cmd.CreateFwUpdateStrategy
self.show_command = cli_cmd.ShowFwUpdateStrategy

View File

@ -199,7 +199,7 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
"external_oam_floating_address": EXTERNAL_OAM_FLOATING_ADDRESS,
}
with tempfile.NamedTemporaryFile() as f:
with tempfile.NamedTemporaryFile(mode='w') as f:
yaml.dump(values, f)
file_path = os.path.abspath(f.name)
actual_call = self.call(
@ -308,10 +308,9 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
with tempfile.NamedTemporaryFile() as f:
file_path = os.path.abspath(f.name)
# Python 2.7 onwards, context manager can be used to get the
# actual Exception object
with self.assertRaises(DCManagerClientException) as context:
self.call(subcloud_cmd.ReconfigSubcloud,
app_args=[ID, '--deploy-config', file_path])
e = self.assertRaises(DCManagerClientException,
self.call,
subcloud_cmd.ReconfigSubcloud,
app_args=[ID, '--deploy-config', file_path])
self.assertTrue('deploy-config file does not exist'
in str(context.exception))
in str(e))

View File

@ -0,0 +1,35 @@
#
# Copyright (c) 2020 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import mock
from oslo_utils import timeutils
from dcmanagerclient.api.v1.sw_update_manager import SwUpdateStrategy
TIME_NOW = timeutils.utcnow().isoformat()
DEFAULT_APPLY_TYPE = 'serial'
DEFAULT_MAX_PARALLEL = 2
DEFAULT_STATE = 'initial'
DEFAULT_STRATEGY_TYPE = 'patch'
def make_strategy(manager=mock.MagicMock(),
strategy_type=DEFAULT_STRATEGY_TYPE,
subcloud_apply_type=DEFAULT_APPLY_TYPE,
max_parallel_subclouds=DEFAULT_MAX_PARALLEL,
stop_on_failure=False,
state=DEFAULT_STATE,
created_at=TIME_NOW,
updated_at=None):
return SwUpdateStrategy(manager,
strategy_type,
subcloud_apply_type,
max_parallel_subclouds,
stop_on_failure,
state,
created_at,
updated_at)

View File

@ -6,7 +6,6 @@ pylint==1.9.2;python_version<"3.0" # GPLv2
pylint==2.3.1;python_version>="3.0" # GPLv2
python-openstackclient>=3.3.0 # Apache-2.0
sphinx>=1.5.1 # BSD
unittest2 # BSD
fixtures>=3.0.0 # Apache-2.0/BSD
mock>=2.0 # BSD
nose # LGPL

View File

@ -1,6 +1,6 @@
[tox]
minversion = 2.3
envlist = py27,pep8,pylint
envlist = py27,py36,pep8,pylint
skipsdist = True
toxworkdir = /tmp/{env:USER}_dc_client_tox
@ -32,6 +32,12 @@ commands =
find {toxinidir} -not -path '{toxinidir}/.tox/*' -name '*.py[c|o]' -delete
stestr --test-path={[dcclient]client_base_dir}/dcmanagerclient/tests run '{posargs}'
[testenv:py36]
basepython = python3.6
commands =
find {toxinidir} -not -path '{toxinidir}/.tox/*' -name '*.py[c|o]' -delete
stestr --test-path={[dcclient]client_base_dir}/dcmanagerclient/tests run '{posargs}'
[testenv:pep8]
basepython = python3
commands = flake8 {posargs}