Skip to content
Open
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
2 changes: 1 addition & 1 deletion bzt/modules/external.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def _get_reader(self):
elif header.startswith("<?xml"):
return XMLJTLReader(self.data_file, self.log)
elif header.startswith("RUN\t") or "\tRUN\t" in header:
return GatlingLogReader(self.data_file, self.log, None)
return GatlingLogReader(self.data_file, self.log, None, None)
elif "timestamp" in header.lower() and "elapsed" in header.lower():
return JTLReader(self.data_file, self.log, self.errors_file)
else:
Expand Down
17 changes: 14 additions & 3 deletions bzt/modules/gatling.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@ def __init__(self):
self.retcode = None
self.simulation_started = False
self.dir_prefix = "gatling-%s" % id(self)
self.group_response_time = "cumulated"
self.tool = None

# def get_cp_from_files(self):
Expand Down Expand Up @@ -500,6 +501,7 @@ def prepare(self):
raise TaurusConfigError(msg)

self.dir_prefix = self.settings.get("dir-prefix", self.dir_prefix)
self.group_response_time = self.settings.get("group-response-time", self.group_response_time)

self.stdout = open(self.engine.create_artifact("gatling", ".out"), "w")
self.stderr = open(self.engine.create_artifact("gatling", ".err"), "w")
Expand All @@ -508,7 +510,7 @@ def prepare(self):
if version.parse(self.tool.version) >= 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)

Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -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__)
Expand All @@ -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)

Expand Down Expand Up @@ -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))
Expand Down
1 change: 1 addition & 0 deletions site/dat/docs/Gatling.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added option to switch Gatling group metrics calculation from cumulated response time to total group duration
46 changes: 46 additions & 0 deletions tests/resources/gatling/gatling-6-000/simulation.log
Original file line number Diff line number Diff line change
@@ -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
32 changes: 25 additions & 7 deletions tests/unit/modules/test_Gatling.py
Original file line number Diff line number Diff line change
Expand Up @@ -760,31 +760,31 @@ 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+")
self.assertIn('request_1', list_of_values[-1][DataPoint.CUMULATIVE].keys())

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+")
self.assertIn('ping request', list_of_values[-1][DataPoint.CUMULATIVE].keys())

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")
self.assertIn('request_1', list_of_values[-1][DataPoint.CUMULATIVE].keys())

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+")
Expand All @@ -793,24 +793,42 @@ 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+")
self.assertIn('http://blazedemo.com/', list_of_values[-1][DataPoint.CUMULATIVE].keys())

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+")
Expand Down