Skip to content

Staging#1865

Closed
nedvedba wants to merge 11 commits intodevelfrom
staging
Closed

Staging#1865
nedvedba wants to merge 11 commits intodevelfrom
staging

Conversation

@nedvedba
Copy link
Collaborator

@nedvedba nedvedba commented Feb 23, 2026

Update Staging

Summary by Sourcery

Bump project versions to the 2.x release line, refine query parameter handling, and expand end-to-end testing and documentation for web and query functionality.

New Features:

  • Add an end-to-end Python API test that exercises query creation, execution, and deletion.
  • Introduce support for web UI end-to-end tests driven by Playwright with documented setup and optional Docker-based execution.

Bug Fixes:

  • Ensure user creation route responds with the created user object.
  • Fix logging and response handling for the expiring token API to correctly describe the query window and report token counts.
  • Correct ZeroMQ message body size error reporting to avoid accessing a closed message object.

Enhancements:

  • Update core, common library, protocol API, web, repo, authz, and Python client versions to new major 2.x/4.x releases with refreshed release metadata.
  • Tighten validation of query parameters in the Foxx query API to require structured objects instead of arbitrary or string payloads.
  • Align query parameter serialization between the C++ core DatabaseAPI and Foxx query endpoints to avoid unnecessary JSON string wrapping.
  • Switch the server factory to use the basic ZeroMQ proxy implementation when the custom proxy type is requested, simplifying proxy selection.
  • Clean up CMake formatting and minor messaging in test configuration files.

Documentation:

  • Extend the end-to-end test README with detailed instructions for running Playwright-based web UI tests locally and via Docker, including headless vs headed execution options.

Tests:

  • Register the new query end-to-end test in CTest with appropriate fixtures and dependencies on record setup.
  • Refine Playwright test configuration to focus on Chromium-based execution and add a debug message when web end-to-end tests are enabled.
  • Introduce scaffolding for additional web UI Playwright tests, including user password change scenarios.

