com.google.api.gax.grpc.GrpcTransportDescriptorTest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gax-grpc Show documentation
Show all versions of gax-grpc Show documentation
Google Api eXtensions for Java (gRPC)
/*
* Copyright 2017 Google LLC
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google LLC nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.google.api.gax.grpc;
import static org.junit.Assert.fail;
import com.google.api.core.ApiFuture;
import com.google.api.core.ApiFutures;
import com.google.api.core.SettableApiFuture;
import com.google.api.gax.rpc.ApiCallContext;
import com.google.api.gax.rpc.ApiException;
import com.google.api.gax.rpc.DataLossException;
import com.google.api.gax.rpc.InvalidArgumentException;
import com.google.api.gax.rpc.StatusCode;
import com.google.api.gax.rpc.StatusCode.Code;
import com.google.api.gax.rpc.UnaryCallable;
import com.google.api.gax.rpc.UnavailableException;
import com.google.api.gax.rpc.UnknownException;
import com.google.common.truth.Truth;
import io.grpc.Status;
import io.grpc.StatusException;
import io.grpc.StatusRuntimeException;
import java.util.Collections;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class GrpcTransportDescriptorTest {
private static boolean NOT_RETRYABLE = false;
private static boolean IS_RETRYABLE = true;
@Rule public ExpectedException thrown = ExpectedException.none();
@Test
public void translateException_StatusException_noRetry() throws Exception {
Throwable originalException = new StatusException(Status.INVALID_ARGUMENT);
GrpcExceptionCallable exceptionCallable =
new GrpcExceptionCallable<>(
failingCallable(originalException), Collections.emptySet());
try {
exceptionCallable.call(0);
fail("Expected exception to be thrown");
} catch (Throwable throwable) {
assertInnerExceptionIsInstanceOf(
throwable, InvalidArgumentException.class, NOT_RETRYABLE, originalException);
}
}
@Test
public void translateException_StatusException_withRetry() throws Exception {
Throwable originalException = new StatusException(Status.UNAVAILABLE);
GrpcExceptionCallable exceptionCallable =
new GrpcExceptionCallable<>(
failingCallable(originalException), Collections.singleton(Code.UNAVAILABLE));
try {
exceptionCallable.call(0);
fail("Expected exception to be thrown");
} catch (Throwable throwable) {
assertInnerExceptionIsInstanceOf(
throwable, UnavailableException.class, IS_RETRYABLE, originalException);
}
}
@Test
public void translateException_StatusRuntimeException_noRetry() throws Exception {
Throwable originalException = new StatusRuntimeException(Status.INVALID_ARGUMENT);
GrpcExceptionCallable exceptionCallable =
new GrpcExceptionCallable<>(
failingCallable(originalException), Collections.emptySet());
try {
exceptionCallable.call(0);
fail("Expected exception to be thrown");
} catch (Throwable throwable) {
assertInnerExceptionIsInstanceOf(
throwable, InvalidArgumentException.class, NOT_RETRYABLE, originalException);
}
}
@Test
public void translateException_StatusRuntimeException_withRetry() throws Exception {
Throwable originalException = new StatusRuntimeException(Status.UNAVAILABLE);
GrpcExceptionCallable exceptionCallable =
new GrpcExceptionCallable<>(
failingCallable(originalException), Collections.singleton(Code.UNAVAILABLE));
try {
exceptionCallable.call(0);
fail("Expected exception to be thrown");
} catch (Throwable throwable) {
assertInnerExceptionIsInstanceOf(
throwable, UnavailableException.class, IS_RETRYABLE, originalException);
}
}
@Test
public void translateException_cancelled() throws Exception {
GrpcExceptionCallable exceptionCallable =
new GrpcExceptionCallable<>(inactiveCallable(), Collections.emptySet());
ApiFuture result = exceptionCallable.futureCall(0);
Truth.assertThat(result.isDone()).isFalse();
result.cancel(true);
Truth.assertThat(result.isCancelled()).isTrue();
Truth.assertThat(result.isDone()).isTrue();
}
@Test
public void translateException_ApiException() throws Exception {
Throwable originalException = new RuntimeException("stuff went wrong");
Throwable apiException =
new DataLossException(
originalException, GrpcStatusCode.of(Status.Code.UNKNOWN), IS_RETRYABLE);
GrpcExceptionCallable exceptionCallable =
new GrpcExceptionCallable<>(
failingCallable(apiException), Collections.emptySet());
try {
exceptionCallable.call(0);
fail("Expected exception to be thrown");
} catch (Throwable throwable) {
assertInnerExceptionIsInstanceOf(
throwable, DataLossException.class, IS_RETRYABLE, originalException);
}
}
@Test
public void translateException_RuntimeException() throws Exception {
Throwable originalException = new RuntimeException("stuff went wrong");
GrpcExceptionCallable exceptionCallable =
new GrpcExceptionCallable<>(
failingCallable(originalException), Collections.emptySet());
try {
exceptionCallable.call(0);
fail("Expected exception to be thrown");
} catch (Throwable throwable) {
assertInnerExceptionIsInstanceOf(
throwable, UnknownException.class, NOT_RETRYABLE, originalException);
}
}
private UnaryCallable failingCallable(final Throwable exception) {
return new UnaryCallable() {
@Override
public ApiFuture futureCall(Integer request, ApiCallContext context) {
return ApiFutures.immediateFailedFuture(exception);
}
};
}
private UnaryCallable inactiveCallable() {
return new UnaryCallable() {
@Override
public ApiFuture futureCall(Integer request, ApiCallContext context) {
return SettableApiFuture.create();
}
};
}
public void assertInnerExceptionIsInstanceOf(
Throwable thrownException, Class clazz, boolean retryable, Throwable originalException)
throws Exception {
Truth.assertThat(thrownException).isInstanceOf(clazz);
ApiException apiException = (ApiException) thrownException;
Truth.assertThat(apiException.isRetryable()).isEqualTo(retryable);
}
}