diff --git a/.github/workflows/run-tox-suite.yml b/.github/workflows/run-tox-suite.yml
index d85fee7..d0c046e 100644
--- a/.github/workflows/run-tox-suite.yml
+++ b/.github/workflows/run-tox-suite.yml
@@ -1,5 +1,5 @@
name: Run Tox Suite
-on: [push, pull_request]
+on: [push, pull_request, workflow_dispatch]
jobs:
py310:
runs-on: ubuntu-latest
diff --git a/biweeklybudget/tests/acceptance/test_plaidlink.py b/biweeklybudget/tests/acceptance/test_plaidlink.py
index 7bcaa3f..efbcaa8 100644
--- a/biweeklybudget/tests/acceptance/test_plaidlink.py
+++ b/biweeklybudget/tests/acceptance/test_plaidlink.py
@@ -133,7 +133,7 @@ def test_03_do_simple_link(self, base_url, selenium):
sb.send_keys('First Platypus')
# click on First Platypus Bank
WebDriverWait(selenium, 10).until(
- EC.element_to_be_clickable((By.ID, 'aut-First Platypus Bank'))
+ EC.element_to_be_clickable((By.ID, 'aut-ins_109508'))
).click()
# click on the non-OAuth institution
WebDriverWait(selenium, 10).until(
diff --git a/biweeklybudget/tests/docker_build.py b/biweeklybudget/tests/docker_build.py
index 0321acf..0730459 100755
--- a/biweeklybudget/tests/docker_build.py
+++ b/biweeklybudget/tests/docker_build.py
@@ -486,15 +486,14 @@ def _test_scripts(self, container):
]
for cmd_info in test_cmds:
logger.debug('Running: %s', cmd_info['cmd'])
- res = container.exec_run(cmd_info['cmd']).decode().strip()
- logger.debug('Command output:\n%s', res)
- if 'output' in cmd_info:
- if cmd_info['output'] not in res:
- raise RuntimeError(
- 'Expected %s output to include "%s" but it did not' % (
- cmd_info['cmd'], cmd_info['output']
- )
+ ecode, res = container.exec_run(cmd_info['cmd'])
+ logger.debug('Command exited %d; output:\n%s', ecode, res)
+ if 'output' in cmd_info and cmd_info['output'] not in res.decode():
+ raise RuntimeError(
+ 'Expected %s output to include "%s" but it did not' % (
+ cmd_info['cmd'], cmd_info['output']
)
+ )
logger.info('script tests SUCCEEDED')
def _run_mysql(self):
@@ -527,11 +526,12 @@ def _run_mysql(self):
while count < 10:
count += 1
logger.info('Creating database...')
- cmd = '/usr/bin/mysql -uroot -proot -e "CREATE DATABASE budgetfoo;"'
+ cmd = ('/usr/bin/mysql -uroot -proot -h 127.0.0.1 '
+ '-e "CREATE DATABASE budgetfoo;"')
logger.debug('Running: %s', cmd)
- res = cont.exec_run(cmd)
- logger.debug('Command output:\n%s', res)
- if 'ERROR' not in res.decode():
+ ecode, res = cont.exec_run(cmd)
+ logger.debug('Command exited %d; output:\n%s', ecode, res)
+ if 'ERROR' not in res.decode() and ecode == 0:
logger.info('Database creation appears successful.')
break
logger.warning('Database creation errored; sleep 5s and retry')
@@ -555,17 +555,15 @@ def _build_image(self, tag):
'quiet': False,
'nocache': True,
'rm': True,
- 'stream': True,
'pull': True,
'dockerfile': '/Dockerfile',
'buildargs': {'version': tag},
'decode': True
}
logger.info('Running docker build with args: %s', kwargs)
- res = self._docker.api.build(**kwargs)
logger.info('Build running; output:')
error = None
- for line in res:
+ for line in self._docker.api.build(**kwargs):
if 'errorDetail' in line:
error = line['errorDetail']
try:
diff --git a/docs/source/flask_app.rst b/docs/source/flask_app.rst
index 1d4bd1a..4891dc9 100644
--- a/docs/source/flask_app.rst
+++ b/docs/source/flask_app.rst
@@ -9,7 +9,7 @@ Running Flask Development Server
Flask comes bundled with a builtin development server for fast local development and testing.
This is an easy way to take biweeklybudget for a spin, but carries some important and critical
warnings if you use it with real data. For upstream documentation, see the
-`Flask Development Server docs `_. Please note that
+`Flask Development Server docs `_. Please note that
the development server is a single process and defaults to single-threaded, and is only realistically
usable by one user.
diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst
index 7e3dbff..8a33e24 100644
--- a/docs/source/getting_started.rst
+++ b/docs/source/getting_started.rst
@@ -198,29 +198,29 @@ Host-Local MySQL Example
++++++++++++++++++++++++
It is also possible to use a MySQL server on the physical (Docker) host system. To do so,
-you'll need to know the host system's IP address. On Linux when using the default "bridge"
-Docker networking mode, this will coorespond to a ``docker0`` interface on the host system.
-The Docker documentation on `adding entries to the Container's hosts file `_
-provides a helpful snippet for this (on my systems, this results in ``172.17.0.1``):
-
-.. code-block:: none
-
- ip -4 addr show scope global dev docker0 | grep inet | awk '{print $2}' | cut -d / -f 1
-
-In our ``biweeklybudget.env``, we would specify the database connection string that uses the "dockerhost" hosts file entry, created by the ``--add-host`` option:
+you'll need to know the host system's IP address (as seen from the container). On Linux when
+using the default "bridge" Docker networking mode, this will coorespond to the container's
+gateway (the gateway of the Docker network that the container is in) and will usually be
+``172.x.0.1``. Using the special ``host-gateway`` option available in the
+`docker run command --add-host option `_,
+we can add ``--add-host=host.docker.internal:host-gateway`` to our ``docker run`` command and
+then use that as the hostname in the DB connection string:
.. code-block:: none
# "dockerhost" is added to /etc/hosts via the `--add-host` docker run option
- DB_CONNSTRING=mysql+pymysql://USERNAME:PASSWORD@dockerhost:3306/DBNAME?charset=utf8mb4
+ DB_CONNSTRING=mysql+pymysql://USERNAME:PASSWORD@host.docker.internal:3306/DBNAME?charset=utf8mb4
So using that, we could run biweeklybudget listening on port 8080 and using our host's MySQL server (on port 3306):
.. code-block:: none
- docker run --name biweeklybudget --env-file biweeklybudget.env \
- --add-host="dockerhost:$(ip -4 addr show scope global dev docker0 | grep inet | awk '{print $2}' | cut -d / -f 1)" \
- -p 8080:80 jantman/biweeklybudget:latest
+ docker run \
+ --name biweeklybudget \
+ --env-file biweeklybudget.env \
+ --add-host="host.docker.internal:host-gateway" \
+ -p 8080:80 \
+ jantman/biweeklybudget:latest
You may need to adjust those commands depending on your operating system, Docker networking mode, and MySQL server.
@@ -236,7 +236,7 @@ Settings Module Example
If you need to provide biweeklybudget with more complicated configuration, this is
still possible via a Python settings module. The easiest way to inject one into the
-Docker image is to `mount `_
+Docker image is to `mount `_
a python module directly into the biweeklybudget package directory. Assuming you have
a custom settings module on your local machine at ``/opt/biweeklybudget-settings.py``, you would
run the container as shown below to mount the custom settings module into the container and use it.
@@ -252,7 +252,7 @@ MySQL running on the Docker host:
Note on Locales
+++++++++++++++
-biweeklybudget uses Python's `locale `_ module
+biweeklybudget uses Python's `locale `_ module
to format currency. This requires an appropriate locale installed on the system. The docker image
distributed for this package only includes the ``en_US.UTF-8`` locale. If you need a different one,
please cut a pull request against ``docker_build.py``.
diff --git a/requirements.txt b/requirements.txt
index 8cf73c0..94ec13f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -34,7 +34,7 @@ python-dateutil==2.8.1
python-editor==1.0.4
pytz
requests
-selenium==3.141.0
+selenium==4.2.0
six==1.14.0
versionfinder>=1.0.0
wishlist==0.2.2
diff --git a/tox.ini b/tox.ini
index e788b7b..c38e50d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -52,6 +52,7 @@ setenv =
PLAID_COUNTRY_CODES=US
deps =
-r{toxinidir}/requirements.txt
+ alabaster==0.7.12
docutils==0.16
pygments==2.6.1
sphinx==1.5.5
@@ -108,7 +109,7 @@ commands =
[testenv:docker]
deps =
-r{toxinidir}/requirements.txt
- docker==2.2.1
+ docker>=7.0.0,<8.0.0
passenv = {[testenv]passenv},DOCKER_TEST_TAG,DOCKER_BUILD_VER,TEST_DOCKER,GITHUB_OUTPUT
setenv = {[testenv]setenv}
basepython = python3.10
@@ -134,7 +135,8 @@ deps =
mock
freezegun
pytest-flask==1.0.0
- pytest-selenium
+ selenium==4.2.0
+ pytest-selenium==4.0.0
pytest-timeout
alembic-verify
retrying
@@ -162,7 +164,8 @@ deps =
mock
freezegun
pytest-flask==1.0.0
- pytest-selenium
+ selenium==4.2.0
+ pytest-selenium==4.0.0
pytest-timeout
alembic-verify
retrying