diff --git a/bzt/modules/external.py b/bzt/modules/external.py index 7347a400d9..a0490521ee 100644 --- a/bzt/modules/external.py +++ b/bzt/modules/external.py @@ -105,7 +105,7 @@ def _get_reader(self): elif header.startswith("= version.parse("3.8.0"): self._copy_dependencies() - self.reader = DataLogReader(self.engine.artifacts_dir, self.log, self.dir_prefix) + self.reader = DataLogReader(self.engine.artifacts_dir, self.log, self.dir_prefix, self.group_response_time) if isinstance(self.engine.aggregator, ConsolidatingAggregator): self.engine.aggregator.add_underling(self.reader) @@ -587,6 +589,8 @@ def _set_env(self): props['gatling.core.directory.resources'] = self.engine.artifacts_dir props['gatling.core.directory.results'] = self.engine.artifacts_dir + props['gatling.charting.useGroupDurationMetric'] = ("true" if self.group_response_time == "duration" else "false") + props.merge(self._get_simulation_props()) props.merge(self._get_load_props()) props.merge(self._get_scenario_props()) @@ -712,7 +716,7 @@ def get_error_diagnostics(self): class DataLogReader(ResultsReader): """ Class to read KPI from data log """ - def __init__(self, basedir, parent_logger, dir_prefix): + def __init__(self, basedir, parent_logger, dir_prefix, group_response_time): super(DataLogReader, self).__init__() self.concurrency = 0 self.log = parent_logger.getChild(self.__class__.__name__) @@ -721,6 +725,7 @@ def __init__(self, basedir, parent_logger, dir_prefix): self.partial_buffer = "" self.delimiter = "\t" self.dir_prefix = dir_prefix + self.group_response_time = group_response_time self.guessed_gatling_version = None self._group_errors = defaultdict(set) @@ -774,7 +779,13 @@ def __parse_group(self, fields): if ',' in label: return None # skip nested groups for now t_stamp = int(fields[2]) / 1000.0 - r_time = int(fields[3]) / 1000.0 + + if self.group_response_time == "duration": + # Switch group response time from cumulated response time to group duration + # Similar behaviour to Gatling's own gatling.charting.useGroupDurationMetric property + r_time = (int(fields[2]) - int(fields[1])) / 1000.0 + else: + r_time = int(fields[3]) / 1000.0 if label in self._group_errors: error = ';'.join(self._group_errors.pop(label)) diff --git a/site/dat/docs/Gatling.md b/site/dat/docs/Gatling.md index c55458d410..2f944abddf 100644 --- a/site/dat/docs/Gatling.md +++ b/site/dat/docs/Gatling.md @@ -260,6 +260,7 @@ included-configs: # it must be a list of string values - `download-link`: Link to download Gatling from. By default: `https://repo1.maven.org/maven2/io/gatling/highcharts/gatling-charts-highcharts-bundle/{version}/gatling-charts-highcharts-bundle-{version}-bundle.zip` - `version`: Gatling version, `3.1.2` by default - `dir-prefix`: Gatling report prefix, `gatling-%s` by default. Used by taurus to find gatling reports. If you use Gatling property `gatling.core.outputDirectoryBaseName`, you may use also this setting. + - `group-response-time`: Group response time metric, `cumulated` (default) or `duration`. If you use Gatling property `charting.charting.useGroupDurationMetric`, you may use also this setting. - `properties`: dictionary for tuning of gatling tool behaviour (see list of available parameters in gatling documentation) and sending your own variables into Scala program: diff --git a/site/dat/docs/changes/feat-gatling-group-duration-metric-support.change b/site/dat/docs/changes/feat-gatling-group-duration-metric-support.change new file mode 100644 index 0000000000..4ca2cba1a8 --- /dev/null +++ b/site/dat/docs/changes/feat-gatling-group-duration-metric-support.change @@ -0,0 +1 @@ +Added option to switch Gatling group metrics calculation from cumulated response time to total group duration \ No newline at end of file diff --git a/tests/resources/gatling/gatling-6-000/simulation.log b/tests/resources/gatling/gatling-6-000/simulation.log new file mode 100644 index 0000000000..6b90085ada --- /dev/null +++ b/tests/resources/gatling/gatling-6-000/simulation.log @@ -0,0 +1,46 @@ +RUN GatlingDemoSimulation gatlingdemosimulation 1715180543697 Gatling Group Duration Demo 3.7.6 +USER Gatling Demo START 1715180545815 +REQUEST Get Page 0 1715180545869 1715180546963 OK +REQUEST Pagination Get Page 0 1715180547003 1715180547128 OK +REQUEST Pagination Get Page 1 1715180547998 1715180548126 OK +REQUEST Pagination Get Page 2 1715180549013 1715180549141 OK +REQUEST Pagination Get Page 3 1715180550019 1715180550146 OK +REQUEST Pagination Get Page 4 1715180551034 1715180551159 OK +USER Gatling Demo START 1715180551798 +GROUP Pagination 1715180546985 1715180552052 633 OK +USER Gatling Demo END 1715180552061 +REQUEST Get Page 0 1715180551798 1715180552180 OK +REQUEST Pagination Get Page 0 1715180552181 1715180552311 OK +REQUEST Pagination Get Page 1 1715180553190 1715180553318 OK +REQUEST Pagination Get Page 2 1715180554192 1715180554327 OK +REQUEST Pagination Get Page 3 1715180555195 1715180555325 OK +REQUEST Pagination Get Page 4 1715180556197 1715180556325 OK +GROUP Pagination 1715180552180 1715180557209 651 OK +USER Gatling Demo END 1715180557211 +USER Gatling Demo START 1715180557803 +REQUEST Get Page 0 1715180557803 1715180558186 OK +REQUEST Pagination Get Page 0 1715180558187 1715180558319 OK +REQUEST Pagination Get Page 1 1715180559194 1715180559324 OK +REQUEST Pagination Get Page 2 1715180560196 1715180560322 OK +REQUEST Pagination Get Page 3 1715180561200 1715180561330 OK +REQUEST Pagination Get Page 4 1715180562215 1715180562347 OK +GROUP Pagination 1715180558187 1715180563221 650 OK +USER Gatling Demo END 1715180563222 +USER Gatling Demo START 1715180563801 +REQUEST Get Page 0 1715180563801 1715180564190 OK +REQUEST Pagination Get Page 0 1715180564191 1715180564322 OK +REQUEST Pagination Get Page 1 1715180565192 1715180565323 OK +REQUEST Pagination Get Page 2 1715180566206 1715180566340 OK +REQUEST Pagination Get Page 3 1715180567210 1715180567341 OK +REQUEST Pagination Get Page 4 1715180568216 1715180568348 OK +GROUP Pagination 1715180564190 1715180569219 659 OK +USER Gatling Demo END 1715180569220 +USER Gatling Demo START 1715180569800 +REQUEST Get Page 0 1715180569800 1715180570195 OK +REQUEST Pagination Get Page 0 1715180570196 1715180570325 OK +REQUEST Pagination Get Page 1 1715180571206 1715180571335 OK +REQUEST Pagination Get Page 2 1715180572221 1715180572353 OK +REQUEST Pagination Get Page 3 1715180573222 1715180573349 OK +REQUEST Pagination Get Page 4 1715180574226 1715180574353 OK +GROUP Pagination 1715180570195 1715180575240 644 OK +USER Gatling Demo END 1715180575241 \ No newline at end of file diff --git a/tests/unit/modules/test_Gatling.py b/tests/unit/modules/test_Gatling.py index 67256520e7..43aa242a24 100644 --- a/tests/unit/modules/test_Gatling.py +++ b/tests/unit/modules/test_Gatling.py @@ -760,7 +760,7 @@ def test_requests_with_include_scenario(self): class TestDataLogReader(BZTestCase): def test_read(self): log_path = RESOURCES_DIR + "gatling/" - obj = DataLogReader(log_path, ROOT_LOGGER, 'gatling-351') + obj = DataLogReader(log_path, ROOT_LOGGER, 'gatling-351', "cumulated") list_of_values = list(obj.datapoints(True)) self.assertEqual(len(list_of_values), 23) self.assertEqual(obj.guessed_gatling_version, "3.4+") @@ -768,7 +768,7 @@ def test_read(self): def test_read_asserts(self): log_path = RESOURCES_DIR + "gatling/" - obj = DataLogReader(log_path, ROOT_LOGGER, 'gatling-1') + obj = DataLogReader(log_path, ROOT_LOGGER, 'gatling-1', "cumulated") list_of_values = list(obj.datapoints(True)) self.assertEqual(len(list_of_values), 3) self.assertEqual(obj.guessed_gatling_version, "3.4+") @@ -776,7 +776,7 @@ def test_read_asserts(self): def test_read_331_format(self): log_path = RESOURCES_DIR + "gatling/" - obj = DataLogReader(log_path, ROOT_LOGGER, 'gatling-331') + obj = DataLogReader(log_path, ROOT_LOGGER, 'gatling-331', "cumulated") list_of_values = list(obj.datapoints(True)) self.assertEqual(len(list_of_values), 2) self.assertEqual(obj.guessed_gatling_version, "3.3.X") @@ -784,7 +784,7 @@ def test_read_331_format(self): def test_read_labels_problematic(self): log_path = RESOURCES_DIR + "gatling/" - obj = DataLogReader(log_path, ROOT_LOGGER, 'gatling-2') # problematic one + obj = DataLogReader(log_path, ROOT_LOGGER, 'gatling-2', "cumulated") # problematic one list_of_values = list(obj.datapoints(True)) self.assertEqual(len(list_of_values), 1) self.assertEqual(obj.guessed_gatling_version, "3.4+") @@ -793,7 +793,7 @@ def test_read_labels_problematic(self): def test_read_labels_regular(self): log_path = RESOURCES_DIR + "gatling/" - obj = DataLogReader(log_path, ROOT_LOGGER, 'gatling-3') # regular one + obj = DataLogReader(log_path, ROOT_LOGGER, 'gatling-3', "cumulated") # regular one list_of_values = list(obj.datapoints(True)) self.assertEqual(len(list_of_values), 10) self.assertEqual(obj.guessed_gatling_version, "3.4+") @@ -801,16 +801,34 @@ def test_read_labels_regular(self): def test_read_group(self): log_path = RESOURCES_DIR + "gatling/" - obj = DataLogReader(log_path, ROOT_LOGGER, 'gatling-4') # regular one + obj = DataLogReader(log_path, ROOT_LOGGER, 'gatling-4', "cumulated") # regular one list_of_values = list(obj.datapoints(True)) self.assertEqual(len(list_of_values), 179) self.assertEqual(obj.guessed_gatling_version, "3.4+") last_cumul = list_of_values[-1][DataPoint.CUMULATIVE] self.assertEqual(2, len(last_cumul['[empty]'][KPISet.ERRORS])) + def test_read_group_response_cucumated(self): + log_path = RESOURCES_DIR + "gatling/" + obj = DataLogReader(log_path, ROOT_LOGGER, 'gatling-6', "cumulated") # reading group response time set to cumulated response time (default) + list_of_values = list(obj.datapoints(True)) + self.assertEqual(len(list_of_values), 9) + self.assertEqual(obj.guessed_gatling_version, "3.4+") + last_cumul = list_of_values[-1][DataPoint.CUMULATIVE] + self.assertEqual(0.6474, last_cumul['Pagination'][KPISet.AVG_RESP_TIME]) + + def test_read_group_response_duration(self): + log_path = RESOURCES_DIR + "gatling/" + obj = DataLogReader(log_path, ROOT_LOGGER, 'gatling-6', "duration") # reading group response time set to total duration + list_of_values = list(obj.datapoints(True)) + self.assertEqual(len(list_of_values), 9) + self.assertEqual(obj.guessed_gatling_version, "3.4+") + last_cumul = list_of_values[-1][DataPoint.CUMULATIVE] + self.assertEqual(5.0408, last_cumul['Pagination'][KPISet.AVG_RESP_TIME]) + def test_read_rc_asserts(self): log_path = RESOURCES_DIR + "gatling/" - obj = DataLogReader(log_path, ROOT_LOGGER, 'gatling-5') # regular one + obj = DataLogReader(log_path, ROOT_LOGGER, 'gatling-5', "cumulated") # regular one list_of_values = list(obj.datapoints(True)) self.assertEqual(len(list_of_values), 1) self.assertEqual(obj.guessed_gatling_version, "3.4+")