Add foundation tracing and platform build wrapper
This commit is contained in:
@@ -54,7 +54,8 @@ add_custom_target(panopainter_modernization_status
|
|||||||
|
|
||||||
add_library(pp_foundation STATIC
|
add_library(pp_foundation STATIC
|
||||||
src/foundation/binary_stream.cpp
|
src/foundation/binary_stream.cpp
|
||||||
src/foundation/parse.cpp)
|
src/foundation/parse.cpp
|
||||||
|
src/foundation/trace.cpp)
|
||||||
target_include_directories(pp_foundation
|
target_include_directories(pp_foundation
|
||||||
PUBLIC
|
PUBLIC
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/src")
|
"${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ ctest --preset desktop-fast --build-config Debug
|
|||||||
powershell -ExecutionPolicy Bypass -File scripts\automation\test.ps1 -Preset desktop-fast -Configuration Debug
|
powershell -ExecutionPolicy Bypass -File scripts\automation\test.ps1 -Preset desktop-fast -Configuration Debug
|
||||||
powershell -ExecutionPolicy Bypass -File scripts\automation\build.ps1 -Preset windows-msvc-default -Configuration Debug -Target pano_cli
|
powershell -ExecutionPolicy Bypass -File scripts\automation\build.ps1 -Preset windows-msvc-default -Configuration Debug -Target pano_cli
|
||||||
cmake --preset android-arm64
|
cmake --preset android-arm64
|
||||||
cmake --build --preset android-arm64 --target pp_foundation pano_cli pp_foundation_binary_stream_tests pp_foundation_parse_tests
|
powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64
|
||||||
```
|
```
|
||||||
|
|
||||||
Known local toolchain state:
|
Known local toolchain state:
|
||||||
@@ -73,7 +73,8 @@ Known local toolchain state:
|
|||||||
- Local Visual Studio generator selected by CMake: Visual Studio 17 2022
|
- Local Visual Studio generator selected by CMake: Visual Studio 17 2022
|
||||||
- Android SDK: `C:\Users\omara\AppData\Local\Android\Sdk`
|
- Android SDK: `C:\Users\omara\AppData\Local\Android\Sdk`
|
||||||
- Android NDK: `C:\Users\omara\AppData\Local\Android\Sdk\ndk\29.0.14206865`
|
- Android NDK: `C:\Users\omara\AppData\Local\Android\Sdk\ndk\29.0.14206865`
|
||||||
- Android arm64 headless configure/build passes through root CMake.
|
- Android arm64 headless configure/build passes through root CMake and the
|
||||||
|
`platform-build` automation wrapper.
|
||||||
- `vcpkg` is not on PATH yet; see DEBT-0007.
|
- `vcpkg` is not on PATH yet; see DEBT-0007.
|
||||||
|
|
||||||
Known warnings after the current CMake app build:
|
Known warnings after the current CMake app build:
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ agent or engineer to remove them without reconstructing context from chat.
|
|||||||
| DEBT-0006 | Open | Modernization | `pano_cli create-document` validates and emits JSON command contracts but does not yet invoke the legacy document/app model | The document model has not been extracted from `Canvas`/`App` yet | `pano_cli create-document --width 64 --height 32 --layers 2`; CTest `pano_cli_create_document_smoke` | Replace command contract implementation with real `pp_document` creation once Phase 4 extracts the document model |
|
| DEBT-0006 | Open | Modernization | `pano_cli create-document` validates and emits JSON command contracts but does not yet invoke the legacy document/app model | The document model has not been extracted from `Canvas`/`App` yet | `pano_cli create-document --width 64 --height 32 --layers 2`; CTest `pano_cli_create_document_smoke` | Replace command contract implementation with real `pp_document` creation once Phase 4 extracts the document model |
|
||||||
| DEBT-0007 | Open | Modernization | `vcpkg.json` exists but CMake is not yet using a validated vcpkg toolchain on this machine | `vcpkg` is not available on PATH and Visual Studio reports manifest mode is disabled | `cmake --preset windows-msvc-default` currently configures with vendored dependencies | Add validated vcpkg toolchain/preset integration for desktop, Android, and Apple triplets |
|
| DEBT-0007 | Open | Modernization | `vcpkg.json` exists but CMake is not yet using a validated vcpkg toolchain on this machine | `vcpkg` is not available on PATH and Visual Studio reports manifest mode is disabled | `cmake --preset windows-msvc-default` currently configures with vendored dependencies | Add validated vcpkg toolchain/preset integration for desktop, Android, and Apple triplets |
|
||||||
| DEBT-0008 | Open | Modernization | `windows-msvc-default` preset is used for local validation because the VS 2026 generator is not installed here | The target VS 2026 preset must remain, but this machine configures with Visual Studio 17 2022 | `cmake --preset windows-msvc-default`; `ctest --preset desktop-fast --build-config Debug` | Validate `windows-vs2026-x64` on a machine with Visual Studio 2026 installed and make it the default Windows validation preset |
|
| DEBT-0008 | Open | Modernization | `windows-msvc-default` preset is used for local validation because the VS 2026 generator is not installed here | The target VS 2026 preset must remain, but this machine configures with Visual Studio 17 2022 | `cmake --preset windows-msvc-default`; `ctest --preset desktop-fast --build-config Debug` | Validate `windows-vs2026-x64` on a machine with Visual Studio 2026 installed and make it the default Windows validation preset |
|
||||||
| DEBT-0009 | Open | Modernization | Android root CMake validation currently builds headless targets only, not APK/package variants | Platform app entrypoints still live in legacy Gradle/CMake projects and need Phase 6 alignment | `cmake --preset android-arm64`; `cmake --build --preset android-arm64 --target pp_foundation pano_cli pp_foundation_binary_stream_tests pp_foundation_parse_tests` | Android standard, Quest, and Focus/Wave package targets consume shared component targets and have package smoke commands |
|
| DEBT-0009 | Open | Modernization | Android root CMake validation currently builds headless targets only, not APK/package variants | Platform app entrypoints still live in legacy Gradle/CMake projects and need Phase 6 alignment | `powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64` | Android standard, Quest, and Focus/Wave package targets consume shared component targets and have package smoke commands |
|
||||||
|
|
||||||
## Closed Debt
|
## Closed Debt
|
||||||
|
|
||||||
|
|||||||
@@ -242,9 +242,10 @@ Gate:
|
|||||||
Goal: make each component reachable by automated tools and future agents.
|
Goal: make each component reachable by automated tools and future agents.
|
||||||
|
|
||||||
Status: in progress. `tests/` exists, `desktop-fast` runs headlessly, and
|
Status: in progress. `tests/` exists, `desktop-fast` runs headlessly, and
|
||||||
PowerShell/bash wrappers exist for configure/build/test/analyze. `pano_cli`
|
PowerShell/bash wrappers exist for configure/build/test/analyze/platform-build.
|
||||||
exists with a first JSON automation command for validating create-document
|
`pano_cli` exists with a first JSON automation command for validating
|
||||||
inputs; full document/app integration is debt-tracked as DEBT-0006.
|
create-document inputs; full document/app integration is debt-tracked as
|
||||||
|
DEBT-0006.
|
||||||
|
|
||||||
Implementation tasks:
|
Implementation tasks:
|
||||||
|
|
||||||
@@ -300,8 +301,9 @@ Goal: split libraries while keeping current app behavior.
|
|||||||
Status: started. `pp_foundation` exists with binary stream utilities and
|
Status: started. `pp_foundation` exists with binary stream utilities and
|
||||||
boundary/overread tests. It also owns strict decimal `uint32` parsing used by
|
boundary/overread tests. It also owns strict decimal `uint32` parsing used by
|
||||||
`pano_cli`, with rejection tests for empty, signed, mixed, and overflowing
|
`pano_cli`, with rejection tests for empty, signed, mixed, and overflowing
|
||||||
input. Continue extracting legacy-safe utilities before moving assets, paint,
|
input. A deterministic `TraceRecorder` now records component/name/thread/frame
|
||||||
or document behavior.
|
and stroke timing spans with invalid-end tests. Continue extracting legacy-safe
|
||||||
|
utilities before moving assets, paint, or document behavior.
|
||||||
|
|
||||||
Implementation tasks:
|
Implementation tasks:
|
||||||
|
|
||||||
@@ -501,25 +503,26 @@ Last verified on 2026-05-31:
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
cmake --preset windows-msvc-default
|
cmake --preset windows-msvc-default
|
||||||
cmake --build --preset windows-msvc-default --config Debug --target pp_foundation_binary_stream_tests pp_foundation_parse_tests pano_cli PanoPainter
|
cmake --build --preset windows-msvc-default --config Debug --target pp_foundation_binary_stream_tests pp_foundation_parse_tests pp_foundation_trace_tests pano_cli PanoPainter
|
||||||
ctest --preset desktop-fast --build-config Debug
|
ctest --preset desktop-fast --build-config Debug
|
||||||
powershell -ExecutionPolicy Bypass -File scripts\automation\test.ps1 -Preset desktop-fast -Configuration Debug
|
powershell -ExecutionPolicy Bypass -File scripts\automation\test.ps1 -Preset desktop-fast -Configuration Debug
|
||||||
powershell -ExecutionPolicy Bypass -File scripts\automation\build.ps1 -Preset windows-msvc-default -Configuration Debug -Target pano_cli
|
powershell -ExecutionPolicy Bypass -File scripts\automation\build.ps1 -Preset windows-msvc-default -Configuration Debug -Target pano_cli
|
||||||
cmake --preset android-arm64
|
cmake --preset android-arm64
|
||||||
cmake --build --preset android-arm64 --target pp_foundation pano_cli pp_foundation_binary_stream_tests pp_foundation_parse_tests
|
powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64
|
||||||
```
|
```
|
||||||
|
|
||||||
Results:
|
Results:
|
||||||
|
|
||||||
- `pp_foundation_binary_stream_tests` passed.
|
- `pp_foundation_binary_stream_tests` passed.
|
||||||
- `pp_foundation_parse_tests` passed.
|
- `pp_foundation_parse_tests` passed.
|
||||||
|
- `pp_foundation_trace_tests` passed.
|
||||||
- `pano_cli_create_document_smoke` passed.
|
- `pano_cli_create_document_smoke` passed.
|
||||||
- `PanoPainter.exe` built through CMake at
|
- `PanoPainter.exe` built through CMake at
|
||||||
`out/build/windows-msvc-default/Debug/PanoPainter.exe`.
|
`out/build/windows-msvc-default/Debug/PanoPainter.exe`.
|
||||||
- PowerShell build/test automation wrappers return JSON summaries and passed
|
- PowerShell build/test automation wrappers return JSON summaries and passed
|
||||||
local smoke checks.
|
local smoke checks.
|
||||||
- Android arm64 configured with NDK 29.0.14206865 and compiled headless
|
- Android arm64 configured with NDK 29.0.14206865 through the platform-build
|
||||||
foundation/tool/test targets.
|
wrapper and compiled headless foundation/tool/test targets.
|
||||||
- Known remaining warnings: legacy project/vendor diagnostics, Visual Studio
|
- Known remaining warnings: legacy project/vendor diagnostics, Visual Studio
|
||||||
vcpkg-manifest warning, `LNK4099` missing libyuv PDBs, and `LNK4098` runtime
|
vcpkg-manifest warning, `LNK4099` missing libyuv PDBs, and `LNK4098` runtime
|
||||||
library conflict from retained vendor binaries.
|
library conflict from retained vendor binaries.
|
||||||
|
|||||||
52
scripts/automation/platform-build.ps1
Normal file
52
scripts/automation/platform-build.ps1
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[string[]]$Presets = @("android-arm64"),
|
||||||
|
[string[]]$Targets = @("pp_foundation", "pano_cli", "pp_foundation_binary_stream_tests", "pp_foundation_parse_tests", "pp_foundation_trace_tests")
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
$started = Get-Date
|
||||||
|
$results = @()
|
||||||
|
$overallExitCode = 0
|
||||||
|
|
||||||
|
foreach ($preset in $Presets) {
|
||||||
|
& cmake --preset $preset
|
||||||
|
$configureExitCode = $LASTEXITCODE
|
||||||
|
if ($configureExitCode -ne 0) {
|
||||||
|
$overallExitCode = $configureExitCode
|
||||||
|
$results += [ordered]@{
|
||||||
|
preset = $preset
|
||||||
|
stage = "configure"
|
||||||
|
exitCode = $configureExitCode
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
$buildArgs = @("--build", "--preset", $preset)
|
||||||
|
foreach ($target in $Targets) {
|
||||||
|
$buildArgs += @("--target", $target)
|
||||||
|
}
|
||||||
|
|
||||||
|
& cmake @buildArgs
|
||||||
|
$buildExitCode = $LASTEXITCODE
|
||||||
|
if ($buildExitCode -ne 0 -and $overallExitCode -eq 0) {
|
||||||
|
$overallExitCode = $buildExitCode
|
||||||
|
}
|
||||||
|
|
||||||
|
$results += [ordered]@{
|
||||||
|
preset = $preset
|
||||||
|
stage = "build"
|
||||||
|
targets = $Targets
|
||||||
|
exitCode = $buildExitCode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$elapsed = [int]((Get-Date) - $started).TotalMilliseconds
|
||||||
|
[ordered]@{
|
||||||
|
command = "platform-build"
|
||||||
|
exitCode = $overallExitCode
|
||||||
|
elapsedMs = $elapsed
|
||||||
|
results = $results
|
||||||
|
} | ConvertTo-Json -Compress -Depth 6
|
||||||
|
|
||||||
|
exit $overallExitCode
|
||||||
29
scripts/automation/platform-build.sh
Normal file
29
scripts/automation/platform-build.sh
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
set -u
|
||||||
|
|
||||||
|
preset="${1:-android-arm64}"
|
||||||
|
shift || true
|
||||||
|
targets="${*:-pp_foundation pano_cli pp_foundation_binary_stream_tests pp_foundation_parse_tests pp_foundation_trace_tests}"
|
||||||
|
start="$(date +%s)"
|
||||||
|
|
||||||
|
cmake --preset "$preset"
|
||||||
|
configure_exit="$?"
|
||||||
|
if [ "$configure_exit" -ne 0 ]; then
|
||||||
|
end="$(date +%s)"
|
||||||
|
elapsed_ms="$(( (end - start) * 1000 ))"
|
||||||
|
printf '{"command":"platform-build","preset":"%s","stage":"configure","exitCode":%s,"elapsedMs":%s}\n' "$preset" "$configure_exit" "$elapsed_ms"
|
||||||
|
exit "$configure_exit"
|
||||||
|
fi
|
||||||
|
|
||||||
|
build_args=""
|
||||||
|
for target in $targets; do
|
||||||
|
build_args="$build_args --target $target"
|
||||||
|
done
|
||||||
|
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
cmake --build --preset "$preset" $build_args
|
||||||
|
build_exit="$?"
|
||||||
|
end="$(date +%s)"
|
||||||
|
elapsed_ms="$(( (end - start) * 1000 ))"
|
||||||
|
printf '{"command":"platform-build","preset":"%s","targets":"%s","exitCode":%s,"elapsedMs":%s}\n' "$preset" "$targets" "$build_exit" "$elapsed_ms"
|
||||||
|
exit "$build_exit"
|
||||||
98
src/foundation/trace.cpp
Normal file
98
src/foundation/trace.cpp
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
#include "foundation/trace.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace pp::foundation {
|
||||||
|
|
||||||
|
Result<TraceSpanId> TraceRecorder::begin_span(TraceSpanDesc desc, std::uint64_t start_us)
|
||||||
|
{
|
||||||
|
if (desc.component.empty()) {
|
||||||
|
return Result<TraceSpanId>::failure(
|
||||||
|
Status::invalid_argument("trace component must not be empty"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc.name.empty()) {
|
||||||
|
return Result<TraceSpanId>::failure(
|
||||||
|
Status::invalid_argument("trace span name must not be empty"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next_id_ == std::numeric_limits<TraceSpanId>::max()) {
|
||||||
|
return Result<TraceSpanId>::failure(
|
||||||
|
Status::out_of_range("trace span id space is exhausted"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto id = next_id_++;
|
||||||
|
ActiveSpan span;
|
||||||
|
span.id = id;
|
||||||
|
span.component.assign(desc.component);
|
||||||
|
span.name.assign(desc.name);
|
||||||
|
span.desc = desc;
|
||||||
|
span.desc.component = span.component;
|
||||||
|
span.desc.name = span.name;
|
||||||
|
span.start_us = start_us;
|
||||||
|
span.active = true;
|
||||||
|
active_spans_.push_back(span);
|
||||||
|
|
||||||
|
return Result<TraceSpanId>::success(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status TraceRecorder::end_span(TraceSpanId id, std::uint64_t end_us)
|
||||||
|
{
|
||||||
|
ActiveSpan* span = find_active_span(id);
|
||||||
|
if (span == nullptr) {
|
||||||
|
return Status::out_of_range("trace span id is not active");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end_us < span->start_us) {
|
||||||
|
return Status::invalid_argument("trace span cannot end before it starts");
|
||||||
|
}
|
||||||
|
|
||||||
|
TraceEvent event;
|
||||||
|
event.component = span->component;
|
||||||
|
event.name = span->name;
|
||||||
|
event.thread_id = span->desc.thread_id;
|
||||||
|
event.frame_id = span->desc.frame_id;
|
||||||
|
event.stroke_id = span->desc.stroke_id;
|
||||||
|
event.start_us = span->start_us;
|
||||||
|
event.duration_us = end_us - span->start_us;
|
||||||
|
events_.push_back(event);
|
||||||
|
|
||||||
|
span->active = false;
|
||||||
|
return Status::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::span<const TraceEvent> TraceRecorder::events() const noexcept
|
||||||
|
{
|
||||||
|
return events_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t TraceRecorder::active_span_count() const noexcept
|
||||||
|
{
|
||||||
|
std::size_t count = 0;
|
||||||
|
for (const auto& span : active_spans_) {
|
||||||
|
if (span.active) {
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TraceRecorder::clear() noexcept
|
||||||
|
{
|
||||||
|
active_spans_.clear();
|
||||||
|
events_.clear();
|
||||||
|
next_id_ = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TraceRecorder::ActiveSpan* TraceRecorder::find_active_span(TraceSpanId id) noexcept
|
||||||
|
{
|
||||||
|
for (auto& span : active_spans_) {
|
||||||
|
if (span.active && span.id == id) {
|
||||||
|
return &span;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
60
src/foundation/trace.h
Normal file
60
src/foundation/trace.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "foundation/result.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <span>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace pp::foundation {
|
||||||
|
|
||||||
|
using TraceSpanId = std::uint64_t;
|
||||||
|
|
||||||
|
struct TraceSpanDesc {
|
||||||
|
std::string_view component;
|
||||||
|
std::string_view name;
|
||||||
|
std::uint64_t thread_id = 0;
|
||||||
|
std::uint64_t frame_id = 0;
|
||||||
|
std::uint64_t stroke_id = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TraceEvent {
|
||||||
|
std::string component;
|
||||||
|
std::string name;
|
||||||
|
std::uint64_t thread_id = 0;
|
||||||
|
std::uint64_t frame_id = 0;
|
||||||
|
std::uint64_t stroke_id = 0;
|
||||||
|
std::uint64_t start_us = 0;
|
||||||
|
std::uint64_t duration_us = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TraceRecorder {
|
||||||
|
public:
|
||||||
|
[[nodiscard]] Result<TraceSpanId> begin_span(TraceSpanDesc desc, std::uint64_t start_us);
|
||||||
|
[[nodiscard]] Status end_span(TraceSpanId id, std::uint64_t end_us);
|
||||||
|
|
||||||
|
[[nodiscard]] std::span<const TraceEvent> events() const noexcept;
|
||||||
|
[[nodiscard]] std::size_t active_span_count() const noexcept;
|
||||||
|
|
||||||
|
void clear() noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct ActiveSpan {
|
||||||
|
TraceSpanId id = 0;
|
||||||
|
TraceSpanDesc desc;
|
||||||
|
std::string component;
|
||||||
|
std::string name;
|
||||||
|
std::uint64_t start_us = 0;
|
||||||
|
bool active = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] ActiveSpan* find_active_span(TraceSpanId id) noexcept;
|
||||||
|
|
||||||
|
std::vector<ActiveSpan> active_spans_;
|
||||||
|
std::vector<TraceEvent> events_;
|
||||||
|
TraceSpanId next_id_ = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -26,6 +26,16 @@ add_test(NAME pp_foundation_parse_tests COMMAND pp_foundation_parse_tests)
|
|||||||
set_tests_properties(pp_foundation_parse_tests PROPERTIES
|
set_tests_properties(pp_foundation_parse_tests PROPERTIES
|
||||||
LABELS "foundation;desktop-fast")
|
LABELS "foundation;desktop-fast")
|
||||||
|
|
||||||
|
add_executable(pp_foundation_trace_tests
|
||||||
|
foundation/trace_tests.cpp)
|
||||||
|
target_link_libraries(pp_foundation_trace_tests PRIVATE
|
||||||
|
pp_foundation
|
||||||
|
pp_test_harness)
|
||||||
|
|
||||||
|
add_test(NAME pp_foundation_trace_tests COMMAND pp_foundation_trace_tests)
|
||||||
|
set_tests_properties(pp_foundation_trace_tests PROPERTIES
|
||||||
|
LABELS "foundation;desktop-fast")
|
||||||
|
|
||||||
if(TARGET pano_cli)
|
if(TARGET pano_cli)
|
||||||
add_test(NAME pano_cli_create_document_smoke
|
add_test(NAME pano_cli_create_document_smoke
|
||||||
COMMAND pano_cli create-document --width 64 --height 32 --layers 2)
|
COMMAND pano_cli create-document --width 64 --height 32 --layers 2)
|
||||||
|
|||||||
109
tests/foundation/trace_tests.cpp
Normal file
109
tests/foundation/trace_tests.cpp
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
#include "foundation/trace.h"
|
||||||
|
#include "test_harness.h"
|
||||||
|
|
||||||
|
using pp::foundation::StatusCode;
|
||||||
|
using pp::foundation::TraceRecorder;
|
||||||
|
using pp::foundation::TraceSpanDesc;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void records_completed_spans_with_context(pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
TraceRecorder recorder;
|
||||||
|
|
||||||
|
const auto id = recorder.begin_span(
|
||||||
|
TraceSpanDesc {
|
||||||
|
.component = "paint",
|
||||||
|
.name = "stroke_commit",
|
||||||
|
.thread_id = 7,
|
||||||
|
.frame_id = 11,
|
||||||
|
.stroke_id = 13,
|
||||||
|
},
|
||||||
|
100);
|
||||||
|
|
||||||
|
PP_EXPECT(h, id.ok());
|
||||||
|
PP_EXPECT(h, recorder.active_span_count() == 1U);
|
||||||
|
PP_EXPECT(h, recorder.end_span(id.value(), 145).ok());
|
||||||
|
PP_EXPECT(h, recorder.active_span_count() == 0U);
|
||||||
|
PP_EXPECT(h, recorder.events().size() == 1U);
|
||||||
|
|
||||||
|
const auto& event = recorder.events()[0];
|
||||||
|
PP_EXPECT(h, event.component == "paint");
|
||||||
|
PP_EXPECT(h, event.name == "stroke_commit");
|
||||||
|
PP_EXPECT(h, event.thread_id == 7U);
|
||||||
|
PP_EXPECT(h, event.frame_id == 11U);
|
||||||
|
PP_EXPECT(h, event.stroke_id == 13U);
|
||||||
|
PP_EXPECT(h, event.start_us == 100U);
|
||||||
|
PP_EXPECT(h, event.duration_us == 45U);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rejects_invalid_span_descriptions(pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
TraceRecorder recorder;
|
||||||
|
|
||||||
|
const auto no_component = recorder.begin_span(
|
||||||
|
TraceSpanDesc { .component = "", .name = "load" },
|
||||||
|
1);
|
||||||
|
const auto no_name = recorder.begin_span(
|
||||||
|
TraceSpanDesc { .component = "assets", .name = "" },
|
||||||
|
1);
|
||||||
|
|
||||||
|
PP_EXPECT(h, !no_component.ok());
|
||||||
|
PP_EXPECT(h, no_component.status().code == StatusCode::invalid_argument);
|
||||||
|
PP_EXPECT(h, !no_name.ok());
|
||||||
|
PP_EXPECT(h, no_name.status().code == StatusCode::invalid_argument);
|
||||||
|
PP_EXPECT(h, recorder.events().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
void rejects_bad_end_calls_without_recording_events(pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
TraceRecorder recorder;
|
||||||
|
const auto id = recorder.begin_span(
|
||||||
|
TraceSpanDesc { .component = "renderer", .name = "readback" },
|
||||||
|
50);
|
||||||
|
|
||||||
|
PP_EXPECT(h, id.ok());
|
||||||
|
|
||||||
|
const auto backwards = recorder.end_span(id.value(), 49);
|
||||||
|
PP_EXPECT(h, !backwards.ok());
|
||||||
|
PP_EXPECT(h, backwards.code == StatusCode::invalid_argument);
|
||||||
|
PP_EXPECT(h, recorder.active_span_count() == 1U);
|
||||||
|
PP_EXPECT(h, recorder.events().empty());
|
||||||
|
|
||||||
|
PP_EXPECT(h, recorder.end_span(id.value(), 51).ok());
|
||||||
|
const auto duplicate = recorder.end_span(id.value(), 52);
|
||||||
|
PP_EXPECT(h, !duplicate.ok());
|
||||||
|
PP_EXPECT(h, duplicate.code == StatusCode::out_of_range);
|
||||||
|
PP_EXPECT(h, recorder.events().size() == 1U);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_resets_events_and_span_ids(pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
TraceRecorder recorder;
|
||||||
|
const auto first = recorder.begin_span(
|
||||||
|
TraceSpanDesc { .component = "ui", .name = "layout" },
|
||||||
|
10);
|
||||||
|
PP_EXPECT(h, first.ok());
|
||||||
|
PP_EXPECT(h, recorder.end_span(first.value(), 20).ok());
|
||||||
|
recorder.clear();
|
||||||
|
|
||||||
|
const auto second = recorder.begin_span(
|
||||||
|
TraceSpanDesc { .component = "ui", .name = "layout" },
|
||||||
|
30);
|
||||||
|
PP_EXPECT(h, second.ok());
|
||||||
|
PP_EXPECT(h, second.value() == first.value());
|
||||||
|
PP_EXPECT(h, recorder.events().empty());
|
||||||
|
PP_EXPECT(h, recorder.active_span_count() == 1U);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
pp::tests::Harness harness;
|
||||||
|
harness.run("records_completed_spans_with_context", records_completed_spans_with_context);
|
||||||
|
harness.run("rejects_invalid_span_descriptions", rejects_invalid_span_descriptions);
|
||||||
|
harness.run("rejects_bad_end_calls_without_recording_events", rejects_bad_end_calls_without_recording_events);
|
||||||
|
harness.run("clear_resets_events_and_span_ids", clear_resets_events_and_span_ids);
|
||||||
|
return harness.finish();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user