Implement wrapper for ascii table parser from tempest_lib.cli
Implement wrapper for ascii table parser from tempest_lib.cli to parse manila specific output from console client in functional tests. Partially implements bp functional-tests Change-Id: Id22e8f89cad311c6dabbf1d4069e50d33ac658ce
This commit is contained in:
parent
c51f80b8a5
commit
b44218141c
87
manilaclient/tests/functional/utils.py
Normal file
87
manilaclient/tests/functional/utils.py
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
# Copyright 2015 Mirantis Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import six
|
||||||
|
from tempest_lib.cli import output_parser
|
||||||
|
|
||||||
|
|
||||||
|
def multi_line_row_table(output_lines, group_by_column_index=0):
|
||||||
|
parsed_table = output_parser.table(output_lines)
|
||||||
|
|
||||||
|
rows = parsed_table['values']
|
||||||
|
row_index = 0
|
||||||
|
|
||||||
|
def get_column_index(column_name, headers, default):
|
||||||
|
return next(
|
||||||
|
(i for i, h in enumerate(headers) if h.lower() == column_name),
|
||||||
|
default
|
||||||
|
)
|
||||||
|
|
||||||
|
if group_by_column_index is None:
|
||||||
|
group_by_column_index = get_column_index(
|
||||||
|
'id', parsed_table['headers'], 0)
|
||||||
|
|
||||||
|
def is_embedded_table(parsed_rows):
|
||||||
|
def is_table_border(t):
|
||||||
|
return six.text_type(t).startswith('+')
|
||||||
|
|
||||||
|
return (isinstance(parsed_rows, list)
|
||||||
|
and len(parsed_rows) > 3
|
||||||
|
and is_table_border(parsed_rows[0])
|
||||||
|
and is_table_border(parsed_rows[-1]))
|
||||||
|
|
||||||
|
def merge_cells(master_cell, value_cell):
|
||||||
|
if value_cell:
|
||||||
|
if not isinstance(master_cell, list):
|
||||||
|
master_cell = [master_cell]
|
||||||
|
master_cell.append(value_cell)
|
||||||
|
|
||||||
|
if is_embedded_table(master_cell):
|
||||||
|
return multi_line_row_table('\n'.join(master_cell), None)
|
||||||
|
|
||||||
|
return master_cell
|
||||||
|
|
||||||
|
def is_empty_row(row):
|
||||||
|
empty_cells = 0
|
||||||
|
for cell in row:
|
||||||
|
if cell == '':
|
||||||
|
empty_cells += 1
|
||||||
|
return len(row) == empty_cells
|
||||||
|
|
||||||
|
while row_index < len(rows):
|
||||||
|
row = rows[row_index]
|
||||||
|
line_with_value = row_index > 0 and row[group_by_column_index] == ''
|
||||||
|
|
||||||
|
if line_with_value and not is_empty_row(row):
|
||||||
|
rows[row_index - 1] = list(map(merge_cells,
|
||||||
|
rows[row_index - 1],
|
||||||
|
rows.pop(row_index)))
|
||||||
|
else:
|
||||||
|
row_index += 1
|
||||||
|
|
||||||
|
return parsed_table
|
||||||
|
|
||||||
|
|
||||||
|
def listing(output_lines):
|
||||||
|
"""Return list of dicts with basic item info parsed from cli output."""
|
||||||
|
|
||||||
|
items = []
|
||||||
|
table_ = multi_line_row_table(output_lines)
|
||||||
|
for row in table_['values']:
|
||||||
|
item = {}
|
||||||
|
for col_idx, col_key in enumerate(table_['headers']):
|
||||||
|
item[col_key] = row[col_idx]
|
||||||
|
items.append(item)
|
||||||
|
return items
|
225
manilaclient/tests/unit/test_functional_utils.py
Normal file
225
manilaclient/tests/unit/test_functional_utils.py
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
# Copyright 2015 Mirantis Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import ddt
|
||||||
|
|
||||||
|
from manilaclient.tests.functional import utils as func_utils
|
||||||
|
from manilaclient.tests.unit import utils
|
||||||
|
|
||||||
|
|
||||||
|
@ddt.ddt
|
||||||
|
class ShellTest(utils.TestCase):
|
||||||
|
|
||||||
|
OUTPUT_LINES_SIMPLE = """
|
||||||
|
+----+------+---------+
|
||||||
|
| ID | Name | Status |
|
||||||
|
+----+------+---------+
|
||||||
|
| 11 | foo | BUILD |
|
||||||
|
| 21 | bar | ERROR |
|
||||||
|
+----+------+---------+
|
||||||
|
"""
|
||||||
|
OUTPUT_LINES_ONE_MULTI_ROW = """
|
||||||
|
+----+------+---------+
|
||||||
|
| ID | Name | Status |
|
||||||
|
+----+------+---------+
|
||||||
|
| 11 | foo | BUILD |
|
||||||
|
| 21 | bar | ERROR |
|
||||||
|
| | | ERROR2 |
|
||||||
|
| 31 | bee | None |
|
||||||
|
+----+------+---------+
|
||||||
|
"""
|
||||||
|
|
||||||
|
OUTPUT_LINES_COMPLICATED_MULTI_ROW = """
|
||||||
|
+----+------+---------+
|
||||||
|
| ID | Name | Status |
|
||||||
|
+----+------+---------+
|
||||||
|
| 11 | foo | BUILD |
|
||||||
|
| 21 | bar | ERROR |
|
||||||
|
| | | ERROR2 |
|
||||||
|
| | | ERROR3 |
|
||||||
|
| 31 | bee | None |
|
||||||
|
| | bee2 | |
|
||||||
|
| | bee3 | |
|
||||||
|
| 41 | rand | None |
|
||||||
|
| | rend | None2 |
|
||||||
|
| | | |
|
||||||
|
+----+------+---------+
|
||||||
|
"""
|
||||||
|
|
||||||
|
OUTPUT_LINES_COMPLICATED_MULTI_ROW_WITH_SHIFTED_ID = """
|
||||||
|
+----+----+------+---------+
|
||||||
|
| ** | ID | Name | Status |
|
||||||
|
+----+----+------+---------+
|
||||||
|
| ** | 11 | foo | BUILD |
|
||||||
|
| | 21 | bar | ERROR |
|
||||||
|
| | | | ERROR2 |
|
||||||
|
| | | | ERROR3 |
|
||||||
|
| | | | |
|
||||||
|
| ** | 31 | bee | None |
|
||||||
|
| | | bee2 | |
|
||||||
|
| | | | |
|
||||||
|
+----+----+------+---------+
|
||||||
|
"""
|
||||||
|
|
||||||
|
OUTPUT_LINES_NESTED_TABLE = """
|
||||||
|
+----+----+------+--------------+
|
||||||
|
| ** | ID | Name | Status |
|
||||||
|
+----+----+------+--------------+
|
||||||
|
| ** | 11 | foo | +----+----+ |
|
||||||
|
| | | | | aa | bb | |
|
||||||
|
| | | | +----+----+ |
|
||||||
|
| | | | +----+----+ |
|
||||||
|
| | 21 | bar | ERROR |
|
||||||
|
| | | | ERROR2 |
|
||||||
|
| | | | ERROR3 |
|
||||||
|
+----+----+------+--------------+
|
||||||
|
"""
|
||||||
|
OUTPUT_LINES_NESTED_TABLE_MULTI_LINE = """
|
||||||
|
+----+----+------+--------------+
|
||||||
|
| ** | ID | Name | Status |
|
||||||
|
+----+----+------+--------------+
|
||||||
|
| ** | 11 | foo | +----+----+ |
|
||||||
|
| | | | | id | bb | |
|
||||||
|
| | | | +----+----+ |
|
||||||
|
| | | | | 01 | a1 | |
|
||||||
|
| | | | | | a2 | |
|
||||||
|
| | | | +----+----+ |
|
||||||
|
| | 21 | bar | ERROR |
|
||||||
|
| | | | ERROR2 |
|
||||||
|
| | | | ERROR3 |
|
||||||
|
+----+----+------+--------------+
|
||||||
|
"""
|
||||||
|
OUTPUT_LINES_DETAILS = """
|
||||||
|
+----------+--------+
|
||||||
|
| Property | Value |
|
||||||
|
+----------+--------+
|
||||||
|
| foo | BUILD |
|
||||||
|
| bar | ERROR |
|
||||||
|
| | ERROR2 |
|
||||||
|
| | ERROR3 |
|
||||||
|
| bee | None |
|
||||||
|
+----------+--------+
|
||||||
|
"""
|
||||||
|
|
||||||
|
@ddt.data({'input': OUTPUT_LINES_SIMPLE,
|
||||||
|
'valid_values': [
|
||||||
|
['11', 'foo', 'BUILD'],
|
||||||
|
['21', 'bar', 'ERROR']
|
||||||
|
]},
|
||||||
|
{'input': OUTPUT_LINES_ONE_MULTI_ROW,
|
||||||
|
'valid_values': [
|
||||||
|
['11', 'foo', 'BUILD'],
|
||||||
|
['21', 'bar', ['ERROR', 'ERROR2']],
|
||||||
|
['31', 'bee', 'None'],
|
||||||
|
]},
|
||||||
|
{'input': OUTPUT_LINES_COMPLICATED_MULTI_ROW,
|
||||||
|
'valid_values': [
|
||||||
|
['11', 'foo', 'BUILD'],
|
||||||
|
['21', 'bar', ['ERROR', 'ERROR2', 'ERROR3']],
|
||||||
|
['31', ['bee', 'bee2', 'bee3'], 'None'],
|
||||||
|
['41', ['rand', 'rend'], ['None', 'None2']],
|
||||||
|
['', '', '']
|
||||||
|
]})
|
||||||
|
@ddt.unpack
|
||||||
|
def test_multi_line_row_table(self, input, valid_values):
|
||||||
|
|
||||||
|
actual_result = func_utils.multi_line_row_table(input)
|
||||||
|
|
||||||
|
self.assertEqual(['ID', 'Name', 'Status'], actual_result['headers'])
|
||||||
|
self.assertEqual(valid_values, actual_result['values'])
|
||||||
|
|
||||||
|
def test_multi_line_row_table_shifted_id_column(self):
|
||||||
|
input = self.OUTPUT_LINES_COMPLICATED_MULTI_ROW_WITH_SHIFTED_ID
|
||||||
|
valid_values = [
|
||||||
|
['**', '11', 'foo', 'BUILD'],
|
||||||
|
['', '21', 'bar', ['ERROR', 'ERROR2', 'ERROR3']],
|
||||||
|
['', '', '', ''],
|
||||||
|
['**', '31', ['bee', 'bee2'], 'None'],
|
||||||
|
['', '', '', '']
|
||||||
|
]
|
||||||
|
|
||||||
|
actual_result = func_utils.multi_line_row_table(
|
||||||
|
input, group_by_column_index=1)
|
||||||
|
|
||||||
|
self.assertEqual(['**', 'ID', 'Name', 'Status'],
|
||||||
|
actual_result['headers'])
|
||||||
|
self.assertEqual(valid_values, actual_result['values'])
|
||||||
|
|
||||||
|
@ddt.data({'input': OUTPUT_LINES_NESTED_TABLE,
|
||||||
|
'valid_nested': {
|
||||||
|
'headers': ['aa', 'bb'],
|
||||||
|
'values': []
|
||||||
|
}},
|
||||||
|
{'input': OUTPUT_LINES_NESTED_TABLE_MULTI_LINE,
|
||||||
|
'valid_nested': {
|
||||||
|
'headers': ['id', 'bb'],
|
||||||
|
'values': [['01', ['a1', 'a2']]]
|
||||||
|
}},)
|
||||||
|
@ddt.unpack
|
||||||
|
def test_nested_tables(self, input, valid_nested):
|
||||||
|
|
||||||
|
actual_result = func_utils.multi_line_row_table(
|
||||||
|
input, group_by_column_index=1)
|
||||||
|
|
||||||
|
self.assertEqual(['**', 'ID', 'Name', 'Status'],
|
||||||
|
actual_result['headers'])
|
||||||
|
|
||||||
|
self.assertEqual(2, len(actual_result['values']))
|
||||||
|
self.assertEqual(valid_nested, actual_result['values'][0][3])
|
||||||
|
|
||||||
|
@ddt.data({'input': OUTPUT_LINES_DETAILS,
|
||||||
|
'valid_values': [
|
||||||
|
['foo', 'BUILD'],
|
||||||
|
['bar', ['ERROR', 'ERROR2', 'ERROR3']],
|
||||||
|
['bee', 'None'],
|
||||||
|
]})
|
||||||
|
@ddt.unpack
|
||||||
|
def test_details(self, input, valid_values):
|
||||||
|
actual_result = func_utils.multi_line_row_table(input)
|
||||||
|
|
||||||
|
self.assertEqual(['Property', 'Value'], actual_result['headers'])
|
||||||
|
self.assertEqual(valid_values, actual_result['values'])
|
||||||
|
|
||||||
|
@ddt.data({'input_data': OUTPUT_LINES_DETAILS,
|
||||||
|
'output_data': [
|
||||||
|
{'Property': 'foo', 'Value': 'BUILD'},
|
||||||
|
{'Property': 'bar', 'Value': ['ERROR', 'ERROR2', 'ERROR3']},
|
||||||
|
{'Property': 'bee', 'Value': 'None'}]},
|
||||||
|
{'input_data': OUTPUT_LINES_SIMPLE,
|
||||||
|
'output_data': [
|
||||||
|
{'ID': '11', 'Name': 'foo', 'Status': 'BUILD'},
|
||||||
|
{'ID': '21', 'Name': 'bar', 'Status': 'ERROR'},
|
||||||
|
]},
|
||||||
|
{'input_data': OUTPUT_LINES_ONE_MULTI_ROW,
|
||||||
|
'output_data': [
|
||||||
|
{'ID': '11', 'Name': 'foo', 'Status': 'BUILD'},
|
||||||
|
{'ID': '21', 'Name': 'bar', 'Status': ['ERROR', 'ERROR2']},
|
||||||
|
{'ID': '31', 'Name': 'bee', 'Status': 'None'},
|
||||||
|
]},
|
||||||
|
{'input_data': OUTPUT_LINES_COMPLICATED_MULTI_ROW,
|
||||||
|
'output_data': [
|
||||||
|
{'ID': '11', 'Name': 'foo', 'Status': 'BUILD'},
|
||||||
|
{'ID': '21', 'Name': 'bar',
|
||||||
|
'Status': ['ERROR', 'ERROR2', 'ERROR3']},
|
||||||
|
{'ID': '31', 'Name': ['bee', 'bee2', 'bee3'],
|
||||||
|
'Status': 'None'},
|
||||||
|
{'ID': '41', 'Name': ['rand', 'rend'],
|
||||||
|
'Status': ['None', 'None2']},
|
||||||
|
{'ID': '', 'Name': '', 'Status': ''},
|
||||||
|
]})
|
||||||
|
@ddt.unpack
|
||||||
|
def test_listing(self, input_data, output_data):
|
||||||
|
actual_result = func_utils.listing(input_data)
|
||||||
|
self.assertEqual(output_data, actual_result)
|
Loading…
Reference in New Issue
Block a user