Skip to content

Add end-to-end Test_ExtendedHeartbeat for app-extended-heartbeat telemetry event#6338

Merged
khanayan123 merged 62 commits into
mainfrom
ayan.khan/app-extended-heartbeat
May 13, 2026
Merged

Add end-to-end Test_ExtendedHeartbeat for app-extended-heartbeat telemetry event#6338
khanayan123 merged 62 commits into
mainfrom
ayan.khan/app-extended-heartbeat

Conversation

@khanayan123
Copy link
Copy Markdown
Contributor

@khanayan123 khanayan123 commented Feb 18, 2026

Summary

Adds a new TELEMETRY_EXTENDED_HEARTBEAT end-to-end scenario and Test_ExtendedHeartbeat test that validates the app-extended-heartbeat telemetry event includes every config previously reported in app-started or app-client-configuration-change.

Also relaxes the v2 telemetry schema (value is no longer required on conf_key_value entries) to match the just-merged authoritative spec change in instrumentation-telemetry-api-docs#124 — backend ingest (UKV, EVP) already accepts a missing value and stores it as an empty string, so the strict requirement was inconsistent with reality and a source of false-positive schema-validation failures for some tracers.

Changes

New scenario

  • utils/_context/_scenarios/__init__.pyTELEMETRY_EXTENDED_HEARTBEAT scenario with shortened intervals (DD_TELEMETRY_HEARTBEAT_INTERVAL=1, DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL=2, plus _DD_* alias) so the extended-heartbeat event fires within the test window.
  • .github/workflows/run-end-to-end.yml — registers the new scenario in the end-to-end CI matrix.

New test

  • tests/test_telemetry.pyTest_ExtendedHeartbeat, gated by the existing @features.app_extended_heartbeat_event decorator. Collects config names from all app-started and app-client-configuration-change events, then asserts every one appears in at least one app-extended-heartbeat event across the stream (order-agnostic, to handle forked workers and remote-config re-reports).

Schema relaxation

  • tests/schemas/utils/miscs/telemetry/v2/objects/configuration.json — drops value from required. Mirrors instrumentation-telemetry-api-docs#124.
  • tests/schemas/test_schemas.py — removes both obsolete golang SchemaBug entries at $.payload.configuration[].value (ticket APMS-12697). These worked around the now-relaxed schema and are no longer needed.

Manifest version gates