JoshuaSBrown and others added 11 commits November 25, 2025 06:54
…se. (#1778)

[DAPS-1786] - Web tests, refactor: add test for hitting password reset. (#1787)
… tests (#1779)

* [DAPS-1775] - fix: core, foxx, add missing {}, foxx query_router add params object schema to routes. (#1781)
* [DAPS-1777] - fix: foxx, user_router fix regression in missing response. (#1778)
* [DAPS-1786] - refactor: web tests, add test for hitting password reset. (#1787)
* [DAPS-1277] - fix: mock, core, common, PROXY_BASIC_ZMQ and PROXY_CUSTOM correctly defined
* [DAPS-1790] - fix: common, core, repo, zmq assertion failure during EXCEPT call due to callin zmq_msg with invalid state after closing it.
* [DAPS-1791] - fix: build, python client, requirements.txt was being moved to a folder named requirements.txt during cmake configure script.
* refactor: only print subset of user properties.

* chore: Auto-format JavaScript files with Prettier
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Feb 23, 2026

Reviewer's Guide

Adds end-to-end query API coverage and Playwright documentation, refines query payload handling and logging in Foxx services, switches servers to use a custom proxy implementation, bumps DataFed major versions to 2.x/4.x, and wires the new tests into CMake/CTest.

Sequence diagram for query API execution with structured params

sequenceDiagram
  actor Client
  participant CoreServer as CoreServer_DatabaseAPI
  participant Foxx as Foxx_QueryRouter
  participant DB as ArangoDB

  Client->>CoreServer: SearchRequest (params as JSON object)
  CoreServer->>CoreServer: parseSearchRequest
  CoreServer->>CoreServer: a_params = "{" + a_params + "}"
  CoreServer->>CoreServer: generalSearch
  CoreServer->>Foxx: HTTP POST /qry/exec
  Note over CoreServer,Foxx: payload.params is serialized JSON object (no wrapping string)
  Foxx->>Foxx: joi validation (params as object)
  Foxx->>Foxx: execQuery(client, mode, published, query)
  Foxx->>DB: AQL query with query.params
  DB-->>Foxx: query results
  Foxx-->>CoreServer: HTTP response (results)
  CoreServer-->>Client: SearchReply
Loading

Sequence diagram for expiring token retrieval and logging

sequenceDiagram
  actor Client
  participant UserRouter
  participant DB as ArangoDB
  participant Logger

  Client->>UserRouter: GET /token/get/expiring?expires_in
  UserRouter->>Logger: logRequestStarted(desc)
  UserRouter->>DB: AQL query for tokens expiring before now + expires_in
  DB-->>UserRouter: results cursor
  UserRouter->>UserRouter: extra_log_info = results.toArray()
  UserRouter-->>Client: send(results)
  UserRouter->>Logger: logRequestSuccess(desc, extra expiring_token_count)
  Note over UserRouter,Logger: On failure, logRequestFailure(desc, expiring_token_count)
Loading

Updated class diagram for proxy factory and server usage

classDiagram
  class IServer {
    <<interface>>
    +run()
  }

  class Proxy {
    +Proxy(socket_options, socket_credentials, log_context)
    +run()
  }

  class ProxyBasicZMQ {
    +ProxyBasicZMQ(socket_options, socket_credentials, log_context)
    +run()
  }

  class ServerFactory {
    -LogContext m_log_context
    +ServerFactory(log_context)
    +create(type, socket_options, socket_credentials) IServer
  }

  class Server {
    +msgRouter(log_context, thread_count)
    +ioInsecure(log_context, thread_count)
  }

  ServerFactory ..> IServer : create
  Proxy ..|> IServer
  ProxyBasicZMQ --|> Proxy
  ServerFactory ..> ProxyBasicZMQ : PROXY_BASIC_ZMQ
  Server ..> IServer : uses proxy (PROXY_CUSTOM)
Loading

File-Level Changes

Change Details Files
Document Playwright-based web UI testing workflow and optional Docker setup for running tests.
  • Extend end-to-end tests README with Playwright installation and usage commands.
  • Provide example Dockerfile and docker run invocation for running Playwright tests in a container.
  • Explain how to toggle headless/headed mode in Playwright configuration when debugging.
tests/end-to-end/README.md
Update project versioning to new major releases across core components and Python client.
  • Refresh release timestamp (month/day/hour) in Version.cmake.
  • Bump common library, protocol API, core, web, repo, authz, and Python client major/minor versions to new 2.x/4.x values while resetting patches where appropriate.
cmake/Version.cmake
Normalize and slightly clean up CMake configuration for tests and web build.
  • Fix whitespace/style in various CMake conditionals and options.
  • Ensure tests subdirectory is added when integration or end-to-end tests are enabled.
  • Add an end-to-end query API test to the CTest suite with proper fixture dependencies.
  • Emit a debug message from the web-UI tests CMake file and wire in auth.setup.js template configuration.
CMakeLists.txt
tests/end-to-end/CMakeLists.txt
tests/end-to-end/web-UI/CMakeLists.txt
Fix Foxx user and token APIs to correctly send responses and improve logging around expiring tokens.
  • Ensure the user create/update route sends the computed result in the HTTP response.
  • Change token-expiring route to use a descriptive message, query the database into a local const, and send results to the client.
  • Log only the count of expiring tokens instead of the full result set in both success and failure paths.
core/database/foxx/api/user_router.js
Tighten Foxx query API validation and stop treating query params as raw JSON strings.
  • Require query params to be objects (via Joi) instead of any type or serialized strings across create/update/exec endpoints.
  • Propagate params objects directly into stored queries rather than stringifying them.
  • Remove old debug logging comments from query routing and execution code.
core/database/foxx/api/query_router.js
Align C++ DatabaseAPI search payload/parse with new structured params expectations.
  • Send the search request params field as-is (already JSON) when building the HTTP payload for general search.
  • Wrap the parsed search params in braces when returning them from parseSearchRequest to satisfy downstream expectations.
core/server/DatabaseAPI.cpp
Switch servers to use a custom proxy type and wire ServerFactory to instantiate the basic ZMQ proxy implementation.
  • Change core and mock core server router/IO paths to request PROXY_CUSTOM instead of PROXY_BASIC_ZMQ from the ServerFactory.
  • Update ServerFactory to include the ProxyBasicZMQ header and construct ProxyBasicZMQ when PROXY_BASIC_ZMQ is requested, maintaining compatibility with existing code paths.
core/server/CoreServer.cpp
tests/mock_core/MockCoreServer.cpp
common/source/ServerFactory.cpp
Improve robustness of ZeroMQCommunicator error reporting for body frame size mismatches.
  • Capture zmq_msg_size into a local variable before closing the message to avoid accessing freed resources.
  • Use the captured size in the exception message when reporting mismatched frame sizes.
common/source/communicators/ZeroMQCommunicator.cpp
Adjust web layer version wiring to use generic version field names and expose API version components.
  • Read release timestamp fields from generic RELEASE_* constants exported by the version module instead of DATAFED_* names.
  • Initialize global API version major/minor/patch from version module and incorporate them into the global version representation.
web/datafed-ws.js
Simplify Playwright configuration to run only Chromium-based tests by default.
  • Remove commented-out Firefox and WebKit project definitions from Playwright config to reduce noise and clarify supported browsers.
tests/end-to-end/web-UI/playwright.config.js
Add an end-to-end Python test that exercises query CRUD and metadata filtering against a real repo/allocation.
  • Implement a unittest that logs in via password, creates a repo and allocation, writes a data record with structured metadata, and then creates/executes a saved query filtering on metadata.
  • Poll for query results until the expected record appears, then assert on the alias name and clean up the query.
  • Implement teardown that deletes the test record, allocation, and repo, waiting for associated tasks to complete.
tests/end-to-end/test_api_query.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@nedvedba nedvedba closed this Feb 23, 2026
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 4 issues, and left some high level feedback:

  • The Playwright README Docker run example uses -e DISPLAY=host.docker. internal:0, which has an extra space and stray dot; this should be corrected to something like host.docker.internal:0 so users can copy/paste it successfully.
  • In tests/end-to-end/web-UI/CMakeLists.txt there is a hardcoded message("ENABLE END TO END!!!!!!!") that will print on every configure; consider removing or guarding it to avoid noisy build output.
  • The query params handling now expects an object in the Foxx routes (e.g., query_router.js schemas) while DatabaseAPI::parseSearchRequest still wraps a_params with braces ("{" + a_params + "}"); aligning the representation used by DatabaseAPI and the Foxx API will prevent subtle mismatches in query parameter formatting.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The Playwright README Docker run example uses `-e DISPLAY=host.docker. internal:0`, which has an extra space and stray dot; this should be corrected to something like `host.docker.internal:0` so users can copy/paste it successfully.
- In `tests/end-to-end/web-UI/CMakeLists.txt` there is a hardcoded `message("ENABLE END TO END!!!!!!!")` that will print on every configure; consider removing or guarding it to avoid noisy build output.
- The query `params` handling now expects an object in the Foxx routes (e.g., `query_router.js` schemas) while `DatabaseAPI::parseSearchRequest` still wraps `a_params` with braces (`"{" + a_params + "}"`); aligning the representation used by `DatabaseAPI` and the Foxx API will prevent subtle mismatches in query parameter formatting.

## Individual Comments

### Comment 1
<location path="core/server/DatabaseAPI.cpp" line_range="1312" />
<code_context>
   payload["qry_end"] = qry_end;
   payload["qry_filter"] = qry_filter;
-  payload["params"] = "{" + params + "}";
+  payload["params"] = params;
   payload["limit"] = to_string(cnt);

</code_context>
<issue_to_address>
**issue (bug_risk):** The `params` field is still sent as a string while the Foxx API now expects a JSON object, which can break validation and query execution.

On the Foxx side, `params` is now validated as `joi.object()` and is no longer `JSON.parse`d from a string, but here `payload["params"]` is still assigned from a `std::string`. That will serialize as a JSON string value (e.g. `"params": "{...}"`) instead of an object (`"params": { ... }`), causing Joi validation and `execQuery` to receive the wrong shape. Please ensure `params` is sent as a JSON object, e.g. by parsing it (`payload["params"] = nlohmann::json::parse(params);`) or constructing the JSON object directly.
</issue_to_address>

### Comment 2
<location path="core/server/DatabaseAPI.cpp" line_range="3946" />
<code_context>
   a_qry_end = a_qry_end;
   a_qry_filter = a_qry_filter;
-
+  a_params = "{" + a_params + "}";
   return cnt;
 }
</code_context>
<issue_to_address>
**question:** Wrapping `a_params` with braces at this layer risks double-wrapping or inconsistent formatting depending on how callers construct `a_params`.

Previously, this function left `a_params` untouched and `generalSearch` added the braces. Now the braces are added here while `generalSearch` passes `params` through. This only works if all callers always pass a raw fragment (e.g. `"cnt:10, offset:0"`) and never include braces.

If any caller already passes a braced string, this will yield `"{{...}}"` and break parsing. Consider standardizing `a_params` (always raw fragment vs. always full JSON) and ensuring that exactly one well-defined layer converts it to a JSON object (potentially by using `nlohmann::json` instead of string concatenation). Also double-check existing call sites for any that already include braces.
</issue_to_address>

### Comment 3
<location path="tests/end-to-end/test_api_query.py" line_range="31-38" />
<code_context>
+            + "python/datafed_pkg"
+        )
+        sys.path.insert(0, path_to_python_datafed_module)
+        try:
+            from datafed.CommandLib import API
+        except ImportError:
+            print(
+                "datafed was not found, make sure you are running script with "
+                "PYTHONPATH set to the location of the package in the datafed repo"
+            )
+            sys.exit(1)
+
+        from datafed import version as df_ver
</code_context>
<issue_to_address>
**suggestion (testing):** Prefer skipping tests instead of calling sys.exit when prerequisites (modules/env vars) are missing

Using `sys.exit(1)` in `setUp` will terminate the entire test run and surface as a hard failure instead of a skipped test due to missing prerequisites. Instead, call `self.skipTest(...)` when `datafed` (or other required modules) isn’t importable or required env vars like `DATAFED_DOMAIN` are unset, so the test is clearly marked as skipped and doesn’t block other tests from running.
</issue_to_address>

### Comment 4
<location path="CMakeLists.txt" line_range="37" />
<code_context>
 building with static depencies is not completely possible because some system
</code_context>
<issue_to_address>
**issue (typo):** Fix spelling of "dependencies" and possessive "its" in this option description.

In this description, please change "depencies" to "dependencies" and "build it's libraries" to "build its libraries" (possessive).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

payload["qry_end"] = qry_end;
payload["qry_filter"] = qry_filter;
payload["params"] = "{" + params + "}";
payload["params"] = params;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): The params field is still sent as a string while the Foxx API now expects a JSON object, which can break validation and query execution.

On the Foxx side, params is now validated as joi.object() and is no longer JSON.parsed from a string, but here payload["params"] is still assigned from a std::string. That will serialize as a JSON string value (e.g. "params": "{...}") instead of an object ("params": { ... }), causing Joi validation and execQuery to receive the wrong shape. Please ensure params is sent as a JSON object, e.g. by parsing it (payload["params"] = nlohmann::json::parse(params);) or constructing the JSON object directly.

a_qry_end = a_qry_end;
a_qry_filter = a_qry_filter;

a_params = "{" + a_params + "}";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Wrapping a_params with braces at this layer risks double-wrapping or inconsistent formatting depending on how callers construct a_params.

Previously, this function left a_params untouched and generalSearch added the braces. Now the braces are added here while generalSearch passes params through. This only works if all callers always pass a raw fragment (e.g. "cnt:10, offset:0") and never include braces.

If any caller already passes a braced string, this will yield "{{...}}" and break parsing. Consider standardizing a_params (always raw fragment vs. always full JSON) and ensuring that exactly one well-defined layer converts it to a JSON object (potentially by using nlohmann::json instead of string concatenation). Also double-check existing call sites for any that already include braces.

Comment on lines +31 to +38
try:
from datafed.CommandLib import API
except ImportError:
print(
"datafed was not found, make sure you are running script with "
"PYTHONPATH set to the location of the package in the datafed repo"
)
sys.exit(1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Prefer skipping tests instead of calling sys.exit when prerequisites (modules/env vars) are missing

Using sys.exit(1) in setUp will terminate the entire test run and surface as a hard failure instead of a skipped test due to missing prerequisites. Instead, call self.skipTest(...) when datafed (or other required modules) isn’t importable or required env vars like DATAFED_DOMAIN are unset, so the test is clearly marked as skipped and doesn’t block other tests from running.

@@ -36,7 +36,7 @@ building with static depencies is not completely possible because some system
libraries must be shared libraries for DataFed to be interoperable. If this
setting is turned on DataFed will build it's libraries as shared and try to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (typo): Fix spelling of "dependencies" and possessive "its" in this option description.

In this description, please change "depencies" to "dependencies" and "build it's libraries" to "build its libraries" (possessive).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants