From 23ae29fd4139ede59f45c5cbe7571eaba6d010e7 Mon Sep 17 00:00:00 2001 From: rokamu623 Date: Wed, 30 Aug 2023 20:49:45 +0900 Subject: [PATCH 01/11] refact: best/worst records Signed-off-by: rokamu623 --- .../record/records_service/response_time.py | 54 +++++ .../records_service/test_response_time_all.py | 208 ++++++++++++++++++ 2 files changed, 262 insertions(+) diff --git a/src/caret_analyze/record/records_service/response_time.py b/src/caret_analyze/record/records_service/response_time.py index 8e35fe053..8aa578d5c 100644 --- a/src/caret_analyze/record/records_service/response_time.py +++ b/src/caret_analyze/record/records_service/response_time.py @@ -262,6 +262,54 @@ def __init__( self._start_timestamps[idx] = start_ts self._end_timestamps[idx] = end_ts + def to_worst_records(self) -> RecordsInterface: + records = self._create_empty_records() + + end_timestamps: list[int] = [] + start_timestamps: list[int] = [] + for start_ts, end_ts in zip(self._start_timestamps[:-1], self._end_timestamps[1:]): + 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 + end_timestamps[idx] = end_ts + + for start_ts, end_ts in zip(start_timestamps, end_timestamps): + record = { + self._start_column: start_ts, + 'response_time': end_ts - start_ts + } + records.append(record) + + return records + + def to_best_records(self) -> RecordsInterface: + records = self._create_empty_records() + + 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 + end_timestamps[idx] = end_ts + + for start_ts, end_ts in zip(start_timestamps, end_timestamps): + 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() @@ -348,6 +396,12 @@ def __init__( self._timeseries = ResponseTimeseries(self._records) self._histogram = ResponseHistogram(self._records, self._timeseries) + def to_best_records(self) -> RecordsInterface: + return self._response_map_all.to_best_records() + + def to_worst_records(self) -> RecordsInterface: + return self._response_map_all.to_worst_records() + def to_all_records(self) -> RecordsInterface: return self._response_map_all.to_all_records() diff --git a/src/test/record/records_service/test_response_time_all.py b/src/test/record/records_service/test_response_time_all.py index 3d1f85ee8..f19bec216 100644 --- a/src/test/record/records_service/test_response_time_all.py +++ b/src/test/record/records_service/test_response_time_all.py @@ -138,3 +138,211 @@ def test_drop_case(self): ] result = to_dict(response_time.to_all_records()) assert result == expect_raw + +class TestResponseTimeBest: + + 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_best_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_best_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_best_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_best_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': 5, 'response_time': 8} + ] + result = to_dict(response_time.to_best_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': 5, 'response_time': 8} + ] + result = to_dict(response_time.to_best_records()) + assert result == expect_raw + +class TestResponseTimeWorst: + + 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_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': 4}, + {'start': 3, 'response_time': 9} + ] + result = to_dict(response_time.to_worst_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': 6}, + {'start': 3, 'response_time': 13} + ] + result = to_dict(response_time.to_worst_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': 3, 'middle': 10, 'end': 11}, + {'start': 3, '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': 11}, + ] + result = to_dict(response_time.to_worst_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_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': 13} + ] + result = to_dict(response_time.to_worst_records()) + assert result == expect_raw From f0366499d7cc415ec1147e70ec92d2a11077b55c Mon Sep 17 00:00:00 2001 From: rokamu623 Date: Thu, 31 Aug 2023 20:53:23 +0900 Subject: [PATCH 02/11] fix: unnesessary discription Signed-off-by: rokamu623 --- src/caret_analyze/record/records_service/response_time.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/caret_analyze/record/records_service/response_time.py b/src/caret_analyze/record/records_service/response_time.py index 174895f13..0766df4e2 100644 --- a/src/caret_analyze/record/records_service/response_time.py +++ b/src/caret_analyze/record/records_service/response_time.py @@ -275,7 +275,6 @@ def to_worst_records(self) -> RecordsInterface: idx = end_timestamps.index(end_ts) if start_ts < start_timestamps[idx]: start_timestamps[idx] = start_ts - end_timestamps[idx] = end_ts for start_ts, end_ts in zip(start_timestamps, end_timestamps): record = { @@ -299,7 +298,6 @@ def to_best_records(self) -> RecordsInterface: idx = end_timestamps.index(end_ts) if start_ts > start_timestamps[idx]: start_timestamps[idx] = start_ts - end_timestamps[idx] = end_ts for start_ts, end_ts in zip(start_timestamps, end_timestamps): record = { From 4d22f96d0bd0fe6c18330e3d8507c38888c761f6 Mon Sep 17 00:00:00 2001 From: rokamu623 Date: Fri, 1 Sep 2023 13:26:21 +0900 Subject: [PATCH 03/11] refact: worst (worst-to-best) Signed-off-by: rokamu623 --- .../record/records_service/response_time.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/caret_analyze/record/records_service/response_time.py b/src/caret_analyze/record/records_service/response_time.py index 0766df4e2..915fde9d1 100644 --- a/src/caret_analyze/record/records_service/response_time.py +++ b/src/caret_analyze/record/records_service/response_time.py @@ -263,30 +263,36 @@ def __init__( self._end_timestamps[idx] = end_ts def to_worst_records(self) -> RecordsInterface: - records = self._create_empty_records() end_timestamps: list[int] = [] start_timestamps: list[int] = [] - for start_ts, end_ts in zip(self._start_timestamps[:-1], self._end_timestamps[1:]): + 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 - for start_ts, end_ts in zip(start_timestamps, end_timestamps): + records = self._create_empty_records() + for start_ts, end_ts, worst_to_best_ts in zip(start_timestamps, + end_timestamps, + worst_to_best_timestamps): record = { - self._start_column: start_ts, - 'response_time': end_ts - start_ts + 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_records(self) -> RecordsInterface: - records = self._create_empty_records() end_timestamps: list[int] = [] start_timestamps: list[int] = [] @@ -299,6 +305,7 @@ def to_best_records(self) -> RecordsInterface: if start_ts > start_timestamps[idx]: start_timestamps[idx] = start_ts + records = self._create_empty_records() for start_ts, end_ts in zip(start_timestamps, end_timestamps): record = { self._start_column: start_ts, From ea65f5bdb2bd4af15c6af1b28e52ceee23ff0f82 Mon Sep 17 00:00:00 2001 From: rokamu623 Date: Fri, 1 Sep 2023 13:27:57 +0900 Subject: [PATCH 04/11] fix: flake8 Signed-off-by: rokamu623 --- src/test/record/records_service/test_response_time_all.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/record/records_service/test_response_time_all.py b/src/test/record/records_service/test_response_time_all.py index f19bec216..7aa4ec1bb 100644 --- a/src/test/record/records_service/test_response_time_all.py +++ b/src/test/record/records_service/test_response_time_all.py @@ -139,6 +139,7 @@ def test_drop_case(self): result = to_dict(response_time.to_all_records()) assert result == expect_raw + class TestResponseTimeBest: def test_empty_case(self): @@ -244,6 +245,7 @@ def test_drop_case(self): result = to_dict(response_time.to_best_records()) assert result == expect_raw + class TestResponseTimeWorst: def test_empty_case(self): From b75740c2e2e16020a22817089ff7bc193230d3bf Mon Sep 17 00:00:00 2001 From: rokamu623 Date: Fri, 20 Oct 2023 15:52:13 +0900 Subject: [PATCH 05/11] fix: option name Signed-off-by: rokamu623 --- .../record/records_service/response_time.py | 14 +- .../records_service/test_response_time.py | 112 +-------------- .../records_service/test_response_time_all.py | 131 ++++++++++++++++-- 3 files changed, 128 insertions(+), 129 deletions(-) diff --git a/src/caret_analyze/record/records_service/response_time.py b/src/caret_analyze/record/records_service/response_time.py index 6197a2621..c38d2d363 100644 --- a/src/caret_analyze/record/records_service/response_time.py +++ b/src/caret_analyze/record/records_service/response_time.py @@ -267,7 +267,7 @@ def __init__( self._end_timestamps[idx] = end_ts self._records[idx] = record - def to_worst_records(self) -> RecordsInterface: + def to_worst_with_external_latency_case_records(self) -> RecordsInterface: end_timestamps: list[int] = [] start_timestamps: list[int] = [] @@ -297,7 +297,7 @@ def to_worst_records(self) -> RecordsInterface: return records - def to_best_records(self) -> RecordsInterface: + def to_best_case_records(self) -> RecordsInterface: end_timestamps: list[int] = [] start_timestamps: list[int] = [] @@ -504,12 +504,6 @@ def __init__( self._timeseries = ResponseTimeseries(self._records) self._histogram = ResponseHistogram(self._records, self._timeseries) - def to_best_records(self) -> RecordsInterface: - return self._response_map_all.to_best_records() - - def to_worst_records(self) -> RecordsInterface: - return self._response_map_all.to_worst_records() - def to_all_records(self) -> RecordsInterface: """ Calculate the data of all records for response time. @@ -565,7 +559,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: """ @@ -585,7 +579,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: """ diff --git a/src/test/record/records_service/test_response_time.py b/src/test/record/records_service/test_response_time.py index 73a988a34..f9e56f616 100644 --- a/src/test/record/records_service/test_response_time.py +++ b/src/test/record/records_service/test_response_time.py @@ -500,7 +500,9 @@ def test_single_flow_case(self): response = ResponseTime(records) response_time = response.to_best_case_records() - expect = [] + expect = [ + {'start': 0, 'response_time': 1} + ] assert to_dict(response_time) == expect response_time = response.to_worst_with_external_latency_case_records() @@ -519,13 +521,14 @@ def test_double_flow_case(self): response_time = response.to_best_case_records() expect = [ - {'start_max': 2, 'response_time': 1} + {'start': 0, 'response_time': 1}, + {'start': 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} + {'start': 0, 'response_time': 3} ] assert to_dict(response_time) == expect @@ -617,106 +620,3 @@ def test_to_worst_case_timeseries(self): ] 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 diff --git a/src/test/record/records_service/test_response_time_all.py b/src/test/record/records_service/test_response_time_all.py index cbd3c5b81..edacc5aa8 100644 --- a/src/test/record/records_service/test_response_time_all.py +++ b/src/test/record/records_service/test_response_time_all.py @@ -152,7 +152,7 @@ def test_empty_case(self): expect_raw = [ ] - result = to_dict(response_time.to_best_records()) + result = to_dict(response_time.to_best_case_records()) assert result == expect_raw def test_two_column_default_case(self): @@ -171,7 +171,7 @@ def test_two_column_default_case(self): {'start': 3, 'response_time': 1}, {'start': 11, 'response_time': 1} ] - result = to_dict(response_time.to_best_records()) + result = to_dict(response_time.to_best_case_records()) assert result == expect_raw def test_three_column_default_case(self): @@ -190,7 +190,7 @@ def test_three_column_default_case(self): {'start': 3, 'response_time': 3}, {'start': 11, 'response_time': 5} ] - result = to_dict(response_time.to_best_records()) + result = to_dict(response_time.to_best_case_records()) assert result == expect_raw def test_single_input_multi_output_case(self): @@ -207,7 +207,7 @@ def test_single_input_multi_output_case(self): expect_raw = [ {'start': 0, 'response_time': 5} ] - result = to_dict(response_time.to_best_records()) + result = to_dict(response_time.to_best_case_records()) assert result == expect_raw def test_multi_input_single_output_case(self): @@ -224,11 +224,11 @@ def test_multi_input_single_output_case(self): expect_raw = [ {'start': 5, 'response_time': 8} ] - result = to_dict(response_time.to_best_records()) + result = to_dict(response_time.to_best_case_records()) assert result == expect_raw -class TestResponseTimeWorst: +class TestResponseTimeWorstWithExternalLatency: def test_empty_case(self): records_raw = [ @@ -240,7 +240,7 @@ def test_empty_case(self): expect_raw = [ ] - result = to_dict(response_time.to_worst_records()) + result = to_dict(response_time.to_worst_with_external_latency_case_records()) assert result == expect_raw def test_two_column_default_case(self): @@ -258,7 +258,7 @@ def test_two_column_default_case(self): {'start': 0, 'response_time': 4}, {'start': 3, 'response_time': 9} ] - result = to_dict(response_time.to_worst_records()) + result = to_dict(response_time.to_worst_with_external_latency_case_records()) assert result == expect_raw def test_three_column_default_case(self): @@ -276,7 +276,7 @@ def test_three_column_default_case(self): {'start': 0, 'response_time': 6}, {'start': 3, 'response_time': 13} ] - result = to_dict(response_time.to_worst_records()) + result = to_dict(response_time.to_worst_with_external_latency_case_records()) assert result == expect_raw def test_single_input_multi_output_case(self): @@ -294,7 +294,111 @@ def test_single_input_multi_output_case(self): expect_raw = [ {'start': 0, 'response_time': 11}, ] - result = to_dict(response_time.to_worst_records()) + result = to_dict(response_time.to_worst_with_external_latency_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_with_external_latency_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': 13}, + {'start': 1, 'response_time': 12} + ] + result = to_dict(response_time.to_worst_with_external_latency_case_records()) + assert result == expect_raw + + +class TestResponseTimeWorst: + + 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): @@ -311,7 +415,7 @@ def test_multi_input_single_output_case(self): expect_raw = [ {'start': 0, 'response_time': 13} ] - result = to_dict(response_time.to_worst_records()) + result = to_dict(response_time.to_worst_case_records()) assert result == expect_raw def test_drop_case(self): @@ -327,9 +431,9 @@ def test_drop_case(self): expect_raw = [ {'start': 0, 'response_time': 8}, - {'start': 5, 'response_time': 8} + {'start': 1, 'response_time': 12} ] - result = to_dict(response_time.to_best_records()) + result = to_dict(response_time.to_worst_case_records()) assert result == expect_raw @@ -412,6 +516,7 @@ def test_drop_case(self): result = to_dict(response_time.to_all_stacked_bar()) assert result == expect_raw + class TestWorstInInputStackedBar: @property From c8ecbe5e7023aceae45242cca299626798642ab4 Mon Sep 17 00:00:00 2001 From: rokamu623 Date: Fri, 20 Oct 2023 16:05:50 +0900 Subject: [PATCH 06/11] fix: test Signed-off-by: rokamu623 --- .../records_service/test_response_time.py | 25 ------------------- .../records_service/test_response_time_all.py | 3 +-- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/src/test/record/records_service/test_response_time.py b/src/test/record/records_service/test_response_time.py index f9e56f616..db2e14f07 100644 --- a/src/test/record/records_service/test_response_time.py +++ b/src/test/record/records_service/test_response_time.py @@ -595,28 +595,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 - diff --git a/src/test/record/records_service/test_response_time_all.py b/src/test/record/records_service/test_response_time_all.py index edacc5aa8..7ebf6ba77 100644 --- a/src/test/record/records_service/test_response_time_all.py +++ b/src/test/record/records_service/test_response_time_all.py @@ -326,8 +326,7 @@ def test_drop_case(self): response_time = ResponseTime(records) expect_raw = [ - {'start': 0, 'response_time': 13}, - {'start': 1, 'response_time': 12} + {'start': 0, 'response_time': 13} ] result = to_dict(response_time.to_worst_with_external_latency_case_records()) assert result == expect_raw From 9c539f94ad70b74f1ce3475593ac0713c8b23c92 Mon Sep 17 00:00:00 2001 From: rokamu623 Date: Fri, 20 Oct 2023 16:34:04 +0900 Subject: [PATCH 07/11] erase old tests (WiP) Signed-off-by: rokamu623 --- .../records_service/test_response_time.py | 59 +------------------ 1 file changed, 1 insertion(+), 58 deletions(-) diff --git a/src/test/record/records_service/test_response_time.py b/src/test/record/records_service/test_response_time.py index db2e14f07..0fdea6c5a 100644 --- a/src/test/record/records_service/test_response_time.py +++ b/src/test/record/records_service/test_response_time.py @@ -474,64 +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 = [ - {'start': 0, 'response_time': 1} - ] - 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': 0, 'response_time': 1}, - {'start': 2, 'response_time': 1} - ] - assert to_dict(response_time) == expect - - response_time = response.to_worst_with_external_latency_case_records() - expect = [ - {'start': 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 = [ @@ -559,6 +501,7 @@ def test_cross_flow_case(self): ] assert to_dict(response_time) == expect + class TestMultiColumnCase: records_raw = [ {'column0': 5, 'column1': 10, 'column2': 15}, # flow 1 [used as first data] From 547b49637ed8ec6b999d8e1011a7d58bea61e577 Mon Sep 17 00:00:00 2001 From: rokamu623 Date: Tue, 24 Oct 2023 09:00:22 +0900 Subject: [PATCH 08/11] fix: test to refactored functions Signed-off-by: rokamu623 --- .../records_service/test_response_time.py | 28 ------- .../records_service/test_response_time_all.py | 81 +++++++++++++++++++ 2 files changed, 81 insertions(+), 28 deletions(-) diff --git a/src/test/record/records_service/test_response_time.py b/src/test/record/records_service/test_response_time.py index 0fdea6c5a..4888e6b7c 100644 --- a/src/test/record/records_service/test_response_time.py +++ b/src/test/record/records_service/test_response_time.py @@ -474,34 +474,6 @@ def test_hist_count(self): class TestResponseTimeseries: - # 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] diff --git a/src/test/record/records_service/test_response_time_all.py b/src/test/record/records_service/test_response_time_all.py index 7ebf6ba77..953717699 100644 --- a/src/test/record/records_service/test_response_time_all.py +++ b/src/test/record/records_service/test_response_time_all.py @@ -139,6 +139,27 @@ def test_drop_case(self): result = to_dict(response_time.to_all_records()) assert result == expect_raw + def test_cross_flow_case(self): + records_raw = [ + {'start': 0, 'end': 10}, + {'start': 3, 'end': 4}, + {'start': 4, 'end': 10}, + {'start': 6, 'end': 6}, + ] + columns = [ColumnValue('start'), ColumnValue('end')] + + records = create_records(records_raw, columns) + response = ResponseTime(records) + + response_time = response.to_all_records() + expect = [ + {'start': 0, 'response_time': 10}, + {'start': 3, 'response_time': 1}, + {'start': 4, 'response_time': 6}, + {'start': 6, 'response_time': 0} + ] + assert to_dict(response_time) == expect + class TestResponseTimeBest: @@ -227,6 +248,26 @@ def test_multi_input_single_output_case(self): result = to_dict(response_time.to_best_case_records()) assert result == expect_raw + def test_cross_flow_case(self): + records_raw = [ + {'start': 0, 'end': 10}, + {'start': 3, 'end': 4}, + {'start': 4, 'end': 10}, + {'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': 3, 'response_time': 1}, + {'start': 4, 'response_time': 6}, + {'start': 6, 'response_time': 0} + ] + assert to_dict(response_time) == expect + class TestResponseTimeWorstWithExternalLatency: @@ -331,6 +372,26 @@ def test_drop_case(self): result = to_dict(response_time.to_worst_with_external_latency_case_records()) assert result == expect_raw + def test_cross_flow_case(self): + records_raw = [ + {'start': 0, 'end': 10}, + {'start': 3, 'end': 4}, + {'start': 4, 'end': 10}, + {'start': 6, 'end': 6}, + ] + columns = [ColumnValue('start'), ColumnValue('end')] + + records = create_records(records_raw, columns) + response = ResponseTime(records) + + response_time = response.to_worst_with_external_latency_case_records() + expect = [ + {'start': 0, 'response_time': 4}, + {'start': 3, 'response_time': 7}, + {'start': 4, 'response_time': 2} + ] + assert to_dict(response_time) == expect + class TestResponseTimeWorst: @@ -435,6 +496,26 @@ def test_drop_case(self): result = to_dict(response_time.to_worst_case_records()) assert result == expect_raw + def test_cross_flow_case(self): + records_raw = [ + {'start': 0, 'end': 10}, + {'start': 3, 'end': 4}, + {'start': 4, 'end': 10}, + {'start': 6, 'end': 6}, + ] + columns = [ColumnValue('start'), ColumnValue('end')] + + records = create_records(records_raw, columns) + response = ResponseTime(records) + + response_time = response.to_worst_case_records() + expect = [ + {'start': 0, 'response_time': 10}, + {'start': 3, 'response_time': 1}, + {'start': 6, 'response_time': 0} + ] + assert to_dict(response_time) == expect + class TestAllStackedBar: From d05e8c1c87ab418ded6de614a3b3e557b331e338 Mon Sep 17 00:00:00 2001 From: rokamu623 Date: Tue, 24 Oct 2023 09:00:46 +0900 Subject: [PATCH 09/11] fix: order to start time Signed-off-by: rokamu623 --- .../record/records_service/response_time.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/caret_analyze/record/records_service/response_time.py b/src/caret_analyze/record/records_service/response_time.py index c38d2d363..78a3db5f1 100644 --- a/src/caret_analyze/record/records_service/response_time.py +++ b/src/caret_analyze/record/records_service/response_time.py @@ -286,9 +286,10 @@ def to_worst_with_external_latency_case_records(self) -> RecordsInterface: 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 zip(start_timestamps, - end_timestamps, - worst_to_best_timestamps): + 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) @@ -311,7 +312,7 @@ def to_best_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 @@ -345,7 +346,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 From 7d14f65329608cfb9d8bb50899663b81ef7c46c2 Mon Sep 17 00:00:00 2001 From: rokamu623 Date: Thu, 2 Nov 2023 14:18:06 +0900 Subject: [PATCH 10/11] fix: pass pytest Signed-off-by: rokamu623 --- src/test/infra/lttng/test_latency_definitions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/infra/lttng/test_latency_definitions.py b/src/test/infra/lttng/test_latency_definitions.py index e094fd13e..84bab8d99 100644 --- a/src/test/infra/lttng/test_latency_definitions.py +++ b/src/test/infra/lttng/test_latency_definitions.py @@ -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'), ] @@ -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'), ] @@ -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'), ] From 90c565d7c12a7b22c2ddef8a2ad0cb833aa37b7a Mon Sep 17 00:00:00 2001 From: rokamu623 Date: Thu, 2 Nov 2023 17:57:25 +0900 Subject: [PATCH 11/11] feat: handling invalid response time Signed-off-by: rokamu623 --- .../record/records_service/response_time.py | 6 + .../records_service/test_response_time_all.py | 121 ++++++++++++++++++ 2 files changed, 127 insertions(+) diff --git a/src/caret_analyze/record/records_service/response_time.py b/src/caret_analyze/record/records_service/response_time.py index 99fc6cb7a..8e2bf2225 100644 --- a/src/caret_analyze/record/records_service/response_time.py +++ b/src/caret_analyze/record/records_service/response_time.py @@ -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) diff --git a/src/test/record/records_service/test_response_time_all.py b/src/test/record/records_service/test_response_time_all.py index 953717699..f371df29b 100644 --- a/src/test/record/records_service/test_response_time_all.py +++ b/src/test/record/records_service/test_response_time_all.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import warnings + from caret_analyze.record import ColumnValue from caret_analyze.record import ResponseTime from caret_analyze.record.record_factory import RecordsFactory @@ -160,6 +162,36 @@ def test_cross_flow_case(self): ] assert to_dict(response_time) == expect + def test_invalid_value_case(self): + records_raw = [ + {'start': 0, 'end': 2}, + {'start': 3, 'end': 2}, + {'start': 3, 'end': 4}, + {'start': 11, 'end': 12}, + {'start': 13, 'end': 12} + ] + columns = [ColumnValue('start'), ColumnValue('end')] + records = create_records(records_raw, columns) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + warning_message =\ + 'Record data is invalid. '\ + 'The end time of the path is recorded before the start time.' + + response_time = ResponseTime(records) + + assert issubclass(w[0].category, UserWarning) + assert str(w[0].message) == warning_message + + expect_raw = [ + {'start': 0, 'response_time': 2}, + {'start': 3, 'response_time': 1}, + {'start': 11, 'response_time': 1} + ] + result = to_dict(response_time.to_all_records()) + assert result == expect_raw + class TestResponseTimeBest: @@ -268,6 +300,36 @@ def test_cross_flow_case(self): ] assert to_dict(response_time) == expect + def test_invalid_value_case(self): + records_raw = [ + {'start': 0, 'end': 2}, + {'start': 3, 'end': 2}, + {'start': 3, 'end': 4}, + {'start': 11, 'end': 12}, + {'start': 13, 'end': 12} + ] + columns = [ColumnValue('start'), ColumnValue('end')] + records = create_records(records_raw, columns) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + warning_message =\ + 'Record data is invalid. '\ + 'The end time of the path is recorded before the start time.' + + response_time = ResponseTime(records) + + assert issubclass(w[0].category, UserWarning) + assert str(w[0].message) == warning_message + + expect_raw = [ + {'start': 0, 'response_time': 2}, + {'start': 3, 'response_time': 1}, + {'start': 11, 'response_time': 1}, + ] + result = to_dict(response_time.to_best_case_records()) + assert result == expect_raw + class TestResponseTimeWorstWithExternalLatency: @@ -392,6 +454,35 @@ def test_cross_flow_case(self): ] assert to_dict(response_time) == expect + def test_invalid_value_case(self): + records_raw = [ + {'start': 0, 'end': 2}, + {'start': 3, 'end': 2}, + {'start': 3, 'end': 4}, + {'start': 11, 'end': 12}, + {'start': 13, 'end': 12} + ] + columns = [ColumnValue('start'), ColumnValue('end')] + records = create_records(records_raw, columns) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + warning_message =\ + 'Record data is invalid. '\ + 'The end time of the path is recorded before the start time.' + + response_time = ResponseTime(records) + + assert issubclass(w[0].category, UserWarning) + assert str(w[0].message) == warning_message + + expect_raw = [ + {'start': 0, 'response_time': 4}, + {'start': 3, 'response_time': 9} + ] + result = to_dict(response_time.to_worst_with_external_latency_case_records()) + assert result == expect_raw + class TestResponseTimeWorst: @@ -516,6 +607,36 @@ def test_cross_flow_case(self): ] assert to_dict(response_time) == expect + def test_invalid_value_case(self): + records_raw = [ + {'start': 0, 'end': 2}, + {'start': 3, 'end': 2}, + {'start': 3, 'end': 4}, + {'start': 11, 'end': 12}, + {'start': 13, 'end': 12} + ] + columns = [ColumnValue('start'), ColumnValue('end')] + records = create_records(records_raw, columns) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + warning_message =\ + 'Record data is invalid. '\ + 'The end time of the path is recorded before the start time.' + + response_time = ResponseTime(records) + + assert issubclass(w[0].category, UserWarning) + assert str(w[0].message) == warning_message + + 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 + class TestAllStackedBar: