Format aggregate command fields and de-race functional tests
Rename metadata to property in all aggregate commands Beef up functional tests to reduce street racing Change-Id: I4598da73b85a954f3e6a3981db21891b45d9548c Signed-off-by: Dean Troyer <dtroyer@gmail.com>
This commit is contained in:
parent
7b7488d51c
commit
03a2accb2f
openstackclient
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from osc_lib.cli import format_columns
|
||||||
from osc_lib.cli import parseractions
|
from osc_lib.cli import parseractions
|
||||||
from osc_lib.command import command
|
from osc_lib.command import command
|
||||||
from osc_lib import exceptions
|
from osc_lib import exceptions
|
||||||
@ -58,6 +59,15 @@ class AddAggregateHost(command.ShowOne):
|
|||||||
|
|
||||||
info = {}
|
info = {}
|
||||||
info.update(data._info)
|
info.update(data._info)
|
||||||
|
|
||||||
|
# Special mapping for columns to make the output easier to read:
|
||||||
|
# 'metadata' --> 'properties'
|
||||||
|
info.update(
|
||||||
|
{
|
||||||
|
'hosts': format_columns.ListColumn(info.pop('hosts')),
|
||||||
|
'properties': format_columns.DictColumn(info.pop('metadata')),
|
||||||
|
},
|
||||||
|
)
|
||||||
return zip(*sorted(six.iteritems(info)))
|
return zip(*sorted(six.iteritems(info)))
|
||||||
|
|
||||||
|
|
||||||
@ -101,8 +111,20 @@ class CreateAggregate(command.ShowOne):
|
|||||||
parsed_args.property,
|
parsed_args.property,
|
||||||
)._info)
|
)._info)
|
||||||
|
|
||||||
# TODO(dtroyer): re-format metadata field to properites as
|
# Special mapping for columns to make the output easier to read:
|
||||||
# in the set command
|
# 'metadata' --> 'properties'
|
||||||
|
hosts = None
|
||||||
|
properties = None
|
||||||
|
if 'hosts' in info.keys():
|
||||||
|
hosts = format_columns.ListColumn(info.pop('hosts'))
|
||||||
|
if 'metadata' in info.keys():
|
||||||
|
properties = format_columns.DictColumn(info.pop('metadata'))
|
||||||
|
info.update(
|
||||||
|
{
|
||||||
|
'hosts': hosts,
|
||||||
|
'properties': properties,
|
||||||
|
},
|
||||||
|
)
|
||||||
return zip(*sorted(six.iteritems(info)))
|
return zip(*sorted(six.iteritems(info)))
|
||||||
|
|
||||||
|
|
||||||
@ -186,6 +208,10 @@ class ListAggregate(command.Lister):
|
|||||||
return (column_headers,
|
return (column_headers,
|
||||||
(utils.get_item_properties(
|
(utils.get_item_properties(
|
||||||
s, columns,
|
s, columns,
|
||||||
|
formatters={
|
||||||
|
'Hosts': format_columns.ListColumn,
|
||||||
|
'Metadata': format_columns.DictColumn,
|
||||||
|
},
|
||||||
) for s in data))
|
) for s in data))
|
||||||
|
|
||||||
|
|
||||||
@ -220,6 +246,15 @@ class RemoveAggregateHost(command.ShowOne):
|
|||||||
|
|
||||||
info = {}
|
info = {}
|
||||||
info.update(data._info)
|
info.update(data._info)
|
||||||
|
|
||||||
|
# Special mapping for columns to make the output easier to read:
|
||||||
|
# 'metadata' --> 'properties'
|
||||||
|
info.update(
|
||||||
|
{
|
||||||
|
'hosts': format_columns.ListColumn(info.pop('hosts')),
|
||||||
|
'properties': format_columns.DictColumn(info.pop('metadata')),
|
||||||
|
},
|
||||||
|
)
|
||||||
return zip(*sorted(six.iteritems(info)))
|
return zip(*sorted(six.iteritems(info)))
|
||||||
|
|
||||||
|
|
||||||
@ -326,7 +361,12 @@ class ShowAggregate(command.ShowOne):
|
|||||||
# 'metadata' --> 'properties'
|
# 'metadata' --> 'properties'
|
||||||
data._info.update(
|
data._info.update(
|
||||||
{
|
{
|
||||||
'properties': utils.format_dict(data._info.pop('metadata')),
|
'hosts': format_columns.ListColumn(
|
||||||
|
data._info.pop('hosts')
|
||||||
|
),
|
||||||
|
'properties': format_columns.DictColumn(
|
||||||
|
data._info.pop('metadata')
|
||||||
|
),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from openstackclient.tests.functional import base
|
from openstackclient.tests.functional import base
|
||||||
@ -19,6 +20,32 @@ from openstackclient.tests.functional import base
|
|||||||
class AggregateTests(base.TestCase):
|
class AggregateTests(base.TestCase):
|
||||||
"""Functional tests for aggregate"""
|
"""Functional tests for aggregate"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def wait_for_status(cls, check_type, check_name, desired_status,
|
||||||
|
wait=120, interval=5, failures=None):
|
||||||
|
current_status = "notset"
|
||||||
|
if failures is None:
|
||||||
|
failures = ['error']
|
||||||
|
total_sleep = 0
|
||||||
|
while total_sleep < wait:
|
||||||
|
output = json.loads(cls.openstack(
|
||||||
|
check_type + ' show -f json ' + check_name))
|
||||||
|
current_status = output['name']
|
||||||
|
if (current_status == desired_status):
|
||||||
|
print('{} {} now has status {}'
|
||||||
|
.format(check_type, check_name, current_status))
|
||||||
|
return
|
||||||
|
print('Checking {} {} Waiting for {} current status: {}'
|
||||||
|
.format(check_type, check_name,
|
||||||
|
desired_status, current_status))
|
||||||
|
if current_status in failures:
|
||||||
|
raise Exception(
|
||||||
|
'Current status {} of {} {} is one of failures {}'
|
||||||
|
.format(current_status, check_type, check_name, failures))
|
||||||
|
time.sleep(interval)
|
||||||
|
total_sleep += interval
|
||||||
|
cls.assertOutput(desired_status, current_status)
|
||||||
|
|
||||||
def test_aggregate_crud(self):
|
def test_aggregate_crud(self):
|
||||||
"""Test create, delete multiple"""
|
"""Test create, delete multiple"""
|
||||||
name1 = uuid.uuid4().hex
|
name1 = uuid.uuid4().hex
|
||||||
@ -36,12 +63,16 @@ class AggregateTests(base.TestCase):
|
|||||||
'nova',
|
'nova',
|
||||||
cmd_output['availability_zone']
|
cmd_output['availability_zone']
|
||||||
)
|
)
|
||||||
# TODO(dtroyer): enable the following once the properties field
|
self.assertIn(
|
||||||
# is correctly formatted in the create output
|
'a',
|
||||||
# self.assertIn(
|
cmd_output['properties']
|
||||||
# "a='b'",
|
)
|
||||||
# cmd_output['properties']
|
self.wait_for_status('aggregate', name1, name1)
|
||||||
# )
|
self.addCleanup(
|
||||||
|
self.openstack,
|
||||||
|
'aggregate delete ' + name1,
|
||||||
|
fail_ok=True,
|
||||||
|
)
|
||||||
|
|
||||||
name2 = uuid.uuid4().hex
|
name2 = uuid.uuid4().hex
|
||||||
cmd_output = json.loads(self.openstack(
|
cmd_output = json.loads(self.openstack(
|
||||||
@ -57,6 +88,12 @@ class AggregateTests(base.TestCase):
|
|||||||
'external',
|
'external',
|
||||||
cmd_output['availability_zone']
|
cmd_output['availability_zone']
|
||||||
)
|
)
|
||||||
|
self.wait_for_status('aggregate', name2, name2)
|
||||||
|
self.addCleanup(
|
||||||
|
self.openstack,
|
||||||
|
'aggregate delete ' + name2,
|
||||||
|
fail_ok=True,
|
||||||
|
)
|
||||||
|
|
||||||
# Test aggregate set
|
# Test aggregate set
|
||||||
name3 = uuid.uuid4().hex
|
name3 = uuid.uuid4().hex
|
||||||
@ -69,6 +106,12 @@ class AggregateTests(base.TestCase):
|
|||||||
name1
|
name1
|
||||||
)
|
)
|
||||||
self.assertOutput('', raw_output)
|
self.assertOutput('', raw_output)
|
||||||
|
self.wait_for_status('aggregate', name3, name3)
|
||||||
|
self.addCleanup(
|
||||||
|
self.openstack,
|
||||||
|
'aggregate delete ' + name3,
|
||||||
|
fail_ok=True,
|
||||||
|
)
|
||||||
|
|
||||||
cmd_output = json.loads(self.openstack(
|
cmd_output = json.loads(self.openstack(
|
||||||
'aggregate show -f json ' +
|
'aggregate show -f json ' +
|
||||||
@ -83,11 +126,11 @@ class AggregateTests(base.TestCase):
|
|||||||
cmd_output['availability_zone']
|
cmd_output['availability_zone']
|
||||||
)
|
)
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
"c='d'",
|
'c',
|
||||||
cmd_output['properties']
|
cmd_output['properties']
|
||||||
)
|
)
|
||||||
self.assertNotIn(
|
self.assertNotIn(
|
||||||
"a='b'",
|
'a',
|
||||||
cmd_output['properties']
|
cmd_output['properties']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
import mock
|
import mock
|
||||||
from mock import call
|
from mock import call
|
||||||
|
|
||||||
|
from osc_lib.cli import format_columns
|
||||||
from osc_lib import exceptions
|
from osc_lib import exceptions
|
||||||
from osc_lib import utils
|
from osc_lib import utils
|
||||||
|
|
||||||
@ -31,16 +32,16 @@ class TestAggregate(compute_fakes.TestComputev2):
|
|||||||
'availability_zone',
|
'availability_zone',
|
||||||
'hosts',
|
'hosts',
|
||||||
'id',
|
'id',
|
||||||
'metadata',
|
|
||||||
'name',
|
'name',
|
||||||
|
'properties',
|
||||||
)
|
)
|
||||||
|
|
||||||
data = (
|
data = (
|
||||||
fake_ag.availability_zone,
|
fake_ag.availability_zone,
|
||||||
fake_ag.hosts,
|
format_columns.ListColumn(fake_ag.hosts),
|
||||||
fake_ag.id,
|
fake_ag.id,
|
||||||
fake_ag.metadata,
|
|
||||||
fake_ag.name,
|
fake_ag.name,
|
||||||
|
format_columns.DictColumn(fake_ag.metadata),
|
||||||
)
|
)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -75,7 +76,7 @@ class TestAggregateAddHost(TestAggregate):
|
|||||||
self.aggregate_mock.add_host.assert_called_once_with(self.fake_ag,
|
self.aggregate_mock.add_host.assert_called_once_with(self.fake_ag,
|
||||||
parsed_args.host)
|
parsed_args.host)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertItemEqual(self.data, data)
|
||||||
|
|
||||||
|
|
||||||
class TestAggregateCreate(TestAggregate):
|
class TestAggregateCreate(TestAggregate):
|
||||||
@ -99,7 +100,7 @@ class TestAggregateCreate(TestAggregate):
|
|||||||
self.aggregate_mock.create.assert_called_once_with(parsed_args.name,
|
self.aggregate_mock.create.assert_called_once_with(parsed_args.name,
|
||||||
None)
|
None)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertItemEqual(self.data, data)
|
||||||
|
|
||||||
def test_aggregate_create_with_zone(self):
|
def test_aggregate_create_with_zone(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -116,7 +117,7 @@ class TestAggregateCreate(TestAggregate):
|
|||||||
self.aggregate_mock.create.assert_called_once_with(parsed_args.name,
|
self.aggregate_mock.create.assert_called_once_with(parsed_args.name,
|
||||||
parsed_args.zone)
|
parsed_args.zone)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertItemEqual(self.data, data)
|
||||||
|
|
||||||
def test_aggregate_create_with_property(self):
|
def test_aggregate_create_with_property(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -135,7 +136,7 @@ class TestAggregateCreate(TestAggregate):
|
|||||||
self.aggregate_mock.set_metadata.assert_called_once_with(
|
self.aggregate_mock.set_metadata.assert_called_once_with(
|
||||||
self.fake_ag, parsed_args.property)
|
self.fake_ag, parsed_args.property)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertItemEqual(self.data, data)
|
||||||
|
|
||||||
|
|
||||||
class TestAggregateDelete(TestAggregate):
|
class TestAggregateDelete(TestAggregate):
|
||||||
@ -234,8 +235,11 @@ class TestAggregateList(TestAggregate):
|
|||||||
TestAggregate.fake_ag.id,
|
TestAggregate.fake_ag.id,
|
||||||
TestAggregate.fake_ag.name,
|
TestAggregate.fake_ag.name,
|
||||||
TestAggregate.fake_ag.availability_zone,
|
TestAggregate.fake_ag.availability_zone,
|
||||||
{key: value for key, value in TestAggregate.fake_ag.metadata.items()
|
format_columns.DictColumn({
|
||||||
if key != 'availability_zone'},
|
key: value
|
||||||
|
for key, value in TestAggregate.fake_ag.metadata.items()
|
||||||
|
if key != 'availability_zone'
|
||||||
|
}),
|
||||||
), )
|
), )
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -250,7 +254,7 @@ class TestAggregateList(TestAggregate):
|
|||||||
columns, data = self.cmd.take_action(parsed_args)
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.assertEqual(self.list_columns, columns)
|
self.assertEqual(self.list_columns, columns)
|
||||||
self.assertEqual(self.list_data, tuple(data))
|
self.assertItemEqual(self.list_data, tuple(data))
|
||||||
|
|
||||||
def test_aggregate_list_with_long(self):
|
def test_aggregate_list_with_long(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
@ -263,7 +267,7 @@ class TestAggregateList(TestAggregate):
|
|||||||
columns, data = self.cmd.take_action(parsed_args)
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.assertEqual(self.list_columns_long, columns)
|
self.assertEqual(self.list_columns_long, columns)
|
||||||
self.assertEqual(self.list_data_long, tuple(data))
|
self.assertListItemEqual(self.list_data_long, tuple(data))
|
||||||
|
|
||||||
|
|
||||||
class TestAggregateRemoveHost(TestAggregate):
|
class TestAggregateRemoveHost(TestAggregate):
|
||||||
@ -290,7 +294,7 @@ class TestAggregateRemoveHost(TestAggregate):
|
|||||||
self.aggregate_mock.remove_host.assert_called_once_with(
|
self.aggregate_mock.remove_host.assert_called_once_with(
|
||||||
self.fake_ag, parsed_args.host)
|
self.fake_ag, parsed_args.host)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertItemEqual(self.data, data)
|
||||||
|
|
||||||
|
|
||||||
class TestAggregateSet(TestAggregate):
|
class TestAggregateSet(TestAggregate):
|
||||||
@ -440,13 +444,14 @@ class TestAggregateShow(TestAggregate):
|
|||||||
|
|
||||||
data = (
|
data = (
|
||||||
TestAggregate.fake_ag.availability_zone,
|
TestAggregate.fake_ag.availability_zone,
|
||||||
TestAggregate.fake_ag.hosts,
|
format_columns.ListColumn(TestAggregate.fake_ag.hosts),
|
||||||
TestAggregate.fake_ag.id,
|
TestAggregate.fake_ag.id,
|
||||||
TestAggregate.fake_ag.name,
|
TestAggregate.fake_ag.name,
|
||||||
utils.format_dict(
|
format_columns.DictColumn({
|
||||||
{key: value
|
key: value
|
||||||
for key, value in TestAggregate.fake_ag.metadata.items()
|
for key, value in TestAggregate.fake_ag.metadata.items()
|
||||||
if key != 'availability_zone'}),
|
if key != 'availability_zone'
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -467,7 +472,7 @@ class TestAggregateShow(TestAggregate):
|
|||||||
self.aggregate_mock.get.assert_called_once_with(parsed_args.aggregate)
|
self.aggregate_mock.get.assert_called_once_with(parsed_args.aggregate)
|
||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertItemEqual(self.data, tuple(data))
|
||||||
|
|
||||||
|
|
||||||
class TestAggregateUnset(TestAggregate):
|
class TestAggregateUnset(TestAggregate):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user