Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions .github/workflows/otel-conformance-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
name: OTel Conformance Tests

# Per-PR OpenTelemetry conformance run. Reuses the shared orchestrator from
# aws-durable-execution-conformance-tests and points it at this repo's own handlers/templates
# (conformance-tests-otel/) via examples_dir, so the handlers live here while the orchestration
# (backend matrix, ADOT layer, collector build, long-running cycle) stays centralized.
#
# Mirrors the Java preset's language config (setup/prepare commands, ADOT repo, runtime) but calls
# opentelemetry-orchestrator.yml directly, matching the Python SDK's caller.

on:
pull_request:
branches: [main]
paths:
- "sdk/**"
- "otel-plugin/**"
- "conformance-tests-otel/**"
- "pom.xml"
- ".github/workflows/otel-conformance-tests.yml"
push:
branches: [main]
paths:
- "sdk/**"
- "otel-plugin/**"
- "conformance-tests-otel/**"
- "pom.xml"
- ".github/workflows/otel-conformance-tests.yml"
workflow_dispatch:
inputs:
phase:
description: Run short tests, launch a long run, or check the active long run
required: true
default: short
type: choice
options:
- short
- launch
- check
delay_seconds:
description: Durable delay in seconds (1-86400, launch only)
required: true
default: "82800"
type: string
aws_region:
description: AWS region
required: true
default: us-west-2
type: string
conformance_test_ref:
description: Optional conformance test commit SHA or branch name
required: false
type: string

permissions: {}

jobs:
opentelemetry:
permissions:
actions: write
contents: read
id-token: write
uses: aws/aws-durable-execution-conformance-tests/.github/workflows/opentelemetry-orchestrator.yml@0f0b5bda84116ef77034451b9c4c21774e76d8e4
with:
language: java
resource_prefix: j
sdk_repository: aws/aws-durable-execution-sdk-java
sdk_ref: ${{ github.event.pull_request.head.sha || github.sha }}
conformance_test_ref: ${{ inputs.conformance_test_ref || '0f0b5bda84116ef77034451b9c4c21774e76d8e4' }}
checkout_sdk: true
# Build the handlers from this repo's checked-out module instead of the conformance repo's
# bundled examples/java. Path is relative to the conformance workspace where the SDK is
# checked out (.build/durable-sdk).
examples_dir: .build/durable-sdk/conformance-tests-otel

This comment was marked as outdated.

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.

setup_command: |
if [ -z "${JAVA_HOME_21_X64:-}" ]; then
echo "The runner does not provide Java 21"
exit 1
fi
export JAVA_HOME="$JAVA_HOME_21_X64"
export PATH="$JAVA_HOME/bin:$PATH"
java -version
prepare_command: |
JAVA_SDK_VERSION=$(
mvn -B -q \
--file "$SDK_CHECKOUT/pom.xml" \
-Dstyle.color=never \
-Dexpression=project.version \
-DforceStdout \
help:evaluate
)
mvn -B -q \
--file "$SDK_CHECKOUT/pom.xml" \
--projects sdk,otel-plugin \
--also-make \
-DskipTests \
install
echo "Using Java SDK version $JAVA_SDK_VERSION"
echo "JAVA_SDK_VERSION=$JAVA_SDK_VERSION" >> "$GITHUB_ENV"
mvn -B -q -DskipTests package \
-Ddurable.sdk.version="$JAVA_SDK_VERSION" \
--file "$EXAMPLES_DIR/pom.xml"
adot_release_repository: aws-observability/aws-otel-java-instrumentation
collector_compatible_runtime: java21
collector_otlp_endpoint: http://localhost:4318
phase: ${{ inputs.phase || 'short' }}
delay_seconds: ${{ inputs.delay_seconds || '82800' }}
aws_region: ${{ inputs.aws_region || 'us-west-2' }}
secrets:
CONFORMANCE_TEST_ROLE_ARN: ${{ secrets.TEST_ROLE_ARN }}
CONFORMANCE_TEST_ACCOUNT_ID: ${{ secrets.TEST_ACCOUNT_ID }}
CONFORMANCE_TEST_LAMBDA_EXECUTION_ROLE_ARN: ${{ secrets.TEST_LAMBDA_EXECUTION_ROLE_ARN }}
DASH0_AUTH_TOKEN: ${{ secrets.DASH0_AUTH_TOKEN }}
DATADOG_ACCESS_TOKEN: ${{ secrets.DATADOG_ACCESS_TOKEN }}
DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }}
DATADOG_APPLICATION_KEY: ${{ secrets.DATADOG_APPLICATION_KEY }}
121 changes: 121 additions & 0 deletions conformance-tests-otel/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<!--
Standalone project (NOT part of the SDK reactor): the OpenTelemetry conformance workflow
builds this module against an SDK already installed to the local repository, passing the SDK
version through the durable.sdk.version property, and SAM builds the same pom during deploy.
It depends on the SDK and OTel-plugin artifacts by version, not as a reactor sibling,
mirroring the examples/java project in aws-durable-execution-conformance-tests.
-->
<groupId>software.amazon.lambda.durable</groupId>
<artifactId>aws-durable-execution-sdk-java-conformance-tests-otel</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>

<name>AWS Lambda Durable Execution SDK OpenTelemetry Conformance Tests</name>
<description>
Java SDK handlers and SAM templates for the durable execution OpenTelemetry conformance
suite (otel-invocation, otel-execution, and otel-long-running). Built and deployed by the
shared OpenTelemetry conformance workflow.
</description>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.release>17</maven.compiler.release>
<!-- Supplied by the conformance workflow (JAVA_SDK_VERSION), resolved from the built SDK. -->
<durable.sdk.version>${env.JAVA_SDK_VERSION}</durable.sdk.version>
<opentelemetry.version>1.65.0</opentelemetry.version>
<aws.lambda.java.core.version>1.4.0</aws.lambda.java.core.version>
</properties>

<dependencies>
<dependency>
<groupId>software.amazon.lambda.durable</groupId>
<artifactId>aws-durable-execution-sdk-java</artifactId>
<version>${durable.sdk.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.lambda.durable</groupId>
<artifactId>aws-durable-execution-sdk-java-plugin-otel</artifactId>
<version>${durable.sdk.version}</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk</artifactId>
<version>${opentelemetry.version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>${aws.lambda.java.core.version}</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.15.0</version>
</plugin>

<!-- Copy the OTel plugin JAR next to the handlers so it can be loaded as a Java agent
extension via OTEL_JAVAAGENT_EXTENSIONS (see template.yaml). -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.11.0</version>
<executions>
<execution>
<id>copy-otel-javaagent-extension</id>
<phase>prepare-package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>software.amazon.lambda.durable</groupId>
<artifactId>aws-durable-execution-sdk-java-plugin-otel</artifactId>
<version>${durable.sdk.version}</version>
<outputDirectory>${project.build.outputDirectory}/lib</outputDirectory>
<destFileName>otel-plugin-extension.jar</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>

<!-- Shaded (uber) JAR so each Lambda deploys as a single artifact. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.2</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.conformance.otel;

import java.util.Map;
import software.amazon.lambda.durable.DurableContext;

/** Wait-for-callback scenario for OTel requirement otel-invocation-10. */
public final class Otel10WaitForCallback extends OtelConformanceHandler<String> {

@Override
public String handleRequest(Map<String, Object> event, DurableContext context) {
requireScenario(event, "wait-for-callback");
return context.waitForCallback("otel-callback", String.class, (callbackId, step) -> {});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.conformance.otel;

import java.util.Map;
import software.amazon.lambda.durable.DurableContext;
import software.amazon.lambda.durable.TypeToken;

/** Chained-invoke scenario for OTel requirement otel-invocation-11. */
public final class Otel11ChainedInvoke extends OtelConformanceHandler<Map<String, Object>> {

@Override
public Map<String, Object> handleRequest(Map<String, Object> event, DurableContext context) {
requireScenario(event, "chained-invoke");
return context.invoke(
"otel-invoke",
System.getenv("OTEL_INVOKE_TARGET_FUNCTION_NAME"),
event,
new TypeToken<Map<String, Object>>() {});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.conformance.otel;

import java.util.Map;
import software.amazon.lambda.durable.DurableContext;

/** Successful chained-invoke target for OTel requirement otel-invocation-11. */
public final class Otel11InvokeTarget extends OtelConformanceHandler<Map<String, Object>> {

@Override
public Map<String, Object> handleRequest(Map<String, Object> event, DurableContext context) {
return event;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.conformance.otel;

import java.util.Map;
import software.amazon.lambda.durable.DurableContext;

/** Failed child-context scenario for OTel requirement otel-invocation-12. */
public final class Otel12ChildContextFailure extends OtelConformanceHandler<Void> {

@Override
public Void handleRequest(Map<String, Object> event, DurableContext context) {
requireScenario(event, "child-context-failure");
return context.runInChildContext("otel-failed-child-context", Void.class, child -> {
throw new RuntimeException("Intentional child-context failure");
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.conformance.otel;

import java.util.Map;
import software.amazon.lambda.durable.DurableContext;
import software.amazon.lambda.durable.DurableFuture;
import software.amazon.lambda.durable.config.ParallelConfig;

/** Failed parallel-branch scenario for OTel requirement otel-invocation-13. */
public final class Otel13ParallelFailure extends OtelConformanceHandler<Void> {

@Override
public Void handleRequest(Map<String, Object> event, DurableContext context) {
requireScenario(event, "parallel-failure");
var parallel = context.parallel(
"otel-failed-parallel",
ParallelConfig.builder().maxConcurrency(1).build());
DurableFuture<Void> failedBranch;
try (parallel) {
failedBranch = parallel.branch("otel-failed-parallel-branch", Void.class, branch -> {
throw new RuntimeException("Intentional parallel branch failure");
});
}
return failedBranch.get();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.conformance.otel;

import java.util.List;
import java.util.Map;
import software.amazon.lambda.durable.DurableContext;
import software.amazon.lambda.durable.config.MapConfig;

/** Failed map-iteration scenario for OTel requirement otel-invocation-14. */
public final class Otel14MapFailure extends OtelConformanceHandler<Void> {

@Override
public Void handleRequest(Map<String, Object> event, DurableContext context) {
requireScenario(event, "map-failure");
var result = context.map(
"otel-failed-map",
List.of(1),
Void.class,
(item, index, iteration) -> {
throw new RuntimeException("Intentional map iteration failure");
},
MapConfig.builder().maxConcurrency(1).build());
if (!result.allSucceeded()) {
throw new RuntimeException("Intentional map failure");
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.conformance.otel;

import java.time.Duration;
import java.util.Map;
import software.amazon.lambda.durable.DurableContext;

/** Interrupted wait scenario for OTel requirement otel-invocation-15. */
public final class Otel15WaitInterrupted extends OtelConformanceHandler<Void> {

@Override
public Void handleRequest(Map<String, Object> event, DurableContext context) {
requireScenario(event, "wait-interrupted");
return context.wait("otel-interrupted-wait", Duration.ofSeconds(30));
}
}
Loading
Loading