Development
To set up a development environment for the API and app, make sure you have a relatively recent version of Docker and Make on your development machine (and that you’ve added your daily user to the docker
group). For the agent, make sure you have pyenv with all the current versions of Python installed.
API
Clone the official Git repository at https://git.sr.ht/~arx10/procustodibus-api. All the development scripts assume that you will run the database and API via the dev docker-compose.yml
file in a custom Docker network named custos
(using the 10.242.4.0/24
address block).
Init
In your local procustodibus-api/
directory, run the make init
command to start up the database and build the dev Docker image:
$ make init TODO
The dev Docker container builds the necessary version of Erlang and Elixir from scratch (it will take 10+ minutes to complete). All the other Make tasks run in this dev Docker container.
Once this command has completed, run the following command to generate a random application-level encryption key:
$ openssl rand -base64 32 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
Copy the random key, open up the .env
file (generated by the make init
command), and paste it in as the value for the DB_ALEK_1
environment variable:
# .env
DB_ALEK_1="value:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
Test
To run the full linting and test suite, run the make check
command (which will take a minute or two to complete):
$ make check docker-compose run api mix format --check-formatted Creating api_api_run ... done docker-compose run api mix compile --all-warnings --warnings-as-errors Creating api_api_run ... done docker-compose run api mix credo --strict Creating api_api_run ... done Checking 365 source files (this might take a while) ... Please report incorrect results: https://github.com/rrrene/credo/issues Analysis took 17.1 seconds (2.5s to load, 14.6s running 67 checks on 365 files) 3756 mods/funs, found no issues. Use `mix credo explain` to explain issues, `mix credo --help` for options. docker-compose run api mix sobelow --config Creating api_api_run ... done Checking Sobelow version... A new version of Sobelow is available: mix archive.install hex sobelow ############################################## # # # Running Sobelow - v0.12.2 # # Created by Griffin Byatt - @griffinbyatt # # NCC Group - https://nccgroup.trust # # # ############################################## Config.HTTPS: HTTPS Not Enabled - High Confidence HTTPS configuration details could not be found in `prod.exs`. ----------------------------------------------- ... SCAN COMPLETE ... docker-compose run api mix test Creating api_api_run ... done Excluding tags: [:aws] .......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... Finished in 43.9 seconds (23.3s async, 20.6s sync) 58 doctests, 3570 tests, 0 failures, 2 excluded Randomized with seed 450375
Watch
To run a specific unit test file every time you make a change to the source code, run the make watch
command, specifying the unit test file to run with the TEST
option:
$ make watch TEST=test/api_web/controllers/page_controller_test.exs docker-compose run shell mix test.watch test/api_web/controllers/page_controller_test.exs Creating api_shell_run ... done Running tests... Compiling 16 files (.ex) Generated api app Excluding tags: [:aws] 1) test index GET / (ApiWeb.PageControllerTest) test/api_web/controllers/page_controller_test.exs:5 Assertion with == failed code: assert conn |> get(~p"/") |> json_response(200) == %{} left: %{"foo" => "bar"} right: %{} stacktrace: test/api_web/controllers/page_controller_test.exs:6: (test) . Finished in 0.09 seconds (0.00s async, 0.09s sync) 2 tests, 1 failure Randomized with seed 498117
Server
The make dev
command will run the API server, with an interactive IEx shell running in your current terminal:
$ make dev docker-compose run --use-aliases api iex -S mix phx.server Creating api_api_run ... done 00:07:41.582 application=swoosh mfa=Swoosh.Application.runtime_children/2 [info] Running Swoosh mailbox preview server with Cowboy using http on port 4001 00:07:41.999 application=phoenix mfa=Phoenix.Endpoint.Cowboy2Adapter.start_link/3 [info] Running ApiWeb.Endpoint with cowboy 2.10.0 at 0.0.0.0:4000 (http) 00:07:42.010 application=phoenix mfa=Phoenix.Endpoint.Supervisor.log_access_url/2 [info] Access ApiWeb.Endpoint at http://10.242.4.242:4000 00:07:42.061 application=ecto_sql mfa=Ecto.Adapters.SQL.log/4 [debug] QUERY OK db=2.7ms decode=2.6ms queue=1.1ms idle=57.2ms INSERT INTO "system_recurring_tasks" ("name","node") VALUES ($1,$2) ON CONFLICT DO NOTHING RETURNING "id" ["alert_endpoint_stats", ""] 00:07:42.072 application=ecto_sql mfa=Ecto.Adapters.SQL.log/4 [debug] QUERY OK db=1.2ms queue=1.3ms idle=78.0ms INSERT INTO "system_recurring_tasks" ("name","node") VALUES ($1,$2) ON CONFLICT DO NOTHING RETURNING "id" ["alert_log_authn", ""] 00:07:42.076 application=ecto_sql mfa=Ecto.Adapters.SQL.log/4 [debug] QUERY OK db=1.5ms queue=1.2ms idle=80.8ms INSERT INTO "system_recurring_tasks" ("name","node") VALUES ($1,$2) ON CONFLICT DO NOTHING RETURNING "id" ["alert_log_authz", ""] 00:07:42.080 application=ecto_sql mfa=Ecto.Adapters.SQL.log/4 [debug] QUERY OK db=2.0ms queue=2.0ms idle=84.3ms INSERT INTO "system_recurring_tasks" ("name","node") VALUES ($1,$2) ON CONFLICT DO NOTHING RETURNING "id" ["alert_log_changes", ""] 00:07:42.086 application=ecto_sql mfa=Ecto.Adapters.SQL.log/4 [debug] QUERY OK db=2.1ms queue=2.5ms idle=89.1ms INSERT INTO "system_recurring_tasks" ("name","node") VALUES ($1,$2) ON CONFLICT DO NOTHING RETURNING "id" ["cache_geoip_uses", ""] 00:07:42.089 application=ecto_sql mfa=Ecto.Adapters.SQL.log/4 [debug] QUERY OK db=1.0ms queue=1.2ms idle=94.2ms INSERT INTO "system_recurring_tasks" ("name","node") VALUES ($1,$2) ON CONFLICT DO NOTHING RETURNING "id" ["post_alerts_hook", ""] 00:07:42.091 application=ecto_sql mfa=Ecto.Adapters.SQL.log/4 [debug] QUERY OK db=1.1ms queue=1.1ms idle=96.7ms INSERT INTO "system_recurring_tasks" ("name","node") VALUES ($1,$2) ON CONFLICT DO NOTHING RETURNING "id" ["post_log_authn_hook", ""] 00:07:42.094 application=ecto_sql mfa=Ecto.Adapters.SQL.log/4 [debug] QUERY OK db=1.5ms queue=1.1ms idle=99.3ms INSERT INTO "system_recurring_tasks" ("name","node") VALUES ($1,$2) ON CONFLICT DO NOTHING RETURNING "id" ["post_log_changes_hook", ""] 00:07:42.098 application=ecto_sql mfa=Ecto.Adapters.SQL.log/4 [debug] QUERY OK db=1.7ms queue=1.8ms idle=102.3ms INSERT INTO "system_recurring_tasks" ("name","node") VALUES ($1,$2) ON CONFLICT DO NOTHING RETURNING "id" ["post_endpoint_stats_hook", ""] 00:07:42.101 application=ecto_sql mfa=Ecto.Adapters.SQL.log/4 [debug] QUERY OK db=1.1ms queue=1.6ms idle=104.6ms INSERT INTO "system_recurring_tasks" ("name","node") VALUES ($1,$2) ON CONFLICT DO NOTHING RETURNING "id" ["check_hung_ldap_polls", ""] 00:07:42.102 application=ecto_sql mfa=Ecto.Adapters.SQL.log/4 [debug] QUERY OK db=0.4ms idle=48.6ms INSERT INTO "system_recurring_tasks" ("name","node") VALUES ($1,$2) ON CONFLICT DO NOTHING RETURNING "id" ["rotate_preshared_keys", ""] 00:07:42.103 application=ecto_sql mfa=Ecto.Adapters.SQL.log/4 [debug] QUERY OK db=0.3ms idle=29.6ms INSERT INTO "system_recurring_tasks" ("name","node") VALUES ($1,$2) ON CONFLICT DO NOTHING RETURNING "id" ["update_sessions_last_used", ""] Erlang/OTP 26 [erts-14.0.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit:ns] Interactive Elixir (1.15.4) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> Users.get_user!(1) |> Map.get(:name) "System User" iex(2)>
In a different terminal, run the following command to try sending a request to the API:
$ curl -w'\n' http://10.242.4.242:4000/health [ { "error": null, "healthy": true, "name": "DB", "time": 4581 } ]
If you make changes to the API source code, it will for the most part reload automatically the next time you make a web request. For example, open up the lib/api_web/controllers/page_controller.ex
file, and change its index/2
function to return some dummy JSON value:
# lib/api_web/controllers/page_controller.ex
defmodule ApiWeb.PageController do
use ApiWeb, :controller
def index(conn, _params) do
conn
|> cache_control("public, max-age=3600")
# change this line to return some dummy value like %{foo: "bar"}:
|> json(%{foo: "bar"})
end
# ...
end
cURL the controller action you just changed to view the results of your change:
$ curl -w'\n' http://10.242.4.242:4000/ {"foo":"bar"}
Shell
To run arbitrary Mix tasks (such as mix format
), start a shell for the dev Docker image with the make shell
command:
$ make shell docker-compose run shell /bin/bash Creating api_shell_run ... done jose@dd383b95cd32:/srv/api$ mix format jose@dd383b95cd32:/srv/api$
Database
To run arbitrary SQL queries in the database, start a shell for the database with the make shell.db
command:
$ make shell.db docker-compose up -d db Creating network "custos" with the default driver Creating api_db_1 ... done docker exec -u postgres -it api_db_1 psql psql (13.11) Type "help" for help. postgres=#
Run the \c custos
command to switch to the dev database; then you can run SQL queries on the dev data:
postgres=# \c custos You are now connected to database "custos" as user "postgres". custos=# select * from users; id | pub_id | active | name | org_id | inserted_at | updated_at | type | locked ----+---------------------+--------+-------------+--------+------------------------+------------------------+-------+-------- 1 | 6620344162125037829 | t | System User | 1 | 2020-01-01 00:00:00+00 | 2020-01-01 00:00:00+00 | admin | f (1 row)
Directories
Here’s a quick tour of the directories in the API project:
-
assets
: static files served by the API (such asfavicon.ico
) -
bin
: miscellaneous shell scripts -
_build
: output of build scripts -
build
: build scripts -
config
: standard Elixir config directory -
ee
: Enterprise Edition code and tests -
lib
: standard Elixir code directory -
me
: your private scratch directory -
ops
: scripts run on deployed systems -
priv
: standard Elixir resources directory -
test
: standard Elixir tests directory
App
Clone the official Git repository at https://git.sr.ht/~arx10/procustodibus-app. All the development scripts assume that you will run the app via the dev docker-compose.yml
file in a custom Docker network named custos_app
(using the 10.242.5.0/28
address block).
Init
In your local procustodibus-app/
directory, run the make init
command to build the dev Docker image:
$ make init TODO
Test
To run the full linting and test suite, run the make check
command (which will take a minute or two to complete):
$ make check docker-compose run app npm run lint Creating app_app_run ... done > custos@1.0.0 lint > npm run lint-js && npm run lint-css && npm run format-check > custos@1.0.0 lint-js > eslint --ext .vue,.js,.jsx,.cjs,.mjs --report-unused-disable-directives --ignore-path .gitignore --cache --cache-location out/ . > custos@1.0.0 lint-css > stylelint "src/**/*.{css,less,sass,scss,sss,styl,vue}" --report-needless-disables --report-invalid-scope-disables --ignore-path .gitignore --cache --cache-location out/ > custos@1.0.0 format-check > prettier --check src/ tests/ Checking formatting... All matched files use Prettier code style! docker-compose run app npm run test Creating app_app_run ... done > custos@1.0.0 test > vitest run --coverage RUN v0.34.1 /srv/app Coverage enabled with v8 stderr | tests/unit/utils/text.spec.js > decodeBase64() > returns blank if not base64 encoded cannot decode as base64 utf-8: 12345 stderr | tests/unit/utils/text.spec.js > decodeBase64Url() > returns blank if not base64 encoded cannot decode as base64 utf-8: 12345 ✓ tests/unit/utils/background.spec.js (28) 6773ms ✓ tests/unit/utils/login.spec.js (34) ✓ tests/unit/utils/rdap.spec.js (10) 320ms ✓ tests/unit/utils/date.spec.js (73) ✓ tests/unit/utils/axios.spec.js (11) ✓ tests/unit/utils/text.spec.js (74) ✓ tests/unit/utils/model.spec.js (22) ✓ tests/unit/utils/env.spec.js (15) ✓ tests/unit/utils/session.spec.js (13) ✓ tests/unit/utils/timeline.spec.js (40) ✓ tests/unit/stores/user.spec.js (10) ✓ tests/unit/utils/download.spec.js (17) ✓ tests/unit/stores/mfa.spec.js (10) ✓ tests/unit/utils/misc.spec.js (26) ✓ tests/unit/utils/error.spec.js (5) ✓ tests/unit/utils/form.spec.js (8) ✓ tests/unit/utils/message.spec.js (6) ✓ tests/unit/utils/pageantry.spec.js (16) ✓ tests/unit/utils/storage.spec.js (4) Test Files 19 passed (19) Tests 422 passed (422) Start at 01:35:22 Duration 11.85s (transform 618ms, setup 4ms, collect 3.48s, tests 7.74s, environment 13.61s, prepare 2.65s) % Coverage report from v8 -----------------------|---------|----------|---------|---------|----------------------------------------------------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s -----------------------|---------|----------|---------|---------|----------------------------------------------------------------- All files | 95.37 | 91.33 | 95.23 | 95.37 | components/app | 100 | 100 | 100 | 100 | app-confirm-form.vue | 100 | 100 | 100 | 100 | app-message.vue | 100 | 100 | 100 | 100 | app-modal-form.vue | 100 | 100 | 100 | 100 | stores | 99.14 | 80.21 | 100 | 99.14 | features.js | 100 | 75 | 100 | 100 | 28 mfa.js | 100 | 100 | 100 | 100 | prefs.js | 83.33 | 66.66 | 100 | 83.33 | 8-10 session.js | 100 | 86.53 | 100 | 100 | 135-141,193-197 user.js | 100 | 52.63 | 100 | 100 | 34-36,39-40,45,49,57-58 utils | 94.68 | 92.74 | 94.47 | 94.68 | axios.js | 89.44 | 86.36 | 83.33 | 89.44 | 45-57,94-97,131-133,199-201 background.js | 95.45 | 96.96 | 100 | 95.45 | 14-21 date.js | 100 | 99.11 | 100 | 100 | 75 download.js | 97.19 | 94 | 92.85 | 97.19 | 16-21,157,159 env.js | 98.29 | 100 | 92.3 | 98.29 | 77-78 error.js | 80.21 | 56.09 | 88.88 | 80.21 | 102-123,133,137,139,141,143,145,149,163,165,167,169,172,183-185 form.js | 82.53 | 100 | 66.66 | 82.53 | 29-39 login.js | 98.84 | 91.8 | 100 | 98.84 | 232,234-235 message.js | 100 | 100 | 100 | 100 | misc.js | 100 | 100 | 100 | 100 | model.js | 80.45 | 83.33 | 91.66 | 80.45 | 40-73,83,85,87,89,91,93,95,97,99 pageantry.js | 100 | 100 | 100 | 100 | rdap.js | 100 | 95.45 | 100 | 100 | 15 storage.js | 100 | 83.33 | 100 | 100 | 19 text.js | 94.87 | 100 | 92.59 | 94.87 | 303-315,323-327 timeline.js | 100 | 91.25 | 100 | 100 | 78,159,217,233,236,272-273 -----------------------|---------|----------|---------|---------|-----------------------------------------------------------------
Watch
To run all the tests every time you make a change to the source code, run the make watch
command:
$ make watch ... Test Files 19 passed (19) Tests 422 passed (422) Start at 01:38:43 Duration 13.81s (transform 573ms, setup 3ms, collect 2.57s, tests 7.43s, environment 10.04s, prepare 1.95s) PASS Waiting for file changes... press h to show help, press q to quit
For the most part, only affected tests will re-run when you make a change.
Press h while this command is waiting to see several options for filtering the tests that are run.
|
Server
The make dev
command will run the dev Vite server, serving a dev build of the app UI:
$ make dev VITE v4.4.8 ready in 816 ms ➜ Local: http://localhost:5173/ ➜ Network: http://10.242.5.12:5173/ ➜ press h to show help
In a different terminal, run the following command to verify the dev server is up and running:
$ curl -sS http://10.242.5.12:5173/ | head <!DOCTYPE html> <html lang="en"> <head> <script type="module" src="/@vite/client"></script> <meta charset="UTF-8"> <link rel="icon" href="/favicon.ico"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Pro Custodibus</title> <link rel="apple-touch-icon" href="/img/icons/apple-touch-icon-180x180.png" sizes="180x180">
If you make changes to the app source code, it will for the most part reload automatically live in your web browser. For example, open up the src/components/nav/nav-header.vue
file, and change the name of the logo.svg
image to some dummy value:
<!-- src/components/nav/nav-header.vue -->
<template>
<header class="header">
<nav-navbar class="container" transparent>
<template #brand>
<nav-navbar-item tag="a" :href="`${env.wwwUrl}/`">
<!-- change this line to use some dummy image name like foo.svg: -->
<img src="@/assets/foo.svg" :alt="env.title" />
</nav-navbar-item>
</template>
<!-- ... -->
If you have the app opened up in a web browser, you’ll see the logo image in the page header has disappeared, and replaced with its alt text (“Local Pro Custodibus”).
Shell
To run arbitrary NPM commands (such as npm outdated
), start a shell with the dev Docker image with the following command:
$ make shell docker-compose run -u $(id -u) shell /bin/bash Creating app_shell_run ... done node@d6b679ca310c:/srv/app$ npm outdated Package Current Wanted Latest Location Depended by axios-extensions 3.1.7 3.1.7 3.1.6 node_modules/axios-extensions app
Directories
Here’s a quick tour of the directories in the app project:
-
bin
: miscellaneous shell scripts -
build
: build scripts -
coverage
: coverage output -
ee
: Enterprise Edition code and tests -
node_modules
: standard Node.js dependencies directory -
ops
: scripts run on deployed systems -
out
: build output -
public
: static files served by the app (such asfavicon.ico
) -
src
: source code-
src/assets
: static files directly included by the source code -
src/components
: Vue.js components -
src/mixins
: Vue.js mixins and composables -
src/pages
: Vue.js pages -
src/plugins
: Vue.js plugins -
src/stores
: Pinia stores -
src/styles
: SCSS stylesheets -
src/utils
: generic JavaScript utility functions
-
-
tests
: unit tests
Agent
Clone the official Git repository at https://git.sr.ht/~arx10/procustodibus-agent. All the development scripts assume that you will use tox for development in an Python virtualenv.
Init
In your local procustodibus-agent/
directory, create a virtualenv with pyenv:
$ pyenv virtualenv 3.10.12 procustodibus-agent
Then activate the virtualenv:
$ pyenv local procustodibus-agent 3.7.17 3.8.17 3.9.17 3.10.12 3.11.4
And install tox into the virtualenv:
(procustodibus-agent) $ pip install tox Collecting tox Downloading tox-4.9.0-py3-none-any.whl (152 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 152.8/152.8 kB 2.9 MB/s eta 0:00:00 Collecting packaging>=23.1 Using cached packaging-23.1-py3-none-any.whl (48 kB) Collecting tomli>=2.0.1 Using cached tomli-2.0.1-py3-none-any.whl (12 kB) Collecting cachetools>=5.3.1 Downloading cachetools-5.3.1-py3-none-any.whl (9.3 kB) Collecting colorama>=0.4.6 Using cached colorama-0.4.6-py2.py3-none-any.whl (25 kB) Collecting pyproject-api>=1.5.3 Downloading pyproject_api-1.5.4-py3-none-any.whl (12 kB) Collecting pluggy>=1.2 Using cached pluggy-1.2.0-py3-none-any.whl (17 kB) Collecting platformdirs>=3.10 Downloading platformdirs-3.10.0-py3-none-any.whl (17 kB) Collecting filelock>=3.12.2 Using cached filelock-3.12.2-py3-none-any.whl (10 kB) Collecting virtualenv>=20.24.3 Downloading virtualenv-20.24.3-py3-none-any.whl (3.0 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.0/3.0 MB 44.3 MB/s eta 0:00:00 Collecting chardet>=5.2 Downloading chardet-5.2.0-py3-none-any.whl (199 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 199.4/199.4 kB 20.2 MB/s eta 0:00:00 Collecting distlib<1,>=0.3.7 Downloading distlib-0.3.7-py2.py3-none-any.whl (468 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 468.9/468.9 kB 32.4 MB/s eta 0:00:00 Installing collected packages: distlib, tomli, pluggy, platformdirs, packaging, filelock, colorama, chardet, cachetools, virtualenv, pyproject-api, tox Successfully installed cachetools-5.3.1 chardet-5.2.0 colorama-0.4.6 distlib-0.3.7 filelock-3.12.2 packaging-23.1 platformdirs-3.10.0 pluggy-1.2.0 pyproject-api-1.5.4 tomli-2.0.1 tox-4.9.0 virtualenv-20.24.3
Finally, install the pre-commit and pre-push hooks:
(procustodibus-agent) $ tox -e pre-commit -- install pre-commit: install_deps> python -I -m pip install pre-commit pre-commit: commands[0]> pre-commit install pre-commit installed at .git/hooks/pre-commit pre-commit: OK (3.89=setup[3.67]+cmd[0.22] seconds) congratulations :) (7.41 seconds) (procustodibus-agent) $ tox -e pre-commit -- install -t pre-push pre-commit: commands[0]> pre-commit install -t pre-push pre-commit installed at .git/hooks/pre-push pre-commit: OK (0.18=setup[0.01]+cmd[0.18] seconds) congratulations :) (1.48 seconds)
Test
Simply run the tox
command to run the full linting and test suite (which will take several minutes to complete):
(procustodibus-agent) $ tox .pkg-cpython37: install_requires> python -I -m pip install 'setuptools>=40.8.0' wheel .pkg-cpython37: _optional_hooks> python /home/me/source/pyenv/versions/3.10.9/envs/procustodibus-agent/lib/python3.10/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__ .pkg-cpython37: get_requires_for_build_editable> python /home/me/source/pyenv/versions/3.10.9/envs/procustodibus-agent/lib/python3.10/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__ .pkg-cpython37: install_requires_for_build_editable> python -I -m pip install wheel .pkg-cpython37: build_editable> python /home/me/source/pyenv/versions/3.10.9/envs/procustodibus-agent/lib/python3.10/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__ py37: install_package_deps> python -I -m pip install 'docopt-ng~=0.7' 'inflection~=0.5' 'pynacl~=1.5' pytest pytest-cov pytest-datadir pytest-mock pytest-timeout pytest-watch 'requests~=2.27' 'tabulate~=0.8' py37: install_package> python -I -m pip install --force-reinstall --no-deps /home/me/procustodibus-agent/.tox/.tmp/package/1/procustodibus_agent-1.3.3-0.editable-py3-none-any.whl py37: commands[0]> pytest ============================================================================================================= test session starts ============================================================================================================= platform linux -- Python 3.7.16, pytest-7.4.0, pluggy-1.2.0 cachedir: .tox/py37/.pytest_cache rootdir: /home/me/procustodibus-agent plugins: mock-3.11.1, datadir-1.4.1, cov-4.1.0, timeout-2.1.0 collected 252 items test/test_api.py .................................. [ 13%] ... test/mfa/test_init.py ..................................... [100%] ---------- coverage: platform linux, python 3.10.9-final-0 ----------- Coverage HTML written to dir htmlcov ============================================================================================================= 252 passed in 1.82s ============================================================================================================= coverage: commands[1]> coverage report Name Stmts Miss Cover ------------------------------------------------------------- procustodibus_agent/__init__.py 5 0 100% procustodibus_agent/agent.py 47 31 34% procustodibus_agent/api.py 155 4 97% procustodibus_agent/cli.py 24 24 0% procustodibus_agent/cnf.py 215 7 97% procustodibus_agent/connectivity.py 77 2 97% procustodibus_agent/credentials.py 19 19 0% procustodibus_agent/executor.py 416 24 94% procustodibus_agent/ip_route.py 36 4 89% procustodibus_agent/mfa/__init__.py 83 12 86% procustodibus_agent/mfa/api.py 33 1 97% procustodibus_agent/mfa/cli.py 29 29 0% procustodibus_agent/resolve_hostname.py 56 0 100% procustodibus_agent/wg.py 44 2 95% procustodibus_agent/wg_cnf.py 174 2 99% ------------------------------------------------------------- TOTAL 1413 161 89% coverage: OK ✔ in 9.32 seconds flake8: install_package_deps> python -I -m pip install cohesion darglint dlint 'docopt-ng~=0.7' flake8 flake8-alfred flake8-bandit flake8-broken-line flake8-bugbear flake8-builtins flake8-class-attributes-order flake8-coding flake8-cognitive-complexity flake8-comprehensions flake8-debugger flake8-docstrings flake8-eradicate flake8-executable flake8-expression-complexity flake8-fixme flake8-functions flake8-isort flake8-logging-format flake8-pep3101 flake8-print flake8-pytest flake8-pytest-style flake8-requirements flake8-rst flake8-spellcheck flake8-string-format 'inflection~=0.5' pep8-naming 'pynacl~=1.5' 'requests~=2.27' 'tabulate~=0.8' flake8: install_package> python -I -m pip install --force-reinstall --no-deps /home/me/procustodibus-agent/.tox/.tmp/package/6/procustodibus_agent-1.3.3-0.editable-py3-none-any.whl flake8: commands[0]> flake8 .pkg: _exit> python /home/me/procustodibus-agent/versions/3.10.9/envs/testpyenv/lib/python3.10/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__ .pkg-cpython37: _exit> python /home/me/procustodibus-agent/versions/3.10.9/envs/testpyenv/lib/python3.10/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__ .pkg-cpython38: _exit> python /home/me/procustodibus-agent/versions/3.10.9/envs/testpyenv/lib/python3.10/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__ .pkg-cpython39: _exit> python /home/me/procustodibus-agent/versions/3.10.9/envs/testpyenv/lib/python3.10/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__ flake8: OK ✔ in 1 minute 26.16 seconds build: install_deps> python -I -m pip install setuptools wheel build: commands[0]> python setup.py -q sdist bdist_wheel /home/me/procustodibus-agent/.tox/build/lib/python3.10/site-packages/setuptools/_distutils/cmd.py:66: SetuptoolsDeprecationWarning: setup.py install is deprecated. !! ******************************************************************************** Please avoid running ``setup.py`` directly. Instead, use pypa/build, pypa/installer or other standards-based tools. See https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html for details. ******************************************************************************** !! self.initialize_options() py37: OK (11.96=setup[9.99]+cmd[1.96] seconds) py38: OK (11.16=setup[9.34]+cmd[1.83] seconds) py39: OK (11.37=setup[9.48]+cmd[1.89] seconds) py310: OK (11.09=setup[9.35]+cmd[1.73] seconds) py311: OK (11.05=setup[9.32]+cmd[1.72] seconds) coverage: OK (9.32=setup[6.79]+cmd[2.30,0.23] seconds) flake8: OK (86.16=setup[14.63]+cmd[71.53] seconds) build: OK (1.94=setup[1.46]+cmd[0.48] seconds) congratulations :) (155.31 seconds)
Watch
To run all the tests every time you make a change to the source code, run the tox -e watch
command:
(procustodibus-agent) $ tox -e watch cli develop-inst-noop: /home/me/procustodibus-agent cli installed: certifi==2023.7.22,cffi==1.15.1,charset-normalizer==3.2.0,colorama==0.4.6,coverage==7.3.0,docopt==0.6.2,docopt-ng==0.9.0,exceptiongroup==1.1.2,idna==3.4,inflection==0.5.1,iniconfig==2.0.0,packaging==23.1,pluggy==1.2.0,# Editable Git install (procustodibus-agent==1.3.3) with either a deleted local remote or invalid URI:,# 'git@git.sr.ht:~arx10/procustodibus-agent',-e /home/me/procustodibus-agent,pycparser==2.21,PyNaCl==1.5.0,pytest==7.4.0,pytest-cov==4.1.0,pytest-datadir==1.4.1,pytest-mock==3.11.1,pytest-timeout==2.1.0,pytest-watch==4.2.0,requests==2.31.0,tabulate==0.9.0,tomli==2.0.1,urllib3==2.0.4,watchdog==3.0.0 watch run-test-pre: PYTHONHASHSEED='526703176' watch run-test: commands[0] | pytest-watch [Wed Aug 02 18:49:23 2023] Running: py.test ================================================= test session starts ================================================= platform linux -- Python 3.10.6, pytest-7.4.0, pluggy-1.2.0 cachedir: .tox/watch/.pytest_cache rootdir: /home/me/procustodibus-agent plugins: mock-3.11.1, datadir-1.4.1, cov-4.1.0, timeout-2.1.0 collected 252 items test/test_api.py .................................. [ 13%] test/test_cnf.py ............................................. [ 31%] test/test_connectivity.py .............. [ 36%] test/test_executor.py ........................................... [ 53%] test/test_ip_route.py ..... [ 55%] test/test_resolve_hostname.py ......................... [ 65%] test/test_wg.py ......... [ 69%] test/test_wg_cnf.py ................................. [ 82%] test/mfa/test_api.py ....... [ 85%] test/mfa/test_init.py ..................................... [100%] ================================================= 252 passed in 1.07s =================================================
CLI
To run the agent CLI (Command-Line Interface), run the tox -e cli
command, followed by --
and the arguments to the agent (eg --help
):
(procustodibus-agent) $ tox -e cli -- --help cli develop-inst-nodeps: /home/me/procustodibus-agent cli installed: certifi==2023.7.22,cffi==1.15.1,charset-normalizer==3.2.0,colorama==0.4.6,coverage==7.3.0,docopt==0.6.2,docopt-ng==0.9.0,exceptiongroup==1.1.2,idna==3.4,inflection==0.5.1,iniconfig==2.0.0,packaging==23.1,pluggy==1.2.0,# Editable Git install (procustodibus-agent==1.3.3) with either a deleted local remote or invalid URI:,# 'git@git.sr.ht:~axr10/procustodibus-agent',-e /home/me/procustodibus-agent,pycparser==2.21,PyNaCl==1.5.0,pytest==7.4.0,pytest-cov==4.1.0,pytest-datadir==1.4.1,pytest-mock==3.11.1,pytest-timeout==2.1.0,pytest-watch==4.2.0,requests==2.31.0,tabulate==0.9.0,tomli==2.0.1,urllib3==2.0.4,watchdog==3.0.0 cli run-test-pre: PYTHONHASHSEED='337286959' cli run-test: commands[0] | procustodibus-agent --help Pro Custodibus Agent. Synchronizes your WireGuard settings with Pro Custodibus. Usage: procustodibus-agent [--config=CONFIG] [--loop=SECONDS] [-v | -vv | --verbosity=LEVEL] procustodibus-agent --help procustodibus-agent --test [--config=CONFIG] [-v | -vv | --verbosity=LEVEL] procustodibus-agent --version Options: -h --help Show this help --test Run connectivity check --version Show agent version -c --config=CONFIG Config file -l --loop=SECONDS Loop indefinitely, sending ping every SECONDS --verbosity=LEVEL Log level (ERROR, WARNING, INFO, DEBUG) -v INFO verbosity -vv DEBUG verbosity ___________________________________________________________________________________________________________________ summary ___________________________________________________________________________________________________________________ cli: commands succeeded congratulations :)
If you make changes to the agent source code, it will automatically recompile the next time you execute it. For example, open up the procustodibus_agent/cli.py
file, and change the main()
function to print out some dummy value when the --version
option is used:
# procustodibus_agent/cli.py
# ...
def main():
"""CLI Entry point."""
args = docopt(__doc__)
if args["--version"]:
# change this line to print some dummy value like "FOOBAR":
print("FOOBAR")
elif args["--test"]:
check(args["--config"], args["--verbosity"] or args["-v"])
else:
run(
args["--config"],
args["--verbosity"] or args["-v"],
args["--loop"],
)
# ...
Run the CLI with the --version
option to view the results of your change:
(procustodibus-agent) $ tox -e cli -- --version cli develop-inst-noop: /home/me/procustodibus-agent cli installed: certifi==2023.7.22,cffi==1.15.1,charset-normalizer==3.2.0,colorama==0.4.6,coverage==7.3.0,docopt==0.6.2,docopt-ng==0.9.0,exceptiongroup==1.1.2,idna==3.4,inflection==0.5.1,iniconfig==2.0.0,packaging==23.1,pluggy==1.2.0,# Editable Git install (procustodibus-agent==1.3.3) with either a deleted local remote or invalid URI:,# 'git@git.sr.ht:~arx10/procustodibus-agent',-e /home/me/procustodibus-agent,pycparser==2.21,PyNaCl==1.5.0,pytest==7.4.0,pytest-cov==4.1.0,pytest-datadir==1.4.1,pytest-mock==3.11.1,pytest-timeout==2.1.0,pytest-watch==4.2.0,requests==2.31.0,tabulate==0.9.0,tomli==2.0.1,urllib3==2.0.4,watchdog==3.0.0 cli run-test-pre: PYTHONHASHSEED='127587549' cli run-test: commands[0] | procustodibus-agent --version FOOBAR _______________________________________________________ summary _______________________________________________________ cli: commands succeeded congratulations :)
Install Tests
To run the install tests, first build the Docker container for each:
(procustodibus-agent) $ docker-compose -f test_install/docker-compose.yml build --pull TODO
Then run the install tests:
(procustodibus-agent) $ tox -e py310 test_install TODO
The install tests will take around 15 minutes to complete.
Directories
Here’s a quick tour of the directories in the agent project:
-
build
: build working directory -
.builds
: SourceHut build scripts -
dist
: output of build scripts -
docker
: docker build scripts -
etc
: service configuration files -
htmlcov
: coverage output -
procustodibus_agent
: source code -
procustodibus_agent.egg-info
: local install directory -
requirements
: requirements files -
test
: unit tests -
test_install
: install tests (run via Docker) -
.tox
: tox working directory