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

test(codegen): add unit tests for one generated starter module #1355

Merged
merged 12 commits into from
Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from 9 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,350 @@
/*
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.cloud.language.v1.spring;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

import com.google.api.gax.core.CredentialsProvider;
import com.google.api.gax.core.InstantiatingExecutorProvider;
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
import com.google.api.gax.retrying.RetrySettings;
import com.google.api.gax.rpc.ApiCallContext;
import com.google.api.gax.rpc.TransportChannel;
import com.google.api.gax.rpc.TransportChannelProvider;
import com.google.auth.Credentials;
import com.google.auth.oauth2.ServiceAccountCredentials;
import com.google.cloud.language.v1.LanguageServiceClient;
import com.google.cloud.language.v1.LanguageServiceSettings;
import com.google.cloud.spring.autoconfigure.core.GcpContextAutoConfiguration;
import java.io.IOException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.threeten.bp.Duration;

@ExtendWith(MockitoExtension.class)
class LanguageAutoConfigurationTests {

private static final String SERVICE_CREDENTIAL_LOCATION =
"src/test/resources/fake-credential-key.json";
private static final String TOP_LEVEL_CREDENTIAL_LOCATION =
"src/test/resources/fake-credential-key-2.json";
private static final String SERVICE_CREDENTIAL_CLIENT_ID = "45678";
private static final String TOP_LEVEL_CREDENTIAL_CLIENT_ID = "12345";
private static final String SERVICE_OVERRIDE_CLIENT_ID = "56789";

@Mock private TransportChannel mockTransportChannel;
@Mock private ApiCallContext mockApiCallContext;
@Mock private TransportChannelProvider mockTransportChannelProvider;
@Mock private CredentialsProvider mockCredentialsProvider;

private ApplicationContextRunner contextRunner =
new ApplicationContextRunner()
.withConfiguration(
AutoConfigurations.of(
GcpContextAutoConfiguration.class, LanguageServiceSpringAutoConfiguration.class));

@Test
void testLanguageServiceClientCreated() {
this.contextRunner.run(
ctx -> {
LanguageServiceClient client = ctx.getBean(LanguageServiceClient.class);
assertThat(client).isNotNull();
});
}

@Test
void testCredentials_fromServicePropertiesIfSpecified() {
this.contextRunner
.withPropertyValues(
"spring.cloud.gcp.credentials.location=file:" + TOP_LEVEL_CREDENTIAL_LOCATION,
"com.google.cloud.language.v1.language-service.credentials.location=file:"
+ SERVICE_CREDENTIAL_LOCATION)
.run(
ctx -> {
LanguageServiceClient client = ctx.getBean(LanguageServiceClient.class);
Credentials credentials =
client.getSettings().getCredentialsProvider().getCredentials();
assertThat(((ServiceAccountCredentials) credentials).getClientId())
.isEqualTo(SERVICE_CREDENTIAL_CLIENT_ID);
});
}

@Test
void testCredentials_fromTopLevelIfNoServiceProperties() {
this.contextRunner
.withPropertyValues(
"spring.cloud.gcp.credentials.location=file:" + TOP_LEVEL_CREDENTIAL_LOCATION)
.run(
ctx -> {
LanguageServiceClient client = ctx.getBean(LanguageServiceClient.class);
Credentials credentials =
client.getSettings().getCredentialsProvider().getCredentials();
assertThat(((ServiceAccountCredentials) credentials).getClientId())
.isEqualTo(TOP_LEVEL_CREDENTIAL_CLIENT_ID);
});
}

@Test
void testShouldUseDefaultTransportChannelProvider() {
Copy link
Contributor

Choose a reason for hiding this comment

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

For the sake of coverage, you might also want to add a testCustomTransportChannelProviderSetToRest?
when property "com.google.cloud.language.v1.language-service.useRest=true" present,
we should expect the transportChannelProvider set to

LanguageServiceSettings.defaultHttpJsonTransportProviderBuilder().build();

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for this suggestion and added! I think it also addresses what I missed earlier in #1355 (comment).

this.contextRunner.run(
ctx -> {
LanguageServiceClient client = ctx.getBean(LanguageServiceClient.class);
TransportChannelProvider transportChannelProvider =
client.getSettings().getTransportChannelProvider();
TransportChannelProvider defaultTransportChannelprovider =
LanguageServiceSettings.defaultTransportChannelProvider();
assertThat(transportChannelProvider)
.usingRecursiveComparison()
.isEqualTo(defaultTransportChannelprovider);
});
}

@Test
void testQuotaProjectIdFromProperties() {
this.contextRunner
.withPropertyValues(
"com.google.cloud.language.v1.language-service.quota-project-id="
+ SERVICE_OVERRIDE_CLIENT_ID)
.run(
ctx -> {
LanguageServiceClient client = ctx.getBean(LanguageServiceClient.class);
String quotaProjectId = client.getSettings().getQuotaProjectId();
assertThat(quotaProjectId).isEqualTo(SERVICE_OVERRIDE_CLIENT_ID);
});
}

@Test
void testExecutorThreadCountFromProperties() {
Integer customExecutorThreadCount = 3;
this.contextRunner
.withPropertyValues(
"com.google.cloud.language.v1.language-service.executor-thread-count="
+ customExecutorThreadCount.toString())
.run(
ctx -> {
LanguageServiceClient client = ctx.getBean(LanguageServiceClient.class);
InstantiatingExecutorProvider backgroundExecutorProvider =
((InstantiatingExecutorProvider)
client.getSettings().getBackgroundExecutorProvider());
assertThat(backgroundExecutorProvider.toBuilder().getExecutorThreadCount())
.isEqualTo(customExecutorThreadCount);
});
}

@Test
void testCustomTransportChannelProviderUsedWhenProvided() throws IOException {
when(mockTransportChannelProvider.getTransportName()).thenReturn("grpc");
when(mockTransportChannelProvider.getTransportChannel()).thenReturn(mockTransportChannel);
when(mockTransportChannel.getEmptyCallContext()).thenReturn(mockApiCallContext);
when(mockApiCallContext.withCredentials(any())).thenReturn(mockApiCallContext);
when(mockApiCallContext.withTransportChannel(any())).thenReturn(mockApiCallContext);

contextRunner
.withBean(
"defaultLanguageServiceTransportChannelProvider",
TransportChannelProvider.class,
() -> mockTransportChannelProvider)
.run(
ctx -> {
LanguageServiceClient client = ctx.getBean(LanguageServiceClient.class);
assertThat(client.getSettings().getTransportChannelProvider())
.isSameAs(mockTransportChannelProvider);
});
}

@Test
void testCustomServiceSettingsUsedWhenProvided() throws IOException {
LanguageServiceSettings customLanguageServiceSettings =
LanguageServiceSettings.newBuilder()
.setCredentialsProvider(mockCredentialsProvider)
.setQuotaProjectId(SERVICE_OVERRIDE_CLIENT_ID)
.build();
contextRunner
.withBean(
"languageServiceSettings",
LanguageServiceSettings.class,
() -> customLanguageServiceSettings)
.run(
ctx -> {
LanguageServiceClient client = ctx.getBean(LanguageServiceClient.class);
assertThat(client.getSettings()).isSameAs(customLanguageServiceSettings);
});
}

@Test
void testRetrySettingsFromProperties_serviceLevel() {
Double customMultiplier = 2.0;
String customDurationString = "PT0.9S";
Duration customDuration = Duration.ofMillis(900);
Duration defaultDurationExpected = Duration.ofMillis(100);
this.contextRunner
.withPropertyValues(
"com.google.cloud.language.v1.language-service.retry.retry-delay-multiplier="
+ customMultiplier.toString(),
"com.google.cloud.language.v1.language-service.retry.max-retry-delay="
+ customDurationString)
.run(
ctx -> {
LanguageServiceClient client = ctx.getBean(LanguageServiceClient.class);

RetrySettings analyzeSentimentRetrySettings =
client.getSettings().analyzeSentimentSettings().getRetrySettings();
assertThat(analyzeSentimentRetrySettings.getRetryDelayMultiplier())
.isEqualTo(customMultiplier);
assertThat(analyzeSentimentRetrySettings.getMaxRetryDelay())
.isEqualTo(customDuration);
// if properties only override certain retry settings, others should still take on
// client library defaults
assertThat(analyzeSentimentRetrySettings.getInitialRetryDelay())
.isEqualTo(defaultDurationExpected);
});
}

@Test
void testRetrySettingsFromProperties_serviceAndMethodLevel() {
Double customServiceMultiplier = 2.0;
Double customMethodMultiplier = 3.0;
String customDurationString = "PT0.9S";
Duration customDuration = Duration.ofMillis(900);
Duration defaultDurationExpected = Duration.ofMillis(100);
this.contextRunner
.withPropertyValues(
"com.google.cloud.language.v1.language-service.retry.retry-delay-multiplier="
+ customServiceMultiplier.toString(),
"com.google.cloud.language.v1.language-service.retry.max-retry-delay="
+ customDurationString,
"com.google.cloud.language.v1.language-service.annotate-text-retry.retry-delay-multiplier="
+ customMethodMultiplier.toString())
.run(
ctx -> {
LanguageServiceClient client = ctx.getBean(LanguageServiceClient.class);

RetrySettings annotateTextRetrySettings =
client.getSettings().annotateTextSettings().getRetrySettings();
// Method-level override should take precedence over service-level
assertThat(annotateTextRetrySettings.getRetryDelayMultiplier())
.isEqualTo(customMethodMultiplier);
// For settings without method-level overrides but when service-level is provided,
// fall back to that
assertThat(annotateTextRetrySettings.getMaxRetryDelay()).isEqualTo(customDuration);
// Settings with neither method not service-level overrides should still take on
// client library defaults
assertThat(annotateTextRetrySettings.getInitialRetryDelay())
.isEqualTo(defaultDurationExpected); // default
});
}

@Test
void testRetrySettingsFromProperties_serviceAndMethodLevel_allRetrySettings() {
Double customServiceMultiplier = 2.0;
String customServiceDurationString = "PT0.5S";
Duration customServiceDuration = Duration.ofMillis(500);
Integer customServiceMaxAttempts = 2;

Double customMethodMultiplier = 3.0;
String customMethodDurationString = "PT0.6S";
Duration customMethodDuration = Duration.ofMillis(600);
Integer customMethodMaxAttempts = 3;

this.contextRunner
.withPropertyValues(
// service-level, all configurable settings
"com.google.cloud.language.v1.language-service.retry.retry-delay-multiplier="
+ customServiceMultiplier.toString(),
"com.google.cloud.language.v1.language-service.retry.rpc-timeout-multiplier="
+ customServiceMultiplier.toString(),
"com.google.cloud.language.v1.language-service.retry.initial-retry-delay="
+ customServiceDurationString,
"com.google.cloud.language.v1.language-service.retry.max-retry-delay="
+ customServiceDurationString,
"com.google.cloud.language.v1.language-service.retry.initial-rpc-timeout="
+ customServiceDurationString,
"com.google.cloud.language.v1.language-service.retry.max-rpc-timeout="
+ customServiceDurationString,
"com.google.cloud.language.v1.language-service.retry.total-timeout="
+ customServiceDurationString,
"com.google.cloud.language.v1.language-service.retry.max-attempts="
+ customServiceMaxAttempts.toString(),
// method-level, all configurable settings
"com.google.cloud.language.v1.language-service.annotate-text-retry.retry-delay-multiplier="
+ customMethodMultiplier.toString(),
"com.google.cloud.language.v1.language-service.annotate-text-retry.rpc-timeout-multiplier="
+ customMethodMultiplier.toString(),
"com.google.cloud.language.v1.language-service.annotate-text-retry.initial-retry-delay="
+ customMethodDurationString,
"com.google.cloud.language.v1.language-service.annotate-text-retry.max-retry-delay="
+ customMethodDurationString,
"com.google.cloud.language.v1.language-service.annotate-text-retry.initial-rpc-timeout="
+ customMethodDurationString,
"com.google.cloud.language.v1.language-service.annotate-text-retry.max-rpc-timeout="
+ customMethodDurationString,
"com.google.cloud.language.v1.language-service.annotate-text-retry.total-timeout="
+ customMethodDurationString,
"com.google.cloud.language.v1.language-service.annotate-text-retry.max-attempts="
+ customMethodMaxAttempts.toString())
.run(
ctx -> {
LanguageServiceClient client = ctx.getBean(LanguageServiceClient.class);
RetrySettings annotateTextRetrySettings =
client.getSettings().annotateTextSettings().getRetrySettings();
RetrySettings analyzeSentimentRetrySettings =
client.getSettings().analyzeSentimentSettings().getRetrySettings();

// Method-level overrides should be used for annotateText
assertThat(annotateTextRetrySettings.getRetryDelayMultiplier())
.isEqualTo(customMethodMultiplier);
assertThat(annotateTextRetrySettings.getRpcTimeoutMultiplier())
.isEqualTo(customMethodMultiplier);
assertThat(annotateTextRetrySettings.getInitialRetryDelay())
.isEqualTo(customMethodDuration);
assertThat(annotateTextRetrySettings.getInitialRpcTimeout())
.isEqualTo(customMethodDuration);
assertThat(annotateTextRetrySettings.getMaxRetryDelay())
.isEqualTo(customMethodDuration);
assertThat(annotateTextRetrySettings.getMaxRpcTimeout())
.isEqualTo(customMethodDuration);
assertThat(annotateTextRetrySettings.getTotalTimeout())
.isEqualTo(customMethodDuration);
assertThat(annotateTextRetrySettings.getMaxAttempts())
.isEqualTo(customMethodMaxAttempts);

// Service-level overrides should be used for analyzeSentiment
assertThat(analyzeSentimentRetrySettings.getRetryDelayMultiplier())
.isEqualTo(customServiceMultiplier);
assertThat(analyzeSentimentRetrySettings.getRpcTimeoutMultiplier())
.isEqualTo(customServiceMultiplier);
assertThat(analyzeSentimentRetrySettings.getInitialRetryDelay())
.isEqualTo(customServiceDuration);
assertThat(analyzeSentimentRetrySettings.getInitialRpcTimeout())
.isEqualTo(customServiceDuration);
assertThat(analyzeSentimentRetrySettings.getMaxRetryDelay())
.isEqualTo(customServiceDuration);
assertThat(analyzeSentimentRetrySettings.getMaxRpcTimeout())
.isEqualTo(customServiceDuration);
assertThat(analyzeSentimentRetrySettings.getTotalTimeout())
.isEqualTo(customServiceDuration);
assertThat(analyzeSentimentRetrySettings.getMaxAttempts())
.isEqualTo(customServiceMaxAttempts);
});
}
}
12 changes: 12 additions & 0 deletions generated/language/src/test/resources/fake-credential-key-2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"type": "service_account",
"project_id": "fake-project-id-2",
"private_key_id": "fake-key",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEugIBADANBgkqhkiG9w0BAQEFAASCBKQwggSgAgEAAoIBAQCh/y7v8lk1Ko79\nWVbQZCtmd0PXZr8WrUmmdEv2aaQQF/ed/KL2M/T2dbTlQ4EeOP+aK/5T8JSuxxZ5\na6e8TsovKXJz2qjeBLpzNFbx2xSyldYziC6v+bRCPKWCQLRNVdz/iYmOqjOu1/Ri\n8njOF7gG3XMQxryl9pmpJbVXj38Zw1n8mefT/g/+l6fObsVIgLs9WjGE9HDMKzx8\n9Ph7f+Ru1EuBrFOgHfKvWeIjVtQWqr3Dz+M1KyLFezYtXGB5HLg02sPJM+tMdcMj\nL9xpuodc6noBBeKvijEfTErLIaO1cJS5AgFHDyEsspaRdgXpJroM4w8ZSj3J0Wp7\ntJ7PeaG/AgMBAAECgf9ubAMSi59DHj9Zcgw7AAyVS7ZynRaj3nrVe3BMBrZOQggH\nKK3sJH5VgOZNYDYi47dW36X8kYDHoe0v1rH/KbWncBkT33g73f05ifO56Buzn27i\nsXEhgpPckno+ztwX2u9JP/cDyAByrcFnsN+nm4NVKp3EUbNFbVJQeeOiS63XYLvO\nuIUGlYJrnqa2zWp/YwhOmvZz5fNhfN/Js+V8kaA/xK/Dk0xhgvAqv73lgYZyL5pg\nlImHgHIm5alAMpchu4bInv2CjhKsgyPvHZU0Wihdm5it58hME0gN3ekD6lbdsp+1\nEwZ50JXALUPvzeMGXWorxuBUe9hpMcDmugR6rjECgYEAzpELFjiX2sNZPDX7cTM0\nYwWCdcvJUVTEapnpWuU2OhDreGMlBAWO6hkTIq6kmBZ0c30o10FNhXBrg0AyesgG\nheY6wO+v4e5hnVIdud2ih7AWDaKXVrb63Z/aF3EUhxcVk0wmnJtQ605cjMjeJOJF\nEyQCGsaiLbsEBsEKrXfLL08CgYEAyMOlz8dCNrEm16rbTE7NZpqql7IJhcAcXB5Z\nGUZicK98W4HnT6r5qPePgCjHnxjXl+/T6siH1B8CxQwtzETI8bu0Jd3ZvL7HZnIS\nHDWiGn72OJnYOvxvq1SvIqdTvlCMKqRQancp8wWP9oubzjS5ZZLGemaqvVL2Occp\nsfUZSpECgYBXPdz/2pEQHNcwXeA/VA/5DlemJpZ1GicGmtB6yjnX1lOM+dqlUy+j\n4Uk6qaXscfdm22KHXxY9mFhgC5oGTzqqDK2d1N1kv4hMqGTTni7Jve3iflwKjKdx\nONUkd2bjEzXSiyP3moVXjDX8Y82mqEXiKqAU7PWL+ONfcuJulxyicwKBgAcPoohR\nSMnlpykUsEvZxa2jKPbW4zDaFeVDh/y0lgfClEwfoIQTzl4b/ucSCBtXY1XLsJdk\nYCqcwJsvl3jEvpCJ+ocOa3cQ+rBmuK5XUJE//+bzukAw2ria7OH6Ip7h9FwXlWB5\nOnd6rZqNRHiXMCIbbHGnpL+t6E0V7Sh+J1qRAoGALRlR4TpW+UQvJIs5iBuF4/vg\n9iWLVOY8QoDYQ1k755EY53Q8tk3fO2ESUyV7A35zu/TQWm7z5PTFCl9R5dpWywMU\nTG7xr3tNVP7oDUN9ofN2ipB99EavN81k3co+nnWwhniJn0zHEpTq9IvGozwGuUjN\nIkiy17wHSSocTzvLDNk=\n-----END PRIVATE KEY-----\n",
"client_email": "test@fake-project.iam.gserviceaccount.com",
"client_id": "12345",
"auth_uri": "https://fake.auth.url.com/o/oauth2/auth",
"token_uri": "https://fake.token.url.com/token",
"auth_provider_x509_cert_url": "https://fake.auth.provider.cert.url.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.fake.client.cert.com/robot/v1/metadata/x509/test@fake-project.iam.gserviceaccount.com"
}
Loading