Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Integration test for End to End tracing #3691

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

manu2
Copy link

@manu2 manu2 commented Mar 18, 2025

With End to End tracing, customers are able to view server side traces. The new integration tests aims to verify this from a client side pov.
Note: Currently the InegrationTestEnv sets up default interceptor which in turns creates a default GlobalOpenTelementry sdk. This sdk is then injected to the gRPC connection builder and stud. So a new opentelemetry sdk has been created in IntegrationTestEnv that sets up the required config for End to End Testing and will be used by default for all integration tests.

manu2 and others added 5 commits March 12, 2025 09:19
@manu2 manu2 requested review from a team as code owners March 18, 2025 08:53
@product-auto-label product-auto-label bot added size: m Pull request size is medium. api: spanner Issues related to the googleapis/java-spanner API. labels Mar 18, 2025
@manu2 manu2 changed the title Integration test for End to End tracing feat: Integration test for End to End tracing Mar 18, 2025
@product-auto-label product-auto-label bot added size: l Pull request size is large. and removed size: m Pull request size is medium. labels Mar 18, 2025
@product-auto-label product-auto-label bot added size: m Pull request size is medium. and removed size: l Pull request size is large. labels Mar 18, 2025
@manu2
Copy link
Author

manu2 commented Mar 19, 2025

Looking through the details of the failure in Kokoro - Test: Integration with Directpath using the following target log

Many of the tests seem to be facing "com.google.api.gax.rpc.PermissionDeniedException: io.grpc.StatusRuntimeException: PERMISSION_DENIED: The caller does not have permission" when on trace exporter.
However in case of ITEndToEndTracingTest, we have a assertion on whether the traces are present in cloud trace, which is causing an assertion failure.

So the underlying issue regarding permission denied for trace export is not related to this change but is causing failure in the new test introduced.

@product-auto-label product-auto-label bot added size: l Pull request size is large. and removed size: m Pull request size is medium. labels Mar 19, 2025
traceConfigurationBuilder.setProjectId(options.getProjectId()).build());

String serviceName =
"java-spanner-jdbc-integration-tests-" + ThreadLocalRandom.current().nextInt();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
"java-spanner-jdbc-integration-tests-" + ThreadLocalRandom.current().nextInt();
"java-spanner-integration-tests-" + ThreadLocalRandom.current().nextInt();


static {
SpannerOptionsHelper.resetActiveTracingFramework();
SpannerOptions.enableOpenTelemetryMetrics();
Copy link
Collaborator

Choose a reason for hiding this comment

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

why do we need to enable metrics?

</dependency>
<dependency>
<groupId>com.google.api.grpc</groupId>
<artifactId>proto-google-cloud-trace-v1</artifactId>
Copy link
Collaborator

Choose a reason for hiding this comment

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

why are we adding this?


@Before
public void initSelectValueQuery() {
selectValueQuery = "SELECT @p1 + @p1 ";
Copy link
Collaborator

Choose a reason for hiding this comment

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

can you initialize selectValueQuery as a static variable?

private static final String selectValueQuery = "SELECT @p1 + @p1";

.build();
try (TraceServiceClient client = TraceServiceClient.create(settings)) {
// It can take a few seconds before the trace is visible.
Thread.sleep(5000L);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there any better way to know that trace is exported? I just wanted to make sure this is not flakky

Copy link
Contributor

Choose a reason for hiding this comment

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

Do a forceflush(), instead of adding a sleep.

sdkTracerProvider.forceFlush();

clientTrace.getSpansList().stream()
.anyMatch(
span ->
"CloudSpannerOperation.ExecuteStreamingQuery".equals(span.getName())));
Copy link
Contributor

Choose a reason for hiding this comment

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

We are only asserting on Client Trace and not on server trace?

.build();
try (TraceServiceClient client = TraceServiceClient.create(settings)) {
// It can take a few seconds before the trace is visible.
Thread.sleep(5000L);
Copy link
Contributor

Choose a reason for hiding this comment

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

Do a forceflush(), instead of adding a sleep.

sdkTracerProvider.forceFlush();

OpenTelemetrySdk.builder()
.setTracerProvider(sdkTracerProvider)
.setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
.buildAndRegisterGlobal();
Copy link
Contributor

Choose a reason for hiding this comment

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

Do not register the tracerProvider at global, instead inject OpenTelemerty object via spanner options.

If we register it globally, we might start seeing traces coming from other parallel integration tests as enableOpenTelemetryTraces is a static method.

// The gRPC stub and connections are created during test env set up using SpannerOptions and
// are
// reused for executing statements.
options = spannerOptionsWithEndToEndTracing(options);
Copy link
Contributor

Choose a reason for hiding this comment

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

This configuration should move to GceTestEnvConfig class where the SpannerOptions is build.

We should add a systemproperty for "End to end tracing" and use it to initialize and set opentelemetry object with tracer provider.

Refer this to see how we are enabling Direct Path in test cases , based on system property.

Copy link
Contributor

Choose a reason for hiding this comment

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

@sakthivelmanii I think if there is only going to be single test for "End to end Tracing", then we might create a new Spanner Object in the Test directly.

Or maybe extend IntegrationTestEnv class and use it.

WDYT?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Agree. We should probably handle it through system property like how we handled in other places.

boolean foundTrace = false;
for (int attempts = 0; attempts < 2; attempts++) {
try {
Trace clientTrace =
Copy link
Contributor

Choose a reason for hiding this comment

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

Create the traceClient in "before" block

@surbhigarg92
Copy link
Contributor

@manu2 I don't understand the need for this Integration test. Do we want to verify server traces as I don't see that in the assert?
Client traces could be verified with InMemoryExporter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: spanner Issues related to the googleapis/java-spanner API. size: l Pull request size is large.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants