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

Merged
merged 21 commits into from
Mar 28, 2025
Merged

Conversation

manu2
Copy link
Contributor

@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 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
Contributor 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();

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done


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?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed.

</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?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We query trace using trace client which requires this dependency.
" trace = client.getTrace(env.getTestHelper().getInstanceId().getProject(), traceId)"


@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";

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.

.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();

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we need to wait for sever side traces which are collected from request on Span FE and asynchronously exported later.

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated.

.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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated.

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TraceClient is created before the block. This is actually the trace, not the client. Updated naming in recent commit to avoid confusion.

@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

@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 25, 2025
@manu2
Copy link
Contributor Author

manu2 commented Mar 25, 2025

@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

The test intents to verify the generation of server side traces when end to end tracing is enabled. Have updated the assertion to validate server side trace.

try {
Trace trace = client.getTrace(env.getTestHelper().getInstanceId().getProject(), traceId);
// Assert Spanner Frontend Trace is present
assertTrue(
Copy link
Contributor

Choose a reason for hiding this comment

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

assertTrue will result into error if the trace is not found and the test will be marked as failed, so the for loop will never actually work. Instead of this , we could try something like below and also remove the 10 second sleep before the loop.

Trace trace = client.getTrace(env.getTestHelper().getInstanceId().getProject(), traceId);
while (trace.getSpansList().stream()
                  .anyMatch(span -> "Spanner.ExecuteStreamingSql".equals(span.getName())
        && metricsPollingStopwatch.elapsed(TimeUnit.SECONDS) < 30) {
      // Try every 5 seconds
      Thread.sleep(5000);
    }
    assertTrue(trace.getSpansList().stream()
                  .anyMatch(span -> "Spanner.ExecuteStreamingSql".equals(span.getName());

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense. If the getTrace calls fails, it throws an APIException. Have kept the catch block to handle it but changed the logic to poll upto 30 sec and sleep for 5 sec if not found.

manu2 and others added 2 commits March 27, 2025 10:04
(cherry picked from commit f47f01a834c80fadf754ed1ceee5179c1bd00deb)
<dependency>
<groupId>com.google.cloud.opentelemetry</groupId>
<artifactId>exporter-trace</artifactId>
<version>0.33.0</version>
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove the version from here. It should either fetch from bom or the latest version

@manu2 manu2 merged commit bf1a07a into googleapis:main Mar 28, 2025
31 of 32 checks passed
svc-squareup-copybara pushed a commit to cashapp/misk that referenced this pull request Mar 31, 2025
| Package | Type | Package file | Manager | Update | Change |
|---|---|---|---|---|---|
|
[com.google.cloud:google-cloud-spanner](https://github.com/googleapis/java-spanner)
| dependencies | misk/gradle/libs.versions.toml | gradle | minor |
`6.89.0` -> `6.90.0` |

---

### Release Notes

<details>
<summary>googleapis/java-spanner
(com.google.cloud:google-cloud-spanner)</summary>

###
[`v6.90.0`](https://github.com/googleapis/java-spanner/blob/HEAD/CHANGELOG.md#6900-2025-03-31)

##### Features

- Add default_isolation_level connection property
([#&#8203;3702](googleapis/java-spanner#3702))
([9472d23](googleapis/java-spanner@9472d23))
- Adds support for Interval datatype in Java client
([#&#8203;3416](googleapis/java-spanner#3416))
([8be8f5e](googleapis/java-spanner@8be8f5e))
- Integration test for End to End tracing
([#&#8203;3691](googleapis/java-spanner#3691))
([bf1a07a](googleapis/java-spanner@bf1a07a))
- Specify isolation level per transaction
([#&#8203;3704](googleapis/java-spanner#3704))
([868f30f](googleapis/java-spanner@868f30f))
- Support PostgreSQL isolation level statements
([#&#8203;3706](googleapis/java-spanner#3706))
([dda2e1d](googleapis/java-spanner@dda2e1d))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 6pm every weekday,before 2am
every weekday" in timezone Australia/Melbourne, Automerge - At any time
(no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://github.com/renovatebot/renovate).

GitOrigin-RevId: a63885015974acb6061bae5ca3b9d61136991376
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: m Pull request size is medium.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants