Skip to content

test(otel/pernode): per-node, CRD-bundling and scraper-routing E2E suites - #773

Open
Aakash-Dantre wants to merge 1 commit into
aws:mainfrom
Aakash-Dantre:smpm/pernode-routing-e2e
Open

Aakash-Dantre wants to merge 1 commit into
aws:mainfrom
Aakash-Dantre:smpm/pernode-routing-e2e

Conversation

@Aakash-Dantre

@Aakash-Dantre Aakash-Dantre commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

End-to-end coverage for the Target Allocator ServiceMonitor/PodMonitor work: per-node allocation, zero-step CRD bundling, Target Allocator resilience when the SM/PM CRDs are absent, and annotation-based routing of monitors between the per-node and cluster-scraper agents.

Supersedes #720 and #724, combined and re-applied onto current main. #724 as it stands was committed from an older tree, so it also deletes 77 files that exist on main (including the Azure VM/AKS suites and test/e2e/containerinsights) and rolls back later changes to others. This PR carries only the new files and is purely additive: 14 files, +1685/-0.

What

Path Contents
test/otel/pernode/ per_node, crd_bundling, ta_resilience, scraper_routing, metrics tests + k8s helpers and workload manifests
terraform/eks/daemon/otel-pernode/ EKS harness for the suite. Images and prometheusScrape are set through chart values, so the suite exercises the chart as shipped (no post-install CR patch).

All suites carry the integration build tag.

Test Verifies
TestPerNodeAllocation, TestPerNodeCoverageAcrossNodes asserted at the per-node Target Allocator, for both the ServiceMonitor and PodMonitor paths: every target it hands out is assigned to the agent pod on the same node as the scraped pod, each running workload pod is assigned exactly once, and targets span more than one node
TestServiceMonitorPodMonitorCRDsBundled the chart installs the SM/PM CRDs and they are owned by this Helm release
TestTargetAllocatorHealthyOnBundledInstall, TestTargetAllocatorDiscoversMonitors with the bundled CRDs present, the Target Allocator is healthy and discovers monitors, confirmed by workload metrics reaching CloudWatch. This does not cover the missing-CRD path, which the operator's unit tests do.
TestScraperRoleWiring the cluster-scraper agent CR carries scraperRole=cluster-scraper; the per-node agent carries the default role
TestClusterScraperTargetAllocatorHealthy the cluster-scraper Target Allocator Deployment is Available and not crashlooping
TestAnnotationRoutingPartition at each Target Allocator's /jobs, the annotated monitor is owned only by the cluster-scraper TA and the unannotated one only by the per-node TA

Running

Against a cluster with the operator and chart changes below deployed:

KUBECONFIG=... CLUSTER_NAME=<cluster> AWS_REGION=<region> \
  go test -tags integration ./test/otel/pernode/... -v

Not yet wired into CI

The suites are not registered in generator/ or any workflow, so they do not run in CI as submitted. An earlier revision edited generator/resources/ec2_linux_test_matrix.json and generator/test_case_generator.go, but those edits were reverts of later main changes rather than a new matrix entry, so they are not carried here. A matrix entry for an EKS target is the remaining follow-up.

Dependencies

Exercises these, which must be deployed first:


PR Checklist

  • Commits are squashed into a logical, reviewable set (one commit for a single change) - one commit.
  • Commits and PR description comply with the contribution guidelines - no internal references in the commit message or this description.
  • make passes locally - this repo has no make target for test packages. go vet -tags integration ./test/otel/pernode/... is clean on this commit. Repo-wide go vet ./... fails identically on main (unkeyed struct literals in test/metric_dimension); that is not introduced here.
  • All GitHub Actions checks on the PR are passing - none have run yet; workflow runs on fork PRs need a maintainer to approve them.
  • Integration test evidence - run against an EKS 1.34 cluster (3 nodes) running images built from the operator PRs and the chart PR: 7 of 8 pass. TestServiceMonitorPodMonitorCRDsBundled does not apply to that cluster, because kube-prometheus-stack already owns the SM/PM CRDs and the chart correctly leaves them alone. Switching the per-node TA to consistent-hashing makes TestPerNodeAllocation fail on a cross-node assignment, so the test detects the case it is meant to. Not yet run through the Terraform harness or CI (not in the test matrix, see above).
  • New or updated integration test coverage - this PR is the integration test coverage for the operator and chart PRs above.
  • New functionality has unit tests; behaviour changes have a reproducing test - N/A: test-only change.
  • Config translation changes include updated golden files - N/A: no translator changes.
  • Breaking or customer-visible changes are called out in the PR description - none. Test-only and purely additive; no existing test is modified or removed.

