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

feat: refactor best/worst record api in response time #323

Merged
merged 17 commits into from
Nov 9, 2023
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
66 changes: 63 additions & 3 deletions src/caret_analyze/record/records_service/response_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,12 @@ def __init__(
continue
start_ts = record.get(self._start_column)

if end_ts < start_ts:
warn('Record data is invalid. '
'The end time of the path is recorded before the start time.',
UserWarning)
continue

if start_ts not in self._start_timestamps:
self._start_timestamps.insert(0, start_ts)
self._end_timestamps.insert(0, end_ts)
Expand All @@ -267,6 +273,60 @@ def __init__(
self._end_timestamps[idx] = end_ts
self._records[idx] = record

def to_worst_with_external_latency_case_records(self) -> RecordsInterface:

end_timestamps: list[int] = []
start_timestamps: list[int] = []
worst_to_best_timestamps: list[int] = []
for start_ts, end_ts, prev_start_ts in zip(self._start_timestamps[1:],
self._end_timestamps[1:],
self._start_timestamps[:-1]):
if end_ts not in end_timestamps:
start_timestamps.append(start_ts)
end_timestamps.append(end_ts)
worst_to_best_timestamps.append(start_ts - prev_start_ts)
else:
idx = end_timestamps.index(end_ts)
if start_ts < start_timestamps[idx]:
start_timestamps[idx] = start_ts
worst_to_best_timestamps[idx] = start_ts - prev_start_ts

records = self._create_empty_records()
for start_ts, end_ts, worst_to_best_ts in sorted(zip(start_timestamps,
end_timestamps,
worst_to_best_timestamps),
key=lambda x: x[0]):
record = {
self._start_column: start_ts - worst_to_best_ts,
'response_time': end_ts - (start_ts - worst_to_best_ts)
}
records.append(record)

return records

def to_best_case_records(self) -> RecordsInterface:

end_timestamps: list[int] = []
start_timestamps: list[int] = []
for start_ts, end_ts in zip(self._start_timestamps, self._end_timestamps):
if end_ts not in end_timestamps:
start_timestamps.append(start_ts)
end_timestamps.append(end_ts)
else:
idx = end_timestamps.index(end_ts)
if start_ts > start_timestamps[idx]:
start_timestamps[idx] = start_ts

records = self._create_empty_records()
for start_ts, end_ts in sorted(zip(start_timestamps, end_timestamps), key=lambda x: x[0]):
record = {
self._start_column: start_ts,
'response_time': end_ts - start_ts
}
records.append(record)

return records

def to_all_records(self) -> RecordsInterface:
records = self._create_empty_records()

Expand All @@ -292,7 +352,7 @@ def to_worst_case_records(self) -> RecordsInterface:
start_timestamps[idx] = start_ts

records = self._create_empty_records()
for start_ts, end_ts in zip(start_timestamps, end_timestamps):
for start_ts, end_ts in sorted(zip(start_timestamps, end_timestamps), key=lambda x: x[0]):
record = {
self._start_column: start_ts,
'response_time': end_ts - start_ts
Expand Down Expand Up @@ -507,7 +567,7 @@ def to_best_case_records(self) -> RecordsInterface:
- {'response_time'}

"""
return self._timeseries.to_best_case_records()
return self._response_map_all.to_best_case_records()

def to_worst_with_external_latency_case_records(self) -> RecordsInterface:
"""
Expand All @@ -527,7 +587,7 @@ def to_worst_with_external_latency_case_records(self) -> RecordsInterface:
- {'response_time'}

"""
return self._timeseries.to_worst_with_external_latency_case_records()
return self._response_map_all.to_worst_with_external_latency_case_records()

def to_all_stacked_bar(self) -> RecordsInterface:
"""
Expand Down
6 changes: 3 additions & 3 deletions src/test/infra/lttng/test_latency_definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,7 @@ def callback_records(callback_arg) -> RecordsInterface:
f'{callback.callback_name}/callback_end_timestamp': 2,
}
],
[
columns=[
ColumnValue(f'{callback.callback_name}/callback_start_timestamp'),
ColumnValue(f'{callback.callback_name}/callback_end_timestamp'),
]
Expand All @@ -984,7 +984,7 @@ def callback_records(callback_arg) -> RecordsInterface:
f'{callback_.callback_name}/callback_end_timestamp': 4,
}
],
[
columns=[
ColumnValue(f'{callback_.callback_name}/callback_start_timestamp'),
ColumnValue(f'{callback_.callback_name}/callback_end_timestamp'),
]
Expand All @@ -1000,7 +1000,7 @@ def variable_passing_records(var_pass_args) -> RecordsInterface:
f'{callback_.callback_name}/callback_start_timestamp': 3,
}
],
[
columns=[
ColumnValue(f'{callback.callback_name}/callback_end_timestamp'),
ColumnValue(f'{callback_.callback_name}/callback_start_timestamp'),
]
Expand Down
210 changes: 0 additions & 210 deletions src/test/record/records_service/test_response_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,88 +474,6 @@ def test_hist_count(self):

class TestResponseTimeseries:

def test_empty_flow_case(self):
records_raw = [
]
columns = [ColumnValue('start'), ColumnValue('end')]

records = create_records(records_raw, columns)
response = ResponseTime(records)

response_time = response.to_best_case_records()
expect = []
assert to_dict(response_time) == expect

response_time = response.to_worst_with_external_latency_case_records()
expect = []
assert to_dict(response_time) == expect

def test_single_flow_case(self):
records_raw = [
{'start': 0, 'end': 1},
]
columns = [ColumnValue('start'), ColumnValue('end')]

records = create_records(records_raw, columns)
response = ResponseTime(records)

response_time = response.to_best_case_records()
expect = []
assert to_dict(response_time) == expect

response_time = response.to_worst_with_external_latency_case_records()
expect = []
assert to_dict(response_time) == expect

def test_double_flow_case(self):
records_raw = [
{'start': 0, 'end': 1},
{'start': 2, 'end': 3},
]
columns = [ColumnValue('start'), ColumnValue('end')]

records = create_records(records_raw, columns)
response = ResponseTime(records)

response_time = response.to_best_case_records()
expect = [
{'start_max': 2, 'response_time': 1}
]
assert to_dict(response_time) == expect

response_time = response.to_worst_with_external_latency_case_records()
expect = [
{'start_min': 0, 'response_time': 3}
]
assert to_dict(response_time) == expect

# NOTE: Is this test up to specification?
def test_cross_flow_case(self):
records_raw = [
{'start': 0, 'end': 10},
{'start': 3, 'end': 4},
{'start': 4, 'end': 8},
{'start': 6, 'end': 6},
]
columns = [ColumnValue('start'), ColumnValue('end')]

records = create_records(records_raw, columns)
response = ResponseTime(records)

response_time = response.to_best_case_records()
expect = [
{'start_max': 3, 'response_time': 1},
{'start_max': 6, 'response_time': 0}
]
assert to_dict(response_time) == expect

response_time = response.to_worst_with_external_latency_case_records()
expect = [
{'start_min': 0, 'response_time': 4},
{'start_min': 3, 'response_time': 3}
]
assert to_dict(response_time) == expect

class TestMultiColumnCase:
records_raw = [
{'column0': 5, 'column1': 10, 'column2': 15}, # flow 1 [used as first data]
Expand Down Expand Up @@ -592,131 +510,3 @@ def test_to_response_records(self):

output_dict = to_dict(records)
assert output_dict == expect

def test_to_best_case_timeseries(self):
response = ResponseTime(
create_records(self.records_raw, self.columns),
columns=self.column_names
)
response_time = response.to_best_case_records()
expect = [
{'column0_max': 20, 'response_time': 10},
{'column0_max': 35, 'response_time': 10}
]
assert to_dict(response_time) == expect

def test_to_worst_case_timeseries(self):
response = ResponseTime(
create_records(self.records_raw, self.columns),
columns=self.column_names
)
response_time = response.to_worst_with_external_latency_case_records()
expect = [
{'column0_min': 5, 'response_time': 25},
{'column0_min': 20, 'response_time': 25}
]
assert to_dict(response_time) == expect


class TestResponseTimeWorstInInput:

def test_empty_case(self):
records_raw = []
columns = [ColumnValue('start'), ColumnValue('end')]
records = create_records(records_raw, columns)

response_time = ResponseTime(records)

expect_raw = []
result = to_dict(response_time.to_worst_case_records())
assert result == expect_raw

def test_two_column_default_case(self):
records_raw = [
{'start': 0, 'end': 2},
{'start': 3, 'end': 4},
{'start': 11, 'end': 12}
]
columns = [ColumnValue('start'), ColumnValue('end')]
records = create_records(records_raw, columns)

response_time = ResponseTime(records)

expect_raw = [
{'start': 0, 'response_time': 2},
{'start': 3, 'response_time': 1},
{'start': 11, 'response_time': 1}
]
result = to_dict(response_time.to_worst_case_records())
assert result == expect_raw

def test_three_column_default_case(self):
records_raw = [
{'start': 0, 'middle': 1, 'end': 2},
{'start': 3, 'middle': 4, 'end': 6},
{'start': 11, 'middle': 13, 'end': 16}
]
columns = [ColumnValue('start'), ColumnValue('middle'), ColumnValue('end')]
records = create_records(records_raw, columns)

response_time = ResponseTime(records)

expect_raw = [
{'start': 0, 'response_time': 2},
{'start': 3, 'response_time': 3},
{'start': 11, 'response_time': 5}
]
result = to_dict(response_time.to_worst_case_records())
assert result == expect_raw

def test_single_input_multi_output_case(self):
records_raw = [
{'start': 0, 'middle': 4, 'end': 5},
{'start': 0, 'middle': 4, 'end': 6},
{'start': 0, 'middle': 12, 'end': 13}
]
columns = [ColumnValue('start'), ColumnValue('middle'), ColumnValue('end')]
records = create_records(records_raw, columns)

response_time = ResponseTime(records)

expect_raw = [
{'start': 0, 'response_time': 5}
]
result = to_dict(response_time.to_worst_case_records())
assert result == expect_raw

def test_multi_input_single_output_case(self):
records_raw = [
{'start': 0, 'middle': 4, 'end': 13},
{'start': 1, 'middle': 4, 'end': 13},
{'start': 5, 'middle': 12, 'end': 13}
]
columns = [ColumnValue('start'), ColumnValue('middle'), ColumnValue('end')]
records = create_records(records_raw, columns)

response_time = ResponseTime(records)

expect_raw = [
{'start': 0, 'response_time': 13}
]
result = to_dict(response_time.to_worst_case_records())
assert result == expect_raw

def test_drop_case(self):
records_raw = [
{'start': 0, 'middle': 4, 'end': 8},
{'start': 1, 'middle': 4},
{'start': 5, 'middle': 12, 'end': 13}
]
columns = [ColumnValue('start'), ColumnValue('middle'), ColumnValue('end')]
records = create_records(records_raw, columns)

response_time = ResponseTime(records)

expect_raw = [
{'start': 0, 'response_time': 8},
{'start': 1, 'response_time': 12}
]
result = to_dict(response_time.to_worst_case_records())
assert result == expect_raw
Loading
Loading