tests: speed up unit tests (#1215)

Adds two configuration parameters that are passed to
generate_password_hash:

- PASSWORD_HASH_METHOD
- PASSWORD_HASH_SALT_LENGTH

The unit tests use high-speed low-security values and
gain 50% speed.
This commit is contained in:
Éloi Rivard 2023-08-13 00:04:06 +02:00 committed by GitHub
parent 0187932365
commit 857ca2d5b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 40 additions and 9 deletions

View file

@ -4,7 +4,7 @@ This document describes changes between each past release.
## 6.1.1 (unreleased) ## 6.1.1 (unreleased)
- Nothing changed yet. - Speed up unit tests (#1214)
## 6.1.0 (2023-07-29) ## 6.1.0 (2023-07-29)

View file

@ -188,3 +188,12 @@ project](https://pythonhosted.org/flask-mail/#configuring-flask-mail)
- **MAIL_USERNAME** : default **None** - **MAIL_USERNAME** : default **None**
- **MAIL_PASSWORD** : default **None** - **MAIL_PASSWORD** : default **None**
- **DEFAULT_MAIL_SENDER** : default **None** - **DEFAULT_MAIL_SENDER** : default **None**
## Configuring password hashes
The werkzeug [generate_password_hash](https://werkzeug.palletsprojects.com/utils/#werkzeug.security.generate_password_hash)
is used to create password hashes. By default the default werkzeug values
are used, however you can customize those values with:
- **PASSWORD_HASH_METHOD** : default **None**
- **PASSWORD_HASH_SALT_LENGTH** : default **None**

View file

@ -9,7 +9,7 @@ from flask_babel import lazy_gettext as _
from flask_wtf.file import FileAllowed, FileField, FileRequired from flask_wtf.file import FileAllowed, FileField, FileRequired
from flask_wtf.form import FlaskForm from flask_wtf.form import FlaskForm
from markupsafe import Markup from markupsafe import Markup
from werkzeug.security import check_password_hash, generate_password_hash from werkzeug.security import check_password_hash
from wtforms.fields import ( from wtforms.fields import (
BooleanField, BooleanField,
DateField, DateField,
@ -43,6 +43,7 @@ from ihatemoney.models import Bill, LoggingMode, Person, Project
from ihatemoney.utils import ( from ihatemoney.utils import (
em_surround, em_surround,
eval_arithmetic_expression, eval_arithmetic_expression,
generate_password_hash,
render_localized_currency, render_localized_currency,
slugify, slugify,
) )

View file

@ -7,11 +7,10 @@ import sys
import click import click
from flask.cli import FlaskGroup from flask.cli import FlaskGroup
from werkzeug.security import generate_password_hash
from ihatemoney.models import Project, db from ihatemoney.models import Project, db
from ihatemoney.run import create_app from ihatemoney.run import create_app
from ihatemoney.utils import create_jinja_env from ihatemoney.utils import create_jinja_env, generate_password_hash
@click.group(cls=FlaskGroup, create_app=create_app) @click.group(cls=FlaskGroup, create_app=create_app)

View file

@ -18,11 +18,10 @@ from sqlalchemy import orm
from sqlalchemy.sql import func from sqlalchemy.sql import func
from sqlalchemy_continuum import make_versioned, version_class from sqlalchemy_continuum import make_versioned, version_class
from sqlalchemy_continuum.plugins import FlaskPlugin from sqlalchemy_continuum.plugins import FlaskPlugin
from werkzeug.security import generate_password_hash
from ihatemoney.currency_convertor import CurrencyConverter from ihatemoney.currency_convertor import CurrencyConverter
from ihatemoney.monkeypath_continuum import PatchedTransactionFactory from ihatemoney.monkeypath_continuum import PatchedTransactionFactory
from ihatemoney.utils import get_members, same_bill from ihatemoney.utils import generate_password_hash, get_members, same_bill
from ihatemoney.versioning import ( from ihatemoney.versioning import (
ConditionalVersioningManager, ConditionalVersioningManager,
LoggingMode, LoggingMode,

View file

@ -7,12 +7,13 @@ from urllib.parse import urlparse, urlunparse
from flask import session, url_for from flask import session, url_for
from libfaketime import fake_time from libfaketime import fake_time
import pytest import pytest
from werkzeug.security import check_password_hash, generate_password_hash from werkzeug.security import check_password_hash
from ihatemoney import models from ihatemoney import models
from ihatemoney.currency_convertor import CurrencyConverter from ihatemoney.currency_convertor import CurrencyConverter
from ihatemoney.tests.common.help_functions import extract_link from ihatemoney.tests.common.help_functions import extract_link
from ihatemoney.tests.common.ihatemoney_testcase import IhatemoneyTestCase from ihatemoney.tests.common.ihatemoney_testcase import IhatemoneyTestCase
from ihatemoney.utils import generate_password_hash
from ihatemoney.versioning import LoggingMode from ihatemoney.versioning import LoggingMode
from ihatemoney.web import build_etag from ihatemoney.web import build_etag

View file

@ -2,11 +2,11 @@ import os
from unittest.mock import MagicMock from unittest.mock import MagicMock
from flask_testing import TestCase from flask_testing import TestCase
from werkzeug.security import generate_password_hash
from ihatemoney import models from ihatemoney import models
from ihatemoney.currency_convertor import CurrencyConverter from ihatemoney.currency_convertor import CurrencyConverter
from ihatemoney.run import create_app, db from ihatemoney.run import create_app, db
from ihatemoney.utils import generate_password_hash
class BaseTestCase(TestCase): class BaseTestCase(TestCase):
@ -15,6 +15,8 @@ class BaseTestCase(TestCase):
"TESTING_SQLALCHEMY_DATABASE_URI", "sqlite://" "TESTING_SQLALCHEMY_DATABASE_URI", "sqlite://"
) )
ENABLE_CAPTCHA = False ENABLE_CAPTCHA = False
PASSWORD_HASH_METHOD = "pbkdf2:sha1:1"
PASSWORD_HASH_SALT_LENGTH = 1
def create_app(self): def create_app(self):
# Pass the test object as a configuration. # Pass the test object as a configuration.

View file

@ -7,3 +7,6 @@ SQLACHEMY_ECHO = DEBUG
SECRET_KEY = "supersecret" SECRET_KEY = "supersecret"
MAIL_DEFAULT_SENDER = "Budget manager <admin@example.com>" MAIL_DEFAULT_SENDER = "Budget manager <admin@example.com>"
PASSWORD_HASH_METHOD = "pbkdf2:sha1:1"
PASSWORD_HASH_SALT_LENGTH = 1

View file

@ -7,3 +7,6 @@ SQLACHEMY_ECHO = DEBUG
SECRET_KEY = "lalatra" SECRET_KEY = "lalatra"
MAIL_DEFAULT_SENDER = "Budget manager <admin@example.com>" MAIL_DEFAULT_SENDER = "Budget manager <admin@example.com>"
PASSWORD_HASH_METHOD = "pbkdf2:sha1:1"
PASSWORD_HASH_SALT_LENGTH = 1

View file

@ -20,6 +20,7 @@ import jinja2
from markupsafe import Markup, escape from markupsafe import Markup, escape
from werkzeug.exceptions import HTTPException from werkzeug.exceptions import HTTPException
from werkzeug.routing import RoutingException from werkzeug.routing import RoutingException
from werkzeug.security import generate_password_hash as werkzeug_generate_password_hash
limiter = limiter = Limiter( limiter = limiter = Limiter(
current_app, current_app,
@ -448,3 +449,15 @@ def format_form_errors(form, prefix):
errors = f"<ul><li>{error_list}</li></ul>" errors = f"<ul><li>{error_list}</li></ul>"
# I18N: Form error with a list of errors # I18N: Form error with a list of errors
return Markup(_("{prefix}:<br />{errors}").format(prefix=prefix, errors=errors)) return Markup(_("{prefix}:<br />{errors}").format(prefix=prefix, errors=errors))
def generate_password_hash(*args, **kwargs):
if current_app.config.get("PASSWORD_HASH_METHOD"):
kwargs.setdefault("method", current_app.config["PASSWORD_HASH_METHOD"])
if current_app.config.get("PASSWORD_HASH_SALT_LENGTH"):
kwargs.setdefault(
"salt_length", current_app.config["PASSWORD_HASH_SALT_LENGTH"]
)
return werkzeug_generate_password_hash(*args, **kwargs)

View file

@ -36,7 +36,7 @@ import qrcode
import qrcode.image.svg import qrcode.image.svg
from sqlalchemy_continuum import Operation from sqlalchemy_continuum import Operation
from werkzeug.exceptions import NotFound from werkzeug.exceptions import NotFound
from werkzeug.security import check_password_hash, generate_password_hash from werkzeug.security import check_password_hash
from ihatemoney.currency_convertor import CurrencyConverter from ihatemoney.currency_convertor import CurrencyConverter
from ihatemoney.emails import send_creation_email from ihatemoney.emails import send_creation_email
@ -63,6 +63,7 @@ from ihatemoney.utils import (
csv2list_of_dicts, csv2list_of_dicts,
flash_email_error, flash_email_error,
format_form_errors, format_form_errors,
generate_password_hash,
limiter, limiter,
list_of_dicts2csv, list_of_dicts2csv,
list_of_dicts2json, list_of_dicts2json,