Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get virtual table #63

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ usage: tsp_cli_client [-h] [--ip IP] [--port PORT]
[--list-experiment UUID] [--list-experiments]
[--delete-experiment UUID] [--list-outputs UUID]
[--list-output OUTPUT_ID] [--get-tree OUTPUT_ID]
[--get-virtual-table-columns OUTPUT_ID]
[--get-virtual-table-lines OUTPUT_ID]
[--table-line-index INDEX] [--table-line-count COUNT]
[--table-times [TIMES ...]] [--table-column-ids [IDs ...]]
[--table-search-direction DIRECTION]
[--table-search-expression COLUMN_ID EXPRESSION]
[--get-timegraph-tree OUTPUT_ID]
[--get-xy-tree OUTPUT_ID] [--get-xy OUTPUT_ID]
[--items [ITEMS ...]] [--time-range START END NUM_TIMES]
Expand Down Expand Up @@ -106,6 +112,22 @@ optional arguments:
--list-output OUTPUT_ID
Get details on the given output of a trace
--get-tree OUTPUT_ID Get the tree of an output of type DATA_TREE
--get-virtual-table-columns OUTPUT_ID
Get the columns of an output of type DATA_TREE
--get-virtual-table-lines OUTPUT_ID
Get the tree lines of an output of type DATA_TREE
--table-line-index TABLE_LINE_INDEX
The index of the table line to start fetching
--table-line-count TABLE_LINE_COUNT
The number of table lines to fetch
--table-times [TABLE_TIMES ...]
The list of times to fetch from table
--table-column-ids [TABLE_COLUMN_IDS ...]
The list of column ids to fetch
--table-search-direction TABLE_LINE_SEARCH_DIRECTION
The direction to search for the table lines
--table-search-expression COLUMN_ID EXPRESSION
The columns expression to search for the table lines
--get-timegraph-tree OUTPUT_ID
Get the tree of an output of type TIME_GRAPH
--get-xy-tree OUTPUT_ID
Expand Down Expand Up @@ -153,6 +175,8 @@ Examples:
./tsp_cli_client --delete-experiment UUID [--do-delete-traces]
./tsp_cli_client --list-outputs UUID
./tsp_cli_client --get-tree OUTPUT_ID --uuid UUID
./tsp_cli_client --get-virtual-table-columns OUTPUT_ID --uuid UUID
./tsp_cli_client --get-virtual-table-lines --table-line-index INDEX --table-line-count COUNT --table-column-ids IDs --table-search-direction DIRECTION --table-search-expression COLUMN_ID EXPRESSION
./tsp_cli_client --get-timegraph-tree OUTPUT_ID --uuid UUID
./tsp_cli_client --get-xy-tree OUTPUT_ID --uuid UUID
./tsp_cli_client --get-xy OUTPUT_ID --uuid UUID --items ITEMS --time-range START END NUM_TIMES
Expand Down
105 changes: 97 additions & 8 deletions test_tsp.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@
"org.eclipse.tracecompass.analysis.timing.core.segmentstore.SegmentStoreStatisticsDataProvider:"
"org.eclipse.linuxtools.lttng2.ust.analysis.callstack"
)
TABLE_DP_ID = (
"org.eclipse.tracecompass.analysis.timing.core.segmentstore.SegmentStoreTableDataProvider:"
"org.eclipse.linuxtools.lttng2.ust.analysis.callstack"
)

REQUESTED_TIME_START = 1332170682440133097
REQUESTED_TIME_END = 1332170692664579801
REQUESTED_TIME_LENGTH = 10
Expand All @@ -47,6 +52,8 @@
CONFIG_SOURCE_TYPE = 'org.eclipse.tracecompass.tmf.core.config.xmlsourcetype'

# pylint: disable=too-many-public-methods


