From: Dominik Csapak <d.csapak@proxmox.com>
To: Lukas Wagner <l.wagner@proxmox.com>, pdm-devel@lists.proxmox.com
Subject: Re: [PATCH datacenter-manager/proxmox v2 00/20] inject application context via API macro for easier integration testing
Date: Mon, 24 Aug 2026 14:33:40 +0200 [thread overview]
Message-ID: <bceb57f6-fd65-4e29-8274-1af4ac3bf24e@proxmox.com> (raw)
In-Reply-To: <20260820145220.418032-1-l.wagner@proxmox.com>
looked at the general idea (and at the code in some patches, but not
too deeply)
the direction looks good to me, it's basically an expansion on our
product-config + injection into the api calls, which is nice.
for some pointers/questions see the answer to the individual patches
On 8/20/26 4:52 PM, Lukas Wagner wrote:
> TL;DR: Inject essential runtime config, client factory, etc. as an application
> context object and allow to retrieve this object easily in an API handler via
> the API macro. This allows us directly call API handler implementations from
> integration tests. The aim is to make it easier to write good tests on a larger
> level.
>
> ## Rationale
>
> Considering the different stages of automated software testing, unit testing
> (test small software components in isolation) integration testing (test
> multiple components together, specifically their interactions) and
> end-to-end testing (test the entire application in a context as close to
> production as possible), I've found that the middle one, integration testing is
> a very challenging one in our stack.
>
> I've found that the challenges with integration testing mostly stem from the
> following:
>
> - "hardcoded" (as in, determined by some constant or literally
> hard-coded) assumptions about storage paths (config, state, caches) and
> users/permissions. This makes it challenging to call into the component
> from a test running as normal user, e.g. from a regular `cargo test`.
>
> - use of global/static instances (examples: Worker task context,
> proxmox-product-config, client factory in PDM...) in application code and
> shared crates. While this can be okay for things that are truly global (e.g.
> logging), it often hinders testing and especially test isolation due to hidden
> dependencies between test cases and some potential internal state of the global
> instance. This is one of the common causes of flaky tests. Also, the setup of
> these global instances in test cases is always a bit awkward, since the order
> of test execution is not defined (and might actually run in parallel), so some
> kind of synchronization between the test cases is necessary. Furthermore,
> certain test cases might require a *different* setup for these global instances
> (example: client factory that should produce a different kind of mocked PVE
> client); but since we usually put these in OnceLocks, one has to put these
> tests into a separate test binary.
>
> - tight coupling between major subsystems (e.g. one part calling into the
> other without any clear boundary or abstraction via callbacks or traits)
>
>
> With regards to PDM, there are a couple of things that need considering when testing:
> - Filesystem access to config, state and caches
> - Interactions with remotes via their API
>
> I feel like if we find a sensible way to abstract these for tests, we can
> reasonably cover a huge amount of the code in the backend.
>
> ## Implementation
>
> The core idea is to provide a context/application object ('struct
> PdmApplication') and "injecting" it into API handlers via special `State`
> parameters, automatically handled by the API macro.
>
> This new context object would give access to:
> - base paths for caches, config, state
> - file permissions, user/group
> - client factory
> - api cache
>
> The PdmApplication object is set up during daemon startup, stored in the RpcEnvironment,
> and then cloned for each API request, assuming that the handle requested access via
> an State<PdmApplication> parameter.
>
> PdmApplication is a thin wrapper around Arc<PdmApplicationInner>, which stores the actual
> configuration and trait objects.
>
> This general pattern of injecting application state/context via a parameter
> to the handler is something that is also common in other Rust-based
> web frameworks, e.g. [actix-web] and [axum].
>
> ## References:
>
> [actix-web]: https://actix.rs/docs/application/#state
> [axum]: https://docs.rs/axum/latest/axum/#sharing-state-with-handlers
>
>
> ## Bumps needed
>
> - proxmox-router
> - proxmox-rest-server
> - proxmox-api-macro
>
> ## Changes since v1:
> - fix a couple typos, grammar mistakes
> - extend the commit message for the commit that adds the type-keyed map
> to RpcEnvironment
> - fix test case for API macro
> - consistently use app handle in node subscpription api handler
> - in read_captured_response, don't unwrap but return an Error
> - add missing doc comments
>
>
> proxmox:
>
> Lukas Wagner (3):
> router: introduce shared state
> rest-server: allow to inject shared state
> api-macro: support shared state extraction type
>
> proxmox-api-macro/src/api/method.rs | 88 ++++++++++++++++++++-
> proxmox-api-macro/tests/state.rs | 101 +++++++++++++++++++++++++
> proxmox-rest-server/src/api_config.rs | 14 +++-
> proxmox-rest-server/src/environment.rs | 6 +-
> proxmox-router/src/cli/environment.rs | 12 ++-
> proxmox-router/src/lib.rs | 2 +
> proxmox-router/src/rpc_environment.rs | 7 ++
> proxmox-router/src/shared_state.rs | 76 +++++++++++++++++++
> 8 files changed, 302 insertions(+), 4 deletions(-)
> create mode 100644 proxmox-api-macro/tests/state.rs
> create mode 100644 proxmox-router/src/shared_state.rs
>
>
> proxmox-datacenter-manager:
>
> Lukas Wagner (17):
> context: promote context to a dir-style module
> pdm-config: remotes: rename trait methods to read/write/lock
> pdm-config: subscriptions: rename trait methods to read/write/lock
> remote iterator: pass remote config reader explicitly
> context: introduce a ContextFactory to build application context
> context: establish PdmApplication object
> context: register PdmApplication in router
> parallel fetcher: pass arguments to closure in a single type
> parallel fetcher: support a custom client factory
> api: sdn: use PdmApplication handle for accessing remotes
> tests: add helpers for building API-handler-level integration tests
> tests: add example tests for SDN API routes
> api-cache: add wrapper type
> context: provide api-cache on the app object
> api: subscriptions: use PdmApplication instead of globals
> pdm-config: subscriptions: drop unused accessor functions
> tests: add example tests for remote subscription management
>
> cli/admin/src/main.rs | 9 +-
> lib/pdm-config/src/remotes.rs | 26 +-
> lib/pdm-config/src/subscriptions.rs | 59 +--
> server/src/api/nodes/subscription.rs | 25 +-
> server/src/api/nodes/tasks.rs | 2 +-
> server/src/api/pbs/mod.rs | 10 +-
> server/src/api/pve/firewall.rs | 34 +-
> server/src/api/pve/mod.rs | 3 +-
> server/src/api/remotes/mod.rs | 5 +-
> server/src/api/remotes/updates.rs | 3 +-
> server/src/api/resources.rs | 39 +-
> server/src/api/sdn/controllers.rs | 20 +-
> server/src/api/sdn/vnets.rs | 23 +-
> server/src/api/sdn/zones.rs | 20 +-
> server/src/api/subscriptions/mod.rs | 226 +++++++-----
> server/src/api_cache.rs | 117 ++++--
> server/src/bin/proxmox-datacenter-api/main.rs | 17 +-
> ...proxmox-datacenter-manager-daily-update.rs | 14 +-
> .../bin/proxmox-datacenter-privileged-api.rs | 22 +-
> server/src/connection.rs | 54 ++-
> server/src/context.rs | 49 ---
> server/src/context/default.rs | 5 +
> server/src/context/faked_remotes.rs | 42 +++
> server/src/context/mod.rs | 167 +++++++++
> server/src/context/product_config.rs | 132 +++++++
> server/src/metric_collection/mod.rs | 6 +-
> .../remote_collection_task.rs | 47 +--
> server/src/parallel_fetcher.rs | 73 +++-
> server/src/remote_tasks/refresh_task.rs | 23 +-
> server/src/remote_updates.rs | 7 +-
> server/src/test_support/fake_remote.rs | 8 +-
> .../pve/remote-a/list_vnets.json | 8 +
> .../pve/remote-a/list_zones.json | 8 +
> .../pve/remote-b/list_vnets.json | 8 +
> .../pve/remote-b/list_zones.json | 8 +
> server/tests/common/environment.rs | 28 ++
> server/tests/common/mod.rs | 109 ++++++
> server/tests/common/test_application.rs | 337 ++++++++++++++++++
> server/tests/test_sdn.rs | 88 +++++
> server/tests/test_subscriptions.rs | 130 +++++++
> 40 files changed, 1606 insertions(+), 405 deletions(-)
> delete mode 100644 server/src/context.rs
> create mode 100644 server/src/context/default.rs
> create mode 100644 server/src/context/faked_remotes.rs
> create mode 100644 server/src/context/mod.rs
> create mode 100644 server/src/context/product_config.rs
> create mode 100644 server/tests/api_responses/pve/remote-a/list_vnets.json
> create mode 100644 server/tests/api_responses/pve/remote-a/list_zones.json
> create mode 100644 server/tests/api_responses/pve/remote-b/list_vnets.json
> create mode 100644 server/tests/api_responses/pve/remote-b/list_zones.json
> create mode 100644 server/tests/common/environment.rs
> create mode 100644 server/tests/common/mod.rs
> create mode 100644 server/tests/common/test_application.rs
> create mode 100644 server/tests/test_sdn.rs
> create mode 100644 server/tests/test_subscriptions.rs
>
>
> Summary over all repositories:
> 48 files changed, 1908 insertions(+), 409 deletions(-)
>
prev parent reply other threads:[~2026-08-24 12:33 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-20 14:52 [PATCH datacenter-manager/proxmox v2 00/20] inject application context via API macro for easier integration testing Lukas Wagner
2026-08-20 14:52 ` [PATCH proxmox v2 01/20] router: introduce shared state Lukas Wagner
2026-08-20 14:52 ` [PATCH proxmox v2 02/20] rest-server: allow to inject " Lukas Wagner
2026-08-20 14:52 ` [PATCH proxmox v2 03/20] api-macro: support shared state extraction type Lukas Wagner
2026-08-24 12:33 ` Dominik Csapak
2026-08-24 13:17 ` Lukas Wagner
2026-08-20 14:52 ` [PATCH datacenter-manager v2 04/20] context: promote context to a dir-style module Lukas Wagner
2026-08-20 14:52 ` [PATCH datacenter-manager v2 05/20] pdm-config: remotes: rename trait methods to read/write/lock Lukas Wagner
2026-08-20 14:52 ` [PATCH datacenter-manager v2 06/20] pdm-config: subscriptions: " Lukas Wagner
2026-08-20 14:52 ` [PATCH datacenter-manager v2 07/20] remote iterator: pass remote config reader explicitly Lukas Wagner
2026-08-20 14:52 ` [PATCH datacenter-manager v2 08/20] context: introduce a ContextFactory to build application context Lukas Wagner
2026-08-24 12:33 ` Dominik Csapak
2026-08-24 13:48 ` Lukas Wagner
2026-08-20 14:52 ` [PATCH datacenter-manager v2 09/20] context: establish PdmApplication object Lukas Wagner
2026-08-21 9:52 ` Thomas Ellmenreich
2026-08-21 12:26 ` Lukas Wagner
2026-08-24 12:33 ` Dominik Csapak
2026-08-24 13:23 ` Lukas Wagner
2026-08-20 14:52 ` [PATCH datacenter-manager v2 10/20] context: register PdmApplication in router Lukas Wagner
2026-08-20 14:52 ` [PATCH datacenter-manager v2 11/20] parallel fetcher: pass arguments to closure in a single type Lukas Wagner
2026-08-20 14:52 ` [PATCH datacenter-manager v2 12/20] parallel fetcher: support a custom client factory Lukas Wagner
2026-08-24 12:33 ` Dominik Csapak
2026-08-24 13:42 ` Lukas Wagner
2026-08-20 14:52 ` [PATCH datacenter-manager v2 13/20] api: sdn: use PdmApplication handle for accessing remotes Lukas Wagner
2026-08-20 14:52 ` [PATCH datacenter-manager v2 14/20] tests: add helpers for building API-handler-level integration tests Lukas Wagner
2026-08-21 9:57 ` Thomas Ellmenreich
2026-08-21 12:25 ` Lukas Wagner
2026-08-20 14:52 ` [PATCH datacenter-manager v2 15/20] tests: add example tests for SDN API routes Lukas Wagner
2026-08-20 14:52 ` [PATCH datacenter-manager v2 16/20] api-cache: add wrapper type Lukas Wagner
2026-08-24 12:33 ` Dominik Csapak
2026-08-24 13:47 ` Lukas Wagner
2026-08-24 13:57 ` Dominik Csapak
2026-08-20 14:52 ` [PATCH datacenter-manager v2 17/20] context: provide api-cache on the app object Lukas Wagner
2026-08-20 14:52 ` [PATCH datacenter-manager v2 18/20] api: subscriptions: use PdmApplication instead of globals Lukas Wagner
2026-08-20 14:52 ` [PATCH datacenter-manager v2 19/20] pdm-config: subscriptions: drop unused accessor functions Lukas Wagner
2026-08-20 14:52 ` [PATCH datacenter-manager v2 20/20] tests: add example tests for remote subscription management Lukas Wagner
2026-08-24 12:33 ` Dominik Csapak [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=bceb57f6-fd65-4e29-8274-1af4ac3bf24e@proxmox.com \
--to=d.csapak@proxmox.com \
--cc=l.wagner@proxmox.com \
--cc=pdm-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox