From b67f157e856b69577c99437d8bc09c9509262ce5 Mon Sep 17 00:00:00 2001 From: alfredeen Date: Thu, 1 Feb 2024 14:00:12 +0100 Subject: [PATCH] Reformatted and code changes for the mypy type checker. --- pyproject.toml | 53 ++++++++++++ source/tests-dev/appviewer_requestshtml.py | 12 +-- source/tests-dev/authenticated.py | 22 ++--- source/tests-dev/register_user_account.py | 14 ++- source/tests/base_user_types.py | 99 +++++++--------------- source/tests/test_plan_classroom.py | 8 +- source/tests/test_plan_normal.py | 8 +- source/tests/test_verify_setup.py | 2 +- 8 files changed, 113 insertions(+), 105 deletions(-) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..8170592 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,53 @@ +# This file contains project information. +# It also contains settings for linters and code checkers isort, black and mypy. +# Note that these settings are not respected with pre-commit run --all-files +# In that case add configurations to the .pre-commit-config.yaml file. + +[project] +name = "serve-load-testing" +version = "1.0.0" +description = "Load testing of the SciLifeLab Serve platform." +requires-python = "=3.8" +keywords = ["load testing", "locust", "python"] + +[tool.isort] +profile = 'black' + +[tool.black] +line-length = 120 +target-version = ['py38'] +include = '\.pyi?$' +extend-exclude = ''' +/( + \.git + | \.mypy_cache + | \.venv + | venv + | migrations +)/ +''' + +[tool.mypy] +strict = false +python_version = "3.8" +ignore_missing_imports = true +warn_return_any = true +exclude = ["venv", ".venv", "examples"] + +[[tool.mypy.overrides]] +module = "*.migrations.*" +ignore_errors = true + +[[tool.mypy.overrides]] +module = [ + "flatten_json.*", + "guardian.*", + "tagulous.*", + "dash.*", + "markdown.*", + "pytz.*", + "requests.*", + "setuptools.*", + "yaml.*", + ] +ignore_missing_imports = true diff --git a/source/tests-dev/appviewer_requestshtml.py b/source/tests-dev/appviewer_requestshtml.py index caa2f24..05d20dd 100644 --- a/source/tests-dev/appviewer_requestshtml.py +++ b/source/tests-dev/appviewer_requestshtml.py @@ -48,9 +48,7 @@ def apps_runner(n_requests: int = 1): """ if n_requests > MAX_APPS_PER_APP_TYPE_LIMIT: - raise Exception( - f"Too many instances of user apps requested to be opened. Max = {MAX_APPS_PER_APP_TYPE_LIMIT}" - ) + raise Exception(f"Too many instances of user apps requested to be opened. Max = {MAX_APPS_PER_APP_TYPE_LIMIT}") start_time = time() n_fails = 0 @@ -64,9 +62,7 @@ def apps_runner(n_requests: int = 1): print(f"Iteration: {i}") try: response = open_user_app_sync(url) - print( - f"DEBUG: open_user_app_sync response = {response.status_code}, {response.reason}" - ) + print(f"DEBUG: open_user_app_sync response = {response.status_code}, {response.reason}") # print(response.content) except Exception as ex: n_fails += 1 @@ -77,9 +73,7 @@ def apps_runner(n_requests: int = 1): sleep(DELAY_BETWEEN_USER_APP_TYPES_SECONDS) duration_s = time() - start_time - print( - f"Duration (sec) for opening {n_requests} user apps = {duration_s}. Nr failures = {n_fails}" - ) + print(f"Duration (sec) for opening {n_requests} user apps = {duration_s}. Nr failures = {n_fails}") def open_user_app_sync(url: str): diff --git a/source/tests-dev/authenticated.py b/source/tests-dev/authenticated.py index f67f07a..d91fdd4 100644 --- a/source/tests-dev/authenticated.py +++ b/source/tests-dev/authenticated.py @@ -35,9 +35,7 @@ def get_token(self): def login(self): print(f"DEBUG: Login as user {username}") - login_data = dict( - username=username, password=password, csrfmiddlewaretoken=self.csrftoken - ) + login_data = dict(username=username, password=password, csrfmiddlewaretoken=self.csrftoken) with self.client.post( url="/accounts/login/", @@ -46,21 +44,17 @@ def login(self): name="---ON START---LOGIN", catch_response=True, ) as response: - print( - f"DEBUG: login response.status_code = {response.status_code}, {response.reason}" - ) + print(f"DEBUG: login response.status_code = {response.status_code}, {response.reason}") # if login succeeds then url = /accounts/login/, else /projects/ print(f"DEBUG: login response.url = {response.url}") if "/projects" in response.url: self.is_authenticated = True else: - response.failure( - f"Login as user {username} failed. Response URL does not contain /projects" - ) + response.failure(f"Login as user {username} failed. Response URL does not contain /projects") def logout(self): print(f"DEBUG: Log out user {username}") - logout_data = dict(username=username, csrfmiddlewaretoken=self.csrftoken) + # logout_data = dict(username=username, csrfmiddlewaretoken=self.csrftoken) self.client.get("/accounts/logout/", name="---ON STOP---LOGOUT") @task @@ -75,9 +69,7 @@ def browse_protected_page(self): request_data = dict(username=username, csrfmiddlewaretoken=self.csrftoken) - response = self.client.get( - page_rel_url, data=request_data, headers={"Referer": "foo"}, verify=False - ) + response = self.client.get(page_rel_url, data=request_data, headers={"Referer": "foo"}, verify=False) with self.client.get( page_rel_url, @@ -86,9 +78,7 @@ def browse_protected_page(self): verify=False, catch_response=True, ) as response: - print( - f"DEBUG: protected page response.status_code = {response.status_code}, {response.reason}" - ) + print(f"DEBUG: protected page response.status_code = {response.status_code}, {response.reason}") # if login succeeds then url = ?, else ? print(f"DEBUG: protected page {response.url=}") if page_rel_url not in response.url: diff --git a/source/tests-dev/register_user_account.py b/source/tests-dev/register_user_account.py index f45e2c9..3586324 100644 --- a/source/tests-dev/register_user_account.py +++ b/source/tests-dev/register_user_account.py @@ -14,12 +14,13 @@ class VisitingBaseUser(HttpUser): # abstract = True - user_type = None + user_type = "" user_individual_id = 0 local_individual_id = 0 user_has_registered = False - def get_user_id(): + @classmethod + def get_user_id(cls): """Increments the class property user_individual_id. Used to assign a unique id to each individual of this user type. """ @@ -30,9 +31,8 @@ def on_start(self): """Called when a User starts running.""" self.client.verify = False # Don't check if certificate is valid self.local_individual_id = VisitingBaseUser.get_user_id() - print( - f"ONSTART new user type {self.user_type}, individual {self.local_individual_id}" - ) + print(f"ONSTART new user type {self.user_type}, individual {self.local_individual_id}") + self.email = "UNSET" # Tasks @@ -72,9 +72,7 @@ def register_user(self): name="---REGISTER-NEW-USER-ACCOUNT", catch_response=True, ) as response: - print( - f"DEBUG: signup response.status_code = {response.status_code}, {response.reason}" - ) + print(f"DEBUG: signup response.status_code = {response.status_code}, {response.reason}") # if login succeeds then url = /accounts/login/ print(f"DEBUG: signup response.url = {response.url}") if "/accounts/login" in response.url: diff --git a/source/tests/base_user_types.py b/source/tests/base_user_types.py index 4378465..9ccb1eb 100644 --- a/source/tests/base_user_types.py +++ b/source/tests/base_user_types.py @@ -7,9 +7,7 @@ SERVE_LOCUST_TEST_USER_PASS = os.environ.get("SERVE_LOCUST_TEST_USER_PASS") -SERVE_LOCUST_DO_CREATE_OBJECTS = os.environ.get( - "SERVE_LOCUST_DO_CREATE_OBJECTS", "False" -) +SERVE_LOCUST_DO_CREATE_OBJECTS = os.environ.get("SERVE_LOCUST_DO_CREATE_OBJECTS", "False") class VisitingBaseUser(HttpUser): @@ -21,12 +19,13 @@ class VisitingBaseUser(HttpUser): abstract = True - user_type = None + user_type = "" user_individual_id = 0 local_individual_id = 0 user_has_registered = False - def get_user_id(): + @classmethod + def get_user_id(cls) -> int: """Increments the class property user_individual_id. Used to assign a unique id to each individual of this user type. """ @@ -37,9 +36,7 @@ def on_start(self): """Called when a User starts running.""" self.client.verify = False # Don't check if certificate is valid self.local_individual_id = VisitingBaseUser.get_user_id() - print( - f"ONSTART new user type {self.user_type}, individual {self.local_individual_id}" - ) + print(f"ONSTART new user type {self.user_type}, individual {self.local_individual_id}") # Tasks @@ -66,13 +63,8 @@ def browse_user_guide(self): @task def register_user(self): """Register this user as a new user account.""" - if ( - SERVE_LOCUST_DO_CREATE_OBJECTS is False - or SERVE_LOCUST_DO_CREATE_OBJECTS == "False" - ): - print( - "Skipping register new user because env var SERVE_LOCUST_DO_CREATE_OBJECTS == False" - ) + if SERVE_LOCUST_DO_CREATE_OBJECTS is False or SERVE_LOCUST_DO_CREATE_OBJECTS == "False": + print("Skipping register new user because env var SERVE_LOCUST_DO_CREATE_OBJECTS == False") return if self.user_has_registered is False: @@ -104,9 +96,7 @@ def register_user(self): name="---REGISTER-NEW-USER-ACCOUNT", catch_response=True, ) as response: - print( - f"DEBUG: signup response.status_code = {response.status_code}, {response.reason}" - ) + print(f"DEBUG: signup response.status_code = {response.status_code}, {response.reason}") # if login succeeds then url = /accounts/login/ print(f"DEBUG: signup response.url = {response.url}") if "/accounts/login" in response.url: @@ -130,7 +120,7 @@ class PowerBaseUser(HttpUser): abstract = True - user_type = None + user_type = "" user_individual_id = 0 local_individual_id = 0 @@ -142,7 +132,8 @@ class PowerBaseUser(HttpUser): is_authenticated = False task_has_run = False - def get_user_id(): + @classmethod + def get_user_id(cls) -> int: """Increments the class property user_individual_id. Used to assign a unique id to each individual of this user type. """ @@ -153,9 +144,7 @@ def on_start(self): """Called when a User starts running.""" self.client.verify = False # Don't check if certificate is valid self.local_individual_id = PowerBaseUser.get_user_id() - print( - f"ONSTART new user type {self.user_type}, individual {self.local_individual_id}" - ) + print(f"ONSTART new user type {self.user_type}, individual {self.local_individual_id}") # Use the pre-created test users for this: f"locust_test_user_{self.local_individual_id}@test.uu.net" self.username = f"locust_test_user_{self.local_individual_id}@test.uu.net" # self.username = "locust_test_persisted_user@test.uu.net" @@ -165,14 +154,12 @@ def on_start(self): @task def power_user_task(self): if self.task_has_run is True: - print( - f"Skipping power user task for user {self.local_individual_id}. It has already been run." - ) + print(f"Skipping power user task for user {self.local_individual_id}. It has already been run.") return self.task_has_run = True - print(f"executing power user task") + print("executing power user task") # Open the home page self.client.get("/home/") @@ -189,18 +176,14 @@ def power_user_task(self): # Open user docs pages self.client.get("/docs/") - if ( - SERVE_LOCUST_DO_CREATE_OBJECTS is False - or SERVE_LOCUST_DO_CREATE_OBJECTS == "False" - ): + if SERVE_LOCUST_DO_CREATE_OBJECTS is False or SERVE_LOCUST_DO_CREATE_OBJECTS == "False": print( - "Skipping task steps that create and delete projects and apps because env var SERVE_LOCUST_DO_CREATE_OBJECTS == False" + "Skipping tasks that create and delete projects and apps because env var \ + SERVE_LOCUST_DO_CREATE_OBJECTS == False" ) return else: - print( - f"DEBUG: Creating and deleting projects and apps as user {self.username}" - ) + print(f"DEBUG: Creating and deleting projects and apps as user {self.username}") # Create project: locust_test_project_new_ project_name = f"locust_test_project_new_{self.local_individual_id}" @@ -222,12 +205,12 @@ def power_user_task(self): # Logout the user self.logout() - def get_token(self, relative_url="/accounts/login/"): + def get_token(self, relative_url: str = "/accounts/login/"): self.client.get(relative_url) self.csrftoken = self.client.cookies["csrftoken"] print(f"DEBUG: self.csrftoken = {self.csrftoken}") - def create_project(self, project_name): + def create_project(self, project_name: str): # Update the csrf token self.get_token("/projects/create?template=Default project") @@ -245,9 +228,7 @@ def create_project(self, project_name): name="---CREATE-NEW-PROJECT", catch_response=True, ) as response: - print( - f"DEBUG: create project response.status_code = {response.status_code}, {response.reason}" - ) + print(f"DEBUG: create project response.status_code = {response.status_code}, {response.reason}") # if succeeds then url = // print(f"DEBUG: create project response.url = {response.url}") if self.username in response.url and project_name in response.url: @@ -255,9 +236,7 @@ def create_project(self, project_name): self.project_url = response.url else: print(response.content) - response.failure( - f"Create project failed. Response URL does not contain username and project name." - ) + response.failure("Create project failed. Response URL does not contain username and project name.") def delete_project(self): # Update the csrf token @@ -275,18 +254,14 @@ def delete_project(self): name="---DELETE-PROJECT", catch_response=True, ) as response: - print( - f"DEBUG: delete project response.status_code = {response.status_code}, {response.reason}" - ) + print(f"DEBUG: delete project response.status_code = {response.status_code}, {response.reason}") # if succeeds then url = /projects/ print(f"DEBUG: delete project response.url = {response.url}") if "/projects" in response.url: print(f"Successfully deleted project at {self.project_url}") else: print(response.content) - response.failure( - f"Delete project failed. Response URL does not contain /projects." - ) + response.failure("Delete project failed. Response URL does not contain /projects.") def login(self): print(f"DEBUG: Login as user {self.username}") @@ -304,21 +279,17 @@ def login(self): name="---ON START---LOGIN", catch_response=True, ) as response: - print( - f"DEBUG: login response.status_code = {response.status_code}, {response.reason}" - ) + print(f"DEBUG: login response.status_code = {response.status_code}, {response.reason}") # if login succeeds then url = /accounts/login/, else /projects/ print(f"DEBUG: login response.url = {response.url}") if "/projects" in response.url: self.is_authenticated = True else: - response.failure( - f"Login as user {self.username} failed. Response URL does not contain /projects" - ) + response.failure(f"Login as user {self.username} failed. Response URL does not contain /projects") def logout(self): print(f"DEBUG: Login out user {self.username}") - logout_data = dict(username=self.username, csrfmiddlewaretoken=self.csrftoken) + # logout_data = dict(username=self.username, csrfmiddlewaretoken=self.csrftoken) self.client.get("/accounts/logout/", name="---ON STOP---LOGOUT") @@ -327,7 +298,7 @@ class AppViewerUser(HttpUser): abstract = True - user_type = None + user_type = "" def on_start(self): """Called when a User starts running.""" @@ -344,24 +315,18 @@ def open_user_app(self): # Dev # ex: https://loadtest-shinyproxy.staging.serve-dev.scilifelab.se/app/loadtest-shinyproxy # from host: https://staging.serve-dev.scilifelab.se - APP_SHINYPROXY = self.host.replace( - "https://", "https://loadtest-shinyproxy." - ) + APP_SHINYPROXY = self.host.replace("https://", "https://loadtest-shinyproxy.") APP_SHINYPROXY += "/app/loadtest-shinyproxy" elif "staging" in self.host: # Staging # ex: https://loadtest-shinyproxy2.staging.serve-dev.scilifelab.se/app/loadtest-shinyproxy2 # from host: https://staging.serve-dev.scilifelab.se - APP_SHINYPROXY = self.host.replace( - "https://", "https://loadtest-shinyproxy2." - ) + APP_SHINYPROXY = self.host.replace("https://", "https://loadtest-shinyproxy2.") APP_SHINYPROXY += "/app/loadtest-shinyproxy2" elif "serve.scilifelab.se" in self.host: # Production # ex: https://adhd-medication-sweden.serve.scilifelab.se/app/adhd-medication-sweden - APP_SHINYPROXY = self.host.replace( - "https://", "https://adhd-medication-sweden." - ) + APP_SHINYPROXY = self.host.replace("https://", "https://adhd-medication-sweden.") APP_SHINYPROXY += "/app/adhd-medication-sweden" print(f"making GET request to URL: {APP_SHINYPROXY}") @@ -373,7 +338,7 @@ class OpenAPIClientBaseUser(HttpUser): abstract = True - user_type = None + user_type = "" def on_start(self): self.client.verify = False # Don't check if certificate is valid diff --git a/source/tests/test_plan_classroom.py b/source/tests/test_plan_classroom.py index eadfc3f..17b2aa0 100644 --- a/source/tests/test_plan_classroom.py +++ b/source/tests/test_plan_classroom.py @@ -1,7 +1,11 @@ """Locust test file defining the test plan scenario for the classroom load.""" -from base_user_types import (AppViewerUser, OpenAPIClientBaseUser, - PowerBaseUser, VisitingBaseUser) +from base_user_types import ( + AppViewerUser, + OpenAPIClientBaseUser, + PowerBaseUser, + VisitingBaseUser, +) from locust import between diff --git a/source/tests/test_plan_normal.py b/source/tests/test_plan_normal.py index 6f7d653..de2b699 100644 --- a/source/tests/test_plan_normal.py +++ b/source/tests/test_plan_normal.py @@ -1,7 +1,11 @@ """Locust test file defining the test plan scenario for normal load.""" -from base_user_types import (AppViewerUser, OpenAPIClientBaseUser, - PowerBaseUser, VisitingBaseUser) +from base_user_types import ( + AppViewerUser, + OpenAPIClientBaseUser, + PowerBaseUser, + VisitingBaseUser, +) from locust import between diff --git a/source/tests/test_verify_setup.py b/source/tests/test_verify_setup.py index 40e07f2..4a664ab 100644 --- a/source/tests/test_verify_setup.py +++ b/source/tests/test_verify_setup.py @@ -17,4 +17,4 @@ def on_start(self): @task def verify_task(self): - print(f"executing simple task verify_task") + print("executing simple task verify_task")