blob: 83bf50f51e611a456aaa8f4754d6c3755723c15f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you 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
*
* http://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 org.apache.calcite.avatica.remote;
import org.apache.calcite.avatica.AvaticaSeverity;
import org.apache.calcite.avatica.remote.Handler.HandlerResponse;
import org.apache.calcite.avatica.remote.Service.ErrorResponse;
import org.apache.calcite.avatica.remote.Service.Request;
import org.apache.calcite.avatica.remote.Service.Response;
import org.junit.Test;
import org.mockito.Mockito;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Objects;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Test for common functionality across {@link Handler} implementations.
*/
public class AbstractHandlerTest {
private String exceptionToString(Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
Objects.requireNonNull(e).printStackTrace(pw);
return sw.toString();
}
@Test public void testExceptionUnwrappingWithoutContext() {
@SuppressWarnings("unchecked")
AbstractHandler<String> handler = Mockito.mock(AbstractHandler.class);
Mockito.when(handler.unwrapException(Mockito.any(Exception.class))).thenCallRealMethod();
Exception e = new RuntimeException();
Response resp = handler.unwrapException(e);
assertTrue("Response should be ErrorResponse, but was " + resp.getClass(),
resp instanceof ErrorResponse);
ErrorResponse errorResp = (ErrorResponse) resp;
assertEquals(ErrorResponse.UNKNOWN_ERROR_CODE, errorResp.errorCode);
assertEquals(AvaticaSeverity.UNKNOWN, errorResp.severity);
assertEquals(Arrays.asList(exceptionToString(e)), errorResp.exceptions);
e = new AvaticaRuntimeException();
resp = handler.unwrapException(e);
assertTrue("Response should be ErrorResponse, but was " + resp.getClass(),
resp instanceof ErrorResponse);
errorResp = (ErrorResponse) resp;
assertEquals(ErrorResponse.UNKNOWN_ERROR_CODE, errorResp.errorCode);
assertEquals(AvaticaSeverity.UNKNOWN, errorResp.severity);
assertEquals(Arrays.asList(exceptionToString(e)), errorResp.exceptions);
}
@Test public void testExceptionUnwrappingWithContext() {
@SuppressWarnings("unchecked")
AbstractHandler<String> handler = Mockito.mock(AbstractHandler.class);
Mockito.when(handler.unwrapException(Mockito.any(Exception.class))).thenCallRealMethod();
final String msg = "Something failed!";
AvaticaRuntimeException e = new AvaticaRuntimeException(msg,
ErrorResponse.UNKNOWN_ERROR_CODE, ErrorResponse.UNKNOWN_SQL_STATE, AvaticaSeverity.FATAL);
Response resp = handler.unwrapException(e);
assertTrue("Response should be ErrorResponse, but was " + resp.getClass(),
resp instanceof ErrorResponse);
ErrorResponse errorResp = (ErrorResponse) resp;
assertEquals(ErrorResponse.UNKNOWN_ERROR_CODE, errorResp.errorCode);
assertEquals(AvaticaSeverity.FATAL, errorResp.severity);
assertEquals(Arrays.asList(exceptionToString(e)), errorResp.exceptions);
assertEquals(msg, errorResp.errorMessage);
}
@Test public void testFailedResponseSerialization() throws IOException {
@SuppressWarnings("unchecked")
final AbstractHandler<String> handler = Mockito.mock(AbstractHandler.class);
final Request request = Mockito.mock(Request.class);
final Response response = Mockito.mock(Response.class);
final IOException exception = new IOException();
final ErrorResponse errorResponse = Mockito.mock(ErrorResponse.class);
final String serializedErrorResponse = "An ErrorResponse";
// Accept a serialized request
Mockito.when(handler.apply(Mockito.anyString())).thenCallRealMethod();
// Deserialize it back into a POJO
Mockito.when(handler.decode(Mockito.anyString())).thenReturn(request);
// Construct the Response for that Request
Mockito.when(request.accept(Mockito.nullable(Service.class))).thenReturn(response);
// Throw an IOException when serializing the Response.
Mockito.when(handler.encode(response)).thenThrow(exception);
Mockito.when(handler.convertToErrorResponse(exception)).thenCallRealMethod();
// Convert the IOException into an ErrorResponse
Mockito.when(handler.unwrapException(exception)).thenReturn(errorResponse);
Mockito.when(handler.encode(errorResponse)).thenReturn(serializedErrorResponse);
HandlerResponse<String> handlerResp = handler.apply("this is mocked out");
assertEquals(500, handlerResp.getStatusCode());
assertEquals(serializedErrorResponse, handlerResp.getResponse());
}
@Test public void testFailedErrorResponseSerialization() throws IOException {
@SuppressWarnings("unchecked")
final AbstractHandler<String> handler = Mockito.mock(AbstractHandler.class);
final Request request = Mockito.mock(Request.class);
final Response response = Mockito.mock(Response.class);
final IOException exception = new IOException();
final ErrorResponse errorResponse = Mockito.mock(ErrorResponse.class);
// Accept a serialized request
Mockito.when(handler.apply(Mockito.anyString())).thenCallRealMethod();
// Deserialize it back into a POJO
Mockito.when(handler.decode(Mockito.anyString())).thenReturn(request);
// Construct the Response for that Request
Mockito.when(request.accept(Mockito.any(Service.class))).thenReturn(response);
// Throw an IOException when serializing the Response.
Mockito.when(handler.encode(response)).thenThrow(exception);
// Convert the IOException into an ErrorResponse
Mockito.when(handler.unwrapException(exception)).thenReturn(errorResponse);
// Fail to serialize the ErrorResponse
Mockito.when(handler.encode(errorResponse)).thenThrow(exception);
try {
handler.apply("this is mocked out");
} catch (RuntimeException e) {
assertEquals(exception, e.getCause());
}
}
@Test public void testFailedRequestDeserialization() throws IOException {
@SuppressWarnings("unchecked")
final AbstractHandler<String> handler = Mockito.mock(AbstractHandler.class);
final IOException exception = new IOException();
final ErrorResponse errorResponse = new ErrorResponse();
final String serializedErrorResponse = "Serialized ErrorResponse"; // Faked out
// Accept a serialized request
Mockito.when(handler.apply(Mockito.anyString())).thenCallRealMethod();
// Throw an Exception trying to convert it back into a POJO
Mockito.when(handler.decode(Mockito.anyString())).thenThrow(exception);
Mockito.when(handler.convertToErrorResponse(exception)).thenCallRealMethod();
Mockito.when(handler.unwrapException(exception)).thenReturn(errorResponse);
Mockito.when(handler.encode(errorResponse)).thenReturn(serializedErrorResponse);
HandlerResponse<String> response = handler.apply("this is mocked out");
assertEquals(serializedErrorResponse, response.getResponse());
assertEquals(500, response.getStatusCode());
}
}
// End AbstractHandlerTest.java