Skip to content

Commit

Permalink
Use start time for filename, add duration to html report and add some…
Browse files Browse the repository at this point in the history
… doc about dev

Signed-off-by: Olivier Briat <olivier.briat@kleegroup.com>
  • Loading branch information
Olivier Briat committed Oct 20, 2024
1 parent ab6ae60 commit 9ece97a
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 14 deletions.
14 changes: 13 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"gevent": true
},
{
"name": "Run locust",
"name": "Run current locust scenario headless, 5 users",
"type": "python",
"request": "launch",
"module": "locust",
Expand All @@ -22,6 +22,18 @@
],
"console": "integratedTerminal",
"gevent": true
},
{
"name": "Run current locust scenario with WebUI",
"type": "python",
"request": "launch",
"module": "locust",
"args": [
"-f",
"${file}"
],
"console": "integratedTerminal",
"gevent": true
}
]
}
14 changes: 14 additions & 0 deletions docs/developing-locust.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ If you install `pre-commit <https://pre-commit.com/>`_, linting and format check

Before you open a pull request, make sure all the tests work. And if you are adding a feature, make sure it is documented (in ``docs/*.rst``).

If you're in a hurry or don't have access to a development environment, you can simply use `Codespaces <https://github.com/features/codespaces>`_, the github cloud development environment. On your fork page, just click on *Code* then on *Create codespace on <branch name>*, and voila, your ready to code and test.

Testing your changes
====================

Expand All @@ -51,6 +53,18 @@ To only run a specific suite or specific test you can call `pytest <https://docs
$ pytest locust/test/test_main.py::DistributedIntegrationTests::test_distributed_tags
Debugging
=========

Debugging Locust is quite easy with Vscode:

- Place breakpoints,
- Select a python file or a scenario (ex: ```examples/basic.py``)
- Check that the Poetry virtualenv is correctly detected (bottom right)
- Open the action *Debug using launch.json*. You will have the choice between debugging the python file, the scenario with WebUI or in headless mode.
- It could be rerun with the F5 shortkey


Formatting and linting
======================

Expand Down
3 changes: 2 additions & 1 deletion locust/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from .runners import STATE_STOPPED, STATE_STOPPING, MasterRunner
from .stats import sort_stats, update_stats_history
from .user.inspectuser import get_ratio
from .util.date import format_utc_timestamp
from .util.date import format_duration, format_utc_timestamp

PERCENTILES_FOR_HTML_REPORT = [0.50, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 1.0]
DEFAULT_BUILD_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "webui", "dist")
Expand Down Expand Up @@ -88,6 +88,7 @@ def get_html_report(
],
"start_time": start_time,
"end_time": end_time,
"duration": format_duration(stats.start_time, stats.last_request_timestamp),
"host": escape(str(host)),
"history": history,
"show_download_link": show_download_link,
Expand Down
10 changes: 10 additions & 0 deletions locust/util/date.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
from datetime import datetime, timezone

import humanfriendly


def format_utc_timestamp(unix_timestamp):
return datetime.fromtimestamp(unix_timestamp, timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")


def format_safe_timestamp(unix_timestamp):
return datetime.fromtimestamp(unix_timestamp).strftime("%Y-%m-%d %Hh%M")


def format_duration(start_unix_timestamp, end_unix_timestamp):
return humanfriendly.format_timespan(end_unix_timestamp - start_unix_timestamp)
18 changes: 9 additions & 9 deletions locust/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from io import StringIO
from itertools import chain
from json import dumps
from time import localtime, strftime
from typing import TYPE_CHECKING, Any

import gevent
Expand Down Expand Up @@ -39,7 +38,7 @@
from .stats import StatsCSV, StatsCSVFileWriter, StatsErrorDict, sort_stats
from .user.inspectuser import get_ratio
from .util.cache import memoize
from .util.date import format_utc_timestamp
from .util.date import format_safe_timestamp
from .util.timespan import parse_timespan

if TYPE_CHECKING:
Expand Down Expand Up @@ -318,11 +317,10 @@ def stats_report() -> Response:
)
if request.args.get("download"):
res = app.make_response(res)
# TODO: Use host & startTime

host = self.environment.host or "no host"
res.headers["Content-Disposition"] = (
f"attachment;filename={self.start} - Locust - "
+ f"{self.environment.locustfile} - {self.environment.host}.html",
f"attachment;filename=Locust - {format_safe_timestamp(self.environment.stats.start_time)} - "
+ f"{self.environment.locustfile} - {host}.html"
)
return res

Expand All @@ -333,9 +331,11 @@ def _download_csv_suggest_file_name(suggest_filename_prefix: str) -> str:
suggest_filename_prefix: Prefix of the filename to suggest for saving the download.
Will be appended with timestamp.
"""

# TODO: Use host & startTime
return f"{strftime('%Y-%m-%d %Hh%M', localtime())}-{suggest_filename_prefix}.csv"
host = self.environment.host or "no host"
return (
f"Locust - {format_safe_timestamp(self.environment.stats.start_time)} - "
+ f"{self.environment.locustfile} - {host} - {suggest_filename_prefix}.csv"
)

def _download_csv_response(csv_data: str, filename_prefix: str) -> Response:
"""Generate csv file download response with 'csv_data'.
Expand Down
3 changes: 2 additions & 1 deletion locust/webui/src/pages/HtmlReport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export default function HtmlReport({
showDownloadLink,
startTime,
endTime,
duration,
charts,
host,
exceptionsStatistics,
Expand Down Expand Up @@ -75,7 +76,7 @@ export default function HtmlReport({
<Box sx={{ display: 'flex', columnGap: 0.5 }}>
<Typography fontWeight={600}>During:</Typography>
<Typography>
{formatLocaleString(startTime)} - {formatLocaleString(endTime)}
{formatLocaleString(startTime)} - {formatLocaleString(endTime)} ({duration})
</Typography>
</Box>

Expand Down
1 change: 1 addition & 0 deletions locust/webui/src/test/mocks/swarmState.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const swarmReportMock: IReport = {
showDownloadLink: true,
startTime: '2024-02-26 12:13:26',
endTime: '2024-02-26 12:13:26',
duration: '0 seconds',
host: 'http://0.0.0.0:8089/',
exceptionsStatistics: [],
requestsStatistics: [],
Expand Down
1 change: 1 addition & 0 deletions locust/webui/src/types/swarm.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export interface IReport {
showDownloadLink: boolean;
startTime: string;
endTime: string;
duration: string;
host: string;
charts: ICharts;
requestsStatistics: ISwarmStat[];
Expand Down
Loading

0 comments on commit 9ece97a

Please sign in to comment.