diff options
Diffstat (limited to 'CLAUDE.md')
| -rw-r--r-- | CLAUDE.md | 67 |
1 files changed, 53 insertions, 14 deletions
@@ -31,8 +31,10 @@ xmake run zenserver xmake run zen # Generate IDE project files -xmake sln # Windows: Visual Studio 2022 -xmake project -k xcode # macOS: Xcode +xmake sln # default: vs2022 on Windows, xcode on macOS, vscode on Linux +xmake sln vs2026 # Windows: Visual Studio 2026 +xmake sln xcode # macOS: Xcode +xmake sln vscode # VS Code / clangd (compile_commands.json) ``` ### Build Configuration Options @@ -60,6 +62,7 @@ xmake test --run=core # zencore-test xmake test --run=store # zenstore-test xmake test --run=server # zenserver test command xmake test --run=integration # zenserver-test +xmake test --run=zen # zen-test (zen CLI integration tests) xmake test --run=http # zenhttp-test xmake test --run=util # zenutil-test xmake test --run=remotestore # zenremotestore-test @@ -70,6 +73,33 @@ xmake test --run=all --junit Tests use the **doctest** framework. To run server tests: `xmake run zenserver test` +### Test Suite Naming Convention + +All `TEST_CASE` blocks must be wrapped in a `TEST_SUITE_BEGIN`/`TEST_SUITE_END` pair (not the `TEST_SUITE()` wrapper macro, to avoid reformatting). Suite names follow the pattern `{module}.{filename}` where the `zen` prefix is stripped from the module name: + +| Module | File | Suite name | +|---|---|---| +| `zencore` | `filesystem.cpp` | `"core.filesystem"` | +| `zenstore` | `blockstore.cpp` | `"store.blockstore"` | +| `zenhttp` | `httpclient.cpp` | `"http.httpclient"` | +| `zenutil` | `wildcard.cpp` | `"util.wildcard"` | +| `zennet` | `statsdclient.cpp` | `"net.statsdclient"` | +| `zentelemetry` | `stats.cpp` | `"telemetry.stats"` | +| `zenremotestore` | `chunkblock.cpp` | `"remotestore.chunkblock"` | +| `zenserver-test` | `cache-tests.cpp` | `"server.cache"` | +| `zen-test` | `artifactprovider-tests.cpp` | `"zen.artifactprovider"` | +| `zen-test` | `trace-tests.cpp` | `"zen.trace"` | + +Each test executable defaults to running only the suites for its own module (e.g. `zencore-test` defaults to `core.*`). This default is derived automatically from the executable name by `RunTestMain` and can be overridden on the command line: + +```bash +# Run only filesystem tests within zencore-test +zencore-test --test-suite=core.filesystem + +# Run all core tests (default behaviour, no flag needed) +zencore-test +``` + ### Code Formatting ```bash @@ -77,10 +107,10 @@ Tests use the **doctest** framework. To run server tests: `xmake run zenserver t xmake precommit # Or use pre-commit directly -pre-commit run --all-files +python -m pre_commit run --all-files ``` -Install pre-commit hooks with `pre-commit install` to auto-format on commit. +Install pre-commit hooks with `python -m pre_commit install` to auto-format on commit. ### Cleaning Build State @@ -129,7 +159,8 @@ The codebase is organized into layered modules with clear dependencies: **Test Projects:** - `*-test` modules contain tests for their corresponding module (only built in debug mode) -- `zenserver-test` contains integration tests +- `zenserver-test` contains integration tests that exercise zenserver end-to-end +- `zen-test` contains integration tests that exercise the `zen` CLI end-to-end ### Key Architectural Patterns @@ -145,17 +176,19 @@ The codebase is organized into layered modules with clear dependencies: - CAS content is garbage collected based on what is referenced from of higher level services **Frontend:** -- Web UI bundled as ZIP in `src/zenserver/frontend/*.zip` - Dashboards for hub, orchestrator, and compute services are located in `src/zenserver/frontent/html/` - These are the files which end up being bundled into the front-end zip mentioned above -- Update with `xmake updatefrontend` after modifying HTML/JS, and check in the resulting zip +- The embedded zip is generated automatically at build time when source files change **Memory Management:** -- Can use mimalloc or rpmalloc for performance +- Can use mimalloc or rpmalloc for performance (selected via `--malloc=mimalloc`, `--malloc=rpmalloc`) - UE-style LLM (Low-Level Memory) tracking available on Windows - Memory tracing support integrated with UE trace system - Avoid using `std::string` when building (concatenating etc) temporary strings. Use `ExtendableStringBuilder<N>` instead with an appropriate size N to avoid heap allocations in the common case. +- For validating or debugging lifetimes using `--malloc=stomp` can be useful. It + ensures that any access to freed or out-of-bounds memory will cause an access + violation. **Tracing:** - UE Trace integration for profiling and diagnostics @@ -168,6 +201,7 @@ The codebase is organized into layered modules with clear dependencies: **Naming Conventions (UE-inspired with modifications):** - Classes/Structs: `PascalCase` - Functions/Methods: `PascalCase()` +- Function parameters/local variables: `PascalCase` - Member variables: `m_PascalCase` - Global variables: `g_PascalCase` - Static variables: `s_PascalCase` @@ -180,15 +214,22 @@ The codebase is organized into layered modules with clear dependencies: - clang-format enforced via pre-commit hooks - Use `std` containers; `eastl::fixed_vector` etc. for performance-critical paths where the number of elements in the container is typically small or when the container is temporary and suitable for stack allocation. +- For shared ownership, prefer intrusive reference counting via `TRefCounted<T>` (or `RefCounted`) with `Ref<T>` + over `std::shared_ptr`. Since the ownership policy is known at type definition time, the overhead of + `std::shared_ptr` (separate control block, etc.) is unnecessary. - Exceptions used only for unexpected errors, not flow control - Some `std` exception types like `runtime_error` are also available in the `zen` namespace and offer convenience of formatting the exception message by allowing fmt-style formatting without using `fmt::format` which can reduce clutter. To use these, please `#include <zencore/except_fmt.h>` -- Logging is done via `ZEN_DEBUG(...)`, `ZEN_INFO(...)`, `ZEN_WARN`, `ZEN_ERROR` macros - - Logging macros use `fmt::vformat` internally for message formatting. The first argument is the format string, +- Logging is done via `ZEN_DEBUG(...)`, `ZEN_INFO(...)`, `ZEN_WARN(...)`, `ZEN_ERROR(...)` macros + - Prefer these over the older `ZEN_LOG_INFO`, `ZEN_LOG_WARN`, etc. variants which require an explicit log category parameter + - Logging macros use `fmt::vformat` internally for message formatting. The first argument is the format string, which must be a string literal (turned into `std::string_view` in the macros) - - Logging channels can be overridden on a scope-by-scope basis (per-class or even per-function) by implementing + - Logging channels can be overridden on a scope-by-scope basis (per-class or even per-function) by implementing a `LoggerRef Log()` function +- Avoid repetition. If the same pattern (e.g. data structure lookups, locking + find) appears multiple times, + factor it into a helper function and call that instead. +- Avoid `auto` when the type is not explicitly visible on the right-hand side of the assignment. Spell out the type instead. - `if`/`else` should use braces even for single-statement branches **Includes:** @@ -235,7 +276,7 @@ Endpoints accepting POST operations should only accept JSON or compact binary fo Key third-party libraries (managed by xmake): - EASTL - High-performance containers - ASIO - Async I/O -- spdlog/fmt - Logging and formatting +- fmt - Formatting - doctest - Testing framework - cxxopts - Command-line parsing - json11 - JSON parsing @@ -276,6 +317,4 @@ When debugging zenserver-test or other multi-process scenarios, use child proces # Create deployable ZIP bundle xmake bundle -# Update frontend ZIP after HTML changes -xmake updatefrontend ``` |