Comment thread test/otel/pernode/per_node_test.go Outdated
}

// Core per-node invariant: scraped by the agent on the pod's own node.
if targetNode != agentNode {

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 think this can detect cross-node scraping. The Prometheus receiver sets resource k8s.node.name from the scraped target's discovery labels (__meta_kubernetes_pod_node_name; see addKubernetesResource in prometheusreceiver/internal/prom_to_otlp.go), and nothing in the prometheuscr pipeline overwrites it. target_node comes from the same label via the relabel in workload.yaml, so the two are always equal, wherever the series was scraped. The comment on agentNodeResourceKey in metrics_test.go (that it comes from ${env:K8S_NODE_NAME}) doesn't match the pipeline either.

Could we assert allocation at the TA instead? /jobs/<job>/targets?collector_id=<agent pod> returns each collector's targets. Comparing each target's __meta_kubernetes_pod_node_name with that agent pod's spec.nodeName from the K8s API tests the allocator directly, and the /jobs probe pod you already have can do it.

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.

You're right, thanks. In a432c10 it checks allocation at the TA as you suggested: each target's pod node against the assigned agent pod's spec.nodeName. Verified on a live cluster: passes with per-node, fails when switched to consistent-hashing.

done
kubectl -n amazon-cloudwatch patch AmazonCloudWatchAgent cloudwatch-agent --type='json' \
-p='[{"op": "replace", "path": "/spec/image", "value": "${var.cwagent_image_repo}:${var.cwagent_image_tag}"}]'
kubectl -n amazon-cloudwatch patch AmazonCloudWatchAgent cloudwatch-agent --type=merge \

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.

The harness forces allocationStrategy: per-node and the TA image by patching the CR after install, so the suite would still pass if the chart's own per-node wiring regressed. aws-observability/helm-charts#376 already renders per-node by default, and the TA image is a chart value (agent.prometheus.targetAllocator.image.repositoryDomainMap.public / .repository / .tag). The comment at line 196 saying it isn't one is out of date. Could the harness set these through helm_release set entries and drop the CR patch, so the E2E covers the chart as shipped?

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.

Done in a432c10: images and prometheusScrape are set through helm_release values, no CR patch. I'll run the Terraform harness end to end before asking for re-review.

@Aakash-Dantre
Aakash-Dantre force-pushed the smpm/pernode-routing-e2e branch 3 times, most recently from 17d6403 to a432c10 Compare October 2, 2026 14:09
…E suites

Adds the EKS end-to-end coverage for the Target Allocator work: per-node
allocation (asserted at the Target Allocator: every assigned target is on its
agent's node), zero-step CRD bundling, Target Allocator health and monitor
discovery with the bundled CRDs, and annotation-based routing of monitors
between the per-node and cluster-scraper agents.

  test/otel/pernode/            per_node, crd_bundling, ta_resilience,
                                scraper_routing, metrics + k8s helpers
  terraform/eks/daemon/otel-pernode/   EKS harness for the suite

Supersedes the earlier per-node-only suite: this branch contains all of it
plus the routing coverage.

The suites are tagged `integration` and are not yet registered in the
generated test matrix, so they do not run in CI until a matrix entry is
added.

The routing /jobs probe presents the agents' Target Allocator client
certificate, because the Target Allocator's HTTPS server requires and
verifies one.

The harness configures the operator and Target Allocator images and
prometheusScrape through chart values rather than patching the agent CR after
install, so the suite exercises the chart's own wiring.
@Aakash-Dantre
Aakash-Dantre force-pushed the smpm/pernode-routing-e2e branch from a432c10 to f18f0d3 Compare October 2, 2026 14: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.

2 participants