class TestTspClient:
"""TspClient test methods.

Expand Down Expand Up @@ -81,34 +88,34 @@ def _delete_traces(self):
@pytest.fixture(scope='module')
def extension(self):
"""Absolute xml analysis file path."""
return (f'{os.getcwd()}/org.eclipse.tracecompass.incubator/tracetypes/'
f'org.eclipse.tracecompass.incubator.ftrace.core/xml_analyses/{self.name}')
return os.path.join(os.getcwd(), 'org.eclipse.tracecompass.incubator', 'tracetypes',
'org.eclipse.tracecompass.incubator.ftrace.core', 'xml_analyses', self.name)

@staticmethod
@pytest.fixture(scope='module')
def kernel():
"""Absolute kernel test trace path."""
return f'{os.getcwd()}/tracecompass-test-traces/ctf/src/main/resources/kernel'
return os.path.join(os.getcwd(), 'tracecompass-test-traces', 'ctf', 'src', 'main', 'resources', 'kernel')

@staticmethod
@pytest.fixture(scope='module')
def other():
"""Absolute kernel-vm test trace path."""
return f'{os.getcwd()}/tracecompass-test-traces/ctf/src/main/resources/kernel_vm'
return os.path.join(os.getcwd(), 'tracecompass-test-traces', 'ctf', 'src', 'main', 'resources', 'kernel_vm')

@staticmethod
@pytest.fixture(scope='module')
def switches():
"""Absolute switches test trace path."""
return (f'{os.getcwd()}/tracecompass-test-traces/ctf/src/main/resources/context-switches/'
f'context-switches-kernel')
return os.path.join(os.getcwd(), 'tracecompass-test-traces', 'ctf', 'src', 'main', 'resources', 'context-switches',
'context-switches-kernel')

@staticmethod
@pytest.fixture(scope='module')
def ust():
"""Absolute ust test trace path."""
return (f'{os.getcwd()}/tracecompass-test-traces/ctf/src/main/resources/context-switches/'
f'context-switches-ust')
return os.path.join(os.getcwd(), 'tracecompass-test-traces', 'ctf', 'src', 'main', 'resources', 'context-switches',
'context-switches-ust')

@pytest.fixture(scope="module", autouse=True)
def test_fetch_traces(self):
Expand Down Expand Up @@ -408,6 +415,88 @@ def test_fetch_timegraph_tree_complete(self, kernel):
self._delete_experiments()
self._delete_traces()

def test_fetch_virtual_table_columns(self, ust):
"""Expect virtual table columns out of opened trace experiment."""
traces = []
response = self.tsp_client.open_trace(os.path.basename(ust), ust)
traces.append(response.model.UUID)
response = self.tsp_client.open_experiment(
os.path.basename(ust), traces)
assert response.status_code == 200
experiment_uuid = response.model.UUID

status = ResponseStatus.RUNNING.name
while status == ResponseStatus.RUNNING.name:
time.sleep(1)
response = self.tsp_client.fetch_virtual_table_columns(
exp_uuid=experiment_uuid, output_id=TABLE_DP_ID)
assert response.model is not None
status = response.model.status.upper()

output_id = TABLE_DP_ID
response = self.tsp_client.fetch_virtual_table_columns(exp_uuid=experiment_uuid, output_id=output_id)
assert response.status_code == 200
assert response.model.model_type == response.model.model_type.VIRTUAL_TABLE_HEADER
assert len(response.model.model.columns) > 0
for column in response.model.model.columns:
assert column.id is not None
assert column.name is not None

self._delete_experiments()
self._delete_traces()

def test_fetch_virtual_table_lines(self, ust):
"""Expect virtual table out of opened trace experiment."""
traces = []
response = self.tsp_client.open_trace(os.path.basename(ust), ust)
traces.append(response.model.UUID)
response = self.tsp_client.open_experiment(
os.path.basename(ust), traces)
assert response.status_code == 200
experiment_uuid = response.model.UUID

status = ResponseStatus.RUNNING.name
while status == ResponseStatus.RUNNING.name:
time.sleep(1)
response = self.tsp_client.fetch_virtual_table_columns(
exp_uuid=experiment_uuid, output_id=TABLE_DP_ID)
assert response.model is not None
status = response.model.status.upper()

output_id = TABLE_DP_ID
response = self.tsp_client.fetch_virtual_table_columns(exp_uuid=experiment_uuid, output_id=output_id)
assert response.status_code == 200
assert response.model.model_type == response.model.model_type.VIRTUAL_TABLE_HEADER
assert len(response.model.model.columns) > 0
for column in response.model.model.columns:
assert column.id is not None
assert column.name is not None

LOW_INDEX = 0
LINE_COUNT = 10

params = {
TspClient.PARAMETERS_KEY: {
TspClient.REQUESTED_TABLE_LINE_INDEX_KEY: LOW_INDEX,
TspClient.REQUESTED_TABLE_LINE_COUNT_KEY: LINE_COUNT
}
}
response = self.tsp_client.fetch_virtual_table_lines(exp_uuid=experiment_uuid, output_id=output_id, parameters=params)
assert response.status_code == 200
assert response.model.model_type == response.model.model_type.VIRTUAL_TABLE
assert len(response.model.model.lines) == 10
for i, line in enumerate(response.model.model.lines):
assert line.index is not None
if i == 0:
assert line.index == LOW_INDEX

assert len(line.cells) > 0
for cell in line.cells:
assert cell.content is not None

self._delete_experiments()
self._delete_traces()

def test_fetch_configuration_sources(self):
"""Expect at least configuration source ."""
response = self.tsp_client.fetch_configuration_sources()
Expand Down
2 changes: 2 additions & 0 deletions tsp/model_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ class ModelType(Enum):
STATES = "states"
XY = "xy"
DATA_TREE = "data_tree"
VIRTUAL_TABLE_HEADER = "virtual_table_header"
VIRTUAL_TABLE = "virtual_table"
6 changes: 6 additions & 0 deletions tsp/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
from tsp.model_type import ModelType
from tsp.output_descriptor import OutputDescriptor
from tsp.entry_model import EntryModel
from tsp.virtual_table_header_model import VirtualTableHeaderModel
from tsp.xy_model import XYModel
from tsp.virtual_table_model import VirtualTableModel

MODEL_KEY = "model"
OUTPUT_DESCRIPTOR_KEY = "output"
Expand Down Expand Up @@ -87,6 +89,10 @@ def __init__(self, params, model_type):
self.model = XYModel(params.get(MODEL_KEY))
elif self.model_type == ModelType.DATA_TREE:
self.model = EntryModel(params.get(MODEL_KEY), self.model_type)
elif self.model_type == ModelType.VIRTUAL_TABLE_HEADER:
self.model = VirtualTableHeaderModel(params.get(MODEL_KEY))
elif self.model_type == ModelType.VIRTUAL_TABLE:
self.model = VirtualTableModel(params.get(MODEL_KEY))

# Output descriptor
if OUTPUT_DESCRIPTOR_KEY in params:
Expand Down
60 changes: 57 additions & 3 deletions tsp/tsp_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,18 @@ class TspClient:
PARAMETERS_KEY = 'parameters'
REQUESTED_TIME_KEY = 'requested_times'
REQUESTED_ITEM_KEY = 'requested_items'

REQUESTED_TIME_RANGE_KEY = 'requested_timerange'
REQUESTED_TIME_RANGE_START_KEY = 'start'
REQUESTED_TIME_RANGE_END_KEY = 'end'
REQUESTED_TIME_RANGE_NUM_TIMES_KEY = 'nbTimes'

REQUESTED_TABLE_LINE_INDEX_KEY = 'requested_table_index'
REQUESTED_TABLE_LINE_COUNT_KEY = 'requested_table_count'
REQUESTED_TABLE_LINE_COLUMN_IDS_KEY = 'requested_table_column_ids'
REQUESTED_TABLE_LINE_SEACH_DIRECTION_KEY = 'table_search_direction'
REQUESTED_TABLE_LINE_SEARCH_EXPRESSION_KEY = 'table_search_expressions'

def __init__(self, base_url):
'''
Constructor
Expand Down Expand Up @@ -281,6 +287,55 @@ def fetch_datatree(self, exp_uuid, output_id, parameters=None):
print(GET_TREE_FAILED.format(response.status_code))
return TspClientResponse(None, response.status_code, response.text)

def fetch_virtual_table_columns(self, exp_uuid, output_id):
'''
Fetch Virtual Table columns, Model extends VirtualTableModel
:param exp_uuid: Experiment UUID
:param output_id: Output ID
:returns: :class: `TspClientResponse <GenericResponse>` object Virtual Table columns response
:rtype: TspClientResponse
'''
api_url = '{0}experiments/{1}/outputs/table/{2}/columns'.format(
self.base_url, exp_uuid, output_id)

response = requests.post(api_url, json={}, headers=headers)

if response.status_code == 200:
return TspClientResponse(GenericResponse(json.loads(response.content.decode('utf-8')),
ModelType.VIRTUAL_TABLE_HEADER),
response.status_code, response.text)
else:
print(GET_TREE_FAILED.format(response.status_code))
return TspClientResponse(None, response.status_code, response.text)

def fetch_virtual_table_lines(self, exp_uuid, output_id, parameters=None):
'''
Fetch Virtual Table lines, Model extends VirtualTableModel
:param exp_uuid: Experiment UUID
:param output_id: Output ID
:param parameters: Query object
:returns: :class: `TspClientResponse <GenericResponse>` object Virtual Table lines response
:rtype: TspClientResponse
'''
api_url = '{0}experiments/{1}/outputs/table/{2}/lines'.format(
self.base_url, exp_uuid, output_id)

params = parameters
if parameters is None:
params = {
TspClient.PARAMETERS_KEY: {}
}

response = requests.post(api_url, json=params, headers=headers)

if response.status_code == 200:
return TspClientResponse(GenericResponse(json.loads(response.content.decode('utf-8')),
ModelType.VIRTUAL_TABLE),
response.status_code, response.text)
else: # pragma: no cover
print(GET_TREE_FAILED.format(response.status_code))
return TspClientResponse(None, response.status_code, response.text)

def fetch_timegraph_tree(self, exp_uuid, output_id, parameters=None):
'''
Fetch Time Graph tree, Model extends TimeGraphEntry
Expand Down Expand Up @@ -417,7 +472,6 @@ def fetch_configuration(self, type_id, config_id):
print("failed to get configuration: {0}".format(response.status_code))
return TspClientResponse(None, response.status_code, response.text)


def post_configuration(self, type_id, params):
'''
Load an extension
Expand Down Expand Up @@ -446,7 +500,7 @@ def put_configuration(self, type_id, config_id, params):
response = requests.put(api_url, json=parameters, headers=headers)

if response.status_code == 200:
return TspClientResponse(Configuration(json.loads(response.content.decode('utf-8'))),
return TspClientResponse(Configuration(json.loads(response.content.decode('utf-8'))),
response.status_code, response.text)
else: # pragma: no cover
print("put extension failed: {0}".format(response.status_code))
Expand Down
Loading