blob: 57a6a2ac165ac474b35f8c766329e98f83dfda00 [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.servicecomb.transport.rest.vertx;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.servicecomb.config.ConfigUtil;
import org.apache.servicecomb.core.Endpoint;
import org.apache.servicecomb.core.SCBEngine;
import org.apache.servicecomb.core.Transport;
import org.apache.servicecomb.core.bootstrap.SCBBootstrap;
import org.apache.servicecomb.core.transport.AbstractTransport;
import org.apache.servicecomb.foundation.common.Holder;
import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.mockito.Mockito;
import io.vertx.core.Context;
import io.vertx.core.Handler;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Route;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.CorsHandler;
import mockit.Expectations;
import mockit.Mock;
import mockit.MockUp;
import mockit.Mocked;
public class TestRestServerVerticle {
private RestServerVerticle instance = null;
Promise<Void> startPromise = null;
@Before
public void setUp() {
ConfigUtil.installDynamicConfig();
instance = new RestServerVerticle();
startPromise = Promise.promise();
SCBBootstrap.createSCBEngineForTest();
}
@After
public void tearDown() {
instance = null;
startPromise = null;
SCBEngine.getInstance().destroy();
ArchaiusUtils.resetConfig();
}
@Test
public void testRestServerVerticleWithRouter(@Mocked Transport transport, @Mocked Vertx vertx,
@Mocked Context context,
@Mocked JsonObject jsonObject, @Mocked Promise<Void> startPromise) throws Exception {
URIEndpointObject endpointObject = new URIEndpointObject("http://127.0.0.1:8080");
new Expectations() {
{
transport.parseAddress("http://127.0.0.1:8080");
result = endpointObject;
}
};
Endpoint endpiont = new Endpoint(transport, "http://127.0.0.1:8080");
new Expectations() {
{
context.config();
result = jsonObject;
jsonObject.getValue(AbstractTransport.ENDPOINT_KEY);
result = endpiont;
}
};
RestServerVerticle server = new RestServerVerticle();
// process stuff done by Expectations
server.init(vertx, context);
server.start(startPromise);
}
@Test
public void testRestServerVerticleWithRouterSSL(@Mocked Transport transport, @Mocked Vertx vertx,
@Mocked Context context,
@Mocked JsonObject jsonObject, @Mocked Promise<Void> startPromise) throws Exception {
URIEndpointObject endpointObject = new URIEndpointObject("http://127.0.0.1:8080?sslEnabled=true");
new Expectations() {
{
transport.parseAddress("http://127.0.0.1:8080?sslEnabled=true");
result = endpointObject;
}
};
Endpoint endpiont = new Endpoint(transport, "http://127.0.0.1:8080?sslEnabled=true");
new Expectations() {
{
context.config();
result = jsonObject;
jsonObject.getValue(AbstractTransport.ENDPOINT_KEY);
result = endpiont;
}
};
RestServerVerticle server = new RestServerVerticle();
// process stuff done by Expectations
server.init(vertx, context);
server.start(startPromise);
}
@Test
public void testRestServerVerticleWithHttp2(@Mocked Transport transport, @Mocked Vertx vertx,
@Mocked Context context,
@Mocked JsonObject jsonObject, @Mocked Promise<Void> startPromise) {
URIEndpointObject endpointObject = new URIEndpointObject("http://127.0.0.1:8080?protocol=http2");
new Expectations() {
{
transport.parseAddress("http://127.0.0.1:8080?protocol=http2");
result = endpointObject;
}
};
Endpoint endpiont = new Endpoint(transport, "http://127.0.0.1:8080?protocol=http2");
new Expectations() {
{
context.config();
result = jsonObject;
jsonObject.getValue(AbstractTransport.ENDPOINT_KEY);
result = endpiont;
}
};
RestServerVerticle server = new RestServerVerticle();
boolean status = false;
try {
server.init(vertx, context);
server.start(startPromise);
} catch (Exception e) {
status = true;
}
Assertions.assertFalse(status);
}
@Test
public void testStartFutureAddressEmpty() {
boolean status = false;
try {
instance.start(startPromise);
} catch (Exception ex) {
status = true;
}
Assertions.assertFalse(status);
}
@Test
public void testStartFutureAddressNotEmpty() {
boolean status = false;
MockForRestServerVerticle.getInstance().mockTransportConfig();
MockForRestServerVerticle.getInstance().mockRestServerVerticle();
try {
instance.start(startPromise);
} catch (Exception ex) {
status = true;
}
Assertions.assertFalse(status);
}
@Test
public void testMountCorsHandler() {
ArchaiusUtils.setProperty("servicecomb.cors.enabled", true);
ArchaiusUtils.setProperty("servicecomb.cors.allowedMethod", "GET,PUT,POST");
ArchaiusUtils.setProperty("servicecomb.cors.allowedHeader", "abc,def");
ArchaiusUtils.setProperty("servicecomb.cors.exposedHeader", "abc2,def2");
ArchaiusUtils.setProperty("servicecomb.cors.maxAge", 1);
Set<HttpMethod> methodSet = new HashSet<>(3);
methodSet.add(HttpMethod.GET);
methodSet.add(HttpMethod.PUT);
methodSet.add(HttpMethod.POST);
AtomicInteger counter = new AtomicInteger(0);
CorsHandler corsHandler = new MockUp<CorsHandler>() {
@Mock
CorsHandler allowCredentials(boolean allow) {
Assertions.assertFalse(allow);
counter.incrementAndGet();
return null;
}
@Mock
CorsHandler allowedHeaders(Set<String> headerNames) {
MatcherAssert.assertThat(headerNames, Matchers.containsInAnyOrder("abc", "def"));
counter.incrementAndGet();
return null;
}
@Mock
CorsHandler exposedHeaders(Set<String> headerNames) {
MatcherAssert.assertThat(headerNames, Matchers.containsInAnyOrder("abc2", "def2"));
counter.incrementAndGet();
return null;
}
@Mock
CorsHandler allowedMethod(HttpMethod method) {
Assertions.assertTrue(methodSet.contains(method));
counter.incrementAndGet();
methodSet.remove(method);
return null;
}
@Mock
CorsHandler maxAgeSeconds(int maxAgeSeconds) {
Assertions.assertEquals(1, maxAgeSeconds);
counter.incrementAndGet();
return null;
}
}.getMockInstance();
new MockUp<RestServerVerticle>() {
@Mock
CorsHandler getCorsHandler(String corsAllowedOrigin) {
Assertions.assertEquals("*", corsAllowedOrigin);
return corsHandler;
}
};
Router router = Mockito.mock(Router.class);
Mockito.when(router.route()).thenReturn(Mockito.mock(Route.class));
RestServerVerticle server = new RestServerVerticle();
server.mountCorsHandler(router);
Assertions.assertEquals(7, counter.get());
}
@Test
public void mountGlobalRestFailureHandler() {
Router mainRouter = Mockito.mock(Router.class);
Holder<Handler<RoutingContext>> handlerHolder = new Holder<>();
Holder<Route> routeHolder = new Holder<>();
Route route = new MockUp<Route>() {
@Mock
Route failureHandler(Handler<RoutingContext> failureHandler) {
handlerHolder.value = failureHandler;
return null;
}
@Mock
Route handler(io.vertx.core.Handler<io.vertx.ext.web.RoutingContext> requestHandler) {
return routeHolder.value;
}
}.getMockInstance();
routeHolder.value = route;
Mockito.when(mainRouter.route()).thenReturn(route);
RestServerVerticle restServerVerticle = new RestServerVerticle();
restServerVerticle.mountGlobalRestFailureHandler(mainRouter);
Assertions.assertNotNull(handlerHolder.value);
RoutingContext routingContext = Mockito.mock(RoutingContext.class);
HttpServerResponse response = Mockito.mock(HttpServerResponse.class);
Mockito.when(response.setStatusCode(500)).thenReturn(response);
Mockito.when(response.putHeader("Content-Type", "application/json")).thenReturn(response);
Mockito.when(routingContext.response()).thenReturn(response);
handlerHolder.value.handle(routingContext);
Mockito.verify(response).end("{\"message\":\"unknown error\"}");
}
}