SDK Gate Notes
cpp_httpd >1.0.4 httpd-datadog v1.0.5 bumped to dd-trace-cpp v2.1.0 (incl. dd-trace-cpp#301).
cpp_nginx >=1.16.1 nginx-datadog v1.16.1 bumped to dd-trace-cpp v2.1.0.
dotnet v3.39.0 dd-trace-dotnet#8227 shipped in v3.39.0; previous schema-validation blocker resolved by the spec relaxation.
golang >=2.8.0 dd-trace-go#4633 shipped in v2.8.0; configs from app-client-configuration-change now flow into the extended heartbeat.
java v1.23.0 (spring-boot-3-native variant remains missing_feature due to a separate native-image limitation around app-started capture.)
nodejs >=5.97.0 New ref_5_97_0 anchor added.
php >=1.20.0 libdatadog v33.0.0 includes #1910; dd-trace-php#3865 (merged 2026-05-11) bumped the submodule and added the parallel PHP-side test. Gate at 1.20.0 since the bump is post-1.19.2.
python v4.6.5
ruby >2.30.0

Related PRs

Add comprehensive parametric test suite for app-extended-heartbeat
telemetry event across all SDK languages. Tests verify timing,
payload structure, consistency, and compliance with API spec.

Tests added:
- test_extended_heartbeat_emission: Verifies interval timing
- test_extended_heartbeat_sequence: Validates multiple events
- test_extended_heartbeat_payload_content: Checks required fields
- test_extended_heartbeat_matches_app_started: Ensures consistency
- test_extended_heartbeat_excludes_products_and_install_signature
- test_extended_heartbeat_default_interval: Validates 24h default

All tests run parametrically across 9 SDK languages (Go, Java, .NET,
C++, PHP, Ruby, Rust, Python, Node.js).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 18, 2026

CODEOWNERS have been resolved as:

.github/workflows/run-end-to-end.yml                                    @DataDog/system-tests-core
manifests/cpp_httpd.yml                                                 @DataDog/dd-trace-cpp
manifests/cpp_nginx.yml                                                 @DataDog/dd-trace-cpp
manifests/dotnet.yml                                                    @DataDog/apm-dotnet @DataDog/asm-dotnet
manifests/golang.yml                                                    @DataDog/dd-trace-go-guild
manifests/java.yml                                                      @DataDog/asm-java @DataDog/apm-java
manifests/nodejs.yml                                                    @DataDog/dd-trace-js
manifests/php.yml                                                       @DataDog/apm-php @DataDog/asm-php
manifests/python.yml                                                    @DataDog/apm-python @DataDog/asm-python
manifests/ruby.yml                                                      @DataDog/ruby-guild @DataDog/asm-ruby
tests/schemas/test_schemas.py                                           @DataDog/system-tests-core
tests/schemas/utils/miscs/telemetry/v2/objects/configuration.json       @DataDog/system-tests-core
tests/test_telemetry.py                                                 @DataDog/libdatadog-telemetry @DataDog/apm-sdk-capabilities @DataDog/system-tests-core
utils/_context/_scenarios/__init__.py                                   @DataDog/system-tests-core

khanayan123 and others added 6 commits February 18, 2026 14:45
Register comprehensive parametric tests for app-extended-heartbeat event
validation across all SDK languages. Tests verify:
- Periodic emission timing (24h default, configurable)
- Payload structure (config, deps, integrations)
- Consistency with app-started event
- Proper field exclusions (products, install_signature)

Language version markers:
- Go: v1.73.0-dev
- Java: v1.40.0
- Node.js: v5.0.0
- Python: v2.0.0
- Ruby: v2.1.0-dev
- C++: v0.2.0-dev
- PHP: v1.0.0-dev
- .NET: missing_feature (intentionally skipped - no forked runtime-id issues)

Tests use fast intervals (0.3-0.5s) for CI efficiency.

Test location: tests/parametric/test_telemetry.py::Test_ExtendedHeartbeat (lines 1256-1514)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed Test_ExtendedHeartbeat manifest entries from development
version strings (e.g., v1.73.0-dev, v2.1.0-dev) to missing_feature
to follow repository conventions.

Development versions should not be specified in manifests. Tests
for unreleased features should use missing_feature until the
feature is actually released in a production version.

Changes:
- cpp.yml: v0.2.0-dev → missing_feature
- golang.yml: v1.73.0-dev → missing_feature
- nodejs.yml: '>=5.0.0' → missing_feature
- php.yml: v1.0.0-dev → missing_feature
- ruby.yml: v2.1.0-dev → missing_feature

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…tionality

Replace 6 complex test methods with a single simplified test that focuses
on the core requirement: comparing configurations across telemetry events.

The new test:
- Grabs app-started, app-extended-heartbeat, and app-client-configuration-change events
- Extracts configuration data from each
- Asserts configs match between app-started and app-extended-heartbeat
- Optionally validates config-change event configs match as well

This reduces test complexity from ~260 lines to ~40 lines while maintaining
coverage of the critical functionality.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Configure manifests to run app-extended-heartbeat tests only on Node.js
for initial validation:

- Enable Node.js: *ref_5_0_0 (>=5.0.0)
- Disable Python: v2.0.0 -> missing_feature
- Disable Java: v1.40.0 -> missing_feature
- Keep all others disabled: missing_feature (cpp, dotnet, php, golang, ruby)

This allows focused testing of Node.js implementation before enabling
other languages.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add SLF001 exception for test_telemetry.py to allow _get_telemetry_event usage
- Fix nodejs.yml manifest to use '>=5.0.0' instead of non-existent anchor
- All linting checks now pass (mypy, ruff, yamlfmt, yamllint, shellcheck)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@datadog-official

This comment has been minimized.

Java tracer supports configurable extended heartbeat interval via
DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL, so enable the parametric
tests.
khanayan123 and others added 3 commits March 30, 2026 22:12
Resolve merge conflicts in manifests/java.yml, manifests/ruby.yml,
and tests/parametric/test_telemetry.py. Keep Test_ExtendedHeartbeat
additions while incorporating main's telemetry key normalization
and stable configuration origin updates.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Revert pyproject.toml changes (not needed for this PR) and remove
DD_TELEMETRY_HEARTBEAT_INTERVAL from Test_ExtendedHeartbeat since
we only need to configure the extended heartbeat interval.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use integer interval (1s) for Java compatibility (getLong)
- Assert configs as superset with value matching, order-agnostic
- Build expected config from app-started + config-change overlay
- Collect all config-change events, not just the last one

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
gh-worker-dd-mergequeue-cf854d Bot pushed a commit to DataDog/dd-trace-py that referenced this pull request Mar 31, 2026
…eat payload (#17203)

## Summary
Fix the extended heartbeat payload key from `"configurations"` (plural) to `"configuration"` (singular) to match the [telemetry v2 API spec](https://github.com/DataDog/instrumentation-telemetry-api-docs/blob/main/GeneratedDocumentation/ApiDocs/v2/SchemaDocumentation/Schemas/app_extended_heartbeat.md) and align with other SDKs (Java, .NET, Node.js).

## Changes
- **`ddtrace/internal/telemetry/writer.py`**: `payload["configurations"]` → `payload["configuration"]`
- **`tests/telemetry/test_telemetry.py`**: Updated test assertions to match

## Motivation
Cross-SDK system tests validate that `app-extended-heartbeat` payloads use the same schema. The spec and all other SDKs use `"configuration"` (singular). This mismatch would cause system test & dropped telemetry payloads failures for Python.

## Related
- System test PR: DataDog/system-tests#6338
- Original Python implementation: #16628

Co-authored-by: ayan.khan <ayan.khan@datadoghq.com>
khanayan123 and others added 2 commits March 31, 2026 15:23
Resolve merge conflict in manifests/ruby.yml (kept both
Test_ExtendedHeartbeat and updated Test_Stable_Configuration_Origin).
Fix ruff lint issues: D209 docstring closing quotes and SLF001
private member access noqa annotations in test_telemetry.py.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@cbeauchesne cbeauchesne left a comment

Choose a reason for hiding this comment

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

There is already test on heartbeats in DEFAULT scenario.

If you plan to test only one or two set of parameters, then the end-to-end DEFAULT scenario is a best fit from a quality POV as the coverage is by far more complete.

We can chat more about what are the good/bad use cases for parametric/end-to-end if you want, just ping me !

gh-worker-dd-mergequeue-cf854d Bot pushed a commit to DataDog/libdatadog that referenced this pull request Apr 1, 2026
…cheduler (#1824)

## Summary
Wire up the `DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL` config value to the telemetry scheduler. The env var was already parsed into `config.telemetry_extended_heartbeat_interval` but the scheduler hardcoded `Duration::from_secs(60 * 60 * 24)` instead of using it.

Default remains 24h this only enables system tests to use a shorter interval to validate the `app-extended-heartbeat` event fires correctly.

## Changes
- **`libdd-telemetry/src/worker/mod.rs`**: Replace hardcoded `60 * 60 * 24` with `config.telemetry_extended_heartbeat_interval`

## Motivation
Cross-SDK system tests need to set a short extended heartbeat interval (e.g., 2s) to validate parity of the `app-extended-heartbeat` telemetry event across all SDKs. Without this fix, PHP and other libdatadog consumers cannot be system-tested for this feature.

## Related
- System test PR: DataDog/system-tests#6338

Co-authored-by: edmund.kump <edmund.kump@datadoghq.com>
khanayan123 and others added 4 commits April 1, 2026 09:56
Add Test_ExtendedHeartbeat to tests/test_telemetry.py for the DEFAULT
scenario, validating that extended heartbeat config is a superset of
app-started plus any config changes. Set DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL
env var in weblog containers. Add manifest entries for all libraries.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move DD_TELEMETRY_EXTENDED_HEARTBEAT_INTERVAL from base container
env to the DEFAULT scenario weblog_env where it belongs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The extended heartbeat validation is better suited as an end-to-end
test in the DEFAULT scenario where it exercises the full tracer stack.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@khanayan123 khanayan123 requested review from cbeauchesne, paullegranddc and zacharycmontoya and removed request for a team April 22, 2026 15:59
doc="Test env var `DD_TELEMETRY_METRICS_ENABLED=false`",
scenario_groups=[scenario_groups.telemetry],
)
telemetry_extended_heartbeat = EndToEndScenario(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

you need to add this scenario in .github/workflows/run-end-to-end.yml

Copy link
Copy Markdown
Contributor Author

@khanayan123 khanayan123 Apr 22, 2026

Choose a reason for hiding this comment

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

Added in 4f7f76e — the TELEMETRY_EXTENDED_HEARTBEAT step is now registered between TELEMETRY_ENHANCED_CONFIG_REPORTING and TELEMETRY_LOG_GENERATION_DISABLED.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 49f6dc1a56

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

scenario_groups=[scenario_groups.telemetry],
)
telemetry_extended_heartbeat = EndToEndScenario(
"TELEMETRY_EXTENDED_HEARTBEAT",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Wire TELEMETRY_EXTENDED_HEARTBEAT into end-to-end CI

This adds a new TELEMETRY_EXTENDED_HEARTBEAT scenario and binds Test_ExtendedHeartbeat to it, but the end-to-end workflow is not updated to execute that scenario: in .github/workflows/run-end-to-end.yml the telemetry section only runs TELEMETRY_APP_STARTED_PRODUCTS_DISABLED, TELEMETRY_ENHANCED_CONFIG_REPORTING, TELEMETRY_LOG_GENERATION_DISABLED, TELEMETRY_METRIC_GENERATION_DISABLED, and TELEMETRY_DEPENDENCY_LOADED_TEST_FOR_DEPENDENCY_COLLECTION_DISABLED. That means the new test path is effectively untested in CI, so regressions in this feature can merge without detection.

Useful? React with 👍 / 👎.

Addresses review feedback — the new scenario needs a step in
.github/workflows/run-end-to-end.yml so CI can actually run it.
Comment thread manifests/cpp_nginx.yml Outdated
tests/test_standard_tags.py: irrelevant
tests/test_telemetry.py::Test_APMOnboardingInstallID: '>=1.12.0' # Modified by easy win activation script
tests/test_telemetry.py::Test_DependencyEnable: '>=1.12.0' # Modified by easy win activation script
tests/test_telemetry.py::Test_ExtendedHeartbeat: ">1.14.0"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't expect this to work, as nginx-datadog has not received an update of its dd-trace-cpp since the app-extended-heartbeat telemetry event was implemented in DataDog/dd-trace-cpp@1603dce

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch — addressed in c78fad7. Marked Test_ExtendedHeartbeat as missing_feature for both cpp_nginx and cpp_httpd until those modules pick up a dd-trace-cpp release that includes the implementation. CI was indeed failing with app-extended-heartbeat event not found on cpp_nginx as you predicted.

Address CI failures across cpp_nginx, cpp_httpd, dotnet, golang, java
(spring-boot-3-native), and php for the new TELEMETRY_EXTENDED_HEARTBEAT
scenario:

- cpp_nginx / cpp_httpd: nginx-datadog and httpd-datadog have not yet
  shipped a release that includes the dd-trace-cpp commit implementing
  app-extended-heartbeat (per zacharycmontoya feedback)
- dotnet: extended-heartbeat payload contains configs missing the
  required `value` field, failing schema validation
- golang: extended-heartbeat only includes app-started configs, not
  app-client-configuration-change configs
- java spring-boot-3-native: native image doesn't capture app-started
  telemetry event
- php: telemetry runs via a sidecar process that does not emit
  app-extended-heartbeat events yet
gh-worker-dd-mergequeue-cf854d Bot pushed a commit to DataDog/libdatadog that referenced this pull request May 5, 2026
## Bug

`ExtendedHeartbeat` is in the scheduler's `delays` catalog but never gets a deadline, so its handler never fires and `app-extended-heartbeat` is never emitted by any libdatadog-based tracer.

`Scheduler::new` initializes `deadlines: Vec::new()`. `next_deadline()` only reads `deadlines`. Events must be moved from `delays` → `deadlines` via `schedule_event(event)`. `Lifecycle(Start)` only scheduled `FlushMetricAggr` + `FlushData`; the `ExtendedHeartbeat` handler self-reschedules but needs a first fire to do so — chicken-and-egg.

Hidden until now because the default interval is 24h, and prior to #1824 it was hardcoded to 24h regardless of config. Surfaced by [system-tests PR 6338](DataDog/system-tests#6338) (`TELEMETRY_EXTENDED_HEARTBEAT` scenario, 2s interval).

## Fix

Schedule `ExtendedHeartbeat` alongside the others in `dispatch_action`'s `Lifecycle(Start)`.

## Tests

- `full_flavor_start_schedules_every_periodic_action` — invariant: walks `delays`, asserts each is in `deadlines` after Start. Catches the whole class of bug, not just this variant. Verified to fail without the fix and pass with it.
- `metrics_logs_flavor_start_does_not_schedule_extended_heartbeat` — negative guard locking in the `MetricsLogs` flavor's intentional exclusion of lifecycle events.

Both are `#[cfg_attr(miri, ignore)]` since they exercise reqwest.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: bob.weinand <bob.weinand@datadoghq.com>
khanayan123 and others added 8 commits May 6, 2026 14:05
… dotnet

Aligns the v2 telemetry schema with the just-merged authoritative spec
in DataDog/instrumentation-telemetry-api-docs#124, which dropped `value`
from the `required` list because backend ingest (UKV, EVP) silently
accepts a missing `value` and stores it as an empty string.

- tests/schemas/utils/miscs/telemetry/v2/objects/configuration.json:
  remove `value` from `required`.
- tests/schemas/test_schemas.py: remove the two golang SchemaBug entries
  at `$.payload.configuration[].value` (ticket APMS-12697) — these
  worked around the now-relaxed schema and are no longer needed.
- manifests/dotnet.yml: flip Test_ExtendedHeartbeat from missing_feature
  to v3.39.0 — the dotnet implementation has shipped (dd-trace-dotnet#8227,
  in v3.39.0+) and the schema-mismatch blocker is gone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All three upstream blockers landed:

- golang: dd-trace-go#4633 (fix(telemetry): app-extended-heartbeat
  event not correctly reporting entire config state) shipped in
  v2.8.0 (2026-05-04). Configs from app-client-configuration-change
  now flow into the extended heartbeat.

- cpp_nginx: nginx-datadog v1.16.1 (2026-05-07) bumps to
  dd-trace-cpp v2.1.0, which includes dd-trace-cpp#301 implementing
  app-extended-heartbeat.

- cpp_httpd: httpd-datadog v1.0.5 (2026-05-07) bumps to dd-trace-cpp
  v2.1.0, same as above.

CI install scripts already pull latest releases for both cpp modules,
so no Dockerfile or pinning changes are needed.

php and java spring-boot-3-native remain missing_feature: php awaits
libdatadog#1910 in a release (not in v32.0.0); spring-boot-3-native
has a separate native-image limitation around app-started capture.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The manifest validator requires NPM-style semver ranges without the
'v' prefix. '>=v2.8.0' was rejected as 'Invalid NPM block'. Use
'>=2.8.0' instead — matches the convention used in adjacent entries
(e.g. cpp_nginx '>=1.16.1', cpp_httpd '>1.0.4').
Both upstream blockers landed:

- libdatadog v33.0.0 (2026-05-07) includes #1910 "schedule
  ExtendedHeartbeat on worker start" — the sidecar now actually emits
  the event.
- dd-trace-php#3865 (merged 2026-05-11) bumped the libdatadog
  submodule past v33.0.0 to also include #1962 "include dependencies
  and integrations in app-extended-heartbeat".

#3865 is post-1.19.2, so gate at >=1.20.0 (the next release).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Invert the weblog matrix from "enable all, except spring-boot-3-native"
to "disable all, except spring-boot". The test exercises a single
canonical weblog rather than implicitly running against every
spring-boot-* and unrelated variants (vertx3, play, resteasy-netty3,
akka-http, openliberty, payara, jetty, undertow).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PHP v1.20.0 emits null for dependencies[].version in the
app-extended-heartbeat payload, failing schema validation in
Test_DdtraceSchemas:

  None is not of type 'string' on instance
    $.payload.dependencies[12].version

The dependencies are populated in the extended heartbeat (per
libdatadog#1962), but the version field is null for at least some
entries. This is a real PHP tracer bug — disable the test until
dd-trace-php emits valid versions.
@khanayan123 khanayan123 marked this pull request as ready for review May 12, 2026 16:40
@khanayan123
Copy link
Copy Markdown
Contributor Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4aabacfb75

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/run-end-to-end.yml Outdated
The step was added with always(), but always() evaluates true even
when the workflow is cancelled — keeping the step running and burning
runner time after a cancel. All surrounding scenario steps use
!cancelled() for exactly this reason. Match the convention.
@khanayan123 khanayan123 merged commit e252036 into main May 13, 2026
2100 checks passed
@khanayan123 khanayan123 deleted the ayan.khan/app-extended-heartbeat branch May 13, 2026 13:46
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